>Форум Mozilla Россия http://forum.mozilla-russia.org/index.php >Скрипты http://forum.mozilla-russia.org/viewforum.php?id=37 >UCF - ваши кнопки, скрипты… http://forum.mozilla-russia.org/viewtopic.php?id=76642 |
Dobrov > 24-05-2021 00:54:06 |
UserChromeFiles загрузчик скриптов/стилей расширяет возможности Firefox 115+ через функцию autoconfig. © Vitaliy V. Демо-профиль обновляемый на github для FF 78+ кнопки, меню, подсказки, стили, клики, hotkeys, жесты: встроена Справка, сайт в боковую панель, создать единый HTML, градиент загрузки, скрыть 1 вкладку, яркость, быстрая закладка или восстановить удалённые, сохранить фото, перевод сайт/текст, скачать видео, режимы Эксперт|Простой, скрытые настройки, режим Прокси цветом ≡ Меню и многое другое… Лёгкость настройки - всё в ucf_hookClicks.js. возможности Демо-профиля: для справки жмите кнопку «Печать» секунду Кнопки — расширяемые кликами кнопок мыши и колёсика, сочетания клавиш и жесты: новые 14 — Журнал и меню опций, История, Закладки, Папки, Пароли, Просмотр части страницы или Запись в Html, Менеджер сессий, Восстановить удалённые закладки или fav-иконки, Ссылки в подсказках, Дополнения, Инспектор атрибутов, UCF… стандартные 7 — Загрузки, ≡ Меню, Печать, Звёздочка, Щит защиты, Замок, Обновить/Стоп расширения 2 — SingleFile (сохранение по Alt+Shift+S), Reader View. User.js скрипт пользователя: запуск по Alt+X, ucf_aom-button.js управление дополнениями ucf_hookClicks.js глобальные функции, меню, подсказки, перехват нажатий мыши и клавиатуры ucf_QuickToggle открытие боковой панели, меню скрытых системных настроек attrsInspector.js Attributes Inspector, auto_hide_sidebar скрытие боковой панели menubarVisibilityChance, ucf_autohidetabstoolbar.js автоскрытие панели с одной вкладкой ucf-loads-favicons восстановить иконки закладок ucf_BookmarkDir быстрая закладка, перевод сайта/текста ucf_contextsearch поиск в контекстном меню, ucf_findbarclose.js автоскрытие поиска ucf_SidebarTabs боковая панель для сайта, журнала, загрузок… ucf_LocationBarEnhancer градиент загрузки страниц ucf_pauseResume кнопка Пауза для скачиваемых файлов ucf_downloads_clear кнопка "Очистить загрузки" на DownloadsPanel ucf_session сохранение | восстановление сессий ucf_tab-update автообновление вкладок по таймеру ucf_undo-tab история закрытых вкладок/окон ucf_win_contextmenuopenwith можно прописать свои приложения открытия ссылок ucf_win_mousedrag жесты мыши для ссылок и выделенного текста ucb_SaveHTML.mjs сохранение страниц в единый Html ClickPicSave.mjs сохранение картинок, в том числе и недоступных для сохранения обычным способом TitleChanged.mjs авто-коррекция имён (заголовков) вкладок PageReadMode.user.js выбор части страницы курсорными клавишами после нажатия Alt+R undoBookmarks.js восстановить удалённые Закладки в панели закладок Возможности дополняются пользовательскими скриптами, например Vk Media Downloader Скрипты для докум. окна браузера [ChromeOnly] Скрипты В фоне [System Principal]: Другие менеджеры скриптов: fx-autoconfig MrOtherGuy, Tampermonkey, userChrome.js Endor8 Список полезных постов (т.к. тема захламлена) |
Vitaliy V. > 05-07-2021 21:26:26 |
del |
harryk > 05-07-2021 23:36:31 |
Vitaliy V.
У меня там только стандартный загрузчик Выделить код Код:load() { if (this.initialized) return; this.initialized = true; /* ************************************************ */ // Здесь может быть ваш код который сработает по событию "load" не раньше /* ************************************************ */ }, Его нужно заменить на тот, что по ссылке? |
Vitaliy V. > 06-07-2021 00:14:56 |
harryk
Да to all |
harryk > 06-07-2021 00:24:39 |
Vitaliy V. |
sandro79 > 06-07-2021 02:13:56 |
Vitaliy V. ucjsDownloadsManager.uc.js Выделить код Код:if (location.href == "chrome://browser/content/browser.xhtml") { Cu.import("resource://gre/modules/Services.jsm"); window.ucjs_downloadManager = { _summary: null, _list: null, createElement: function(localName, arryAttribute) { let elm = document.createXULElement(localName); for(let i = 0; i < arryAttribute.length; i++) { elm.setAttribute(arryAttribute[i].attr, arryAttribute[i].value); } return elm; }, init: function() { window.addEventListener("unload", this, false); let ref = document.getElementById("menu_openDownloads"); let menu = ref.parentNode.insertBefore( this.createElement("menuitem", [{attr: "label", value:"Менеджер загрузок"}, {attr : "oncommand", value: "ucjs_downloadManager.openDownloadManager(true);"} ]), ref); XPCOMUtils.defineLazyModuleGetter(this, "Downloads", "resource://gre/modules/Downloads.jsm"); // Ensure that the DownloadSummary object will be created asynchronously. if (!this._summary) { this.Downloads.getSummary(this.Downloads.ALL).then(summary => { this._summary = summary; return this._summary.addView(this); }).then(null, Cu.reportError); } if (!this._list) { this.Downloads.getList(this.Downloads.ALL).then(list => { this._list = list; return this._list.addView(this); }).then(null, Cu.reportError); } }, uninit: function() { window.removeEventListener("unload", this, false); if (this._summary) { this._summary.removeView(this); } if (this._list) { this._list.removeView(this); } }, handleEvent: function(event) { switch (event.type) { case "unload": this.uninit(); break; } }, openDownloadManager: function ucjs_openDownloadManager(aForceFocus) { var enumerator = Services.wm.getEnumerator(null); while(enumerator.hasMoreElements()) { var win = enumerator.getNext(); if (win.location == "chrome://browser/content/downloads/contentAreaDownloadsView.xhtml" && PrivateBrowsingUtils.isWindowPrivate(window) == PrivateBrowsingUtils.isWindowPrivate(win)) { if (aForceFocus) win.focus(); return; } } try { var height = Math.max(100,Services.prefs.getIntPref("browser.download.manager.size.height")); var width = Math.max(300,Services.prefs.getIntPref("browser.download.manager.size.width")); var screenX = Math.min(Math.max(0,Services.prefs.getIntPref("browser.download.manager.size.screenX")), screen.availWidth - width); var screenY = Math.min(Math.max(0,Services.prefs.getIntPref("browser.download.manager.size.screenY")), screen.availHeight - height); } catch(r){ height = 300; width = 480; screenX = 5; screenY = 5; } var win = window.open("chrome://browser/content/downloads/contentAreaDownloadsView.xhtml", "Download" + (PrivateBrowsingUtils.isWindowPrivate(window) ? " - Private Window" : ""), "outerWidth=" + width + ",outerHeight=" + height + ",left=" + screenX + ",top=" + screenY + ",chrome,toolbar=yes,dialog=no,resizable"); }, closeDownloadManager: function ucjs_closeDownloadManager() { var enumerator = Services.wm.getEnumerator(null); while(enumerator.hasMoreElements()) { var win = enumerator.getNext(); if (win.location == "chrome://browser/content/downloads/contentAreaDownloadsView.xhtml") { win.close(); return; } } }, onDownloadAdded: function (aDownload) { var showWhenStarting = true; try { showWhenStarting = Services.prefs.getBoolPref("browser.download.manager.showWhenStarting"); } catch(e) {} var numDls = 0; if (showWhenStarting) { if (this._list) { this._list.getAll().then(downloads => { for (let download of downloads) { if (!download.stopped) numDls++; } if (numDls > 0) this.openDownloadManager(false); }).then(null, Cu.reportError); } } }, onDownloadChanged: function (aDownload) { if (!this._list) return; this._list.getAll().then(downloads => { var num = 0; for (let download of downloads) { if (!download.succeeded) num++; } if (num == 0) { var closeWhenDone = true; try { closeWhenDone = Services.prefs.getBoolPref("browser.download.manager.closeWhenDone"); } catch(e) {} if (closeWhenDone) { this.closeDownloadManager(); } } }).then(null, Cu.reportError); } }; ucjs_downloadManager.init(); } ucjsDownloadsManager2.uc.js Выделить код Код:Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/DownloadIntegration.jsm"); window.ucjs_downloadManagerMain = { originalTitle:"", _summary: null, _list: null, _wait:false, createElement: function(localName, arryAttribute) { let elm = document.createXULElement(localName); for(let i = 0; i < arryAttribute.length; i++) { elm.setAttribute(arryAttribute[i].attr, arryAttribute[i].value); } return elm; }, createElementNS: function(NS, localName, arryAttribute) { let elm = document.createElementNS(NS, localName); for(let i = 0; i < arryAttribute.length; i++) { elm.setAttribute(arryAttribute[i].attr, arryAttribute[i].value); } return elm; }, init: function() { window.addEventListener("unload", this, false); // xxx remove in-content css var elements = document.childNodes; for (var i = 0; i <= elements.length; i++) { var element = elements[i]; if (element.nodeValue.indexOf("chrome://browser/skin/downloads/contentAreaDownloadsView.css") > -1) { document.removeChild(element); break; } } document.getElementById("downloadsListEmptyDescription").setAttribute("flex", "1"); let ref = document.documentElement; ref = ref.appendChild(this.createElement("hbox", [])); ref.appendChild(this.createElement("button", [{attr: "id", value: "ucjs_clearListButton"}, {attr: "label", value: "Очистить загрузки"}, ])); ref.appendChild(this.createElement("spacer", [{attr: "flex", value: "1"}])); ref.appendChild(this.createElementNS("http://www.w3.org/1999/xhtml", "input", [{attr: "id", value: "ucjs_downloadManagerMain_input"}, {attr: "clickSelectsAll", value: "true"}, {attr: "type", value: "search"}, {attr: "placeholder", value: "Поиск в загрузках"}, {attr: "aria-autocomplete", value: "list"} ])); document.getElementById("ucjs_clearListButton").addEventListener("command", function(event) { ucjs_downloadManagerMain.clearDownloads(); }); document.getElementById("ucjs_downloadManagerMain_input") .addEventListener("input", function(event) { ucjs_downloadManagerMain.doSearch(event.target.value); }); this.originalTitle = document.title + (PrivateBrowsingUtils.isWindowPrivate(window) ? " - Private Window" : ""); /* // xxx Bug 1279329 "Copy Download Link" of context menu in Library is grayed out var listBox = document.getElementById("downloadsRichListBox"); var placesView = listBox._placesView; var place = placesView.place; placesView.place= null; placesView.place = place; */ setTimeout(function(){this._wait = true}.bind(this), 0); // Ensure that the DownloadSummary object will be created asynchronously. if (!this._summary) { Downloads.getSummary(Downloads.ALL).then(summary => { this._summary = summary; return this._summary.addView(this); }).then(null, Cu.reportError); } if (!this._list) { Downloads.getList(Downloads.ALL).then(list => { this._list = list; return this._list.addView(this); }).then(null, Cu.reportError); } try { var showProgressInTaskButton = Services.prefs.getBoolPref("browser.download.manager.showProgressInTaskButton") } catch(ex) { showProgressInTaskButton = true; //default } if (showProgressInTaskButton) setTimeout(function() { try { let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner .QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIXULWindow).docShell; let gWinTaskbar = Components.classes["@mozilla.org/windows-taskbar;1"] .getService(Components.interfaces.nsIWinTaskbar); this._taskbarProgress = gWinTaskbar.getTaskbarProgress(docShell); } catch(ex) { this._taskbarProgress = null; } }.bind(this), 10); }, uninit: function() { window.removeEventListener("unload", this, false); this._taskbarProgress = null; if (this._wait) this.saveSizePosition(); if (this._summary) { this._summary.removeView(this); } if (this._list) { this._list.removeView(this); } }, handleEvent: function(event) { switch (event.type) { case "unload": this.uninit(); break; } }, saveSizePosition: function() { if (window.windowState == 3) { Services.prefs.setIntPref("browser.download.manager.size.height", window.outerHeight); Services.prefs.setIntPref("browser.download.manager.size.width", window.outerWidth); Services.prefs.setIntPref("browser.download.manager.size.screenX", window.screenX); Services.prefs.setIntPref("browser.download.manager.size.screenY", window.screenY); } }, onSummaryChanged: function () { if (!this._summary) return; if (this._summary.allHaveStopped || this._summary.progressTotalBytes == 0) { document.title = this.originalTitle; if (this._taskbarProgress) { this._taskbarProgress.setProgressState( Ci.nsITaskbarProgress.STATE_NO_PROGRESS, 0, 0); } Cu.import("resource://gre/modules/Services.jsm"); var enumerator = Services.wm.getEnumerator("navigator:browser"); while(enumerator.hasMoreElements()) { return; } var closeWhenDone = true; try { closeWhenDone = Services.prefs.getBoolPref("browser.download.manager.closeWhenDone"); } catch(e) {} if (closeWhenDone) { DownloadIntegration._store.save(); window.close(); } } else { // If the last browser window has been closed, we have no indicator any more. if (this._taskbarProgress) { if (this._summary.allHaveStopped || this._summary.progressTotalBytes == 0) { this._taskbarProgress.setProgressState( Ci.nsITaskbarProgress.STATE_NO_PROGRESS, 0, 0); } else { // For a brief moment before completion, some download components may // report more transferred bytes than the total number of bytes. Thus, // ensure that we never break the expectations of the progress indicator. let progressCurrentBytes = Math.min(this._summary.progressTotalBytes, this._summary.progressCurrentBytes); this._taskbarProgress.setProgressState( Ci.nsITaskbarProgress.STATE_NORMAL, progressCurrentBytes, this._summary.progressTotalBytes); } } // Update window title var numDls = 0; if (!this._list) return; this._list.getAll().then(downloads => { for (let download of downloads) { if (download.hasProgress && !download.succeeded) numDls++; } let progressCurrentBytes = Math.min(this._summary.progressTotalBytes, this._summary.progressCurrentBytes); let percent = Math.floor(progressCurrentBytes / this._summary.progressTotalBytes * 100); let text = percent + "% из " + numDls + (numDls < 2 ? " файла - " : " файлов - ") ; document.title = text + this.originalTitle; }).then(null, Cu.reportError); } }, clearDownloads: function ucjs_clearDownloads() { var DO_NOT_DELETE_HISTORY = true; /* custmizable true or false */ var richListBox = document.getElementById("downloadsRichListBox"); var places = []; function addPlace(aURI, aTitle, aVisitDate) { places.push({ uri: aURI, title: aTitle, visits: [{ visitDate: (aVisitDate || Date.now()) * 1000, transitionType: Ci.nsINavHistoryService.TRANSITION_LINK }] }); } function moveDownloads2History(d) { if (DO_NOT_DELETE_HISTORY && !PrivateBrowsingUtils.isWindowPrivate(window)) { for (let element of richListBox.childNodes) { let download = element._shell.download; let aURI = makeURI(download.source.url); // let aTitle = document.getAnonymousElementByAttribute(element, "class", "downloadTarget").value let aTitle = download.target.path; aTitle = aTitle.match( /[^\\]+$/i )[0]; aTitle = aTitle.match( /[^/]+$/i )[0]; let aVisitDate = download.endTime || download.startTime; addPlace(aURI, aTitle, aVisitDate) } } // Clear List richListBox._placesView.doCommand('downloadsCmd_clearDownloads'); if (DO_NOT_DELETE_HISTORY && !PrivateBrowsingUtils.isWindowPrivate(window)) { if (places.length > 0) { var asyncHistory = Components.classes["@mozilla.org/browser/history;1"] .getService(Components.interfaces.mozIAsyncHistory); asyncHistory.updatePlaces(places); } } } var btn = document.getElementById("ucjs_clearListButton"); moveDownloads2History(0); }, doSearch: function ucjs_doSearch(filterString) { var richListBox = document.getElementById("downloadsRichListBox"); richListBox._placesView.searchTerm = filterString; } }; ucjs_downloadManagerMain.init(); Небольшие косметические улучшения Выделить код Код:@-moz-document url(chrome://browser/content/downloads/contentAreaDownloadsView.xhtml) { #downloadsListEmptyDescription { margin: 0 !important; padding: 1px 0 0 6px !important; background-color: white !important; } #contentAreaDownloadsView > hbox { background-color: -moz-Dialog !important; padding-top: 2px !important; border: 1px solid gainsboro !important; } #ucjs_clearListButton { margin: 1px 2px 2px !important; } } |
sandro79 > 06-07-2021 15:44:42 |
Скрипты авторства Dumby, которые использую: user_chrome.manifest firefox 90 Выделить код Код:content user_chrome_files ./ # Не уверены, не редактируйте этот файл! override chrome://global/skin/icons/defaultFavicon.svg chrome://user_chrome_files/content/custom_styles/svg/defaultFavicon.svg override chrome://branding/content/identity-icons-brand.svg chrome://user_chrome_files/content/custom_styles/svg/defaultFavicon.svg override chrome://mozapps/skin/extensions/extension.svg chrome://user_chrome_files/content/custom_styles/svg/extension.svg override chrome://global/skin/icons/settings.svg chrome://user_chrome_files/content/custom_styles/svg/settings.svg override chrome://mozapps/skin/extensions/extensionGeneric.svg chrome://user_chrome_files/content/custom_styles/svg/extension.svg override chrome://global/skin/icons/help.svg chrome://user_chrome_files/content/custom_styles/svg/help.svg override chrome://global/skin/icons/plugin.svg chrome://user_chrome_files/content/custom_styles/svg/pluginGeneric.svg override chrome://mozapps/skin/extensions/category-discover.svg chrome://user_chrome_files/content/custom_styles/svg/category-discover.svg override chrome://mozapps/skin/extensions/category-extensions.svg chrome://user_chrome_files/content/custom_styles/svg/category-extensions.svg override chrome://mozapps/skin/extensions/category-themes.svg chrome://user_chrome_files/content/custom_styles/svg/category-themes.svg override chrome://mozapps/skin/extensions/category-plugins.svg chrome://user_chrome_files/content/custom_styles/svg/category-plugins.svg override chrome://browser/skin/preferences/category-general.svg chrome://user_chrome_files/content/custom_styles/svg/settings.svg override chrome://browser/skin/home.svg chrome://user_chrome_files/content/custom_styles/svg/home.svg override chrome://browser/skin/preferences/category-search.svg chrome://user_chrome_files/content/custom_styles/svg/category-search.svg override chrome://browser/skin/preferences/category-privacy-security.svg chrome://user_chrome_files/content/custom_styles/svg/category-privacy-security.svg override chrome://browser/skin/preferences/category-experiments.svg chrome://user_chrome_files/content/custom_styles/svg/category-experiments.svg override chrome://global/skin/icons/more.svg chrome://user_chrome_files/content/custom_styles/svg/more.svg override chrome://global/skin/icons/folder.svg chrome://user_chrome_files/content/custom_styles/svg/folder.svg override chrome://browser/skin/places/folder.svg chrome://user_chrome_files/content/custom_styles/svg/folder.svg override chrome://global/skin/icons/arrow-dropdown-16.svg chrome://user_chrome_files/content/custom_styles/svg/arrow-dropdown-16.svg override chrome://browser/skin/history.svg chrome://user_chrome_files/content/custom_styles/svg/history.svg override chrome://global/skin/icons/chevron.svg chrome://user_chrome_files/content/custom_styles/svg/chevron.svg override chrome://browser/skin/menu.svg chrome://user_chrome_files/content/custom_styles/svg/menu.svg override chrome://global/skin/icons/page-portrait.svg chrome://global/skin/icons/info.svg override chrome://branding/content/icon16.png chrome://branding/content/identity-icons-brand.svg override chrome://browser/skin/controlcenter/tracking-protection.svg chrome://user_chrome_files/content/custom_styles/svg/tracking-protection.svg скрытый текст Выделить код Код:/* иконка щита "трекеры не обнаружены" */ #urlbar-input-container[pageproxystate="valid"] > #tracking-protection-icon-container > #tracking-protection-icon-box > #tracking-protection-icon { list-style-image: url(./svg/tracking-protection.svg) !important; fill-opacity: 0.6 !important; } /* иконка щита "блокируются трекеры" */ #urlbar-input-container[pageproxystate="valid"] > #tracking-protection-icon-container > #tracking-protection-icon-box:not([hasException])[active] > #tracking-protection-icon { display: block !important; background-image: url(./svg/tracking-protection-active.svg) !important; transform: translateX(-256px) !important; width: 272px !important; background-size: auto !important; height: 16px !important; min-height: 16px !important; -moz-context-properties: fill, fill-opacity !important; } /* зелёный замок */ #identity-box[pageproxystate="valid"].verifiedDomain #identity-icon, #identity-box[pageproxystate="valid"].mixedActiveBlocked #identity-icon { list-style-image: url(./svg/security.svg) !important; fill: #12BC00 !important; } /* зелёный замок в "информация о сайте" */ #identity-popup[connection^="secure"] .identity-popup-security-connection { background-image: url(./svg/security.svg) !important; fill: #12BC00 !important; } /* чёрный замок смешанного содержимого */ #identity-box[pageproxystate="valid"].weakCipher #identity-icon, #identity-box[pageproxystate="valid"].mixedDisplayContent #identity-icon, #identity-box[pageproxystate="valid"].mixedDisplayContentLoadedActiveBlocked #identity-icon, #identity-box[pageproxystate="valid"].certUserOverridden #identity-icon, #identity-box[pageproxystate="valid"].certErrorPage #identity-icon { list-style-image: url(./svg/security-warning.svg) !important; fill-opacity: 0.6 !important; } /* чёрный замок смешанного содержимого в "информация о сайте" */ #identity-popup[ciphers="weak"] .identity-popup-security-connection, #identity-popup[mixedcontent~="passive-loaded"][isbroken] .identity-popup-security-connection { background-image: url(./svg/security-warning.svg) !important; } /* зачёркнутый замок незащещённого содержимого */ #identity-box[pageproxystate="valid"].notSecure #identity-icon, #identity-box[pageproxystate="valid"].mixedActiveContent #identity-icon, #identity-box[pageproxystate="valid"].httpsOnlyErrorPage #identity-icon { list-style-image: url(./svg/security-broken.svg) !important; fill-opacity: 0.6 !important; } /* зачёркнутый замок незащещённого содержимого в "информация о сайте" */ .identity-popup-security-connection { background-image: url(./svg/security-broken.svg) !important; } /* значок дополнительных разрешений */ #permissions-granted-icon { list-style-image: url(./svg/permissions.svg) !important; fill-opacity: 0.6 !important; } /* значок запрета автовоспроизведения */ .autoplay-media-icon.blocked-permission-icon { list-style-image: url(./svg/autoplay-media-blocked.svg) !important; fill-opacity: 0.6 !important; } /* значок разрешённого автовоспроизведения */ .autoplay-media-icon { list-style-image: url(./svg/autoplay-media.svg) !important; fill-opacity: 0.6 !important; } /* кнопка "назад" */ #back-button { list-style-image: url("./svg/back.svg") !important; } /* кнопка "вперёд" */ #forward-button { list-style-image: url("./svg/forward.svg") !important; } /* значок "v" "показать историю" */ #urlbar .urlbar-history-dropmarker { /* list-style-image: url(./svg/arrow-dropdown-16.svg) !important; */ fill-opacity: 0.6 !important; } /* звёздочка в адресной строке */ #pageAction-panel-bookmark, #star-button { list-style-image: url("./svg/bookmark-hollow.svg") !important; fill-opacity: 0.6 !important; } #pageAction-panel-bookmark[starred], #star-button[starred] { list-style-image: url("./svg/bookmark.svg") !important; fill-opacity: 1 !important; } /* прозрачность значка "копироать ссылку" */ #pageAction-urlbar-ucf-copyURL .urlbar-icon { fill-opacity: .6 !important; } |
kokoss > 07-07-2021 19:40:52 |
Скрипты для custom_script.js: скрипт Выделить код Код:(async () => { var id = "ucf-toggle-tooltip-url", label = "Тултипы с URL", tooltiptext = "Переключить тултипы", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' style='fill:context-fill rgb(142, 142, 152);'><path d='M9.618 6.721a2.483 2.483 0 0 0-.39-.317l-.735.734A1.486 1.486 0 0 1 8.91 9.55l-2.12 2.122a1.486 1.486 0 0 1-2.122 0 1.486 1.486 0 0 1 0-2.121l.605-.605a3.53 3.53 0 0 1-.206-1.209L3.961 8.843a2.506 2.506 0 0 0 0 3.535 2.506 2.506 0 0 0 3.535 0l2.122-2.121a2.506 2.506 0 0 0 0-3.536z'/><path d='M6.79 9.55c.12.121.25.226.389.317l.734-.734a1.486 1.486 0 0 1-.417-2.411L9.618 4.6a1.486 1.486 0 0 1 2.121 0 1.486 1.486 0 0 1 0 2.121l-.605.605c.137.391.211.798.206 1.209l1.106-1.107a2.506 2.506 0 0 0 0-3.535 2.506 2.506 0 0 0-3.535 0L6.789 6.014a2.506 2.506 0 0 0 0 3.536z'/><circle style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round' cx='8' cy='8' r='7.4'/></svg>", imgcolordisable = "color-mix(in srgb, currentColor 20%, #e31b5d)"; var branch = "extensions.ucf.", pref = "tooltip_url_enable"; var tpurl = { initialised: false, tooltip_url_enable: true, get ext_branch() { delete this.ext_branch; return this.ext_branch = Services.prefs.getBranch(branch); }, init() { if (this.initialised) return; Services.prefs.getDefaultBranch(branch).setBoolPref(pref, true); Services.prefs.addObserver(`${branch}${pref}`, this); if (this.tooltip_url_enable = this.ext_branch.getBoolPref(pref)) this.registerActor(); this.initialised = true; }, observe(subject, topic, data) { var fill = ""; if ((this.tooltip_url_enable = this.ext_branch.getBoolPref(pref)) === true) this.registerActor(); else { fill = imgcolordisable; this.unregisterActor(); } this.callWithEachWindow(id, {fill: fill}); }, 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]); } }, registerActor() { ChromeUtils.registerWindowActor("UcfTooltipUrl", { child: { moduleURI: "chrome://user_chrome_files/content/custom_scripts/Ucf_TooltipUrlChild.jsm", events: { mouseover: { capture: true }, }, }, allFrames: true, matches: ["<all_urls>"], messageManagerGroups: ["browsers"], }); }, unregisterActor() { ChromeUtils.unregisterWindowActor("UcfTooltipUrl"); }, }; CustomizableUI.createWidget({ id: id, label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { tpurl.init(); btn.style.setProperty("list-style-image", `url("${img}")`, "important"); if (!tpurl.tooltip_url_enable) btn.style.setProperty("fill", imgcolordisable); }, onCommand(e) { tpurl.ext_branch.setBoolPref(pref, !tpurl.ext_branch.getBoolPref(pref)); }, }); })(); ucf_TooltipUrlChild.jsm Выделить код Код:var EXPORTED_SYMBOLS = ["UcfTooltipUrlChild"]; ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); class UcfTooltipUrlChild extends JSWindowActorChild { handleEvent(e) { timer.cancel(); timer.initWithCallback(() => { var elm = e.isTrusted && e.composedTarget, el, titl; if (!elm) return; do { if (!elm.matches) continue; if (elm.matches(":any-link")) { if (elm.matches("[href='#'], [href^='javascript']")) return; el = elm; if (elm.matches("[title]")) titl = elm; else while (elm = elm.flattenedTreeParentNode) { if (!elm.matches) continue; if (elm.matches("[title]")) { titl = elm; break; } } break; } if (elm.matches("[title]")) { titl = elm; while (elm = elm.flattenedTreeParentNode) { if (!elm.matches) continue; if (elm.matches(":any-link")) { if (elm.matches("[href='#'], [href^='javascript']")) return; el = elm; break; } } break; } } while (elm = elm.flattenedTreeParentNode); if (!el) return; var href = el.href; if (titl) el = titl; titl = (el.title || ""); var title = titl.trim(), pre = "", path = ""; try { href = Services.io.newURI(href); pre = href.displayPrePath; path = `\n${href.pathQueryRef}`; if (path === "\n/") path = ""; href = `${pre}${path}`; } catch (e) {} try { href = decodeURIComponent(href); } catch (e) {} el.title = title = `${href}${title === "" ? "" : `\nTitle: ${title}`}`; this.contentWindow.addEventListener("mouseout", () => { try { if (!el || title !== el.title) return; if (titl !== "") el.title = titl; else el.removeAttribute("title"); } catch (e) {} }, { once: true }); }, 400, Ci.nsITimer.TYPE_ONE_SHOT); } didDestroy() { timer.cancel(); } } Proxy: https://forum.mozilla-russia.org/viewto … 94#p782794; Скрипты для custom_script_win.js: |
_zt > 13-07-2021 01:34:33 |
UndoBookmarksContextMenu - пункты контекстного меню закладок "вернуть\повторить удаление" (закладки) скрытый текст // ==UserScript== // @name s_UndoBookmarksContextMenu // @namespace http://space.geocities.yahoo.co.jp/gl/alice0775 // @include * // @compatibility Firefox 60 // @author alice0775 // @version 2019/11/20 23:00 fix redeclaration error // @version 2019/07/10 10:00 fix 70 Bug 1558914 - Disable Array generics in Nightly // @version 2018/10/04 20:00 remove conflict shortcuts key for main window // @version 2018/10/04 60+ // ==/UserScript== if (typeof window.undobookmarksmenu == "undefined") { window.undobookmarksmenu = { popup: null, handleEvent: function(event) { init: function() { let ref = document.getElementById("placesContext_deleteSeparator"); uninit: function() { popupshown: function(event){ jsonToDOM: function(jsonTemplate, doc, nodes) { // Note that 'elemNameOrArray' is: either the full element name (eg. [html:]div) or an array of elements in JSON notation // Single element? Parse element namespace prefix (if none exists, default to defaultNamespace), and create element // Set element's attributes and/or callback functions (eg. onclick) var attrNs = namespace(key); // Create and append this element's children return jsonToDOM(jsonTemplate, doc, nodes); window.undobookmarksmenu.init(); |
_zt > 16-07-2021 16:50:17 |
Кнопка для Attributes_Inspector от Dumby скрытый текст Выделить код Код:// Открытие окна "Инструменты браузера" // по ПКМ на иконке Attributes Inspector // Создано по шаблонам, где то здесь - // https://forum.mozilla-russia.org/viewtopic.php?pid=791976#p791976 (this.opendevtoolsrclick3 = { async init(that) { await window.delayedStartupPromise; var btn = CustomizableUI.getWidget("AttributesInspector")?.forWindow(window).node; if (!btn) return; btn.setAttribute("context", ""); btn.tooltipText = `ЛКМ: Attributes Inspector\nПКМ: Инструменты браузера`; var listener = e => { if (e.button != 2) return; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); var pref = Services.prefs, chr = "devtools.chrome.enabled", rem = "devtools.debugger.remote-enabled"; if (!pref.getBoolPref(chr) || !pref.getBoolPref(rem)) { pref.setBoolPref(chr, true); pref.setBoolPref(rem, true); } var { BrowserToolboxLauncher } = ChromeUtils.import("resource://devtools/client/framework/browser-toolbox/Launcher.jsm"); BrowserToolboxLauncher.init(); }; btn.addEventListener("click", listener); that.unloadlisteners.push("opendevtoolsrclick3"); this.destructor = () => { btn.removeEventListener("click", listener); }; } }).init(this); Строка загрузки - loadscript("subfolder/script_file_name.uc.js", this); или loadscript("script_file_name.uc.js", this); |
sandro79 > 18-07-2021 20:56:13 |
Vitaliy V. скрытый текст Выделить код Код:.bookmark-item:not([container])[image^='page-icon:https://yandex.ru/'] image { object-position: 16px 0px !important; list-style-image: none !important; background: url("./svg/yandex.ico") transparent center no-repeat !important; } Я использую этот скрипт для отображения фавикона в строке адреса, но наверно он там же считывает иконку, где и Ваш faviconinurlbar. Может можно что-то придумать. Ещё поменял на NNM сразу на трёх адресах, там у них вообще странно, если масштаб страницы 100%, то отображается одна бабочка(нормальная), повёрнутая вправо, а если ставлю больше масштаб(133% использую почти везде), то уже другая. Мелочи это всё конечно, но как-то это нелогично, в slimjet с бабочкой такой проблемы нет, а в давненько уже. скрытый текст Войдите или зарегистрируйтесь, чтобы увидеть скрытый текст. Выделить код Код:.bookmark-item:not([container]):is([image^='page-icon:https://nnm-club.me/'], [image^='page-icon:https://nnmclub.ro/'], [image^='page-icon:https://nnmclub.to/']) image { object-position: 16px 0px !important; list-style-image: none !important; background: url("./svg/nnmclub.ico") transparent center no-repeat !important; } |
Vitaliy V. > 19-07-2021 20:28:58 |
sandro79 пишет
Это скрипты для сайтов, для этого есть Greasemonkey и т.д. sandro79 пишет
Естественно со страницы сайта по ссылке например Ладно попробую но только потому что в Greasemonkey не сработают некоторые события. скрытый текст Выделить код Код:ChromeUtils.registerWindowActor("LinkWinActor", { child: { moduleURI: "chrome://user_chrome_files/content/custom_scripts/LinkWinActorChild.jsm", events: { DOMLinkAdded: { capture: true }, DOMLinkChanged: {}, DOMHeadElementParsed: {}, pageshow: {}, }, }, messageManagerGroups: ["browsers"], matches: [ // адреса где работает скрипт "https://yandex.ru/", "https://yandex.ru/?*", "https://yandex.ru/search/*", "https://passport.yandex.ru/*", "https://nnmclub.to/*", "about:config", "about:user-chrome-files", ], }); LinkWinActorChild.jsm скрытый текст Выделить код Код:var EXPORTED_SYMBOLS = ["LinkWinActorChild"]; ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); const LINK_SELECTOR = "link[href]:is([rel~='icon'],[rel~='apple-touch-icon'],[rel~='apple-touch-icon-precomposed'],[rel~='fluid-icon'],[rel~='mask-icon'])"; const ICONS = { // "домен, или адрес для about|chrome|resource": "иконка", "yandex.ru": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><rect rx='2' ry='2' width='16' height='16' style='fill:rgb(231, 43, 90);'/><path d='M 8.56,2 C 6.31,2 4.49,3.5 4.49,5.99 4.49,7.49 5.31,8.48 6.97,9.57 L 4,13.5 V 14 H 5.76 L 8.53,9.57 H 9.47 V 14 H 11 V 2 Z M 9.47,8.48 H 8.67 C 7.36,8.48 6.05,7.98 6.05,5.99 6.05,4 7.26,3 8.47,3 H 9.47 Z' style='fill:white;'/></g></svg>", "nnmclub.to": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><path d='M 0.887,0 C 0.54,0.14 0.289,0.279 0.135,0.711 0.051,0.851 0.015,0.991 0,1.27 -0.009,1.71 0.061,2.16 0.325,3.05 0.564,3.88 0.612,4.12 0.612,4.37 0.612,4.48 0.612,4.56 0.588,4.67 0.457,5.43 0.457,6.07 0.588,6.56 0.672,6.87 0.779,7.09 0.947,7.28 1.21,7.57 1.49,7.73 2.05,7.87 L 2.27,7.91 2.11,7.96 C 1.87,8.01 1.71,8.08 1.55,8.19 1.33,8.31 1.22,8.41 1.09,8.59 0.947,8.65 0.887,8.83 0.839,8.99 0.803,9.17 0.792,9.41 0.827,9.65 0.851,9.93 0.851,9.93 0.827,10 0.827,10.1 0.767,10.3 0.708,10.5 0.588,10.9 0.564,11.1 0.564,11.2 0.564,11.5 0.612,11.6 0.875,11.8 1.15,12.2 1.18,12.3 1.15,12.6 1.1,13.2 1.18,13.6 1.39,13.7 1.49,13.7 1.6,13.9 1.75,14 1.93,14 2.05,14.1 2.28,14.4 2.48,14.5 2.55,14.5 2.64,14.5 2.73,14.7 2.73,14.7 2.87,14.7 3.04,14.7 3.04,14.7 3.47,14.5 4.03,14 4.19,13.9 4.44,13.9 4.55,13.7 4.6,13.7 4.68,13.7 4.88,13.6 5.11,13 5.35,11.9 5.39,11.8 5.43,11.6 5.47,11.5 5.65,10.9 5.89,10.4 6.12,10 6.24,9.83 6.48,9.59 6.49,9.59 6.49,9.59 6.49,9.75 6.48,10.1 6.44,10.3 6.43,10.5 6.28,11.1 6.12,11.5 6.08,11.7 6.05,12 6.03,12.4 6.11,12.6 6.21,12.9 6.32,13 6.43,13 6.57,13 6.71,12.9 6.81,12.6 6.91,12.4 7.07,12 7.11,11.7 7.11,11 7.11,10.7 7.13,10.4 7.27,10 7.35,9.75 7.32,9.75 7.37,9.83 7.52,10.1 7.64,10.7 7.69,11.3 7.72,11.6 7.72,12.2 7.69,12.4 7.64,13 7.61,13.6 7.68,14 7.72,14.4 7.76,14.5 8.01,14.5 8.15,14.7 8.31,14.8 8.67,15.5 8.92,15.9 9.03,15.9 9.11,16 9.17,16 9.17,16 9.33,16 9.52,16 9.52,16 9.77,15.9 10.1,15.7 10.1,15.7 10.4,15.7 10.7,15.7 10.7,15.7 10.7,15.7 11,15.6 11.1,15.5 11.4,14.9 11.4,14.9 11.4,14.8 11.5,14.7 11.5,14.5 11.6,14.4 11.7,14.1 12.2,13.9 12.2,13.9 12.2,13.7 12.4,13.6 12.4,13.6 12.4,13 12.4,12.6 12.5,12.4 12.5,12.3 12.5,12.3 12.5,12.2 12.7,12 12.8,11.7 12.8,11.6 12.8,11.5 12.8,11.2 12.8,11.1 12.8,11.1 12.7,10.7 12.4,10.3 12,9.93 11.9,9.83 11.9,9.83 11.9,9.83 12.2,9.93 12.7,9.93 12.9,9.93 13.7,9.75 14,9.08 14.1,7.84 14.1,7.76 14.3,7.59 14.3,7.49 14.3,7.27 14.3,7.19 14.5,7.01 14.5,6.83 14.8,6.6 15.1,6.19 15.7,5.24 15.9,4.85 16,4.41 16,4.31 16,4.25 16,4.03 16,3.84 16,3.76 16,3.69 15.7,3.03 15.2,2.68 14.3,2.75 13.7,2.76 13,2.97 12.2,3.32 12,3.4 11.6,3.63 11.4,3.81 10.2,4.49 9.11,5.55 8.08,6.85 7.95,7 7.85,7.11 7.85,7.11 7.85,7.11 7.84,7.05 7.84,7.04 7.76,6.93 7.72,6.87 7.61,6.81 L 7.53,6.73 7.64,6.47 C 7.92,5.92 8.13,5.51 8.31,5.23 8.35,5.12 8.51,4.91 8.76,4.63 9.43,3.73 9.68,3.47 9.77,3.35 10,3.21 10,3.2 10,3.15 10.1,3.05 10,2.92 10,2.87 9.95,2.87 9.95,2.91 9.84,2.97 9.84,3.11 9.52,3.44 9.11,4.03 8.92,4.19 8.76,4.37 8.76,4.45 8.35,4.95 7.95,5.69 7.61,6.47 7.53,6.6 7.49,6.73 7.47,6.73 7.47,6.73 7.43,6.71 7.37,6.71 L 7.28,6.68 V 6.59 C 7.2,5.69 7.08,5.08 6.91,4.49 6.83,4.16 6.8,4 6.59,3.44 6.33,2.75 6.2,2.32 6.2,2.21 6.17,2.09 6.05,2.08 6,2.2 5.97,2.31 5.99,2.39 6.11,2.55 6.21,2.75 6.32,2.97 6.73,4.15 7,4.96 7.07,5.13 7.2,6.29 7.23,6.68 7.23,6.68 7.2,6.68 7.13,6.68 6.97,6.75 6.89,6.83 6.83,6.87 6.81,6.89 6.81,6.89 6.81,6.89 6.75,6.73 6.68,6.56 6.53,6.07 6.4,5.77 6.2,5.27 5.36,3.43 4.39,2.01 3.36,1.13 2.64,0.571 2.01,0.14 1.49,0 1.32,0 1.02,0 0.887,0 Z' style='fill:rgb(0, 140, 255);stroke:black;stroke-width:0.6;stroke-linejoin:round;stroke-linecap:round;'/></g></svg>", "about:config": "chrome://global/skin/icons/settings.svg", "about:user-chrome-files": "chrome://global/skin/icons/settings.svg", }; class LinkWinActorChild extends JSWindowActorChild { actorCreated() { var docURI = this.document.documentURIObject, host; if (!/^(?:about|chrome|resource)$/.test(docURI.scheme)) try { let baseDomain = Services.eTLD.getBaseDomain(docURI); host = Cc["@mozilla.org/network/idn-service;1"].getService(Ci.nsIIDNService) .convertToDisplayIDN(baseDomain, {}); } catch (e) { try { host = docURI.displayHost; } catch (e) { host = docURI.specIgnoringRef; } } else host = docURI.specIgnoringRef; var icon = ICONS[host]; if (!icon) { this.handleEvent = e => {}; return; } this._icon = icon; this.onHeadParsed(this.document.head); } onHeadParsed(target) { for (let link of target.querySelectorAll(LINK_SELECTOR)) link.remove(); var link = this.document.createElement("link"); link.setAttribute("rel", "icon"); link.setAttribute("sizes", "any"); link.setAttribute("href", this._icon); target.append(link); } onLinkEvent(link) { if (!link.matches(LINK_SELECTOR) || link.href == this._icon) return; link.href = this._icon; link.setAttribute("rel", "icon"); link.setAttribute("sizes", "any"); if (link.hasAttribute("type")) link.removeAttribute("type"); } handleEvent(e) { switch (e.type) { case "DOMLinkAdded": case "DOMLinkChanged": this.onLinkEvent(e.target); break; case "pageshow": this.onHeadParsed(e.target.head); break; } } } Или вариант поддомен + домен, для тех кому надо устанавливать разные иконки для поддоменов скрытый текст Выделить код Код:var EXPORTED_SYMBOLS = ["LinkWinActorChild"]; ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); const LINK_SELECTOR = "link[href]:is([rel~='icon'],[rel~='apple-touch-icon'],[rel~='apple-touch-icon-precomposed'],[rel~='fluid-icon'],[rel~='mask-icon'])"; const ICONS = { // "поддомен + домен, или адрес для about|chrome|resource": "иконка", "yandex.ru": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><rect rx='2' ry='2' width='16' height='16' style='fill:rgb(231, 43, 90);'/><path d='M 8.56,2 C 6.31,2 4.49,3.5 4.49,5.99 4.49,7.49 5.31,8.48 6.97,9.57 L 4,13.5 V 14 H 5.76 L 8.53,9.57 H 9.47 V 14 H 11 V 2 Z M 9.47,8.48 H 8.67 C 7.36,8.48 6.05,7.98 6.05,5.99 6.05,4 7.26,3 8.47,3 H 9.47 Z' style='fill:white;'/></g></svg>", get "passport.yandex.ru"() { return this["yandex.ru"]; }, "nnmclub.to": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><path d='M 0.887,0 C 0.54,0.14 0.289,0.279 0.135,0.711 0.051,0.851 0.015,0.991 0,1.27 -0.009,1.71 0.061,2.16 0.325,3.05 0.564,3.88 0.612,4.12 0.612,4.37 0.612,4.48 0.612,4.56 0.588,4.67 0.457,5.43 0.457,6.07 0.588,6.56 0.672,6.87 0.779,7.09 0.947,7.28 1.21,7.57 1.49,7.73 2.05,7.87 L 2.27,7.91 2.11,7.96 C 1.87,8.01 1.71,8.08 1.55,8.19 1.33,8.31 1.22,8.41 1.09,8.59 0.947,8.65 0.887,8.83 0.839,8.99 0.803,9.17 0.792,9.41 0.827,9.65 0.851,9.93 0.851,9.93 0.827,10 0.827,10.1 0.767,10.3 0.708,10.5 0.588,10.9 0.564,11.1 0.564,11.2 0.564,11.5 0.612,11.6 0.875,11.8 1.15,12.2 1.18,12.3 1.15,12.6 1.1,13.2 1.18,13.6 1.39,13.7 1.49,13.7 1.6,13.9 1.75,14 1.93,14 2.05,14.1 2.28,14.4 2.48,14.5 2.55,14.5 2.64,14.5 2.73,14.7 2.73,14.7 2.87,14.7 3.04,14.7 3.04,14.7 3.47,14.5 4.03,14 4.19,13.9 4.44,13.9 4.55,13.7 4.6,13.7 4.68,13.7 4.88,13.6 5.11,13 5.35,11.9 5.39,11.8 5.43,11.6 5.47,11.5 5.65,10.9 5.89,10.4 6.12,10 6.24,9.83 6.48,9.59 6.49,9.59 6.49,9.59 6.49,9.75 6.48,10.1 6.44,10.3 6.43,10.5 6.28,11.1 6.12,11.5 6.08,11.7 6.05,12 6.03,12.4 6.11,12.6 6.21,12.9 6.32,13 6.43,13 6.57,13 6.71,12.9 6.81,12.6 6.91,12.4 7.07,12 7.11,11.7 7.11,11 7.11,10.7 7.13,10.4 7.27,10 7.35,9.75 7.32,9.75 7.37,9.83 7.52,10.1 7.64,10.7 7.69,11.3 7.72,11.6 7.72,12.2 7.69,12.4 7.64,13 7.61,13.6 7.68,14 7.72,14.4 7.76,14.5 8.01,14.5 8.15,14.7 8.31,14.8 8.67,15.5 8.92,15.9 9.03,15.9 9.11,16 9.17,16 9.17,16 9.33,16 9.52,16 9.52,16 9.77,15.9 10.1,15.7 10.1,15.7 10.4,15.7 10.7,15.7 10.7,15.7 10.7,15.7 11,15.6 11.1,15.5 11.4,14.9 11.4,14.9 11.4,14.8 11.5,14.7 11.5,14.5 11.6,14.4 11.7,14.1 12.2,13.9 12.2,13.9 12.2,13.7 12.4,13.6 12.4,13.6 12.4,13 12.4,12.6 12.5,12.4 12.5,12.3 12.5,12.3 12.5,12.2 12.7,12 12.8,11.7 12.8,11.6 12.8,11.5 12.8,11.2 12.8,11.1 12.8,11.1 12.7,10.7 12.4,10.3 12,9.93 11.9,9.83 11.9,9.83 11.9,9.83 12.2,9.93 12.7,9.93 12.9,9.93 13.7,9.75 14,9.08 14.1,7.84 14.1,7.76 14.3,7.59 14.3,7.49 14.3,7.27 14.3,7.19 14.5,7.01 14.5,6.83 14.8,6.6 15.1,6.19 15.7,5.24 15.9,4.85 16,4.41 16,4.31 16,4.25 16,4.03 16,3.84 16,3.76 16,3.69 15.7,3.03 15.2,2.68 14.3,2.75 13.7,2.76 13,2.97 12.2,3.32 12,3.4 11.6,3.63 11.4,3.81 10.2,4.49 9.11,5.55 8.08,6.85 7.95,7 7.85,7.11 7.85,7.11 7.85,7.11 7.84,7.05 7.84,7.04 7.76,6.93 7.72,6.87 7.61,6.81 L 7.53,6.73 7.64,6.47 C 7.92,5.92 8.13,5.51 8.31,5.23 8.35,5.12 8.51,4.91 8.76,4.63 9.43,3.73 9.68,3.47 9.77,3.35 10,3.21 10,3.2 10,3.15 10.1,3.05 10,2.92 10,2.87 9.95,2.87 9.95,2.91 9.84,2.97 9.84,3.11 9.52,3.44 9.11,4.03 8.92,4.19 8.76,4.37 8.76,4.45 8.35,4.95 7.95,5.69 7.61,6.47 7.53,6.6 7.49,6.73 7.47,6.73 7.47,6.73 7.43,6.71 7.37,6.71 L 7.28,6.68 V 6.59 C 7.2,5.69 7.08,5.08 6.91,4.49 6.83,4.16 6.8,4 6.59,3.44 6.33,2.75 6.2,2.32 6.2,2.21 6.17,2.09 6.05,2.08 6,2.2 5.97,2.31 5.99,2.39 6.11,2.55 6.21,2.75 6.32,2.97 6.73,4.15 7,4.96 7.07,5.13 7.2,6.29 7.23,6.68 7.23,6.68 7.2,6.68 7.13,6.68 6.97,6.75 6.89,6.83 6.83,6.87 6.81,6.89 6.81,6.89 6.81,6.89 6.75,6.73 6.68,6.56 6.53,6.07 6.4,5.77 6.2,5.27 5.36,3.43 4.39,2.01 3.36,1.13 2.64,0.571 2.01,0.14 1.49,0 1.32,0 1.02,0 0.887,0 Z' style='fill:rgb(0, 140, 255);stroke:black;stroke-width:0.6;stroke-linejoin:round;stroke-linecap:round;'/></g></svg>", "about:config": "chrome://global/skin/icons/settings.svg", "about:user-chrome-files": "chrome://global/skin/icons/settings.svg", }; class LinkWinActorChild extends JSWindowActorChild { actorCreated() { var docURI = this.document.documentURIObject, host; if (!/^(?:about|chrome|resource)$/.test(docURI.scheme)) try { host = docURI.displayHost; } catch (e) { host = docURI.specIgnoringRef; } else host = docURI.specIgnoringRef; var icon = ICONS[host]; if (!icon) { this.handleEvent = e => {}; return; } this._icon = icon; this.onHeadParsed(this.document.head); } onHeadParsed(target) { for (let link of target.querySelectorAll(LINK_SELECTOR)) link.remove(); var link = this.document.createElement("link"); link.setAttribute("rel", "icon"); link.setAttribute("sizes", "any"); link.setAttribute("href", this._icon); target.append(link); } onLinkEvent(link) { if (!link.matches(LINK_SELECTOR) || link.href == this._icon) return; link.href = this._icon; link.setAttribute("rel", "icon"); link.setAttribute("sizes", "any"); if (link.hasAttribute("type")) link.removeAttribute("type"); } handleEvent(e) { switch (e.type) { case "DOMLinkAdded": case "DOMLinkChanged": this.onLinkEvent(e.target); break; case "pageshow": this.onHeadParsed(e.target.head); break; } } } sandro79 пишет
Этот скрипт ужасен, что вы в нем нашли? |
sandro79 > 19-07-2021 21:35:55 |
Vitaliy V. пишет
Виталий, ну Вы Мастер!!! Я думал там попроще будет, как с иконкой поисковика примерно.
Да, я вижу его недостатки, скорее всего поверхностно, но плюс в том, что он мне подходит тем, что на месте скрытой стилем лупы в строке адреса, он ставит значок на странице about:newtab, также расположение фавикона мне привычней (ну этим можно и пожертвовать), с тех пор как пользуюсь этим скриптом, с 60 какой-то версии. И плюс ещё, что фавикон в строке адреса при навигации в пределах страницы, обновлении страницы - всегда отображается и не исчезает. Если бы в Вашем скрипте фавикон не менялся на identity-icon пока находишься на странице - обновляешь, по ссылкам ходишь, я бы его использовал конечно, но постоянное обновление фавикона, ну мне не подходит. Я вижу недостатки в используемом мной скрипте, насколько фавикон жёстко привязан к высоте адресной строки, чуть размер строки другой, растягивается или сжимается, подбирать вручную нужно правкой скрипта. Но я настроил под свой режим и пойдёт пока. |
Dumby > 20-07-2021 00:43:08 |
Vitaliy V. Если я правильно понимаю, то лисий LinkHandlerChild А LinkWinActorChild зачем их слушает? |
Vitaliy V. > 20-07-2021 12:46:43 |
Dumby |
Vitaliy V. > 20-07-2021 13:28:48 |
sandro79 пишет
Это не постоянное обновление, если говорить об этом то ваш скрипт обновляет её намного чаще, когда это и не нужно. sandro79 пишет
что требуется удалить для этого Выделить код Код:#urlbar:not(.searchButton) #identity-box[pageproxystate="invalid"].localResource #identity-faviconinurlbar[faviconchrome="true"] { display: -moz-inline-box !important; } |
Dumby > 20-07-2021 13:50:20 |
Vitaliy V. пишет
О как! Принято, тогда действительно стоит прогонять ещё раз, на всякий случай. |
kokoss > 20-07-2021 14:34:34 |
sandro79 пишет
Можно не скрывая подставить другую иконку, например так: скрытый текст Выделить код Код:#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] #identity-icon { list-style-image: url("chrome://branding/content/about-logo.svg") !important; } |
sandro79 > 20-07-2021 15:22:09 |
Vitaliy V. пишет
Да, это сработало.
А это не сработало. Добавление в конце css кода тоже нет. Да я может не совсем правильно поставил задачу, не знаю даже. Скрины выложу. Вот на about:newtab у него как и на служебных страницах тоже добавляются значки, может можно так сделать, а так теперь фавикон не мелькает скрытый текст скрытый текст Выделить код Код:(this.faviconinurlbar = { init(that) { var identity = document.querySelector("#identity-icon"); if (!identity) return; var iconDefault = "chrome://branding/content/identity-icons-brand.svg"; // или свою иконку var style = "data:text/css;charset=utf-8," + encodeURIComponent(` #identity-faviconinurlbar { --v-faviconinurlbar-default: url("${iconDefault}"); list-style-image: var(--v-faviconinurlbar, none) !important; pointer-events: none !important; height: 16px !important; width: auto !important; margin-inline-start: 4px !important; -moz-context-properties: fill, fill-opacity; fill: currentColor; fill-opacity: var(--urlbar-icon-fill-opacity, 1); } #identity-faviconinurlbar:not([faviconinurlbar="true"]) { --v-faviconinurlbar: var(--v-faviconinurlbar-default) !important; } #urlbar[actiontype="extension"] #identity-faviconinurlbar, #identity-box:is(.extensionPage,.chromeUI,.localResource) #identity-faviconinurlbar { display: none !important; } `); windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); var faviconinurlbar = document.createXULElement("image"); faviconinurlbar.id = "identity-faviconinurlbar"; identity.after(faviconinurlbar); gBrowser.tabContainer.addEventListener("TabAttrModified", this); gBrowser.addProgressListener(this); that.unloadlisteners.push("faviconinurlbar"); var {STATE_START, STATE_STOP, STATE_IS_NETWORK} = Ci.nsIWebProgressListener; var updatefavicon = image => { if (image) { faviconinurlbar.style.setProperty("--v-faviconinurlbar", `url("${image}")`); faviconinurlbar.setAttribute("faviconinurlbar", "true"); faviconinurlbar.setAttribute("faviconchrome", `${image.startsWith("chrome:")}`); } else { faviconinurlbar.setAttribute("faviconinurlbar", "false"); faviconinurlbar.style.setProperty("--v-faviconinurlbar", ""); } }; this.handleEvent = e => { var tab = e.target, changed; if (!tab.selected || !((changed = e.detail.changed).includes("image") || changed.includes("selected"))) return; updatefavicon(tab.image); }; this.onStateChange = (aWebProgress, aRequest, aStateFlags, aStatus) => { if (aStateFlags & STATE_IS_NETWORK && aWebProgress?.isTopLevel) { if (aStateFlags & STATE_START) faviconinurlbar.setAttribute("favbusy", "true"); else if (aStateFlags & STATE_STOP) { faviconinurlbar.setAttribute("favbusy", "false"); updatefavicon(gBrowser.selectedTab.image); } } }; }, destructor() { gBrowser.tabContainer.removeEventListener("TabAttrModified", this); gBrowser.removeProgressListener(this); } }).init(this); kokoss пишет
Да, спасибо. Я знаю как подобные иконки менять Но как вариант да, сойдет. |
kokoss > 20-07-2021 15:27:25 |
sandro79 пишет
Я и не сомневался, но может кому нибудь ещё пригодится |
Vitaliy V. > 20-07-2021 15:38:01 |
sandro79 пишет
я ещё писал про ,.localResource |
sandro79 > 20-07-2021 16:12:53 |
Vitaliy V. пишет
Вот же ж, всё-таки недоглядел я, запутался.
Да, я неправильно сформулировал задачу, не упомянув о служебных страницах, извиняюсь. скрытый текст Выделить код Код:#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] > #identity-icon-box { display: none !important; } Ну я понял, тут дело в том как, к чему привязан что ли вафикон в разных скриптах, технически не знаю как сформулировать. Ну тут похоже надо больше переделывать. kokoss пишет
Конечно, любой рабочий код будет полезен. |
Vitaliy V. > 20-07-2021 16:30:09 |
sandro79 пишет
Нет дело не в этом, просто нужно скрывать #identity-icon а не контейнер скрытый текст Выделить код Код:#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] #identity-icon { display: none !important; } |
sandro79 > 20-07-2021 16:54:23 |
Vitaliy V. пишет
Огромное Вам спасибо! Теперь всё отлично! скрытый текст Здесь оставлю коды скрипта и стиля, как резерв скрытый текст Выделить код Код:(this.faviconinurlbar = { init(that) { var identity = document.querySelector("#identity-icon"); if (!identity) return; var iconDefault = "chrome://global/skin/icons/info.svg"; // или свою иконку var style = "data:text/css;charset=utf-8," + encodeURIComponent(` #identity-faviconinurlbar { --v-faviconinurlbar-default: url("${iconDefault}"); list-style-image: var(--v-faviconinurlbar, none) !important; pointer-events: none !important; height: 16px !important; width: auto !important; margin-inline-start: 4px !important; -moz-context-properties: fill, fill-opacity; fill: currentColor; fill-opacity: var(--urlbar-icon-fill-opacity, 1); } #identity-faviconinurlbar:not([faviconinurlbar="true"]) { --v-faviconinurlbar: var(--v-faviconinurlbar-default) !important; } `); windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); var faviconinurlbar = document.createXULElement("image"); faviconinurlbar.id = "identity-faviconinurlbar"; identity.after(faviconinurlbar); gBrowser.tabContainer.addEventListener("TabAttrModified", this); gBrowser.addProgressListener(this); that.unloadlisteners.push("faviconinurlbar"); var {STATE_START, STATE_STOP, STATE_IS_NETWORK} = Ci.nsIWebProgressListener; var updatefavicon = image => { if (image) { faviconinurlbar.style.setProperty("--v-faviconinurlbar", `url("${image}")`); faviconinurlbar.setAttribute("faviconinurlbar", "true"); faviconinurlbar.setAttribute("faviconchrome", `${image.startsWith("chrome:")}`); } else { faviconinurlbar.setAttribute("faviconinurlbar", "false"); faviconinurlbar.style.setProperty("--v-faviconinurlbar", ""); } }; this.handleEvent = e => { var tab = e.target, changed; if (!tab.selected || !((changed = e.detail.changed).includes("image") || changed.includes("selected"))) return; updatefavicon(tab.image); }; this.onStateChange = (aWebProgress, aRequest, aStateFlags, aStatus) => { if (aStateFlags & STATE_IS_NETWORK && aWebProgress?.isTopLevel) { if (aStateFlags & STATE_START) faviconinurlbar.setAttribute("favbusy", "true"); else if (aStateFlags & STATE_STOP) { faviconinurlbar.setAttribute("favbusy", "false"); updatefavicon(gBrowser.selectedTab.image); } } }; }, destructor() { gBrowser.tabContainer.removeEventListener("TabAttrModified", this); gBrowser.removeProgressListener(this); } }).init(this); скрытый текст Выделить код Код:#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] #identity-icon { display: none !important; } |
Vitaliy V. > 20-07-2021 17:17:06 |
sandro79 пишет
Не думаете же вы что это сложно изменить, вот даже стилем можно ну или вместо -moz-box-ordinal-group: 0 !important; |
sandro79 > 20-07-2021 17:41:21 |
Vitaliy V. пишет
Да, я собирался вообще попробовать, но что-то подумал, что там жёстко у Вас фавикон привязан, и вообще решил не трогать, оставить оригинальное расположение.
А так вообще великолепно! Спасибо! Только замок от фавикона чуть отодвину стилем, это я уже сам. скрытый текст |
sandro79 > 20-07-2021 20:48:04 |
Vitaliy V. скрытый текст Окончательный вариант скрипта, добавил в скрипт css-коды с предыдущих сообщений скрытый текст Выделить код Код:(this.faviconinurlbar = { init(that) { var identity = document.querySelector("#identity-icon"); if (!identity) return; var iconDefault = "chrome://global/skin/icons/defaultFavicon.svg"; // или свою иконку var style = "data:text/css;charset=utf-8," + encodeURIComponent(` #identity-faviconinurlbar { --v-faviconinurlbar-default: url("${iconDefault}"); list-style-image: var(--v-faviconinurlbar, none) !important; pointer-events: none !important; height: 16px !important; width: 16px !important; margin-inline-start: 3px !important; -moz-context-properties: fill, fill-opacity; fill: currentColor; fill-opacity: var(--urlbar-icon-fill-opacity, 1); } #identity-faviconinurlbar:not([faviconinurlbar="true"]) { --v-faviconinurlbar: var(--v-faviconinurlbar-default) !important; } #identity-icon { margin-inline-start: 4px !important; } .identity-box-button { padding-inline: 2px !important; } #urlbar[actiontype="extension"] #identity-faviconinurlbar, #identity-box:is(.extensionPage,.chromeUI,.unknownIdentity:not(.mixedDisplayContent,.mixedDisplayContentLoadedActiveBlocked)) #identity-faviconinurlbar { display: none !important; } #urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] #identity-icon { display: none !important; } `); windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); var faviconinurlbar = document.createXULElement("image"); faviconinurlbar.id = "identity-faviconinurlbar"; identity.before(faviconinurlbar); gBrowser.tabContainer.addEventListener("TabAttrModified", this); gBrowser.addProgressListener(this); that.unloadlisteners.push("faviconinurlbar"); var {STATE_START, STATE_STOP, STATE_IS_NETWORK} = Ci.nsIWebProgressListener; var updatefavicon = image => { if (image) { faviconinurlbar.style.setProperty("--v-faviconinurlbar", `url("${image}")`); faviconinurlbar.setAttribute("faviconinurlbar", "true"); faviconinurlbar.setAttribute("faviconchrome", `${image.startsWith("chrome:")}`); } else { faviconinurlbar.setAttribute("faviconinurlbar", "false"); faviconinurlbar.style.setProperty("--v-faviconinurlbar", ""); } }; this.handleEvent = e => { var tab = e.target, changed; if (!tab.selected || !((changed = e.detail.changed).includes("image") || changed.includes("selected"))) return; updatefavicon(tab.image); }; this.onStateChange = (aWebProgress, aRequest, aStateFlags, aStatus) => { if (aStateFlags & STATE_IS_NETWORK && aWebProgress?.isTopLevel) { if (aStateFlags & STATE_START) faviconinurlbar.setAttribute("favbusy", "true"); else if (aStateFlags & STATE_STOP) { faviconinurlbar.setAttribute("favbusy", "false"); updatefavicon(gBrowser.selectedTab.image); } } }; }, destructor() { gBrowser.tabContainer.removeEventListener("TabAttrModified", this); gBrowser.removeProgressListener(this); } }).init(this); скрытый текст |
Vitaliy V. > 21-07-2021 17:44:46 |
Обновил Замена фавиконок для сайтов P.S. Насчет иконок, в идеале лучше использовать svg, если др. форматов то размером от 32x32 px и более |
Dumby > 21-07-2021 19:28:36 |
Vitaliy V. пишет
Но в LinkWinActorChild.jsm его нет. |
sandro79 > 21-07-2021 20:36:07 |
Vitaliy V. пишет
Огромное Спасибо за обнову!!! Обновился, всё везде сработало, на закладках иконки тоже обновились, и в топе сайтов. скрытый текст |
Vitaliy V. > 22-07-2021 18:06:56 |
Обновил Добавить кнопку Пауза/Продолжить в загрузки https://forum.mozilla-russia.org/viewto … 50#p776150 |
sandro79 > 22-07-2021 19:22:14 |
Vitaliy V. пишет
Спасибо! Тоже обновился, скрытый текст скрытый текст Выделить код Код:@-moz-document url("chrome://browser/content/places/places.xhtml") { .downloadButton > .button-box { border-radius: 16px !important; } } Выделить код Код:@-moz-document url(chrome://browser/content/downloads/contentAreaDownloadsView.xhtml) { .downloadButton > .button-box { border-radius: 16px !important; } } |
sandro79 > 24-07-2021 22:58:01 |
Не знаю, может кому пригодится. скрытый текст Выделить код Код:<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve"> <image id="image0" width="16" height="16" x="0" y="0" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJN AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABiVBMVEUAAAAAAQoAF6wAChMA AREAwN0AAAAAAQoAZXYADC0AEagAUtkAAAAAAAAALnAABCoATcgBDGoBAwUVXdkAKLAAABcAHn4A U+kABAkAAAAAChwACTsAH3EAfY8AQHYAC0EAN7cEAQIAABcABjQAAEQAAlYANY8AoPMARqIAABMA F2EAG3gKGVUAu/4AUZAACA4ACBAAHH0ABiAAAAAAAAB/9vswXFYAjY4AgagAAg4AAAEAicsPW1oA AAAAAgQAlOwASnYAhM8As/gAXbcBQowAAgkAAAAAJ0IABRQAAQIAN+MABHoAfewAh/QAH9IAovUA Tf4ALtoAwPsAjvcN8/8A+/8cms8+n8wO2v8AIcsAOOMgvP8O/v8BUdEABHQAH84Akf8Ahf8AH+QA rvcCqvoA3P8By/8AVn8FAzkAGZ8AEJMAJewAP9EAffYAk/oAoP0Auv8AnNsAMJ0Ao/8BqvgLU+EA uf8A7P8AQaMCVdsA+P8o/f8A/P8U0f5V+v8A8P8Aqf0Aof/////gm21KAAAASnRSTlMASfMnMfQI Krpm+v0GAZdk8qlA/fJM1/wUDkGDrMSrZuXybnfO+OX+vETNxer+vRhC334UF/6Tq8EwOPyXAxL9 lfD76bYaGl0yB0c23wgAAAABYktHRIKLs/9EAAAAB3RJTUUH5QcYFgUmGgEtiwAAAK5JREFUGNNj YGBkYmZAASxerGwoAuzePhwoApxcvtw8SHxePj//AH5kAYHAoGBBZC1CwiGhIkh8UbGw8AhxCQZe SSlpGVk5eQaFyKjomFhFJWUV1bj4hMQkBrXklNS09IzMrOyc3Dx1DU0GrfyCQm2douKS0rJyXT19 BgaDCkMjY5PKqmpTM3MLS5CpxkBsZV1TW2dji3CfnX19Q6MDkt22jk7OLq7IrnNz9/CEsACxmSFY BCmxVAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wNy0yNFQyMjowNTozOCswMzowMJlJCfEAAAAl dEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDctMjRUMjI6MDU6MzgrMDM6MDDoFLFNAAAAAElFTkSuQmCC" /> </svg> Сконвертировал бабочку из оригинальной .ico-иконки. Ещё, как я понял в ходе экспериментов, чтоб иконка отработала в упомянутых в ссылках выше кодах, нужно заменить все двойные кавычки на одинарные. Получился готовый для использования код с максимальным качеством(Detailed) 14,6 КБ кода Выделить код Код:data:image/svg+xml;utf8,<svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0' d='M 0.5 0 L 1 3.5 L 0 3.5 L 0.5 0 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0' d='M 4.5 0 L 16 0 L 16 7 L 8.5 7 L 7.5 8 L 6 6.5 L 6 3.5 L 4 0.5 L 4.5 0 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0' d='M 0.5 6 L 0.5 7 L 0.5 6 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0' d='M 15.5 10 L 16 16 L 10 15.5 L 11 13 Q 14.25 13.5 15.5 10 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0' d='M 0.5 12 Q 1.5 14 2.5 12 Q 6.25 10.75 5 14.5 L 5.5 16 L 0 16 L 0.5 12 Z '></path><path fill='rgb(0,6,17)' stroke='rgb(0,6,17)' stroke-width='1' opacity='0.17647058823529413' d='M 3.5 0 L 3.5 1 L 3.5 0 Z '></path><path fill='rgb(0,6,17)' stroke='rgb(0,6,17)' stroke-width='1' opacity='0.17647058823529413' d='M 1.5 1 L 2 2.5 L 1 2.5 L 1.5 1 Z '></path><path fill='rgb(0,6,17)' stroke='rgb(0,6,17)' stroke-width='1' opacity='0.17647058823529413' d='M 13.5 11 L 13.5 12 L 13.5 11 Z '></path><path fill='rgb(0,6,17)' stroke='rgb(0,6,17)' stroke-width='1' opacity='0.17647058823529413' d='M 8.5 15 L 8.5 16 L 8.5 15 Z '></path><path fill='rgb(0,131,215)' stroke='rgb(0,131,215)' stroke-width='1' opacity='0.9764705882352941' d='M 6.5 12 L 6.5 13 L 6.5 12 Z '></path><path fill='rgb(0,131,215)' stroke='rgb(0,131,215)' stroke-width='1' opacity='0.9764705882352941' d='M 6.5 14 L 6.5 15 L 6.5 14 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.00392156862745098' d='M 0.5 4 L 1 5.5 L 0 5.5 L 0.5 4 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.00392156862745098' d='M 8.5 7 L 8.5 8 L 8.5 7 Z '></path><path fill='rgb(0,51,115)' stroke='rgb(0,51,115)' stroke-width='1' opacity='0.615686274509804' d='M 1.5 4 L 1.5 5 L 1.5 4 Z '></path><path fill='rgb(0,51,115)' stroke='rgb(0,51,115)' stroke-width='1' opacity='0.615686274509804' d='M 12.5 7 L 12.5 8 L 12.5 7 Z '></path><path fill='rgb(0,51,115)' stroke='rgb(0,51,115)' stroke-width='1' opacity='0.615686274509804' d='M 14.5 7 L 14.5 8 L 14.5 7 Z '></path><path fill='rgb(0,51,115)' stroke='rgb(0,51,115)' stroke-width='1' opacity='0.615686274509804' d='M 10.5 13 L 10.5 14 L 10.5 13 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 3.5 4 L 3.5 5 L 3.5 4 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 13.5 9 L 13.5 10 L 13.5 9 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 1.5 10 L 1.5 11 L 1.5 10 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 3.5 10 L 3.5 11 L 3.5 10 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 6.5 13 L 6.5 14 L 6.5 13 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 9.5 13 L 9.5 14 L 9.5 13 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 1.5 3 L 1.5 4 L 1.5 3 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 5.5 4 L 5.5 5 L 5.5 4 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 11.5 7 L 11.5 8 L 11.5 7 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 15.5 7 L 15.5 8 L 15.5 7 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 8.5 8 L 8.5 9 L 8.5 8 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 7.5 15 L 7.5 16 L 7.5 15 Z '></path><path fill='rgb(1,2,7)' stroke='rgb(1,2,7)' stroke-width='1' opacity='0.25098039215686274' d='M 1.5 0 L 1.5 1 L 1.5 0 Z '></path><path fill='rgb(1,2,7)' stroke='rgb(1,2,7)' stroke-width='1' opacity='0.25098039215686274' d='M 1.5 6 L 1.5 7 L 1.5 6 Z '></path><path fill='rgb(1,2,7)' stroke='rgb(1,2,7)' stroke-width='1' opacity='0.25098039215686274' d='M 5.5 12 L 5.5 13 L 5.5 12 Z '></path><path fill='rgb(23,250,255)' stroke='rgb(23,250,255)' stroke-width='1' opacity='1' d='M 4.5 8 L 4.5 9 L 4.5 8 Z '></path><path fill='rgb(23,250,255)' stroke='rgb(23,250,255)' stroke-width='1' opacity='1' d='M 8.5 11 L 8.5 12 L 8.5 11 Z '></path><path fill='rgb(45,156,205)' stroke='rgb(45,156,205)' stroke-width='1' opacity='1' d='M 2.5 7 L 4 7.5 L 2.5 8 L 2.5 7 Z '></path><path fill='rgb(4,82,221)' stroke='rgb(4,82,221)' stroke-width='1' opacity='0.9882352941176471' d='M 4.5 3 L 5 4.5 L 4 4.5 L 4.5 3 Z '></path><path fill='rgb(4,82,221)' stroke='rgb(4,82,221)' stroke-width='1' opacity='0.9882352941176471' d='M 1.5 5 Q 4 6 2.5 7 Q 0 6 1.5 5 Z '></path><path fill='rgb(4,82,221)' stroke='rgb(4,82,221)' stroke-width='1' opacity='0.9882352941176471' d='M 5.5 7 L 6 8.5 L 5 8.5 L 5.5 7 Z '></path><path fill='rgb(4,82,221)' stroke='rgb(4,82,221)' stroke-width='1' opacity='0.9882352941176471' d='M 9.5 10 L 9.5 11 L 9.5 10 Z '></path><path fill='rgb(4,82,221)' stroke='rgb(4,82,221)' stroke-width='1' opacity='0.9882352941176471' d='M 6.5 11 L 6.5 12 L 6.5 11 Z '></path><path fill='rgb(0,11,25)' stroke='rgb(0,11,25)' stroke-width='1' opacity='0.2549019607843137' d='M 10.5 7 L 10.5 8 L 10.5 7 Z '></path><path fill='rgb(0,11,25)' stroke='rgb(0,11,25)' stroke-width='1' opacity='0.2549019607843137' d='M 0.5 11 L 0.5 12 L 0.5 11 Z '></path><path fill='rgb(0,15,98)' stroke='rgb(0,15,98)' stroke-width='1' opacity='0.7607843137254902' d='M 5.5 5 L 5.5 6 L 5.5 5 Z '></path><path fill='rgb(0,15,98)' stroke='rgb(0,15,98)' stroke-width='1' opacity='0.7607843137254902' d='M 9.5 8 L 9.5 9 L 9.5 8 Z '></path><path fill='rgb(0,15,98)' stroke='rgb(0,15,98)' stroke-width='1' opacity='0.7607843137254902' d='M 0.5 10 L 0.5 11 L 0.5 10 Z '></path><path fill='rgb(0,15,98)' stroke='rgb(0,15,98)' stroke-width='1' opacity='0.7607843137254902' d='M 4.5 10 L 4.5 11 L 4.5 10 Z '></path><path fill='rgb(0,87,137)' stroke='rgb(0,87,137)' stroke-width='1' opacity='0.7098039215686275' d='M 4.5 2 L 4.5 3 L 4.5 2 Z '></path><path fill='rgb(0,87,137)' stroke='rgb(0,87,137)' stroke-width='1' opacity='0.7098039215686275' d='M 14.5 9 Q 16 10 13.5 11 Q 12 10 14.5 9 Z '></path><path fill='rgb(0,87,137)' stroke='rgb(0,87,137)' stroke-width='1' opacity='0.7098039215686275' d='M 11.5 11 L 11.5 12 L 11.5 11 Z '></path><path fill='rgb(0,87,137)' stroke='rgb(0,87,137)' stroke-width='1' opacity='0.7098039215686275' d='M 9.5 14 L 9.5 15 L 9.5 14 Z '></path><path fill='rgb(0,47,180)' stroke='rgb(0,47,180)' stroke-width='1' opacity='0.9215686274509803' d='M 5.5 6 L 5.5 7 L 5.5 6 Z '></path><path fill='rgb(0,47,180)' stroke='rgb(0,47,180)' stroke-width='1' opacity='0.9215686274509803' d='M 0.5 8 L 0.5 9 L 0.5 8 Z '></path><path fill='rgb(0,47,180)' stroke='rgb(0,47,180)' stroke-width='1' opacity='0.9215686274509803' d='M 8.5 14 L 8.5 15 L 8.5 14 Z '></path><path fill='rgb(0,37,131)' stroke='rgb(0,37,131)' stroke-width='1' opacity='0.8705882352941177' d='M 1.5 7 L 1.5 8 L 1.5 7 Z '></path><path fill='rgb(0,37,131)' stroke='rgb(0,37,131)' stroke-width='1' opacity='0.8705882352941177' d='M 0.5 9 L 0.5 10 L 0.5 9 Z '></path><path fill='rgb(0,37,131)' stroke='rgb(0,37,131)' stroke-width='1' opacity='0.8705882352941177' d='M 2.5 11 L 2.5 12 L 2.5 11 Z '></path><path fill='rgb(0,170,250)' stroke='rgb(0,170,250)' stroke-width='1' opacity='0.996078431372549' d='M 1.5 9 L 3 9.5 L 1.5 10 L 1.5 9 Z '></path><path fill='rgb(0,170,250)' stroke='rgb(0,170,250)' stroke-width='1' opacity='0.996078431372549' d='M 7.5 10 L 9 10.5 L 7.5 11 L 7.5 10 Z '></path><path fill='rgb(0,170,250)' stroke='rgb(0,170,250)' stroke-width='1' opacity='0.996078431372549' d='M 8.5 13 Q 10 14 7.5 15 Q 6 14 8.5 13 Z '></path><path fill='rgb(5,213,255)' stroke='rgb(5,213,255)' stroke-width='1' opacity='1' d='M 4.5 7 L 4.5 8 L 4.5 7 Z '></path><path fill='rgb(5,213,255)' stroke='rgb(5,213,255)' stroke-width='1' opacity='1' d='M 3.5 9 L 5 9.5 L 3.5 10 L 3.5 9 Z '></path><path fill='rgb(0,86,127)' stroke='rgb(0,86,127)' stroke-width='1' opacity='1' d='M 5.5 9 L 5.5 10 L 5.5 9 Z '></path><path fill='rgb(0,20,161)' stroke='rgb(0,20,161)' stroke-width='1' opacity='0.9803921568627451' d='M 2.5 0 L 2.5 1 L 2.5 0 Z '></path><path fill='rgb(0,20,161)' stroke='rgb(0,20,161)' stroke-width='1' opacity='0.9803921568627451' d='M 2.5 3 L 2.5 4 L 2.5 3 Z '></path><path fill='rgb(0,20,161)' stroke='rgb(0,20,161)' stroke-width='1' opacity='0.9803921568627451' d='M 7.5 9 L 9 9.5 L 7.5 10 L 7.5 9 Z '></path><path fill='rgb(3,6,77)' stroke='rgb(3,6,77)' stroke-width='1' opacity='0.9725490196078431' d='M 2.5 2 L 2.5 3 L 2.5 2 Z '></path><path fill='rgb(3,6,77)' stroke='rgb(3,6,77)' stroke-width='1' opacity='0.9725490196078431' d='M 6.5 8 L 7 9.5 Q 6 12 5 10.5 L 6.5 8 Z '></path><path fill='rgb(3,6,77)' stroke='rgb(3,6,77)' stroke-width='1' opacity='0.9725490196078431' d='M 10.5 8 L 12 8.5 L 10.5 9 L 10.5 8 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 2.5 1 L 2.5 2 L 2.5 1 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 2.5 4 L 3 5.5 L 2 5.5 L 2.5 4 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 1.5 8 L 3 8.5 L 1.5 9 L 1.5 8 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 12.5 8 L 12.5 9 L 12.5 8 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 15.5 8 L 15.5 9 L 15.5 8 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 9.5 9 L 11 9.5 L 9.5 10 L 9.5 9 Z '></path><path fill='rgb(0,139,247)' stroke='rgb(0,139,247)' stroke-width='1' opacity='0.996078431372549' d='M 3.5 2 L 4 3.5 L 3 3.5 L 3.5 2 Z '></path><path fill='rgb(0,139,247)' stroke='rgb(0,139,247)' stroke-width='1' opacity='0.996078431372549' d='M 4.5 5 L 4.5 6 L 4.5 5 Z '></path><path fill='rgb(0,139,247)' stroke='rgb(0,139,247)' stroke-width='1' opacity='0.996078431372549' d='M 13.5 8 L 15 8.5 L 11.5 10 L 11.5 9 L 13.5 8 Z '></path><path fill='rgb(0,187,253)' stroke='rgb(0,187,253)' stroke-width='1' opacity='0.996078431372549' d='M 3.5 5 L 3.5 6 L 3.5 5 Z '></path><path fill='rgb(0,187,253)' stroke='rgb(0,187,253)' stroke-width='1' opacity='0.996078431372549' d='M 2.5 10 L 2.5 11 L 2.5 10 Z '></path><path fill='rgb(0,187,253)' stroke='rgb(0,187,253)' stroke-width='1' opacity='0.996078431372549' d='M 10.5 10 L 10.5 11 L 10.5 10 Z '></path><path fill='rgb(0,187,253)' stroke='rgb(0,187,253)' stroke-width='1' opacity='0.996078431372549' d='M 12.5 10 L 12.5 11 L 12.5 10 Z '></path><path fill='rgb(0,10,21)' stroke='rgb(0,10,21)' stroke-width='1' opacity='0.09411764705882353' d='M 14.5 10 L 14.5 11 L 14.5 10 Z '></path><path fill='rgb(0,0,22)' stroke='rgb(0,0,22)' stroke-width='1' opacity='0.32941176470588235' d='M 0.5 7 L 0.5 8 L 0.5 7 Z '></path><path fill='rgb(0,0,22)' stroke='rgb(0,0,22)' stroke-width='1' opacity='0.32941176470588235' d='M 7.5 8 L 7.5 9 L 7.5 8 Z '></path><path fill='rgb(0,0,22)' stroke='rgb(0,0,22)' stroke-width='1' opacity='0.32941176470588235' d='M 15.5 9 L 15.5 10 L 15.5 9 Z '></path><path fill='rgb(0,56,160)' stroke='rgb(0,56,160)' stroke-width='1' opacity='1' d='M 6.5 10 L 6.5 11 L 6.5 10 Z '></path><path fill='rgb(0,56,160)' stroke='rgb(0,56,160)' stroke-width='1' opacity='1' d='M 1.5 11 L 1.5 12 L 1.5 11 Z '></path><path fill='rgb(0,6,32)' stroke='rgb(0,6,32)' stroke-width='1' opacity='0.49411764705882355' d='M 3.5 11 L 3.5 12 L 3.5 11 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.08627450980392157' d='M 4.5 11 L 6 11.5 L 4.5 12 L 4.5 11 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.08627450980392157' d='M 1.5 12 L 1.5 13 L 1.5 12 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.08627450980392157' d='M 6.5 15 L 6.5 16 L 6.5 15 Z '></path><path fill='rgb(1,245,255)' stroke='rgb(1,245,255)' stroke-width='1' opacity='1' d='M 3.5 6 L 5 6.5 L 3.5 7 L 3.5 6 Z '></path><path fill='rgb(1,245,255)' stroke='rgb(1,245,255)' stroke-width='1' opacity='1' d='M 11.5 10 L 11.5 11 L 11.5 10 Z '></path><path fill='rgb(1,245,255)' stroke='rgb(1,245,255)' stroke-width='1' opacity='1' d='M 7.5 11 L 8 13.5 L 7 13.5 L 7.5 11 Z '></path><path fill='rgb(106,248,253)' stroke='rgb(106,248,253)' stroke-width='1' opacity='0.996078431372549' d='M 9.5 11 L 10 12.5 L 9 12.5 L 9.5 11 Z '></path><path fill='rgb(26,198,254)' stroke='rgb(26,198,254)' stroke-width='1' opacity='1' d='M 3.5 8 L 3.5 9 L 3.5 8 Z '></path><path fill='rgb(26,198,254)' stroke='rgb(26,198,254)' stroke-width='1' opacity='1' d='M 8.5 12 L 8.5 13 L 8.5 12 Z '></path><path fill='rgb(31,92,88)' stroke='rgb(31,92,88)' stroke-width='1' opacity='0.5843137254901961' d='M 10.5 11 L 11 12.5 L 10 12.5 L 10.5 11 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.03137254901960784' d='M 4.5 1 L 4.5 2 L 4.5 1 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.03137254901960784' d='M 5.5 3 L 5.5 4 L 5.5 3 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.03137254901960784' d='M 9.5 7 L 9.5 8 L 9.5 7 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.03137254901960784' d='M 12.5 12 L 12.5 13 L 12.5 12 Z '></path><path fill='rgb(0,25,25)' stroke='rgb(0,25,25)' stroke-width='1' opacity='0.047058823529411764' d='M 9.5 15 L 9.5 16 L 9.5 15 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.011764705882352941' d='M 11.5 12 L 11.5 13 L 11.5 12 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.011764705882352941' d='M 5.5 14 L 5.5 15 L 5.5 14 Z '></path><path fill='rgb(0,192,221)' stroke='rgb(0,192,221)' stroke-width='1' opacity='0.9568627450980393' d='M 3.5 1 L 3.5 2 L 3.5 1 Z '></path><path fill='rgb(0,116,165)' stroke='rgb(0,116,165)' stroke-width='1' opacity='0.8117647058823529' d='M 13.5 7 L 13.5 8 L 13.5 7 Z '></path><path fill='rgb(0,116,165)' stroke='rgb(0,116,165)' stroke-width='1' opacity='0.8117647058823529' d='M 12.5 11 L 12.5 12 L 12.5 11 Z '></path><path fill='rgb(0,10,10)' stroke='rgb(0,10,10)' stroke-width='1' opacity='0.09019607843137255' d='M 6.5 7 L 6.5 8 L 6.5 7 Z '></path><path fill='rgb(0,10,10)' stroke='rgb(0,10,10)' stroke-width='1' opacity='0.09019607843137255' d='M 5.5 13 L 5.5 14 L 5.5 13 Z '></path><path fill='rgb(0,10,10)' stroke='rgb(0,10,10)' stroke-width='1' opacity='0.09019607843137255' d='M 10.5 14 L 10.5 15 L 10.5 14 Z '></path></svg> Ага, у них есть ещё оптимизатор, прогнал через него и файл уменьшился до 3,5КБ, а качество вроде бы и не пострадало. Это уже внушает оптимизм, можно дальше экспериментировать. Нет, оптимизированный код выдал ошибку скрытый текст Выделить код Код:data:image/svg+xml;utf8,<svg width='16' height='16' xmlns='http://www.w3.org/2000/svg'><path fill='#050919' stroke='#050919' opacity='.176' d='M3.5 0v1-1zM1.5 1L2 2.5H1L1.5 1zM13.5 11v1-1zM8.5 15v1-1z'/><path fill='#367BDC' stroke='#367BDC' opacity='.969' d='M6.5 14v1-1z'/><path stroke='#000' opacity='.004' d='M.5 4L1 5.5H0L.5 4zM8.5 7v1-1z'/><path fill='#1B3672' stroke='#1B3672' opacity='.627' d='M1.5 4v1-1zM12.5 7v1-1zM14.5 7v1-1zM10.5 13v1-1z'/><path fill='#3F9CF8' stroke='#3F9CF8' opacity='.996' d='M3.5 4v1-1zM13.5 9v1-1zM1.5 10v1-1zM7.5 10v1-1zM9.5 13v1-1z'/><path fill='#080E3A' stroke='#080E3A' opacity='.42' d='M1.5 3v1-1zM5.5 4v1-1zM11.5 7v1-1zM15.5 7v1-1zM8.5 8v1-1zM3.5 11v1-1zM7.5 15v1-1z'/><path fill='#02030A' stroke='#02030A' opacity='.251' d='M1.5 0v1-1zM1.5 6v1-1zM5.5 12v1-1z'/><path fill='#4DEFFE' stroke='#4DEFFE' d='M3.5 6v1-1zM11.5 10v1-1zM7.5 13v1-1z'/><path fill='#3F94CE' stroke='#3F94CE' opacity='.996' d='M2.5 7l1.5.5-1.5.5V7zM3.5 10v1-1zM6.5 12v1-1z'/><path fill='#3349DC' stroke='#3349DC' opacity='.988' d='M4.5 3L5 4.5H4L4.5 3zM1.5 5q2.5 1 1 2-2.5-1-1-2zM5.5 7L6 8.5H5L5.5 7zM10.5 9q1.5 1-1 2-1.5-1 1-2zM6.5 11v1-1z'/><path fill='#02051F' stroke='#02051F' opacity='.325' d='M.5 7v1-1zM7.5 8v1-1z'/><path fill='#150B62' stroke='#150B62' opacity='.761' d='M5.5 5v1-1zM9.5 8v1-1zM.5 10v1-1zM4.5 10v1-1z'/><path fill='#245A8B' stroke='#245A8B' opacity='.718' d='M4.5 2v1-1zM14.5 9q1.5 1-1 2-1.5-1 1-2zM11.5 11v1-1zM9.5 14v1-1z'/><path fill='#2726B1' stroke='#2726B1' opacity='.922' d='M5.5 6v1-1zM.5 8v1-1zM8.5 14v1-1z'/><path fill='#1D2182' stroke='#1D2182' opacity='.871' d='M1.5 7v1-1zM.5 9v1-1zM2.5 11v1-1z'/><path fill='#41A6F9' stroke='#41A6F9' opacity='.996' d='M1.5 9l1.5.5-1.5.5V9zM8.5 10v1-1zM8.5 13q1.5 1-1 2-1.5-1 1-2z'/><path fill='#4AD9FE' stroke='#4AD9FE' d='M4.5 7v1-1zM3.5 9v1-1z'/><path fill='#21557E' stroke='#21557E' d='M5.5 9v1-1z'/><path fill='#2600B2' stroke='#2600B2' opacity='.988' d='M2.5 0v1-1zM2.5 3L3 4.5H2L2.5 3zM1.5 8v1-1zM12.5 8v1-1zM7.5 9l1.5.5-1.5.5V9z'/><path fill='#15055D' stroke='#15055D' opacity='.976' d='M2.5 2v1-1zM10.5 8l1.5.5-1.5.5V8zM6.5 9q1.5 1-1 2-1.5-1 1-2z'/><path fill='#301ADF' stroke='#301ADF' d='M2.5 1v1-1zM2.5 5v1-1zM2.5 8v1-1zM15.5 8v1-1zM9.5 9v1-1z'/><path fill='#3C85F6' stroke='#3C85F6' opacity='.996' d='M3.5 2L4 3.5H3L3.5 2zM4.5 5v1-1zM13.5 8l1.5.5-3.5 1.5V9l2-1zM6.5 13v1-1z'/><path fill='#45B8FD' stroke='#45B8FD' opacity='.996' d='M3.5 5v1-1zM3.5 8v1-1zM2.5 10v1-1zM10.5 10v1-1zM12.5 10v1-1z'/><path fill='#051C21' stroke='#051C21' opacity='.059' d='M14.5 10v1-1zM9.5 15v1-1z'/><path fill='#030718' stroke='#030718' opacity='.263' d='M10.5 7v1-1zM15.5 9v1-1zM.5 11v1-1z'/><path fill='#24349E' stroke='#24349E' d='M6.5 10v1-1zM1.5 11v1-1z'/><path fill='#050414' stroke='#050414' opacity='.722' d='M6.5 8v1-1z'/><path stroke='#000' opacity='.086' d='M4.5 11l1.5.5-1.5.5v-1zM1.5 12v1-1zM6.5 15v1-1z'/><path fill='#51FCFE' stroke='#51FCFE' d='M4.5 6v1-1zM4.5 8v1-1zM7 11l2 .5q-1 2.5-2 1V11z'/><path fill='#7DF8FC' stroke='#7DF8FC' opacity='.996' d='M9.5 11l.5 1.5H9l.5-1.5z'/><path fill='#49CBFD' stroke='#49CBFD' d='M4.5 9v1-1zM8.5 12v1-1z'/><path fill='#2E5C58' stroke='#2E5C58' opacity='.584' d='M10.5 11l.5 1.5h-1l.5-1.5z'/><path stroke='#000' opacity='.031' d='M4.5 1v1-1zM5.5 3v1-1zM9.5 7v1-1zM12.5 12v1-1z'/><path fill='#0D0D13' stroke='#0D0D13' opacity='.075' d='M6.5 7v1-1zM5.5 13v1-1z'/><path stroke='#000' opacity='.012' d='M11.5 12v1-1zM5.5 14v1-1z'/><path fill='#40BEDB' stroke='#40BEDB' opacity='.957' d='M3.5 1v1-1z'/><path fill='#2B71A2' stroke='#2B71A2' opacity='.812' d='M13.5 7v1-1zM12.5 11v1-1z'/><path fill='#090913' stroke='#090913' opacity='.102' d='M10.5 14v1-1z'/></svg> |
Vitaliy V. > 25-07-2021 14:01:34 |
sandro79 пишет
Так у вас повтор здесь ... </svg><svg width='16' height='16' xmlns='http://www.w3.org/2000/svg'> ... А вообще конечно всякие там конверторы из растра в SVG ерунда полная, да и зачем иконок SVG тоже полно. |
sandro79 > 25-07-2021 15:28:40 |
Vitaliy V. пишет
Ну это, тот, что под первым спойлером в оптимизированном варианте, бабочка ихняя. В rgb(a) пока не пробовал, достаточно трудоёмкая для меня задача, заменил пакетно # на %23, всё-равно ошибку даёт. Может после %23 пробел должен быть, тоже пробовал, не прошло.
Да это верно, но хоть что-то, если не знаешь сам как и что делать. Да хотелось именно оригинальную иконку бабочки перегнать в svg. Зациклило меня на решении этой задачи.
Виталий, я тут оставлю результаты кодов svg без моего вмешательства неоптимизированный и оптимизированный, на всякий случай, оба в виде файлов svg в браузере открываются нормально. Вы имеете в виду из первого большого кода конвертнуть в нормальном неонлайн-редакторе? Может глянете, если не сильно муторно, а если муторно, то и не стоит оно того значит скрытый текст Выделить код Код:<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0" d="M 0.5 0 L 1 3.5 L 0 3.5 L 0.5 0 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0" d="M 4.5 0 L 16 0 L 16 7 L 8.5 7 L 7.5 8 L 6 6.5 L 6 3.5 L 4 0.5 L 4.5 0 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0" d="M 0.5 6 L 0.5 7 L 0.5 6 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0" d="M 15.5 10 L 16 16 L 10 15.5 L 11 13 Q 14.25 13.5 15.5 10 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0" d="M 0.5 12 Q 1.5 14 2.5 12 Q 6.25 10.75 5 14.5 L 5.5 16 L 0 16 L 0.5 12 Z "></path><path fill="rgb(5,9,25)" stroke="rgb(5,9,25)" stroke-width="1" opacity="0.17647058823529413" d="M 3.5 0 L 3.5 1 L 3.5 0 Z "></path><path fill="rgb(5,9,25)" stroke="rgb(5,9,25)" stroke-width="1" opacity="0.17647058823529413" d="M 1.5 1 L 2 2.5 L 1 2.5 L 1.5 1 Z "></path><path fill="rgb(5,9,25)" stroke="rgb(5,9,25)" stroke-width="1" opacity="0.17647058823529413" d="M 13.5 11 L 13.5 12 L 13.5 11 Z "></path><path fill="rgb(5,9,25)" stroke="rgb(5,9,25)" stroke-width="1" opacity="0.17647058823529413" d="M 8.5 15 L 8.5 16 L 8.5 15 Z "></path><path fill="rgb(54,123,220)" stroke="rgb(54,123,220)" stroke-width="1" opacity="0.9686274509803922" d="M 6.5 14 L 6.5 15 L 6.5 14 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.00392156862745098" d="M 0.5 4 L 1 5.5 L 0 5.5 L 0.5 4 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.00392156862745098" d="M 8.5 7 L 8.5 8 L 8.5 7 Z "></path><path fill="rgb(27,54,114)" stroke="rgb(27,54,114)" stroke-width="1" opacity="0.6274509803921569" d="M 1.5 4 L 1.5 5 L 1.5 4 Z "></path><path fill="rgb(27,54,114)" stroke="rgb(27,54,114)" stroke-width="1" opacity="0.6274509803921569" d="M 12.5 7 L 12.5 8 L 12.5 7 Z "></path><path fill="rgb(27,54,114)" stroke="rgb(27,54,114)" stroke-width="1" opacity="0.6274509803921569" d="M 14.5 7 L 14.5 8 L 14.5 7 Z "></path><path fill="rgb(27,54,114)" stroke="rgb(27,54,114)" stroke-width="1" opacity="0.6274509803921569" d="M 10.5 13 L 10.5 14 L 10.5 13 Z "></path><path fill="rgb(63,156,248)" stroke="rgb(63,156,248)" stroke-width="1" opacity="0.996078431372549" d="M 3.5 4 L 3.5 5 L 3.5 4 Z "></path><path fill="rgb(63,156,248)" stroke="rgb(63,156,248)" stroke-width="1" opacity="0.996078431372549" d="M 13.5 9 L 13.5 10 L 13.5 9 Z "></path><path fill="rgb(63,156,248)" stroke="rgb(63,156,248)" stroke-width="1" opacity="0.996078431372549" d="M 1.5 10 L 1.5 11 L 1.5 10 Z "></path><path fill="rgb(63,156,248)" stroke="rgb(63,156,248)" stroke-width="1" opacity="0.996078431372549" d="M 7.5 10 L 7.5 11 L 7.5 10 Z "></path><path fill="rgb(63,156,248)" stroke="rgb(63,156,248)" stroke-width="1" opacity="0.996078431372549" d="M 9.5 13 L 9.5 14 L 9.5 13 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 1.5 3 L 1.5 4 L 1.5 3 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 5.5 4 L 5.5 5 L 5.5 4 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 11.5 7 L 11.5 8 L 11.5 7 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 15.5 7 L 15.5 8 L 15.5 7 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 8.5 8 L 8.5 9 L 8.5 8 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 3.5 11 L 3.5 12 L 3.5 11 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 7.5 15 L 7.5 16 L 7.5 15 Z "></path><path fill="rgb(2,3,10)" stroke="rgb(2,3,10)" stroke-width="1" opacity="0.25098039215686274" d="M 1.5 0 L 1.5 1 L 1.5 0 Z "></path><path fill="rgb(2,3,10)" stroke="rgb(2,3,10)" stroke-width="1" opacity="0.25098039215686274" d="M 1.5 6 L 1.5 7 L 1.5 6 Z "></path><path fill="rgb(2,3,10)" stroke="rgb(2,3,10)" stroke-width="1" opacity="0.25098039215686274" d="M 5.5 12 L 5.5 13 L 5.5 12 Z "></path><path fill="rgb(77,239,254)" stroke="rgb(77,239,254)" stroke-width="1" opacity="1" d="M 3.5 6 L 3.5 7 L 3.5 6 Z "></path><path fill="rgb(77,239,254)" stroke="rgb(77,239,254)" stroke-width="1" opacity="1" d="M 11.5 10 L 11.5 11 L 11.5 10 Z "></path><path fill="rgb(77,239,254)" stroke="rgb(77,239,254)" stroke-width="1" opacity="1" d="M 7.5 13 L 7.5 14 L 7.5 13 Z "></path><path fill="rgb(63,148,206)" stroke="rgb(63,148,206)" stroke-width="1" opacity="0.996078431372549" d="M 2.5 7 L 4 7.5 L 2.5 8 L 2.5 7 Z "></path><path fill="rgb(63,148,206)" stroke="rgb(63,148,206)" stroke-width="1" opacity="0.996078431372549" d="M 3.5 10 L 3.5 11 L 3.5 10 Z "></path><path fill="rgb(63,148,206)" stroke="rgb(63,148,206)" stroke-width="1" opacity="0.996078431372549" d="M 6.5 12 L 6.5 13 L 6.5 12 Z "></path><path fill="rgb(51,73,220)" stroke="rgb(51,73,220)" stroke-width="1" opacity="0.9882352941176471" d="M 4.5 3 L 5 4.5 L 4 4.5 L 4.5 3 Z "></path><path fill="rgb(51,73,220)" stroke="rgb(51,73,220)" stroke-width="1" opacity="0.9882352941176471" d="M 1.5 5 Q 4 6 2.5 7 Q 0 6 1.5 5 Z "></path><path fill="rgb(51,73,220)" stroke="rgb(51,73,220)" stroke-width="1" opacity="0.9882352941176471" d="M 5.5 7 L 6 8.5 L 5 8.5 L 5.5 7 Z "></path><path fill="rgb(51,73,220)" stroke="rgb(51,73,220)" stroke-width="1" opacity="0.9882352941176471" d="M 10.5 9 Q 12 10 9.5 11 Q 8 10 10.5 9 Z "></path><path fill="rgb(51,73,220)" stroke="rgb(51,73,220)" stroke-width="1" opacity="0.9882352941176471" d="M 6.5 11 L 6.5 12 L 6.5 11 Z "></path><path fill="rgb(2,5,31)" stroke="rgb(2,5,31)" stroke-width="1" opacity="0.3254901960784314" d="M 0.5 7 L 0.5 8 L 0.5 7 Z "></path><path fill="rgb(2,5,31)" stroke="rgb(2,5,31)" stroke-width="1" opacity="0.3254901960784314" d="M 7.5 8 L 7.5 9 L 7.5 8 Z "></path><path fill="rgb(21,11,98)" stroke="rgb(21,11,98)" stroke-width="1" opacity="0.7607843137254902" d="M 5.5 5 L 5.5 6 L 5.5 5 Z "></path><path fill="rgb(21,11,98)" stroke="rgb(21,11,98)" stroke-width="1" opacity="0.7607843137254902" d="M 9.5 8 L 9.5 9 L 9.5 8 Z "></path><path fill="rgb(21,11,98)" stroke="rgb(21,11,98)" stroke-width="1" opacity="0.7607843137254902" d="M 0.5 10 L 0.5 11 L 0.5 10 Z "></path><path fill="rgb(21,11,98)" stroke="rgb(21,11,98)" stroke-width="1" opacity="0.7607843137254902" d="M 4.5 10 L 4.5 11 L 4.5 10 Z "></path><path fill="rgb(36,90,139)" stroke="rgb(36,90,139)" stroke-width="1" opacity="0.7176470588235294" d="M 4.5 2 L 4.5 3 L 4.5 2 Z "></path><path fill="rgb(36,90,139)" stroke="rgb(36,90,139)" stroke-width="1" opacity="0.7176470588235294" d="M 14.5 9 Q 16 10 13.5 11 Q 12 10 14.5 9 Z "></path><path fill="rgb(36,90,139)" stroke="rgb(36,90,139)" stroke-width="1" opacity="0.7176470588235294" d="M 11.5 11 L 11.5 12 L 11.5 11 Z "></path><path fill="rgb(36,90,139)" stroke="rgb(36,90,139)" stroke-width="1" opacity="0.7176470588235294" d="M 9.5 14 L 9.5 15 L 9.5 14 Z "></path><path fill="rgb(39,38,177)" stroke="rgb(39,38,177)" stroke-width="1" opacity="0.9215686274509803" d="M 5.5 6 L 5.5 7 L 5.5 6 Z "></path><path fill="rgb(39,38,177)" stroke="rgb(39,38,177)" stroke-width="1" opacity="0.9215686274509803" d="M 0.5 8 L 0.5 9 L 0.5 8 Z "></path><path fill="rgb(39,38,177)" stroke="rgb(39,38,177)" stroke-width="1" opacity="0.9215686274509803" d="M 8.5 14 L 8.5 15 L 8.5 14 Z "></path><path fill="rgb(29,33,130)" stroke="rgb(29,33,130)" stroke-width="1" opacity="0.8705882352941177" d="M 1.5 7 L 1.5 8 L 1.5 7 Z "></path><path fill="rgb(29,33,130)" stroke="rgb(29,33,130)" stroke-width="1" opacity="0.8705882352941177" d="M 0.5 9 L 0.5 10 L 0.5 9 Z "></path><path fill="rgb(29,33,130)" stroke="rgb(29,33,130)" stroke-width="1" opacity="0.8705882352941177" d="M 2.5 11 L 2.5 12 L 2.5 11 Z "></path><path fill="rgb(65,166,249)" stroke="rgb(65,166,249)" stroke-width="1" opacity="0.996078431372549" d="M 1.5 9 L 3 9.5 L 1.5 10 L 1.5 9 Z "></path><path fill="rgb(65,166,249)" stroke="rgb(65,166,249)" stroke-width="1" opacity="0.996078431372549" d="M 8.5 10 L 8.5 11 L 8.5 10 Z "></path><path fill="rgb(65,166,249)" stroke="rgb(65,166,249)" stroke-width="1" opacity="0.996078431372549" d="M 8.5 13 Q 10 14 7.5 15 Q 6 14 8.5 13 Z "></path><path fill="rgb(74,217,254)" stroke="rgb(74,217,254)" stroke-width="1" opacity="1" d="M 4.5 7 L 4.5 8 L 4.5 7 Z "></path><path fill="rgb(74,217,254)" stroke="rgb(74,217,254)" stroke-width="1" opacity="1" d="M 3.5 9 L 3.5 10 L 3.5 9 Z "></path><path fill="rgb(33,85,126)" stroke="rgb(33,85,126)" stroke-width="1" opacity="1" d="M 5.5 9 L 5.5 10 L 5.5 9 Z "></path><path fill="rgb(38,0,178)" stroke="rgb(38,0,178)" stroke-width="1" opacity="0.9882352941176471" d="M 2.5 0 L 2.5 1 L 2.5 0 Z "></path><path fill="rgb(38,0,178)" stroke="rgb(38,0,178)" stroke-width="1" opacity="0.9882352941176471" d="M 2.5 3 L 3 4.5 L 2 4.5 L 2.5 3 Z "></path><path fill="rgb(38,0,178)" stroke="rgb(38,0,178)" stroke-width="1" opacity="0.9882352941176471" d="M 1.5 8 L 1.5 9 L 1.5 8 Z "></path><path fill="rgb(38,0,178)" stroke="rgb(38,0,178)" stroke-width="1" opacity="0.9882352941176471" d="M 12.5 8 L 12.5 9 L 12.5 8 Z "></path><path fill="rgb(38,0,178)" stroke="rgb(38,0,178)" stroke-width="1" opacity="0.9882352941176471" d="M 7.5 9 L 9 9.5 L 7.5 10 L 7.5 9 Z "></path><path fill="rgb(21,5,93)" stroke="rgb(21,5,93)" stroke-width="1" opacity="0.9764705882352941" d="M 2.5 2 L 2.5 3 L 2.5 2 Z "></path><path fill="rgb(21,5,93)" stroke="rgb(21,5,93)" stroke-width="1" opacity="0.9764705882352941" d="M 10.5 8 L 12 8.5 L 10.5 9 L 10.5 8 Z "></path><path fill="rgb(21,5,93)" stroke="rgb(21,5,93)" stroke-width="1" opacity="0.9764705882352941" d="M 6.5 9 Q 8 10 5.5 11 Q 4 10 6.5 9 Z "></path><path fill="rgb(48,26,223)" stroke="rgb(48,26,223)" stroke-width="1" opacity="1" d="M 2.5 1 L 2.5 2 L 2.5 1 Z "></path><path fill="rgb(48,26,223)" stroke="rgb(48,26,223)" stroke-width="1" opacity="1" d="M 2.5 5 L 2.5 6 L 2.5 5 Z "></path><path fill="rgb(48,26,223)" stroke="rgb(48,26,223)" stroke-width="1" opacity="1" d="M 2.5 8 L 2.5 9 L 2.5 8 Z "></path><path fill="rgb(48,26,223)" stroke="rgb(48,26,223)" stroke-width="1" opacity="1" d="M 15.5 8 L 15.5 9 L 15.5 8 Z "></path><path fill="rgb(48,26,223)" stroke="rgb(48,26,223)" stroke-width="1" opacity="1" d="M 9.5 9 L 9.5 10 L 9.5 9 Z "></path><path fill="rgb(60,133,246)" stroke="rgb(60,133,246)" stroke-width="1" opacity="0.996078431372549" d="M 3.5 2 L 4 3.5 L 3 3.5 L 3.5 2 Z "></path><path fill="rgb(60,133,246)" stroke="rgb(60,133,246)" stroke-width="1" opacity="0.996078431372549" d="M 4.5 5 L 4.5 6 L 4.5 5 Z "></path><path fill="rgb(60,133,246)" stroke="rgb(60,133,246)" stroke-width="1" opacity="0.996078431372549" d="M 13.5 8 L 15 8.5 L 11.5 10 L 11.5 9 L 13.5 8 Z "></path><path fill="rgb(60,133,246)" stroke="rgb(60,133,246)" stroke-width="1" opacity="0.996078431372549" d="M 6.5 13 L 6.5 14 L 6.5 13 Z "></path><path fill="rgb(69,184,253)" stroke="rgb(69,184,253)" stroke-width="1" opacity="0.996078431372549" d="M 3.5 5 L 3.5 6 L 3.5 5 Z "></path><path fill="rgb(69,184,253)" stroke="rgb(69,184,253)" stroke-width="1" opacity="0.996078431372549" d="M 3.5 8 L 3.5 9 L 3.5 8 Z "></path><path fill="rgb(69,184,253)" stroke="rgb(69,184,253)" stroke-width="1" opacity="0.996078431372549" d="M 2.5 10 L 2.5 11 L 2.5 10 Z "></path><path fill="rgb(69,184,253)" stroke="rgb(69,184,253)" stroke-width="1" opacity="0.996078431372549" d="M 10.5 10 L 10.5 11 L 10.5 10 Z "></path><path fill="rgb(69,184,253)" stroke="rgb(69,184,253)" stroke-width="1" opacity="0.996078431372549" d="M 12.5 10 L 12.5 11 L 12.5 10 Z "></path><path fill="rgb(5,28,33)" stroke="rgb(5,28,33)" stroke-width="1" opacity="0.058823529411764705" d="M 14.5 10 L 14.5 11 L 14.5 10 Z "></path><path fill="rgb(5,28,33)" stroke="rgb(5,28,33)" stroke-width="1" opacity="0.058823529411764705" d="M 9.5 15 L 9.5 16 L 9.5 15 Z "></path><path fill="rgb(3,7,24)" stroke="rgb(3,7,24)" stroke-width="1" opacity="0.2627450980392157" d="M 10.5 7 L 10.5 8 L 10.5 7 Z "></path><path fill="rgb(3,7,24)" stroke="rgb(3,7,24)" stroke-width="1" opacity="0.2627450980392157" d="M 15.5 9 L 15.5 10 L 15.5 9 Z "></path><path fill="rgb(3,7,24)" stroke="rgb(3,7,24)" stroke-width="1" opacity="0.2627450980392157" d="M 0.5 11 L 0.5 12 L 0.5 11 Z "></path><path fill="rgb(36,52,158)" stroke="rgb(36,52,158)" stroke-width="1" opacity="1" d="M 6.5 10 L 6.5 11 L 6.5 10 Z "></path><path fill="rgb(36,52,158)" stroke="rgb(36,52,158)" stroke-width="1" opacity="1" d="M 1.5 11 L 1.5 12 L 1.5 11 Z "></path><path fill="rgb(5,4,20)" stroke="rgb(5,4,20)" stroke-width="1" opacity="0.7215686274509804" d="M 6.5 8 L 6.5 9 L 6.5 8 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.08627450980392157" d="M 4.5 11 L 6 11.5 L 4.5 12 L 4.5 11 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.08627450980392157" d="M 1.5 12 L 1.5 13 L 1.5 12 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.08627450980392157" d="M 6.5 15 L 6.5 16 L 6.5 15 Z "></path><path fill="rgb(81,252,254)" stroke="rgb(81,252,254)" stroke-width="1" opacity="1" d="M 4.5 6 L 4.5 7 L 4.5 6 Z "></path><path fill="rgb(81,252,254)" stroke="rgb(81,252,254)" stroke-width="1" opacity="1" d="M 4.5 8 L 4.5 9 L 4.5 8 Z "></path><path fill="rgb(81,252,254)" stroke="rgb(81,252,254)" stroke-width="1" opacity="1" d="M 7 11 L 9 11.5 Q 8 14 7 12.5 L 7 11 Z "></path><path fill="rgb(125,248,252)" stroke="rgb(125,248,252)" stroke-width="1" opacity="0.996078431372549" d="M 9.5 11 L 10 12.5 L 9 12.5 L 9.5 11 Z "></path><path fill="rgb(73,203,253)" stroke="rgb(73,203,253)" stroke-width="1" opacity="1" d="M 4.5 9 L 4.5 10 L 4.5 9 Z "></path><path fill="rgb(73,203,253)" stroke="rgb(73,203,253)" stroke-width="1" opacity="1" d="M 8.5 12 L 8.5 13 L 8.5 12 Z "></path><path fill="rgb(46,92,88)" stroke="rgb(46,92,88)" stroke-width="1" opacity="0.5843137254901961" d="M 10.5 11 L 11 12.5 L 10 12.5 L 10.5 11 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.03137254901960784" d="M 4.5 1 L 4.5 2 L 4.5 1 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.03137254901960784" d="M 5.5 3 L 5.5 4 L 5.5 3 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.03137254901960784" d="M 9.5 7 L 9.5 8 L 9.5 7 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.03137254901960784" d="M 12.5 12 L 12.5 13 L 12.5 12 Z "></path><path fill="rgb(13,13,19)" stroke="rgb(13,13,19)" stroke-width="1" opacity="0.07450980392156863" d="M 6.5 7 L 6.5 8 L 6.5 7 Z "></path><path fill="rgb(13,13,19)" stroke="rgb(13,13,19)" stroke-width="1" opacity="0.07450980392156863" d="M 5.5 13 L 5.5 14 L 5.5 13 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.011764705882352941" d="M 11.5 12 L 11.5 13 L 11.5 12 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.011764705882352941" d="M 5.5 14 L 5.5 15 L 5.5 14 Z "></path><path fill="rgb(64,190,219)" stroke="rgb(64,190,219)" stroke-width="1" opacity="0.9568627450980393" d="M 3.5 1 L 3.5 2 L 3.5 1 Z "></path><path fill="rgb(43,113,162)" stroke="rgb(43,113,162)" stroke-width="1" opacity="0.8117647058823529" d="M 13.5 7 L 13.5 8 L 13.5 7 Z "></path><path fill="rgb(43,113,162)" stroke="rgb(43,113,162)" stroke-width="1" opacity="0.8117647058823529" d="M 12.5 11 L 12.5 12 L 12.5 11 Z "></path><path fill="rgb(9,9,19)" stroke="rgb(9,9,19)" stroke-width="1" opacity="0.10196078431372549" d="M 10.5 14 L 10.5 15 L 10.5 14 Z "></path></svg> скрытый текст Выделить код Код:<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path fill="#050919" stroke="#050919" opacity=".176" d="M3.5 0v1-1zM1.5 1L2 2.5H1L1.5 1zM13.5 11v1-1zM8.5 15v1-1z"/><path fill="#367BDC" stroke="#367BDC" opacity=".969" d="M6.5 14v1-1z"/><path stroke="#000" opacity=".004" d="M.5 4L1 5.5H0L.5 4zM8.5 7v1-1z"/><path fill="#1B3672" stroke="#1B3672" opacity=".627" d="M1.5 4v1-1zM12.5 7v1-1zM14.5 7v1-1zM10.5 13v1-1z"/><path fill="#3F9CF8" stroke="#3F9CF8" opacity=".996" d="M3.5 4v1-1zM13.5 9v1-1zM1.5 10v1-1zM7.5 10v1-1zM9.5 13v1-1z"/><path fill="#080E3A" stroke="#080E3A" opacity=".42" d="M1.5 3v1-1zM5.5 4v1-1zM11.5 7v1-1zM15.5 7v1-1zM8.5 8v1-1zM3.5 11v1-1zM7.5 15v1-1z"/><path fill="#02030A" stroke="#02030A" opacity=".251" d="M1.5 0v1-1zM1.5 6v1-1zM5.5 12v1-1z"/><path fill="#4DEFFE" stroke="#4DEFFE" d="M3.5 6v1-1zM11.5 10v1-1zM7.5 13v1-1z"/><path fill="#3F94CE" stroke="#3F94CE" opacity=".996" d="M2.5 7l1.5.5-1.5.5V7zM3.5 10v1-1zM6.5 12v1-1z"/><path fill="#3349DC" stroke="#3349DC" opacity=".988" d="M4.5 3L5 4.5H4L4.5 3zM1.5 5q2.5 1 1 2-2.5-1-1-2zM5.5 7L6 8.5H5L5.5 7zM10.5 9q1.5 1-1 2-1.5-1 1-2zM6.5 11v1-1z"/><path fill="#02051F" stroke="#02051F" opacity=".325" d="M.5 7v1-1zM7.5 8v1-1z"/><path fill="#150B62" stroke="#150B62" opacity=".761" d="M5.5 5v1-1zM9.5 8v1-1zM.5 10v1-1zM4.5 10v1-1z"/><path fill="#245A8B" stroke="#245A8B" opacity=".718" d="M4.5 2v1-1zM14.5 9q1.5 1-1 2-1.5-1 1-2zM11.5 11v1-1zM9.5 14v1-1z"/><path fill="#2726B1" stroke="#2726B1" opacity=".922" d="M5.5 6v1-1zM.5 8v1-1zM8.5 14v1-1z"/><path fill="#1D2182" stroke="#1D2182" opacity=".871" d="M1.5 7v1-1zM.5 9v1-1zM2.5 11v1-1z"/><path fill="#41A6F9" stroke="#41A6F9" opacity=".996" d="M1.5 9l1.5.5-1.5.5V9zM8.5 10v1-1zM8.5 13q1.5 1-1 2-1.5-1 1-2z"/><path fill="#4AD9FE" stroke="#4AD9FE" d="M4.5 7v1-1zM3.5 9v1-1z"/><path fill="#21557E" stroke="#21557E" d="M5.5 9v1-1z"/><path fill="#2600B2" stroke="#2600B2" opacity=".988" d="M2.5 0v1-1zM2.5 3L3 4.5H2L2.5 3zM1.5 8v1-1zM12.5 8v1-1zM7.5 9l1.5.5-1.5.5V9z"/><path fill="#15055D" stroke="#15055D" opacity=".976" d="M2.5 2v1-1zM10.5 8l1.5.5-1.5.5V8zM6.5 9q1.5 1-1 2-1.5-1 1-2z"/><path fill="#301ADF" stroke="#301ADF" d="M2.5 1v1-1zM2.5 5v1-1zM2.5 8v1-1zM15.5 8v1-1zM9.5 9v1-1z"/><path fill="#3C85F6" stroke="#3C85F6" opacity=".996" d="M3.5 2L4 3.5H3L3.5 2zM4.5 5v1-1zM13.5 8l1.5.5-3.5 1.5V9l2-1zM6.5 13v1-1z"/><path fill="#45B8FD" stroke="#45B8FD" opacity=".996" d="M3.5 5v1-1zM3.5 8v1-1zM2.5 10v1-1zM10.5 10v1-1zM12.5 10v1-1z"/><path fill="#051C21" stroke="#051C21" opacity=".059" d="M14.5 10v1-1zM9.5 15v1-1z"/><path fill="#030718" stroke="#030718" opacity=".263" d="M10.5 7v1-1zM15.5 9v1-1zM.5 11v1-1z"/><path fill="#24349E" stroke="#24349E" d="M6.5 10v1-1zM1.5 11v1-1z"/><path fill="#050414" stroke="#050414" opacity=".722" d="M6.5 8v1-1z"/><path stroke="#000" opacity=".086" d="M4.5 11l1.5.5-1.5.5v-1zM1.5 12v1-1zM6.5 15v1-1z"/><path fill="#51FCFE" stroke="#51FCFE" d="M4.5 6v1-1zM4.5 8v1-1zM7 11l2 .5q-1 2.5-2 1V11z"/><path fill="#7DF8FC" stroke="#7DF8FC" opacity=".996" d="M9.5 11l.5 1.5H9l.5-1.5z"/><path fill="#49CBFD" stroke="#49CBFD" d="M4.5 9v1-1zM8.5 12v1-1z"/><path fill="#2E5C58" stroke="#2E5C58" opacity=".584" d="M10.5 11l.5 1.5h-1l.5-1.5z"/><path stroke="#000" opacity=".031" d="M4.5 1v1-1zM5.5 3v1-1zM9.5 7v1-1zM12.5 12v1-1z"/><path fill="#0D0D13" stroke="#0D0D13" opacity=".075" d="M6.5 7v1-1zM5.5 13v1-1z"/><path stroke="#000" opacity=".012" d="M11.5 12v1-1zM5.5 14v1-1z"/><path fill="#40BEDB" stroke="#40BEDB" opacity=".957" d="M3.5 1v1-1z"/><path fill="#2B71A2" stroke="#2B71A2" opacity=".812" d="M13.5 7v1-1zM12.5 11v1-1z"/><path fill="#090913" stroke="#090913" opacity=".102" d="M10.5 14v1-1z"/></svg> |
unter_officer > 25-07-2021 16:29:13 |
sandro79 пишет
Не помню уже откуда взял, но завалялась у меня эта бабочка в PNG, размером 170px на 170px. |
Vitaliy V. > 25-07-2021 16:39:20 |
sandro79 пишет
Под первым у вас вообще то png в обертке SVG, а там где 14,6 КБ кода, нет повтора как в последнем sandro79 пишет
Нет никаким редактором не получится нормально конвертировать растровое изображение в векторное SVG |
sandro79 > 25-07-2021 17:13:52 |
unter_officer пишет
Спасибо! Тоже пригодится, буду экспериментировать. Vitaliy V. пишет
Да-да, имелся в виду 14,6 КБ. Про тот забыл уже.
Да, точно, вот же ж, два раза вставил.
Да-да, я так уже поверхностно понимаю суть, тут ещё вы говорили. Надо будет так, хоть в общем, ознакомится с этой темой. Огромное Спасибо за разъяснение. Подправил тот код под третьим спойлером, убрал дубляж, хоть и не работает, но так, для порядка. |
sandro79 > 29-07-2021 20:57:04 |
Vitaliy V. Новый код кнопки с новой иконкой Выделить код Код:try { CustomizableUI.createWidget({ id: "b-sound-muted-all-tabs", type: "custom", label: "Переключить звук", tooltiptext: "ЛКМ: Переключить звук в выделенных вкладках\nСКМ: Закрыть другие вкладки с источником звука\nПКМ: Переключить звук во всех вкладках", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onBuild(doc) { var trbn = doc.createXULElement("toolbarbutton"), win = doc.defaultView; trbn.id = "b-sound-muted-all-tabs"; trbn.className = "toolbarbutton-1 chromeclass-toolbar-additional"; trbn.setAttribute("label", "Переключить звук"); trbn.setAttribute("tooltiptext", "ЛКМ: Переключить звук в выделенных вкладках\nСКМ: Закрыть другие вкладки с источником звука\nПКМ: Переключить звук во всех вкладках"); trbn.setAttribute("context", false); trbn.setAttribute("image", "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 48 48'><g style='fill:context-fill;fill-opacity:context-fill-opacity;'><path d='M 22.5,4.49 15,12 H 10.5 C 6,12 3,16.5 3,21 L 3,27 C 3,31.5 5.99,36 10.5,36 H 15 L 22.5,43.5 C 24.9,45.9 27,45 27,43.5 V 4.49 C 27,2.99 24.9,2.09 22.5,4.49 Z'/><path d='M 39,24 C 39,19 35,15 30,15 28,15 28,18 30,18 33.3,18 36,20.7 36,24 36,27.3 33.3,30 30,30 28,30 28,33 30,33 35,33 39,29 39,24 Z'/><path d='M 30,9 C 28,9 28,12 30,12 36.6,12 42,17.4 42,24 42,30.6 36.6,36 30,36 28,36 28,39 30,39 38.4,39 45,32.4 45,24 45,15.6 38.4,9 30,9 Z'/></g></svg>"); trbn.addEventListener("click", e => { if (e.button == 0) { win.gBrowser.toggleMuteAudioOnMultiSelectedTabs(win.gBrowser.selectedTab); } else if (e.button == 1) { for (let tab of win.gBrowser.visibleTabs.filter(tab => !tab.selected && (tab.muted || tab.soundPlaying))) win.gBrowser.removeTab(tab); } else if (e.button == 2) { e.preventDefault(); e.stopPropagation(); let tabsToToggle; if (win.gBrowser.selectedTab.activeMediaBlocked) { tabsToToggle = win.gBrowser.visibleTabs.filter(tab => tab.activeMediaBlocked || tab.linkedBrowser.audioMuted); } else { let tabMuted = win.gBrowser.selectedTab.linkedBrowser.audioMuted; tabsToToggle = win.gBrowser.visibleTabs.filter(tab => (tab.linkedBrowser.audioMuted == tabMuted && !tab.activeMediaBlocked) || (tab.activeMediaBlocked && tabMuted)); } for (let tab of tabsToToggle) tab.toggleMuteAudio(); } }); return trbn; }, }); } catch(e) {} скрытый текст Выделить код Код:data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='16' height='16' fill='context-fill' fill-opacity='context-fill-opacity'><path d='M7.245 1.35 4.117 5 2 5a2 2 0 0 0-2 2l0 2a2 2 0 0 0 2 2l2.117 0 3.128 3.65C7.848 15.353 9 14.927 9 14L9 2c0-.927-1.152-1.353-1.755-.65z'/><path d='M11.764 15a.623.623 0 0 1-.32-1.162 6.783 6.783 0 0 0 3.306-5.805 6.767 6.767 0 0 0-3.409-5.864.624.624 0 1 1 .619-1.085A8.015 8.015 0 0 1 16 8.033a8.038 8.038 0 0 1-3.918 6.879c-.1.06-.21.088-.318.088z'/><path d='M11.434 11.85A4.982 4.982 0 0 0 13.25 8a4.982 4.982 0 0 0-1.819-3.852l-.431 0 0 7.702.434 0z'/></svg> |
Vitaliy V. > 30-07-2021 00:19:31 |
sandro79 пишет
для иконок загруженных по data: -moz-context-properties не работает sandro79 пишет
Ну так и впишите этот адрес вместо data: ... |
sandro79 > 30-07-2021 00:52:03 |
Vitaliy V. пишет
Да, это пробовал. Но почему-то, как и с вариантом chrome://user_chrome_files/content/далее путь к иконке, иконка краснеет.
Да, вот это сработало как надо. Да надо было сразу так сделать и проверить, зациклило меня, чтоб внутрь скрипта иконку встроить. скрытый текст Выделить код Код:try { CustomizableUI.createWidget({ id: "b-sound-muted-all-tabs", type: "custom", label: "Переключить звук", tooltiptext: "ЛКМ: Переключить звук в выделенных вкладках\nСКМ: Закрыть другие вкладки с источником звука\nПКМ: Переключить звук во всех вкладках", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onBuild(doc) { var trbn = doc.createXULElement("toolbarbutton"), win = doc.defaultView; trbn.id = "b-sound-muted-all-tabs"; trbn.className = "toolbarbutton-1 chromeclass-toolbar-additional"; trbn.setAttribute("label", "Переключить звук"); trbn.setAttribute("tooltiptext", "ЛКМ: Переключить звук в выделенных вкладках\nСКМ: Закрыть другие вкладки с источником звука\nПКМ: Переключить звук во всех вкладках"); trbn.setAttribute("context", false); trbn.setAttribute("image", "chrome://global/skin/media/audio.svg"); trbn.addEventListener("click", e => { if (e.button == 0) { win.gBrowser.toggleMuteAudioOnMultiSelectedTabs(win.gBrowser.selectedTab); } else if (e.button == 1) { for (let tab of win.gBrowser.visibleTabs.filter(tab => !tab.selected && (tab.muted || tab.soundPlaying))) win.gBrowser.removeTab(tab); } else if (e.button == 2) { e.preventDefault(); e.stopPropagation(); let tabsToToggle; if (win.gBrowser.selectedTab.activeMediaBlocked) { tabsToToggle = win.gBrowser.visibleTabs.filter(tab => tab.activeMediaBlocked || tab.linkedBrowser.audioMuted); } else { let tabMuted = win.gBrowser.selectedTab.linkedBrowser.audioMuted; tabsToToggle = win.gBrowser.visibleTabs.filter(tab => (tab.linkedBrowser.audioMuted == tabMuted && !tab.activeMediaBlocked) || (tab.activeMediaBlocked && tabMuted)); } for (let tab of tabsToToggle) tab.toggleMuteAudio(); } }); return trbn; }, }); } catch(e) {} Наткнулся недавно на вроде бы полезный скрипт. Исправляет контекстное меню журнала. Было|Cтало |
momo2000 > 10-08-2021 16:30:44 |
ПАРОЛИ/КУКИ FindBar для custom_script_all_win.js в секцию load Код для CB, но отлично работает в ucf и в новых версиях FF Туда же горячая клавиша для FindBar Выделить код Код:addEventListener('keydown', e=> { if(e.ctrlKey&e.code=="KeyF"&&!gFindBar.hidden) { e.preventDefault()+gFindBar.close() } }); |
rubel > 22-08-2021 09:30:16 |
Dumby |
Dumby > 24-08-2021 13:42:16 |
rubel скрытый текст Выделить код Код:(async self => CustomizableUI.createWidget(({ label: "Unnamed", tooltiptext: "Unnamed", fileName: "http-request-log.txt", images: { true: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP/AwMD/AAAA/wAAAP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ==", false: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP/AwMD/AAAA/wAAAP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AACsQQAArEEAAKxBH/isQR/4rEEf+KxBH/isQR/4rEEf+KxBH/isQR/4rEEf+KxBH/isQQAArEEAAKxBAACsQQ==" }, id: "ucf-httpRequestLogger", localized: false, init(pref) { var topic = "http-on-modify-request"; this.toggle = () => Services.prefs.setBoolPref(pref, !this.active); var prefObs = () => { var val = Services.prefs.getBoolPref(pref, false); if (this.active ^ (this.active = val)) Services.obs[`${val ? "add" : "remove"}Observer`](this, topic); this.setBtnsState(); } prefObs(); Services.prefs.addObserver(pref, prefObs); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.prefs.removeObserver(pref, prefObs); self.active && Services.obs.removeObserver(self, topic); }, "quit-application-granted"); return self = this; }, onCreated(btn) { btn._handleClick = this.toggle; btn.setAttribute("image", this.images[this.active]); }, setBtnsState() {this.setBtnsState = () => { var img = this.images[this.active]; var widget = CustomizableUI.getWidget(this.id); for(var win of CustomizableUI.windows) widget.forWindow(win).node?.setAttribute("image", img); }}, log: "", observe(channel) { if (!(channel instanceof Ci.nsIHttpChannel)) return; this.log += `${ channel.referrerInfo?.originalReferrer?.spec || "(none)" } ${ channel.requestMethod } ${ channel.URI.spec }\r\n`; this.busy || this.write(); }, write() { var file = Services.dirsvc.get("Desk", Ci.nsIFile); file.append(this.fileName); var {path} = file; var {IOUtils} = Cu.getGlobalForObject(Cu); var modes = [{mode: "create"}, {mode: "append"}]; var unbusy = () => { this.busy = false; this.log && this.write(); } (this.write = () => { this.busy = true; var {log} = this; this.log = ""; IOUtils.writeUTF8(path, log, modes[+file.exists()]) .finally(unbusy); })(); } }).init("ucf.httpRequestLogger.enabled")))(); |
unter_officer > 24-08-2021 16:04:11 |
Dumby пишет
Dumby, большое спасибо. |
rubel > 24-08-2021 17:54:28 |
Dumby |
bezuma > 24-08-2021 19:24:38 |
unter_officer, rubel добавлено чорд возьми, нашел его в персонализации |
Vitaliy V. > 20-09-2021 02:40:48 |
Новая версия UserChromeFiles со многими изменениями в коде, готова к использованию насколько могу судить, скрытый текст Выделить код Код:var uiCustomization = "browser.uiCustomization.state"; Services.prefs.setCharPref(uiCustomization, Services.prefs.getCharPref(uiCustomization, "").replace(/"add-/g, "\"ucf-")); врядли это затронет другие кнопки хоть и вероятность есть, или при закрытом браузере отредактируйте настройку "browser.uiCustomization.state" в prefs.js заменив "add- на "ucf- PS: Да и коды для загрузки доп. файлов скриптов теперь не требуются ... |
kokoss > 20-09-2021 11:04:17 |
Vitaliy V. |
Vitaliy V. > 20-09-2021 11:43:37 |
kokoss скрытый текст scriptschrome: { // Для докум. окна браузера [ChromeOnly] domload: [ // По событию DOMContentLoaded ], Да и параметр ucfobj должен быть true для моих скриптов (если не указано), и false или отсутствовать для других (если автором скрипта не указано обратное) PS: custom_script_win.js и custom_script_all_win.js не нужно подключать в CustomStylesScripts.jsm И кстати коды загрузчиков скриптов для custom_script_win.js custom_script_all_win.js также будут работать можете использовать их если нравится |
kokoss > 20-09-2021 15:45:29 |
Vitaliy V. пишет
Пока не ясно как это работает, но надеюсь разберусь Vitaliy V. пишет
Спасибо! |
Vitaliy V. > 20-09-2021 16:39:59 |
kokoss пишет
А что не ясно, как работает (алгоритм, непонятно объяснил) или это не работает для вас? |
kokoss > 20-09-2021 17:01:25 |
Vitaliy V. пишет
Я же не сказал что не работает, просто многовато изменений.
да вроде понятно, если что спрошу |
Vitaliy V. > 20-09-2021 18:45:18 |
kokoss пишет
Возможностей тоже прибавилось и потому что для более новых версий , 78+ теперь |
sandro79 > 20-09-2021 21:00:57 |
Vitaliy V. скрытый текст Выделить код Код:var EXPORTED_SYMBOLS = ["UcfStylesScripts"]; var UcfStylesScripts = { /* ************************▼ Настройки ▼************************ */ /** * Настройки стилей: * path: путь к файлу от папки custom_styles * type: права стиля AGENT_SHEET, AUTHOR_SHEET или USER_SHEET */ styleschrome: [ // Для докум. всех окон [ChromeOnly] // { path: "custom_styles_chrome_author.css", type: "AUTHOR_SHEET", sheet(f) { preloadSheet(this, f); }, }, { path: "custom_styles_chrome_user.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, { path: "special_widget.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Special Widgets { path: "auto_hide_sidebar.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Auto Hide Sidebar ], stylesall: [ // Для всех документов // { path: "custom_styles_all_agent.css", type: "AGENT_SHEET", sheet() { registerSheet(this); }, }, // { path: "custom_styles_all_user.css", type: "USER_SHEET", sheet() { registerSheet(this); }, }, ], /** * Настройки скриптов: * path: путь к скрипту от папки custom_scripts * urlregxp: Адрес где работает скрипт в регулярном выражении, только Для докум. всех окон [ChromeOnly] * ucfobj: true - загружать скрипт в специально созданный объект либо в window, для скриптов В фоне [System Principal] не используется */ scriptschrome: { // Для докум. окна браузера [ChromeOnly] domload: [ // По событию DOMContentLoaded ], load: [ // По событию load // { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar { path: "scripts3/favicon_in_urlbar.js", ucfobj: true, }, { path: "scripts3/restart_item_in_menu.js", ucfobj: true, }, { path: "scripts3/urlbarhistorydropmarker.js", ucfobj: true, }, { path: "scripts3/contextmenuopenwith.js", ucfobj: true, }, { path: "scripts3/add_bookmark_to_bookmarks_menu.js", ucfobj: false, }, { path: "scripts3/pageInfo.js", ucfobj: false, }, { path: "scripts3/places_addBookmarks.js", ucfobj: false, }, { path: "scripts3/search_engine_icon.js", ucfobj: false, }, { path: "scripts3/tabs_focus.js", ucfobj: false, }, { path: "scripts3/tabstoolbar_doubleclick_opennewtab.js", ucfobj: false, }, { path: "scripts2/ucjsDownloadsManager.uc.js", ucfobj: false, }, ], }, scriptsallchrome: { // Для докум. всех окон [ChromeOnly] domload: [ // По событию DOMContentLoaded // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, { path: "scripts2/ucjsDownloadsManager2.uc.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, ], load: [ // По событию load // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, ], }, scriptsbackground: [ // В фоне [System Principal] { path: "custom_script.js", }, ], }; /* ************************▲ Настройки ▲************************ */ var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var UcfSSS = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var preloadSheet = (obj, func) => { try { let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`); let type = UcfSSS[obj.type]; let preload = UcfSSS.preloadSheet(uri, type); (obj.sheet = f => { try { f(preload, type); } catch (e) {} })(func); } catch (e) { obj.sheet = () => {}; } }; var registerSheet = async obj => { try { let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`); let type = UcfSSS[obj.type]; if (!UcfSSS.sheetRegistered(uri, type)) UcfSSS.loadAndRegisterSheet(uri, type); } catch (e) {} }; Добавление второй части скрипта в эту же секцию результата не дало, ну это и было ожидаемо. |
Vitaliy V. > 21-09-2021 01:06:26 |
sandro79 пишет
Ок добавил ещё параметр где можно указать функцию которая выполнится при загрузке скрипта вот так это должно выглядеть для окна библиотеки скрытый текст Выделить код Код:load: [ // По событию load { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.places();" }, ], и для CustomStylesScriptsChild.jsm если нужно в контенте скрытый текст Выделить код Код:pageshow: [ // По событию pageshow { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, func: "ucf_where_to_open_link.places();" }, ], sandro79 пишет
Да с чего вы взяли что ваш ucjsDownloadsManager это окно библиотеки? Там все вместе и заклади и загрузки... скрытый текст |
sandro79 > 21-09-2021 02:28:22 |
Vitaliy V. пишет
Я так понял, что это было добавлено в нижнюю секцию "Настройки", обновил в обоих файлах и обновил user_chrome.js. В окне библиотеке сработало, для CustomStylesScriptsChild.jsm не добавлял, в контенте не нужно. Но вот почему не работает из боковой панели, значка журнала на панели, журнала из панели меню, ну то есть, как я понимаю в окне браузера "Для докум. окна браузера"? Вот это самое главное, о чём я забыл упомянуть выше, что вообще нигде не работает, кроме как если добавить загрузчик в custom_script_all_win.js, хотя можно и в custom_script_win.js.
Да, в ходе экспериментов я это понял, когда оставил в адресе в регулярном выражении только chrome:/ - так кажется и серипт заработал. Сейчас с вашим адресом тоже работает. Только вот с ucf_wheretoopenlink.js не могу до конца разобраться. скрытый текст Выделить код Код:var EXPORTED_SYMBOLS = ["UcfStylesScripts"]; var UcfStylesScripts = { /* ************************▼ Настройки ▼************************ */ /** * Настройки стилей: * path: путь к файлу от папки custom_styles * type: права стиля AGENT_SHEET, AUTHOR_SHEET или USER_SHEET */ styleschrome: [ // Для докум. всех окон [ChromeOnly] // { path: "custom_styles_chrome_author.css", type: "AUTHOR_SHEET", sheet(f) { preloadSheet(this, f); }, }, { path: "custom_styles_chrome_user.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, { path: "special_widget.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Special Widgets { path: "auto_hide_sidebar.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Auto Hide Sidebar ], stylesall: [ // Для всех документов { path: "custom_styles_all_agent.css", type: "AGENT_SHEET", sheet() { registerSheet(this); }, }, // { path: "custom_styles_all_user.css", type: "USER_SHEET", sheet() { registerSheet(this); }, }, ], /** * Настройки скриптов: * path: путь к скрипту от папки custom_scripts * urlregxp: Адрес где работает скрипт в регулярном выражении, только Для докум. всех окон [ChromeOnly] * ucfobj: true - загружать скрипт в специально созданный объект либо в window, для скриптов В фоне [System Principal] не используется * func: Функция в виде строки которая выполнится при загрузке скрипта, только Для докум. всех окон [ChromeOnly] */ scriptschrome: { // Для докум. окна браузера [ChromeOnly] domload: [ // По событию DOMContentLoaded ], load: [ // По событию load // { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar { path: "scripts3/favicon_in_urlbar.js", ucfobj: true, }, { path: "scripts3/restart_item_in_menu.js", ucfobj: true, }, { path: "scripts3/urlbarhistorydropmarker.js", ucfobj: true, }, { path: "scripts3/contextmenuopenwith.js", ucfobj: true, }, { path: "scripts3/add_bookmark_to_bookmarks_menu.js", ucfobj: false, }, { path: "scripts3/pageInfo.js", ucfobj: false, }, { path: "scripts3/places_addBookmarks.js", ucfobj: false, }, { path: "scripts3/search_engine_icon.js", ucfobj: false, }, { path: "scripts3/tabs_focus.js", ucfobj: false, }, { path: "scripts3/tabstoolbar_doubleclick_opennewtab.js", ucfobj: false, }, { path: "scripts2/ucjsDownloadsManager.uc.js", ucfobj: false, }, { path: "scripts2/ucf_wheretoopenlink.js", ucfobj: false, }, ], }, scriptsallchrome: { // Для докум. всех окон [ChromeOnly] domload: [ // По событию DOMContentLoaded // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, { path: "scripts2/ucjsDownloadsManager2.uc.js", urlregxp: /chrome:\/\/browser\/content\/downloads\/contentAreaDownloadsView\.xhtml/, ucfobj: false, }, ], load: [ // По событию load // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.places();" }, ], }, scriptsbackground: [ // В фоне [System Principal] { path: "custom_script.js", }, ], }; /* ************************▲ Настройки ▲************************ */ var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var UcfSSS = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var preloadSheet = (obj, func) => { try { let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`); let type = UcfSSS[obj.type]; let preload = UcfSSS.preloadSheet(uri, type); (obj.sheet = f => { try { f(preload, type); } catch (e) {} })(func); } catch (e) { obj.sheet = () => {}; } }; var registerSheet = async obj => { try { let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`); let type = UcfSSS[obj.type]; if (!UcfSSS.sheetRegistered(uri, type)) UcfSSS.loadAndRegisterSheet(uri, type); } catch (e) {} }; |
Vitaliy V. > 21-09-2021 02:57:54 |
sandro79 скрытый текст Выделить код Код:{ path: "scripts2/ucf_wheretoopenlink.js", ucfobj: false, func: "ucf_where_to_open_link.browser();" }, А это для других докум. скрытый текст Выделить код Код:{ path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/bookmarksSidebar\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.bookmarksSidebar();" }, { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/historySidebar\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.historySidebar();" }, { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.places();" }, Дело в том что нужно разные функции добавлять, а это "ucf_where_to_open_link.places();" только для библиотеки |
sandro79 > 21-09-2021 08:38:38 |
Vitaliy V. CustomStylesScripts.jsm Выделить код Код:var EXPORTED_SYMBOLS = ["UcfStylesScripts"]; var UcfStylesScripts = { /* ************************▼ Настройки ▼************************ */ /** * Настройки стилей: * path: путь к файлу от папки custom_styles * type: права стиля AGENT_SHEET, AUTHOR_SHEET или USER_SHEET */ styleschrome: [ // Для докум. всех окон [ChromeOnly] // { path: "custom_styles_chrome_author.css", type: "AUTHOR_SHEET", sheet(f) { preloadSheet(this, f); }, }, { path: "custom_styles_chrome_user.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, { path: "special_widget.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Special Widgets { path: "auto_hide_sidebar.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Auto Hide Sidebar ], stylesall: [ // Для всех документов { path: "custom_styles_all_agent.css", type: "AGENT_SHEET", sheet() { registerSheet(this); }, }, // { path: "custom_styles_all_user.css", type: "USER_SHEET", sheet() { registerSheet(this); }, }, ], /** * Настройки скриптов: * path: путь к скрипту от папки custom_scripts * urlregxp: Адрес где работает скрипт в регулярном выражении, только Для докум. всех окон [ChromeOnly] * ucfobj: true - загружать скрипт в специально созданный объект либо в window, для скриптов В фоне [System Principal] не используется * func: Функция в виде строки которая выполнится при загрузке скрипта, только Для докум. всех окон [ChromeOnly] */ scriptschrome: { // Для докум. окна браузера [ChromeOnly] domload: [ // По событию DOMContentLoaded ], load: [ // По событию load // { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar { path: "scripts3/favicon_in_urlbar.js", ucfobj: true, }, { path: "scripts3/restart_item_in_menu.js", ucfobj: true, }, { path: "scripts3/urlbarhistorydropmarker.js", ucfobj: true, }, { path: "scripts3/contextmenuopenwith.js", ucfobj: true, }, { path: "scripts3/add_bookmark_to_bookmarks_menu.js", ucfobj: false, }, { path: "scripts3/pageInfo.js", ucfobj: false, }, { path: "scripts3/places_addBookmarks.js", ucfobj: false, }, { path: "scripts3/search_engine_icon.js", ucfobj: false, }, { path: "scripts3/tabs_focus.js", ucfobj: false, }, { path: "scripts3/tabstoolbar_doubleclick_opennewtab.js", ucfobj: false, }, { path: "scripts2/ucjsDownloadsManager.uc.js", ucfobj: false, }, { path: "scripts2/ucf_wheretoopenlink.js", ucfobj: false, func: "ucf_where_to_open_link.browser();" }, ], }, scriptsallchrome: { // Для докум. всех окон [ChromeOnly] domload: [ // По событию DOMContentLoaded // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, { path: "scripts2/ucjsDownloadsManager2.uc.js", urlregxp: /chrome:\/\/browser\/content\/downloads\/contentAreaDownloadsView\.xhtml/, ucfobj: false, }, ], load: [ // По событию load // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.places();" }, { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/bookmarksSidebar\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.bookmarksSidebar();" }, { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/historySidebar\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.historySidebar();" }, { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.places();" }, ], }, scriptsbackground: [ // В фоне [System Principal] { path: "scripts/add-sound-realtek-app.js", }, { path: "scripts/Close-Tabs-button.js", }, { path: "scripts/downloadPauseResumeButton.js", }, { path: "scripts/ExtensionOptionsMenu.js", }, { path: "scripts/LinkWinActor.js", }, { path: "scripts/PotPlayer.js", }, { path: "scripts/To_switch_proxy.js", }, { path: "scripts/ucf-copyURL.js", }, { path: "scripts/UCFNewTabPage.js", }, { path: "scripts/undo_closetab_button.js", }, { path: "scripts/yandex@search.js", }, ], }; /* ************************▲ Настройки ▲************************ */ var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var UcfSSS = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var preloadSheet = (obj, func) => { try { let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`); let type = UcfSSS[obj.type]; let preload = UcfSSS.preloadSheet(uri, type); (obj.sheet = f => { try { f(preload, type); } catch (e) {} })(func); } catch (e) { obj.sheet = () => {}; } }; var registerSheet = async obj => { try { let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`); let type = UcfSSS[obj.type]; if (!UcfSSS.sheetRegistered(uri, type)) UcfSSS.loadAndRegisterSheet(uri, type); } catch (e) {} }; CustomStylesScriptsChild.jsm Выделить код Код:var EXPORTED_SYMBOLS = ["UcfCustomStylesScriptsChild"]; var UcfStylesScripts = { /* ************************▼ Настройки ▼************************ */ /** * Настройки стилей: * path: путь к файлу от папки custom_styles * type: права стиля AGENT_SHEET, AUTHOR_SHEET или USER_SHEET */ stylescontent: [ // { path: "custom_styles_content_author.css", type: "AUTHOR_SHEET", sheet(f) { preloadSheet(this, f); }, }, { path: "custom_styles_content_user.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, ], /** * Настройки скриптов: * path: путь к скрипту от папки custom_scripts * urlregxp: Адрес где работает скрипт, в регулярном выражении * func: Функция в виде строки которая выполнится при загрузке скрипта */ scriptscontent: { DOMWindowCreated: [ // По событию DOMWindowCreated // { path: "example_all_about.js", urlregxp: /about:.*/, }, ], pageshow: [ // По событию pageshow // { path: "example_downloads.js", urlregxp: /about:downloads/, }, { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, func: "ucf_where_to_open_link.places();" }, { path: "scripts2/ucjsDownloadsManager2.uc.js", urlregxp: /about:downloads/, }, ], }, }; /* ************************▲ Настройки ▲************************ */ var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var UcfSSS = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var preloadSheet = async (obj, func) => { try { let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`); let type = UcfSSS[obj.type]; let preload = await UcfSSS.preloadSheetAsync(uri, type); (obj.sheet = f => { try { f(preload, type); } catch (e) {} })(func); } catch (e) { obj.sheet = () => {}; } }; class UcfCustomStylesScriptsChild extends JSWindowActorChild { actorCreated() { var win = this.contentWindow; var href = this.href = win?.location.href; if (!href) return; var { addSheet } = win.windowUtils; for (let s of UcfStylesScripts.stylescontent) s.sheet(addSheet); } handleEvent(e) { var href = this.href; if (!href || href === "about:blank") return; for (let s of UcfStylesScripts.scriptscontent[e.type]) { try { if (s.urlregxp.test(href)) { let win = this.contentWindow; Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${s.path}`, win, "UTF-8"); if (s.func) new win.Function(s.func).apply(win, null); } } catch (e) {} } } } |
_zt > 21-09-2021 13:32:26 |
Vitaliy V. скрытый текст Выделить код Код:try { ((img, preventClearThumbs) => { CustomizableUI.createWidget({ id: "bt-clear-part-history", label: "Очистить историю", tooltiptext: "Очистить историю", defaultArea: CustomizableUI.AREA_NAVBAR, onCreated: function(bt) { bt.image = img; }, onCommand: function(event) { var win = event.target.ownerDocument.defaultView; var itemsToClear = [ "cookies", "history", "formdata", "sessions", "cache", // "downloads", // "offlineApps", // "openWindows", "pluginData", // "siteSettings", ]; var range = win.Sanitizer.getClearRange(0); // Диапазон очистки, 0 = все, 1,2,3 = часы, 4 = сегодня win.Sanitizer.sanitize(itemsToClear, { ignoreTimespan: !range, range, }).then(() => { var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); alertsService.showAlertNotification(img, "Данные очищены!", "", false); win.setTimeout(()=> alertsService.closeAlert(), 2000); }); } }); })("data:image/png;base64,i...", null); } catch(e) {} В CustomStylesScripts.jsm присутстуют раскомментированные строки: { path: "translatetextorpage.js", ucfobj: true, }, { path: "contextproxy.js", ucfobj: true, }, но таких скриптов в комплекте нет. |
Vitaliy V. > 21-09-2021 18:05:46 |
_zt пишет
Иконки то нет _zt пишет
Это я из FullTheme забыл убрать прежде чем отправить Обновил в FullTheme файлы: common.css, CustomStylesScripts.jsm, CustomStylesScriptsChild.jsm |
_zt > 21-09-2021 21:21:10 |
Vitaliy V.
На старом то ucf этот скрипт уведомление выводит. Иконку я здесь из кода удалил так как много места занимает. |
Vitaliy V. > 21-09-2021 22:24:16 |
_zt пишет
Какое отношение имеет ucf к глюкам при очистке миниатюр сайтов, у вас же не может установленно на одном и том же профиле одновременно старый и новый ucf, чтобы это утверждать, а если профили разные то и подавно. Проверте есть ли такая ошибка при штатной очистке из браузера, если хотите с ucf и без |
_zt > 22-09-2021 02:47:05 |
Vitaliy V. Находим виновника И отправляем его в ссылку |
sandro79 > 22-09-2021 10:27:06 |
Vitaliy V. скрытый текст Выделить код Код:@-moz-document regexp("(?:https?|ftp|file):\/\/.*") { input, textarea { /* border: 1px solid rgba(131,137,150,.5); */ outline: 1px solid transparent; } } |
Dumby > 22-09-2021 11:07:04 |
sandro79 пишет
А в новом в custom_styles_all_user.css |
sandro79 > 22-09-2021 11:19:06 |
Dumby пишет
Да, работает там, в трёх соснах заблудился. Спасибо за подсказку Вот надо же, так облажаться И chrome и content работает, как и в старом. Всё отлично. |
Vitaliy V. > 22-09-2021 19:57:20 |
del |
_zt > 23-09-2021 03:38:51 |
Vitaliy V.
|
rubel > 23-09-2021 11:12:27 |
_zt |
kokoss > 23-09-2021 11:22:10 |
rubel Add, |
rubel > 23-09-2021 14:21:42 |
kokoss |
Vitaliy V. > 23-09-2021 18:32:00 |
_zt пишет
Нет в common.css только контент. Вроде готово, обновил FullTheme upd: обновил Sidebar Tabs и Тултипы с URL https://forum.mozilla-russia.org/viewto … 02#p792702 |
_zt > 24-09-2021 17:07:29 |
Vitaliy V. Прошлая версия |
Vitaliy V. > 24-09-2021 18:03:30 |
_zt пишет
А что тут объяснять |
_zt > 24-09-2021 22:56:50 |
Vitaliy V. |
sandro79 > 25-09-2021 12:16:33 |
Dumby скрытый текст Выделить код Код:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACNUlEQVQ4jY2TT08aQRjG59LL7mk/gxdvXmw/QD+MX6AePNhk0jThMGljEzLpxio0arQWMGpqomXBP7TQ3YpQ5J8CQf65C7vUKK61Hp4eFhMwBPskc5iZzO9987zPENIV9WyOTkxMPCGPaJIxcdq7NdJ3SJcj4+/jdns+WvMPg1AqC+5vujKjdhrUEx4lhBDyciE0NqPZbU8G8BWAz9pgyCRj4oKqK0t5wJsF5MPr+rS8NkKmOJfc301tMQesl4BQFdhJ9UMolYX1pK5slYGNEuAvAF7VCFJKBUIIIS7OpYW4pX4pA/t14KgJRLMOhDEm7mZ1JaYDB3UgXAXWkkaQUlnoa9HFubSRMrXoOXBsAuVLIFGoBuJFXcn/BtIWkGgBoUxP5YdycS7tnVhqvg3UO0D7D9CygUbHAaoFI0hlefDje3HOpWTZ1Jo2cHMH2HeAeQMkS0Mq94oxJv4qG4p5A1z9ddb5NRDL1XyP5oTKshA71ZXiBVC5dFpv2kDlCshYwHZqCIQxJm4f64pmOGalLUAt6ErqzFKLF0CyBUQagO9wAIRSWViN68rOGRCqOeNSum5zzqUfRVP7aQDhGrBZAuaiPZBJxsS5mK6snDgB2SgBgUT/nDnnUjBnqV8rQKAIfMwCM3tdyOul/Wfuo9vObNqJqEcd7LaLc8mfNLVPp8CHNPBWta0X8qbzH+jq4fM32m3n3cGAhD2AzGuWyuO2RZcj432XU4u7T/9nzi7OpVcrobH7/T9AEdt1RBP8kgAAAABJRU5ErkJggg== Закинул в папку svg комплекта эту иконку, чтоб белой была на тёмном фоне без надобности включения svg.context-properties.content.enabled. Прописал путь к иконке chrome://user_chrome_files/content/custom_styles/svg/panel-icon-cancel.svg, иконка появилась, всё работает нормально скрытый текст Выделить код Код:CustomizableUI.createWidget({ id: "Close-Tabs-button", label: "Закрыть другие вкладки", tooltiptext: "Закрыть другие вкладки", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { btn._handleClick = this.close; btn.setAttribute("image", "chrome://user_chrome_files/content/custom_styles/svg/panel-icon-cancel.svg"); }, close() { var gb = this.ownerGlobal.gBrowser; gb.removeAllTabsBut(gb.selectedTab); } }); скрытый текст |
Dumby > 25-09-2021 13:33:51 |
sandro79 Но можно во viewBox подогнать x, y, width и height. |
sandro79 > 25-09-2021 14:24:57 |
Dumby пишет
6 6 20 20 всё-же крупновато получается. Но попробовал подрегулировать до viewBox="5 5 22 22", почти как с оригинальной svg и стилем, но чуть всё-равно крупнее. А 6 6 23 23 попробовал - размер визуально вроде не отличается, но сдвигается вверх и влево. Никак не получается один к одному подогнать. |
Dumby > 25-09-2021 15:02:35 |
sandro79 пишет
Вот все центрированные варианты скрытый текст Выделить код Код:viewBox="0 0 32 32" viewBox="1 1 30 30" viewBox="2 2 28 28" viewBox="3 3 26 26" viewBox="4 4 24 24" viewBox="5 5 22 22" viewBox="6 6 20 20" Хотя, может можно не целые числа, не проверял.
Допустим, в атрибут style. Может не сработать, скрытый текст Выделить код Код:CustomizableUI.createWidget({ id: "Close-Tabs-button", label: "Закрыть другие вкладки", tooltiptext: "Закрыть другие вкладки", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { btn.render = this.render; btn._handleClick = this.close; btn.setAttribute("image", "chrome://user_chrome_files/content/custom_styles/svg/panel-icon-cancel.svg"); }, render() { delete this.render; this.render(); this.icon.style.setProperty("padding", "2px", "important"); }, close() { var gb = this.ownerGlobal.gBrowser; gb.removeAllTabsBut(gb.selectedTab); } }); |
sandro79 > 25-09-2021 15:26:46 |
Dumby пишет
Спасибо, это тоже мне может пригодится в процессе экспериментов в дальнейшем. Пятый и шестой вариант, ну почти подходят.
Отлично всё, сработало! Теперь один в один. Огромное Вам Спасибо за помощь |
Dumby > 25-09-2021 15:48:41 |
sandro79 скрытый текст Выделить код Код:viewBox="0 0 32 32" viewBox="0.1 0.1 31.8 31.8" viewBox="0.2 0.2 31.6 31.6" viewBox="0.3 0.3 31.4 31.4" viewBox="0.4 0.4 31.2 31.2" viewBox="0.5 0.5 31 31" viewBox="0.6 0.6 30.8 30.8" viewBox="0.7 0.7 30.6 30.6" viewBox="0.8 0.8 30.4 30.4" viewBox="0.9 0.9 30.2 30.2" viewBox="1 1 30 30" viewBox="1.1 1.1 29.8 29.8" viewBox="1.2 1.2 29.6 29.6" viewBox="1.3 1.3 29.4 29.4" viewBox="1.4 1.4 29.2 29.2" viewBox="1.5 1.5 29 29" viewBox="1.6 1.6 28.8 28.8" viewBox="1.7 1.7 28.6 28.6" viewBox="1.8 1.8 28.4 28.4" viewBox="1.9 1.9 28.2 28.2" viewBox="2 2 28 28" viewBox="2.1 2.1 27.8 27.8" viewBox="2.2 2.2 27.6 27.6" viewBox="2.3 2.3 27.4 27.4" viewBox="2.4 2.4 27.2 27.2" viewBox="2.5 2.5 27 27" viewBox="2.6 2.6 26.8 26.8" viewBox="2.7 2.7 26.6 26.6" viewBox="2.8 2.8 26.4 26.4" viewBox="2.9 2.9 26.2 26.2" viewBox="3 3 26 26" viewBox="3.1 3.1 25.8 25.8" viewBox="3.2 3.2 25.6 25.6" viewBox="3.3 3.3 25.4 25.4" viewBox="3.4 3.4 25.2 25.2" viewBox="3.5 3.5 25 25" viewBox="3.6 3.6 24.8 24.8" viewBox="3.7 3.7 24.6 24.6" viewBox="3.8 3.8 24.4 24.4" viewBox="3.9 3.9 24.2 24.2" viewBox="4 4 24 24" viewBox="4.1 4.1 23.8 23.8" viewBox="4.2 4.2 23.6 23.6" viewBox="4.3 4.3 23.4 23.4" viewBox="4.4 4.4 23.2 23.2" viewBox="4.5 4.5 23 23" viewBox="4.6 4.6 22.8 22.8" viewBox="4.7 4.7 22.6 22.6" viewBox="4.8 4.8 22.4 22.4" viewBox="4.9 4.9 22.2 22.2" viewBox="5 5 22 22" viewBox="5.1 5.1 21.8 21.8" viewBox="5.2 5.2 21.6 21.6" viewBox="5.3 5.3 21.4 21.4" viewBox="5.4 5.4 21.2 21.2" viewBox="5.5 5.5 21 21" viewBox="5.6 5.6 20.8 20.8" viewBox="5.7 5.7 20.6 20.6" viewBox="5.8 5.8 20.4 20.4" viewBox="5.9 5.9 20.2 20.2" viewBox="6 6 20 20" |
sandro79 > 25-09-2021 16:20:21 |
Dumby пишет
Да, это работает. viewBox="4.7 4.7 22.6 22.6" подошло идеально, ну я не увидел визуально разницы. Спасибо Большое за таблицу. Тоже пригодится в дальнейшем. Почти получилось с кнопкой повтора с viewBox="4.7 4.7 22.6 22.6", округлости чуть снизу не хватает, но попробую ещё с другими числами. Да так и оставлю в окнах загрузок, нормально. |
voqabuhe > 26-09-2021 18:43:42 |
Vitaliy V. |
Vitaliy V. > 26-09-2021 19:24:51 |
voqabuhe |
voqabuhe > 26-09-2021 20:10:00 |
Vitaliy V. |
sandro79 > 26-09-2021 20:36:11 |
Vitaliy V. |
Vitaliy V. > 26-09-2021 23:33:02 |
sandro79 |
sandro79 > 26-09-2021 23:56:00 |
Vitaliy V. пишет
Ну да. Но ничего так, вполне удобно. Колесо у меня работает отлично. Добавлю себе в пост, чтоб не потерять, три варианта скрипта: старый с правленным мной под Протон адресом для иконки, новый без обновления по СКМ, и новый с обновлением страницы по СКМ скрытый текст browser.urlbar.suggest.history - true browser.urlbar.suggest.topsites - false скрытый текст Допротоновский адрес для иконки chrome://global/skin/icons/arrow-dropdown-16.svg В версиях 92+ этот скрипт лучше не использовать Выделить код Код:(this.urlbarhistorydropmarker = { dropmarker: null, provider: null, get style() { delete this.style; return this.style = "data:text/css;charset=utf-8," + encodeURIComponent(` #urlbar .urlbar-history-dropmarker { list-style-image: url("chrome://global/skin/icons/arrow-down.svg"); transition: opacity 0.15s ease; } #urlbar[switchingtabs] > #urlbar-input-container > .urlbar-history-dropmarker { transition: none; } #urlbar[usertyping] > #urlbar-input-container > .urlbar-history-dropmarker { display: none; } #nav-bar:not([customizing="true"]) > #nav-bar-customization-target > #urlbar-container:not(:hover) > #urlbar:not([focused]) > #urlbar-input-container > .urlbar-history-dropmarker { opacity: 0; } `); }, init(that) { Services.prefs.addObserver("browser.urlbar.suggest.history", this); Services.prefs.addObserver("browser.urlbar.suggest.topsites", this); that.unloadlisteners.push("urlbarhistorydropmarker"); var {UrlbarProviderTopSites: provider} = {UrlbarProviderTopSites: this.provider} = ChromeUtils.import("resource:///modules/UrlbarProviderTopSites.jsm"); if (!provider.orig_PRIORITY) { provider.orig_PRIORITY = provider.ucf_PRIORITY = provider.PRIORITY; delete provider.constructor.prototype.PRIORITY; Object.defineProperty(provider.constructor.prototype, "PRIORITY", { enumerable: true, get() { var priory = this.ucf_PRIORITY; this.ucf_PRIORITY = this.orig_PRIORITY; return priory; }, set(val) { this.ucf_PRIORITY = val; }, }); } if (Services.prefs.getBoolPref("browser.urlbar.suggest.history", false) && !Services.prefs.getBoolPref("browser.urlbar.suggest.topsites", true)) this.createDropmarker(); }, createDropmarker() { var fragment = MozXULElement.parseXULToFragment(`<image class="urlbar-history-dropmarker urlbar-icon chromeclass-toolbar-additional" role="button" tooltiptext="Показать историю"/>`); var dropmarker = this.dropmarker = fragment.firstElementChild; document.querySelector("#urlbar #page-action-buttons").before(fragment); dropmarker.addEventListener("mousedown", this); windowUtils.loadSheetUsingURIString(this.style, windowUtils.USER_SHEET); }, removeDropmarker() { this.dropmarker.removeEventListener("mousedown", this); this.dropmarker.remove(); this.dropmarker = null; windowUtils.removeSheetUsingURIString(this.style, windowUtils.USER_SHEET); }, destructor() { if (this.dropmarker) this.dropmarker.removeEventListener("mousedown", this); Services.prefs.removeObserver("browser.urlbar.suggest.history", this); Services.prefs.removeObserver("browser.urlbar.suggest.topsites", this); }, observe() { if (Services.prefs.getBoolPref("browser.urlbar.suggest.history", false) && !Services.prefs.getBoolPref("browser.urlbar.suggest.topsites", true) && !this.dropmarker) this.createDropmarker(); else if (this.dropmarker) this.removeDropmarker(); }, handleEvent(event) { event.preventDefault(); event.stopPropagation(); if (gURLBar.view.isOpen) gURLBar.view.close(); else { this.provider.PRIORITY = 0; gURLBar.focus(); gURLBar.startQuery({ allowAutofill: false }); } } }).init(this); скрытый текст Выделить код Код:(this.urlbarhistorydropmarker = { // -- Настройки --> hidewhenusertyping: false, // скрывать dropmarker при вводе copyurlpightclick: true, // копирование URL по ПКМ currentURIlabel: "Адрес текущей страницы в буфере обмена!", valueIsTypedlabel: "Содержимое адресной строки в буфере обмена!", ЛКМtooltiptext: "Показать историю", ПКМtooltiptext: "Копировать URL в буфер обмена", // <-- Настройки -- dropmarker: null, provider: null, get style() { delete this.style; return this.style = "data:text/css;charset=utf-8," + encodeURIComponent(` #urlbar .urlbar-history-dropmarker { list-style-image: url("chrome://global/skin/icons/arrow-down.svg") !important; transition: opacity 0.15s ease; } #urlbar[switchingtabs] > #urlbar-input-container > .urlbar-history-dropmarker { transition: none; } ${this.hidewhenusertyping ? `#urlbar[usertyping] > #urlbar-input-container > .urlbar-history-dropmarker { display: none; }` : ""} #nav-bar:not([customizing="true"]) > #nav-bar-customization-target > #urlbar-container:not(:hover) > #urlbar:not([focused]) > #urlbar-input-container > .urlbar-history-dropmarker { opacity: 0; } `); }, init(that) { Services.prefs.addObserver("browser.urlbar.suggest.history", this); Services.prefs.addObserver("browser.urlbar.suggest.topsites", this); that.unloadlisteners?.push("urlbarhistorydropmarker"); var { UrlbarProviderTopSites: provider } = { UrlbarProviderTopSites: this.provider } = ChromeUtils.import("resource:///modules/UrlbarProviderTopSites.jsm"); if (!provider.orig_PRIORITY) { provider.orig_PRIORITY = provider.ucf_PRIORITY = provider.PRIORITY; delete provider.constructor.prototype.PRIORITY; Object.defineProperty(provider.constructor.prototype, "PRIORITY", { enumerable: true, get() { var priory = this.ucf_PRIORITY; this.ucf_PRIORITY = this.orig_PRIORITY; return priory; }, set(val) { this.ucf_PRIORITY = val; }, }); } if (Services.prefs.getBoolPref("browser.urlbar.suggest.history", false) && !Services.prefs.getBoolPref("browser.urlbar.suggest.topsites", true)) this.createDropmarker(); }, createDropmarker() { var fragment = MozXULElement.parseXULToFragment(`<image class="urlbar-page-action urlbar-history-dropmarker urlbar-icon" tooltiptext="${ !this.copyurlpightclick ? `${this.ЛКМtooltiptext}` : `ЛКМ: ${this.ЛКМtooltiptext} ПКМ: ${this.ПКМtooltiptext}` }"/>`); var dropmarker = this.dropmarker = fragment.firstElementChild; document.querySelector("#urlbar #urlbar-go-button").after(fragment); dropmarker.addEventListener("mousedown", this); if (this.copyurlpightclick) dropmarker.addEventListener("click", this); windowUtils.loadSheetUsingURIString(this.style, windowUtils.USER_SHEET); }, removeDropmarker() { this.removeListeners(); this.dropmarker.remove(); this.dropmarker = null; windowUtils.removeSheetUsingURIString(this.style, windowUtils.USER_SHEET); }, removeListeners() { this.dropmarker.removeEventListener("mousedown", this); if (this.copyurlpightclick) this.dropmarker.removeEventListener("click", this); }, destructor() { if (this.dropmarker) this.removeListeners(); Services.prefs.removeObserver("browser.urlbar.suggest.history", this); Services.prefs.removeObserver("browser.urlbar.suggest.topsites", this); }, observe() { if (Services.prefs.getBoolPref("browser.urlbar.suggest.history", false) && !Services.prefs.getBoolPref("browser.urlbar.suggest.topsites", true) && !this.dropmarker) this.createDropmarker(); else if (this.dropmarker) this.removeDropmarker(); }, mousedown(e) { if (e.button !== 0) return; e.preventDefault(); e.stopPropagation(); if (gURLBar.view.isOpen) gURLBar.view.close(); else { this.provider.PRIORITY = 0; gURLBar.focus(); gURLBar.startQuery({ allowAutofill: false }); } }, click(e) { if (e.button !== 2) return; var currentURI = this.currentURIlabel, valueIsTyped = this.valueIsTypedlabel; var gBrowserBundle = { GetStringFromName(str) { return ({ "confirmationHint.currentURI.label": currentURI, "confirmationHint.valueIsTyped.label": valueIsTyped, })[str]; } }; var show = eval(`(function ${e.view.ConfirmationHint.show})`); var helper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); (this.click = e => { if (e.button !== 2) return; e.preventDefault(); e.stopPropagation(); var url, mesId; if (!gURLBar.valueIsTyped) { url = gURLBar.makeURIReadable(gBrowser.selectedBrowser.currentURI).displaySpec; mesId = "currentURI"; } else { url = gURLBar.untrimmedValue; mesId = "valueIsTyped"; } helper.copyString(url); show.call(ConfirmationHint, this.dropmarker, mesId, { hideArrow: true }); })(e); }, handleEvent(e) { this[e.type](e); }, }).init(this); скрытый текст Выделить код Код:(this.urlbarhistorydropmarker = { // -- Настройки --> hidewhenusertyping: false, // скрывать dropmarker при вводе reloadpage: true, // обновить текущую страницу по СКМ copyurlrightclick: true, // копирование URL по ПКМ copyvalueistyped: true, // при вводе копировать содержимое адресной строки вместо URL currentURIlabel: "Адрес текущей страницы в буфере обмена!", valueIsTypedlabel: "Содержимое адресной строки в буфере обмена!", Ltooltiptext: "Показать историю", Mtooltiptext: "Обновить текущую страницу", Rtooltiptext: "Копировать URL в буфер обмена", // <-- Настройки -- dropmarker: null, provider: null, get style() { delete this.style; return this.style = "data:text/css;charset=utf-8," + encodeURIComponent(` #urlbar .urlbar-history-dropmarker { list-style-image: url("chrome://global/skin/icons/arrow-down.svg") !important; transition: opacity 0.15s ease; } #urlbar[switchingtabs] > #urlbar-input-container > .urlbar-history-dropmarker { transition: none; } ${this.hidewhenusertyping ? `#urlbar[usertyping] > #urlbar-input-container > .urlbar-history-dropmarker { display: none; }` : ""} #nav-bar:not([customizing="true"]) > #nav-bar-customization-target > #urlbar-container:not(:hover) > #urlbar:not([focused]) > #urlbar-input-container > .urlbar-history-dropmarker { opacity: 0; } `); }, init(that) { Services.prefs.addObserver("browser.urlbar.suggest.history", this); Services.prefs.addObserver("browser.urlbar.suggest.topsites", this); that.unloadlisteners?.push("urlbarhistorydropmarker"); var { UrlbarProviderTopSites: provider } = { UrlbarProviderTopSites: this.provider } = ChromeUtils.import("resource:///modules/UrlbarProviderTopSites.jsm"); if (!provider.orig_PRIORITY) { provider.orig_PRIORITY = provider.ucf_PRIORITY = provider.PRIORITY; delete provider.constructor.prototype.PRIORITY; Object.defineProperty(provider.constructor.prototype, "PRIORITY", { enumerable: true, get() { var priory = this.ucf_PRIORITY; this.ucf_PRIORITY = this.orig_PRIORITY; return priory; }, set(val) { this.ucf_PRIORITY = val; }, }); } if (Services.prefs.getBoolPref("browser.urlbar.suggest.history", false) && !Services.prefs.getBoolPref("browser.urlbar.suggest.topsites", true)) this.createDropmarker(); }, get tooltipText() { delete this.tooltipText; var l = this.Ltooltiptext, m = "", r = ""; if (this.reloadpage) l = `ЛКМ: ${this.Ltooltiptext}`, m = ` СКМ: ${this.Mtooltiptext}`; if (this.copyurlrightclick) l = `ЛКМ: ${this.Ltooltiptext}`, r = ` ПКМ: ${this.Rtooltiptext}`; return this.tooltipText = `${l}${m}${r}`; }, createDropmarker() { var fragment = MozXULElement.parseXULToFragment(`<image class="urlbar-page-action urlbar-history-dropmarker urlbar-icon" tooltiptext="${this.tooltipText}"/>`); var dropmarker = this.dropmarker = fragment.firstElementChild; document.querySelector("#urlbar #urlbar-go-button").after(fragment); dropmarker.addEventListener("mousedown", this); if (this.copyurlrightclick || this.reloadpage) dropmarker.addEventListener("click", this); windowUtils.loadSheetUsingURIString(this.style, windowUtils.USER_SHEET); }, removeDropmarker() { this.removeListeners(); this.dropmarker.remove(); this.dropmarker = null; windowUtils.removeSheetUsingURIString(this.style, windowUtils.USER_SHEET); }, removeListeners() { this.dropmarker.removeEventListener("mousedown", this); if (this.copyurlrightclick || this.reloadpage) this.dropmarker.removeEventListener("click", this); }, destructor() { if (this.dropmarker) this.removeListeners(); Services.prefs.removeObserver("browser.urlbar.suggest.history", this); Services.prefs.removeObserver("browser.urlbar.suggest.topsites", this); }, observe() { if (Services.prefs.getBoolPref("browser.urlbar.suggest.history", false) && !Services.prefs.getBoolPref("browser.urlbar.suggest.topsites", true) && !this.dropmarker) this.createDropmarker(); else if (this.dropmarker) this.removeDropmarker(); }, mousedown(e) { if (e.button !== 0) return; e.preventDefault(); e.stopPropagation(); if (gURLBar.view.isOpen) gURLBar.view.close(); else { this.provider.PRIORITY = 0; gURLBar.focus(); gURLBar.startQuery({ allowAutofill: false, }); } }, click(e) { if (e.button === 0) return; var currentURI = this.currentURIlabel, valueIsTyped = this.valueIsTypedlabel; var gBrowserBundle = { GetStringFromName(str) { return ({ "confirmationHint.currentURI.label": currentURI, "confirmationHint.valueIsTyped.label": valueIsTyped, })[str]; } }; var show = eval(`(function ${e.view.ConfirmationHint.show})`); var helper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); (this.click = e => { if (e.button === 0) return; e.preventDefault(); e.stopPropagation(); if (e.button === 1) { BrowserReload(); return; } var url, mesId; if (!gURLBar.valueIsTyped || !this.copyvalueistyped) url = gURLBar.makeURIReadable(gBrowser.selectedBrowser.currentURI).displaySpec, mesId = "currentURI"; else url = gURLBar.untrimmedValue, mesId = "valueIsTyped"; helper.copyString(url); show.call(ConfirmationHint, this.dropmarker, mesId, { hideArrow: true }); })(e); }, handleEvent(e) { this[e.type](e); }, }).init(this); |
Kot DaVinci > 30-09-2021 10:21:31 |
Кто-нибудь может помоч мне с этой проблемой? |
Dumby > 30-09-2021 11:39:56 |
Kot DaVinci Лучше во второй код, потому что там "таблетка от сепараторов" прописана, |
Kot DaVinci > 30-09-2021 16:50:18 |
Dumby, спасибо. Работает как надо. |
Dumby > 04-10-2021 18:42:27 |
egorsemenov06 скрытый текст Выделить код Код:// var evt = node.ownerDocument.createEvent("KeyboardEvent"); // evt.initKeyEvent( // "keypress", true /*bubbles*/, true /*cancelable*/, node.ownerDocument.defaultView, // e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, // e.keyCode, e.charCode // ); var evt = new node.ownerGlobal.KeyboardEvent( "keypress", {bubbles: true, cancelable: true, ...e} ); Во второй ничего не смог заметить. |
kokoss > 06-10-2021 17:32:12 |
Vitaliy V. Add, и если возможно, то объединить с этим скриптом: https://forum.mozilla-russia.org/viewto … 72#p782672 |
Vitaliy V. > 07-10-2021 14:42:09 |
kokoss скрытый текст // if (!this.findbar.hidden) // this.findbar.close(); if (this.findbar.hidden) return; this.findbar.clear(); this.findbar.close(); скрытый текст gFindBar.clear(); gFindBar.close(); |
kokoss > 07-10-2021 15:05:26 |
Vitaliy V. пишет
Благодарю
куда...? |
Vitaliy V. > 07-10-2021 15:15:32 |
kokoss пишет
там ниже функция keydown(e) {... |
kokoss > 07-10-2021 15:51:28 |
Vitaliy V. пишет
Я так понимаю что если для этого не использую клави..., то можно удалить этот код: скрытый текст Выделить код Код:keydown(e) { if (e.ctrlKey && e.code == "KeyF" && !e.altKey && !e.shiftKey) { if (this.timer != null) { e.preventDefault(); return; } this.timer = setTimeout(() => { this.timer = null; }, 1000); if (window.gFindBarInitialized && !gFindBar.hidden) { e.preventDefault(); gFindBar.clear(); gFindBar.close(); } } }, |
Vitaliy V. > 07-10-2021 16:01:06 |
kokoss пишет
Нет, один этот код удалять нельзя, только вместе со слушателем, и удалять код не обязательно, достаточно отключить слушатель. |
kokoss > 07-10-2021 16:05:42 |
Vitaliy V. пишет
Я это уже понял... Vitaliy V. пишет
Спасибо! |
Inko7 > 10-10-2021 13:54:23 |
Скачал комплект UserChromeFiles - 2021-9-23. Обновил/перезаписал все файлы по нужным папкам. скрытый текст Выделить код Код:/* Этот файл для правил CSS с правами USER_SHEET */ /* значки папок закладок желтого цвета */ @import url("./css/Colored-folders-91.css"); /* скрыть элементы меню закладок */ @import url("./css/hide_bookmarks_elements.css"); /* скрыть элементы контекстного меню на странице */ @import url("./css/hide_context_elements.css"); /* убрать history-dropmarker из адресной строки */ @import url("./css/history-dropmarker.css"); /* компактная панель поиска сверху справа */ @import url("./css/findbar_compakt.css"); /* панель быстрого поиска такая хе, как и полного поиска */ @import url("./css/findbar_show_full_quickfindbar.css"); /* в приложении GISMETEO - белый шрифт значка погоды */ @import url("./css/gismeteo.css"); /* изменение высоты панели вкладок, компактное меню (Proton) */ @import url("./css/bar_compact_proton.css"); теперь появились три файла: custom_styles_all_user.css , custom_styles_chrome_user.css , custom_styles_content_user.css пробовал помещать код в них - безрезультатно Не пойму куда вообще копать? |
Vitaliy V. > 10-10-2021 14:21:38 |
Inko7 |
Inko7 > 10-10-2021 16:28:09 |
Vitaliy V. получается, раз скрипты заработали сразу, то файлы custom_script.js / custom_script_all_win.js / custom_script_win.js обрабатываются изначально и их прописывать дополнительно не нужно? |
Vitaliy V. > 10-10-2021 17:20:57 |
Inko7 пишет
custom_script.js добавлен в CustomStylesScripts.jsm, но его можно удалить, переименовать, |
_zt > 15-10-2021 12:34:54 |
Vitaliy V.
Например, #context-copy появляется везде при выделенном на странице тексте, но главное здесь расширения, очень часто они добавляют свои пункты без учета контекста. |
Vitaliy V. > 16-10-2021 00:17:22 |
_zt если не заметили недавно обновил ваши скрипты |
_zt > 16-10-2021 11:23:02 |
Vitaliy V. скрытый текст Выделить код Код:#st_splitter { -moz-appearance: none !important; appearance: none !important; background-color: var(--chrome-content-separator-color, rgba(127,127,127,.5)) !important; background-clip: content-box !important; border-inline: 1px solid transparent !important; min-width: 3px !important; margin-inline: -1px !important; position: relative !important; z-index: 2 !important; -moz-box-ordinal-group: ${this.ST_RIGHT ? "100" : "0"} !important; -moz-box-orient: vertical !important; Тултипы сейчас обновил. Я тут подумал, что отображение заголовка перед адресом более удобно, как их местами поменять? У меня не получается, без заголовка остается пустая строка перед адресом. ps^ А как вы svg преобразовываете, например вот это как в скрипт засунуть? скрытый текст
|
Vitaliy V. > 16-10-2021 14:02:03 |
_zt пишет
надо только добавил _zt пишет
// el.title = title = `${href}${title === "" ? "" : `\nTitle: ${title}`}`; |
_zt > 16-10-2021 15:26:10 |
Vitaliy V. |
Dumby > 03-11-2021 20:41:55 |
egorsemenov06 пишет
Заменить residentSetSize и residentUniqueSize на memory Dobrov пишет
С помощью таймаута наверно, как же ещё. скрытый текст Выделить код Код:(async (bar, exp, tid, self) => CustomizableUI.createWidget(self = { label: "Панели, Папки", tooltiptext: [ "ЛКМ: ★ Закладки\n…+ Alt Домашняя папка", "ПКМ: ⟳ История\n…+ Alt Папка установки", "СКМ: Папка профиля\n…+ Alt user_chrome_files" ].join("\n"), id: "add-additional-personaltoolbar-button", localized: false, onCreated(btn) { btn.onclick = this.click; btn.style.setProperty("list-style-image", "url(chrome://user_chrome_files/content/vertical_top_bottom_bar/svg/bookmark-16.svg)", "important"); }, exec(num, win) { tid = null; self[num](win); }, context: win => win.document.getElementById(self.id) .dispatchEvent(new win.MouseEvent("contextmenu", self.a)), a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0}, click(e) { if (e.detail > 2) return; var n2 = e.button != 2; var dbl = e.detail == 2; var num = 16 * e.button + 8 * e.ctrlKey + 4 * e.shiftKey + 2 * e.altKey + dbl; if (!self[num]) { if (n2) return; num = "context"; for(var p in self.a) self.a[p] = e[p]; } n2 || e.preventDefault(); var win = e.view; if (dbl) tid &&= win.clearTimeout(tid), self[num](win); else tid = win.setTimeout(self.exec, 300, num, win); }, 0: w => bar(w, "viewBookmarksSidebar"), // ЛКМ 2: () => exp("Home"), // Alt+ЛКМ 16: () => exp("ProfD"), // СКМ 18: () => exp("UChrm", "user_chrome_files"), // Alt+СКМ 32: w => bar(w, "viewHistorySidebar"), // ПКМ 34: () => exp("GreD"), // Alt+ПКМ 1(win) { // Double Left Click win.alert("DBL Click"); }, 33(win) { // Double Right Click win.alert("DBL Right Click"); }, 29(win) { // Ctrl + Shift + Double Middle Click win.alert("Ctrl + Shift + DBL Middle Click"); }, }))( (win, bar) => win.SidebarUI.toggle(bar), (dir, sub) => { dir = Services.dirsvc.get(dir, Ci.nsIFile); sub && dir.append(sub); dir.exists() && dir.launch(); } ); |
kokoss > 05-11-2021 13:10:05 |
Vitaliy V. Add, вроде получилось что хотел, удалил из скрипта часть кода: this.ExtensionParent.WebExtensionPolicy.getByID(id).extension . Правильно ли я это сделал? Нужно было отключить AutoPopup значков расширений. Add, и ешё вопрос, для чего нужен этот скрипт? |
Dobrov > 06-11-2021 01:35:56 |
Dumby - Спасибо, скрипт очень компактный и крутой, но в двойной клик на UCF-кнопке правый клик мыши работает неверно. Выделить код Код:var reset = e => e.target.linkedObject = this; var id, lo = {click: e => n2 || reset(e)}; var lin = /macos|linux/.test(e.view.AppConstants.platform); var stop = e => reset(e) && e.preventDefault(); lo.contextmenu = lin ? e => e.ctrlKey || e.shiftKey ? 0 : stop(e) : stop; n2 || reset(e) && e.preventDefault(); …… Dumby - ещё просьба по твоему скрипту перехвата кликов на кнопках > добавить Двойной клик (у меня не удалось): Второе (если это возможно) > изменить способ перехвата кнопок со стандартного addEventListener на такой же «продвинутый», как и в новом скрипте, ucf_hookClicks.js (скрипт перехвата кликов на downloads-button, PanelUI-menu) Выделить код Код:(async (id, func) => { // дополнительные клики на downloads-button, PanelUI-menu для custom_script_win.js await window.delayedStartupPromise; var btn = document.getElementById("downloads-button"), pui = document.getElementById("PanelUI-menu-button"); if (!btn) return; btn.tooltipText = GetDynamicShortcutTooltipText(btn.id) +` ПКМ: Сохранить как единый html всё | выделенное на странице …+ Shift Обзор папки [Загрузки]\n Ролик: Сохранить как файл .txt …+ Shift Сайт: графика Вкл/Выкл\n Колёсико на рисунке: ➜ Сохранить Двойной клик: найти Похожие фото`, PanelUI_help = `Браузер Firefox, версия ${Services.appinfo.platformVersion}\n Колёсико: Развернуть | окно …+ Alt Полный экран Правый клик ⇲ Свернуть …+ Shift Закрыть ✕ …+ Alt Персонализация`; var addDestructor = nextDestructor => { var {destructor} = ucf[id]; ucf[id].destructor = () => { try {destructor();} catch(ex) {Cu.reportError(ex);} nextDestructor(); } }, showInStatusPanel = (info, time = 5000) => { var win = Services.wm.getMostRecentWindow("navigator:browser"); StatusPanel = win.StatusPanel; if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update; StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time); StatusPanel._label = info; }, saveSelectionToTxt = async () => { // сохранить страницу или выделенный текст как файл .txt var splice = saveURL.length == 10; var msgName = id + ":Save:GetSelection"; var receiver = msg => { var title = document.title || gBrowser.selectedTab.label; var args = [ "data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\n\n" + msg.data), title.replace(/[:\\\/<>?*|"]+/g,'_').replace(/\s+/g,' ').slice(0, 100).trim() + '_' + new Date().toLocaleString('ru').replace(', ','-').replace(/:/g, '։') + '.txt', null, false, true, null, window.document ]; splice && args.splice(5, 0, null); saveURL(...args) && showInStatusPanel("√ текст сохранён: " + title.slice(0, 60)); } messageManager.addMessageListener(msgName, receiver); addDestructor(() => messageManager.removeMessageListener(msgName, receiver)); var func = fm => { var res, fed, win = {}, fe = fm.getFocusedElementForWindow(content, true, win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed) { var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if (sel.isCollapsed) fed && fed.blur(), docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(), docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("saveSelectionToTxt", res); } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})`.replace("saveSelectionToTxt", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, // end save = async () => { // автор: Лекс, правка: Dumby, Dobrov (пути сохранения HTML) var msgName = id + "ucfDwnldsBtnSaveSnapshotToHTML"; if (typeof IOUtils != "object") { // Firefox 78 ESR var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); var PathUtils = {join: (...args) => OS.Path.join(...args)}; var IOUtils = {writeUTF8: (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt))}; } var write = IOUtils.writeUTF8 ? "writeUTF8" : "writeAtomicUTF8"; var Title = (type) => { // получить заголовок (без обрезки, если type не указан) или домен (type <0) var title = (document.title || gBrowser.selectedTab.label); if ( !type ) return title; // заголовок if ( type > 0 ) return title.slice(0, type).replace(/ \| Форум Mozilla Россия$| — Mozilla Firefox|[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim(); // ограничить длину имени var host = (/^file:\/\//.test(gURLBar.value)) ? '' : gURLBar.value.replace(/^.*url=|https?:\/\/|www\.|\/.*/g,''); return host.replace(/^ru\.|^m\.|forum\./,'').replace(/^club\.dns/,'dns'); } var msgListener = async msg => { var [fileContent, fileName] = msg.data, dir; try {dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("ucf_save.dirs", "_Web||_Images|0").split('|').slice(0, 2); // Dir/subdir: пусто|0 title|1 домен arr[1] = (arr[1] == "0") ? Title(100) : (arr[1] == "1") ? Title(-1) : ""; // имя вкладки или домен arr.forEach(dir.append); // для ucf_save.dirs = "_Web||_Pics|1" HTML сохранится в папку [Загрузки]/_Web/имя вкладки dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); // создать папку, если не существует… var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(dir.path); dir.append(fileName); await IOUtils[write](dir.path, fileContent) && showInStatusPanel("√ страница записана: " + fileName.slice(0, 60)); var d = await Downloads.createDownload({ source: "about:blank", target: FileUtils.File(dir.path)}); // Fake download (await Downloads.getList(Downloads.ALL)).add(d); d.refresh(d.succeeded = true); // кнопка Загрузки мигает } messageManager.addMessageListener(msgName, msgListener); addDestructor(() => messageManager.removeMessageListener(msgName, msgListener)); var svc = 'globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services'; var url = "data:;charset=utf8," + encodeURIComponent(`(${func})(${svc});`.replace("%MSG_NAME%", msgName)); (save = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, // end save listener = e => { var trg = e.target; // Downloads Clicks if (e.button == 1) { if (e.shiftKey) { // СКМ + Shift if ( prefs.getIntPref("permissions.default.image", 1) == 1) prefs.setIntPref("permissions.default.image", 2), trg.style.filter = "hue-rotate(180deg) brightness(95%)" else prefs.setIntPref("permissions.default.image", 1), trg.style.filter = ""; BrowserReload(); } else // СКМ Click saveSelectionToTxt(); // сохранить .txt } else if (e.button == 2) { if (e.shiftKey) Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError) // Обзор папки «Загрузки» else // ПКМ Click save(); // Single HTML } }, listener_pui = e => { // PanelUI-menu Clicks if (e.button == 1) { if (e.altKey) window.BrowserFullScreen() else if( window.windowState != window.STATE_MAXIMIZED ) window.maximize() else window.restore(); } else if (e.button == 2) if (e.altKey) return else { e.stopPropagation(); (e.shiftKey) ? window.close() : window.minimize(); } }, // end Clicks keydown_win = e => { // нажатие клавиш if (!(e.keyCode == 83 && e.shiftKey && e.altKey)) return; var singlesave = document.getElementById(save_ex); // SingleSave singlesave ? singlesave.click() : save(); // имитировать клик по кнопке, используя её ID }, {prefs, dirsvc} = Services, tmax = btn.tooltipText.split("\n")[0].length, save_ex = "_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action"; btn.setAttribute("context", "event.stopPropagation()"); prefs.setBoolPref("browser.download.autohideButton", false); // не скрывать кнопку Загрузки (async () => { // SingleSave - дополнить подсказку setTimeout((but = document.getElementById(save_ex))=> { if (but) btn.tooltipText = btn.tooltipText + '\n\nAlt⇧S нажатие SingleSave'; if (!/Закрыть/.test(pui.tooltipText)) pui.tooltipText = PanelUI_help; }, 9000); // после запуска ждать от 3 сек })(); btn.addEventListener("click", listener), pui.addEventListener("click", listener_pui); window.addEventListener("keydown", keydown_win); var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; ucf[id] = {destructor() { btn.removeEventListener("click", listener), pui.removeEventListener("click", listener_pui); window.removeEventListener("keydown", keydown_win); }}; ucf.unloadlisteners.push(id); })("downloads-button-click-listener", ({io, focus}) => { // SingleHTML не сохраняет svg графику var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec; } catch {} }, getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r; } catch(e) {} } }, encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else img = obj; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }, toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }, mainWin = {}; focus.getFocusedElementForWindow(content, true, mainWin); mainWin = mainWin.value; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild), meta = doc.createElement('meta'), sheets = doc.styleSheets, title = doc.getElementsByTagName('title')[0]; meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).trim(); fileName += "_" + new Date().toLocaleDateString('ru', {day: 'numeric', month: 'numeric', year: '2-digit'}) +'-'+ new Date().toLocaleTimeString().replace(/:/g, "։"); if (!/\.html?$/.test(fileName)) fileName += '.html'; sendAsyncMessage("%MSG_NAME%", [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', fileName]); }); // END hookClicks В скрипт Quick Toggle about:config тоже добавить Двойной клик на кнопке (в коде есть ещё Долгое нажатие) ucf_QuickToggle.js (скрипт из моего профиля FF в шапке темы) Выделить код Код:// Quick Toggle Быстрое переключение параметров about:config для custom_script.js (async (name, id, func) => { // https://forum.mozilla-russia.org/viewtopic.php?pid=789824#p789824 if (name == "Object") return CustomizableUI.createWidget(func()); var win = name == "Window", g = Cu.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); // BEGIN QuickToggle… })(this.constructor.name, "ToggleAboutConfig", () => { var help = `клик+Alt Библиотека закладок …+ Shift ± zoom Текст/страница ։нажать Антизапрет ⇆ proxy\n ПКМ Меню быстрых настроек ։нажать © Краткая справка …+ Alt Опции about:config\n СКМ Вкладка «Топ сайтов» …+ Alt Восстановить вкладку …+ Shift ● Захват цвета, Zoom ։нажать Консоль браузера\n ⟳ Обновить ↯ Перезапуск ЛкМ: Левый клик, СкМ: Колёсико нажать: долгий клик мыши ≥1 сек`, // ЛКМ+Alt+Shift: настройки User Chrome Files. свободные hotkeys: СКМ+Alt ЛКМ+Alt+⇧ Нет в подсказке: ЛКМ панель Журнала, СКМ+Shift – Пипетка help_ucf = ['chrome://user_chrome_files/content/help.html', 'http://forum.puppyrus.org/index.php?topic=22762'], // Ctrl+Click или правый клик - сброс параметра по-умолчанию // клик по параметру с Shift блокирует авто-закрытие меню // строки с userAlt имеют шрифт italic // refresh: false - reload current tab, true - reload current tab skip cache // restart: false - restart browser, true - restart browser with confirm // Разделитель: Имя меню "—,⟳,↯" Опция, ⟳ обновить страницу, ↯ перезапуск браузера // иконки равны ключам: userChoice:зелёный, userAlt:жёлтый, userPro:серый, нет userChoice:серый, ни один:красный // пути сохранения Html/Pics в [Загрузки]/dir/subdir заданы в ucf_save.dirs="_Html dir|subdir|_Pics dir|subdir" : пусто|0 заголовок|1 домен // ucf_save.dirs="_Web||_Pics|1" save Html: [Загрузки]/_Web/имя страницы.html, save Pic: [Загрузки]/_Pics/имя вкладки/имя картинки {prefs, dirsvc} = Services, db = prefs.getDefaultBranch(""), my_vpn = "https://antizapret.prostovpn.org/proxy.pac", icon_vpn = "hue-rotate(270deg) brightness(95%)", menuactive = (AppConstants.platform == "macosx") ? '#e8e8e8' : '#124', // текст, подсвеченный курсором xul_ns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", fonts = ["Arial","Cantarell","DejaVu Sans","Roboto","PT Serif","Segoe UI","Ubuntu","Cambria","Fira Sans","Georgia","Noto Sans","Calibri","Times","системный"], font_pref = (font) => { return font.map(function(name) { // массив с вложениями return (name == font[font.length -1]) ? ["", name,,, `prefs.setIntPref("browser.display.use_document_fonts", 1)`] : [name, name,,, `prefs.setIntPref("browser.display.use_document_fonts", 0)`]; }); }, fontserif = font_pref(fonts), fontsans = [["PT Sans","PT Sans"], ...fontserif], dw; // путь загрузки try {dw = prefs.getComplexValue("browser.download.dir",Ci.nsIFile);} catch {dw = dirsvc.get("DfltDwnld", Ci.nsIFile);}; var secondary = [{ // pref … [apref, lab, akey, hint, js-code] pref: ["dom.disable_open_during_load", "Всплывающие окна"], userChoice: 2, userAlt: true, values: [[true, "Блокировать"], [false, "Разрешить"]] },{ pref: ["browser.safebrowsing.downloads.remote.block_dangerous", "Опасные файлы, сайты",,"browser.safebrowsing.downloads.remote.block_dangerous_host"], userChoice: true, userAlt: false, values: [[true, "Отключить",,,`prefs.setBoolPref('browser.safebrowsing.downloads.remote.block_dangerous_host',true)`], [false, "Загружать",,,`prefs.setBoolPref('browser.safebrowsing.downloads.remote.block_dangerous_host',false)`]] },{ pref: ["permissions.default.image", "Загрузка графики"], userChoice: 1, userAlt: 3, refresh: true, values: [[1, "Разрешена"], [3, "Только с сайта"], [2, "Отключить"]] },{ pref: ["ucf_save.dirs", `Сайт|Графика`,,`\nПути сохранения страниц | графики\n[Загрузки] — папка по-умолчанию${dw ? ":\n"+ dw.path : ""}`], userChoice: "_Сайты||_Фото|1", userAlt: "", userPro: "_Web||_Images|1", values: [ ["", "папка [Загрузки]"], // subdir: пусто | 0 заголовок | 1 домен [`_Сайты||_Фото|1`, "_Сайты|_Фото/имя…"], // _Web/host|_Pics/title [`_Сайты||_Рисунки|1`, "_Сайты|_Рисунки/…"], [`_Web||_Images|`, "_Web|_Images"], [`_Web||_Images|1`, "_Web|_Images/имя"], [`_Web||_Photo|1`, "_Web|_Photo/имя"], [`_Web|1|_Pics|0`, "_Web/сайт|_Pics/…"], [`_Web|1|_Pics|`, "_Web/сайт|_Pics"], [`_Web|1|_Images|0`, "ввести свои пути"]] // здесь нужно открыть about:config },null,{ pref: ["network.cookie.cookieBehavior", "Получать куки",, "\nПерсональные настройки посещённых сайтов"], userChoice: 3, userAlt: 0, userPro: 4, refresh: false, values: [[0, "со всех сайтов"], [3, "кроме не посещённых"], [4, "кроме трекеров"], [1, "кроме сторонних"], [2, "никогда"]] },{ pref: ["network.proxy.autoconfig_url", "Прокси (VPN) URL", "п"], userChoice: my_vpn, userAlt: "127.0.0.1", userPro: "", refresh: true, values: [ ["", "сброшен", ""], [my_vpn, "АнтиЗапрет", "1", "\nНадёжный доступ на заблокированные сайты\n«Режим прокси» меняется на 2", `prefs.setIntPref('network.proxy.type', 2); node.parentNode.parentNode.style.filter = icon_vpn;`], ["https://git.io/ac-anticensority-pac", "ac-anticensority", "2"], // ["localhost", "Tor Browser", "4", "Только для Linux, MacOS\nУстановите сервис: «tor»"], [prefs.getStringPref("user.pacfile", "file:///etc/proxy.pac"), "user .pac файл", "3"], // нужен диалог выбора pac-файла ["127.0.0.1", "local host", "0",, `prefs.setIntPref('network.proxy.type', 0); node.parentNode.parentNode.style.filter = '';`]] },{ pref: ["network.proxy.type", "Режим прокси", "р"], userChoice: 0, userAlt: 2, refresh: true, values: [ [0, "Без прокси", "0", "по-умолчанию"], [5, "Системные (из IE)", "5"], [2, "Автонастройка", "2", "about:config - user.pacfile"], [1, "Ручная настройка", "1", "Используется network.proxy.autoconfig_url"], [4, "Автоопределение", "4"] ] },{ // pref: ["network.proxy.share_proxy_settings", "Все протоколы через прокси"], userAlt: true, refresh: true, // values: [[true, "Да", "", "Прокси для всех протоколов при ручной настройке"], [false, "Нет"]] // },{ pref: ["network.trr.mode", "DNS поверх HTTPS",, "\nШифрование DNS-трафика для\nзащиты персональных данных"], userChoice: 1, userAlt: 2, userPro: 5, refresh: true, values: [ [0, "по-умолчанию", "0"], [1, "автоматически", "1", "используется DNS или DoH, в зависимости от того, что быстрее"], [2, "DoH, затем DNS", "2"], [3, "только DoH", "3"], [4, "DNS и DoH", "4"], [5, "отключить DoH", "5"] ] },null,{ pref: ["browser.zoom.full", "Масштабировать"], userChoice: false, userAlt: true, values: [[true, "всю страницу"], [false, "только текст"]] },{ pref: ["font.name.sans-serif.x-cyrillic", "Шрифт без засечек ",,"\nТакже влияет на всплывающие подсказки\nСистемный: загрузка шрифтов документа"], userAlt: "", values: fontsans },{ pref: ["font.name.serif.x-cyrillic", "Шрифт с засечками"], userAlt: "", values: fontserif },{ pref: ["image.animation_mode", "Анимация изображений"], userChoice: "none", userAlt: "normal", refresh: true, values: [["none", "Выключена"], ["normal", "По циклу"], ["once", "Единожды"]] },null,{ pref: ["media.autoplay.default", "Авто-play аудио/видео"], userChoice: 0, userAlt: 2, userPro: 5, refresh: true, values: [ [0, "Разрешить", "0"], [2, "Спрашивать", "2"], [1, "Запретить", "1"], [5, "Блокировать", "5"]] },{ pref: ["media.autoplay.blocking_policy", "Автозапуск (политика)"], userChoice: 1, userAlt: 2, refresh: true, values: [[1, "Временная", "1"], [2, "По действию", "2"], [0, "Постоянная", "0"]] },{ pref: ["gfx.webrender.all", "Аппаратное ускорение графики"], userChoice: true, refresh: true, values: [[true, "Да"], [false, "Нет"]] },{ pref: ["gfx.webrender.force-disabled", "Web render disabled", , "gfx.webrender.compositor.force-enabled\n\nАппаратная отрисовка страниц видеокартой.\nотключите при разных проблемах с графикой"], userChoice: false, restart: true, values: [ [true, "Да",,, `prefs.setBoolPref("gfx.webrender.compositor.force-enabled", false)`], [false, "Нет",,, `prefs.setBoolPref("gfx.webrender.compositor.force-enabled", true)`]] },null,{ pref: ["network.http.sendRefererHeader", "Referer: для чего"], userChoice: 2, userAlt: 1, values: [[0, "Ни для чего", "0"], [1, "Только ссылки", "1"], [2, "Ссылки, графика", "2"]] },{ pref: ["dom.storage.enabled", "Локальное хранилище",, "\nСохранение персональных данных, по\nкоторым вас можно идентифицировать"], userChoice: false, userAlt: true, values: [[true, "Разрешить"], [false, "Запретить"]] },{ pref: ["privacy.resistFingerprinting", "Изоляция Firstparty-Fingerprint", ,"privacy.firstparty.isolate\n\nЗащита данных пользователя также\nзапрещает запоминать размер окна"], userChoice: false, values: [[true, "Да", , "Защита от слежки",`prefs.setBoolPref('privacy.firstparty.isolate', true);`], [false, "Нет", , "Защита от слежки",`prefs.setBoolPref('privacy.firstparty.isolate', false);`]] },{ pref: ["media.peerconnection.enabled", "WebRTC ваш реальный IP"], userChoice: false, values: [[true, "Выдать"], [false, "Скрыть"]] },null,{ pref: ["browser.tabs.remote.force-enable", "Многопоточный режим вкладок",,"\nПо-умолчанию режим разрешён"], userChoice: null, userAlt: true, userPro: false, values: [[true, "Да"], [false, "Нет"]] },{ pref: ["javascript.enabled", "Выполнять скрипты Java",,"\nПоддержка интерактивных сайтов (и рекламы)"], userChoice: true, refresh: true, values: [[true, "Да"], [false, "Нет"]] },{ pref: ["browser.cache.disk.capacity", "Кэш браузера",,"browser.cache.memory.enable\n\ncache.memory.max_entry_size:\nдиск и память: 5120\nтолько память: -1"], userChoice: 1048576, userAlt: 0, values: [ [1048576, "Диск и Память",,, `prefs.setBoolPref("browser.cache.memory.enable", true); prefs.setBoolPref("browser.cache.disk.enable", true); prefs.setIntPref('browser.cache.memory.max_entry_size', 5120)`], [0, "только Память",,, `prefs.setBoolPref("browser.cache.memory.enable", true); prefs.setBoolPref("browser.cache.disk.enable", false); prefs.setIntPref('browser.cache.memory.max_entry_size', -1)`], [2097152, "только Диск",,, `prefs.setBoolPref("browser.cache.memory.enable", false); prefs.setBoolPref("browser.cache.disk.enable", true)`]] },{ pref: ["dom.enable_performance", "Статус загрузки страницы",,"\nПередача данных разрешит определять\nфакт использования прокси-сервера"], userAlt: true },{ pref: ["general.useragent.override", "User Agent",,"\nот user-агент зависит вид сайтов"], userChoice: null, userAlt: "Mozilla/5.0 (Android 9; Mobile; rv:68.0) Gecko/68.0 Firefox/68.0", userPro: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:68.0) Gecko/20100101 Firefox/68.0", refresh: true, values: [ (arr => { var pref = "general.useragent.override"; var has = prefs.prefHasUserValue(pref); if (has) { var val = prefs.getStringPref(pref); prefs.clearUserPref(pref); } var ua = Cc["@mozilla.org/network/protocol;1?name=http"] .getService(Ci.nsIHttpProtocolHandler).userAgent; // текущий юзерагент has && prefs.setStringPref(pref, val); var find = node => node.pref && node.pref.pref == pref; var redef = (doc, hint) => { var popup = doc.getElementById("ToggleAboutConfig-secondaryPopup"); var menuitem = Array.from(popup.children).find(find).menupopup.firstChild; menuitem.tooltipText = hint ? ua + "\n" + hint : ua; menuitem.setAttribute("oncommand", `event.stopPropagation(); this.closest("toolbarbutton").linkedObject.contextmenu({ preventDefault: Boolean, target: this.parentNode.parentNode });` ); } Object.defineProperty(arr, "0", {enumerable: true, get() { if (Components.stack.formattedStack.includes("createRadios")) { var win = Services.wm.getMostRecentWindow("navigator:browser"); win.setTimeout(redef, 0, win.document, this[3]); } else return ""; }}); return arr; })([null, "По-умолчанию"]), ["Mozilla/5.0 (Android 9; Mobile; rv:68.0) Gecko/68.0 Firefox/68.0", "Firefox Android9"], ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:68.0) Gecko/20100101 Firefox/68.0", "Firefox 68 MacOSX"], ["Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Safari/537.36", "Chrome61 Win10"], ["Mozilla/5.0 (Windows NT 6.1; WOW64; rv:56.0) Gecko/20100101 Firefox/56.0", "Firefox 56"], ["Mozilla/5.0 (X11; Linux x86_64; rv:56.0) Gecko/20100101 Firefox/56.0", "Firefox 56 Linux"], ["Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)", "MSIE 6.0 Windows"], ["Mozilla/5.0 (Linux; Android 7.0; PLUS Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36", "Chrome61 Android7"], ["Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30", "Safari 6 MacOSX"], ["Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12 Version/12.16", "Opera12 W8"], ["Mozilla/5.0 (Linux; Android 5.1.1; SM-G928X Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36", "Samsung Galaxy S6"], ["Mozilla/5.0 (PlayStation 4 3.11) AppleWebKit/537.73 (KHTML, like Gecko)", "Playstation 4"], ["Xbox (Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", "Xbox One (mobile)"], ["Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586", "Microsoft Lumia 950"], ["Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; SAMSUNG; GT-I8350)", "Windows Phone"], ["Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)", "GoogleBot"]] },{ pref: ["browser.cache.disk.free_space_soft_limit", "Неактивные вкладки",, "\nПри запуске загружаются все вкладки,\nэто может замедлить работу браузера.\nОптимально - Выгружать старые табы."], userChoice: 5121, userAlt: 5120, userPro: 5122, values: [ [5120, "Загружать",,, `prefs.setBoolPref("browser.sessionstore.restore_on_demand", true); prefs.setBoolPref("browser.tabs.unloadOnLowMemory", false)`], [5121, "Оптимально",, "Выгружать старые вкладки, экономя память", `prefs.setBoolPref("browser.sessionstore.restore_on_demand", true); prefs.setBoolPref("browser.tabs.unloadOnLowMemory", true)`], [5122, "Не загружать",,, `prefs.setBoolPref("browser.sessionstore.restore_on_demand", false); prefs.setBoolPref("browser.tabs.unloadOnLowMemory", true)`]] }]; return { label: "Quick Toggle Settings", id: "ToggleAboutConfig", tooltiptext: help, localized: false, image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAADhUlEQVR4AaWUIYzsNhCG91WVelKfqoWrpwMLFxQYGhoGBgYGBgYGGhoGBhoGGhoaBhoaGhqcdIFhf+dGt2n09rpq1ZE+2bHl+eyxd0993yVjNIwxq9F6/WjtaNd5nBnq85g2PMeMo8EwDEUI0Z7+jm/EY2it87ZtuAf1EUqAzZZZcuCxnyOlBFoLkuhnkgdBjBG36YqzP+EaTqgmSckyjrGuK8paWGythVLKfv/9t/O/OkEIC6pZoskCfanQuQYLSTm2/ZQkjSil8Pc8z6iqyp/P58tn2l92wWjGnEuG9gO6uUVtaygnMOQaU+nR+hotjfeugwmaHNv9pJzYOYcQAp+kbVv3cBJrbA45QIQLVLyizRI6t5R8gC0aY+nQZYWK5lT4E3nNn2XaiJX5PAmLXl9fuweBz54X97mCoYR21SwYc8+yjsbrKKGCvAu4TDnne3IO7z2oTP1RwCVKJXGJ+rlHaxu0ocZQahLWaO4lmjtov5eI7yDZFnFqWXQUPL1kFzwaV3GpmqQo+cMlc1li9MBCyacbUnC74MePy3NBiAukFRDLBTd/QWUVUk44BJclx5lMPVYvEJ3e7+CZYN+dSw5TmpiQA1/oPTYip4SV5gANRIloa5Ku/LKeCqhljrHmhLzMSIFYPGLw3N/KCMAAuUYeBUkXLDE9vCIW0K45MbXYoW/aFZdiyxYoM9Y0oiwGaxyBjcAElAHFCETTw40T6tvVXP749eUfBe/v78xdlJaAvNwTGmo1YYiRIME6YosGxWnEaUDQbXFt5adazKO6DEcBX97b29tRAq4tl0XzpZKAkzJFEx31iY1bYuANIBtkW6engl1CRD6JAYrh5Mg90QBRAYsgbkAkksS2VJvT0jXqUj0R7HzOrViCQ1kGILZAUAQl9AxLVl/BDTI24tyK1+/8n/SVYOexVDMlaQAvAHdjOHmQLPS6grxe9ZeviDgKuM/jzIZM38kbbE4ekguGBV7CDwLXy1k/vKJtPf4ODmAPFhbf74mLa5DmFltQwCKJCskIiPNpprTi42+bRcaYTIv3Z/oVhcgpUrIOm1NYbIvZWtjJIliSLgpIFdZZohMvgQRqFyilRimFF0I4+QXik7ZR3vRqqSsRpJSO1jEf/bFXGUsNhAq2uWS63eb0X+NjN/uuforb9UXYXjqEBkkLyMupP85/I/53fDzLsZV6am8zCdR9/C+4MZTbZ2zc/gAAAABJRU5ErkJggg==", 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, "secondary", secondary); this.createCloseMenusOption(doc, btn); if (prefs.getIntPref('network.proxy.type') == 2) btn.style.filter = icon_vpn; // btn.style.cssText = "background-image: -moz-linear-gradient(#c0c8c0, #c0c8c0, #c0c8c0) !important"; btn.linkedObject = this; for(var type of ["command", "contextmenu", "mousedown", "auxclick"]) // события btn.setAttribute("on" + type, `linkedObject.${type}(event)`); this.addSheet(btn); }, addSheet(btn) { var cb = Array.isArray(btn._destructors); var id = cb ? btn.id : "ToggleAboutConfig"; var css = `#${id} menu[_moz-menuactive] { color: ${menuactive} !important; }`; var args = [ "data:text/css;charset=utf-8," + encodeURIComponent(css), Ci.nsIDOMWindowUtils.USER_SHEET ]; if (cb) var destructor = function() { this.removeSheetUsingURIString(...args); } var add = b => b.ownerGlobal.windowUtils.loadSheetUsingURIString(...args); (this.addSheet = !cb ? add : btn => { add(btn); btn._destructors.push({destructor, context: btn.ownerGlobal.windowUtils}); })(btn); }, 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, hint] = val; pref.pref = apref; pref.lab = lab || apref; if (hint) pref.hint = hint; } 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`]; var map, set = prefs[`set${str}Pref`]; if (pref.hasVals) { for(var [val, , , , code] of obj.values) code && (map || (map = new Map())).set(val, code); if (map) pref.set = (key, val) => { set(key, val); map.has(val) && eval(map.get(val)); // выполнить код } } if (!map) pref.set = set; 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 = "ToggleAboutConfig.closeMenus"; var data = [null, { pref: [pn, "Закрывать меню этой кнопки"], values: [[true, "Да"], [false, "Нет"]] }]; var setCloseMenus = (e, trg = e.target) => { e.stopPropagation(); var {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: dimgray !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); }, UserImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAe1BMVEUAAAB1dXV1dXV1dXV1dXV1dXV1dXV1dXV8fHyRkZGfn5+oqKipqamqqqqysrKzs7O6urq8vLy9vb3ExMTFxcXHx8fNzc3Ozs7Pz8/Q0NDY2NjZ2dna2tre3t7g4ODi4uLj4+Pk5OTl5eXn5+fs7Ozv7+/w8PDx8fHy8vLK4aRZAAAACHRSTlMAGFiAiNDw+LBTincAAACRSURBVBgZBcFBTsMADAAwJ20pqjgM+P8TgQua2Nok2AAAAiIzdfcgkOv2/ub357yaIF8+jwgz969nS7He9pnumf22hrSse1d1V/W+LlIc3d1V3d1HCPsHkWjj+5FUTVdVTdcQtmMNkXrMdT/Dur0KYYy/8wqx7QugHucE+bIFmPPZArkuS+qqqwmIzNTdAwAA/zI6Uy+Vzu5KAAAAAElFTkSuQmCC", // серый UserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABGElEQVR4AWKgPgAQSmbgEsNQFB53GHz43GGcioPF4mCxGCwWi8FiMBgMBoPFYOzOPWf2/cv3Z/3P7Wo2W2VQolIJ59zb/grvlfLnO1lWJ7lmwDn2cEbnY3jciF0XSTUqSfKZRCLP4NB9c9tlyrOE4iXUwMAd2OMZHLiPj2O0uUZcWcQXp3jKsQTAuSeODlxm7grEIRmxZZal2EuhOxjEGR24yNwXqHOe5MQsdtVCq72He+DiIfNQYMxGwJRHhdIzPLs4zwViGw4ypF5MGsiYIBLML/t04D49gja7kz4eyEB6yiQCnhG4zDx/xsa30sUL3RMtgXP5jO9+JApt2L+DZ3C+/o2sbv9l5xsNtYBz7B0HS8qUZSZqAwCSaKMMRS9J3wAAAABJRU5ErkJggg==", // зелёный notUserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABDElEQVR4Aa2TK3CEQBBEt6JwdxKJRJ48GRkZiURGxqt4dV5FnkQikSdXIpHIweE6+8KKyf+7Va92qqe770v493MOoUw8JGJizcSslV+Fm3NRWLxrZUMnzaOAGY0dng/DXVnK+kdpGhKXFI4CZjR2ePC+edu0W3eSYieNPQEPGjvhwUuG7FXuuK+b691uX4Sw2obBmkHbwIOXjC+4qY61D+d5Bq89g5eML6hpxvQd8JLxBXk5uxsM3p05vmBcJhfmnrkzbmaHl4wv6KfL5IKuZHbFecZLxhecxiEuiwVX4nBhPHjJvP0j7QtZe5TaWmqqdG8wo7HD8+m/MWHxUMluDym0wYzGDs/fHqb/Pk9WVkDcHStz1AAAAABJRU5ErkJggg==", // красный UserAltImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABAklEQVR4Aa2TKVDEQBREx3sRiUQi8Wpl5MqVSCQyMhIZGYlciVy5cmQkEhk5runHNQf3kapX9ev36w97hX9/xk3ozGCiScDMjuyr8va6D+syd9LdIOkgYGZHhvNhed4FyxdSmswsaQ/M7MiEg9uWO65r6aV1MCOFCnZkOLh0ygPjMgXpvjc7i5f50HORHRkOLp3yQNSR131uYZMPFbAjw8GlUx5IWk5kLJwiGeQMOzIcoFMfiEEFz+IZMHsHOW8PRO0dHMyxIEK9w8FtX8IYBwe3gPQeOcel0377Vt1w/XNwcOm8/SJtLcxI70OG8+m3kevxKihNucjMjgznbz+m/34eAEg4sZItNtjUAAAAAElFTkSuQmCC", // жёлтый regexpRefresh: /^(?:view-source:)?(?:https?|ftp)/, 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 hint = exists ? val : "Эта опция не указана"; if (hint === "") hint = "[ пустая строка ]"; hint += "\n" + pref.pref; if (pref.hint) hint += "\n" + pref.hint; node.tooltipText = hint; var img, alt = "userAlt" in pref && val == pref.userAlt, pro = "userPro" in pref && val == pref.userPro; if (alt) img = this.UserAltImg; if (pro) img = this.UserImg; if ("userChoice" in pref) if (val == pref.userChoice) node.style.removeProperty("color"), img = this.UserChoiceImg; else { node.style.setProperty("color", "#804040", "important"); if (!alt && !pro) img = this.notUserChoiceImg; } node.nextSibling && node.setAttribute("image", img || this.UserImg); // серый значок, если нет userChoice 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}`; } lab = exists ? lab : '['+ lab +']'; // имя = [имя] если преф не существует 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, hint] = 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 (hint) tip += "\n" + hint; menuitem.tooltipText = tip; popup.append(menuitem); } }, openPopup(popup) { var btn = popup.parentNode; if (btn.domParent != btn.parentNode) { btn.domParent = btn.parentNode; if (btn.matches(".widget-overflow-list > :scope")) var 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); }, 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.BrowserReloadSkipCache() : win.BrowserReload(); } }, maybeClosePopup(e, trg) { !e.shiftKey && prefs.getBoolPref(this.closePref, undefined) && trg.parentNode.hidePopup(); }, 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; } } }, click(e) { if (e.button) return; var trg = e.target, {pref} = trg; if (!pref) return; }, command(e) { // нажатия левой кнопки мыши var trg = e.target, win = e.view; if (trg.btn) { // LMB if (e.shiftKey) e.altKey ? win.openDialog("chrome://user_chrome_files/content/options/prefs_win.xhtml", "user_chrome_prefs:window", "centerscreen,resizable,dialog=no") // Alt+Shift : e.view.ZoomManager.toggleZoom(); // Alt Пипетка else if (e.altKey) e.view.PlacesCommandHook.showPlacesOrganizer("BookmarksToolbar"); // Shift Библиотека Панель закладок else { // LMB Click var bar = e.target.ownerDocument.querySelector("#ucf-additional-vertical-bar") if (bar) { win.setToolbarVisibility(bar, bar.collapsed); bar.collapsed ? win.SidebarUI.hide() : win.SidebarUI.show("viewHistorySidebar"); } else win.SidebarUI.toggle("viewHistorySidebar"); } return; } 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); }, auxclick(e) { // CKM if (e.button != 1 || !e.target.btn) return; if (e.altKey) e.shiftKey ? this.switchToTab(e, "ya.ru") // Alt+Shift : e.view.undoCloseTab() else if (e.shiftKey) this.eyedropper(e.target) else this.switchToTab(e, "about:newtab"); }, contextmenu(e) { // RMB var trg = e.target, win = e.view; if (trg.btn) { if (e.ctrlKey || e.shiftKey) return; if (e.detail == 2) return trg.secondaryPopup.hidePopup(); // меню быстрых настроек ! e.altKey ? this.openPopup(trg.secondaryPopup) : this.switchToTab(e, "about:config"); } else if ("pref" in trg) { this.maybeClosePopup(e, trg); if (trg.pref.user) prefs.clearUserPref(trg.pref.pref), this.maybeRe(trg); } e.preventDefault(); }, mousedown(e) { var reset = e => e.target.linkedObject = this; var id, lo = {command: reset, mousedown: reset, auxclick: e => e.button != 1 || reset(e)}; var lin = /macos|linux/.test(e.view.AppConstants.platform); var stop = e => reset(e) && e.preventDefault(); lo.contextmenu = lin ? e => e.ctrlKey || e.shiftKey ? dsp(e) : stop(e) : stop; var context = lin ? e => e.button == 2 && e.type.endsWith("p") && this.contextmenu(e) : () => {}; var dsp = (e, timeout) => { var trg = e.target; trg.onmouseup = trg.onmouseleave = null; if (timeout) return this.londPress(e); e.view.clearTimeout(id); reset(e); context(e); } (this.mousedown = e => { var trg = e.target; if (!trg.btn) return; trg.linkedObject = lo; trg.onmouseup = trg.onmouseleave = dsp; id = e.view.setTimeout(dsp, 500, e, true); })(e); }, londPress(e) { // удержание кнопки мыши. на второй долгий клик при отпускании сработает действие на обычный клик этой кнопки var trg = e.target, win = e.view; if (e.button == 0) this.switchProxy(e, my_vpn); if (e.button == 1) trg.ownerDocument.getElementById("key_browserConsole").doCommand(); // Консоль браузера if (e.button == 2) { // RMB Long var newURI = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).convertChromeURL(Services.io.newURI(help_ucf[0])); // .spec = file:/// (newURI.QueryInterface(Ci.nsIFileURL).file.exists()) ? this.switchToTab(e, help_ucf[0]) : this.switchToTab(e, help_ucf[1]); } }, switchProxy(e, pac) { if (prefs.getIntPref('network.proxy.type') == 2) { // выключить prefs.setIntPref('network.proxy.type', 0); prefs.setStringPref("network.proxy.autoconfig_url", "127.0.0.1"); e.target.style.removeProperty("filter"); this.showInStatusPanel("\u{1F6A6} Настройки сети - работа без прокси"); // символ Светофор } else { prefs.setIntPref('network.proxy.type', 2); prefs.setStringPref("network.proxy.autoconfig_url", pac); e.target.style.setProperty("filter", icon_vpn, "important"); this.showInStatusPanel("\u{1F6A6} Заблокированные сайты через «АнтиЗапрет»"); // this.Notify('Proxy', 'Работаем через VPN Антизапрет'); } }, showInStatusPanel(info, ms = 5000) { var win = Services.wm.getMostRecentWindow("navigator:browser"); StatusPanel = win.StatusPanel; if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update; StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, ms); StatusPanel._label = info; }, eyedropper(trg) { // Пипетка - захват цвета var obj = ChromeUtils.import("resource://devtools/shared/Loader.jsm") .require("devtools/client/menus").menuitems .find(menuitem => menuitem.id == "menu_eyedropper"); (this.eyedropper = target => obj.oncommand({target}))(trg); }, Notify(title, text, ms = 3000){ Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService).showAlertNotification(null, title, text, false, '', null, ms); }, switchToTab(e = this, url) { // открыть вкладку | закрыть, если открыта for(var tab of e.view.gBrowser.tabs) if ( tab.linkedBrowser.currentURI.spec == url ) {e.view.gBrowser.removeTab(tab); return;}; // вкладка найдена, закрыть e.view.switchToTabHavingURI(url, true, {relatedToCurrent: true, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); } }; }); // END ToggleAboutConfig |
Dumby > 06-11-2021 19:02:14 |
Dobrov пишет
Посмотрел на Mint, и точно, так и есть. скрытый текст Выделить код Код:(async (bar, exp, tid, self) => CustomizableUI.createWidget(self = { label: "Панели, Папки", tooltiptext: [ "ЛКМ: ★ Закладки\n…+ Alt Домашняя папка", "ПКМ: ⟳ История\n…+ Alt Папка установки", "СКМ: Папка профиля\n…+ Alt user_chrome_files" ].join("\n"), id: "add-additional-personaltoolbar-button", localized: false, onCreated(btn) { btn.onclick = this.click; btn.toggleAttribute("context"); btn.style.setProperty("list-style-image", "url(chrome://user_chrome_files/content/vertical_top_bottom_bar/svg/bookmark-16.svg)", "important"); }, exec(num, win) { tid = null; self[num](win); }, context(win) { var btn = win.document.getElementById(this.id); btn.removeAttribute("context"); btn.dispatchEvent(new win.MouseEvent("contextmenu", this.a)); btn.toggleAttribute("context"); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0}, click(e) { if (e.detail > 2) return; var n2 = e.button != 2; var dbl = e.detail == 2; var num = 16 * e.button + 8 * e.ctrlKey + 4 * e.shiftKey + 2 * e.altKey + dbl; if (!self[num]) { if (n2) return; num = "context"; for(var p in self.a) self.a[p] = e[p]; } var win = e.view; if (dbl) tid &&= win.clearTimeout(tid), self[num](win); else tid = win.setTimeout(self.exec, 300, num, win); }, 0: w => bar(w, "viewBookmarksSidebar"), // ЛКМ 2: () => exp("Home"), // Alt+ЛКМ 16: () => exp("ProfD"), // СКМ 18: () => exp("UChrm", "user_chrome_files"), // Alt+СКМ 32: w => bar(w, "viewHistorySidebar"), // ПКМ 34: () => exp("GreD"), // Alt+ПКМ 1(win) { // Double Left Click win.alert("DBL Click"); }, 33(win) { // Double Right Click win.alert("DBL Right Click"); }, 29(win) { // Ctrl + Shift + Double Middle Click win.alert("Ctrl + Shift + DBL Middle Click"); }, }))( (win, bar) => win.SidebarUI.toggle(bar), (dir, sub) => { dir = Services.dirsvc.get(dir, Ci.nsIFile); sub && dir.append(sub); dir.exists() && dir.launch(); } ); А ещё у меня там не работают альт-клики. Насколько я понял, mousedown занят системой: альт-левый — перетаскивание окна, альт-средний — менюшка как по Alt+Пробел, альт-правый — ресайз окна. Но у тебя, видимо, такого нет. Dobrov пишет
Там полную раскликовку сделать сложнее, скрытый текст Выделить код Код:/* listener = e => { var trg = e.target; // Downloads Clicks if (e.button == 1) { if (e.shiftKey) { // СКМ + Shift if ( prefs.getIntPref("permissions.default.image", 1) == 1) prefs.setIntPref("permissions.default.image", 2), trg.style.filter = "hue-rotate(180deg) brightness(95%)" else prefs.setIntPref("permissions.default.image", 1), trg.style.filter = ""; BrowserReload(); } else // СКМ Click saveSelectionToTxt(); // сохранить .txt } else if (e.button == 2) { if (e.shiftKey) Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError) // Обзор папки «Загрузки» else // ПКМ Click save(); // Single HTML } }, listener_pui = e => { // PanelUI-menu Clicks if (e.button == 1) { if (e.altKey) window.BrowserFullScreen() else if( window.windowState != window.STATE_MAXIMIZED ) window.maximize() else window.restore(); } else if (e.button == 2) if (e.altKey) return else { e.stopPropagation(); (e.shiftKey) ? window.close() : window.minimize(); } }, // end Clicks */ tid, allowMousedown, listener = { handleEvent(e) { if (e.detail > 2) return; var btn = e.target; var dbl = e.detail == 2; var num = (btn == pui && 100) + 16 * e.button + 8 * e.ctrlKey + 4 * e.shiftKey + 2 * e.altKey + dbl; if (!this[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "mousedown"; } if (dbl) tid &&= clearTimeout(tid), this[num](btn); else tid = setTimeout(this.exec, 300, num, btn, this); }, exec(num, btn, self) { tid = null; self[num](btn); }, mousedown(btn) { allowMousedown = true; btn.dispatchEvent(new MouseEvent("mousedown", {})); allowMousedown = false; }, context(btn) { btn.removeAttribute("context"); btn.dispatchEvent(new MouseEvent("contextmenu", this.a)); btn.toggleAttribute("context"); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0}, /*** ======= Downloads Clicks ======= ***/ 16: saveSelectionToTxt, // СКМ Click (сохранить .txt) 20(btn) { // СКМ + Shift var pref = "permissions.default.image"; var one = prefs.getIntPref(pref) == 1; prefs.setIntPref(pref, one ? 2 : 1); btn.style.filter = one ? "hue-rotate(180deg) brightness(95%)" : ""; BrowserReload(); }, 32: save, // ПКМ Click (Single HTML) 36() { // Shift + ПКМ Downloads.getSystemDownloadsDirectory() .then(path => FileUtils.File(path).launch(), Cu.reportError) // Обзор папки «Загрузки» }, 1() { // Double Left Click alert("Double Left Click"); }, 41() { // Ctrl + Double Right Click alert("Ctrl + Double Right Click"); }, 4() { // Shift + ЛКМ alert("Shift + ЛКМ"); }, /*** ======= PanelUI-menu Clicks ======= ***/ 118: BrowserFullScreen, // Alt + СКМ 116() { // СКМ windowState != STATE_MAXIMIZED ? maximize() : restore(); }, 132() { // ПКМ minimize(); }, 136: BrowserTryToCloseWindow, // Shift + ПКМ 134() { // Alt + ПКМ gCustomizeMode.enter(); }, 101() { // Double Left Click alert("Double Left Click"); }, 141() { // Ctrl + Double Right Click alert("Ctrl + Double Right Click"); }, 104() { // Shift + ЛКМ alert("Shift + ЛКМ"); }, }, // end Clicks Выделить код Код:/* btn.addEventListener("click", listener), pui.addEventListener("click", listener_pui); window.addEventListener("keydown", keydown_win); var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; ucf[id] = {destructor() { btn.removeEventListener("click", listener), pui.removeEventListener("click", listener_pui); window.removeEventListener("keydown", keydown_win); }}; */ var mouseenter = function(e) { this.parentNode.addEventListener("mousedown", stop, true); this.addEventListener("mouseleave", mouseleave, {once: true}); } var mouseleave = function(e) { this.parentNode.removeEventListener("mousedown", stop, true); } var stop = e => { e.button || allowMousedown || e.stopImmediatePropagation(); } var btns = [btn, pui]; for(var b of btns) { b.toggleAttribute("context"), b.addEventListener("click", listener, true), b.addEventListener("mouseenter", mouseenter); } window.addEventListener("keydown", keydown_win); var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; ucf[id] = {destructor() { for(var b of btns) { b.removeEventListener("click", listener, true); b.removeEventListener("mouseenter", mouseenter); if (b.matches(":hover")) b.removeEventListener("mouseleave", mouseleave), b.parentNode.removeEventListener("mousedown", stop, true); } window.removeEventListener("keydown", keydown_win); }}; Dobrov пишет
Уволь. |
Dobrov > 07-11-2021 05:32:38 |
Dumby - спасибо, я немного переделал код и обновил профиль-сборку скриптов. Dumby пишет
Не системой, а демоном горячих клавиш, которые можно изменить в Настройках из меню. |
Dumby > 07-11-2021 09:14:37 |
egorsemenov06 пишет
Какой просьбе? Нет там никакой просьбы. скрытый текст Есть сетование на трудности рихтовки и констатация отсутствия реакции индикатора на очистку памяти фишкой. Но индикатор и не должен напрямую реагировать ни на какие фишки. И код рабочий, так что, если фишка действительно чистит память, И ещё там есть вопрос, можно ли сделать подобный индикатор, Когда-то давно я уже отвечал на это, целый трактат написал. |
Dobrov > 11-11-2021 18:05:36 |
Dumby - Помоги исправить код перехода в "Адаптивный дизайн". код в сложной кнопке QuickToggle.js работает, но если несколько раз включить/выключить Адаптивный дизайн через кнопку, то это переключение перестаёт работать. Выделить код Код:responsiveUI(trg) { var obj = ChromeUtils.import("resource://devtools/shared/Loader.jsm").require("devtools/client/menus").menuitems.find(menuitem => menuitem.id == "menu_responsiveUI"); (this.responsiveUI = target => obj.oncommand({target}))(trg); }, строка 155 - ucf_hookClicks.js Выделить код Код:(async (id, func) => { // дополнительные клики на downloads-button, PanelUI-menu для custom_script_win.js await window.delayedStartupPromise; var btn = document.getElementById("downloads-button"), pui = document.getElementById("PanelUI-menu-button"); if (!btn) return; btn.tooltipText = GetDynamicShortcutTooltipText(btn.id) +` Двойной клик: открыть [Загрузки] …на картинке: ⧉ найти Похожие\n Правый клик (Alt+S): Сохранить в единый html всё / выделенное …дважды Картинки вкл/выкл\n Ролик: Сохранить как файл .txt Колёсико на рисунке: ➜ Сохранить`, PanelUI_help = `Клик мыши: меню Firefox ${Services.appinfo.platformVersion} …+ дважды ⊠ закрыть браузер …+ Alt Обновить без кэша …+ Shift ⚑ Краткая справка\n Правый клик ⇲ Свернуть …+ Alt Персонализация Колёсико: Развернуть | окно …+ Alt Полный экран`; var addDestructor = nextDestructor => { var {destructor} = ucf[id]; ucf[id].destructor = () => { try {destructor();} catch(ex) {Cu.reportError(ex);} nextDestructor(); } }, showInStatusPanel = (info, time = 5000) => { var win = Services.wm.getMostRecentWindow("navigator:browser"); StatusPanel = win.StatusPanel; if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update; StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time); StatusPanel._label = info; }, saveSelectionToTxt = async () => { // сохранить страницу или выделенный текст как файл .txt var splice = saveURL.length == 10; var msgName = id + ":Save:GetSelection"; var receiver = msg => { var title = document.title || gBrowser.selectedTab.label; var args = [ "data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\n\n" + msg.data), title.replace(/[:\\\/<>?*|"]+/g,'_').replace(/\s+/g,' ').slice(0, 100).trim() + '_' + new Date().toLocaleString('ru').replace(', ','-').replace(/:/g, '։') + '.txt', null, false, true, null, window.document ]; splice && args.splice(5, 0, null); saveURL(...args) && showInStatusPanel("√ текст сохранён: " + title.slice(0, 60)); } messageManager.addMessageListener(msgName, receiver); addDestructor(() => messageManager.removeMessageListener(msgName, receiver)); var func = fm => { var res, fed, win = {}, fe = fm.getFocusedElementForWindow(content, true, win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed) { var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if (sel.isCollapsed) fed && fed.blur(), docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(), docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("saveSelectionToTxt", res); } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})`.replace("saveSelectionToTxt", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, // end save = async () => { // автор: Лекс, правка: Dumby, Dobrov (пути сохранения HTML) var msgName = id + "ucfDwnldsBtnSaveSnapshotToHTML"; if (typeof IOUtils != "object") { // Firefox 78 ESR var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); var PathUtils = {join: (...args) => OS.Path.join(...args)}; var IOUtils = {writeUTF8: (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt))}; } var write = IOUtils.writeUTF8 ? "writeUTF8" : "writeAtomicUTF8"; var Title = (type) => { // получить заголовок (без обрезки, если type не указан) или домен (type <0) var title = (document.title || gBrowser.selectedTab.label); if ( !type ) return title; // заголовок if ( type > 0 ) return title.slice(0, type).replace(/ \| Форум Mozilla Россия$| — Mozilla Firefox|[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim(); // ограничить длину имени var host = (/^file:\/\//.test(gURLBar.value)) ? '' : gURLBar.value.replace(/^.*url=|https?:\/\/|www\.|\/.*/g,''); return host.replace(/^ru\.|^m\.|forum\./,'').replace(/^club\.dns/,'dns'); } var msgListener = async msg => { var [fileContent, fileName] = msg.data, dir; try {dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("ucf_save.dirs", "_Web||_Images|0").split('|').slice(0, 2); // Dir/subdir: пусто|0 title|1 домен arr[1] = (arr[1] == "0") ? Title(100) : (arr[1] == "1") ? Title(-1) : ""; // имя вкладки или домен arr.forEach(dir.append); // для ucf_save.dirs = "_Web||_Pics|1" HTML сохранится в папку [Загрузки]/_Web/имя вкладки dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); // создать папку, если не существует… var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(dir.path); dir.append(fileName); await IOUtils[write](dir.path, fileContent) && showInStatusPanel("√ страница записана: " + fileName.slice(0, 60)); var d = await Downloads.createDownload({ source: "about:blank", target: FileUtils.File(dir.path)}); // Fake download (await Downloads.getList(Downloads.ALL)).add(d); d.refresh(d.succeeded = true); // кнопка Загрузки мигает } messageManager.addMessageListener(msgName, msgListener); addDestructor(() => messageManager.removeMessageListener(msgName, msgListener)); var svc = 'globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services'; var url = "data:;charset=utf8," + encodeURIComponent(`(${func})(${svc});`.replace("%MSG_NAME%", msgName)); (save = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, // end save tid, allowMousedown, listener = { handleEvent(e) { if (e.detail > 2) return; var btn = e.target; var dbl = e.detail == 2; var num = (btn == pui && 100) + 16 * e.button + 8 * e.ctrlKey + 4 * e.shiftKey + 2 * e.altKey + dbl; if (!this[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "mousedown"; } if (dbl) tid &&= clearTimeout(tid), this[num](btn); else tid = setTimeout(this.exec, 300, num, btn, this); }, exec(num, btn, self) { tid = null; self[num](btn); }, mousedown(btn) { allowMousedown = true; btn.dispatchEvent(new MouseEvent("mousedown", {})); allowMousedown = false; }, context(btn) { btn.removeAttribute("context"); btn.dispatchEvent(new MouseEvent("contextmenu", this.a)); btn.toggleAttribute("context"); }, switchToTab(but, url) { // открыть вкладку | закрыть, если открыта for(var tab of but.ownerGlobal.gBrowser.tabs) if ( tab.linkedBrowser.currentURI.spec == url ) {but.ownerGlobal.gBrowser.removeTab(tab); return;}; // вкладка найдена, закрыть but.ownerGlobal.switchToTabHavingURI(url, true, {relatedToCurrent: true, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }, responsiveUI(trg) { var obj = ChromeUtils.import("resource://devtools/shared/Loader.jsm").require("devtools/client/menus").menuitems.find(menuitem => menuitem.id == "menu_responsiveUI"); (this.responsiveUI = target => obj.oncommand({target}))(trg); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0}, /*** ======= Downloads Clicks ======= ***/ 16: saveSelectionToTxt, // СКМ Click (сохранить .txt) 1() { // Double Left Click - Обзор папки «Загрузки» Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError) // Обзор папки «Загрузки» }, 32: save, // ПКМ Click (Single HTML) 33(btn) { // Double Right Click var pref = "permissions.default.image"; var one = prefs.getIntPref(pref) == 1; prefs.setIntPref(pref, one ? 2 : 1); btn.style.filter = one ? "hue-rotate(180deg) brightness(95%)" : ""; BrowserReload(); }, 2() { // Alt + ЛКМ }, /*** ======= PanelUI-menu Clicks ======= ***/ 102: BrowserReloadSkipCache, // Alt + Click 104() { // Shift + ЛКМ var help_ucf = ['chrome://user_chrome_files/content/help.html', 'http://forum.puppyrus.org/index.php?topic=22762']; var newURI = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).convertChromeURL(Services.io.newURI(help_ucf[0])); // .spec = file:/// (newURI.QueryInterface(Ci.nsIFileURL).file.exists()) ? this.switchToTab(pui, help_ucf[0]) : this.switchToTab(pui, help_ucf[1]); }, 118: BrowserFullScreen, // Alt + СКМ 116() { // СКМ windowState != STATE_MAXIMIZED ? maximize() : restore(); }, 132() { // ПКМ minimize(); }, 134() { // Alt + ПКМ gCustomizeMode.enter(); }, 101: BrowserTryToCloseWindow, // Double Left Click 133(pui) { // Double Right Click responsiveUI(pui); }, }, // end Clicks keydown_win = e => { // нажатие клавиш if (e.keyCode == 83 && e.altKey) e.shiftKey // Alt+S [+Shift] ? singlesave ? singlesave.click() : save() : save(); // имитировать клик по кнопке, используя её ID }, {prefs, dirsvc} = Services, linux = /macos|linux/.test(AppConstants.platform), save_ex = "_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action", singlesave; prefs.setBoolPref("browser.download.autohideButton", false); // не скрывать кнопку Загрузки (async () => { setTimeout(()=> { // дополнить подсказки singlesave = document.getElementById(save_ex); singlesave ? btn.tooltipText = btn.tooltipText + '\n\nAlt⇧S ⌨ нажатие SingleSave' : 0; if (!/Закрыть/.test(pui.tooltipText)) pui.tooltipText = PanelUI_help; }, linux ? 3000 : 9000); // ожидание для Windows больше })(); var mouseenter = function(e) { this.parentNode.addEventListener("mousedown", stop, true); this.addEventListener("mouseleave", mouseleave, {once: true}); } var mouseleave = function(e) { this.parentNode.removeEventListener("mousedown", stop, true); } var stop = e => { e.button || allowMousedown || e.stopImmediatePropagation(); } var btns = [btn, pui]; for(var b of btns) { b.toggleAttribute("context"), b.addEventListener("click", listener, true), b.addEventListener("mouseenter", mouseenter); } window.addEventListener("keydown", keydown_win); var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; ucf[id] = {destructor() { for(var b of btns) { b.removeEventListener("click", listener, true); b.removeEventListener("mouseenter", mouseenter); if (b.matches(":hover")) b.removeEventListener("mouseleave", mouseleave), b.parentNode.removeEventListener("mousedown", stop, true); } window.removeEventListener("keydown", keydown_win); }}; ucf.unloadlisteners.push(id); })("downloads-button-click-listener", ({io, focus}) => { // SingleHTML не сохраняет svg графику var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec; } catch {} }, getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r; } catch(e) {} } }, encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else img = obj; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }, toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }, mainWin = {}; focus.getFocusedElementForWindow(content, true, mainWin); mainWin = mainWin.value; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild), meta = doc.createElement('meta'), sheets = doc.styleSheets, title = doc.getElementsByTagName('title')[0]; meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).trim(); fileName += "_" + new Date().toLocaleDateString('ru', {day: 'numeric', month: 'numeric', year: '2-digit'}) +'-'+ new Date().toLocaleTimeString().replace(/:/g, "։"); if (!/\.html?$/.test(fileName)) fileName += '.html'; sendAsyncMessage("%MSG_NAME%", [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', fileName]); }); // END hookClicks Ещё вопрос - как имитировать нажатие клавиш, например "послать" переключения в режим "Адаптивный дизайн" - у меня это Option+Command+M (Win+Alt+M) |
Dumby > 11-11-2021 23:09:22 |
Dobrov пишет
this.responsiveUI(pui); Или (для понимания) без промежуточности скрытый текст Выделить код Код:..... 133(pui) { var obj = ChromeUtils.import("resource://devtools/shared/Loader.jsm").require("devtools/client/menus").menuitems.find(menuitem => menuitem.id == "menu_responsiveUI"); (this[133] = target => obj.oncommand({target}))(pui); },
На FF87 у window нет метода QueryInterface(), |
Dobrov > 12-11-2021 17:26:33 |
Dumby - спасибо, исправил и доработал код. Вопрос - как сделать перехват кликов на кнопках расширений, которые динамически появляются? Выделить код Код:win.document.getElementById("pageAction-panel-_2495d258-41e7-4cd5-bc7d-ac15981f064e_").click() trg.ownerDocument.getElementById("key_responsiveDesignMode").doCommand(); // Адаптивный дизайн id="pageAction-panel-_2495d258-41e7-4cd5-bc7d-ac15981f064e_" Reader View в меню Действия на странице id="pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_" в строке адреса actionid="_2495d258-41e7-4cd5-bc7d-ac15981f064e_" Желательно добавить перехват кликов в тот же UCF-скрипт, который расширяет возможности кнопок Меню и Загрузки: ucf_hookClicks.js Выделить код Код:(async (id, func) => { // дополнительные клики на downloads-button, PanelUI-menu для custom_script_win.js await window.delayedStartupPromise; var btn = document.getElementById("downloads-button"), pui = document.getElementById("PanelUI-menu-button"); if (!btn) return; btn_help =` Двойной клик: открыть [Загрузки] …на картинке: ⧉ найти Похожие\n Правый клик (Alt+S): Сохранить в единый html всё / выделенное …дважды Картинки вкл/выкл\n Ролик: Сохранить как файл .txt Колёсико на рисунке: ➜ Сохранить`, PanelUI_help = `Клик мыши: меню Firefox ${Services.appinfo.platformVersion} …+ Shift ⚑ Краткая справка …+ Alt Персонализация Клик дважды ⊠ закрыть браузер \n Правый клик ⇲ Свернуть …+ дважды ⤾ Вернуть вкладку …+ Alt Диспетчер задач …+ Shift Адаптивный дизайн\n Колёсико: Развернуть | окно …+ Alt Полный экран …+ дважды Обновить без кэша`, singlesave_help = `\nAlt⇧S ⌨ нажатие SingleSave`; var addDestructor = nextDestructor => { var {destructor} = ucf[id]; ucf[id].destructor = () => { try {destructor();} catch(ex) {Cu.reportError(ex);} nextDestructor(); } }, showInStatusPanel = (info, time = 5000) => { var win = Services.wm.getMostRecentWindow("navigator:browser"); StatusPanel = win.StatusPanel; if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update; StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time); StatusPanel._label = info; }, saveSelectionToTxt = async () => { // сохранить страницу или выделенный текст как файл .txt var splice = saveURL.length == 10; var msgName = id + ":Save:GetSelection"; var receiver = msg => { var title = document.title || gBrowser.selectedTab.label; var args = [ "data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\n\n" + msg.data), title.replace(/[:\\\/<>?*|"]+/g,'_').replace(/\s+/g,' ').slice(0, 100).trim() + '_' + new Date().toLocaleString('ru').replace(', ','-').replace(/:/g, '։') + '.txt', null, false, true, null, window.document ]; splice && args.splice(5, 0, null); saveURL(...args) && showInStatusPanel("√ текст сохранён: " + title.slice(0, 60)); } messageManager.addMessageListener(msgName, receiver); addDestructor(() => messageManager.removeMessageListener(msgName, receiver)); var func = fm => { var res, fed, win = {}, fe = fm.getFocusedElementForWindow(content, true, win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed) { var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if (sel.isCollapsed) fed && fed.blur(), docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(), docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("saveSelectionToTxt", res); } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})`.replace("saveSelectionToTxt", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, // end save = async () => { // автор: Лекс, правка: Dumby, Dobrov (пути сохранения HTML) var msgName = id + "ucfDwnldsBtnSaveSnapshotToHTML"; if (typeof IOUtils != "object") { // Firefox 78 ESR var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); var PathUtils = {join: (...args) => OS.Path.join(...args)}; var IOUtils = {writeUTF8: (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt))}; } var write = IOUtils.writeUTF8 ? "writeUTF8" : "writeAtomicUTF8"; var Title = (type) => { // получить заголовок (без обрезки, если type не указан) или домен (type <0) var title = (document.title || gBrowser.selectedTab.label); if ( !type ) return title; // заголовок if ( type > 0 ) return title.slice(0, type).replace(/ \| Форум Mozilla Россия$| — Mozilla Firefox|[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim(); // ограничить длину имени var host = (/^file:\/\//.test(gURLBar.value)) ? '' : gURLBar.value.replace(/^.*url=|https?:\/\/|www\.|\/.*/g,''); return host.replace(/^ru\.|^m\.|forum\./,'').replace(/^club\.dns/,'dns'); } var msgListener = async msg => { var [fileContent, fileName] = msg.data, dir; try {dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("ucf_save.dirs", "_Web||_Images|0").split('|').slice(0, 2); // Dir/subdir: пусто|0 title|1 домен arr[1] = (arr[1] == "0") ? Title(100) : (arr[1] == "1") ? Title(-1) : ""; // имя вкладки или домен arr.forEach(dir.append); // для ucf_save.dirs = "_Web||_Pics|1" HTML сохранится в папку [Загрузки]/_Web/имя вкладки dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); // создать папку, если не существует… var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(dir.path); dir.append(fileName); await IOUtils[write](dir.path, fileContent) && showInStatusPanel("√ страница записана: " + fileName.slice(0, 60)); var d = await Downloads.createDownload({ source: "about:blank", target: FileUtils.File(dir.path)}); // Fake download (await Downloads.getList(Downloads.ALL)).add(d); d.refresh(d.succeeded = true); // кнопка Загрузки мигает } messageManager.addMessageListener(msgName, msgListener); addDestructor(() => messageManager.removeMessageListener(msgName, msgListener)); var svc = 'globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services'; var url = "data:;charset=utf8," + encodeURIComponent(`(${func})(${svc});`.replace("%MSG_NAME%", msgName)); (save = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, // end save tid, allowMousedown, listener = { handleEvent(e) { if (e.detail > 2) return; var btn = e.target; var dbl = e.detail == 2; var num = (btn == pui && 100) + 16 * e.button + 8 * e.ctrlKey + 4 * e.shiftKey + 2 * e.altKey + dbl; if (!this[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "mousedown"; } if (dbl) tid &&= clearTimeout(tid), this[num](btn); else tid = setTimeout(this.exec, 300, num, btn, this); }, exec(num, btn, self) { tid = null; self[num](btn); }, mousedown(btn) { allowMousedown = true; btn.dispatchEvent(new MouseEvent("mousedown", {})); allowMousedown = false; }, context(btn) { btn.removeAttribute("context"); btn.dispatchEvent(new MouseEvent("contextmenu", this.a)); btn.toggleAttribute("context"); }, switchToTab(but, url) { // открыть вкладку | закрыть, если открыта for(var tab of but.ownerGlobal.gBrowser.tabs) if ( tab.linkedBrowser.currentURI.spec == url ) {but.ownerGlobal.gBrowser.removeTab(tab); return;}; // вкладка найдена, закрыть but.ownerGlobal.switchToTabHavingURI(url, true, {relatedToCurrent: true, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0}, /*** ======= Downloads Clicks ======= ***/ 16: saveSelectionToTxt, // СКМ Click (сохранить .txt) 1() { // Double Left Click - Обзор папки «Загрузки» Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError) // Обзор папки «Загрузки» }, 32: save, // ПКМ Click (Single HTML) 33(btn) { // Double Right Click var pref = "permissions.default.image"; var one = prefs.getIntPref(pref) == 1; prefs.setIntPref(pref, one ? 2 : 1); btn.style.filter = one ? "hue-rotate(180deg) brightness(95%)" : ""; BrowserReload(); }, 2() { // Alt + ЛКМ }, /*** ======= PanelUI-menu Clicks ======= ***/ 102() { gCustomizeMode.enter(); // ЛКМ + Alt Персонализация }, 104() { // Shift + ЛКМ var help_ucf = ['chrome://user_chrome_files/content/help.html', 'http://forum.puppyrus.org/index.php?topic=22762']; var newURI = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).convertChromeURL(Services.io.newURI(help_ucf[0])); // .spec = file:/// (newURI.QueryInterface(Ci.nsIFileURL).file.exists()) ? this.switchToTab(pui, help_ucf[0]) : this.switchToTab(pui, help_ucf[1]); }, 118: BrowserFullScreen, // Alt + СКМ 116() { // СКМ windowState != STATE_MAXIMIZED ? maximize() : restore(); }, 117: BrowserReloadSkipCache, // СКМ Double 132() { // ПКМ minimize(); }, 134(pui) { // Alt + ПКМ this.switchToTab(pui, 'about:performance'); }, 136(pui) { // Shift + ПКМ pui.ownerDocument.getElementById("key_responsiveDesignMode").doCommand(); // запуск пункта меню с HotKey }, 138(pui) { // Shift + Alt + ПКМ var obj = ChromeUtils.import("resource://devtools/shared/Loader.jsm").require("devtools/client/menus").menuitems.find(menuitem => menuitem.id == "menu_devtools_remotedebugging"); (this[136] = target => obj.oncommand({target}))(pui); // запуск пункта меню, у которого нет HotKey }, 101: BrowserTryToCloseWindow, // Double Left Click 133(pui) { // ПКМ Double Right Click pui.ownerGlobal.undoCloseTab(); }, }, // end Clicks keydown_win = e => { // нажатие клавиш if (e.keyCode == 83 && e.altKey) e.shiftKey // Alt+S [+Shift] ? singlesave ? singlesave.click() : save() : save(); // имитировать клик по кнопке, используя её ID }, {prefs, dirsvc} = Services, linux = /macos|linux/.test(AppConstants.platform), singlesave; prefs.setBoolPref("browser.download.autohideButton", false); // не скрывать кнопку Загрузки var mouseenter = function(e) { this.parentNode.addEventListener("mousedown", stop, true); this.addEventListener("mouseleave", mouseleave, {once: true}); if ((e.target == pui) && (!/справка/.test(pui.tooltipText))) pui.tooltipText = PanelUI_help; // обновить подсказки кнопок if (e.target == btn) { var singlesave = document.getElementById("_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action"), dw; try {dw = prefs.getComplexValue("browser.download.dir",Ci.nsIFile)} catch {dw = dirsvc.get("DfltDwnld", Ci.nsIFile)}; // if (!/Двойной/.test(btn.tooltipText)) btn.tooltipText = GetDynamicShortcutTooltipText(btn.id) + btn_help; // обновлять подсказку при наведении мыши if (singlesave){ if (!/SingleSave/.test(btn.tooltipText)) btn.tooltipText = btn.tooltipText + singlesave_help; } else btn.tooltipText = btn.tooltipText.replace(singlesave_help,''); if (!/выбранная/.test(btn.tooltipText)) btn.tooltipText = btn.tooltipText + `${dw ? "\n\n[Загрузки] — выбранная папка:\n"+ dw.path.substring(0,33) + `${dw.path.length > 32 ? `…\n…${dw.path.substring(dw.path.length -31, dw.path.length)}`: ""}` : ""}`; // сократить/разбить длинную строку } } var mouseleave = function(e) { this.parentNode.removeEventListener("mousedown", stop, true); } var stop = e => { e.button || allowMousedown || e.stopImmediatePropagation(); } var btns = [btn, pui]; for(var b of btns) { b.toggleAttribute("context"), b.addEventListener("click", listener, true), b.addEventListener("mouseenter", mouseenter); } window.addEventListener("keydown", keydown_win); var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; ucf[id] = {destructor() { for(var b of btns) { b.removeEventListener("click", listener, true); b.removeEventListener("mouseenter", mouseenter); if (b.matches(":hover")) b.removeEventListener("mouseleave", mouseleave), b.parentNode.removeEventListener("mousedown", stop, true); } window.removeEventListener("keydown", keydown_win); }}; ucf.unloadlisteners.push(id); })("downloads-button-click-listener", ({io, focus}) => { // SingleHTML не сохраняет svg графику var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec; } catch {} }, getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r; } catch(e) {} } }, encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else img = obj; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }, toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }, mainWin = {}; focus.getFocusedElementForWindow(content, true, mainWin); mainWin = mainWin.value; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild), meta = doc.createElement('meta'), sheets = doc.styleSheets, title = doc.getElementsByTagName('title')[0]; meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).trim(); fileName += "_" + new Date().toLocaleDateString('ru', {day: 'numeric', month: 'numeric', year: '2-digit'}) +'-'+ new Date().toLocaleTimeString().replace(/:/g, "։"); if (!/\.html?$/.test(fileName)) fileName += '.html'; sendAsyncMessage("%MSG_NAME%", [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', fileName]); }); // END hookClicks |
unter_officer > 13-11-2021 00:15:26 |
Dumby |
Dobrov > 13-11-2021 02:00:44 |
unter_officer пишет
пример уже есть в этом топике Выделить код Код:(async (bar, exp, tid, self) => CustomizableUI.createWidget(self = { id: "test-button", localized: false, label: "Test Button", tooltiptext: `ЛКМ: Design View CKM: folder UCF`, onCreated(btn) { btn.onclick = this.click; btn.toggleAttribute("context"); btn.setAttribute("image", "chrome://browser/skin/preferences/application.png"); }, exec(num, win) { tid = null; self[num](win); }, context(win) { var btn = win.document.getElementById(this.id); btn.removeAttribute("context"); btn.dispatchEvent(new win.MouseEvent("contextmenu", this.a)); btn.toggleAttribute("context"); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0}, click(e) { if (e.detail > 2) return; var n2 = e.button != 2; var dbl = e.detail == 2; var num = 16 * e.button + 8 * e.ctrlKey + 4 * e.shiftKey + 2 * e.altKey + dbl; if (!self[num]) { if (n2) return; num = "context"; for(var p in self.a) self.a[p] = e[p]; } var win = e.view; if (dbl) tid &&= win.clearTimeout(tid), self[num](win); else tid = win.setTimeout(self.exec, 300, num, win); }, 0(win) { // ЛКМ var btn = win.document.getElementById(this.id); btn.ownerDocument.getElementById("key_responsiveDesignMode").doCommand(); // запуск пункта меню с HotKey }, 1(win) { // Double Left Click win.alert("DBL Click"); }, 16: () => exp("UChrm", "user_chrome_files"), // СКМ }))( (win, bar) => win.SidebarUI.toggle(bar), (dir, sub) => { dir = Services.dirsvc.get(dir, Ci.nsIFile); sub && dir.append(sub); dir.exists() && dir.launch(); } ); |
Dobrov > 13-11-2021 06:39:10 |
Dumby - ещё просьба вдобавок к первой: Может, это пригодиться для отладки скриптов без перезапуска браузера. А может есть более простой способ отладки части кода кнопки? |
xrun1 > 13-11-2021 10:36:01 |
Dobrov |
Dobrov > 13-11-2021 13:46:13 |
xrun1 - не то. Цитата - Выполняем внешний скрипт. И никаких подгружаемых функций. |
Dumby > 13-11-2021 20:59:05 |
Dobrov пишет
Значит слушать клики на родительском контейнере и проверять id кликнутого.
Если scriptloader'ом по протоколу chrome:, то будет кэшироваться. скрытый текст Выделить код Код:Services.scriptloader.loadSubScriptWithOptions( "chrome://user_chrome_files/content/custom_scripts/user.js", {ignoreCache: true, target: {myVariable1, myVariable2, myFunction}} ); (new Function())(); тоже не подходит: «Functions created with the Function constructor do not create closures to their creation contexts; they always are created in the global scope.» Остаётся только direct eval().
Вот, сводный пример. Добавляем после ucf.unloadlisteners.push(id); скрытый текст Выделить код Код:..... var box = document.getElementById("page-action-buttons"); var key = document.getElementById("key_responsiveDesignMode"); var uri = Services.io.newURI("chrome://user_chrome_files/content/custom_scripts/user.js"); var boxLst = e => eval(Cu.readUTF8URI(uri)); box.addEventListener("auxclick", boxLst, true); addDestructor(() => box.removeEventListener("auxclick", boxLst, true)); user.js Выделить код Код:if ( e.button == 1 && e.target.id == "pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_" ) e.stopImmediatePropagation(), key.doCommand();
this[138], наверно. unter_officer пишет
А в чём конкретно затруднение? скрытый текст Выделить код Код:(async id => CustomizableUI.createWidget({ get label() { var l10n = new (ChromeUtils.import("resource://devtools/shared/Loader.jsm") .require("devtools/shared/l10n")).MultiLocalizationHelper( "devtools/client/locales/startup.properties", "devtools/client/locales/menus.properties" ); this.tooltiptext = l10n.getFormatStr( "toolbox.buttons.responsive", Services.appinfo.OS == "Darwin" ? "Cmd+Opt+M" : "Ctrl+Shift+M" ); delete this.label; return this.label = l10n.getStr("responsiveDesignMode.label"); }, id: "ucf-responsiveDesignMode-btn", localized: false, onCreated(btn) { btn._handleClick = this.click; btn.style.cssText = ` fill-opacity: 0 !important; -moz-context-properties: fill, fill-opacity !important; list-style-image: url(chrome://devtools/skin/images/command-responsivemode.svg) !important; `; }, click() { this.ownerDocument.getElementById(id).doCommand(); } }))("key_responsiveDesignMode"); |
unter_officer > 14-11-2021 01:00:53 |
Dumby пишет
Для меня это не так просто. Dumby, большое спасибо. |
Dobrov > 14-11-2021 02:19:52 |
Dumby - Спасибо! Ещё проблема: при возвращении из режима "Адаптивный дизайн" в обычный просмотр многие страницы остаются обрезанными, нужно F5 жать. Dumby - а как обновить подсказку для "Reader View" в панели адреса? Выделить код Код:var box = document.getElementById("page-action-buttons"); // кнопки панели адреса var boxLst = e => { if (e.button == 1 && e.target.id == "pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_") // Reader View e.stopImmediatePropagation(), document.getElementById("key_responsiveDesignMode").doCommand(); // Адаптивный дизайн } box.addEventListener("auxclick", boxLst, true); addDestructor(() => box.removeEventListener("auxclick", boxLst, true)); Dumby - Вопрос: в custom_script.js функция loadscript не грузит одну .JSM-ку, для которой нужна отдельная строка запуска : Выделить код Код:var EXPORTED_SYMBOLS = ["registerUCFTitleChanged", "UCFTitleChangedChild"]; function registerUCFTitleChanged() { // исправление заголовка вкладки ………… Попробуй исправить loadscript, чтобы он был более универсальный, а второй параметр мог быть именем выполняемой функции: Выделить код Код:const scripts = 'chrome://user_chrome_files/content/custom_scripts'; (async () => { // загрузка внешних js или jsm-скриптов var loadscript = (name, function_register) => { try { name.split('.').pop().split("?")[0].split("#")[0].toLowerCase() == "jsm" ? ChromeUtils.import(`${scripts}/${name}`, {}).function_register : Services.scriptloader.loadSubScript(`${scripts}/${name}`,globalThis,"UTF-8"); return true; } catch(e) {} }; loadscript("ucf_eom-button.js"); // нижеследующая строка не работает: // loadscript("UCFTitleChangedChild.jsm", registerUCFTitleChanged()); })(); |
Dumby > 14-11-2021 20:10:47 |
Dobrov пишет
Можно проверять gBrowser.selectedBrowser.browsingContext.inRDMPane
Если в смысле установить свою как для аддона, то вот вариант (в custom_script.js). скрытый текст Выделить код Код:(async url => { var tooltip = "Test Tooltip"; var m = "2495d258-41e7-4cd5-bc7d-ac15981f064e", id = `{${m}}`, aid = `_${m}_`; var manager = ChromeUtils.import(url).ExtensionParent.apiManager; var wait = (e, isAppShutdown) => isAppShutdown || manager.on("ready", onReady); var onReady = (e, addon) => { if (addon.id != id) return; manager.off("ready", onReady); addon.once("shutdown", wait); manager.global.PageActions.actionForID(aid).setTooltip(tooltip); } manager.on("ready", onReady); })("resource://gre/modules/ExtensionParent.jsm");
Что-то мне не слишком понятны код и задача, может так сойдёт? скрытый текст Выделить код Код:(async scripts => { var re = /\.jsm$/i; var loadscript = name => { try { var {href, pathname} = new URL(scripts + name); if (re.test(pathname)) return ChromeUtils.import(href); Services.scriptloader.loadSubScript(href); return true; } catch(ex) {Cu.reportError(ex);} } loadscript("ucf_eom-button.js"); loadscript("UCFTitleChangedChild.jsm")?.registerUCFTitleChanged?.(); })("chrome://user_chrome_files/content/custom_scripts/"); Добавлено: Хотя нет, сам вызов же может завершиться с ошибкой. Тогда затащим внутрь, как написано, второй параметр — имя выполняемой функции. скрытый текст Выделить код Код:(async scripts => { var re = /\.jsm$/i; var loadscript = (name, funcName) => { try { var {href, pathname} = new URL(scripts + name); if (re.test(pathname)) { var obj = ChromeUtils.import(href); funcName && obj[funcName](); } else Services.scriptloader.loadSubScript(href); return true; } catch(ex) {Cu.reportError(ex);} } loadscript("ucf_eom-button.js"); loadscript("UCFTitleChangedChild.jsm", "registerUCFTitleChanged"); })("chrome://user_chrome_files/content/custom_scripts/"); |
Dobrov > 15-11-2021 00:13:02 |
Dumby - Спасибо! обновление подсказки кнопки также работает из custom_script_win.js. Dumby - проверь мой новый загрузчик: (сократил, чтобы не повторять строки с loadscript) Выделить код Код:const scripts = 'chrome://user_chrome_files/content/custom_scripts/'; (async () => { // ваши скрипты [['ucf_QuickToggle.js'], ['UCFTitleChangedChild.jsm', 'registerUCFTitleChanged'], ['Test.jsm']] .forEach(function(name) { try { if (/\.jsm$/i.test(name[0])) { // [скрипт js или jsm, инициализация] var obj = ChromeUtils.import(scripts + name[0]); name[1] && obj[name[1]](); } else Services.scriptloader.loadSubScript(scripts + name[0]); } catch(ex) {Cu.reportError(ex);} }); })(); |
Dumby > 15-11-2021 13:39:52 |
Dobrov пишет
Ну, выглядит нормально. Или, в исходнике, name.split('.').pop().split("?")[0].split("#")[0].toLowerCase() |
Dobrov > 16-11-2021 16:02:55 |
Dumby - вопрос по коду обновления ToolTip кнопки расширения. Выделить код Код:var view_id = "2495d258-41e7-4cd5-bc7d-ac15981f064e"; // Reader View var vdh_id = "b9db16a4-6edc-47ec-a1f4-b86292ed211d"; // Video DownloadHelper var manager = ChromeUtils.import("resource://gre/modules/ExtensionParent.jsm").ExtensionParent.apiManager, wait = (e, isAppShutdown) => isAppShutdown || manager.on("ready", onReady), onReady = (e, addon) => { // if (addon.id != `{${view_id}}`) return; if (addon.id == `{${view_id}}`) { manager.off("ready", onReady), addon.once("shutdown", wait); manager.global.PageActions.actionForID(`_${view_id}_`).setTooltip(`Reader View ${Services.appinfo.OS == "Darwin" ? "⌥⌘M" : "Ctrl+⇧+M"}\n\nКлик мыши Режим для чтения\nКолёсико Адаптивный дизайн`); // изменить подсказку } if (addon.id == `{${vdh_id}}`) { manager.off("ready", onReady), addon.once("shutdown", wait); manager.global.PageActions.actionForID(`_${vdh_id}_`).setTooltip(`Video DownloadHelper\nСкачивание проигрываемого видео`); } }; manager.on("ready", onReady); |
Dumby > 17-11-2021 14:33:12 |
Dobrov пишет
Совсем разные вещи. У RV pageAction, а у VDH browserAction. скрытый текст Выделить код Код:(async url => { // Reader View var rv = "2495d258-41e7-4cd5-bc7d-ac15981f064e"; var rv_id = `{${rv}}`, rv_aid = `_${rv}_`; var rv_ttt = `Reader View ${Services.appinfo.OS == "Darwin" ? "⌥⌘M" : "Ctrl+⇧+M"}\n\nКлик мыши Режим для чтения\nКолёсико Адаптивный дизайн`; // Video DownloadHelper var vdh_id = "{b9db16a4-6edc-47ec-a1f4-b86292ed211d}"; var vdh_ttt = "Video DownloadHelper\nСкачивание проигрываемого видео"; var count = 0; var manager = ChromeUtils.import(url).ExtensionParent.apiManager; var wait = (e, isAppShutdown) => isAppShutdown || !--count || manager.on("ready", onReady); var onReady = (e, addon) => { if (addon.id == rv_id) manager.global.PageActions.actionForID(rv_aid).setTooltip(rv_ttt); else if (addon.id == vdh_id) setVDHTooltip(addon); else return; ++count == 2 && manager.off("ready", onReady); addon.once("shutdown", wait); } manager.on("ready", onReady); var setVDHTooltip = addon => { var vdh_wid = `_${vdh_id.slice(1, -1)}_-browser-action`; var {gPalette} = Cu.import("resource:///modules/CustomizableUI.jsm", {}); var upd = manager.global.browserAction.prototype.updateButton; var asgn = eval(`({${upd}})`.replace(/\n^.+"tooltiptext".+$/m, "")); (setVDHTooltip = addon => { var widget = gPalette.get(vdh_wid); widget.tooltiptext = vdh_ttt; var {action} = manager.global.browserActionFor(addon); Object.assign(action.buttonDelegate, asgn); for(var [, node] of widget.instances) node.setAttribute("tooltiptext", vdh_ttt); })(addon); } })("resource://gre/modules/ExtensionParent.jsm"); |
Dobrov > 18-11-2021 18:33:26 |
Dumby - ты делал перехват кликов для кнопок в панели адреса в скрипте ucf_hookClicks.js. Возможно ли доработать код, чтобы сразу перехватывать клики кнопок "nav-bar-customization-target" основной панели и "page-action-buttons" панели адреса ? Ещё хотелка - добавить перехват "wheel". Ожидаемый итог работы кода: перехват событий кнопок для двух панелей, разбор такой же, как в твоём коде перехвата кликов: 512: saveSelectionToTxt, // СКМ Click (сохранить .txt) цифра содержит сумму событий: id кнопки, клавиш мыши, мета-клавиш, тип кликов, скролл над кнопками тулбара… ucf_hookClicks.js - поменял подсчёт кнопок и клавиш - строка 136 Выделить код Код:(async (id, func) => { // для custom_script_win.js: дополнительные клики и подсказки кнопок await window.delayedStartupPromise; var box = document.getElementById("page-action-buttons"), // кнопки панели адреса nav = document.getElementById("nav-bar-customization-target"), // кнопки панели btn = document.getElementById("downloads-button"), // 0 Загрузки pui = document.getElementById("PanelUI-menu-button"), // 1 меню fav = document.getElementById("star-button"), // 2 prn = document.getElementById("print-button"), // 3 rv = "pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_", // 4 Reader View sgs = "_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action", // SingleSave button vdh = "_b9db16a4-6edc-47ec-a1f4-b86292ed211d_-browser-action"; /*Video DownloadHelper*/ if (!btn) return; btn_help =` Двойной клик: ⬇︎ открыть [Загрузки] …на картинке: ⧉ найти Похожие\n Правый клик (Alt+S): Сохранить в единый html всё / выделенное …дважды Картинки вкл/выкл\n Ролик: Сохранить как файл .txt Колёсико на рисунке: ➜ Сохранить`, PanelUI_help = `Клик мыши: меню Firefox ${Services.appinfo.platformVersion} …+ Shift ⚑ Краткая справка …+ Alt Персонализация Клик дважды ⊠ закрыть браузер \n Правый клик ⇲ Свернуть …+ дважды ⤾ Вернуть вкладку …+ Alt Диспетчер задач …+ Shift Адаптивный дизайн\n Колёсико: Развернуть | окно …+ Alt Полный экран …+ дважды Обновить без кэша`, sgs_help = `\nAlt⇧S ⌨ нажатие SingleSave`, rv_help = `Reader View ${Services.appinfo.OS == "Darwin" ? "⌥⌘M" : "Ctrl+⇧+M"}\n Клик мыши Режим для чтения Колёсико Адаптивный дизайн`; // vdh_help =`Video DownloadHelper\nСкачивание проигрываемого видео`; var addDestructor = nextDestructor => { var {destructor} = ucf[id]; ucf[id].destructor = () => { try {destructor();} catch(ex) {Cu.reportError(ex);} nextDestructor(); } }, showInStatusPanel = (info, time = 5000) => { var win = Services.wm.getMostRecentWindow("navigator:browser"); StatusPanel = win.StatusPanel; if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update; StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time); StatusPanel._label = info; }, Title = (max, title) => { // получить заголовок. без обрезки: max не указан, домен: max <0, + дата: max=0 if (!title) var title = document.title || gBrowser.selectedTab.label; if (max == undefined) return title; // заголовок как есть или ограничить длину, убрать служебные символы title = title.replace(/[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim(); if ( max > 0 ) return title.slice(0, max); if ( max == 0) return title.slice(0, 100) +"_"+ new Date().toLocaleDateString('ru', {day: 'numeric', month: 'numeric', year: '2-digit'}) +'-'+ new Date().toLocaleTimeString().replace(/:/g, "։"); var host = decodeURIComponent(gURLBar.value); // max < 0 if (!/^file:\/\//.test(host)) host = host.replace(/^.*url=|https?:\/\/|www\.|\/.*/g,''); return host.replace(/^ru\.|^m\.|forum\./,'').replace(/^club\.dns/,'dns'); }, saveSelectionToTxt = async () => { // сохранить страницу или выделенный текст как файл .txt var splice = saveURL.length == 10; var msgName = id + ":Save:GetSelection"; var receiver = msg => { var title = Title(0); var args = [ "data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\n\n" + msg.data), title + '.txt', null, false, true, null, window.document]; splice && args.splice(5, 0, null); saveURL(...args) && showInStatusPanel("√ текст сохранён: " + title.slice(0, 60)); } messageManager.addMessageListener(msgName, receiver); addDestructor(() => messageManager.removeMessageListener(msgName, receiver)); var func = fm => { var res, fed, win = {}, fe = fm.getFocusedElementForWindow(content, true, win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed) { var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if (sel.isCollapsed) fed && fed.blur(), docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(), docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("saveSelectionToTxt", res); } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})`.replace("saveSelectionToTxt", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, save = async () => { // SingleHtml by Лекс, правка: Dumby, Dobrov var msgName = id + "ucfDwnldsBtnSaveSnapshotToHTML"; if (typeof IOUtils != "object") { // Firefox 78 ESR var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); var PathUtils = {join: (...args) => OS.Path.join(...args)}; var IOUtils = {writeUTF8: (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt))}; } var write = IOUtils.writeUTF8 ? "writeUTF8" : "writeAtomicUTF8"; var msgListener = async msg => { var [fileContent, fileName] = msg.data, dir; // fileName: выделенный текст или null try {dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("ucf_save.dirs","_Web||_Images|0").split('|').slice(0,2); //subdir: title|host arr[1] = (arr[1] == "0") ? Title(100) : (arr[1] == "1") ? Title(-1) : ""; // имя вкладки или домен arr.forEach(dir.append); // ucf_save.dirs = "_Web||_Pics|1" HTML сохранится в папку [Загрузки]/_Web/label dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); // создать, если не существует… var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(dir.path); if (!fileName) fileName = Title(100); // убрать служебные символы dir.append(Title(0, fileName) +'.html'); await IOUtils[write](dir.path, fileContent) && showInStatusPanel("√ страница записана: " + fileName.slice(0, 60)); var d = await Downloads.createDownload({ source: "about:blank", target: FileUtils.File(dir.path)}); // Fake download (await Downloads.getList(Downloads.ALL)).add(d); d.refresh(d.succeeded = true); // кнопка Загрузки мигает } messageManager.addMessageListener(msgName, msgListener); addDestructor(() => messageManager.removeMessageListener(msgName, msgListener)); var svc = 'globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services'; var url = "data:;charset=utf8," + encodeURIComponent(`(${func})(${svc});`.replace("%MSG_NAME%", msgName)); (save = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, tid, allowMousedown, listener = { // доп.события для 15 кнопок handleEvent(e) { if (e.detail > 2) return; var btn = e.target; var dbl = e.detail == 2; var num = e.button *512 + e.metaKey *256 + e.ctrlKey *128 + e.shiftKey *64 + e.altKey *32 + dbl *16 + (btn == document.getElementById(rv) && 4) + (btn == prn && 3) + (btn == fav && 2) + (btn == pui && 1); if (!this[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "mousedown"; } if (dbl) tid &&= clearTimeout(tid), this[num](btn); else tid = setTimeout(this.exec, 300, num, btn, this); }, exec(num, btn, self) { tid = null; self[num](btn); }, mousedown(btn) { allowMousedown = true; btn.dispatchEvent(new MouseEvent("mousedown", {})); allowMousedown = false; }, context(btn) { btn.removeAttribute("context"); btn.dispatchEvent(new MouseEvent("contextmenu", this.a)); btn.toggleAttribute("context"); }, switchToTab(but, url) { // открыть вкладку | закрыть, если открыта for(var tab of but.ownerGlobal.gBrowser.tabs) if ( tab.linkedBrowser.currentURI.spec == url ) {but.ownerGlobal.gBrowser.removeTab(tab); return;}; // вкладка найдена, закрыть but.ownerGlobal.switchToTabHavingURI(url, true, {relatedToCurrent: true, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0}, /*** ======= Downloads Clicks ======= ***/ 512: saveSelectionToTxt, // СКМ Click (сохранить .txt) 16() { // Double Left Click - Обзор папки «Загрузки» Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError) // Обзор папки «Загрузки» }, 1024: save, // ПКМ Click (Single HTML) 1040(btn) { // Double Right Click var pref = "permissions.default.image"; var one = prefs.getIntPref(pref) == 1; prefs.setIntPref(pref, one ? 2 : 1); btn.style.filter = one ? "hue-rotate(180deg) brightness(95%)" : ""; BrowserReload(); }, /*** ======= PanelUI-menu Clicks ======= 100*pui 32*e.button 8*e.ctrlKey 4*e.shiftKey 2*e.altKey dbl btn ***/ 33() { gCustomizeMode.enter(); // ЛКМ + Alt Персонализация }, 65() { // Shift + ЛКМ var help_ucf = ['chrome://user_chrome_files/content/help.html', 'http://forum.puppyrus.org/index.php?topic=22762']; var newURI = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).convertChromeURL(Services.io.newURI(help_ucf[0])); // .spec = file:/// (newURI.QueryInterface(Ci.nsIFileURL).file.exists()) ? this.switchToTab(pui, help_ucf[0]) : this.switchToTab(pui, help_ucf[1]); }, 545: BrowserFullScreen, // Alt + СКМ 513() { // СКМ windowState != STATE_MAXIMIZED ? maximize() : restore(); }, 529: BrowserReloadSkipCache, // СКМ Double 1025() { // ПКМ minimize(); }, 1057(pui) { // Alt + ПКМ this.switchToTab(pui, 'about:performance'); }, 1089(pui) { // Shift + ПКМ pui.ownerDocument.getElementById("key_responsiveDesignMode").doCommand(); // запуск пункта меню с HotKey if (gBrowser.selectedBrowser.browsingContext.inRDMPane) BrowserReload(); }, 1153(pui) { // Shift + Alt + ПКМ var obj = ChromeUtils.import("resource://devtools/shared/Loader.jsm").require("devtools/client/menus").menuitems.find(menuitem => menuitem.id == "menu_devtools_remotedebugging"); (this[138] = target => obj.oncommand({target}))(pui); // запуск пункта меню, у которого нет HotKey }, 17: BrowserTryToCloseWindow, // Double Left Click 1041(pui) { // ПКМ Double Right Click pui.ownerGlobal.undoCloseTab(); }, }, // end Clicks keydown_win = e => { // нажатие клавиш if (e.keyCode == 83 && e.altKey) e.shiftKey // Alt+S [+Shift] ? singlesave ? singlesave.click() : save() : save(); // имитировать клик по кнопке, используя её ID if (e.keyCode == 68 && e.altKey){ // Alt+D отладка - запуск внешнего JS // e.target.ownerDocument.getElementById("key_browserConsole").doCommand(); eval(Cu.readUTF8URI(Services.io.newURI("chrome://user_chrome_files/content/custom_scripts/User.js"))); console.log("END User.js " + Math.random()); } }, {prefs, dirsvc} = Services, linux = /macos|linux/.test(AppConstants.platform), singlesave; prefs.setBoolPref("browser.download.autohideButton", false); // не скрывать кнопку Загрузки var hint_upd = function(btn, text, find) { // обновить подсказку return; } var mouseenter = function(e) { this.parentNode.addEventListener("mousedown", stop, true); this.addEventListener("mouseleave", mouseleave, {once: true}); var sgs_btn = document.getElementById(sgs), dw; try {dw = prefs.getComplexValue("browser.download.dir",Ci.nsIFile)} catch {dw = dirsvc.get("DfltDwnld", Ci.nsIFile)}; var rv_btn = document.getElementById(rv); // Reader View if (e.target == rv_btn) { rv_btn.tooltipText = rv_help; } // var vdh_btn = document.getElementById(vdh); // Video DownloadHelper // if (e.target == vdh_btn) { // vdh_btn.tooltipText = vdh_help; // } if ((e.target == pui) && (!/справка/.test(pui.tooltipText))) pui.tooltipText = PanelUI_help; // обновить подсказки кнопок if (e.target == btn) { // if (!/Двойной/.test(btn.tooltipText)) btn.tooltipText = GetDynamicShortcutTooltipText(btn.id) + btn_help; // обновлять подсказку при наведении мыши if (sgs_btn){ if (!/SingleSave/.test(btn.tooltipText)) btn.tooltipText = btn.tooltipText + sgs_help; } else btn.tooltipText = btn.tooltipText.replace(sgs_help,''); if (!/выбранная/.test(btn.tooltipText)) btn.tooltipText = btn.tooltipText + `${dw ? "\n\n[Загрузки] — выбранная папка:\n"+ dw.path.substring(0,33) + `${dw.path.length > 32 ? `…\n…${dw.path.substring(dw.path.length -31, dw.path.length)}`: ""}` : ""}`; // сократить/разбить длинную строку } } var mouseleave = function(e) { this.parentNode.removeEventListener("mousedown", stop, true); } var stop = e => { e.button || allowMousedown || e.stopImmediatePropagation(); } var btns = [btn, pui]; for(var b of btns) { b.toggleAttribute("context"), b.addEventListener("click", listener, true), b.addEventListener("mouseenter", mouseenter); } var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; ucf[id] = {destructor() { for(var b of btns) { b.removeEventListener("click", listener, true); b.removeEventListener("mouseenter", mouseenter); if (b.matches(":hover")) b.removeEventListener("mouseleave", mouseleave), b.parentNode.removeEventListener("mousedown", stop, true); } }}; ucf.unloadlisteners.push(id); var boxLst = e => { console.log('@: '+ e.button); if (e.button == 1 && e.target.id == `pageAction-urlbar-_${rv}_`) { // Reader View Button e.stopImmediatePropagation(), document.getElementById("key_responsiveDesignMode").doCommand(); // Адаптивный дизайн if (gBrowser.selectedBrowser.browsingContext.inRDMPane) BrowserReload(); } } box.addEventListener("auxclick", boxLst, true); box.addEventListener("mouseenter", mouseenter, true); window.addEventListener("keydown", keydown_win); addDestructor(() => { box.removeEventListener("auxclick", boxLst, true); box.removeEventListener("mouseenter", mouseenter, true); window.removeEventListener("keydown", keydown_win); }); })("downloads-button-click-listener", ({io, focus}) => { // SingleHTML не сохраняет svg графику var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec;} catch {} }, getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r;} catch(e) {} } }, encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else img = obj; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }, toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }, mainWin = {}; focus.getFocusedElementForWindow(content, true, mainWin); mainWin = mainWin.value; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild), meta = doc.createElement('meta'), sheets = doc.styleSheets, title = doc.getElementsByTagName('title')[0]; meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var selText = selWin ? win.getSelection().toString().slice(0, 200) : undefined; sendAsyncMessage("%MSG_NAME%", [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', selText]); // выделенный текст }); // END hookClicks ucf_BookmarkDir.js - только как пример: яркость прокруткой над ★ Выделить код Код:(async (id, sel) => { // Клики на Звёздочке, ToolTip: расположение закладки в Избранном, Недавняя папка var g = Cu.getGlobalForObject(Cu), stt = g[id]; // https://forum.mozilla-russia.org/viewtopic.php?pid=790890#p790890 if (!stt) { var {obs, prefs} = Services, {bookmarks: bm, observers: pobs} = PlacesUtils; stt = g[id] = { bm, help_star: ` Правый клик: ⤾ Вернуть вкладку …+ Alt Перевод выдел.текст | Сайт …+ Shift Гугл Перевод или поиск\n Колесико ± Яркость страниц …+ клик Полная яркость`, pref: `ucf.${id}Guid`, events: ["bookmark-added"], async init() { this.handleEvent = e => this[e.type](e); if ((this.pbm = typeof PlacesBookmarkMoved == "function")) this.events.push("bookmark-moved"); else this.QueryInterface = g.ChromeUtils.generateQI([Ci.nsINavBookmarkObserver]), bm.addObserver(this); pobs.addListener(this.events, this.added = events => { for(var e of events) e.isTagging || this[e.constructor.name](e); }); obs.addObserver(this, "quit-application-granted"); this.args = [b => this.bguids.add(b.parentGuid), {concurrent: true}]; var guid = prefs.getStringPref(this.pref, ""); if (!guid) try {var [guid] = await PlacesUtils.metadata.get( PlacesUIUtils.LAST_USED_FOLDERS_META_KEY, [] )} catch {} this.guids.push(guid || await PlacesUIUtils.defaultParentGuid || bm.unfiledGuid); var pref = "ucf.tabbrowser-tabpanels.opacity"; // яркость страницы var getPref = () => Services.prefs.getIntPref(pref, 100); var css = `@-moz-document url(chrome://browser/content/browser.xhtml) { :is(${sel})[rst] {filter: grayscale(1%) !important;} :root:not([chromehidden*=toolbar]) #tabbrowser-tabbox {background-color: black !important;} :root:not([chromehidden*=toolbar]) #tabbrowser-tabpanels {opacity:${getPref()/100} !important;}}`; var subst = "ucf-tabbrowser-tabpanels-opacity-style", url = `resource://${subst}/`; Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(subst, Services.io.newURI("data:text/css," + encodeURIComponent(css))); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(Services.io.newURI(url), sss.USER_SHEET); var st = InspectorUtils.getAllStyleSheets(document).find(s => s.href == url).cssRules[0].cssRules[2].style; this.setPref = (e, val = 100) => { Services.prefs.setIntPref(pref, val); e.target.toggleAttribute("rst"); } this.wheel = e => { var val = getPref() + (e.deltaY < 0 ? 5 : -5); // шаг val < 25 || val > 100 || this.setPref(e, val); } var observer = () => st.setProperty("opacity", getPref() / 100, "important"); Services.prefs.addObserver(pref, observer); this.removePrefObs = () => Services.prefs.removeObserver(pref, observer); }, observe() { this.pbm || bm.removeObserver(this); pobs.removeListener(this.events, this.added); obs.removeObserver(this, "quit-application-granted"); prefs.setStringPref(this.pref, this.guids[0]); this.removePrefObs(); }, bguids: new g.Set(), guids: new g.Array(), skipTags: true, tt(win) { var list = win.InspectorUtils .getChildrenForNode(win.document.documentElement, true); return list.item(list.length - 1); }, PlacesBookmarkAddition(e) { if (e.itemType == bm.TYPE_BOOKMARK && e.source == bm.SOURCES.DEFAULT) this.guids[0] = e.parentGuid; }, PlacesBookmarkMoved(e) { e.parentGuid != e.oldParentGuid && this.PlacesBookmarkAddition(e); }, onItemMoved(a, b, c, d, e, itemType, f, oldParentGuid, parentGuid, source) { this.PlacesBookmarkMoved({itemType, source, oldParentGuid, parentGuid}); }, fetch(win) { this.bguids.clear(); return bm.fetch({url: win.gBrowser.currentURI.spec}, ...this.args); }, addTab: function(win, url, add, params = {relatedToCurrent: true}) { // открыть адрес [add: в новой вкладке] params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); return (add) ? win.gBrowser.addTab(url, params) : win.gBrowser.loadURI(url, params); }, translate(browserMM, win, e, go) { // Google-перевод сайта | выделенного текста (go) поиск выдел. текста в Яндекс browserMM.addMessageListener('getSelect', function listener(msg) { var url = (msg.data) ? (go) ? "https://yandex.ru/search/?text="+ msg.data +"&src=suggest_Pers&lang=ru" // поиск текста в Яндекс : "https://translate.google.com/#view=home&op=translate&sl=auto&tl=ru&text="+ msg.data // Гугл перевод : "http://translate.google.com/translate?u="+ gURLBar.value +"&hl=ru&ie=UTF-8&sl=auto&tl=ru"; // Перевод сайта if (go && !msg.data) // Перевод сайти в Яндекс. ничего не выделено + go не пуст gBrowser.selectedTab = e.addTab(win, "https://translate.yandex.com/translate?url=" + gURLBar.value + "&dir=&ui=ru&lang=auto-ru", 1) else gBrowser.selectedTab = e.addTab(win, url, 1); browserMM.removeMessageListener('getSelect', listener, true); }); browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false); }, auxclick(e) { if (e.button == 2) { var win = e.view; if (e.altKey) this.translate(gBrowser.selectedBrowser.messageManager, win, this, 1); else if (e.shiftKey) this.translate(gBrowser.selectedBrowser.messageManager, win, this); else win.undoCloseTab(); } else this.setPref(e); }, find: obj => obj.name == "tooltiptext" }; var ps = ["onBeginUpdateBatch", "onEndUpdateBatch", "onItemChanged", "onItemVisited"]; var noop = () => {}; for(var p of ps) stt[p] = noop; stt.init(); var func = id => this[id].mouseenter = async function(e) { var win = e.view, star = e.target, result = [], starred = star.hasAttribute("starred"); starred && await this.fetch(win); this.help_star = this.help_star.replace(/Яркость страниц.*/, `Яркость страниц ${win.Services.prefs.getIntPref("ucf.tabbrowser-tabpanels.opacity", 100)}%`); for(var guid of (starred ? this.bguids : this.guids)) { var arr = [], num = 50; while(--num) { if (!star.matches(":hover")) return; var res = await this.bm.fetch(guid); if (!res) break; if ((guid = res.parentGuid) == this.bm.rootGuid) { arr.unshift(this.bm.getLocalizedTitle(res)); break; } arr.unshift(res.title || "[Безымянная папка]"); } arr.length && result.push(arr.join("\\")); } if (!star.matches(":hover")) return; var text = (await win.document.l10n.formatMessages([{ // стандартная подсказка id: star.getAttribute("data-l10n-id"), args: JSON.parse(star.getAttribute("data-l10n-args")) }]))[0].attributes.find(this.find).value, txt; if (result.length) { txt = result.join("\n"); txt = starred ? `\n\n★ ${result.length > 1 ? "Данные закладки добавлены" : "Данная закладка добавлена"} в:\n${txt}` : "\n\n★ Недавно добавленная папка:\n" + txt; } win.document.tooltipNode == star ? this.tt(win).label = text + this.help_star + txt : star.tooltipText = text + this.help_star + txt; } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})("${id}")`); g.ChromeUtils.compileScript(url).then(ps => ps.executeInGlobal(g)); } await delayedStartupPromise; var types = ["auxclick", "mouseenter", "wheel"]; var stars = Array.from(document.querySelectorAll(sel)); for(var star of stars) for(var type of types) star.addEventListener(type, stt); star.setAttribute("context", "event.stopPropagation()"); var destructor = () => { for(var star of stars) for(var type of types) star.removeEventListener(type, stt); } var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win; if (ucf) ucf[id] = {destructor}, ucf.unloadlisteners.push(id); else window.addEventListener("unload", destructor, {once: true}); })("ucfBookmarksStarFTooltipHelper", "#star-button, #context-bookmarkpage"); ucf_QuickToggle.js - здесь код LongPress |
Dumby > 22-11-2021 21:25:38 |
Dobrov пишет
Так PanelUI-menu-button же торчит в коде,
Раз предполагаются элементы с видимыми для мыши
И ты думаешь я смогу это всё нормально записать? скрытый текст Выделить код Код:(() => { var c = msg => Services.console.logStringMessage("[HC] " + msg); var data = { "#downloads-button": { mousedownTarget: true, 128() { // СКМ Click c("Downloads Button Middle Click"); }, 4() { // Double Left Click c("Downloads Button Double Left Click"); }, 256() { // ПКМ Click c("Downloads Button Right Click"); }, 260(btn) { // Double Right Click c("Downloads Button Double Right Click"); }, 1() { // Left Long Press c("Downloads Button Left Long Press"); }, }, "#PanelUI-menu-button": { mousedownTarget: true, 8() { // ЛКМ + Alt c("PUI Button Alt + Left Click"); }, 16(btn) { // Shift + ЛКМ c("PUI Button Shift + Left Click"); }, 136(btn) { // Alt + СКМ c("PUI Button Alt + Middle Click"); }, 128() { // СКМ c("PUI Button Middle Click"); }, 132() { // СКМ Double c("PUI Button Double Middle Click"); }, 256() { // ПКМ c("PUI Button Right Click"); }, 264(btn) { // Alt + ПКМ c("PUI Button Alt + Right Click"); }, 272() { // Shift + ПКМ c("PUI Button Shift + Right Click"); }, 280(btn) { // Shift + Alt + ПКМ c("PUI Button Shift + Alt + Right Click"); }, 4() { // Double Left Click c("PUI Button Double Left Click"); }, 260() { // ПКМ Double Right Click c("PUI Button Double Right Click"); }, 145() { // Shift + Middle Long Press c("PUI Button Shift + Middle Long Press"); }, }, "#pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_": { // Reader View Button 128() { // Middle Click c("Reader View Middle Click"); }, 289() { // Ctrl + Right Long Press c("Reader View Ctrl + Right Long Press"); }, 2(trg, forward) { // wheel c("Reader View Wheel " + (forward ? "forward" : "backward")); }, }, "#star-button-box": { 1() { // Left Long Press c("Star Left Long Press"); }, 4() { // Double Left Click c("Star Double Left Click"); }, 129() { // Middle Long Press c("Star Middle Long Press"); }, }, "#identity-permission-box": { 2(trg, forward) { // wheel c("Identity Permisson Box Wheel " + (forward ? "forward" : "backward")); } }, "#identity-box": { 2(trg, forward) { // wheel c("Identity Box Wheel " + (forward ? "forward" : "backward")); }, 34(trg, forward) { // Ctrl + wheel c("Identity Box Ctrl + Wheel " + (forward ? "forward" : "backward")); }, }, "#identity-icon-box": { 16() { // Shift + Left Click c("Identity Icon Box Shift + Left Click"); }, }, }; var listener = { filter(sel) { return this.closest(sel); }, find(sel) { return data[sel][this] || data[sel][this + 1]; }, handleEvent(e) { if (this.skip || e.detail > 2) return; var trg = e.target; var sels = this.selectors.filter(this.filter, trg); var {length} = sels; if (!length) return; var dbl = e.detail == 2; var wh = e.type.startsWith("w"); var num = e.metaKey *64 + e.ctrlKey *32 + e.shiftKey *16 + e.altKey *8 + (wh ? 2 : e.button *128 + dbl *4); var obj = data[ length > 1 && sels.find(this.find, num) || sels[0] ]; // wheel if (wh) return obj[num]?.(trg, e.deltaY < 0); // mousedown if (e.type.startsWith("m")) { obj.mousedownTarget && this.stop(e); if (dbl) return; this.longPress = false; if (++num in obj) this.mousedownTID = setTimeout(this.onLongPress, 640, trg, obj, num); if (e.button == 2) this.ctx = trg.getAttribute("context"), trg.setAttribute("context", ""); return; } // click obj.mousedownTarget || this.stop(e); if (this.longPress) return this.longPress = false; dbl ? this.clickTID &&= clearTimeout(this.clickTID) : this.mousedownTID &&= clearTimeout(this.mousedownTID); if (!obj[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "dispatch", this.mdt = obj.mousedownTarget; obj = this; } dbl ? obj[num](trg) : this.clickTID = setTimeout(this.exec, 300, trg, obj, num); }, get selectors() { this.exec = (trg, obj, num) => { this.clickTID = null; obj[num](trg); } this.onLongPress = (trg, obj, num) => { this.mousedownTID = null; this.longPress = true; obj[num](trg); } delete this.selectors; return this.selectors = Object.keys(data); }, get mdEvent() { delete this.mdEvent; return this.mdEvent = new MouseEvent("mousedown", {bubbles: true}); }, context(trg) { this.ctx ? trg.setAttribute("context", this.ctx) : trg.removeAttribute("context"); trg.dispatchEvent(new MouseEvent("contextmenu", this.a)); }, dispatch(trg) { this.skip = true; this.mdt ? trg.dispatchEvent(this.mdEvent) : trg.click(); this.skip = false; }, stop: e => { e.preventDefault(); e.stopImmediatePropagation(); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0} }; var root = document.getElementById("nav-bar"); var events = ["click", "mousedown", "wheel"]; for(var type of events) root.addEventListener(type, listener, true); var id = "test-hookClicks"; ucf_custom_script_win.unloadlisteners.push(id); ucf_custom_script_win[id] = {destructor() { for(var type of events) root.removeEventListener(type, listener, true); }}; })(); |
Dobrov > 23-11-2021 02:02:40 |
Dumby спасибо за отличный код дополнительных кликов. Только не понял, как в код обновления tooltips добавить removeEventListener и нужен ли он. Ещё не обновляются подсказки для 1) tracking-protection-icon-container "На этой странице не обнаружено ни одного известного Firefox трекера" и 2) identity-icon-box "Подтверждено: Let's Encrypt". |
Dumby > 23-11-2021 22:34:40 |
Dobrov пишет
Да так же как и в коде для кликов. Допустим, тултипский код рядом, сразу после var listener = {.....}; скрытый текст Выделить код Код:....... var str_cut = s => s; var dsym = Symbol(); var j = (...args) => args.join("\n"); var tooltips = { get "PanelUI-menu-button"() { delete this["PanelUI-menu-button"]; return j( `Клик мыши: меню Firefox ${Services.appinfo.platformVersion}`, "…+ Shift ⚑ Краткая справка", "…+ Alt Персонализация", "Клик дважды ⊠ закрыть браузер\n", "Правый клик ⇲ Свернуть", "…+ дважды ⤾ Вернуть вкладку", "…+ Alt Диспетчер задач", "…+ Shift Адаптивный дизайн\n", "Колёсико: Развернуть | окно", "…+ Alt Полный экран", "…+ дважды Обновить без кэша" ); }, "pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_": j( `Reader View ${Services.appinfo.OS == "Darwin" ? "⌥⌘M" : "Ctrl+⇧+M"}\n`, "Клик мыши Режим для чтения", "Колёсико Адаптивный дизайн" ), "_b9db16a4-6edc-47ec-a1f4-b86292ed211d_-browser-action": j( "Video DownloadHelper", "Скачивание проигрываемого видео" ), [dsym]: j( GetDynamicShortcutTooltipText("downloads-button"), "\nДвойной клик: ⬇︎ открыть [Загрузки]", "…на картинке: ⧉ найти Похожие\n", "Правый клик (Alt+S): Сохранить", " в единый html всё / выделенное", "…дважды Картинки вкл/выкл\n", "Ролик: Сохранить как файл .txt", "Колёсико на рисунке: ➜ Сохранить" ), get "downloads-button"() { var hint = this[dsym]; if (document.getElementById("_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action")) hint += "\nAlt⇧S ⌨ нажатие SingleSave"; try {var dw = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dw = Services.dirsvc.get("DfltDwnld", Ci.nsIFile);} if (dw) hint += "\n\n[Загрузки] — выбранная папка:\n" + str_cut(dw.path, 33); return hint; }, get "identity-icon-box"() { var ttt = ""; var trg = window.event.target; if (!trg.id.endsWith("x")) { if (trg.hasAttribute("tooltiptext")) ttt = trg.ttt = trg.tooltipText; else ttt = trg.ttt; if (ttt) ttt += "\n\n"; trg.removeAttribute("tooltiptext"); } return ttt + "Свой текст"; }, get "tracking-protection-icon-container"() { var trg = window.event?.target; return trg.id.endsWith("r") && trg.textContent + "\n\nСвой текст"; } }; document.getElementById("tracking-protection-icon-container") .removeAttribute("tooltip"); var onMouseenter = e => { var trg = e.target; var hint = tooltips[trg.id] || tooltips[(trg = trg.parentNode).id]; if (hint) trg.tooltipText = hint; } var root = document.getElementById("nav-bar"); var events = ["click", "mousedown", "wheel"]; root.addEventListener("mouseenter", onMouseenter, true); for(var type of events) root.addEventListener(type, listener, true); var id = "hookClicks-and-tooltips"; ucf_custom_script_win.unloadlisteners.push(id); ucf_custom_script_win[id] = {destructor() { root.removeEventListener("mouseenter", onMouseenter, true); for(var type of events) root.removeEventListener(type, listener, true); }}; })(); |
Dobrov > 30-11-2021 07:08:17 |
Dumby - спасибо! Скрипт hookClicks пригодится многим, он позволит прописывать обработку кликов в одном скрипте и позволит «разгрузить» другие кнопки, не добавлять в них код обработки кликов. hookClicks дополнительные клики и подсказки кнопок Выделить код Код:(async (id, func) => { // для custom_script_win.js: дополнительные клики и подсказки кнопок © Dumby, mod Dobrov var dsym = Symbol(), j = (...args) => args.join("\n"), br_val = () => { return ` ${Services.prefs.getIntPref("ucf.tabbrowser-tabpanels.opacity",100)}%`;}, br_txt = `Клик ролика сброс яркости\nКрутить ± Яркость страниц`, tooltips = { get "PanelUI-menu-button"() { /* delete this["PanelUI-menu-button"]; */ return j( `Клик мыши: меню Firefox ${Services.appinfo.platformVersion}`, `… держать ⚑ Краткая справка`, `…+ Alt Персонализация`, `Клик дважды ⊠ закрыть браузер\n`, `Правый клик ⇲ Свернуть`, `…+ дважды ⤾ Вернуть вкладку`, `…+ Alt Диспетчер задач\n`, `Колёсико: Развернуть | окно`, `…+ Alt Полный экран`, `…+ дважды Обновить без кэша` );}, [dsym]: j(GetDynamicShortcutTooltipText("downloads-button"), `\nДвойной клик: ⬇︎ открыть [Загрузки]`, `…на картинке: ⧉ найти Похожие\n`, `Правый клик (Alt+S): Сохранить`, ` в единый html всё / выделенное`, `…дважды Картинки вкл/выкл\n`, `Ролик: Сохранить как файл .txt`, `Колёсико на рисунке: ➜ Сохранить` ), get "titlebar-button titlebar-close"() { return j( `Закрыть Firefox ${AppConstants.MOZ_APP_VERSION.replace(/-.*/,'')}\n`, `◉ колёсико вернуть вкладку`, `◧ держать краткая Справка`, `◨ пр. клик ⇲ Свернуть`); }, get "pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_"() { return j( `Reader View ${Services.appinfo.OS == "Darwin" ? "⌥⌘M" : "Ctrl+⇧+M"}\n`, `Клик мыши Режим для чтения`, `Колёсико Адаптивный дизайн\nКолесико ± Яркость сайта` + br_val()); }, "_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action": `Сохранить страницу с помощью SingleFile (Alt+S)` , "_b9db16a4-6edc-47ec-a1f4-b86292ed211d_-browser-action": `Video DownloadHelper\nСкачивание проигрываемого видео` , get "downloads-button"() { var hint = this[dsym]; if (document.getElementById("_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action")) hint += "\nAlt⇧S ⌨ нажатие SingleSave"; //убрать/добавить try {var dw = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dw = Services.dirsvc.get("DfltDwnld", Ci.nsIFile);} //отличается от ⇧ if (dw) hint += "\n\n[Загрузки] — выбранная папка:\n" + str_cut(dw.path, 33); return hint; }, get "identity-icon-box"() { var trg = window.event.target, ttt = ""; if (!trg.id.endsWith("x")) { if (trg.hasAttribute("tooltiptext")) ttt = trg.ttt = trg.tooltipText; else ttt = trg.ttt; if (ttt) ttt += "\n\n"; trg.removeAttribute("tooltiptext"); } return ttt +`Правый клик Копировать адрес в буфер\n`+ br_txt + br_val(); }, get "tracking-protection-icon-container"() { var trg = window.event?.target; return trg.id.endsWith("r") && trg.textContent + "\n\n" + br_txt + br_val(); } }; /* end tooltips */ document.getElementById("tracking-protection-icon-container").removeAttribute("tooltip"); var listener = { // дополнительные клики кнопок и перехват существующих filter(sel) { return this.closest(sel); }, find(sel) { return data[sel][this] || data[sel][this + 1]; }, handleEvent(e) { if (this.skip || e.detail > 2) return; var trg = e.target; var sels = this.selectors.filter(this.filter, trg); var {length} = sels; if (!length) return; var dbl = e.detail == 2; var wh = e.type.startsWith("w"); var num = e.metaKey *64 + e.ctrlKey *32 + e.shiftKey *16 + e.altKey *8 + (wh ? 2 : e.button *128 + dbl *4); var obj = data[ length > 1 && sels.find(this.find, num) || sels[0] ]; // wheel if (wh) return obj[num]?.(trg, e.deltaY < 0); // mousedown if (e.type.startsWith("m")) { obj.mousedownTarget && this.stop(e); if (dbl) return; this.longPress = false; if (++num in obj) this.mousedownTID = setTimeout(this.onLongPress, 640, trg, obj, num); if (e.button == 2) this.ctx = trg.getAttribute("context"), trg.setAttribute("context", ""); return; } // click obj.mousedownTarget || this.stop(e); if (this.longPress) return this.longPress = false; dbl ? this.clickTID &&= clearTimeout(this.clickTID) : this.mousedownTID &&= clearTimeout(this.mousedownTID); if (!obj[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "dispatch", this.mdt = obj.mousedownTarget; obj = this; } dbl ? obj[num](trg) : this.clickTID = setTimeout(this.exec, 300, trg, obj, num); }, get selectors() { this.exec = (trg, obj, num) => { this.clickTID = null; obj[num](trg); } this.onLongPress = (trg, obj, num) => { this.mousedownTID = null; this.longPress = true; obj[num](trg); } delete this.selectors; return this.selectors = Object.keys(data); }, get mdEvent() { delete this.mdEvent; return this.mdEvent = new MouseEvent("mousedown", {bubbles: true}); }, context(trg) { this.ctx ? trg.setAttribute("context", this.ctx) : trg.removeAttribute("context"); trg.dispatchEvent(new MouseEvent("contextmenu", this.a)); }, dispatch(trg) { this.skip = true; this.mdt ? trg.dispatchEvent(this.mdEvent) : trg.click(); this.skip = false; }, stop: e => { e.preventDefault(); e.stopImmediatePropagation(); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0} }; var onMouseenter = e => { var trg = e.target, id = trg.id || trg.className; console.log('id= «'+ id + '» '+ Math.random()); var hint = tooltips[id] || tooltips[(trg = trg.parentNode).id]; if (hint) trg.tooltipText = hint; } var keydown_win = e => { // нажатие клавиш if (e.keyCode == 83 && e.altKey) { // Alt+S [+Shift] var singlesave = document.getElementById('_531906d3-e22f-4a6c-a102-8057b88a1a63_-browser-action'); e.shiftKey ? singlesave ? singlesave.click() : save() : save(); // имитировать клик по кнопке, используя её ID } if (e.keyCode == 88 && e.altKey){ // Alt+X отладка внешнего JS-кода // e.target.ownerDocument.getElementById("key_browserConsole").doCommand(); eval(Cu.readUTF8URI(Services.io.newURI("chrome://user_chrome_files/content/custom_scripts/User.js"))); console.log("[END] User.js " + Math.random()); } } var root = document.getElementById("navigator-toolbox"); var events = ["click", "mousedown", "wheel"]; root.addEventListener("mouseenter", onMouseenter, true); for(var type of events) root.addEventListener(type, listener, true); window.addEventListener("keydown", keydown_win); ucf_custom_script_win.unloadlisteners.push(id); ucf_custom_script_win[id] = {destructor() { root.removeEventListener("mouseenter", onMouseenter, true); for(var type of events) root.removeEventListener(type, listener, true); window.removeEventListener("keydown", keydown_win); }}; addDestructor = nextDestructor => { var {destructor} = ucf_custom_script_win[id]; ucf_custom_script_win[id].destructor = () => { try {destructor();} catch(ex) {Cu.reportError(ex);} nextDestructor(); } }; // end Hooks var {prefs, dirsvc} = Services, getIntPref = (p) => prefs.getIntPref(p, 100), c = msg => Services.console.logStringMessage("[HC] "+ msg), // отладка sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService), my_br = "ucf.tabbrowser-tabpanels.opacity", // яркость страниц css = `@-moz-document url(chrome://browser/content/browser.xhtml) { :is(${id})[rst] {filter: grayscale(1%) !important;} :root:not([chromehidden*=toolbar]) #tabbrowser-tabbox {background-color: black !important;} :root:not([chromehidden*=toolbar]) #tabbrowser-tabpanels {opacity:${getIntPref(my_br)/100} !important;}}`, subst = "ucf-tabbrowser-tabpanels-opacity-style", url = `resource://${subst}/`; Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(subst, Services.io.newURI("data:text/css," + encodeURIComponent(css))); sss.loadAndRegisterSheet(Services.io.newURI(url), sss.USER_SHEET); var st = InspectorUtils.getAllStyleSheets(document).find(s => s.href == url).cssRules[0].cssRules[2].style; var observer = () => st.setProperty("opacity", getIntPref(my_br)/100, "important"); prefs.addObserver(my_br, observer); this.removePrefObs = () => prefs.removeObserver(my_br, observer); // end яркость if (typeof IOUtils != "object") { // Firefox 78 ESR var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); var PathUtils = {join: (...args) => OS.Path.join(...args)}; var IOUtils = {writeUTF8: (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt))}; }; prefs.setBoolPref("browser.download.autohideButton", false); // не скрывать кнопку Загрузки str_cut = (s, cut = 33) => { // сократить/разбить строку return s.substring(0,cut) + `${s.length > cut - 1 ? `…\n…${s.substring(s.length -cut + 2, s.length)}`: ''}`; }, url_color = (color = "rgba(240,176,0,0.5)", ms = 300) => { // строка адреса мигает var u_alert = document.getElementById("urlbar-input-container"); u_alert.style.background = color; setTimeout(() => u_alert.style.background = "", ms); }, gClipboard = { get ch() { delete this.ch; return this.ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, write(str) { this.ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard);} }, switchToTab = (url, but = window) => { // открыть вкладку | закрыть, если открыта for(var tab of but.ownerGlobal.gBrowser.tabs) if (tab.linkedBrowser.currentURI.spec == url) {but.ownerGlobal.gBrowser.removeTab(tab); return;}; // закрыть but.ownerGlobal.switchToTabHavingURI(url, true, {relatedToCurrent: true, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }, showInStatusPanel = (info, time = 5000) => { StatusPanel = window.StatusPanel; if (StatusPanel.update.tid) clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update; StatusPanel.update(); } } StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time); StatusPanel._label = info; }, Title = (max, title) => { // получить заголовок. без обрезки: max не указан, домен: max <0, + дата: max=0 if (!title) var title = document.title || gBrowser.selectedTab.label; if (max == undefined) return title; // заголовок как есть или ограничить длину, убрать служебные символы title = title.replace(/[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim(); if ( max > 0 ) return title.slice(0, max); if ( max == 0) return title.slice(0, 100) +"_"+ new Date().toLocaleDateString('ru', {day: 'numeric', month: 'numeric', year: '2-digit'}) +'-'+ new Date().toLocaleTimeString().replace(/:/g, "։"); var host = decodeURIComponent(gURLBar.value); // max < 0 if (!/^file:\/\//.test(host)) host = host.replace(/^.*url=|https?:\/\/|www\.|\/.*/g,''); return host.replace(/^ru\.|^m\.|forum\./,'').replace(/^club\.dns/,'dns'); }, saveSelectionToTxt = async () => { // сохранить выделенный/весь текст страницы как .txt var msgName = id + ":Save:GetSelection", splice = saveURL.length == 10; var receiver = msg => { var args = ["data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\n\n" + msg.data), Title(0) + '.txt', null, false, true, null, window.document]; splice && args.splice(5, 0, null); saveURL(...args); showInStatusPanel("√ текст сохранён: "+ Title(0).slice(0, 60)); } messageManager.addMessageListener(msgName, receiver); addDestructor(() => messageManager.removeMessageListener(msgName, receiver)); var func = fm => { var res, fed, win = {}, fe = fm.getFocusedElementForWindow(content, true, win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed) { var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if (sel.isCollapsed) fed && fed.blur(), docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(), docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("saveSelectionToTxt", res); } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})`.replace("saveSelectionToTxt", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, save = async () => { // SingleHtml by Лекс, правка: Dumby, Dobrov var msgName = id + "ucfDwnldsBtnSaveSnapshotToHTML"; var write = IOUtils.writeUTF8 ? "writeUTF8" : "writeAtomicUTF8"; var msgListener = async msg => { var [fileContent, fileName] = msg.data, dir; // fileName: выделенный текст или null try {dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("ucf_save.dirs","_Web||_Images|0").split('|').slice(0,2); //subdir: title|host arr[1] = (arr[1] == "0") ? Title(100) : (arr[1] == "1") ? Title(-1) : ""; // имя вкладки или домен arr.forEach(dir.append); // ucf_save.dirs = "_Web||_Pics|1" HTML сохранится в папку [Загрузки]/_Web/label dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); // создать, если не существует… var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(dir.path); if (!fileName) fileName = Title(100); // убрать служебные символы dir.append(Title(0, fileName) +'.html'); await IOUtils[write](dir.path, fileContent) && showInStatusPanel("√ страница записана: " + fileName.slice(0, 60)); var d = await Downloads.createDownload({ source: "about:blank", target: FileUtils.File(dir.path)}); // Fake download (await Downloads.getList(Downloads.ALL)).add(d); d.refresh(d.succeeded = true); // кнопка Загрузки мигает } messageManager.addMessageListener(msgName, msgListener); addDestructor(() => messageManager.removeMessageListener(msgName, msgListener)); var svc = 'globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services'; var url = "data:;charset=utf8," + encodeURIComponent(`(${func})(${svc});`.replace("%MSG_NAME%", msgName)); (save = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); }, bright = (trg, forward, val) => { // wheel if (!val) var val = getIntPref(my_br) + (forward ? 5 : -5); val = val > 100 ? 100 : val < 20 ? 20 : val; prefs.setIntPref(my_br, val), trg.toggleAttribute("rst"), showInStatusPanel("☀ Яркость страниц: "+ val +"%"); }, help = (btn) => { // встроенная справка var help_ucf = ['chrome://user_chrome_files/content/help.html', 'http://forum.puppyrus.org/index.php?topic=22762']; var newURI = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry).convertChromeURL(Services.io.newURI(help_ucf[0])); // .spec = file:/// (newURI.QueryInterface(Ci.nsIFileURL).file.exists()) ? switchToTab(help_ucf[0]) : switchToTab(help_ucf[1]); }, GetSelection = (mM = gBrowser.selectedBrowser.messageManager) => { mM.addMessageListener('getSelect', function sel_listener(msg) { window.seltxt = msg.data; mM.removeMessageListener('getSelect', sel_listener, true); }); mM.loadFrameScript('data:,sendAsyncMessage("getSelect",content.document.getSelection().toString())',false); }, data = { "#downloads-button": { mousedownTarget: true, 4() { // Double Left Click - Обзор папки «Загрузки» c("DW Double Left Click"); Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError); }, 128() { saveSelectionToTxt();}, // СКМ Click (сохранить .txt) 256() { save();}, // ПКМ Click (Single HTML) 260(btn) { // Double ПКМ Click var pref = "permissions.default.image"; var one = prefs.getIntPref(pref) == 1; prefs.setIntPref(pref, one ? 2 : 1); btn.style.filter = one ? "hue-rotate(180deg) brightness(95%)" : ""; BrowserReload(); }, }, "#PanelUI-menu-button": { mousedownTarget: true, 1(btn) { help(btn);}, // Long Press 8() { gCustomizeMode.enter();}, //ЛКМ + Alt Персонализация 16(btn) { help(btn);}, // Shift + ЛКМ 4() { goQuitApplication();}, // Double Left Click 128() { windowState != STATE_MAXIMIZED ? maximize() : restore();}, // СКМ 136(btn) { BrowserFullScreen();}, // Alt + СКМ 132() { BrowserReloadSkipCache();}, // СКМ Double 256() { minimize();}, // ПКМ 260(btn) { btn.ownerGlobal.undoCloseTab();}, // ПКМ Double Right Click 264(btn) { switchToTab('about:performance');}, // Alt + ПКМ 280(btn) { // Shift + Alt + ПКМ var obj = ChromeUtils.import("resource://devtools/shared/Loader.jsm").require("devtools/client/menus").menuitems.find(menuitem => menuitem.id == "menu_devtools_remotedebugging"); (this[280] = target => obj.oncommand({target}))(btn); // запуск пункта меню, у которого нет HotKey }, }, "#pageAction-urlbar-_2495d258-41e7-4cd5-bc7d-ac15981f064e_": { // Reader View Button 128(btn) { // СКМ btn.ownerDocument.getElementById("key_responsiveDesignMode").doCommand(); // запуск пункта меню с HotKey if (gBrowser.selectedBrowser.browsingContext.inRDMPane) BrowserReload(); }, 2(trg, forward) { bright(trg, forward);}, // яркость по wheel ± 264(btn) { // Alt + ПКМ translate(gBrowser.selectedBrowser.messageManager, 1); }, 1(btn) { // Shift + ПКМ translate(gBrowser.selectedBrowser.messageManager); }, }, "#star-button-box": { 1() { // Left Long Press c("Star Left Long Press"); }, 2(trg, forward) { bright(trg, forward);}, // яркость по wheel ± // 128(btn) { // СКМ // switchToTab('about:config'); // }, 256() { // ПКМ window.undoCloseTab(); }, }, "#identity-box": { // Замок 2(trg, forward) { bright(trg, forward);}, // яркость по wheel ± 128(trg, forward) { bright(trg, forward, 100);}, // СКМ 256(btn) { // ПКМ gClipboard.write(gURLBar.value); url_color(), showInStatusPanel("в буфере: "+ gURLBar.value.slice(0, 80)); }, }, "#tracking-protection-icon-container": { // Защита 2(trg, forward) { bright(trg, forward);}, // яркость по wheel ± 128(trg, forward) { bright(trg, forward, 100);}, // СКМ }, "#identity-permission-box": { 2(trg, forward) { // wheel c("Identity Permisson Box Wheel " + (forward ? "forward" : "backward")); } }, "#identity-icon-box": { 16() { // Shift + Left Click c("Identity Icon Box Shift + Left Click"); }, }, }; // end Clicks, HotKeys ================================================== })("hookClicks-and-tooltips", ({io, focus}) => { // SingleHTML не сохраняет svg графику var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec;} catch {} }, getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r;} catch(e) {} } }, encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else img = obj; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }, toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }, mainWin = {}; focus.getFocusedElementForWindow(content, true, mainWin); mainWin = mainWin.value; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild), meta = doc.createElement('meta'), sheets = doc.styleSheets, title = doc.getElementsByTagName('title')[0]; meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; sendAsyncMessage("%MSG_NAME%", [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', selWin ? win.getSelection().toString().slice(0, 200) : undefined]); // выделенный текст }); // END hookClicks |
Dumby > 06-12-2021 18:57:00 |
egorsemenov06 пишет
/*JSON.parse*/ |
sachka > 08-12-2021 20:37:15 |
воможно ли с помощью скрипта https://forum.mozilla-russia.org/viewto … 54#p782454 открывать ссылки и страницы в tor browser? после последнего обновления тор открывается через скрипт, но соединения нет |
sandro79 > 14-12-2021 21:47:29 |
Dumby скрытый текст Выделить код Код:CustomizableUI.createWidget({ id: "Close-Tabs-button", label: "Закрыть другие вкладки", tooltiptext: "Закрыть другие вкладки", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { btn.render = this.render; btn._handleClick = this.close; btn.setAttribute("image", "chrome://devtools/skin/images/close.svg"); }, render() { delete this.render; this.render(); this.icon.style.setProperty("padding", "3px", "important"); }, close() { var gb = this.ownerGlobal.gBrowser; gb.removeAllTabsBut(gb.selectedTab); } }); |
Dumby > 14-12-2021 23:11:31 |
sandro79 пишет
Верно, эту строку. Как? Ну, обычно, скрытый текст Выделить код Код:... //gb.removeAllTabsBut(gb.selectedTab); var tab = gb.selectedTab; tab.multiselected ? gb.removeMultiSelectedTabs() : gb.removeTab(tab, {animate: true}); Но там учитывается вариант несколько-выделенных вкладок. Если нужно это игнорировать, то есть понимать вопрос строго буквально «чтоб он закрывал текущую вкладку» и никак иначе, то, в простейшем случае, можно заменить на gb.removeTab(gb.selectedTab, {animate: true}); |
sandro79 > 14-12-2021 23:42:17 |
Dumby пишет
С этим я пока не разобрался, хотя не помешало бы такую мелочь самому вычислить.
Да, как раз так и хотел, пункт "Выбрать все вкладки" не использую, и он у меня скрыт стилем. Скрипт собрал, всё работает скрытый текст Выделить код Код:CustomizableUI.createWidget({ id: "Close-Tab", label: "Закрыть вкладку", tooltiptext: "Закрыть вкладку", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { btn.render = this.render; btn._handleClick = this.close; btn.setAttribute("image", "chrome://devtools/skin/images/close.svg"); }, render() { delete this.render; this.render(); this.icon.style.setProperty("padding", "3px", "important"); }, close() { var gb = this.ownerGlobal.gBrowser; gb.removeTab(gb.selectedTab, {animate: true}); } }); |
voqabuhe > 15-12-2021 18:09:11 |
Dumby |
xrun1 > 15-12-2021 19:47:29 |
У меня кнопка "Закрыть вкладки..." такая, может кому пригодится. Кто-то помогал сделать, закреплённые вкладки, когда удаление слева или другие не удаляет. Я бы сам так не осилил. Работает, ucf у меня старый. custom_script.js Выделить код Код:// Этот скрипт можно использовать для создания кнопок с помощью CustomizableUI.createWidget (() => { var loadscript = name => { try { Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${name}`, globalThis, "UTF-8"); } catch(e) {} }; loadscript("my_buttons.js"); })(); my_buttons.js Выделить код Код:var {classes: Cc, interfaces: Ci, utils: Cu} = Components; var {console} = Cu.import("resource://gre/modules/Console.jsm", {}); try { CustomizableUI.createWidget({ id: "add-select-close-tabs-app", type: "custom", tooltiptext: [ "ЛКМ: Закрыть все вкладки", "Shift+ЛКМ: Закрыть другие вкладки", "Ctrl+ЛКМ: Закрыть слева", "Alt+ЛКМ: Закрыть справа", ].join("\n"), onBuild: function(document) { var toolbarbutton_0 = document.createXULElement("toolbarbutton"); toolbarbutton_0.id = this.id; toolbarbutton_0.tooltipText = this.tooltiptext; toolbarbutton_0.label = "Закрыть все вкладки"; toolbarbutton_0.setAttribute("context", false); toolbarbutton_0.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFLSURBVDhPYxg8wD5wy1y7gK1/7AO3/ncI2nq7uOnk3cq20//BuOP07b1Hnt09eurl/6OnXvwB0rOh2hAAphmGU0uOQDRD8ZrN94CaQQZADIFqQwBkzSAcnLTnVkLewWMgnFZy6Ep9z9kr3dMuHoNhqDYEQDeAEIZqQ4Dd937/JwVDtSEANkX4MFQbAmBThA9DtSEANkXIeM/t7/8vz1v9/1590//rE2f8/+pkIQ3VCgHYNMEwSPOLtOT/X1ws/n9xNvv/xRVIO5l9+OxsoQvVjt+AS/PXgDX/vXnt/4/q4v9/b1z9/y0tGmiY6S6odvwGgJwNshmk+f+fP/9/790JcQnQFVDt+A0A+RnsAqDNIM3/Prz//y0lEmTAZah2/OCrvZkM0LnvvqXFgG3+lgzUDAoHZ9N4qBLC4LOriQ7Qxt0gZwMNuQLRzMAAAAEG9BCOlZEaAAAAAElFTkSuQmCC"); toolbarbutton_0.addEventListener("click", function(event) { var win = event.target.ownerDocument.defaultView; if (event.button == 0) { if (event.shiftKey) { win.gBrowser.removeAllTabsBut(win.gBrowser.selectedTab); } else if (event.ctrlKey) { var ctab = win.gBrowser.selectedTab, tabs; if (ctab.multiselected) tabs = win.gBrowser.visibleTabs.filter(tab => !tab.multiselected && !tab.pinned); else tabs = win.gBrowser.visibleTabs.filter(tab => !tab.pinned); var index = tabs.indexOf(ctab); tabs = tabs.slice(0, (index != -1) ? index : tabs.length); tabs.forEach((tab) => { win.gBrowser.removeTab(tab); }); } else if (event.altKey) { var ctab = win.gBrowser.selectedTab, tabs; if (ctab.multiselected) tabs = win.gBrowser.visibleTabs.filter(tab => !tab.multiselected && !tab.pinned); else tabs = win.gBrowser.visibleTabs.filter(tab => !tab.pinned); var index = tabs.indexOf(ctab); tabs = tabs.slice((index != -1) ? (index + 1) : 0, tabs.length); tabs.forEach((tab) => { win.gBrowser.removeTab(tab); }); } else { win.gBrowser.selectAllTabs(); win.gBrowser.removeMultiSelectedTabs(); } } }, false); toolbarbutton_0.classList.add("toolbarbutton-1"); toolbarbutton_0.classList.add("chromeclass-toolbar-additional"); return toolbarbutton_0; } }); } catch(e) {} И ещё мне 2 кнопки сделал Vitaliy V. здесь. |
Dumby > 15-12-2021 19:48:55 |
voqabuhe пишет
Что значит лучше? скрытый текст Выделить код Код:var UcfStylesScripts = { /** ************************▼ Настройки ▼************************ */ ....... scriptsbackground: [ // В фоне [System Principal] ....... { path: "closeOtherTabs.js" }, ], /** ************************▲ Настройки ▲************************ */ };
Что значит не хочет работать? id'шник проверь, чтоб уникальный был. |
unter_officer > 15-12-2021 21:18:30 |
xrun1 пишет
Интересная кнопочка. Что-то типа такого: скрытый текст |
kokoss > 16-12-2021 00:05:28 |
xrun1 |
_zt > 16-12-2021 02:14:46 |
Dumby скрытый текст Выделить код Код:try { CustomizableUI.createWidget({ id: "additional-toolbars-button", type: "custom", label: "Доп. панели", tooltiptext: [ "ЛКМ: Переключить верт. панель", "ПКМ: Переключить доп. панель" ].join("\n"), localized: false, onBuild(doc) { var trbn = doc.createXULElement("toolbarbutton"); trbn.id = this.id; trbn.tooltipText = this.tooltiptext; trbn.label = this.label; trbn.className = "toolbarbutton-1 chromeclass-toolbar-additional"; trbn.setAttribute("context", false); trbn.setAttribute("image", "chrome://user_chrome_files/content/custom_styles/svg/layer-visible-off.svg"); trbn.addEventListener("click", function(e) { var pref = "browser.add.toolbars.visibility"; if (e.button == 0) { e.preventDefault(); e.stopPropagation(); CustomizableUI.setToolbarVisibility("ucf-additional-vertical-bar", doc.querySelector("#ucf-additional-vertical-bar").collapsed); } else if (e.button == 2) { e.preventDefault(); e.stopPropagation(); CustomizableUI.setToolbarVisibility("ucf-additional-top-bar", doc.querySelector("#ucf-additional-top-bar").collapsed); } }, false); return trbn; }, }); } catch(e) {} |
xrun1 > 16-12-2021 05:01:45 |
unter_officer скрытый текст Заменить в user_chrome.js кнопку с id: "add-view-bookmarks-sidebar-button". Ещё раз повторюсь, ucf у меня старый. Выделить код Код:try { CustomizableUI.createWidget({ id: "add-view-bookmarks-sidebar-button", type: "custom", label: "Закладки Библиотека История", tooltiptext: "ЛКМ: Показать / Скрыть Закладки\nСКМ: Открыть Библиотеки в табе\nПКМ: Показать / Скрыть Историю", localized: false, onBuild: function(doc) { var win = doc.defaultView; var trbn_0 = doc.createElementNS(ns_xul, "toolbarbutton"); trbn_0.id = "add-view-bookmarks-sidebar-button"; trbn_0.className = "toolbarbutton-1 chromeclass-toolbar-additional"; trbn_0.setAttribute("label", "Закладки Библиотека История"); trbn_0.setAttribute("context", "false"); trbn_0.setAttribute("tooltiptext", "ЛКМ: Показать / Скрыть Закладки\nСКМ: Открыть Библиотеки в табе\nПКМ: Показать / Скрыть Историю"); trbn_0.addEventListener("click", function(e) { if (e.button == 0) { if ("SidebarUI" in win) win.SidebarUI.toggle("viewBookmarksSidebar"); else if ("toggleSidebar" in win) win.toggleSidebar("viewBookmarksSidebar"); } else if (e.button == 1) { var url="chrome://browser/content/places/places.xhtml"; win.SidebarUI.hide(); /* Для CB, открывает "История" в окне "Библиотека" PlacesCommandHook.showPlacesOrganizer('History'); */ win.gBrowser.selectedTab = win.gBrowser.addTrustedTab(url); } else if (e.button == 2) { if ("SidebarUI" in win) win.SidebarUI.toggle("viewHistorySidebar"); else if ("toggleSidebar" in win) win.toggleSidebar("viewHistorySidebar"); } }); return trbn_0; } }); } catch(e) {} |
Dumby > 16-12-2021 12:20:30 |
_zt пишет
Не люблю я вопросы про «правильно», откуда мне знать что есть правильно. скрытый текст И, потом, не всегда понятен замысел, вот смотришь и думаешь, что здесь имелось в виду? Если судить по себе, то далеко не всё пишется с каким-то смыслом, иногда просто от балды, первое что в голову придёт. Вот, например, в коде определяется переменная pref, но нигде не используется. Или tooltiptext массивом. Когда там целая батарея подсказочных строк, то имеет смысл. Выделить код Код:(async () => CustomizableUI.createWidget({ label: "Доп. панели", tooltiptext: "ЛКМ: Переключить верт. панель\nПКМ: Переключить доп. панель", id: "additional-toolbars-button", localized: false, onCreated(btn) { btn.toggleAttribute("context"); btn.setAttribute("image", "chrome://user_chrome_files/content/custom_styles/svg/layer-visible-off.svg"); }, 0: "ucf-additional-vertical-bar", 2: "ucf-additional-top-bar", onClick(e) { var id = this[e.button]; id && CustomizableUI.setToolbarVisibility(id, e.view.document.getElementById(id).collapsed); } }))(); |
_zt > 16-12-2021 15:06:02 |
Dumby |
unter_officer > 16-12-2021 15:31:27 |
xrun1 пишет
Dumby |
voqabuhe > 16-12-2021 16:40:01 |
Dumby пишет
Типа про это как раз и спрашивал, в какой из них лучше, в чём разница?
В смысле, что она ваще не появлялась.
Ага, это и было причиной, видно с чем-то совпало, после изменения id, кнопка появилась и работает. Спасибо. |
kokoss > 16-12-2021 17:04:23 |
xrun1 пишет
И как это работает? А то у меня в 95 не работает! |
Dumby > 16-12-2021 20:53:59 |
unter_officer пишет
Обязательно в кнопку? скрытый текст Выделить код Код:(async anim => { var re = /^(?:Digit|Numpad)(1|2|3|4)$/; var funcs = { 1: () => { gBrowser.selectAllTabs(); gBrowser.removeMultiSelectedTabs(); }, 2: t => gBrowser.removeAllTabsBut(t), 3: t => gBrowser.removeTabsToTheStartFrom(t, anim), 4: t => gBrowser.removeTabsToTheEndFrom(t, anim), }; var args = ["keydown", e => { if ( e.ctrlKey || e.altKey || !re.test(e.code) || e.repeat || docShell.isCommandEnabled("cmd_insertText") ) return; var num = RegExp.$1; if (e.shiftKey || e.code.startsWith("N") && e.getModifierState("NumLock") && e.key != num) e.preventDefault(), funcs[num](gBrowser.selectedTab); }, true]; addEventListener(...args); var id = Symbol(), ucf = ucf_custom_script_win; ucf.unloadlisteners.push(id); ucf[id] = {destructor: () => removeEventListener(...args)}; })({animate: true}); kokoss пишет
Там ns_xul не определён, вот и не работает. |
unter_officer > 16-12-2021 22:33:09 |
Dumby пишет
Dumby, большое спасибо! P.S. Вопрос конечно же был не о Firefox 52. |
kokoss > 16-12-2021 23:31:48 |
Dumby пишет
Иконку то я прикрутил, только не мог понять почему у него работает, а у меня нет, теперь понятно. Спасибо за подсказку! |
xrun1 > 17-12-2021 05:23:26 |
kokoss _zt пишет
Не, это мой код, он там двумя постами выше. Кнопку делал, когда только-только Vitaliy V. сделал ucf. Делал по аналогии c кнопками, которые уже были в ucf. Поэтому там и type: "custom". А e.preventDefault(); e.stopPropagation(); у меня затесались по старой памяти от CB. |
kokoss > 17-12-2021 14:17:22 |
Может кому пригодится: кнопка для custom_script.js Выделить код Код:try { CustomizableUI.createWidget({ id: "add-personalization-button-app", type: "custom", tooltiptext: [ "ЛКМ: Персонализация", "СКМ: about:about", "ПКМ: about:support" ].join("\n"), onBuild: function(document) { var toolbarbutton_0 = document.createXULElement("toolbarbutton"); toolbarbutton_0.id = this.id; toolbarbutton_0.tooltipText = this.tooltiptext; toolbarbutton_0.label = "Персонализация about:about about:support"; toolbarbutton_0.image = "chrome://browser/content/robot.ico"; toolbarbutton_0.setAttribute("context", false); toolbarbutton_0.addEventListener("click", function(event) { var win = event.target.ownerDocument.defaultView; win.SidebarUI.hide(); if (event.button == 0) { win.gCustomizeMode.enter(); } if (event.button == 1) { win.gBrowser.selectedTab = win.gBrowser.addTrustedTab('about:about'); } if (event.button == 2) { win.gBrowser.selectedTab = win.gBrowser.addTrustedTab('about:support'); } }, false); toolbarbutton_0.classList.add("toolbarbutton-1"); toolbarbutton_0.classList.add("chromeclass-toolbar-additional"); return toolbarbutton_0; } }); } catch(e) {} в 95 вроде работает, немного изменил... эту кнопку |
unter_officer > 17-12-2021 17:40:44 |
Dumby Что-то вроде нескольких кнопок в одной. для FF 91. |
sandro79 > 17-12-2021 21:52:07 |
Dumby скрытый текст Tab Mix Plus поставил, посмотрел, ну три небольших скрипта и два дополнения она мне компенсировала. Но в обычном нужен ещё скрипт для работы дополнения и bootstrapLoader.xpi по-любому ставить. В общем отказался, в только пока оставил |
unter_officer > 17-12-2021 22:58:01 |
sandro79 пишет
Возможно я ошибаюсь, но вроде это можно реализовать стилем. Что-то типа такого: |
sandro79 > 17-12-2021 23:17:21 |
unter_officer пишет
Нет, Вы не ошибаетесь, действительно можно стилем. Спасибо за подсказку скрытый текст |
Dumby > 18-12-2021 00:00:55 |
unter_officer пишет
Ещё как сложно. Вопрос слишком общего характера. скрытый текст Выделить код Код:(async () => CustomizableUI.createWidget({ label: "Some Label", tooltiptext: "Some Tooltip Text", id: "_some_unique_identifier_", localized: false, onCreated(btn) { btn.setAttribute("type", "menu"); btn.setAttribute("image", "chrome://global/skin/narrate/headphone-active.svg"); var doc = btn.ownerDocument; var popup = doc.createXULElement("menupopup"); popup.creator = this; popup.toggleAttribute("context"); popup.setAttribute("oncommand", "creator.cmd(event);"); popup.setAttribute("oncontextmenu", "hidePopup(); creator.cmd(event);"); for(var item of this.data) { if (!item) { popup.append(doc.createXULElement("menuseparator")); continue; } var menuitem = popup.appendChild(doc.createXULElement("menuitem")); menuitem.linkedItem = item; menuitem.setAttribute("label", item.lab || ""); item.ttt && menuitem.setAttribute("tooltiptext", item.ttt); if (item.img) menuitem.className = "menuitem-iconic", menuitem.setAttribute("image", item.img); } btn.prepend(popup); }, cmd(e) { var it = e.target.linkedItem; it && this[it.fnc](e, it.val); }, data: [ { lab: "Пункт 1", ttt: "Бла", img: "chrome://devtools/skin/images/fox-smiling.svg", fnc: "sayBla", }, { lab: "Пункт 2", ttt: "Трижды Бла", img: "chrome://devtools/skin/images/fox-smiling.svg", fnc: "sayBla", val: 3, }, null, // <= separator { lab: "Пункт 3", fnc: "alertLabel", }, { lab: "Пункт 4", fnc: "viewImgSource", img: "chrome://browser/skin/protections/resolved-breach.svg", }, null, { lab: "Пункт 5", ttt: "Default", img: "chrome://browser/skin/preferences/face-sad.svg", }, ], sayBla(e, val = 1) { Services.prompt.alert(null, null, "Бла ".repeat(val)); }, alertLabel(e) { e.view.alert(e.target.label); }, viewImgSource(e) { var gb = e.view.gBrowser; gb.selectedTab = gb.addTrustedTab( "view-source:" + e.target.image, {index: gb.selectedTab._tPos + 1} ); }, undefined(e) { Services.prompt.alert(null, "Method missing!", "event.button = " + e.button); } }))(); |
unter_officer > 18-12-2021 00:38:30 |
Dumby пишет
На многих кнопках вешаются разные действия на клик мыши с модификаторами (Shift+ЛКМ, Ctrl+ПКМ и тому подобное). Мне проще сделать одну кнопку и добавлять в неё по мере необходимости нужные действия. P.S. Dumby, большое спасибо за кнопку. |
xrun1 > 18-12-2021 03:11:15 |
Случайно поднял глаза и заметил. В кнопке для адресной строки "Копировать ссылку" в 95 сменился значок. Теперь такой iconURL: "chrome://global/skin/icons/link.svg" |
xrun1 > 19-12-2021 18:25:16 |
Это глюк гугла или что-то в скрипте? Автоматический перевод страницы Ru --> En не переводит. En --> Ru работает. №8287. скрытый текст |
Пострел > 20-12-2021 13:04:38 |
xrun1, здравствуйте. скрытый текст Выделить код Код:var url = "http://translate.google.com/translate?u="+encodeURIComponent(urlt)+"&hl="+lng+"&langpair="+dir+"&tbb=1"; заменить на: var url = "https://translate.google.com/translate?sl=auto&tl=ru&u="+encodeURIComponent(urlt)+"&hl="+lng+"&langpair="+dir+"&tbb=1"; |
xrun1 > 20-12-2021 22:03:24 |
Пострел, приветствую! |
xrun1 > 21-12-2021 06:35:20 |
Хотел на халяву проскочить. Не получилось, пришлось самому подумать. скрытый текст Выделить код Код:var url = "http://translate.google.com/translate?u="+encodeURIComponent(urlt)+"&hl="+lng+"&langpair="+dir+"&tbb=1"; заменить на: var url = "http://translate.google.com/translate?u=" + encodeURIComponent(urlt) + '&tl=' + l[1] + "&hl=" + lng + "&langpair=" + dir + "&tbb=1"; |
Пострел > 21-12-2021 13:21:08 |
xrun1, |
unter_officer > 28-12-2021 19:01:48 |
Dumby Пример Выделить код Код:try { (this.contextmenubookmark = { init(that) { var contextMenu = this.contextMenu = document.querySelector("#placesContext"); if (!contextMenu) return; contextMenu.addEventListener("popupshowing", this); that.unloadlisteners.push("contextmenubookmark"); var style = "data:text/css;charset=utf-8," + encodeURIComponent(` /* Здесь какой-то стиль ..... */ `); try { windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); } catch (e) {} }, destructor() { this.contextMenu.removeEventListener("popupshowing", this); }, handleEvent(e) { var array = [ ["ucf_ID_1", "label_1", "func_1", "data:image/png;base64,....."], ["ucf_ID_2", "label_2", "func_2", "data:image/png;base64,....."], // ["separator"], ["ucf_ID_3", "label_3", "func_3", "data:image/png;base64,....."], // ["separator"], ["ucf_ID_4", "label_4", "func_4", "data:image/png;base64,....."], ["ucf_ID_5", "label_5", "func_5", "data:image/png;base64,....."], ["ucf_ID_6", "label_6", "func_6", "data:image/png;base64,....."], // ["separator"], ["ucf_ID_7", "label_7", "func_7", "data:image/png;base64,....."], // ["separator"], ["ucf_ID_8", "label_8", "func_8", "data:image/png;base64,....."], ]; array.forEach(m=> { // if (m[0] == "separator") { document.createXULElement("menuseparator"); return }; var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("id", m[0]); menuitem.setAttribute("label", m[1]); menuitem.className = "menuitem-iconic"; menuitem.setAttribute("image", m[3]); menuitem.setAttribute("oncommand", m[2]); (this.contextMenu.lastElementChild).after(menuitem); this.handleEvent = () => menuitem.hidden; }); }, }).init(this); } catch(ex) { Cu.reportError(ex); } |
Dumby > 28-12-2021 19:57:17 |
unter_officer пишет
Чтобы вставлять "menuseparator" его нужно... «вставлять», скрытый текст Выделить код Код:… // if (m[0] == "separator") { document.createXULElement("menuseparator"); return }; if (m[0] == "separator") { e.target.append(document.createXULElement("menuseparator")); return; }; |
unter_officer > 28-12-2021 20:33:44 |
Dumby пишет
Спасибо за помощь. |
sandro79 > 05-01-2022 12:23:45 |
Dumby |
Dumby > 05-01-2022 21:02:41 |
sandro79 пишет
Что-то у меня там нет ChromeUtils в сандбоксе, наверно версия UCF совсем старая. скрытый текст Выделить код Код:(async id => { label = "Дополнения", tooltiptext = "ЛКМ: Меню дополнений\nСКМ: Отладка дополнений\nПКМ: Открыть менеджер дополнений", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 24,4.5 18,12 3,23.7 12,32.7 3.9,44.1 7.8,48 H 45 C 46.7,48 48,46.7 48,45 V 26.1 L 34.8,12.9 31.8,12.3 Z'/><path style='fill:white;' d='M 19.88,3 C 16.93,3 14.55,4.662 14.55,6.701 14.63,7.474 15.11,8.438 15.37,8.762 16.59,10.41 16.59,11.44 16.29,12.06 H 6.299 C 4.476,12.06 3,13.53 3,15.35 V 23.68 C 3.625,24 4.65,24 6.299,22.77 6.625,22.52 7.587,22.02 8.363,21.94 10.4,21.94 12.06,24.35 12.06,27.29 12.06,30.24 10.4,32.65 8.363,32.65 7.725,32.63 6.774,32.07 6.299,31.82 4.65,30.59 3.625,30.59 3,30.91 V 41.71 C 3,43.53 4.476,45 6.299,45 H 19.58 C 19.88,44.38 19.88,43.35 18.65,41.71 18.4,41.38 17.91,40.42 17.82,39.65 17.82,37.6 20.23,35.94 23.18,35.94 26.14,35.94 28.55,37.6 28.55,39.65 28.53,40.28 27.97,41.23 27.71,41.71 26.47,43.35 26.47,44.38 26.79,45 H 32.65 C 34.47,45 35.96,43.53 35.96,41.71 V 32.55 C 36.56,32.23 37.59,32.23 39.23,33.47 39.72,33.73 40.68,34.29 41.29,34.29 43.35,34.29 45,31.91 45,28.94 45,25.99 43.35,23.59 41.29,23.59 40.54,23.67 39.58,24.17 39.23,24.41 37.59,25.65 36.56,25.65 35.96,25.33 V 15.35 C 35.96,13.53 34.47,12.06 32.65,12.06 H 23.49 C 23.19,11.44 23.19,10.41 24.41,8.762 24.66,8.287 25.22,7.337 25.23,6.713 25.23,4.662 22.85,3 19.88,3' /></g></svg>", checked = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='M 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([ ]); var imp = Cu.getGlobalForObject(Cu).ChromeUtils.import; var {AddonManager} = imp("resource://gre/modules/AddonManager.jsm"); var {GlobalManager} = imp("resource://gre/modules/ExtensionParent.jsm").ExtensionParent; var extensionOptionsMenu = { get alertsService() { delete this.alertsService; return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); }, get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, get exceptions_type_listarr() { delete this.exceptions_type_listarr; var arr = ["extension", "theme", "locale", "dictionary"]; if (!exceptions_type_listset.size) return this.exceptions_type_listarr = arr; return this.exceptions_type_listarr = arr.filter(type => !exceptions_type_listset.has(type)); }, async populateMenu(e) { var popup = e.target, doc = e.view.document; var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr); var addonsMap = new WeakMap(), setAttributesMenu = (mi, addon, extension) => { var permissions, uuid, props = { label: `${addon.name}${show_version ? ` ${addon.version}` : ""}`, class: "menuitem-iconic", tooltiptext: `${ show_description && addon.description ? addon.description + "\n" : "" }ID: ${ addon.id }${ addon.isActive && (uuid = extension && extension.uuid) ? `\nUUID: ${uuid}` : "" }${ user_permissions && ( permissions = addon.userPermissions && addon.userPermissions.permissions || "" ).length ? `\nРазрешения: ${permissions.join(", ")}` : "" }\n${ addon.optionsURL ? "\nЛКМ: Настройки" : "" }\nCtrl+ЛКМ: Копировать ID${ uuid ? "\nShift+ЛКМ: Копировать UUID" : "" }${ addon.creator && addon.creator.url ? "\nCtrl+Shift+ЛКМ: Автор" : "" }${ addon.homepageURL ? "\nСКМ: Домашняя страница" : "" }${ !addon.isBuiltin ? "\nCtrl+СКМ: Просмотр источника" : "" }\nShift+СКМ: Просмотр источника во вкладке\nПКМ: Включить/Отключить${ !addon.isSystem && !addon.isBuiltin ? "\nCtrl+ПКМ: Удалить" : "" }` }; for (let p in props) mi.setAttribute(p, props[p]); if (addon.iconURL) mi.setAttribute("image", addon.iconURL); var cls = mi.classList; addon.isActive ? cls.remove("ucf-disabled") : cls.add("ucf-disabled"); addon.optionsURL ? cls.remove("ucf-notoptions") : cls.add("ucf-notoptions"); addon.isSystem ? cls.add("ucf-system") : cls.remove("ucf-system"); cls.add(`ucf-type-${addon.type}`); }; addons.filter(a => !(a.iconURL || "").startsWith("resource://search-extensions/")).sort((a, b) => { var ka = `${(enabled_first ? a.isActive ? "0" : "1" : "")}${a.type || ""}${a.name.toLowerCase()}`; var kb = `${(enabled_first ? b.isActive ? "0" : "1" : "")}${b.type || ""}${b.name.toLowerCase()}`; return (ka < kb) ? -1 : 1; }).forEach(addon => { if (!exceptions_listset.has(addon.id) && (!addon.hidden || show_hidden) && (!addon.userDisabled || show_disabled)) { let extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.append(mi); addonsMap.set(addon, mi); } }); var click = e => { 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 && 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(`${img}`, "ID в буфере обмена!", addon.id, false); }, 100); } else if (e.shiftKey) { if (extension && extension.uuid) { this.clipboardHelp.copyString(extension.uuid); win.setTimeout(() => { this.alertsService.showAlertNotification(`${img}`, "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: win.BrowserOpenAddonsMgr(`addons://detail/${encodeURIComponent(addon.id)}/preferences`); 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); }, }; CustomizableUI.createWidget({ type: "custom", id, label, tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild(doc) { var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView, props = { context: "", type: "menu", id, label, tooltiptext, 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) e.view.BrowserOpenAddonsMgr("addons://list/extension"); }); 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}, #${id}-popup menuitem { list-style-image: url("${img}") !important; } #${id}-popup menuitem::after { display: -moz-box !important; content: "" !important; height: 16px !important; width: 16px !important; padding: 0 !important; border: 1px solid rgb(0, 116, 232) !important; border-radius: 0 !important; background-repeat: no-repeat !important; background-position: center !important; background-size: 16px !important; background-color: rgb(0, 116, 232) !important; background-image: url("${checked}") !important; opacity: 1 !important; } #${id}-popup menuitem.ucf-disabled::after { border-color: currentColor !important; background-color: transparent !important; background-image: none !important; opacity: .6 !important; } #${id}-popup menuitem.ucf-disabled > label, #${id}-popup menuitem.ucf-notoptions > label { opacity: .6 !important; } #${id}-popup menuitem.ucf-system > label { text-decoration: underline !important; text-decoration-style: dotted !important; } #${id}-popup menuitem > label { margin-inline-end: 0 !important; } #${id}-popup menuitem > .menu-accel-container { display: -moz-box !important; padding: 4px !important; margin: 0 !important; opacity: 1 !important; } #${id}-popup menuitem > .menu-accel-container .menu-iconic-accel { display: -moz-box !important; margin: 0 !important; height: 8px !important; width: 8px !important; border-radius: 4px !important; background-color: transparent !important; opacity: 1 !important; font-size: 0 !important; } #${id}-popup menuitem.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel { background-color: rgb(227, 27, 93) !important; } #${id}-popup menuitem.ucf-type-locale > .menu-accel-container .menu-iconic-accel { background-color: rgb(48, 172, 55) !important; } #${id}-popup menuitem.ucf-type-theme > .menu-accel-container .menu-iconic-accel { background-color: rgb(219, 106, 0) !important; } `); try { win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} return btn; }, }); })("ucf-aom-button");
яд.иск . Это ты залил для всех, кроме меня.
Похоже, в 69 у JSWindowActorChild нет callback'а actorCreated(). Ладно, попробуем. Итак, в первом скрипте меняем первую строку на Остальные двое: скрытый текст Выделить код Код:const ICONS = { // "домен, или адрес для about|chrome|resource": "иконка", "yandex.ru": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><rect rx='2' ry='2' width='16' height='16' style='fill:rgb(231, 43, 90);'/><path d='M 8.56,2 C 6.31,2 4.49,3.5 4.49,5.99 4.49,7.49 5.31,8.48 6.97,9.57 L 4,13.5 V 14 H 5.76 L 8.53,9.57 H 9.47 V 14 H 11 V 2 Z M 9.47,8.48 H 8.67 C 7.36,8.48 6.05,7.98 6.05,5.99 6.05,4 7.26,3 8.47,3 H 9.47 Z' style='fill:white;'/></g></svg>", "nnmclub.to": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><path d='M 0.887,0 C 0.54,0.14 0.289,0.279 0.135,0.711 0.051,0.851 0.015,0.991 0,1.27 -0.009,1.71 0.061,2.16 0.325,3.05 0.564,3.88 0.612,4.12 0.612,4.37 0.612,4.48 0.612,4.56 0.588,4.67 0.457,5.43 0.457,6.07 0.588,6.56 0.672,6.87 0.779,7.09 0.947,7.28 1.21,7.57 1.49,7.73 2.05,7.87 L 2.27,7.91 2.11,7.96 C 1.87,8.01 1.71,8.08 1.55,8.19 1.33,8.31 1.22,8.41 1.09,8.59 0.947,8.65 0.887,8.83 0.839,8.99 0.803,9.17 0.792,9.41 0.827,9.65 0.851,9.93 0.851,9.93 0.827,10 0.827,10.1 0.767,10.3 0.708,10.5 0.588,10.9 0.564,11.1 0.564,11.2 0.564,11.5 0.612,11.6 0.875,11.8 1.15,12.2 1.18,12.3 1.15,12.6 1.1,13.2 1.18,13.6 1.39,13.7 1.49,13.7 1.6,13.9 1.75,14 1.93,14 2.05,14.1 2.28,14.4 2.48,14.5 2.55,14.5 2.64,14.5 2.73,14.7 2.73,14.7 2.87,14.7 3.04,14.7 3.04,14.7 3.47,14.5 4.03,14 4.19,13.9 4.44,13.9 4.55,13.7 4.6,13.7 4.68,13.7 4.88,13.6 5.11,13 5.35,11.9 5.39,11.8 5.43,11.6 5.47,11.5 5.65,10.9 5.89,10.4 6.12,10 6.24,9.83 6.48,9.59 6.49,9.59 6.49,9.59 6.49,9.75 6.48,10.1 6.44,10.3 6.43,10.5 6.28,11.1 6.12,11.5 6.08,11.7 6.05,12 6.03,12.4 6.11,12.6 6.21,12.9 6.32,13 6.43,13 6.57,13 6.71,12.9 6.81,12.6 6.91,12.4 7.07,12 7.11,11.7 7.11,11 7.11,10.7 7.13,10.4 7.27,10 7.35,9.75 7.32,9.75 7.37,9.83 7.52,10.1 7.64,10.7 7.69,11.3 7.72,11.6 7.72,12.2 7.69,12.4 7.64,13 7.61,13.6 7.68,14 7.72,14.4 7.76,14.5 8.01,14.5 8.15,14.7 8.31,14.8 8.67,15.5 8.92,15.9 9.03,15.9 9.11,16 9.17,16 9.17,16 9.33,16 9.52,16 9.52,16 9.77,15.9 10.1,15.7 10.1,15.7 10.4,15.7 10.7,15.7 10.7,15.7 10.7,15.7 11,15.6 11.1,15.5 11.4,14.9 11.4,14.9 11.4,14.8 11.5,14.7 11.5,14.5 11.6,14.4 11.7,14.1 12.2,13.9 12.2,13.9 12.2,13.7 12.4,13.6 12.4,13.6 12.4,13 12.4,12.6 12.5,12.4 12.5,12.3 12.5,12.3 12.5,12.2 12.7,12 12.8,11.7 12.8,11.6 12.8,11.5 12.8,11.2 12.8,11.1 12.8,11.1 12.7,10.7 12.4,10.3 12,9.93 11.9,9.83 11.9,9.83 11.9,9.83 12.2,9.93 12.7,9.93 12.9,9.93 13.7,9.75 14,9.08 14.1,7.84 14.1,7.76 14.3,7.59 14.3,7.49 14.3,7.27 14.3,7.19 14.5,7.01 14.5,6.83 14.8,6.6 15.1,6.19 15.7,5.24 15.9,4.85 16,4.41 16,4.31 16,4.25 16,4.03 16,3.84 16,3.76 16,3.69 15.7,3.03 15.2,2.68 14.3,2.75 13.7,2.76 13,2.97 12.2,3.32 12,3.4 11.6,3.63 11.4,3.81 10.2,4.49 9.11,5.55 8.08,6.85 7.95,7 7.85,7.11 7.85,7.11 7.85,7.11 7.84,7.05 7.84,7.04 7.76,6.93 7.72,6.87 7.61,6.81 L 7.53,6.73 7.64,6.47 C 7.92,5.92 8.13,5.51 8.31,5.23 8.35,5.12 8.51,4.91 8.76,4.63 9.43,3.73 9.68,3.47 9.77,3.35 10,3.21 10,3.2 10,3.15 10.1,3.05 10,2.92 10,2.87 9.95,2.87 9.95,2.91 9.84,2.97 9.84,3.11 9.52,3.44 9.11,4.03 8.92,4.19 8.76,4.37 8.76,4.45 8.35,4.95 7.95,5.69 7.61,6.47 7.53,6.6 7.49,6.73 7.47,6.73 7.47,6.73 7.43,6.71 7.37,6.71 L 7.28,6.68 V 6.59 C 7.2,5.69 7.08,5.08 6.91,4.49 6.83,4.16 6.8,4 6.59,3.44 6.33,2.75 6.2,2.32 6.2,2.21 6.17,2.09 6.05,2.08 6,2.2 5.97,2.31 5.99,2.39 6.11,2.55 6.21,2.75 6.32,2.97 6.73,4.15 7,4.96 7.07,5.13 7.2,6.29 7.23,6.68 7.23,6.68 7.2,6.68 7.13,6.68 6.97,6.75 6.89,6.83 6.83,6.87 6.81,6.89 6.81,6.89 6.81,6.89 6.75,6.73 6.68,6.56 6.53,6.07 6.4,5.77 6.2,5.27 5.36,3.43 4.39,2.01 3.36,1.13 2.64,0.571 2.01,0.14 1.49,0 1.32,0 1.02,0 0.887,0 Z' style='fill:rgb(0, 140, 255);stroke:black;stroke-width:0.6;stroke-linejoin:round;stroke-linecap:round;'/></g></svg>", "about:config": "resource://normandy/skin/shared/heartbeat-icon.svg", "about:user-chrome-files": "chrome://browser/skin/accessibility.svg", }; var EXPORTED_SYMBOLS = ["LinkWinActorChild"]; ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); const LINK_SELECTOR = "link[href]:-moz-any([rel~='icon'],[rel~='apple-touch-icon'],[rel~='apple-touch-icon-precomposed'],[rel~='fluid-icon'],[rel~='mask-icon'])"; var noop = () => {}; var re = /^(?:about|chrome|resource)$/; var idn = Cc["@mozilla.org/network/idn-service;1"].getService(Ci.nsIIDNService); var once = function() { delete this.handleEvent; var doc = this.document; var docURI = doc.documentURIObject, host; if (re.test(docURI.scheme)) host = docURI.specIgnoringRef; else try { host = idn.convertToDisplayIDN(Services.eTLD.getBaseDomain(docURI), {}); } catch { try {host = docURI.displayHost;} catch {host = docURI.specIgnoringRef;} } var icon = ICONS[host]; if (!icon) return this.handleEvent = noop; this._icon = icon; this.onHeadParsed(doc.head || doc.documentElement); } class LinkWinActorChild extends JSWindowActorChild { handleEvent = once; onHeadParsed(target) { for (let link of target.querySelectorAll(LINK_SELECTOR)) link.remove(); var link = this.document.createElementNS("http://www.w3.org/1999/xhtml", "link"); link.setAttribute("rel", "icon"); link.setAttribute("sizes", "any"); link.setAttribute("href", this._icon); target.append(link); } onLinkEvent(link) { if (!link.matches(LINK_SELECTOR) || link.href == this._icon) return; link.href = this._icon; link.setAttribute("rel", "icon"); link.setAttribute("sizes", "any"); if (link.hasAttribute("type")) link.removeAttribute("type"); } handleEvent(e) { switch (e.type) { case "DOMLinkAdded": case "DOMLinkChanged": this.onLinkEvent(e.target); break; case "pageshow": this.onHeadParsed(e.target.head || e.target.documentElement); break; } } } скрытый текст Выделить код Код:const ICONS = { // "поддомен + домен, или адрес для about|chrome|resource": "иконка" "yandex.ru": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><rect rx='2' ry='2' width='16' height='16' style='fill:rgb(231, 43, 90);'/><path d='M 8.56,2 C 6.31,2 4.49,3.5 4.49,5.99 4.49,7.49 5.31,8.48 6.97,9.57 L 4,13.5 V 14 H 5.76 L 8.53,9.57 H 9.47 V 14 H 11 V 2 Z M 9.47,8.48 H 8.67 C 7.36,8.48 6.05,7.98 6.05,5.99 6.05,4 7.26,3 8.47,3 H 9.47 Z' style='fill:white;'/></g></svg>", get "passport.yandex.ru"() { return this["yandex.ru"]; }, "nnmclub.to": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><path d='M 0.887,0 C 0.54,0.14 0.289,0.279 0.135,0.711 0.051,0.851 0.015,0.991 0,1.27 -0.009,1.71 0.061,2.16 0.325,3.05 0.564,3.88 0.612,4.12 0.612,4.37 0.612,4.48 0.612,4.56 0.588,4.67 0.457,5.43 0.457,6.07 0.588,6.56 0.672,6.87 0.779,7.09 0.947,7.28 1.21,7.57 1.49,7.73 2.05,7.87 L 2.27,7.91 2.11,7.96 C 1.87,8.01 1.71,8.08 1.55,8.19 1.33,8.31 1.22,8.41 1.09,8.59 0.947,8.65 0.887,8.83 0.839,8.99 0.803,9.17 0.792,9.41 0.827,9.65 0.851,9.93 0.851,9.93 0.827,10 0.827,10.1 0.767,10.3 0.708,10.5 0.588,10.9 0.564,11.1 0.564,11.2 0.564,11.5 0.612,11.6 0.875,11.8 1.15,12.2 1.18,12.3 1.15,12.6 1.1,13.2 1.18,13.6 1.39,13.7 1.49,13.7 1.6,13.9 1.75,14 1.93,14 2.05,14.1 2.28,14.4 2.48,14.5 2.55,14.5 2.64,14.5 2.73,14.7 2.73,14.7 2.87,14.7 3.04,14.7 3.04,14.7 3.47,14.5 4.03,14 4.19,13.9 4.44,13.9 4.55,13.7 4.6,13.7 4.68,13.7 4.88,13.6 5.11,13 5.35,11.9 5.39,11.8 5.43,11.6 5.47,11.5 5.65,10.9 5.89,10.4 6.12,10 6.24,9.83 6.48,9.59 6.49,9.59 6.49,9.59 6.49,9.75 6.48,10.1 6.44,10.3 6.43,10.5 6.28,11.1 6.12,11.5 6.08,11.7 6.05,12 6.03,12.4 6.11,12.6 6.21,12.9 6.32,13 6.43,13 6.57,13 6.71,12.9 6.81,12.6 6.91,12.4 7.07,12 7.11,11.7 7.11,11 7.11,10.7 7.13,10.4 7.27,10 7.35,9.75 7.32,9.75 7.37,9.83 7.52,10.1 7.64,10.7 7.69,11.3 7.72,11.6 7.72,12.2 7.69,12.4 7.64,13 7.61,13.6 7.68,14 7.72,14.4 7.76,14.5 8.01,14.5 8.15,14.7 8.31,14.8 8.67,15.5 8.92,15.9 9.03,15.9 9.11,16 9.17,16 9.17,16 9.33,16 9.52,16 9.52,16 9.77,15.9 10.1,15.7 10.1,15.7 10.4,15.7 10.7,15.7 10.7,15.7 10.7,15.7 11,15.6 11.1,15.5 11.4,14.9 11.4,14.9 11.4,14.8 11.5,14.7 11.5,14.5 11.6,14.4 11.7,14.1 12.2,13.9 12.2,13.9 12.2,13.7 12.4,13.6 12.4,13.6 12.4,13 12.4,12.6 12.5,12.4 12.5,12.3 12.5,12.3 12.5,12.2 12.7,12 12.8,11.7 12.8,11.6 12.8,11.5 12.8,11.2 12.8,11.1 12.8,11.1 12.7,10.7 12.4,10.3 12,9.93 11.9,9.83 11.9,9.83 11.9,9.83 12.2,9.93 12.7,9.93 12.9,9.93 13.7,9.75 14,9.08 14.1,7.84 14.1,7.76 14.3,7.59 14.3,7.49 14.3,7.27 14.3,7.19 14.5,7.01 14.5,6.83 14.8,6.6 15.1,6.19 15.7,5.24 15.9,4.85 16,4.41 16,4.31 16,4.25 16,4.03 16,3.84 16,3.76 16,3.69 15.7,3.03 15.2,2.68 14.3,2.75 13.7,2.76 13,2.97 12.2,3.32 12,3.4 11.6,3.63 11.4,3.81 10.2,4.49 9.11,5.55 8.08,6.85 7.95,7 7.85,7.11 7.85,7.11 7.85,7.11 7.84,7.05 7.84,7.04 7.76,6.93 7.72,6.87 7.61,6.81 L 7.53,6.73 7.64,6.47 C 7.92,5.92 8.13,5.51 8.31,5.23 8.35,5.12 8.51,4.91 8.76,4.63 9.43,3.73 9.68,3.47 9.77,3.35 10,3.21 10,3.2 10,3.15 10.1,3.05 10,2.92 10,2.87 9.95,2.87 9.95,2.91 9.84,2.97 9.84,3.11 9.52,3.44 9.11,4.03 8.92,4.19 8.76,4.37 8.76,4.45 8.35,4.95 7.95,5.69 7.61,6.47 7.53,6.6 7.49,6.73 7.47,6.73 7.47,6.73 7.43,6.71 7.37,6.71 L 7.28,6.68 V 6.59 C 7.2,5.69 7.08,5.08 6.91,4.49 6.83,4.16 6.8,4 6.59,3.44 6.33,2.75 6.2,2.32 6.2,2.21 6.17,2.09 6.05,2.08 6,2.2 5.97,2.31 5.99,2.39 6.11,2.55 6.21,2.75 6.32,2.97 6.73,4.15 7,4.96 7.07,5.13 7.2,6.29 7.23,6.68 7.23,6.68 7.2,6.68 7.13,6.68 6.97,6.75 6.89,6.83 6.83,6.87 6.81,6.89 6.81,6.89 6.81,6.89 6.75,6.73 6.68,6.56 6.53,6.07 6.4,5.77 6.2,5.27 5.36,3.43 4.39,2.01 3.36,1.13 2.64,0.571 2.01,0.14 1.49,0 1.32,0 1.02,0 0.887,0 Z' style='fill:rgb(0, 140, 255);stroke:black;stroke-width:0.6;stroke-linejoin:round;stroke-linecap:round;'/></g></svg>", "about:config": "resource://normandy/skin/shared/heartbeat-icon.svg", "about:user-chrome-files": "chrome://browser/skin/accessibility.svg", }; var EXPORTED_SYMBOLS = ["LinkWinActorChild"]; const LINK_SELECTOR = "link[href]:-moz-any([rel~='icon'],[rel~='apple-touch-icon'],[rel~='apple-touch-icon-precomposed'],[rel~='fluid-icon'],[rel~='mask-icon'])"; var noop = () => {}; var re = /^(?:about|chrome|resource)$/; var once = function() { delete this.handleEvent; var doc = this.document; var docURI = doc.documentURIObject, host; if (re.test(docURI.scheme)) host = docURI.specIgnoringRef; else try {host = docURI.displayHost;} catch {host = docURI.specIgnoringRef;} var icon = ICONS[host]; if (!icon) return this.handleEvent = noop; this._icon = icon; this.onHeadParsed(doc.head || doc.documentElement); } class LinkWinActorChild extends JSWindowActorChild { handleEvent = once; onHeadParsed(target) { for (let link of target.querySelectorAll(LINK_SELECTOR)) link.remove(); var link = this.document.createElementNS("http://www.w3.org/1999/xhtml", "link"); link.setAttribute("rel", "icon"); link.setAttribute("sizes", "any"); link.setAttribute("href", this._icon); target.append(link); } onLinkEvent(link) { if (!link.matches(LINK_SELECTOR) || link.href == this._icon) return; link.href = this._icon; link.setAttribute("rel", "icon"); link.setAttribute("sizes", "any"); if (link.hasAttribute("type")) link.removeAttribute("type"); } handleEvent(e) { switch (e.type) { case "DOMLinkAdded": case "DOMLinkChanged": this.onLinkEvent(e.target); break; case "pageshow": this.onHeadParsed(e.target.head || e.target.documentElement); break; } } } |
sandro79 > 05-01-2022 21:46:46 |
Dumby пишет
Да, отлично, завелось, работает! Вроде всё в норме.
Понял. Тогда буду, как и скриншоты, заливать на https://www.upload.ee/
Да, тоже всё завелось и отлично работает! Как и в актуальных версиях. |
shadow_user > 12-01-2022 22:41:01 |
Здесь https://forum.mozilla-russia.org/viewto … 08#p792708 скрипт ucjsDownloadsManager.uc.js. Никак не могу добиться его работы через UserChromeFiles от VitaliyV, его user_chrome_files установлен, из него работают дополнительные панели инструментов, их настраивать не пришлось, они заработали сразу. Возможно, не туда прописываю или неправильно прописываю. Пробовал запустить другие скрипты, тоже не получилось. |
sandro79 > 12-01-2022 22:58:50 |
shadow_user пишет
Вот тут уже рабочий пример подключения скриптов. |
shadow_user > 13-01-2022 10:35:50 |
sandro79 пишет
Не получилось ничего. Ясное дело, тему читал, startupCache чистил кнопкой в настройках UCF. В умолчальных скриптах разкомментирую скрипт автоскрытия тулбара, и тоже не работает. Менял на ваш CustomStylesScripts.jsm, рядом с ним в папку scripts2 ложил ucjsDownloadsManager2.uc.js, и увы. |
sandro79 > 13-01-2022 13:17:57 |
shadow_user |
shadow_user > 13-01-2022 14:50:18 |
sandro79 пишет
Комплект заработал, вижу новые иконки папок и некоторых кнопок, но... кроме прогресса загрузки , упрямо не появляется. Может, и еще что не заработало. В about:profiles вижу два профиля, один default - "по умолчанию, сейчас используется и не может быть удален", второй default -esr - "сейчас используется другим приложением и не может быть удален", что-то тут не так, я сам еще один профиль не создавал. |
sandro79 > 13-01-2022 15:46:08 |
shadow_user пишет
Вот эти два чекбокса должны быть включены. |
shadow_user > 13-01-2022 17:51:48 |
sandro79 пишет
Искренне благодарен за терпение и помощь! По прочтению темы я помню, что один или два д.б. включены, включал по одному, не помогло. Создал новый профиль, включил два, наконец-то прогресс загрузки показался! Возникла пара вопросов: |
sandro79 > 13-01-2022 18:27:49 |
shadow_user пишет
Это один скрипт разделён на два под особенности комплекта user_chrome_files, нужны оба скрипта и они оба подключены.
Его можно удалить, ну и строку { path: "scripts3/tabs_focus.js", ucfobj: false, }, в CustomStylesScripts.jsm удалить или // закомментировать.
Это скрипт авторства Vitaliy V., только немного изменённый под себя по советам автора. Обсуждение начиная с первой страницы этой темы. |
shadow_user > 13-01-2022 19:17:01 |
sandro79 пишет
Все понял и исправил под свои пожелания, кроме: не смог идентифицировать скрипт (или стиль?) для фавиконки, просьба нацелить. Дело в том, что у меня есть скрипт, который показывает фавиконку в размере 22х22, а не 16х16, не скажу, что это лучше или хуже, но мне нужно выбрать один. Так же вроде логично, чтобы фавиконка была не перед замком, а перед урлом, вроде и вы в какой-то теме об этом писали |
sandro79 > 13-01-2022 19:34:13 |
shadow_user пишет
Скрипт favicon_in_urlbar.js
Ну это тоже можно настроить, см. height и width. Войдите или зарегистрируйтесь, чтобы увидеть скрытый текст. со здоровенной иконкой и она не отображалась пока auto не заменил на значение в пикселях как у height.
Да не, я наоборот у Виталия спрашивал как её перед замком поставить. У Ариса когда-то так было, привык. |
shadow_user > 13-01-2022 20:40:56 |
sandro79 пишет
Ну конечно, нужно быть слепым, чтобы не заметить. На сей момент со всем разобрался, спасибо! |
sandro79 > 13-01-2022 20:52:45 |
shadow_user пишет
Ну favicon_in_urlbar2.js это Арисовский скрипт, ну просто оставил для потомков Он не подключен.
Ну да. Там два в одном, ещё закрыть текущую.
To_switch_proxy.js Ну там две кнопки в одном скрипте - переключить прокси и показать загрузки когда-то Виталий по моей просьбе делал. |
kokoss > 13-01-2022 21:15:06 |
Dumby |
Dumby > 13-01-2022 22:31:32 |
kokoss пишет
Проверил на 96 — вроде работает.
Да, разумеется, «что то не так сделать» можно всегда. |
kokoss > 13-01-2022 22:44:33 |
Dumby пишет
Добавил скрипт в папку custom_scripts и прописал путь до скрипта в custom_script.js так: скрытый текст Выделить код Код:(() => { var loadscript = relpath => { try { Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${relpath}`, globalThis, "UTF-8"); } catch(e) {} }; loadscript("/ucf-cbbtn-BBCode-Multi.js"); loadscript("/AutoCopyChild.jsm"); // loadscript("/Undo_Close_Tabs.js"); // loadscript("/QuickToggle_AboutConfig.js"); // и т. д. })(); |
Dumby > 13-01-2022 23:19:00 |
kokoss пишет
Не-не, JSM'ки scriptloder'ом не грузят. Можно в CustomStylesScripts.jsm прописать скриншот Выделить код Код:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+EAAAFpCAIAAAB8p74tAAB7qklEQVR42uy9T2wcSZ7vF5zZnvfWeLAlWSQNrJ+t7h4KLv4xeht6fnikW3zi9u5aGhiWCaHgk9uHdlELHUR40PZhZRAEeDDQGIA8NJYkBAN9M2iioMuIl1kKklDCW6PRLYAiyxbV07L3JIloavHWaxtvZ+WMjPwTERm/yIysLFYU6/s5SMWoqIhf/DIy85u//GXG0F//9V8zAAAAAAAAgDcMBRr9L//yL3ttBgAAAAAAACAi0uh/9Vd/1WtLAAAAAAAAAJxUo//5n/95r41ReO+990ZGRl6/fp37b68tBQAAAAAAoEr81eh/8Ad/UESgQ6YDAAAAAIBThr8aHXF0AAAAAAAwmPir0RFHBwAAAAAAg0nFGv3lg7u/+Z6du3Rj/qMzHTblVRz9xdrM2OITpWh69V3r9trMEC8OP7OdhaFrm8E3jfvvNq6y6Ku0+mHr9s/F57hi/EOlSCk39Bu29Itfm+3J/EDYkkNqaqPReDa+0bodNxNZHVUIvt3c3JSHIswOCupbqj3ycHPHqxuZtafyDbqzsCz6b9xfivpuN5e39thU/dbww692X43O3br5yXlRFhD8eYNtB+Xij6Wbn9jbT34YMFVfmq/xD4/Xl0UDbGpq6vXwfF4jRo4erwszhIWdOKESe5LxPhzu1B6bK9Xtwst3mkPXQhc36u82atX3CwAAAPSUKjX626fN7eOPP3//h+bbP+xco/sWRw9k62fs60h4hn+0Qu0YCMqteiRIA+V573qiN5W/1mZmxK+5OmWRKOVSeKueyPGk/aDOyjhvMylM2kraoexRupU7KzAuXv1ZKqNnnn8RtZ+0KcR7LKqDKivPJu+0+B/BN19ebEU9hQMQ7VDj1XrIt6dSuEZnqrYLxS8LJOD5R4EoTIR1u7l+dDkRn/yvfC0bNLXNbqrVwrIboiEuO1+nQv/xevP8zXknmSm3Vg6LPd3GbbzEdhEYtiMAAABwKuhCrsvLB5VodIc4+gs2M8aiwOt9thGM6lrUSPDn9XssjdhOs8MWE5pwYYiFQW92n0UVVg+ZphdlYu14GAhLNbIbqdAvns+MHdyR9LCi0SMJOyaJabWSrrlTwZtpy26PWlVp1jYuQ4Xg8iMckNRiaFj92T1unPw5q9GlURnHywpo9O5BafSRQAKyULHG4VqLRk+D5aNzc2xfKF45gi6+EtrXrKqTqHhMpEGj8ihqnPyVyGhDa3JTaqQ/jZePjo6yiZsWe+hxiUak+wmqpWpcP6wc/HhkdzduSHxJjZe2k9ou5HaMptHjmbFdtnqrdbsLoX0AAACg+/ir0V3j6GszbKvOhBp8scbGtlI5niDXYfwEH6nz++/YWPCTA/Zug7QnzSKZzkR2xXd6uSGO/otfZwRoLFRlbRqLY6Ituz1a1ewvM6S5JaYhPJvenLyjXmpcvxfYfOdgLGh4fGUh0ehSuksUaTcIbkmYGzW61R6No7WZr/RUIP6rucPWJ3aNb9J2cb5GoBW/ejMbS0dKo3MhyyKBmYR6o2qmODpTNKimoU1xZbVjrU5WYT9eX08KuD37E9lrg0z83mCPbVxCvIvK7WaTzScGmewJGp+SGkpdahwvbad5u9DbUUxUaHQAAAD9jb8a3TkffYcNrUS6fGEo0N0sjummYXXGVZ+u0QOBnpuxzWxx9ESfannVSs61SNC2aFZZ4yrZ3HFb5eLoRTS6Mg4pF8Xw8yhazvjQooz8BXMc/dozkTdfQqPb7KmI4jkShEa3Jr0QGl3+PtHQjM79SMtVI1hWE2fi01KE2pgbT9ljHVfGDNKeUKPLgjqo8CgeJDHefDs72Y4AAABAf+GvRi+Rj742ww7uhLkusVgXaTCTsV43xNGZLXYuQ+dgRNnj/DlORVCa1PGLArkupiRyWqP/3GCOS66L7ceM0uhX2c7OztWrV7lLTRq9QG4PUzV6JruH9mFKtXF0M4ouTcV3Rxo91KPtmjWuLPedrZDRxMUS5cOQtCnvPLGnQo2+rl1E5Gn0InbqQKMDAAA4rfir0cu812WHDd3j+eUr47EQD4PoUaQ8/KzH0ctq9ESbynkpqro268siz4zycjXZJVejJ/aoVXOj6MnjqXGjmlKmNHoModHTZgs+Mxr/PM+eiiiu7eQ0Dfmz+iYTOUPEqNHV6rJileWs2gwTcnaWPcwo46wmpt6somjl9NKAtMc2Lsc4+i4zPxdrHC9hZ8nt+GJtfWxx5P67+eqnDgAAAHAiVKnRxYsXU85d+nz+o9KtlXuvi3gSVE5fSZLOWYOtPmPhOwRDXS7lwMjC3YjpHYg8s+V5lDkdZrkklcK/pHcv6qkrtncRxiX854x/pvK8jfZczXyR9/LFzEsfZX2sdTwmpcAH1VjyZ2N19dmiao/buyZTU2l7KsUp/io/Q2l+FtP4gkXlC+1RUvXFiemXmRwPXbXrj6TKP1G7noq1r6HQbo9pXHq/VLnU7/qbEba398rQgWm8hJ3ltmN7Yejh+OHNLj94DAAAAHQRf9cw8ur96OCU0Tc5EnTo2nO0XJcuYd6OO82Z55fxtCgAAIC+xl+N7tv70cFpwrCGkWeUeYLSG6g32FQJ1jACAABwqvFXoyOODgAAAAAABhN/NTri6JVhyl4PyUtWBwAAAAAAvcBfjY44OgAAAAAAGEz81eiIowMAAAAAgMHEX42OODoAAAAAABhM/NXoIo7+F3/xF/Zqf/ZnfwaZDgAAAAAAThMVa/Snzbvf/Mg/nLt0o8OlRkUcfXl5+Ze//CVV51e/+tXS0tIJuElaYujwa/ZZspLPO/vSR+paPckTmunyRo1G49n4Rl4jRpIHQTtf5qcSe5LxSsuEesyLxzNju0/w2j4AAAAAeEnF64x+e1ZIc77kKPv08ysXyreWxNHtGv3E4ujywvXir3wtG+joz1hLrRaWfS0a4gr+WSr012YWXBe+l1srh8WeblNivFXRN2sYAQAAAGAg6Vauy9unze/OzF+5UL4Fhzj6CzYzxqJA8H22EYzqWlQh+PP6PZYuLj/NDltM6NmFIcaLG+w+iyqsHjKL1rVodHmt+1W2JRSvvtp9HHQ3q+rM6xGjoHtUHsXKk78SGW1oTW5KjfSn8fLp6WlWb1nsocclGpHuJ6iWqnH9sHLw48nFxbgh8SU1XtrOaoFGBwAAAIDPdEmjv3zQfHtl/qNOmnCNo6/NsK06E3LuxRob20rleIJch3GhFqnz++/YWPCTA/Zug7SH0uhcyLJIYIbKk6Ua1RRHZ4oG1TS0Ka6sdqzVySrstZmZpIDbs1XPXhtk4vcGe2zjEuJdVN5ZWGAbiUEme4LGG1JDB3diNW4cr0tc/2ht5ivDi9+n5w5bn9jvLECjAwAAAMBnuqDR3z5tbn9ztrNEF6bG0QMtnq0gytN89B02tBLp8oWhQHezSP3tpGF1xlWortEDgV4k3YLQ6NakF0Kjy98nGprRuR9puWoEy2piw3JFSYTamBtP2WMdV8YM0p5Qo6eqPKzwZTxIYrz5dnYIF+ibo6uHN/1PmwcAAADAYFKxRg/1Oev4eVFOiXz0tRl2cCfMdYnFukiDmYz1uiGOzmyxcxlFl6biuyONHurRe9etcWW572yFjCYuligfPtppik8n9lSo0We0i4g8jV7ETgHi6AAAAAA4nVT8zOhvji993lmKS0KZ97rssKF7PL98ZTwW4mEQPYqUh5/1OHphjS6nacif1TeZyBkiRo2uVpcVqyxn1WaYkLN32EpGGWc1MfVmFUUrp5cGpD22cTnG0ReZ+blY43gJOysGGh0AAAAAPlOdRg9D6D9KBR/24r0u4klQOX0lSTpnDbb6jIVPOYa6XMqBkYW7BfkZSvOzmMYXLCpfaI+Sqi9OTL/M5Hjoql1/JFX+idp1I9a+hkK7PaZx6f1S5VK/MweTbHPziaED03gJOysGGh0AAAAAPuPvGkZevR+999Cha8/Rcl08ARodAAAAAD7jr0bHOqOCrj9B2U2oN9j0HqxhBAAAAACP8Vejizh6INPlfwPJLkS5XN5rSwEAAAAAAKgSfzW6iKNrcnx5eXlpaSlb3mtjAQAAAAAAqAx/NTri6AAAAAAAYDDxV6Mjjg4AAAAAAAYTfzU64ugAAAAAAGAw8Vej+xxHf/F4/TN2o/XJ+V47CYBTQ3thuX19aZ6/U399nd24eRu7FzjV4DwCALBTsUZPFzI61+mCox7H0VMxkRAcbb88fzP7Hj+qnMK1HZSjnHFRu7z4Sq/DRufe3fyEGWk3h7b2gv8b9aUNJn3u6Ysog0GN7YbDmKq/m6/SlFz/eLIdUd6n5RTW+obzCAAAyFSp0V8+uPub40iaB2J9l83Nf3SmdGvextH14Ee7vVOrjYlj8fDjhXZtQ3xFlVO4toNylCflR49nvtp9ok4ou+ZW1EMg2du1amWxX1j849V2RHnflVPk1UcQHQCQS7dyXTrX6L7G0TPBjzgkGTK6eiu+R0+Vkw07toNylEvlO83la0kxswbRQ0iNLrU/PXdL1hBpF6Nzq2w/TEcJdoetTaVhbhLbXl58Nbo6N7K4u6fbr0S1p+5HyS2iJPoz6miq/u7yUaSteWSdhX0l7Zvq05cZpH88244o77Nyipz6CKIDAPKpXKPzYPr3rIJcFz/j6MbgB79Hvz8Rq5b8ckvjTu2gHOVpuRoqzk1cSRNLQlI5Hsb/hHQIpPPBbNQO17gsEsHhb1koO9oL60cbNz9J9osklTyU3ZGGDm17cyeW41sTSV/NoYfDQisnPwxHx6ZHZltCcAe/fXS+FQr0Z3O37rzZfn5ZtE/Up6D949d2RHm/lVNY6iOIDgAoQrfi6IFU//bsjVMXRzcHP9bWmxdvzl8NRMA2a0nBS6qcwrUdlKNcLpfj3O/y5psWR585uhwpBrOWjbR4phmbRk/0fdrdsBDcqZjeaa4rmvtNc2iL3b81vJJUi+3RgvpkfRrKP75tR5T3VzkFXR9BdABAIbr3XpeXD5pvr3QQSvcwjo7gB/CaWM4WefqT0OiBeng4Ht+Xl+pQGj1tTds1tHezFNLosxNbW/v1oHcmVYvi6DUlAM/o+hX5B4AugfMIAKAgVWr0p827xx9/fuUC/8xTXtin0R+l8C+OjuAH8B0eKn6dH0RnlEaXY36hop2sp7kuK8OJROZp6ExNF8lo9OVFlloSxRR17Z5Kf5GSHgXLjwwaXW7EVr8i/wDQHXAeAQAUpdo4epyMzk5hPjqCH6AfaO+0a1cLBNFFMrr87kWhd6U89dHGFNvce5VEneU3GKahaCLPO9DiByP856I8zVQx1Y9aFg99JhX0Z0Zr0XN4/InVXXP9fJleyD8AdAmcRwAAxfF3DSPP4uhKDgAAwA7WIQIgA84jAAAH/NXovsXRAQAFSSPuBZ5eBQAAAEAWfzW6Z3F0AAAAAAAATgh/NTri6AAAAAAAYDDxV6Mjjg4AAAAAAAYTfzU64ugAAAAAAGAw8VejI44OAAAAAAAGE381uoijB6LcXk1I9hO2De+4BQAAAAAA3aMbGj1cyejDjhYZZXEcfXl5+Ze//CVV51e/+tXS0tIJuktgWChOWbWxQDkAAAAAAAAU1Wv0p827xx9cOj4+M3/lQiftJHF0WaMHolz78+Tj6HoQvd3eqdXGhBYffrzQrm2Ir6hyAAAAAAAArFSs0V8+uPvt2RvzF142v+tUoxvj6FmNfuJx9EwQvR0tpR4yupqsIUeVAwAAAAAAYKVKjf72aXP7+GOe4hJ86lij+xlHN2aiB4Vj+xOrbF9b/JwqBwAAAAAAwEKVGj3MQ0//PHfpxvxHZ0q3JsfRAy2erSDKTzaObshEZ3zl8+bFm/NXjx7PbLOWtPI5VQ4AAAAAAICF7rzX5ZTG0fE6FwAAAAAAcAL4q9H9y0c3B9EBAAAAAAColuo1epLx0mGui29xdATRAQAAAADAyeDvGkaevR+9vbD8cBzvZgEAAAAAAN3HX43u8zqjAAAAAAAAdA9/NbqIowcyXf43kOxClMvlvbYUAAAAAACAKvFXo4s4uibHl5eXl5aWsuVDQ0O9thcAAAAAAIBq8FejI44OAAAAAAAGE381ulMcvdfGAgAAAAAAUBn+anTE0QEAAAAAwGDir0bHe10AxYvHM5+xr1uf/LxgOQAAAABAf1GxRk8WMGIffvr5lQudNOXZ+9Er48XazNjik+DD9Oph63bFalI03rj/bqNPVkPdWVi+tsk/NO4vFbY5+NG964bqVLlaqTl0bU8pmZ47hKwfEIKruLHdJ3znu9VK1jpIp8To6uHE1pfnW18c8WqN+ruNWg+MlO15d/N2sREVn8bRPodpDwAAnlOpRg8U+rdnP5//KP54qtYZtbA2s3Cx5aaKAzHNI75Va3TR8peu1vQOrheYmxTqPIi+05x5fjmUaO2FmaMvoFQGh+wk4YKY3X83f5XFeldI8+BzINZPXqPr9uzXc2U6c7+DhDtOAADgP1Vq9LdPm9+dmb9yQfz18kHz7ZVQr5fDGEfPavSTjKOvzQyFEXDGpqenWb3Vup1GxWOiGHZUHsXKk7/etaLTrUGjy01JNc39huwsDIkgdFB/lW2J9rhGZ/Vni+IXaUhdNBIY9DX7LOxH/yo1X1gyPd148mQzKLnPrvFu4vq0nYwdrc18tcgcAnTuGr2jIHpU1aTRk3hkQhJo1ELvOQHI9sLQ1qaxnbX1ocVXsZ+FqaHDeK9TgSxjYYCTh3jZdlgzDqNGBowGW3kxKE8NiPpyuQkhbShptGRcmc+rG+FX8k+S+G5cyHUtE8YoTRkp7gfRDl0/rMOkz3nLAOvaNGjn0cXW/FVjTb4f7cb7UexhYUywCfh+tPsk+1VqpzBydLrxKtyP6uyavLEof26zliTKg21xr/YuiutPNTb3NplqDzkuySfR3Jai8tDoAADgP92Kowd6ffubs53ku/gWR5dVNRfHz1J5ao6j7yzMPP8iUeFanaxGX5uZSQq4DN6qi/apfvlnJstmJl0PpJ+VXoSoF8J6Z2GBbQS/DgT6Vj3OugkqrIy/i689Ju+HwivsZiwOz1N2hnRdo1eSiU7F0dNG5HJJNhXsRW5nqH1dxEQDAbc1IWnrh+OpLOMykQvTZ3OHd958JmxbW5+JxLHw0/rzjaB+aEydHVy8yTf82vrCwciz8cv52tSALE+l8WbiykzoPNkeJb7Lt/lWPdbKk3kb090P5vpKnLvw/RB9C9I/lMee/RW/GhGStx3uRzXCzqPYJ/wChgXCeiw22+hPwwSLLQztmRTSPFvN8sPY7QtizpD1AQAAeEbF+eihNP+Rfzp36RI7TqPq7shx9ECLZyuI8hOMo6dhazkIzehcl7Rc1essq9Ez8XipC2O/vMWNluEmuJLrovWbMSObGRNVYdy+Vijlh+5dF7F1XnHMYmc5nzpp9AqC6KwnGj0Tr01tiOOpenhe+okIpnInCWNmD4JmD4dXgl4SLeuMEkpP4rLxxYCtsvYTPWqb06mTH+j62n2PgtnVThqdvAbI/oqyk8WTJ54JUbPDZn+OWTW65ZrEODNTXV6sPgAAAK/o3ntdOs118S2OrpDEm0PIfPRYE2crZOLopOYm+u2RRr9azE4HRzpo9Kpe50JpF7NGV9NgimjBVE4V1OjhV0ogNqoTSvNhKf8hvmDg0e7XPI6btuOKGkcXUd6rlEYny1n8c34Vmf+QpasfrBq9gjh6JrfEsBFZFzR6jb4WMuW66PnxBTV3XE0LojNodAAA6Ae6pdFfPrj7w/sdvdnFt3x0OccjUa76V3ICSvTVwsU7bEVTxqZcl1B+G970QvWr1k87dtPoWvuJ9H9BaXTSzpCu5rpUE0RX9E0qYnjiwcVHcbhai6PHKRzFlI1kj5LrYspdYYq8y2gpXm08yQhnRg0na3Txyo5i6emqrEzaCUThynCyAdPto5anSDkYOyJNxe4fVz9Q9avR6Iwcr5tGZ7bcJJNGJ/1JPTNaRqMLT86ylYy10OgAAOA/VeejR29erODdi77F0aUHK5me4JFmo2QSP3TVLieu6E0Zu7D0K3/ViAW6SEVpRKnkvKvwwdVDrd+0ITXNpiFyz5NWrt8Lfpc8aSp+RZvURY1eSRBdeqpPYur+6utrvHwq1EZxVJiHzGu/TgZU5CV32QdPRftRKF1Kb4hCzsqzkleVROekwTd3hGKTWhBZJcmLK5Mkk8IaPZu7MhXpQs1Lcmhc9V6UmyHGKz0zmnerwdUPpvovSvRLz5bseOn2D2OfZ/yTtXNYGlTtXtBI8qSp+FXWn9GVdebdi8Xt0R8nTe+Q5PsBAACAV/i7htEpeT+6KXQNEgpr9KDiyrgh3ZkqN6MGO0OkUHfnGF7YV7J9EYi96HaLAOQxcNqUuMMwcH4AAIA+xF+N3u/rjJJPmAKJUmsYlafbGr1yx/RqGZ3TinENo1OJ/MJQdRZhDSMAAOgP/NXoIo4eyHT530CyC1Eul/faUgAAAAAAAKrEX40u4uiaHF9eXl5aWsqWDw0N9dpeAAAAAAAAqsFfjY44OgAAAAAAGEz81ehOcfReGwsAAAAAAEBl+KvREUcHAAAAAACDib8avd/f6wKyVLVQKAAAAADA6aakRherFZ27dGP+ozNp6dunze1vfoz+6HQRo1PyfvQMyZJB4dJC1atSqv1q+y31zsSOFgqV3yUnwMvjAAAAAHBaKaPRuRQ//vjz939ovv1DXaN/d2b+yoVKLPNtnVELazMLF1tub/cOFDOPHHdtbSOq/ar6Lb4+aNp1x0H0dN37wmu/AwAAAAD0Ix3kurx80FWNboyjZzX6ScbR12aGosW+p6enWb3Vup1Gp2Oi5Yqi8ihmnfz1rhWv8Z7VynJTUk1zv0xZJCkbGnfU6OE65swhLu2u0TsKokdVTRo9WSY9IYmva6F3W9xdXchdW+NGXpt9lW1FqyDJP4nXbE8KpTXb85bLaUdLu2ftlNaKj29XHEnLy8+z8GYGb59thzVjMyKDubWLQXk68KivsDWb/aHNTPp8fiez5nw6LpudJn8CAAAAIJeqNXp1uS6+xdFldcvl8bNURpvj6DsLM8+/SNSwVierlddmZpICLte36qJ9st+dnZ2rV69Gvx06uKMsZeqbRq8kE52Ko6eNyOXBmLZZK5SehXoJ6j+62BILjkrtcL3L7ouFSMPrASbkprxkKS/fr0syd6sea9zJAk6S7U8WPQ2E79aEpK0fjqftczu5QH82d3jnzWfCJ+oSqjsL6883gvqhE+rs4OJNPjvW1hcORp6NX7bZH3z+8nwrsjn1Q9RgYmry8zw7dX8CAAAAoAiVanT127s/vN+JSpfj6IEWz1YQ5ScYR5cC13G4XEDluqTlql5nWa2cicdLXRD9qj9RDPIu16WCIDo7AY2ehn6TNPtY7Noqaz9Ro9EFgscGjS4LXG3scdf6bQHpJ8F1xb1auHGEE2YPgmYPh1eCXiJNz0j7tfsScS+ERmf5durOAQAAAEABuqbRw6+vzH9U2jLf4ugKgWxeGc+Jo7NUmmcrZLQyr7rRul243/DTYRp3/1LtwCuNXtXrXNbWF0Q8uJBGV+Vm/gOmatx3aIuFspLQ6GQ5i3/Or6oaxTyUhq4LavTwKyWAHdUJpflwenGSXKjwuwGveUJL3A5pPxFHJzZZATtVfwIAAACgEFVq9KfNu7/9IHrTS/Rc6ZULpS3zLR9dzkXhCvne9SRwnX7FQ95MD7HfYStqEJ2ZtLIiunP7DX8fJaaHAfXJjuLoXc11qSaIrujF+LOI5l58FIeNtTh6nGrinOsiac1A3a4MJ45Jx62WSx7mFwaTkb4P01HynCr5Qcl1MeWuqHamFy0srTaeZMwz5WaCdVyK/Q4avZidcr8AAAAAKEIZjS5evJhy7tLncbw8kOlRQrpUWA7f4ujpg5scNbUkzUbRUk6yql1OXNGbMnZB9Sulukw3Gmxz80n4HdW+rd+uavRKgujSU4kSU/dXX1/j5VNhvngcveYh89qvkwEl0XSXZ0bjNjO9y6Fx1SqezjEW9yU9M2rrN/vAa9q1alLUr/LMaDzk5IlP0eCbO5HlaQvac5/TcUq9i/1GezKu0+00+RMAAAAAufi7htEpeT96JhP9dFBYowcVV8YNadlUuRk1WBsihZz7FyVo3dG4RAD7otutCQAAAAD4ir8avd/XGSWfMD0VlFrDqDynVaNXR7RBCmbAAwAAAMBz/NXoIo4eyHT530CyC1Eul/faUgAAAAAAAKrEX40u4uiaHF9eXl5aWsqWDw0N9dpeAAAAAAAAqsFfjY44OgAAAAAAGEz81ehOcfReGwsAAAAAAEBl+KvREUcHAAAAAACDib8a3ef3urx4vP4Zu9H6BCuyAAAAAACA6imp0cUyRucu3ZDXGWXy8kYfftrJIqPM6/ejtxeW29eXlNf+Bar9y/M3s6+9o8oBAAAAAACgKKPR3z5tbh9//Pn7PzTf/qGi0QOF/u1Zsbxo+FFX8E4Y1xnVOMl1RhP0IHq7vVOrjQktPvx4oV3bEF9R5QAAAAAAAFjpINfl5QNNowfa/bsz81cupF9fCfV6OXyNo2eC6O3m0NZe/Mfo6q2b0VI7VDkAAAAAAABWqtTochydx9q/OdtJvoufcXRjJnpQOLY/scr22Q1FiFPlAAAAAAAAWKhUo0fS/Ef+6dylS+w4jaq7I8fRAy2erSDKTzaObshEZ3yl+ubFm/NXjx7PbLPWzU9yywEAAAAAALBQsUbXvu4k18XDODpe5wIAAAAAAE6Abmn0lw/u/vB+R2928S8f3RxEBwAAAAAAoFrKaPT0BYuCc5dEDrryRcfvXvQtjo4gOgAAAAAAOBn8XcPIszh6e2H54TjezQIAAAAAALqPvxrd53VGAQAAAAAA6B7+anQRRw9kuvxvINmFKJfLe20pAAAAAAAAVeKvRhdxdE2OLy8vLy0tZct7bSwAAAAAAACV4a9GRxwdAAAAAAAMJv5qdMTRAQAAAADAYOKvRkccHQAAAAAADCb+anTE0asmXYNpbX2d3cB7JAEAAAAAPKWkRn/avPvNj/zDuUs35KVG3z5tbosvOl7DyM84+ovH61+ev7lRy6vXbg5t7QX/N+pLG0z6nPvDLhs/tvuKf5qqv5vvqSkAAAAAAICm5Dqj354V0pyvLMoSNR5+IdYcDT7+8H5HKt27OHq7vVOrjQmNPvx4oV3bsK45qqj5QLK3a5DFAAAAAACgCJ3murx92vzuzPyVC/zzywfNt38YR9XlL0rhXRw9Do2HjK7mrTlKanSpnem5Wy1J6O80l6+Jb0bnVtl+mI7SXlje2lQa5l2z7eXFV6OrcyOLu3tZe9bWg2/Fx6n7UXKLKIn+jDqaqr+7fDTz1e4TJiLrLOwrad9U33qZYbCfPabbN9ifb6fqB8o/whVZP7Cjx2o72nYUrcWVAQAAAAB6RIcancvyK2HgnGU1+i6bj78qgXdxdJErsj8Rq+cClXdfJX+mcjyMxwsJGIjIg9koAYbrURaJ4PC3LNKg60cbNz8JSj5jN4IWklTyUIDK0vPNnViOb00kfTWHHg6/u/kJk3LQw1Gw6ZHZlhDcwW8fnW+FAvrZ3K07b7afXxbtE/UJCPst7VP2m/vVrnlmji6HY7T5x+iH2J6a2o4AGh0AAAAAXtCBRg9zz89KaefVanTv4uhcPjYv3py/Goi8bdYSgo+G0JR6KDdOUo+0ZqYZmwZN9H3a3bAkQEN2muuK5n7THNpi928NryTVYnu0oD5Z3wxlv6V9k/01sl83jc5IP6j+hxwHAAAAgI+U1OihPmfq86JqDnrHuS4extGdIDXl8sPxOL9CqkNr3Lg1oUGTEu3dLIU0+uzE1tZ+/ZYqYeO4shJ4ZnR9M1aNTrWftb9G9kte8xj9c2TV6FIcnV8JQKYDAAAAwDNKPjP6m+NLn2dj5G+fPnh54Uoo2zt/ZtTDOLoTZk0px+DDgO5kPc11WRlOJCxPumB1Jcyc0ejLi2zuXSyLoxi/rn1T6SySs6Ng9pFBo8uN2OoTkPZb2jfbb+7XTaPTftDGkmr32GzkugAAAACg57hr9PT1ihHyWxaTdzJ2/u7Fvo6jJ8no8rsXhe6U8tRHG1Nsc+9V8k5G6RlH6UWN5twYrkEPRvjPRXmaSWKqH7UsHvo8kp7jVJ4ZrUXPs/InPnfN9a0y3WC/9tu4/UCaG+2n7Dwcfkj5k/KPuVx/ZlQbFDQ6AAAAALzA3zWM+j2O3m36fR2ifrcfAAAAAKB7+KvR+zqO3m3SiPVomi7SR/S7/QAAAAAAXcVfjY44OgAAAAAAGEz81eiIowMAAAAAgMHEX42OODoAAAAAABhM/NXoiKMDAAAAAIDBxF+Njjg6AAAAAAAYTPzV6IijAwAAAACAwaSkRk/WKjp36cZ8uLCogC9B+r1eWA4/4+jKapf+IRZIakgLlAIATgx1tV0AAACgPGU0eiDEvz0rVDjX5CxeUZSvQHr88efv/9B8+4eda3Tv4ujt9k6tNiY0+vDjhXZto9dn4rX15sWb+oqYnl9FAOCKcZ6fAk7ruAAAAFRCp7kugS7/7sz8lQtS0csHlWh07+Lo7WgJ+pDR1VtVrpEZrukzujo3sri7p7cv9Ts9F4foMmvaJ7FzrtHZxLNd8a22rH3hte4z7QuT2Ha49lC88NBOc/nanvjzfNiyXv/2edGjZHnBfqfq7+ZZ+Nt8V0dm8D7nVtk+X76UmdsJ7Tf4OV5TKfJM1GDw28tHRj8k4yrsH9s6TemKTummaRP+dNtevH6x+RPVt/nN5J9527Vgdrv8op3e5xHfyhNDWtlqdJpNtAKn0fPc4DdReXS08eoVn+R1do0PPH+2G/ql5lU8VQKzv2bbwViS9sUtLMayIzLt1wXHpdoDAABgoOhQo3M9fmX+o0zZaYyji9Pw/kRytq6W8MQc6wl+Cn9zR3wO4/dX4zoHs/K53BxHH9tlQgoEnz9jNyRxXFija/H4dnPm6LJoZ219XRp+e2H9aINriOhD0mNaTfptIYKxPzrfCgXis7lbd95sP79s8zYXUiwSi/LYqXYoPycGh1uZTY/MtuI2TX4gx0v4x7bdtyZiVRfo6YfD7+z+dNxe1Pwh65N+M/vHdbtQ/cpzlf/2dXphY5znZr+F2ncy0LssuDJhwVYey7utRPVLzisWX/aIS692c4HNJ+1n9jh6v6b3X8oPAAAABooONDpPbfnmbJzoknJa4+jJOTU40W6zyoNbmv5OpYwaclPjbXm5Lq76uEg7kYbjXwQa4l5N2GPT6NL9B4cQfrHQOy2CiXYoP0cGvwm13a3hlXiMrhqd8A892LiyYKe5Hmri6jQ6MX9y62f8ZvaP63ah56d860CZJ4Z5TvmNxftmMOvatUBhF0j9MvZrvbiidyujRjfv12SuC+kHAAAAA0VJjR7qc2Z+NPT0xtG7iibC4nN5cMJ+OB4H8DTB0RuNnkjPYcO1SlajqDHdSDnZOo7llxIoJbFqdFM7hJ/D8tmJra39ukj5yNHo9Hit/qGMlH67Lt83MLbvsr3I+ZN7DWbwm8k/rtul0PxM7yeIrruq0Y39VqjRzfONFclHV/0AAABgoCj5zOhvji99rqW4SF+f1jh6V+H3xFnm/r4cs0/u46caXY5VsyQvltZAFeS6RO2sH42bcn5yNXr+NYMkv4o8VKe+SYMPkAkXEe2Y/czSPGPe1FFHGt3iH9N2t+XGdKrR6flT5D6J7jeTf1y3Szqi0B4WR+sVP6jXcsZ5bvbbkbNGp/ol5xVzjqMb51uhcRW5pgUAAHBKcdfoYQj9R6ngwzjdRbx4MeUcreMLMIBx9IMRtrkXPQSXZBokz6IxNtqY4hUaklaI00j0B9caUUruHlOSFopq9Lx2wgpvZhX1YM6p0J59zHsAVHlmtKYk/tpclzw7GPdLt2P0c9SCqCz99nD4IekHOgfJ7J/cIWvtWNsvvr2M8+eLI6J+rW302yrbNfrHPkDDdlHGFT1MqWyCCHWKZua52T/DkmG1dvCT5MlOi/cs/Zrs15/lpcqTpqj9mhqXzQ8AAAAGCX/XMBq8OPp6Nx5FrRoRsDy/sNy+3p/qoct+7nv/gGrpk/0aAACAd/ir0Qcqji69bc3z1zhE8cI+XSap+37ub/+Aaumf/RoAAIB3+KvRBy2ODgAAAAAAgMBfjT5QcXQAQLcwLNgkQLY3AAAAf/FXoyOODgAAAAAABhN/NTri6AAAAAAAYDDxV6Mjjg4AAAAAAAYTfzU64ugACIqvZAQAAACA00FJjf60eVesY3Tu0g15SVGqvAR+xtHdlhbvsiViGRplVZS+QVrzBa+lM5IucMPy134CAIBwfdxre0pJf54gQBliVaCcL9IpMTp3OLEfCBixhl2vXhAs25N76nfXOZG0ODXTvoxGf/ng7rdnhQTnS4syaZ1RY3k5vIujt9s7tdqY0OjDjxfatQ0PZkB/R1jDldvvjOw/vwwBqrO2vnwwi5esAwDc2GmuR0fUdnPm6HK/nh2AO1k9wAUxixaEFnpXSPNeRRt1e/YnikToXHVOf+silU5zXd4+bX53Zv7KhaLlxfEujt7NuKa884irzOQqUCyDkqxqrr0wLjsXyfryG+iU69ckpC2tzR6vCS+tFc+HzLaDxqNqJj+Ipoq+0i46TDD1RKL4mRPYU9//iuyXHJdyvb7K9m3LPRpezxd3YbKHW0v3myXcKIT9UvvSpT9fr/T6yG4cElP8LC0Xn7g6uxa9wX4ltGC2n26HxuBnFjc+FRyOWdimbf7EI4qGEzUY/PbyEbFdHO3Ut2/OoGzby+g3Yv6E402rReMK/0ziQ/q8yoRCbfM/6jf8k0mfz5vnSXJwiKZBNDfoHZbwW9TyVHSujQ0eZexVchjR/Waah8LPjSm2uReGyqam2N7eE+Eum5/18UZ+zsyf1ddb5nk176pNbPPNtD8yYvu+MQf5jsz7i6V9C0aN7jTfbOKGOh4a7TyyHAcM+8Uq23WbnxTW/d18XrDu19p50H48LO4Hcvta92sLuh4I2nl0vmWa7fzkyyae7Yohpx626A3dTmHk6Gjj1St+0q+za/LGovy5zVrqOfpebSmK609Nbe7tMdUeclyST6K5LZ2FodETXj5ovr0y/1Hhcge8i6PHl305aq+DxtPr2rZJtoop2G4usPnk8tc8F0315TXJ5evXNF4bznuWHB/5n/v1+BgxGd8XC3dUeT98cyfdndw0+tp68+LNoCbXoxvSfpsOKhhIuyZOqFS/1Lgy8QOWe4yTnZme50h7zP3SgyX8Ft6fSQ6C8rZ4kogJZbzLWxPSOezhcNhv5MPE1NQ8Y/uk/XQ7BKSfo9MDPyE9m7t158228GfudgyNYdMjs624TdN+4WyncroqEF90nW/U/FENU6a6PK9Se6TTmNwgZQ913DDPk7DxOnsT7nd8BzwYeT1+2d1vhnPtun37Guchd87sxNbW/uQUe8ZG2N7ren1i6yFvmfIzPV7z/KHKHSHnG7E/0tuXmnv0/kK1T++S5ji603yzQB2fzXaS4zLtFyXmp9O8pY9X5H5NnAcp3P1grm/TA0U2Dcv5oTz27K9M+oE4ngif8AsYFuz1Y7HZRn8aJlhsYWjPyP34mKZVs/wwdrvQEnT9vqUDjf72aXP7m7PZhBaq3BHv4ujJPMicnyrBrtEte5pRo+v1DXG++FJYGov9ajV2gpKDUf6WmXR8FxfThgsP9Rxg6HeYGFdG9xfcBEU1OuVPunHSb2pTUY5gZo6l41XjIrGdtGal2rf6rbD2pf0cd6GF5Sg/RB29CY/1t4ZX4mFWqdHTIedfRjrON3r+SFrBMs+LaHSj37T4aHqTxzhPWNj47JtgGh8OPwwaT7SCm98yQTJZozvM87iOnnJK71/m8TJy/lDljhDzjVH7I719lTi0NA+N+8uRrX2KHmh0i53EccC8Xxy5z0+neUsdr+zH86PCkWxXP9D1qXledNMIrMrBQW/YjyehlBczwX6cHLNqdMs1iXFmprq8WP0+paRGD3U4yz4XSpWXwMM4elfprka3HJtkLdg2p53IJ1RNDJXW6PqzTdIN6LRNIm4t1aE0YsUaPWOPc/uk/csPx29lOjLdW7BqdGo+FG3f4gorVo0emqoEYOj5k4RUo5BVjkZ3tVOPq4moj/Waymm+2eZPJEGGDdddBs2kylBdg2b8ZvZP3jmV732vFW3t5reMsCPio7nzPIrJHU7sB43U97+K9T3pZ1sc3TR/qPJy5OYSFNHoil6Pj2/m/aWURqe0i9N8sztBPx7atanpOGDeL47c56fTvGWlzhem82B+p0X8YNXoFcTR6XhidzV6rZjekC7Pyhzn42paEJ1Bo/MHQo8vfZ5JZaHKy+FhHL2rpLNKyzlhlWh0vjOsDBuOv/I5VT58SPee2uL2XHrPnaWJX+ruUTzXRd+HpXaCRtrXo/vjaq6LqV9qXGo5N4zlHWGJHdtsD9Uvhdn+I/X8JN1LVU9OqQ2W3AlmP0br7dvsL36MI/18JOukdJJQ21FJlT7qskYvoHVc55vVGL6ZxqUcObERLz6Kw4daXDPeTHqui8me3NwPZZ7QOSpufmMWje42z4Wdv2iHI621k2qUny25Pcb5Q5WLn3Pt5ZKebnr+x+Bn2/alPpP7i21/N2Bqv8R8s3RAHJ8JO4lxGfeLvPnpkktJ7O/U8coy34znQQpXP1D1q9Ho9PHZNSaYczzRNbrtvGx8ZrTccZ57cpatZKwdbI0ehsp/lAo+FGktVHlZBi2OLt1uk57djJ8xSogv5bPPME0lxxFTfY70zAcz3raeHh1lEzfi5LBXTHlWJjrPBfvqwUj0jBfT4y7FjqHySJXn/9Knx9SR8V3a0q95XGp5TghEudeZ3tPMPmiV2GPp1whlv9RFNHxjOkpqv2M52X6B+ZDvN8rPyjNSNTnB0egH5RlE6beHww+peehmZ/Zedp4yc5tvxPxJ4FvhzWzSozLetjSu8FltcX2uZYAY7bHspwb/DJP7HXkTn/Cb5oHG1N7mHosfky08z+fm+CNr0lae5nm6X13b054kTv08Row3fKbWMH+iZ0Yz5dKjroWf/nfZ78jtqx/PtWd/DfuL0zxXPZZuMsUPxeabsX3b8dCeU5cdV3a/OMqdn4U1unV/p84LxeebTfy5+sFU/0WJfmN/mnJC9PHS7b8h9YPleBIMqtYOGkmeNFX2AsmfYqtl371Y3B79PEvcER1sjX5SDFoc3QeKzOz8xN/ODNAzZ+IL9K72W8Ie16Z6Yr+H9IsfKrJTBJzOp6HHHtvTdfrFTqY93ncqMDi/7PHKSHXHw8r2CyBzmrRpIYg7DKfJD/5q9IGLo/eO9Hq30DsEC9XslYV+0u/2D5ofqrMzigV2uFzI4Pmt++jvpDoNdFujV0c1+wXQMK5hdCqRn2dTZxHWMDopEEcHAAAAAACDib8aHXF0AAAAAAAwmPir0RFHBwAAAAAAg4m/Gh1xdAAAAAAAMJj4q9ERRwcAAAAAAIOJvxodcXQAADjtUOtzlaff37zW7/YDAKqipEZ/2rwr1is6d+nG/EdnkvJ0IaNznS446mcc3fCC2J5Cv4EoW836PqbT+CYyAID/pCvjuCz5qRMvzRPSh++e89J+19WUxUj4y+/8f/nmAJNZi6rQfBNioyfvNDS+UzJ90+vUVOP18IaX801bVqyg9+T9roxGf/ng7rdnhTQPPv6GxeuJ8j+OI2keiPVdNifLd1e8i6O32zu12pjQ6MOPF9q1jZ7HOTIrJ1s4gbVFMks9AwDASRCcCw9m+/hl2/1uv0q6pj3wEyXaGFwfPhwuck3Vqzs82X7lEn7x8Lr8NWGXdUtbXqirhAzrNNcl0OLfnZm/csFQ3qFG9y6O3s04h7hMFIHw7NWqvHbuKtsX21iOoIuvkjkqXbqlC+fyyTE7sbUlL7asVc5e5JVfe1lbcD5ZJVheY9k8XrmpLgRjtOva9OaDtH3NxsSODhc8DxoZXZ0bWdzdSwrT1ctjs6NtxLfablBfLIHO25+aYnt7T0Q1Y7+snVkDWVkf2ymYYZg/TF6bmoVtFhhXPBOiBoPfXj4y+kdax1srLzh/HOI65nFlmzLOq8j54bikz8+p8UpLqavby7BMuryWtb69ImNC25j0Wd8lC+x6xPGBkceB/PmvjM62X2TsJz6H8yoNk8cGjzL2SjZP8TONaVxcFF4f2Y0PiZEzlYOkdjAxzocj837hPJ+J+VDf/4qYV8xoPz1eAsf9KGpZ2y6hNxL7s5O8MTW1uben2yN13ajX2cNUo2ftt/TLXCHmLbE/xpJuz1BO4dvx0zAf3I+fukbPXehK9bN80562x3R8K3V+t2v0lCOlr2gOxL1IK6yNTrMJHtykdYvBTlEyOtp49YqLojq7lpw7rI6TNXridqMuuiodN5Jp2aFGf/mg+faKktPCg+nfswpyXbyLowv37U/IZ8FqG5f3mWSFW74/s+hYFm4/lu5+pji6ssC1dH0czgl5P8lkthiW1S2s0aOuietRsXvHknSBzQfDpMYrX2gKh3fznqkU7wnvkyQ6Ro5pqZfs688vJ4dd+ZAU+VO9UI7ajy+Q9ien2DM2wvZe1+sTWw/DbWfuN/ph0nXaLLH6MQU5fwKbH51vhSeYZ3O37rzZLjiucKOw6ZHZVtymaTvS9lNE9tSIqVh0XK7zKmjnXi3a1vJvqfEWmiey/fRq1YSd5v3X1Q/F2lHinbL96TmbGC9lv7k8c6SS9iPCzwTmcYnTZyLu43nLRC/MeJwkjjPm/cJ9PhPzwTxewv6r7vPBbT+SK6vbRR+CNKix3ZFET8TfBmeKh+PRiUnJdSG3l7VfJ8zzltofpalYJCrs2/GTnA+Ox0/1GqbItR8fyFhkz5tkc1P2VHt+N24p86rG6tgTTWKJuxt1i9nOcD+dDHQ8CyQNE9HGvORnOo5u0kXZ8Xag0cPc87NxoouGlA9TEu/i6Mm2dMkwKY59XzX/JmsJfezL6gl9bjmKP9I/2S9MLZPncj2uYD98ZOMN+VcU8uHJfN2sxgkojW72p7QJZP3HTJfIdL82jS7FMwpcxFPzJ+5XCyNR44oMeBMem24Nr8RjrFKjp34oPy7XeZWj0TPjLTRPVI1u3F5anC/aCs7ahfCDtR3z/Ke0DjFes/2WcalBKV2jZ/1MTRLjuDIqXGzK6+3423QIcmzPMB+I/aJqja6N98hs/8awu5Z124+igza/ccSC7XJem05GjW7Yv7QjfDIc2/nI1q8T3dTonh0/GT0fHLe7Hkffem0JvSdm6B9qbcqe/ONAYVNzt5Sm9VMdokxLWSoonRp0C2VnMnnimVbgAUVFoiizhVZcFWj0UJ+zSzYRng2xu+FhHL2rdF+jKycVTzX6SScyJte4chxIdw6h0Ul/RrJvWN06YYzhcGI/aKq+/1UaL6f7ZcZjk6b/cu5RWs8x4VRRAiGMHFdyK6B+SzlVUPES0n4KNQ4kohS2azMnjU7Xt2l0w3iLzRMqji5tL/JaovsaXfm56T6sZCc53tJxdOElKe5onlf5k0QZVzsrLlMz5ONk9Pm8636hb+ICkBrdOK+M9pfT6A77kWhw9mD76PrI/vPaxFZb6a57Gt3erxOmeUv6n6mXkXmJLp4dP4+sGt1lu2ePXRatWU6jV3h+z9vvlONY0p3txr50P8pUjT6ultHokm2qGd3S6PKzoTJPm3ePP5aeH2VEjL0YHsbRu0q6VcJrOCYlz0lP1vNrMiaHfq33cOWpthZFLJK0y27kusixXukYQWj0AuPtOml8Qj6Li/tZJo0u/VDyp76fc7ePqzlRoqNftONDW3IOo/tlBTR6kZwQ8/yRjumy8dS4kvw5TUp2RaMX0CLUuCw5Y8Z5RWt003iJ7SU27sVHcVO0Rs/RsvT+6+qHgu1I1aRzSaJ16PlZnUY3zysKalzqhFHPi/Io4qGRxxliv3Caz5b5QI2Xst91PrjuR/wme5s9G77cOv9o5uHrydmcGAGpvSSHy7kEpP2WfsWtp6Iv+THMW9v+KE3jgrkuXh0/SX86bndVXCqX4uZJFe5Bptwbsz2ux2E7GT+oBmeOG9zts2xFSXpRk0ykazmjbjHb2R8aPX29YsSHqRSPk9HZ6cxH7y7p7ZXooZPkEl9+zEt7FjNFyWXU702Ldy8mzyyanynpWKNLt/WlZ7nUXBRTboltvAXvhbk7OcJ0jz5yFDd1OHOXXNLcByOJP/V4DG/tzayyRabqh8MPk1yXO2++Em/DDFS7od8anQOj+LPQs5WG+aM8Gxc/BxkmIRjHpTzjJf02GVEjStHbY8RtTcuLQY3bpcgZOjuuZCMa7DHNK6Y9eB13vfp6yzhecVDObq/xh5J/2nK/b4zby2ank9+o7cuI+UPM/+wDdskmMI73iyOz/fHzT3p5/Kxk1G5jam9TfmbU5OeCU6VIrhr1mKzhOEPvF07bRdlf2hk/GMfrPq5c56S+ZfafhMHd85mccnU2JM/6M+O8lXO6pqYae3ubdr+Z++Xkvyk4hpq3yv4r74+1dhIPMmceWrambH8Pj5/F9mv7drc8UFvwJ9RrFcodh91zXfLOg5k7CbZODbrF9JNbwyvJRq+1g58kRzzLXik1IhtJ6SLDfufvGkaDFkfvOVg4wwkiIVUEEs6Tl87ecwLv6PSaIq84OHUYM98G0A/AB4xZRkY8nLen+/jpz7sXc+g4cdcf/NXoAxdH7w3SdRtWnSiM+YlyTuTPIuFPD6HHBQAA3aefV9M7zcdPx2dSq8W4hpGRgqs69hH+anTE0QEAAAAAwGDir0ZHHB0AAAAAAAwm/mp0xNEBAAAAAMBg4q9GRxwdAAAAAAAMJv5qdMTRAQAAAADAYOKvRkccHQAAAAAADCYlNfrT5l2xjtG5SzfmPzqjfhmuZPRhR4uMMl/j6AWWleoIv94c1NZXHwAAAAAAACdAGY0eaPBvzwppzuU4U9V4IN+PP7h0fHxmXi51x7s4eru9U6uNCY0+/HihXduoXLbKa1b7ARY2AgAAAAA4eTrNdXn7tPmdpMYj+X7hpVJaCu/i6PJax8XWYHdiR1uWPFwEQby6XwTURQV57e7G1NTmnmEN27Sp0blVti8teyZW2Cm6+q6yXHC4tnC0RkO8QEPUUfDnDRYucBC6hT3OfBY/Z2HvYfkb4czQknb6+Xm0BkRkYdR+vKyx5iJbdF9fGzlvexH11yz2KPNBskduqthKFqbtlV0TmJvEtgN7RlfnRhZ397LjkpYdjjfxkdn/YTukn23+0bbjeaJfZrafqh+WEOOS/Kxt8c7ng7JGd9rg6Gp9YmtLXVs7Z7zE8trh2uPZ/YL2P7P4jdqvO/BDzrxaW3ecJ/oC2tLNQON2LGdP9vjD12A39WuZt5Xsp8yyf7n48/KR0Q/UcYDbT+8XAIBTQ4ca/eWD5tsr8x+JPwK9vn38MQ+qa8q9FN7F0cVpeH9CVb2VYoqjK9k10gq3oSYYEcd6OdrNj/ssOomGdZgk4wpr9OAE8HBYXCSIloNm79X4aU9d67i9sH60ERpM2ckH9eh8KzyBPZu7defN9vPL/OdJg9pvk/ZDb7PpkdmWEASScwpF96N+a7o9jvVJe2QzpAWoZf+ICWM//RPbK3Js0kXSbHialyV4tCafsoB2vPks/reMy+qfbDvGfm32G+2kxiXuX4npGtQ5mI01XyXzIbPH7TTXxbio+Uz6WZ0P8n5KtGP0P+k3cr929INlXMS8cpwnCunxgdyO+uFrPZlXdnv09ql+8+Z/Z/upbb9w8iexXcj5YPEnAODU0IFG55L8m7NSokuYh55+b0pVd8C7ODo/FDYv3py/2r2MFEeNbjmmd2pJ3GBybki7k7SOprPlOGI2VJYNgto0Og+0s/u3hlcSXVVCkzmtXUzUJ+0xanRDXNDedY7IMGpcTd+I5KsZyTAmaR3K/5Zx2f2jtHNE9UvYz0g7zeOq6aHWNC5byXzIBFNzNPoR7Wdaoxv3C8L/1Han9+vqNLrR/87zRB2ysr2M25HW6OR8MB1/cvvV5201+6ll/3Lzp7NGp/0JADg1lNTooT5npAg/pXH0ruOPRs/cs5ZvB0enxmHF2rw4ek0JQNo1+uzE1tZ+/ZYu6eRzcP7tXTVuys+IdplO1LfbE5mdxtFd/Z9TP6u61DhiMY1u8r9lXHb/KO1YNavB/iOLRjeNq9ZeWH44fisVwfIT2xXMh4zATeKgFWp0Mo5O+z+z3W3zxMkPuXF9rZrzPFEINl/7Ot+PcrajSaOb7WHE8Yfol5r/1e2nlv3LxZ/k8ZOaD7Q/AQCnhpLPjP7m+NLncYqLgSo0uodx9K5DaPTo6BwGTlh8DqaO6cEJbGVYOhUtb7E0xOKQj673rsDPWONqzk+uRmfJjYiwCq3R+bVBmtstx9G/2p0Mx+Kc25DRjsXrk/bIOkDKdVH9n491exk1+vIiS6+XEpeSOQCE/+lx5ftHbceWe5B3jZHWN49L3iOkCVDZfGCOGp2wXxRefBRP6UIa3eb/7IjIeeLoB5s95nnlOE9U0vsn1HYkDjKUPYnbx605h0q8mTj+VLOfWvYvF3+6afQjmz8BAKcGd40ehtB/lAq0tywmGS8d5roMWhxdj1snD2al9zSjh5CC4/vXbFtEzvgtTqa/IVFuSr0H6qjR6Xcv8tDdm9l3mQi3bk/0zJz6nOXo3P2RXeUB2XjIq6+30mf45Oe9wmeqmPS8LHN9Ns76oBtVX3mmULLncPih9oCg3IW6KfO9bd5exL3sQHwcjLDNvUzc1FhfeWYu9f8q2zX7udAzo2k7XIJYclFcyqlxSUHi0cYUr8B/Mvy4kvmgbanG1N7mXtoRM+5fJvuVeSLtNdR+Wt//ivQ/ncNgmCdHbn4g99MwiSLrf2r+58+TmCLbMa6vPQBNzPNkINLxh+zXMm8r2U/p9p38mRxPCs430p+Q6QCcLvxdw2gQ4+h9gAgcnk9DyJU1nIai/cdwc/mk7NfuoZ8aTuu4+gXf/E/Y07XjzwnZDwAADvir0Qctjt4nRO8CQ8ymJ6SRvGJvi+sXTuu4+gXf/E/b0x/HH9/8CQDoU/zV6IijAwAAAACAwcRfjY44OgAAAAAAGEz81eiIowMAAAAAgMHEX42OODoAAAAAABhM/NXoiKMDAAAAAIDBxF+N3o9x9EJrqQAAAAAAAGClpEZ/2rwr1jFSFipSljfSljZyxs84unXV5bb/b+0FAAAAAAD+U0ajv3xw99uzQprzRUVZIsYDjf7dmfnoj07xLo7ebu/UamNCow8/XmjXNjJLbyKIDgAAAAAAOqfTXBdFlleq0b2Lo8dLfIcoy1aLrxFEBwAAAAAAldChRn/5oPn2yvxH0V+V5rp4F0cPI+Vj+xOrbD+7yDOC6AAAAAAAoCo60OihIj9LKfGXD+7+8H4nKp2Ko2vVAsl+Ys5aW29evDl/9ejxzDZr6StUI4gOAAAAAACqoaRGD/U5k58XzaCG2N3xMI5OgSA6AAAAAACokJLPjP7m+NLnGf39tHn3tx9Esp2L+OOPuxFH9+/96AiiAwAAAACAKnHX6ErSOUdOPE/eycjOGUS8E/0SR0cQHQAAAAAAVIu/axj1SRy9vbD8cFx/xwsAAAAAAADl8Vej90scHQAAAAAAgGrxV6P3SRwdAAAAAACAivFXoyOODgAAAAAABhN/NTri6AAAAAAAYDDxV6Mjjg4AAAAAAAYTfzU64ugAAAAAAGAw8Vejizh6IMrt1YRk77WxwAtePJ75jH3d+uTnBcuBn2B7AQAAACU1erJW0blL0cKiKXwZ0u/DT/LqRs6IOPry8vIvf/lLqs6vfvWrpaWlXvqvLDsLQyvjh63bJ6RCXqzNjC0+adx/t9Evq6EGMm1s90mj/m6jVvg3OwvL964vZYdIlauVmkPX9pSS6blDyMSTo70wtLUZ/zG9eqt1mtYcENNZG1c65UZXDye2vjzf+uLIfdZXh2zPu5u3i42o+G4S7IbXNrFbAQBAYcpo9ECEf3tWSHOux5mkxMNFSM92Is0Tkji6rNEDUa79OQhx9LWZhYutTtV1INO/7LyVk4Kfz5mbVOk8iL7TnHl+OZRQ7YWZoy+gJE6StfWhg9neaNMTIDsJuSBm99/NX2XqBWnwORDrJ+8H3Z79eq5MZ+53PHCHBAAAitNprksgyr87M3/lQvzHLpuf/6gSy4xx9KxGP8k4+trM0OKT8NP09DSrt1rROWxnYeiaiABOr66yreAcdPvnUeXp1cOv2Wdj/GdRFFuEtMO6aRw9rBz8eHJxMW5IfJnUjpFj4U72cI3O6s8WxS/SZig7lfZFoTBmerrx5MlmUHKfXePdxPVlU6dX37XkE/zR2sxXi8whgOau0TsKokdVTRo9iRcmJIFALfSeEyBU4sRK/UCeLr6K/SxMDR3Ge50KZBMLA5A8BMu2w5pxmDMyYDTYyotBeWpA1FfcmiPF7bnNRHnm83llvAVCpzsL68+vjyzG/owaCS2ZXp2bXNzdlMs1f+qezPgn+FMaVDiwZHIlQ2PpD137zUXXpkGnjy625q8aa/L9dDfeT+MtKOwPeuT76e6T7Ffp9hIjGp1uvAr30zq7Jk8G03h54TZrSaI8cN292rsorj/V2NzbZKo95LikORDtO1JUHhodAACK06FGf/mg+fZKIsqDv35g7PvvqSwYJ3yLowcS9DOhdoUIfhbJUP6ZyTKVpdpbiGUhWHcWFthGcn6TWxOEgljWuwd3Uq1siKO72qN9Vno32RnYs1WPRxKm5vBvw1Ymg+ZZ1M1YHJ5fm5lJmuS1tuqSTO+6Rq8kE52Ko6eNyOWSrCnYi9zOUPu6iFkGAmtrQtLWD8dT2cRlHBfEz+YO77z5TNi2tj7DbiT5ElzabgT1Q2Pq7ODiTb7h19YXDkaejV8uky7iao8S95X9097ZqV1NRGROjFxou6kojhv+eXBnSYwlEKCyvozKqfbN/snOr7hcri/Hj137dZuf9I2aUNeyRONqv+KXB0LytsP9tEZsr9Cfk/VwP91iwSjG4s1kHK9hAscWhvZMCj9kq1l+GE+nBTEnyfoAAAAIOtDombyWsODHSJt3HFOX4+iBFs9WEOUnGEdPw9NSsHlnYeb5Rus29YuZ518Yk86NGj1V5WpqCpHr4maPkuuiGZa1M5MZE1Vh3O5WKOWH7l0XsXVecUyP96sRf1dHL1/bHF09vFk4Xb+CIDrriUbPxFNTG+J4px6slX4igp1cIwpjZg+CZg+HV4JeEg3thrs92n2G9Fs5XivHral+1Tjui1RTKjo4vSSg2jf6J2NqVF9tRHxzP742cOu34KYXWDW6+ZrH+Ctqe7HYn/FMi5odNo93zKrRSXuImZ/q8mL1AQAAGCmp0UM5zrRIOS/87Qefx7r8abPJ5sqH0n2LoyskceUqNfqMXFBAo7vZ012NftXqhzIOdoijV/U6F0pbmDW6qvmKpD2kcqegRg+/UgKlUZ1Qeg5LujbWuDy74zWPs6btOOFuD6Hhgg24Mn4rjdfm5VjrAe8XprivVG5r3+CfbHfRxRsVaC/Tr33T6zkhhG3d1eg1YrxEroueH19Qc8fVtCA6g0YHAAAXSj4z+pvjS5+bYuRPm3ePPxaRdTUNxh3f8tEVDR0rVKa/oUXONHGOoy+yNI1b1uVp11Lzrva4aXT9miGW4C8ojW5/U01Xc12qCaKreRqJyOBC7eKjOByrxdFFOkGtoPKQ7FFyXYjcDEl+ZbQOrzbOttIfGjSWrNHFKzUKpae72mPWcEfq9UPsKJt3dIMjX/GcE5YmNEdd57Sf8Q89zECMrgwbJmapfkmMz4xK/abz3U2jM1vuk0mjk+Olnhkto9GFu2bZSsZaaHQAACiOu0YXGS1SgfqGxYrevOhfHF16gJJpiRzyV/EXciKKrTz5JtDEB5NsczN56vJQzxdX+3WyJ3mesxGlkm/GXRwSduqPqzZE7nnSyvV7we+SJ03Fr2iTuqjRKwmiaw8URkzdX319jZeLPOn4YUEeMq/9OhlQkZfQZR88Fe1HofRs7oTyjOZVJRE5afDNHSl7W7QgntWLXnInPenooNGd7Dmc2BLjakSpz7F/JLcEBY0ptrmX90pBIock0KAHI/znojxxsr19xT/MkNMibyx16ye5LmX6pSByQtJ+k5e6EP48jLep7h+D34aljVW7FzSSPGkqfmUcLzO9e7G4PfrjpO0oD15/igYaHQAACuPvGkan+/3oWbRclwGnsEZXcg8KlJvREhs4Uqi7cwxJESXbF4HSi263CPoZw6axUZl/HPvNYeC0KZFwP3B+AACADvBXow/UOqPSWxS1txYOKmXWMCpPtzV6dUQx8l4tc3PCpBHfAqvqhFTjH/d+czCuYXQqkV9I2tASkLCGEQAAuOCvRhdx9ECmy/8Gkl2Icrm815YCAAAAAABQJf5qdBFH1+T48vLy0tJStnxoaKjX9gIAAAAAAFAN/mp0xNEBAAAAAMBg4q9Gd4qj99pYAAAAAAAAKsNfjY44OgAAAAAAGEz81egD9V4X4BVVLVwKAAAAAFCOkho9XcjonLTgqLK8UYdLGJ3y96NbV+XsCsmSRMrqSHS5pRFlwSTPKfMOx44WLpXfPSfAy+YGB+M7FuW1gQ4ntr483/ri6CTfLKqTXauowIiKT2O8YxEAAKqhjEbnS4keR9I8kOW7bG7+ozNM/PHdmfkrFyqxzLd1RnvI2szCxVY1qjgQ2Z+Zlkqiyo0tfFmVNd2n+Hql6QA7DqKny9oTK7mA00p2knBBzO6LF+3LF4yGZa1OBN2e/XqRF8C73kHCHScAAOicTnNduqfRjXH0rEY/yTi6tNLQ9DSrt+LFhnYWhqJ1sadXV9mW0Lqi8vRquAo3/1kUfTbGrcPKwY8nFxfjhsSXSe0YOYZttie1xhAad9LoxnFxjc7qzxZFz6k51HgVO0WhGNT0dOPJE75A/X12LVx2JqovD1lf0Slc95w5BOjcNXpHQfSoqkmjS2vIRySBRi30nhOAbEdLsmfrS2u8xwuzH0nLws+zMMDJQ7xsO6wZh1EjA0aDrbwYlKcGRH017ruu2akuUG+JK/N5JVaPkn+SxHfjQmkt+vxlgIr7QbRD1w/rMOlz3vJDujYN2nl0sWVaCYtr9GA/2o33o9jDwphgE/D9aPdJ9qvUTmHk6HTjVbgf1dk1eWNR/txmLUmUB9viXu1dFNefamzubTLVHnJckk+iuS1F5aHRAQCgc0prdB5M/551MdfFtzi6rGK5eH0WyUf+mcnykqXCWIhcITR3FhbYRnLey2riUMjKOvXgTqpxDXF0yh62s7Nz9WoijtNWiH6pcmpc2mflV6bxBjZs1WOPhCk+/Nuwlcn7ofAKuxmLw/NrMzNJk7zWVl2S6V3X6JVkolNx9LQRuVySTQV7kdtJFkMNBNzWhKStH46nsozLRC5Mn80d3nnzmbBNXVp1Z2H9+UZQPzSmzg4u3uQbfm194WDk2fjlUktjyvJUGm8mrsyEzpPtUeK7fJtv1WOtPJm3Md39YK6vxLkL3w/RtyD9Q3ns2V/xqxEhedvhflQj7DyKfcIvYFggrMdis43+NEyw2MLQnkkhzbPVLD+M3b4g5gxZHwAAgCOdxtEDqf7t2RtRHF374of3O1Hpchw90OLZCqL8BOPoUoA6DRLvLMw832jdpn4x8/wLYwKJUaPLelpOKSFyXYz26KF3LXe8sEYnx6XkumgDzI43kxkTVWG8v1Yo5YfuXRexdV5xTL9vkBmB0wZbvrY5unp4s3DafwVBdNYTjZ6J16Y2xPFUPTwv/UQEU7keFcbMHgTNHg6vBL0kWtYZJZSexGXjiwFbZe0netQ2p1MnP9D1tfseBbOrnTQ6eQ2Q/RVlJ4snTzwTomaHzf4cs2p0yzWJcWamurxYfQAAAE50/l6Xlw+ab68kofT88qL4FkdXSOLBVWr0GbmggEYn7JEeRs3mjvuu0a9a/VlmQznE0at6nQulXcwaXU2DKaIFUzlVUKOHXymB2KhOKM2HpfyH+IKBR7tf8zhu2o4rahxdRHmvUhqdLGfxz/nVaP5Dlq5+sGr0CuLomdwSw0ZkXdDoNfpayJTroufHF9TccTUtiM6g0QEAoArKaPSnzbvHH0chcp7ywqKslqD8tx9EMXWe9pJUKoVv+eiKho6VJdPf0CJniDjH0RdZmn4t6/K0a6l5sz0vYu3LWJpPUjbXxTguN42uX3vEEvwFpdHtb7zpaq5LNUF0Rd+kIoYnHlx8FIertTh6nMJRTNlI9ii5LqbcFabIu4yW4tXGk4xwZtRwskYXr+wolp6uysqknUAUrgwnGzDdPmp5ipSDsSPSVOz+cfUDVb8ajc7I8bppdGbLTTJpdNKf1DOjZTS68OQsW8lYC40OAACdUy6OHiejMzUfPZTpUUK6Wl4C3+Lo0oOPTEvAkL+Kv5ATUWzlyTeBlj2YZJubydOSh3qet9ovZY+U6jLdaPAGw++ofkl7jONKGm9EqeSbsamHxHhNuTdjUivX7wW/S540Fb+iXd1FjV5JEF16qk9i6v7q62u8fCrURnFUmIfMa79OBlTkJXfZB09F+1EoXUpviELOyrOSV5VE56TBN3eEYpNaEFkl0Uv0pMc0C2v0bO7KVKQLNS/JoXHVe1Fuhhiv9Mxo3q0GVz+Y6r8o0S89W7Ljpds/jH2e8U/WzmFpULV7QSPJk6biV1l/RlfWmXcvFrdHf5w0vUOS7wcAAABO+LuG0el+P3oWLdcFVEJhjR5UXBk3pDtT5WbUYGeIFOruHMML+0q2LwKxF91uEYA8Bk6bEncYBs4PAADQBfzV6AO1zqj0FkXtbYOgM8qsYVSebmv06ohi5L1aRue0YlzD6FQivzBUnUVYwwgAAKrBX40u4uiBTJf/DSS7EOVyea8tBQAAAAAAoEr81egijq7J8eXl5aWlpWz50NBQr+0FAAAAAACgGvzV6IijAwAAAACAwcRfje4UR++1sQAAAAAAAFSGvxodcXQAAAAAADCY+KvRB+q9LqAvqGohUgAAAAAAO51o9HAlow8/lRcT5cuLikWMOl7D6HS/H926mmZHzYYrAlXQcPg6yGqaqppolJ28pDJZnqfYmpnJj0ouRJpZe6jQu/nE6+168g474zsE0zVxphqN1+MbN318Sai2jFRB71GrcrrSeTv0UlZ4pyEAAAwW5TX60+bd4w8uHR+fmb9yQZRwzX4cSfNArO+yufmPzpS2zLjOqMZJrjPaQ9ZmFi62iirJCtdC8nhZpZ2FmecbHWr0YuuPJnQYRNfWWh96OP6ugMbtVYQ+269cwi8eXq8Wsd8IX0D+ZvcWTlIumQxvrO8HcMcGAABASY0eyPFvz96Yv/Cy+V2q0WU61+gextGllYamp1m9FWvEMK4ryldX2ZbQtaJyssp9sqb9i7WZ8E8mx6ijoPXq5OJi3JD4MqkdE7VC28OF9Z361rV4Ufekk9RKpoXHjfazWKP/4teJCaLzpHpksGiNGq9ip+oEuTnRSFTeaGxuburDlVzRuH+frcgaPVwnnTkEGN01evkgemS+ptFzFzZqR0uyR46TjJVCxfFtgGih+DDszaTP59U15EeLCmu7Rk85UvqKYsBxL6mdo+H8DArVBe0Ztda9aEGUjE43Xj3ZDEZaZ9e4Q3LvfChbJHG7MGZ6Lpyfu0+Sdoxx62jlq6nG5l48D6VO0+V7RsP95YY0drWdsNPp1bnJxd14B0vuS0jbNxsah0YHAABQRqPzhJbjj3mKS/BJ1+hhAgyrINfFtzh6IBE/i9Url5XPolwL/plFSjKUkUyXxSIrY2dhgW0k53m5NUEoZBtSQwd3Uo1riKNT9ig5KnI7Ozs7V68mojlp3WK/pNEnZcEd/VYfrXm8Qf2telwnTPERdga//jIZFQ+LfyHqhK1OJlI+HqOcHJTNdem6Ru9cM6npLnlCkw/o4M7SxljU/uHC8sp4KO8C2bc1EQ9Uisdr1wDJCu1yIJnbsF8vHb+XNLek9dXV4JMYuSXuboyjm+0MN+xksKFYoGjZ/dAh6TDJbUvE0YUsFsa3w/kZt2O8JhnbnUx0vDKWYH8Jr6/COkxOB8q2EzpNvpTim5V/bu/s1OL9cX3oYFaZjNDoAAAAymj0WIZHnLt0IxsvjwLtFcXRAy2erSDKTzCOLgWi0/iuNelCkp4aRo2eqnJVwhK5LkZ76HbUkHz8A5v9UfxbVsOh3ckNBH0U2fEqSlypYtHohnKtZdWMUtvSSaN3GkRn2Tj61jNLSnoixfQPtV/PPLrYkgLwO82Z55eVOK4gCs1m4tYFM/DtWlDT+qnmVvR6kvOvd2rQ6JSdQfk2a4WSWtx5eFFIoyf9qiFq9XLCPl7immdnYf25JRHfqNFl/Z02qw65UYdGBwAAoNDZe10McfSElw+ab690EEr3LY6ukMaDK9ToSvJ3AY1utIdqR3lIVWo8R6MfTDY2N5mScCKLY22Ap1SjVyKYNHFp15rlNHoJTek6ZMl/0sVJ3B2ZaK7m35uqEXaW1OjEhVNvNLqSEB83u5PcGDFOBmh0AAAAVWp0/hTpx9FbXnisnSmvfHHFt3x0RfsGivfe9TgQLb+hRc4ccY6jL7I0Yi3r8rRrqXnKHqWdJNdFFrVyNonV/qiLQ2VMcr9KHgsxXvWaIb0kSD2g5swQ2l0aoZrbE9LVXJcKguhM12GKRDMQa9NEkyVST9V8qWSkcl3KvWkkowVVgwPz1EsFLrtn2YqS9KImmUj59+lX7SiD5Splp3caXbNTn0fmXBeWyfNJxsVYms8DjQ4AAECivEZPMl6kXBcpC+bU5aNLDz4y9dFN5as0hyRNRLGVJ98EWvZgkm1uRg1NZ/O81X6N9ohM7UYjaSdtRkp1iSo0Ui2etT/Na7/4ZfKI6GEiqaVHVdOrB9N4qRwbuTx99jR+3jSsxqImo36V1J7wqdI0CaeLGr2qILr67sX8N+iZc1eYOUciqdyIUrc35Z+oryMsl+uiJJAY3h0pqW2BrdP0ccmG7Se3xlfESKfuv6vdC36SPPHZoDed1IhspGZ/kluilwuTxgr7097O1fCC5GCEbe7F+3XciLR9pxtTvELYFNkOsV0AAACcWvxdw8i3OHq38fhFhyTZuwH9QmGNTgW88wLhFeHPuxdzoEPUA061L3+ERgcAgMHBX40+UOuMSm9R7GhpHlhbkFJrGJ0sSrz8pM00rmFkJH0RYebBR2B+E05JsIYRAAAMFv5qdBFHD2S6/G8g2YUol8t7bSkAAAAAAABV4q9GF3F0TY4vLy8vLS1ly3ttLAAAAAAAAJXhr0ZHHB0AAAAAAAwm/mp0xNEBAAAAAMBg4q9GRxwdAAAAAAAMJv5qdMTRAQAAAADAYNKJRg9XLPowu5goVe7GgMbRxUvvTuoldmIdIWVBptK0m8tbe2yqfmv44Ve7r0bnbt38pMsvD/eYwBkPh7vpgaPH61+9mV2az58l1W2X8OV/o6uHN/vwhfgAAABAn1Feoz9t3j3+4NLx8Zn5KxeKlLsymHF0lzXqnVmbWbjY0tV4INO/zJaWgKvGXRZIwPOPAlE4VS+iH914vN48f7PyVntPd8dV6Xbp6vwEAAAAQEJJjf7ywd1vz96Yv/Cy+Z2ixanyEgxmHL2gBgpXEZpeXZ1cXBQLh0+vHsbLfe4sDMWriaelImAutZDEzrlGZ/Vni+JbLaQerqPDii2aEmrBkUACsuby1ms5XCsiuZzRuTm2z27crLWDuq+EXhTfyvHdx+vLu9HKL6OjbOLmzU9E46+k3mStmdYXxaLy6OjUq1c8gFxnW7z7fHVq6JewP7BUVA7MvsG2Q9Oi9hNLMyMKfjyyuxs3JL60jivHSLUL0n56u5QAGh0AAAA4Gcpo9LdPm9vHH/NUluCTpMWp8nIgjm4nlOmxpOYS/OCO+Lyzs3P16tW4Tlwq/jTH0ccWmRDzwWe+0niayuCi0ZP8DqakYXCByyLhmYR0A5kYfH6URI/bzfWjy0I8BuXbQgWL376eW4q1sjHeHAjT/YlYeIYmLMWaPhamvPthuTsTVL+U/fHY+OUFr9luNtl80r7cWmJnfFWiZ6qUjKNLTrP6zbxdygGNDgAAAJwMZTR6mG+e/nnu0o35j85YyssxgHF0p3xfTX+nKStqyFwOjOfnuuwszDz/olVlujEXkvOxyJahNLocttbCygYte6RL76glxhXrzVA6L7drIrb+KEcIG/sl7c+YrY8uq9FlgSzbU4lGt/itSnaaQ9f22Ek9LwEAAAAMLJ2914WKlyOOXhaXOPqMHPKOpfbOwtDKuJThIuea94lGV34dxcVDuqzRjf1WqNHX5YIuaHTSbxWCODoAAABwMvir0Qcwjs5cc13Y6rvW7fjPUH+H2SotURgG1CeVOHos63nOOhPfWDW6U66LGfUNJ2nmSKpi1QwSRcvGCls0lX4lJaCo2jeW1EfOGp3ql7I/7s0hjh4M0ni9YRxX0t0eFRRXe7f4zcKLtfUw06noq1qo+enaDgAAAADslNfoSWaLltNClbuCOLqdQHAfTLLNzSirJXk8VEp1mW40eIU03SV9nLSRCHRRmf/Nom+l508r0OhMfcwx1Zvp45LRw5TiCUi5sp6zkWZzSOXqY5dTIvdclAR/1NrBT5InOy0pIJZ+TfbLiSW28uSbQEO/GWF7e1FDo+aHajUDnTQ67Tca17g4VR/xdQAAAKBa/F3DCHF0O1quC/AcLdelc7KhenfaC0MPx12C38H8XBm/1bp9vsN2AAAAAGDHX40+mHH0gmsYhS91CT9Np+kuwFuktyLOdZYmLsXpO20qfAD0Xs0tiL45df/d/NXO2gEAAABALv5q9MGMowMAAAAAAOCvRh/QODroHpkFg2K69qZCAAAAAIBS+KvREUcHAAAAAACDib8aHXF0AAAAAAAwmPir0RFHBwAAAAAAg4m/Gh1xdABAN6BeW1nF6yzBydHv26vf7e828A8AnWj0cLWiDz/9/MqFqODt0+b2Nz9Gf8hflGFA4+jF3r2YkK5KlKxL1EvCNwNm3gmYvi9wdO7WxP6j8zcvH63bVxTqpn2RIWJVI/FH7ksM1dVGOckDqMpqRB0YprXvA/rapeF6SreGHwYDt49aOMfXR3GpVVgLr8564njrT3nJril1gdyu7i9xJ55ur6rsj46n3h0Y7AZHn+3zwck/9uN29vwS/EZd0y0xiBnfXXsyfjba2Ss/E/6pdWE/rQJu1pvZTnZ26vyVLEnu2lbhdx+H7yweLb0Id3mN/rR59/iDS8fHZ+avXIiKAo3+nfRnZwxmHN1tvcYXazOfsZZP70fXVrxn6vL2stQIPndykCqNujon/2s+tvbxetPVor6O9OSMV5MQ4cZjwaHt/KPgAJWrF3u1fXPp0yC6j/50P71V6OTuba8Sx4ES7RS0v8K1z6oaF0kZuWNv7IZypDYdt6nziz5eef8Jm54d2Zca7LqfLXb2ys+kf7p8MOz6PDRCn79KXOtndY6dTtbhLqnRXz64++3ZG/MXXiqivFKNPphx9OLbUo6gc8LFjALRPrb4RATURYXp1cPW7Z9H5Y3G5qb4jRJzT5uaXl1lW9LypUdrM18tsrnD1icFrwD53B2pK8KOUBb8GzbxeldczKe7jLi+l+Il+lcsqS8OdaOjU69e8QvkOtvisYUp5UAoqishE9OxPvNaxqRXe1zBeCyTViwaHWUT9oOpoX16XEe85dG5uZHd3SQgI59mVP9Y/EmPVx6FErgIfzIShaJey/3K8aE5ti/80avtK1lkPAkWCqLLJ1HRluxo8/Yl7LGMl8I/f1qNVH/ivL/Q/Vr3I8N2NPqNmfaLaPtOTe3t7SnT37JfmOws0w5lv7I6mTzZ1tnsxP5WHDq27u/kvLXaU4HfyswHKTgeHtDUCrp/yOM2feUqtOBwZspFP2JKi931c46dvfEz5R+W2U9tx8OK9wuLc/Sh6ceHGyz3+GY8f9HXPNljv9T1iMM11klrdJ7Scvwxz2TRRHmluS6Io+djiqMHZV9ebEUCfGdh5vkXQnGHMn1SSPPwd5ES5wKdRYo9rMNCVS8ac9bo+r029cgqk1zWiiObcpiIdw2+w7ebTTYv7l3uT8Qth90sxdo63vF4mGI4PhjKcRFea38ivjFaJo5ePPgql7TDo0GRq229Hdu4ltMQjHQH0Owf2p8sJ56R1UDxtmXKbcdMfIhJZ6sebF+pA8Px32k7pmdVadJQ29dmD+F/yu/++dM2a42XoMX9TPVr34+y7VB+o/aLxBO1TGvG/cJip1M7pH/a7XatllxcJTvYY3FZLkZQYH+n5i0rGt8t7zen+ZCOUe7Vtn1Nx236/MIkDZfRdsIP2sG/m36m7eyhnyn/MJfjYbX7hQ3Vh+bjA318o85f8U5gTBEiNbpr7tZJa/QwDz3989ylG/MfnTFU+uH9TlT6AMbRnfOWHDW6qZx/2uhetoxVo1PHOMOvMnGIqAqLj1axpIwqDmeXK4oUW7c1Op0raIM8Cmvjqunh7XS8Rv+cz/6RYjtWFs3/Uxzow/bNsbZwJjptv2n7HlntsSqJPvZn5xrd5jfLfmS6gDT67YjcL9w0Fm2nqyYm7Ne7kBI23PZ3R3uq9JvDfFBrZmaL8SZJCY1uihNLbcvddNfPlJ099XPxODqj5nnF+4UV3YfEcZg4b9rRbxpXzk5z6NoeK/ycoUxn73WxJbe8fNB8e2X+o9KDQhw9H/81uvVo0kXNUSO1jtK2al5FGl3pTIln5/ipoEZf1yoOokant6+Dk63lNvsN29dqj/8avZQ/q4ijF+tX3Y/MF8Zd1eiltgu1fxEX9mlgTm7TdX/vR41uCZFmDVB+bs3MJu8byLkisbrrrp8pO3vqZ6fzHWFPlftFDpajqHyf0EuN3oN89AhVoz9t3v3tB1FMPc2HKcsAxtFZRRo9ymNRM1co7b6zMLQynmS3yJkvrESuSxb1rlB6Z9VNc+jHUCkfkdgnqbtRsvjUhGjahXwDOP5ViXv3hqTKgjkY1ji6/LRKcrwz+4f2p328xR+k8W370n52e51LukXUe8TU9rXZ46DR/fQnQRW5LlS/9H5k3l6U36j9wqohDPuF5Xji1A4ZRE88KWcJaE+nKTkY5LiM87bYuDrym2MORtq+ku9B74/G4zZlPyt2TSIdPwfNz84a3Tje6vYLZn2OiG5EnjIlNToxCDmHsDMoXfdibT3UaLbUifIaPcl4kXNdApkeJaSfu/R5B0F0hjh6HmszQ4tPpL+Tp0DF86H80/Tq6uTi4ub06uHX7DNRxmux6BHR6Vi+y02pL3CsQKMz9bGP5KUu4haZ/DqsMO3rDRHmMN0LHpZaqbXF27PEk3NT0eFPfr2U6bEbbfdLvzDecJfbocrJTqUOzM9rpT8Rb4cixjX8cP3NCNvbS57SMT27k3bcJv1pHq+y1QqGFnzbvsZjvfOdkNQe5Vkry/Y1fWX1f9/4M8dIqbrz/kL4jTTGcucq6zezH2z+jNOCTftF1qRh93Ys8zA2c3Rqiu/gyVYSf4qvUilI5MZQ87bguEr7zXE+qAPmj/zdyD7voUEdt432S4VylrmcgJ0+TDk6+urVq8Hys8E/qul0O9lnTyvYL6TeC2r0zPHhKOf4RkJc84TWVPPCW0rXFdF7/q5hhDg6AFkqfEdYDv3++ml9MNRTQR6+mB5Q9Pv26nf7u4Kky+GfLpKTmek33TOeONFVORUDXbcyfqt1Ww/ULww9HM97/tBfjT6YcXTXNYzAQCG9baqCG3AFujup6wEAwIBxwkezgaWf/ay8kbQrxlsfaaiE8F0gU/ffzV/Vv2gO3avlKj1/NfpgxtEBAAAAAADwV6N7GEf/3Yvvf/LvjQ79k3/Sa98AAPoWwwvLBNXkPg6cnQAAcErxV6N7GEf/3f/+/G9+8V++9y/++c/+9NP3/viPAr3eaycBAAAAAIBTiL8a3cM4esD//d//+f/3v/yv4vPv/ceTgVL/2Z/+8U//o4u99hYAAAAAADg9+KvRPYyjB7w7fvv2X8y++7v/Ry78yT/993/2J5++98dz7/3zf8Z++tNeew4AAAAAAPQ3/mp0P+PoAf/v5v/8dyv/k/GroX/n3/7ZH11570/+6L0rs0O///u9diEAwEDJVWOBZ/T79up3+/sF+Bn0L51o9HAVow8/1RcTTRY3YtnvHPAzjs75+9+9/Zd/8g//11/nWP/JtAiu/2R42KFxx3cv7kTrEXHU5Yd6QvimpMw7kuS1J25N7D86f/Py0Xr+ygLdsi8yRKxuIP7IfalT9l2pyQN18goQnRjm4WuB9bXcwvUlxApL9lEL5/j6aKHbgqM+4K0/5SVPtEWkurq/xJ14ur0Gw/5qXND9457s5+6/y890vqt2G5c4n5baH81nczPakt2lR5U9v5R5N6KL5dG7EUdX895T3ivKa/SnzbvHH1w6Pj4zf+VCUvj2aXP7m7OdSPMEb+PoAf9m9+G//m/+20JVf/ITnrb+p58Gev2nY/lTwG0NoxdrM5+xVuv2CQ/fgrZSPVOX+5WlRrFFeqtHXa1MWRrasjYyRV9HaHLGq0mIZAno84+KLL/Wq+2bS58G0X30p/vps0Ind297lTgOlGjHf/t9o9y4DH4Oi2ZH9qUTQWX9Uue7qqj2fJo3CZXzY3ehzy8lrmWzOsSOz2tHltToLx/c/fbsjfkLL5vfSRo9UOi7bH7+o0os8zeOHvKv/6v/+t88+VdOP/nphf+Qi/U//qPfu/RxoN2NdYrPFTmCzplefde6HYj2scUnIqAuKkyvHrZu/zwqbzQ2N8VvlJh72tT06irbYl+34gvKo7WZrxbZ3GHrk4JXmHzfGKkrwo44cvBv2MTrXRHK1hcGl+LcxjXDpbV/R0enXr3iF+B1tsXDC4Y1kOWQiVmjZ14zl/RqjzcYj3HSmhF88WW7iDG0T4/riLccLcUcDUwySvePxZ/0eOVRKIGR8Ccj0drOr+V+5bjOHNsX/ujV9pUsMp4cCwXR5ZOfaEt2tHn7EvZYxkvhnz+tRqo/cd5f6H6t+5FhOxr9xkz7RbR9p6b29tQ1yS37hcnOMu242F9rO85Da79u84GG2i5G/1Pz0zhPHlPHt4LjKjZPopMSS88E5P7u5E+WcyWdrZ83XtWKYNbdYK7n0072Rz4nHuZodGlQehf6dgmMzzv+GM8vdCwgu09IXY84XBudNo3Og+XHH/NYefBJ1ugvHzR/YOz773/kf5y7dGP+ozPlLSsdR//7b5/+3f+4/Lv/86/L9lyMf/iHd3/7t+V+OnTu7M8+neNp65f/06F//I/lrzqPowdlX15sRQJ8Z2Hm+RdCcYcyfVJI8/B3kRLnAp1Fij2sw0JVLxpz1uj6PTVVEcskl83iGKQcKeJdj58I281mcN1X43vd/kTcctjNUnxOindsHl4Yjg+Scp4Gr7U/IU6r5eLoxYOvckk7PNoUuZrX27GNazkNzUh3GM3+of3JcuJD2XNbvG2ZclszE9dh0nmlB9tX6sCgNpy2Y3o2bCunc+P2tdlD+J/yu3/+tM1a4yVocT9T/dr3o2w7lN+o/SLxRC3TmnG/sNjp1I6r/a7zkLbfbT5Yt7mhX8p++/w3zQfz8Y0al+s8kdpRDv6Un938SZ/vqHlIjtdoQ7nzqcP+KJ/A3TJGNIPN28U238znl4xVapeERnfNoTptGj1NOA9JxHiY6PJj9GfHMfXScfS/+c/+i98dtHvt2EIM/aN/9HufzPzsTz8NJPvQv3vOOS/KUaObyvmnje5ly1iPKdQx0fCrTHwiqsJilRBLyqjicHb5leg42G2NTufo2jBodOO4anp4Ox2v0T/ns3+k2DR60fxC8mZor7ZvjrWFM9Fp+03b98hqD70X9Lc/O9foNr9Z9iPTBaTRb0fkfuGmyWg7XbWdm/2u89Biv9N8sG14Y7/WpAjrWSCr0Q3HN1tMwWmeKGXy187zwejPN8RI6XlYaLxJ7XLn0+L7o/ZDp2Q2vVPiOOk83wyzonp2mkPX9ljh5wBPks7e66LG0blG/+0Hn8e6/GlwwTxXPpReOo7+N3/6n/+u/X/02rHF+OlP3vtP/tl7fzz3sz/59Cf/wT9lXY6j90CjW8/iXdQcNfKcobStmleRRlc6U+LZOX4qqNHXtYqDqNFrZRIlnTai/ZyX2b4lNUpf+7OKOHqxftX9yHxh3FWNXmq7UPuXg/3O85Dot0qNbuy3Qo1uOr7l3/cz+ME4CfUcLWOWSmmNzog9wqbRyfEmlVIDyp1Pe6PRTdvFV41+2uLoKVqui3iQ9GPxxOjLB823V3oRR//7/+2bv/3v/oec9670lKF/6/ffm/3kvT/59Gdz/3LorHIRU4lGj/JY/v/27ia0jfSO4/goiZNrktoxvTlvBTvrrpP6svYmRk4dk0ChCONDoWyhITb4EN96CWwN6akX+1BQginsqWDMsKf4ZuO63lNITLNZQWKI21tqEzksu7TsBnfeNPPMaJ6RZkaynrG+n0OQHo1Ho2f08st/nnnGP3JFlt1XpnIP+9zRLeLIFy3BWJdq/qNO3hHReJkj+N0tjCOXfOZlR7vE8BkIot5TiAduK3+V4Nh9VR2n7jEYkXV08WwY9+s7vH/k/Rn9eus/UUe1/Svv53jTuXh7xH/kXrZ/o7YnRkZXsz8lGjHWRfa88s9R+P6S9ZvscxGZyUI+FxHfJ7HWE3f7474PZc8b9/0gU9/73/+FErOOHvr9Vtfrqv0+Cf5fwl2/rJ/j9Wf892HE63XujmjrviO/8b8f4o118fWgf+xQxHk+8je/uNaEGV3y4RPHUKUjy13bC0UrQ7VyypfkGd0d8eIfeN6gmRfVntfF8O1vfvfDP76K9SfHOjs7xvInb42d+PST3KlTocvUn9EXhnOz4vO7Z4Ha54eat4bm5z+anX08NP/6C+0zu81cSnNOER2qxHdxVf4JHBuQ0TX/aSXuSej2oeN+Z2iaWdmwhpXtSsocwcPN/fZYNnctvSVr7JxzZlK/87U4Jxyf7p8Uv3oqp+j4Pt7eA6EH3MX1yNqlTyo8QeCc9ar12LNPSV5X13px95z24oV79pr/TNPgE5ek/Rn+en17rc7ShWr7N/S3JPaREG97nJO67K6O2L9hD0X2f2b6s8ZGCovH/rxI+k26MRFHrqr7LbwfovqzMlw47HNRvUld8deTYvvrfR+Gb3/890Md+13aP7W+fyK+PyXfb5LXFeN9IvakuVZxJl57GHRIP8foz0pH1P8+1KJfrxZaPUn1/VD78+gbomKdDe39SsbK6FX7ZS/J+83dl9W1AGtrGjNrjix3qVBfV/caRirP6/LD+sa3v/19nQsfv3SxY+zmyVs3T1wb0HK56IVVeE9AZYFjo010pKZvjjjrSMGJ6SGT9f2V9e1vugZ9v2Wmn2u83jiH4FqreXOJSn6IGrmLjdz1sG9m836wUD+VW+9r9bzp6mZ0devoP354nx//8K9/Ry2Ty534xdWT42MdY6PHL5yPsfKY1zBCWxFms2rWBTj8T3dY/x8A0PYO+fut5SJeb5KZB1qg+deEin8RhrisuTr6nxwUbgcf0HNf9rY8iamb0ZWto//3r198/8c/hT6UO3Wq48anHbdu2vO0tLoLAQAAkEnqZnQ16+gH++/3Pxk5+O57sfHYT8523Myb852PXJcNNAcAU8hEfjbF6mVZ2U40FvsdUIa6GV3NOvp3f3jwv78t2bed64aOj524+rF2/HirOwwAAABHhLoZXcE6+odXr9+P/+rExz83ZzQfHzt+6WKrOwkAAABHkLoZXcE6+o///PrYT7uPdXW1um8AAABwlKmb0RWsowMAAACHIE1Gty5XJFypaEtffPrOe9h/baPYlKujr+i5O9YsQ0yMCAAAgGZKntGNRF6+MFguny7keyota+6d/S19VRtNk9HVrKNzjSEAAAA0W8KMvrO2+OzMRKFnR3/uZXSRmNeTUa6ObiGjAwAAoNmSZPT9LX25fM0c4mLcCs3osvY4qKMDAACgPSXJ6NY4dO9u9bjzRkR0aR09sJgR2Q+zv8joAAAAaLZ087pIwnj6gS4adXQAAAC0qyZk9IZU0bM2Hn17oXh5Vpt/PX3/0mFuDgAAAI6g5BndHfESGOvSoIiesTo69XUAAAA0irrXMMpUHb00lVvvo4gOAACARlA3oytXR4+4hpHx0Je9FNEBAADQEOpmdDXr6AAAAECzqZvRlaujAwAAAIdC3YxOHR0AAADtSd2MTh0dAAAA7UndjE4dHQAAAO1J3Yyuch19e6P4mTaxeb2z1Z0EHBmlqbnSrz8v3Na0hWJRm5i+z8cLRxq/IwCipcno1lWMLv7ybr7H32Td8rcnoHAd3QsTLuPb9s+d09WzL8raZeKuh3ba/Uorpd7bNd9vJT23ZE4kem/y80eacLul04caL+ry6lvzVv/kQaFJmxLeP6rtR9qz1S4TuXzI7wgAiJJn9C19sXxhsFz2rim6v6Uvl6/Z0dwI62/Op0rpytbRg8WPUmmlt/ey/V3ctTFV6n1kPyRrl4m7Htppr3pfrehzd/4zejB9vZ63sZcejMhe6m1aLFZISP+oth9pz1a7TK3lKaIDqClhRjci+LMzE4WeHf25L6O794zbq9poYeB04i1TtY5eVfyolCQt3fMzlWP0snbpimOuh3baA++rvY3hv6x+VV9FXJrRhfUPjc5sBv4DYD/SPTqvvbSGoxgfh6XHvhWbm6Qtz82+7Z4fPTe7+qJ6OxeKxqP2zf4nzuAWu8W56zxR/+TBjT37FVmVdc16Lnf9YctH/zcjtH9U24+0Z6tdpsbyFNEB1JYko3v1cjGVm7yhLtrZwbuFgTRbpmYdPbT4YR6jf3mlklpqt0esPNZ6aKddbBczdM1SujewxOLFcav+Z0cHIzp/M+LEWXPlmhOCrb/VrNhRmiruPZq+7n4u3KHkVux2MrQVjncfVOL40hX3ufTcepe9qe4fWq9OGzo3smkHbuNv/965aQX0r0dnHuwuv7phr1+yvJysf1Tbj7Rnq10mYnmK6ADqkSSjC0ncdHZwwqmX76ytafl8j3lzf2ttpyefooyuZh09vPixUNR/Nl24bYSJZW1T+O2XtcvEXQ/ttHvtlSKxrWYpPVBHH9674SSG8PU4WbxqNVEZ3c333tN12YHb27IVvejL3Lt6bkl7MtP10F2ssj2Bor50eRl5/6i1H2nPWruMfHmK6ADqkm5eF38dfWdN379aGd7iu5OEgnV0ih9QllckttUqpUsyupEe1vsqx+WFZWQZ3Vtb4KMRmJulrow+cmVp6eWk8eyasJhTR+/1FeA1+fIN6h+gSfgdAVCnRmZ0373UGV29OjrFD6jKXyS2RZfSwzO6WPOz1vnRpDfW5WGXG5HNYejapK9MXpXR52Y1Lwc7NcVgdveivz0k3SmW74VkdHElUcs3qH+A5uB3BEC9kmd0d8SLN9bFNwom7eSLqtXRKX5AWcJZmAJ5qdgdjC7OvWjnXWGceve9fu3xi7dulhWfxQu4kjEkRhb/5pz553a7N1IlbHlnzfZJn+4CwXNGe53z8MwzVlfDl5fE9Lj9AzQJvyMA6qfuNYwUq6P7xgAAiMZ1iIAq/I4AiEHdjK5aHR1Anby6NbVqAAASUTejK1ZHBwAAAA6JuhmdOjoAAADak7oZnTo6AAAA2pO6GZ06OgAAANqTuhmdOjoAAADak7oZnTo6AAAA2lOajG5dsch/qSLvIkZpL2GUpI6+MjV353H3/Ovp+5da3a8AAABAUskz+pa+WL4wWC6fLuR7nCYjoT87c7cwULnpXn80iWR1dDOma5MHXOMbAAAAmZUwozsRvGdHf+5l9P0t8d7Omr6ft/J6MsnGo0sz+vbG8OVVbX5mkyu8AQAAQG1JMrqRxZfL18yhLP5ULtbRzWWenkkz3qXBdXQyOgAAADIiSUb3Bp1bzg56Y1qsaP7Obh3UxHEwscnq6IHFjMjuu7+i5+680O4x3AUAAABZlW5el0Ad3SftWJfQOrrsX/evGI8OAACArGtWRt9ZW3xzPtXMLqF19OiArskz+vZC8fLsuScHhduH3cMAAABAPMkzujvixRvrIg6CST33YkPr6KWp3HofczICAAAgC9S9hlHiOvrDvqoTQ1f04Vc3OFsUAAAAmaBuRk9QR7euYdTPgBYAAABkmroZPVkdHQAAAMg6dTN6svHoAAAAQNapm9GpowMAAKA9qZvRqaMDAACgPamb0amjAwAAoD2pm9GpowMAAKA9Jcro+1v68tN3zh3fxYq8R1Jfw4g6OgAAANpT0oz+/HQh3xNs31lbfHbmbmHAvvnmfKqUTh0dAAAA7en/BF0at09HDNAAAAAASUVORK5CYII= |
kokoss > 13-01-2022 23:41:13 |
Dumby скрытый текст Выделить код Код:(async () => { // загрузка внешних js или jsm-скриптов var loadscript = name => { try { name.split('.').pop().split("?")[0].split("#")[0].toLowerCase() != "jsm" ? Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${name}`,globalThis,"UTF-8") : ChromeUtils.import(`chrome://user_chrome_files/content/custom_scripts/${name}`); return true; } catch(e) {} }; loadscript("/AutoCopyChild.jsm"); loadscript("/ucf-cbbtn-BBCode-Multi.js"); })(); код взял у dobrov |
Dumby > 14-01-2022 00:31:28 |
kokoss пишет
Ну да, можно и так. Но это мелочи, удивительно другое: То есть, например, адрес вида |
Dobrov > 14-01-2022 02:36:03 |
shadow_user пишет
А первый пост видели? Именно для начинающих в начале темы есть готовый Демо-профиль, в котором все нужные опции включены и имеется минимально-необходимый набор скриптов. kokoss пишет
kokoss — Вот более новый вариант загрузчика js/jsm скриптов для custom_script_win.js: Выделить код Код:var loadscript = (js, win = this, init) => { try { if (/\.jsm$/i.test(js)) { // скрипт js или jsm [инициализация] var obj = ChromeUtils.import('chrome://user_chrome_files/content/custom_scripts/'+ js, win); init && obj[init](); } else Services.scriptloader.loadSubScript('chrome://user_chrome_files/content/custom_scripts/'+ js, win); return true; } catch(e) {} return false; } ……………… // подключить внешние скрипты - сначала глобальные функции var jscripts = [["ucf_global_win.js", globalThis], ["ucf_mousedrag.js"], ["ucf_BookmarkDir.js"], ["ucf_hookClicks.js"], ["ucf_autohidetabstoolbar.js"], ["ucf_LocationBarEnhancer.js"], ["ucf_contextsearch.js"], ["ClickPicSave.jsm"], ["UCFTitleChangedChild.jsm", this, "registerUCFTitleChanged"]]; for (i = 0; i < jscripts.length; i++) loadscript(jscripts[i][0], jscripts[i][1], jscripts[i][2]); |
_zt > 14-01-2022 12:35:18 |
Dobrov |
shadow_user > 14-01-2022 21:53:00 |
sandro79 |
sandro79 > 14-01-2022 22:27:42 |
shadow_user пишет
Это скрипт contextmenuopenwith.js
Да, я тоже уже об этом задумывался, но своими силами добавить индикацию конечно не смогу. Не знаю, может Dumby попросить добавить, если можно. |
Dumby > 15-01-2022 00:41:33 |
sandro79 пишет
Несколько раз перечитал эти три слова, |
shadow_user > 15-01-2022 09:22:27 |
Dumby пишет
Слева отжата, звук включен, справа нажата, звук выключен, или вместо перечеркивания иконка меняет цвет на красный. Так будет визуально видно положение кнопки отжата\нажата. |
Dumby > 15-01-2022 10:31:14 |
shadow_user пишет
Звук в(ы)ключен где?
То есть будет видно, нажата кнопка чётное количество раз, или нечётное. |
shadow_user > 15-01-2022 17:12:23 |
Dumby пишет
Кнопка управляет звуком активной вкладки, если несколько вкладок, то для каждой вкладки кнопку можно применить индивидуально, в одной вкладке звук включен (белая иконка), в другой можно выключить (перечеркнутая или красная иконка). |
Dumby > 15-01-2022 20:59:29 |
shadow_user пишет
Управляет, но не монопольно же. Звук может быть переключён как угодно, Ладно, вместо «добавить в этот скрипт индикацию активности кнопки», скрытый текст Выделить код Код:(async self => CustomizableUI.createWidget(self = { label: "Переключить звук", tooltiptext: "ЛКМ: Переключить звук в выделенных вкладках\n" + //"СКМ: Закрыть другие вкладки с источником звука\n" + "СКМ: Закрыть другие вкладки «ВОСПРОИЗВОДИТСЯ» и «БЕЗ ЗВУКА»\n" + "ПКМ: Переключить звук во всех вкладках", imgs: [ "url(chrome://global/skin/media/audio.svg)", "url(chrome://global/skin/media/audio-muted.svg)" ], id: "b-sound-muted-all-tabs", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { btn.onclick = this.click; btn.toggleAttribute("context"); var win = btn.ownerGlobal, gb = win.gBrowser; btn.muted = gb.selectedTab.muted; this.setImg(btn); var tc = gb.tabContainer; var args = ["TabAttrModified", e => this.tam(e, btn)]; tc.addEventListener(...args); win.addEventListener("unload", () => tc.removeEventListener(...args) , {once: true}); }, setImg: btn => btn.style.setProperty( "list-style-image", self.imgs[+btn.muted], "important" ), tam(e, btn) { if (e.target.selected) { var arr = e.detail.changed; if (arr.includes("selected") || arr.includes("muted")) btn.muted ^ (btn.muted = e.target.muted) && this.setImg(btn); } }, click(e) { var gb = this.ownerGlobal.gBrowser; if (e.button == 0) gb.toggleMuteAudioOnMultiSelectedTabs(gb.selectedTab); else if (e.button == 1) gb.visibleTabs.filter(self.f1).forEach(gb.removeTab, gb); else if (e.button == 2) for(var tab of gb.selectedTab.activeMediaBlocked ? gb.visibleTabs.filter(self.f2) : gb.visibleTabs.filter(self.f3, gb.selectedTab.linkedBrowser.audioMuted) ) tab.toggleMuteAudio(); }, f1: tab => !tab.selected && (tab.muted || tab.soundPlaying), f2: tab => tab.activeMediaBlocked || tab.linkedBrowser.audioMuted, f3(tab) { return tab.linkedBrowser.audioMuted == this && !tab.activeMediaBlocked || tab.activeMediaBlocked && this } }))(); |
Dobrov > 16-01-2022 04:13:46 |
Как в скрипте Контекстный поиск переместить меню «Искать в…» выше? (например перед строкой «Добавить в Заладки») _zt пишет
Как это происходит? Мне не удалось воспроизвести: «как минимум ломает стили окна», но всё-же поправил код в своём сообщении. |
Dumby > 16-01-2022 09:02:45 |
Dobrov пишет
скрытый текст Выделить код Код:… //searchSelect.before(menu); document.getElementById("context-bookmarklink").before(menu);
Уж не знаю что поправил, но запятая в конце первой части кода всё ещё торчит. |
shadow_user > 16-01-2022 09:03:57 |
Dumby пишет
Спасибо, самое оно! |
_zt > 16-01-2022 10:19:22 |
Dobrov пишет
Будет явно заметно с VitaliyVstyle full_theme + Windows 7, но уверен, что и на 10-11 имеется смещение рамки окна. Что приведет к ошибкам при правке стилей. |
Dobrov > 16-01-2022 14:09:18 |
Dumby - спасибо за помощь с меню поиска! _zt - не знаю, на каком custom_script_win.js вы проверяете, но я брал загрузчик от Виталия, где фрагмент кода var loadscript также завершался запятой! Выделить код Код:// Загрузчик для custom_script_win.js https://forum.mozilla-russia.org/viewtopic.php?pid=788301#p788301 var loadscript = (js, win = this, init) => { try { if (/\.jsm$/i.test(js)) { // скрипт js или jsm [инициализация] var obj = ChromeUtils.import('chrome://user_chrome_files/content/custom_scripts/'+ js, win); init && obj[init](); } else Services.scriptloader.loadSubScript('chrome://user_chrome_files/content/custom_scripts/'+ js, win); return true; } catch(e) {} return false; }, load_scripts_by_url = { browser: win => { //>>>>>>>>>>| Этот блок требуется для боковой панели и др., очистите строку ниже если он нужен |>>>>>>>>>> /* var box = document.querySelector("#browser") || window; var listener = e => { var doc = e.target || ({}); load_scripts_by_url[doc.documentURI]?.(doc.defaultView); }; box.addEventListener("pageshow", listener); this.loadscriptswinandsidebar = { destructor() { box.removeEventListener("pageshow", listener); } }; this.unloadlisteners.push("loadscriptswinandsidebar"); /* <<<<<<<<<<<<<<<<<<<< */ setTimeout(() => { //>>>>>>>>>>| Загрузка скриптов для browser.xhtml |>>>>>>>>>> // подключить внешние скрипты - сначала глобальные функции var jscripts = [["ucf_global_win.js", globalThis], ["ucf_win_contextmenuopenwith.js"], ["ucf_mousedrag.js"], ["ucf_QuickToggle.js"], ["ucf_BookmarkDir.js"], ["ucf_hookClicks.js"], ["ucf_autohidetabstoolbar.js"], ["ucf_LocationBarEnhancer.js"], ["ucf_contextsearch.js"], ["ucf_findbarclose.js"], ["ucf_tab-update.js"], ["ucf_cooks-pass.js"], ["ClickPicSave.jsm"], ["UCFTitleChangedChild.jsm", this, "registerUCFTitleChanged"]]; // auto_hide_sidebar.js for (i = 0; i < jscripts.length; i++) loadscript(jscripts[i][0], jscripts[i][1], jscripts[i][2]); //<<<<<<<<<<<<<<<<<<<< }, 0); }, //>>>>>>>>>>| Загрузка скриптов для др. документов |>>>>>>>>>> "chrome://browser/content/places/bookmarksSidebar.xhtml": win => { // боковая панель закладок }, "chrome://browser/content/places/historySidebar.xhtml": win => { // боковая панель истории }, //<<<<<<<<<<<<<<<<<<<< }; load_scripts_by_url.browser(window); // END Загрузчик для custom_script_win.js |
_zt > 16-01-2022 15:42:42 |
Dobrov Dobrov пишет
На актуальном. Dobrov пишет
Я ничего не говорил про запятые. Dobrov пишет
Однако его загрузчик работает без подобных ошибок. Хотя, у меня давно уже весь импорт в CustomStylesScripts.jsm и CustomStylesScriptsChild.jsm, но его загрузчик до сих пор в custom_script_win.js присутствовал. |
Dumby > 16-01-2022 20:57:11 |
Dobrov пишет
Нет. Фрагмент кода начинается инструкцией var, которая завершается точкой с запятой; _zt пишет
Это не точки, а троеточия ("\u2026", HORIZONTAL ELLIPSIS). то, что последовательность троеточий не является частью кода, |
_zt > 16-01-2022 22:58:54 |
Dumby |
Viatcheslav > 17-01-2022 12:23:38 |
Есть кнопка для СВ, отображающая расход оперативной памяти, индикатор расположен в адресной строке (код во вкладке "Инициализация") Memory Indicator Выделить код Код:(async id => ({ delay: 2e3, val: "", init(topic, mm) { Services.obs.addObserver(mm = this, topic); Services.obs.addObserver(function quit(s, t) { this.timer?.cancel(); Services.obs.removeObserver(mm, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); }, observe(win) { var df = win.MozXULElement.parseXULToFragment( `<hbox id="${id}" align="center"><label id="${id += "-label"}"/></hbox>` ); this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); // Bug 1665318 - In about:processes refresh, ResidentUniqueDistinguishedAmount is slow (Firefox 94+) // https://bugzilla.mozilla.org/show_bug.cgi?id=1665318 parseInt(Services.appinfo.platformVersion) < 94 && Object.assign(this, eval( `({${this.notify}})`.replace("memory", "residentSetSize").replace("memory", "residentUniqueSize") )); (this.observe = async win => { this.timer.cancel(); await new Promise(ChromeUtils.idleDispatch); var ind = win.document.importNode(df, true); win.document.getElementById("star-button-box").after(ind); this.notify(); })(win); }, async notify() { var info = await ChromeUtils.requestProcInfo(); var bytes = info.memory; for(var child of info.children) bytes += child.memory; this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT); var prev = this.val; if ((this.val = this.mgb(bytes)) != prev) for(var win of CustomizableUI.windows) { var lab = win.document.getElementById(id); if (lab) lab.value = this.val; } }, mgb: bytes => bytes < 1073741824 ? Math.round(bytes / 1048576) + "MB" : (bytes / 1073741824).toFixed(2) + "GB" }).init("browser-delayed-startup-finished"))("ucf-mem-indicator"); Работает крайне нестабильно. Индикатор то отображается, то пропадает после перезапуска браузера, через несколько сессий опять появляется... Dumby, если можно, перепишите, пожалуйста, под UCF. Спасибо большое |
Wave > 17-01-2022 13:21:51 |
Помогите, пожалуйста, сделать пункты «открыть ссылку в {другой программе}». Скачал user_chrome_files. Сами UCF работают, например, есть три ненужных мне панели, да и в about:user-chrome-files иначе было бы не зайти. Но меню открытия в других программах нету. |
_zt > 17-01-2022 13:50:46 |
Wave |
Wave > 17-01-2022 14:50:47 |
_zt, я пошагово написал, что и как я делаю. Полностью совпадает с вашей инструкцией. |
Vitaliy V. > 17-01-2022 14:54:40 |
Wave Wave пишет
ucfobj: true |
Wave > 17-01-2022 15:26:08 |
Vitaliy V., спасибо, заработало. Vitaliy V. пишет
В теме, в которой мне посоветовали UCF, я писал:
Я же не виноват, что простейшее и конкретное действие в квантуме можно организовать только будучи изрядно красноглазым. Дайте мне простой аддон, который можно поставить, залезть в его настройки и всё — и я не буду пользоваться UCF. |
Vitaliy V. > 17-01-2022 15:43:41 |
Wave пишет
Я не согласен с этим, что там такого громоздкого, а то что лишнее отключается в настройках и на работу браузера никак не влияет. |
Wave > 17-01-2022 16:02:33 |
Распаковывать файлы по разным местам, редактировать конфиги вручную, вручную добавлять скрипты, которые или где-то находить, или писать самому, чистить startup cache, что там ещё. Вы сами сказали — это не для всех. |
Vitaliy V. > 17-01-2022 16:46:53 |
Wave пишет
Ну так это не такая уж простейшая функция вызов внешних приложений, в расширениях этого теперь точно не будет |
Wave > 17-01-2022 17:31:38 |
Vitaliy V. пишет
async_run_applications.2021.9.7.xpi умеет вызывать внешние программы и передавать им текущий адрес или адрес из буфера обмена. Правда, тоже требует некоторых телодвижений в каталоге установленного фаерфокса. |
Vitaliy V. > 17-01-2022 17:53:12 |
Wave пишет
Ну да мое расширение может но оно WebExtensions Experiments, для ознакомления https://firefox-source-docs.mozilla.org … xperiments Wave пишет
Не пользуюсь и PotPlayer, но судя по коду расширения оно добавляет ссылку в виде |
shadow_user > 17-01-2022 18:50:24 |
Wave |
Wave > 17-01-2022 19:00:01 |
Очевидно, что ты скачал где-то в другом месте набор, в котором этот скрипт уже был и был подключен. Я же сначала нагуглил скрипт, потом по цепочке выяснил, что подключить его можно через UCF, потом сам пакет UCF, потом выяснил, где и как в нём этот скрипт включить. И шёл я от темы про userChrome.css, потому что несколько лет назад было выяснил, что данную функцию можно задействовать через chrome. И что такое UCF вообще, не сразу выяснил. |
shadow_user > 17-01-2022 19:11:40 |
Wave |
Dumby > 17-01-2022 21:10:55 |
Viatcheslav пишет
Это что ещё за фантазии? |
Viatcheslav > 17-01-2022 22:19:57 |
Dumby пишет
Благодарю за просветление Вроде, нашёл его в теме для СВ, ну да ладно |
negodnik > 23-01-2022 10:18:43 |
Fx 91.4.1 ESR Можно ли с помощью UCF переместить findbar в нижнюю панель (#browser-bottombox) и
|
Dumby > 25-01-2022 11:47:55 |
negodnik пишет
Ты так говоришь, как будто он один на всё окно,
Если не нравятся серые полосы зачем тогда включать letterboxing
Не слишком ли надумано? |
doud > 25-01-2022 15:33:27 |
Ищу скрипты для custom_script.js- «Показать весь журнал» и «открыть about:config» |
kokoss > 25-01-2022 17:50:09 |
doud пишет
|
voqabuhe > 25-01-2022 18:39:02 |
kokoss |
negodnik > 25-01-2022 18:41:11 |
Dumby Стиль видел. |
kokoss > 25-01-2022 18:48:15 |
voqabuhe |
doud > 25-01-2022 19:21:51 |
kokoss,СКМ открывать не удобно, надо чтобы открывала по ЛКМ |
unter_officer > 25-01-2022 19:29:10 |
doud пишет
Два в одном подойдёт? скрытый текст Выделить код Код:try { CustomizableUI.createWidget({ id: "ucf_ShowHistory_AboutConfig", type: "custom", label: "Показать журнал / about:config", tooltiptext: [ "ЛКМ: Показать журнал", "ПКМ: about:config" ].join("\n"), // defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onBuild(doc) { var win = doc.defaultView; var trbn = doc.createXULElement("toolbarbutton"); trbn.id = this.id; trbn.tooltipText = this.tooltiptext; trbn.label = this.label; trbn.className = "toolbarbutton-1 chromeclass-toolbar-additional"; trbn.setAttribute("context", false); trbn.setAttribute("image", "chrome://browser/skin/history.svg"); trbn.addEventListener("click", function(e) { if (e.button == 0) { e.preventDefault(); e.stopPropagation(); win.SidebarUI.toggle("viewHistorySidebar"); } else if (e.button == 2) { win.switchToTabHavingURI("about:config", true, { relatedToCurrent: true, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() });; } }, false); return trbn; }, }); } catch(e) {} |
doud > 25-01-2022 19:40:00 |
По ЛКМ покзывает журнал в боковой панели,а хотелось бы в новом окне или в новой вкладке |
unter_officer > 25-01-2022 20:04:53 |
doud пишет
Подтянутся гуру и может подскажут, как это реализовать. А пока попробуйте в коде заменить строку: на строку: Возможно, что вам такой вариант подойдёт. |
doud > 25-01-2022 20:17:19 |
Спасибо, отлично получилось открывает в новом окне |
Dumby > 26-01-2022 09:42:42 |
negodnik пишет
их Вообще, вроде можно там findbar-склад устроить. скрытый текст Выделить код Код:(async uriStr => { var attr = "current"; await delayedStartupPromise; gBrowser.browserBottomBox = document.getElementById("browser-bottombox"); Object.assign(gBrowser, eval(`({${gBrowser._createFindBar}})` .replace(/\/\/.+?\);/s, "this.browserBottomBox.append(findBar);") .replace("return f", `aTab.selected && findBar.toggleAttribute("${attr}");\n $&`) )); windowUtils.loadSheetUsingURIString(uriStr.replace("A", attr), windowUtils.USER_SHEET); var arr = [["TabSelect", e => { e.target._findBar?.toggleAttribute(attr); e.detail.previousTab._findBar?.removeAttribute(attr); }], ["TabClose", e => e.target._findBar?.remove()]]; var tc = gBrowser.tabContainer; for(var args of arr) tc.addEventListener(...args); var id = Symbol(), ucf = ucf_custom_script_win; ucf.unloadlisteners.push(id); ucf[id] = {destructor: () => arr.forEach(args => tc.removeEventListener(...args))}; })("data:text/css,%23browser-bottombox>findbar:not([A]){display:none!important;}"); |
negodnik > 27-01-2022 14:30:01 |
findbar-склад устроился, но и полосы не пропали. Странный этот letterboxing. |
Farby > 27-01-2022 22:42:23 |
del |
Vitaliy V. > 28-01-2022 17:47:02 |
Farby пишет
Если бы это было так то уже бы другие пользователи об этом сообщили, и у мненя на это работает. Скорее всего проблема у вас в другом стиле или скрипте. Farby пишет
Да я собирался сделать, хотя мне не нужны пункты для вызова приложений в контекстном меню особенно когда их много, |
Farby > 29-01-2022 20:54:07 |
del. |
Dobrov > 05-02-2022 14:39:25 |
Vitaliy V. или Dumby - проблема с скриптом Контекстный поиск - при клике или выборе строк ничего не происходит. Не работает на версии Firefox 91.5 и выше на МакОС, при этом на Linux скрипт работает без проблем на версиях от 80 до новейшей. Выделить код Код:scriptschrome: { // Для докум. окна браузера [ChromeOnly] domload: [ // По событию "DOMContentLoaded" { path: "ucf_contextsearch.js", ucfobj: true, }, Как исправить работу скрипта Контекстный поиск для Firefox 90+ ??? (т. к. некоторые скрипты Dumby делал только под новый Firefox) |
_zt > 05-02-2022 21:47:49 |
Vitaliy V. > 06-02-2022 00:49:48 |
Dobrov |
Dumby > 06-02-2022 09:05:19 |
Кстати, заметил что там небольшой кусочек замысла скрытый текст Выделить код Код:/* this.handler = ev => { if (ev.target != popup) return; menu.hidden = searchSelect.hidden; }; this.handlerRebuild = () => this.handler(e) || this.rebuild(menu); */ this.handler = e => e.target != popup || (menu.hidden = searchSelect.hidden); this.handlerRebuild = e => this.handler(e) || this.rebuild(menu); И ещё случайно наткнулся на такой момент: searchSelect.collapsed = true; — скрывает пункт, но в клавиатурной навигации он продолжает участвовать. То есть, когда searchSelect не hidden, и стрелками клавиатуры Если написать searchSelect.style.setProperty("display", "none", "important"); |
Vitaliy V. > 06-02-2022 14:16:43 |
Dumby пишет
Ок, поправил это похоже после последней правки упустил когда проверку e.target != popup добавлял |
Dobrov > 16-02-2022 11:38:43 |
Dumby - доработал твой код, исправил неудобство кнопки «Быстрое переключение параметров about:config», которое есть во всех примерах форума: Теперь поведение выбора строк подменю одинаковое для параметров по-умолчанию, независимо от того, есть они в about:config или нет (сброшены). Как пример, в коде «Автовыбор значений по-умолчанию» включен в опциях: Загрузки, Многопоточный режим вкладок, User Agent. Скрипт брать из демо-профиля шапки темы, так как код скрипта сокращён и зависит от двух других: win_global.js и ucf_hookClicks.js. |
xrun1 > 16-02-2022 16:38:19 |
Dobrov пишет
Всё вроде выбирается. Код кнопки у меня отсюда. |
_zt > 16-02-2022 17:54:10 |
xrun1 пишет
Такая же фигня на 91 esr. |
Dobrov > 17-02-2022 07:03:42 |
Vitaliy V. — насколько я понял, в CustomStylesScripts.jsm нет возможности подключать jsm-скрипты ? Выделить код Код:scriptsbackground: [ // В фоне [System Principal] { path: "custom_script.js", }, ……………… { path: "ClickPicSave.jsm", }, if (s.path) // правка в user_chrome.js if (/\.jsm$/i.test(s.path)) ChromeUtils.import(`chrome://user_chrome_files/content/custom_scripts/${s.path}`) else Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${s.path}`, scope); _zt пишет
Не накрутил, а оптимизировал и по возможности сократил код, исключил клики и подсказки и повысил удобство использования. xrun1 пишет
_zt и xrun1 - Неверно! Я тоже тестировал все версии кода! Вот код xrun1 со всеми правками: но сброшенная опция "Многопоточный режим вкладок" не выбирается! Выделить код Код:// Быстрое переключение параметров about:config (async (name, id, func) => { if (name == "Object") return CustomizableUI.createWidget(func()); 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"; //===================================================================================== // refresh: // false - reload current tab // true - reload current tab skip cache // // restart: // false - restart browser // true - restart browser with confirm var primary = [{ pref: ["network.proxy.type", "Настройки прокси"], userChoice: 5, userAlt: 1, refresh: true, values: [ [0, "Не проксировать", "0"], [5, "Системные (из IE)", "5"], [2, "Авто (pacfile)", "2"], [1, "Прописанные", "1"], [4, "Автоопределение", "4"] ]}, null, { pref: ["permissions.default.image", "Загружать графику"], userChoice: 1, refresh: true, values: [[1, "Да"], [3, "С сайта"], [2, "Нет"]] },{ pref: ["browser.display.use_document_fonts", "Загружать web-шрифты"], userChoice: 1, refresh: true, values: [[1, "Да"], [0, "Нет"]] },{ pref: ["javascript.enabled", "Выполнять скрипты Java"], userChoice: true, refresh: true, values: [[true, "Да"], [false, "Нет"]] },{ pref: ["media.autoplay.default", "Автозапуск медиа"], userChoice: 5, refresh: true, values: [ [5, "Блокировать все", "5"], [1, "Блокировать не приглушенное", "1"], [0, "Разрешить все", "0"] ]},{ pref: ["media.autoplay.blocking_policy", "Автозапуск (политика)"], userChoice: 1, userAlt: 2, refresh: true, values: [ [1, "Временная", "1"], [2, "По действию", "2"], [0, "Постоянная", "0"] ]},{ pref: ["network.cookie.cookieBehavior", "Cookies"], userChoice: 1, userAlt: 3, refresh: false, values: [ [1, "Не принимать сторонние"], [3, "Не принимать с не посещенных"], [4, "Не принимать от трекеров"], [2, "Не принимать со всех"], [0, "Принимать со всех"] ]}, null, { pref: ["dom.storage.enabled", "Локальное хранилище"], userChoice: true },{ pref: ["browser.tabs.remote.force-enable", "Многопоточный режим вкладок"], userChoice: true, userAlt: false, values: [[true, "Да"], [false, "Нет"]] } ]; //===================================================================================== var secondary = [{ pref: ["dom.serviceWorkers.enabled", "Видео dom.serviceWorkers"], userChoice: false },{ pref: ["dom.enable_performance", "Статус загрузки страницы"], userChoice: false }, null, { pref: ["browser.cache.memory.enable", "Кэш в оперативной памяти"], userChoice: true }, null, { pref: ["intl.accept_languages", "Язык для веб-страниц"], userChoice: "en-US, en", values: [["en-US, en", "en-US, en"], ["en-US, en, ru-RU, ru", "en-US, en, ru-RU, ru"]] },{ pref: ["browser.display.document_color_use", "Использовать цвета сайтов"], userChoice: 0, values: [[0, "Авто", "0"], [1, "Всегда", "1"], [2, "Никогда", "2"]] }, null, { pref: ["network.http.sendRefererHeader", "Referer - для чего"], userChoice: 1, values: [[0, "Ни для чего", "0"], [1, "Только ссылки", "1"], [2, "Ссылки и изобр.", "2"]] },{ pref: ["network.http.referer.trimmingPolicy", "Referer - что"], userChoice: 0, values: [[0, "Полный URL", "0"], [1, "scheme+host+port+path", "1"], [2, "scheme+host+port", "2"]] },{ pref: ["network.http.referer.XOriginPolicy", "RefererXO - когда"], userChoice: 0, values: [[0, "В любом случае", "0"], [1, "При совп. баз. домена", "1"], [2, "При совпадении адреса", "2"]] },{ pref: ["network.http.referer.XOriginTrimmingPolicy", "RefererXO - что"], userChoice: 0, values: [[0, "Полный URL", "0"], [1, "scheme+host+port+path", "1"], [2, "scheme+host+port", "2"]] },{ pref: ["network.http.referer.spoofSource", "Referer - корень сайта"], userChoice: false }, null, { pref: ["media.peerconnection.enabled", "WebRTC утечка IP"], userChoice: false } ]; return { label: "Quick toggle", id: "QuickToggleAboutConfigSettings", localized: false, image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFPSURBVDhPnVPNSsNAEJ5tamnBk+A7BMEcikohp/gi9i18nRafQoT00kK16tnn8CJo4vp9m5m41eSgH0zmd3d+diJ/gfdedvl0QW7k1PcLwem+3TjowZagK+Nn6yc3gNCJ+LCCh9LzzTMdqeoNbkQSFZmpJLGCW5Gx2hZaQahMbZ52VuDSfHpnAVJXOb4FKzianbzCXiLrHLYl5C3t5NTRwtxaKJxUTZ/JcOTr6q2Rxwf0aVb2/hLs4KqL3Isckz/mmSdRRksjyg+z7IM6LzDCBfuvAEOJmIKBOqAWmo1YodxLlQNsyO0rsIV/AZM+JGc2a4GgzhZ2p9mFmrpboCMqNYBDdMlwompoTWN6F2nFT5hBXb0PEpmo/Gk+oH+RrqNZINPeIlnZViV1jQuLFJQuWGB0gJdwgShvqdPXZv6J+F/QS7oXqQ9xBTFZ5oa8fAGs9fed5YhPSwAAAABJRU5ErkJggg==", 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/9hAAACRUlEQVR42qWTS2gTQRjH/zPJZo2BDfgkB62vYg5CjQdvRUE8WB8HKyahYotIQQOeFKGCF7EgvQlBqOCjWFKlevBRDyL4uHloLXhYqWJroaEqlETSptndGb+ZPDH0ojN8O8vA98vv+/Itw38u1nSRYRE6UhKyg4FF1R292/Q+xhhLi4TIrgjgIzwe4MbgmR2nrZMtxxEN63zYORuPZp7gzpehvCu9XjfuPmwCUHIiEtw4fK89zVvD2+FHAD56quXBpV3CVO4ret6nxHzxZxdBRuqADCKmz7RHD9y2tlmbYbBVfwE8DXBkEd/y39H5+mze8ZyoSIpsFXC9u/VE3/ldpyg5AAMEoJMTQi2hANKBgyKdy0h/eoChqcf9MimvVAHjd/fdiG0NRwgQpDAp1agBpDZwdHKJLKZzc+h5e3kCSexh5c5j8fmhW0HGpNZXFkqfsQpAKgcFKGmAlAxHXp5bkkmsrhosjh4cCIJ5pG5qfQXgtMslqO1qgEMWTPrR+eriEhoA4wN7L8TWh0KVXzfgY2RQAUjVBenWLH4UCrj04Wa9BNXEo5va+w63xCiJ6WRVP2MVgNQIgjgEA17MTODZ7Lt+AtSaGDG4377a1m2FAkKrc11/dUwIID1dSKHEcW3yft4RbpR6kK1PYgaJtaY1nNp5jIeMsjKNbs1AWRUcjvTnp2Kh9LtLJGTDINUhcTIZ3L+hzdq9ZgvWmSF9/Wu5gI8L03gzP5l3hddL/3/zKDdA9MdE0UERrdzaFGMUaap75Y/pX9Yfap76EQYaCeEAAAAASUVORK5CYII=", notUserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACNUlEQVR42qXTT2jTUBwH8G9e0ta2ks5ND0Ww/qX1oGyevEwQnOBA6EHXwLwoUh3eRGRs501RPE6xgp6KrexQECZY8DBPXmbRS4Z/K0gRtmmDa2yb5PlLX7p2Gwpi4EfCy8sn3/dPwn9e0saGnCRF6XYFnA9DkhKtRs51ep6jmtEcp/JHIM9Yivl9mf0XNDV2Ngn1YLzVxdB1lJ8U8P5hzuCWnR6xrPwmIM8kLRjdkT326BaLHNgLKAFA9ouXdhOw6qi++4j589cd89vSaMqyc2sAPUXlgF8fyt9WI3t2Av4w4NsCMJ8AHAKav6hqqH76iuLINcNuNhOawyttYCp+7tRE/6XT9GFQAG4CpniATQkIaNQIMVG6/xSL2WfTGueTbWDh5L2rA9t29QGBrQQEPUDuAuoEmFSr+P5lGc8v33mtAUfaQO3M4/GgDOoYCIkUin8D0BDDoBQ2ZMxqN0wCQh0gMxaUnYb4uzt+dwIZ8wBHTGQbYAHMpu+uAxaGxpMDvSr3AHcFaAIlD+BtoN6ag5WqhOLNwrohTMWPH5roP7pdLIwb3wW6EziWGAZhpVdLWHzxdpqAyc4yKrJ+4uKg2oMV+lgRK9CdwAVsG1WpF8UH84Zt2QkCKmsbiRAtFAllB5OHWQ9fpr81OwlcgBL9kPrwsvDGMQ1zNMV5ZyN1ISlZYZl9/TE1tjuMSFgA1VWO8uef+FAqG47tpFMcm7dyFyIOEzBMlfCadao5qhk39l9P479evwFbiOcRSXKueAAAAABJRU5ErkJggg==", UserAltImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIfSURBVDhPpVM9b9NQFD02cSKKFVGKIFFREFsmFiCA1AEQQrQjC0gssLCkC0jJj0iFWFoGdiT4Ay0SEmJBhPI5FBokikL4SCC0Te2UxInt13Mdu1CVrVc6713fe86x/T6w09DCeTNKJ7Q0pzyUmoCmZYOiUhXms8RMcd6vB7UwthhM5fTLWix2L3PmYjKdOwdz9DDFGtr1KuovnqD29JGlfO9Goew9DCV/DaZy2pXE8PD9Y/mbupk6xE6cVWPQhEujHo2+4fXdO76ztnq1UPYfSCcwKB1HWjeMyunCraSZOsDqbkBPsBOTNoMGvkOTLto/f+F56bble262OK/qesiYzIydTJojFLjrgEe4bcIOEdXWYe6LITN2KgmFSRFGBuPpo0eAngX0SexTJHD5LOgLpEZTcgKuUuMijAyy5l7+r0NSb21g5LQI5gGYSy2AjYBLjQyRAUniTnJXsBoayBzm3RBBndwwIoOK3fgNdIREQYCV/0DqLdiNZqCRITKYayx85RfQuUNiZ3k7IgO+vfGeXGpkiAyma++WLHtZhZ8o5H/FEVpos1V7u8TFwLQId8nw+Afa51Oq2vyycmlk9KCW0GXFZeu63IUO8z88Bx5s28SbuUXfddzrxVcobxpI0GTh7H734/dPzQt9d0/CGBpCPB7nbhmwbAPVxR4+PPtsuU7/WuElth/lKORUcsoTE8TgMg0WbJaY4Zu3XKYdBrABARUk+ls4DfQAAAAASUVORK5CYII=", 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 += ` — "${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.BrowserReloadSkipCache() : win.BrowserReload(); } }, maybeClosePopup(e, trg) { !e.ctrlKey && prefs.getBoolPref(this.closePref, undefined) && trg.parentNode.hidePopup(); }, command(e) { var trg = e.target; if (trg.btn) return 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); } }; }); |
unter_officer > 17-02-2022 09:43:32 |
Dobrov пишет
Выделить код Код:scriptsbackground: [ // В фоне [System Principal] { func: 'ChromeUtils.import("chrome://user_chrome_files/content/custom_scripts/xxxxxxxx.jsm");', }, |
xrun1 > 17-02-2022 15:20:57 |
Dobrov пишет
Что я понимаю не так? 97.0 Добавил опцию в свой файл, т.к. не пользуюсь и сделал видео (лежит на ЯД). ЛКМ - красный, ПКМ - синий. |
Farby > 17-02-2022 16:23:34 |
Перелопатил форум на предмет скрита auto_hide_sidebar.uc.js, оказывается для userChromeJS его не так-то просто подключить. скрытый текст Выделить код Код:data:application/x-javascript;base64,Ly8gPT1Vc2VyU2NyaXB0PT0KLy8gQG5hbWUJQXV0byBIaWRlIFNpZGViYXIKLy8gQGF1dGhvcglWaXRhbGl5IFYuCi8vIEBpbmNsdWRlCW1haW4KLy8gQHNodXRkb3duCXRoaXMuYXV0b2hpZGVzaWRlYmFyLmRlc3RydWN0b3IoKTsKLy8gQG5vdGUJaHR0cHM6Ly9naXRodWIuY29tL1ZpdGFsaXlWc3R5bGUvVml0YWxpeVZzdHlsZS5naXRodWIuaW8vdHJlZS9tYXN0ZXIvc3R5bGVzZmYvdXNlcl9jaHJvbWVfZmlsZXMvCi8vIEBvbmx5b25jZQovLyA9PS9Vc2VyU2NyaXB0PT0KCih0aGlzLmF1dG9oaWRlc2lkZWJhciA9IHsKCXNpZGViYXI6IG51bGwsCgl0aW1lcjogbnVsbCwKCWRlbGF5OiBudWxsLAoJbGlzdGVuZXI6IG51bGwsCglldmVudHM6IFsiZHJhZ2VudGVyIiwgImRyb3AiLCAiZHJhZ2V4aXQiLCAiTW96TGF5ZXJUcmVlUmVhZHkiLCAibW91c2VlbnRlciIsICJtb3VzZWxlYXZlIl0sCglnZXQgdW5sb2FkbGlzdGVuZXJzKCkgewoJCWRlbGV0ZSB0aGlzLnVubG9hZGxpc3RlbmVyczsKCQl3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigidW5sb2FkIiwgdGhpcywgeyBvbmNlOiB0cnVlIH0pOwoJCXJldHVybiB0aGlzLnVubG9hZGxpc3RlbmVycyA9IFtdOwoJfSwKCWluaXQoKSB7CgkJdmFyIHNpZGViYXIgPSB0aGlzLnNpZGViYXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIjc2lkZWJhci1ib3giKTsKCQlpZiAoIXNpZGViYXIpIHJldHVybjsKCQlmb3IgKGxldCB0eXBlIG9mIHRoaXMuZXZlbnRzKQoJCQlzaWRlYmFyLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgdGhpcyk7CgkJdGhpcy51bmxvYWRsaXN0ZW5lcnMucHVzaCgiYXV0b2hpZGVzaWRlYmFyIik7CgkJdmFyIHBvcHVwID0gdGhpcy5wb3B1cCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIiNzaWRlYmFyTWVudS1wb3B1cCIpOwoJCWlmICghcG9wdXApIHJldHVybjsKCQlwb3B1cC5hZGRFdmVudExpc3RlbmVyKCJwb3B1cHNob3dpbmciLCB0aGlzKTsKCQlsZXQgc3R5bGUgPSB0aGlzLnN0eWxlCgkJdmFyIHNzcyA9IENjWydAbW96aWxsYS5vcmcvY29udGVudC9zdHlsZS1zaGVldC1zZXJ2aWNlOzEnXS5nZXRTZXJ2aWNlKENpLm5zSVN0eWxlU2hlZXRTZXJ2aWNlKTsKCQlsZXQgbmV3VVJJUGFyYW0gPSB7CgkJCWFVUkw6ICdkYXRhOnRleHQvY3NzLCcgKyBlbmNvZGVVUklDb21wb25lbnQoc3R5bGUpLAoJCQlhT3JpZ2luQ2hhcnNldDogbnVsbCwKCQkJYUJhc2VVUkk6IG51bGwKCQl9CgkJbGV0IGNzc1VyaSA9IFNlcnZpY2VzLmlvLm5ld1VSSShuZXdVUklQYXJhbS5hVVJMLAoJCQkJCQluZXdVUklQYXJhbS5hT3JpZ2luQ2hhcnNldCwKCQkJCQkJbmV3VVJJUGFyYW0uYUJhc2VVUkkpOwoJCXNzcy5sb2FkQW5kUmVnaXN0ZXJTaGVldChjc3NVcmksIHNzcy5BR0VOVF9TSEVFVCk7Cgl9LAoJZGVzdHJ1Y3RvcigpIHsKCQl2YXIgc2lkZWJhciA9IHRoaXMuc2lkZWJhcjsKCQlmb3IgKGxldCB0eXBlIG9mIHRoaXMuZXZlbnRzKQoJCQlzaWRlYmFyLnJlbW92ZUV2ZW50TGlzdGVuZXIodHlwZSwgdGhpcyk7CgkJaWYgKCF0aGlzLnBvcHVwKSByZXR1cm47CgkJdGhpcy5wb3B1cC5yZW1vdmVFdmVudExpc3RlbmVyKCJwb3B1cHNob3dpbmciLCB0aGlzKTsKCX0sCgloYW5kbGVFdmVudChlKSB7CgkJdGhpc1tlLnR5cGVdKGUpOwoJfSwKCU1vekxheWVyVHJlZVJlYWR5KGUpIHsKCQlpZiAoZS5vcmlnaW5hbFRhcmdldD8uaWQgPT0gIndlYmV4dC1wYW5lbHMtYnJvd3NlciIgJiYgIXRoaXMuc2lkZWJhci5oYXNBdHRyaWJ1dGUoInNpZGViYXJkcmFnIikpIHsKCQkJd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIm1vdXNlZG93biIsICgpID0+IHsKCQkJCXRoaXMuZHJvcCgpOwoJCQl9LCB7IG9uY2U6IHRydWUgfSk7CgkJCXRoaXMuZHJhZ2VudGVyKCk7CgkJfQoJfSwKCWNsaWNrOiBmdW5jdGlvbihldmVudCkgewoJCXZhciBzaWRlYmFyID0gdGhpcy5zaWRlYmFyOwoJCXZhciBib3hPYmogPSBzaWRlYmFyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBib3hTY3JuID0gIXNpZGViYXIuYm94T2JqZWN0ID8gc2lkZWJhciA6IHNpZGViYXIuYm94T2JqZWN0OwoJCWlmIChldmVudC5zY3JlZW5ZIDwgYm94U2Nybi5zY3JlZW5ZIHx8IGV2ZW50LnNjcmVlblk+IGJveFNjcm4uc2NyZWVuWSArIGJveE9iai5oZWlnaHQgfHwgZXZlbnQuc2NyZWVuWCA8IGJveFNjcm4uc2NyZWVuWHx8IGV2ZW50LnNjcmVlblggPiBib3hTY3JuLnNjcmVlblggKyBib3hPYmoud2lkdGgpIHsKCQkJd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsaWNrIiwgdGhpcywgZmFsc2UpOwoJCQl0aGlzLmxpc3RlbmVyID0gZmFsc2U7CgkJCWlmIChzaWRlYmFyLmhhc0F0dHJpYnV0ZSgic2lkZWJhcmRyYWciKSkKCQkJCXNpZGViYXIucmVtb3ZlQXR0cmlidXRlKCJzaWRlYmFyZHJhZyIpOwoJCX0KCX0sCgltb3VzZWVudGVyOiBmdW5jdGlvbigpIHsKCQl2YXIgc2lkZWJhciA9IHRoaXMuc2lkZWJhcjsKCQlpZiAoIXNpZGViYXIuaGFzQXR0cmlidXRlKCJzaWRlYmFyZHJhZyIpICYmICF0aGlzLmxpc3RlbmVyKSB7CgkJCWNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTsKCQkJdmFyIGRlbGF5ID0gdGhpcy5kZWxheSB8fCAodGhpcy5kZWxheSA9ICtnZXRDb21wdXRlZFN0eWxlKHNpZGViYXIpLmdldFByb3BlcnR5VmFsdWUoInRyYW5zaXRpb24tZGVsYXkiKS5yZXBsYWNlKC9bXjAtOVwuXS9nLCAiIikgKiAxMDAwKTsKCQkJdGhpcy50aW1lciA9IHNldFRpbWVvdXQoKCkgPT4gewoJCQkJc2lkZWJhci5zZXRBdHRyaWJ1dGUoInNpZGViYXJkcmFnIiwgInRydWUiKTsKCQkJCXRoaXMubGlzdGVuZXIgPSB0cnVlOwoJCQkJd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoImNsaWNrIiwgdGhpcywgZmFsc2UpOwoJCQl9LCBkZWxheSk7CgkJfQoJfSwKCW1vdXNlbGVhdmU6IGZ1bmN0aW9uKCkgewoJCWNsZWFyVGltZW91dCh0aGlzLnRpbWVyKTsKCX0sCglwb3B1cHNob3dpbmcoKSB7CgkJdGhpcy5wb3B1cC5hZGRFdmVudExpc3RlbmVyKCJwb3B1cGhpZGRlbiIsICgpID0+IHsKCQkJdGhpcy5kcm9wKCk7CgkJfSwgeyBvbmNlOiB0cnVlIH0pOwoJCXRoaXMuZHJhZ2VudGVyKCk7Cgl9LAoJZHJhZ2VudGVyKCkgewoJCWlmICghdGhpcy5zaWRlYmFyLmhhc0F0dHJpYnV0ZSgic2lkZWJhcmRyYWciKSkKCQkJdGhpcy5zaWRlYmFyLnNldEF0dHJpYnV0ZSgic2lkZWJhcmRyYWciLCAidHJ1ZSIpOwoJfSwKCWRyb3AoKSB7CgkJaWYgKHRoaXMuc2lkZWJhci5oYXNBdHRyaWJ1dGUoInNpZGViYXJkcmFnIikpCgkJCXRoaXMuc2lkZWJhci5yZW1vdmVBdHRyaWJ1dGUoInNpZGViYXJkcmFnIik7Cgl9LAoJZHJhZ2V4aXQoZSkgewoJCXZhciBzaWRlYmFyID0gdGhpcy5zaWRlYmFyOwoJCXZhciBib3hPYmogPSBzaWRlYmFyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBib3hTY3JuID0gIXNpZGViYXIuYm94T2JqZWN0ID8gc2lkZWJhciA6IHNpZGViYXIuYm94T2JqZWN0OwoJCWlmICgoIWUucmVsYXRlZFRhcmdldCB8fCBlLnNjcmVlblkgPD0gKGJveFNjcm4uc2NyZWVuWSArIDUpIHx8IGUuc2NyZWVuWT49IChib3hTY3JuLnNjcmVlblkgKyBib3hPYmouaGVpZ2h0IC0gNSkKCQkJfHwgZS5zY3JlZW5YIDw9IChib3hTY3JuLnNjcmVlblggKyA1KSB8fCBlLnNjcmVlblggPj0gKGJveFNjcm4uc2NyZWVuWCArIGJveE9iai53aWR0aCAtIDUpKQoJCQkmJiBzaWRlYmFyLmhhc0F0dHJpYnV0ZSgic2lkZWJhcmRyYWciKSkKCQkJc2lkZWJhci5yZW1vdmVBdHRyaWJ1dGUoInNpZGViYXJkcmFnIik7Cgl9LAoJc3R5bGU6IGBALW1vei1kb2N1bWVudCB1cmwoImNocm9tZTovL2Jyb3dzZXIvY29udGVudC9icm93c2VyLnhodG1sIikgewoJCQkjc2lkZWJhci1ib3ggewoJCQkJLS12LXNpZGViYXItbWluLXdpZHRoOiAycHg7CgkJCQktLXYtc2lkZWJhci1taW4td2lkdGgtbm9ybWFsOiA1cHg7CgkJCQktLXYtc2lkZWJhci1tYXgtd2lkdGg6IDMwZW07CgkJCQktLXYtc2lkZWJhci10cmFuc2l0aW9uLWRlbGF5LXNob3c6IC4zczsKCQkJCS0tdi1zaWRlYmFyLXRyYW5zaXRpb24tZGVsYXktaGlkZTogLjZzOwoJCQkJLS12LXNpZGViYXItdHJhbnNpdGlvbi1kdXJhdGlvbjogLjNzOwoJCQkgLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKCQkJIHBvc2l0aW9uOiByZWxhdGl2ZSAhaW1wb3J0YW50OwoJCQkgei1pbmRleDogMiAhaW1wb3J0YW50OwoJCQkgbWluLXdpZHRoOiB2YXIoLS12LXNpZGViYXItbWF4LXdpZHRoKSAhaW1wb3J0YW50OwoJCQkgd2lkdGg6IHZhcigtLXYtc2lkZWJhci1tYXgtd2lkdGgpICFpbXBvcnRhbnQ7CgkJCSBtYXgtd2lkdGg6IHZhcigtLXYtc2lkZWJhci1tYXgtd2lkdGgpICFpbXBvcnRhbnQ7CgkJCSBvdmVyZmxvdzogaGlkZGVuICFpbXBvcnRhbnQ7CgkJCSBvcGFjaXR5OiAwICFpbXBvcnRhbnQ7CgkJCSAtLXYtc2lkZWJhci1tYXJnaW4tbWF4LXdpZHRoOiBjYWxjKC0xICogdmFyKC0tdi1zaWRlYmFyLW1heC13aWR0aCkpOwoJCQkgLS12LXNpZGViYXItdHJhbnNmb3JtLWxvY2FsZS1kaXI6IC0xOwoJCQkgLS12LXNpZGViYXItdHJhbnNmb3JtLWxvY2FsZS1kaXItdmlzaWJsZTogMTsKCQkJIG1hcmdpbi1pbmxpbmUtc3RhcnQ6IDAgIWltcG9ydGFudDsKCQkJIG1hcmdpbi1pbmxpbmUtZW5kOiB2YXIoLS12LXNpZGViYXItbWFyZ2luLW1heC13aWR0aCkgIWltcG9ydGFudDsKCQkJIGJvcmRlcjogbm9uZSAhaW1wb3J0YW50OwoJCQkgYm9yZGVyLWlubGluZS1lbmQ6IDFweCBzb2xpZCB2YXIoLS1zaWRlYmFyLWJvcmRlci1jb2xvciwgVGhyZWVEU2hhZG93KSAhaW1wb3J0YW50OwoJCQkgdHJhbnNmb3JtOiB0cmFuc2xhdGVYKGNhbGModmFyKC0tdi1zaWRlYmFyLXRyYW5zZm9ybS1sb2NhbGUtZGlyKSAqICh2YXIoLS12LXNpZGViYXItbWF4LXdpZHRoKSAtIHZhcigtLXYtc2lkZWJhci1taW4td2lkdGgpKSkpICFpbXBvcnRhbnQ7CgkJCSB0cmFuc2l0aW9uLXRpbWluZy1mdW5jdGlvbjogbGluZWFyLCBzdGVwLXN0YXJ0ICFpbXBvcnRhbnQ7CgkJCSB0cmFuc2l0aW9uLWRlbGF5OiB2YXIoLS12LXNpZGViYXItdHJhbnNpdGlvbi1kZWxheS1oaWRlKSwgY2FsYyh2YXIoLS12LXNpZGViYXItdHJhbnNpdGlvbi1kZWxheS1oaWRlKSArIHZhcigtLXYtc2lkZWJhci10cmFuc2l0aW9uLWR1cmF0aW9uKSkgIWltcG9ydGFudDsKCQkJIHRyYW5zaXRpb24tZHVyYXRpb246IHZhcigtLXYtc2lkZWJhci10cmFuc2l0aW9uLWR1cmF0aW9uKSwgMHMgIWltcG9ydGFudDsKCQkJIHRyYW5zaXRpb24tcHJvcGVydHk6IHRyYW5zZm9ybSwgb3BhY2l0eSAhaW1wb3J0YW50OwoJCSB9CgkJICNzaWRlYmFyLWJveFtwb3NpdGlvbmVuZD0idHJ1ZSJdIHsKCQkJIG1hcmdpbi1pbmxpbmUtc3RhcnQ6IHZhcigtLXYtc2lkZWJhci1tYXJnaW4tbWF4LXdpZHRoKSAhaW1wb3J0YW50OwoJCQkgbWFyZ2luLWlubGluZS1lbmQ6IDAgIWltcG9ydGFudDsKCQkJIGJvcmRlci1pbmxpbmUtc3RhcnQ6IDFweCBzb2xpZCB2YXIoLS1zaWRlYmFyLWJvcmRlci1jb2xvciwgVGhyZWVEU2hhZG93KSAhaW1wb3J0YW50OwoJCQkgYm9yZGVyLWlubGluZS1lbmQ6IG5vbmUgIWltcG9ydGFudDsKCQkgfQoJCSAjc2lkZWJhci1ib3hbcG9zaXRpb25lbmQ9InRydWUiXTotbW96LWxvY2FsZS1kaXIobHRyKSwKCQkgI3NpZGViYXItYm94Om5vdChbcG9zaXRpb25lbmQ9InRydWUiXSk6LW1vei1sb2NhbGUtZGlyKHJ0bCkgewoJCQkgLS12LXNpZGViYXItdHJhbnNmb3JtLWxvY2FsZS1kaXI6IDE7CgkJCSAtLXYtc2lkZWJhci10cmFuc2Zvcm0tbG9jYWxlLWRpci12aXNpYmxlOiAtMTsKCQkgfQoJCSA6cm9vdFt2X3ZlcnRpY2FsX2Jhcl9hdXRvaGlkZV1bdl92ZXJ0aWNhbF9iYXJfc2lkZWJhcj0idHJ1ZSJdICNzaWRlYmFyLWJveDpub3QoOmhvdmVyLFtzaWRlYmFyZHJhZ10pLAoJCSA6cm9vdFt2X3ZlcnRpY2FsX2Jhcl9hdXRvaGlkZV06bm90KFt2X3ZlcnRpY2FsX2Jhcl9zaWRlYmFyXSkgI3NpZGViYXItYm94Om5vdCg6aG92ZXIsW3NpZGViYXJkcmFnXSkgewoJCQkgdHJhbnNpdGlvbi1kZWxheTogMHMsIHZhcigtLXYtc2lkZWJhci10cmFuc2l0aW9uLWR1cmF0aW9uKSAhaW1wb3J0YW50OwoJCSB9CgkJIDpyb290W3NpemVtb2RlPSJub3JtYWwiXSAjc2lkZWJhci1ib3ggewoJCQkgLS12LXNpZGViYXItbWluLXdpZHRoOiB2YXIoLS12LXNpZGViYXItbWluLXdpZHRoLW5vcm1hbCkgIWltcG9ydGFudDsKCQkgfQoJCSAjc2lkZWJhci1ib3g6aG92ZXIsCgkJICNzaWRlYmFyLWJveFtzaWRlYmFyZHJhZ10gewoJCQkJCQl0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoMHB4KSAhaW1wb3J0YW50OwoJCQkgb3BhY2l0eTogMSAhaW1wb3J0YW50OwoJCQkgdHJhbnNpdGlvbi1kZWxheTogdmFyKC0tdi1zaWRlYmFyLXRyYW5zaXRpb24tZGVsYXktc2hvdykgIWltcG9ydGFudDsKCQkgfQoJCSA6cm9vdFt2X3ZlcnRpY2FsX2Jhcl92aXNpYmxlXVt2X3ZlcnRpY2FsX2Jhcl9zdGFydD0idHJ1ZSJdICNzaWRlYmFyLWJveDpub3QoW3Bvc2l0aW9uZW5kPSJ0cnVlIl0pLAoJCSA6cm9vdFt2X3ZlcnRpY2FsX2Jhcl92aXNpYmxlXVt2X3ZlcnRpY2FsX2Jhcl9zdGFydD0iZmFsc2UiXSAjc2lkZWJhci1ib3hbcG9zaXRpb25lbmQ9InRydWUiXSB7CgkJCSB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoY2FsYyh2YXIoLS12LXNpZGViYXItdHJhbnNmb3JtLWxvY2FsZS1kaXItdmlzaWJsZSkgKiB2YXIoLS12LXZlcnRpY2FsX2Jhcl93aWR0aCwgMHB4KSkpICFpbXBvcnRhbnQ7CgkJCSBvcGFjaXR5OiAxICFpbXBvcnRhbnQ7CgkJCSB0cmFuc2l0aW9uLWRlbGF5OiAwcyAhaW1wb3J0YW50OwoJCSB9CgkJICNicm93c2VyID4gI3NpZGViYXItc3BsaXR0ZXIgewoJCQkgZGlzcGxheTogbm9uZSAhaW1wb3J0YW50OwoJCSB9CgkJICNzaWRlYmFyLWJveCA+ICNzaWRlYmFyIHsKCQkJIG1pbi13aWR0aDogMCAhaW1wb3J0YW50OwoJCQkgd2lkdGg6IGF1dG8gIWltcG9ydGFudDsKCQkJIG1heC13aWR0aDogbm9uZSAhaW1wb3J0YW50OwoJCQkgLW1vei1ib3gtZmxleDogMSAhaW1wb3J0YW50OwoJCSB9CgkJIH1gCn0pLmluaXQodGhpcyk7Cg== ЗЫ: может кому сгодиться, тестил на 91esr и 97 |
Vitaliy V. > 17-02-2022 19:49:37 |
Farby пишет
скрипт ваш неправильный во первых он скорее всего не работает в таком виде в userChromeJS разве что там есть массив unloadlisteners, я не курсе Farby пишет
вот это совсем лишнее учитывая что он там уже присутствует по умолчанию и с нормальной (кешированной) загрузкой стиля 17-02-2022 20:17:21 Dobrov пишет
Как вариант добавить перед строкой var UcfStylesScripts = { { func: jsmImport("path/scriptName"), }, |
_zt > 17-02-2022 23:47:00 |
Dobrov Dobrov пишет
Dumby же давал загрузчик: скрытый текст Выделить код Код:(async url => ChromeUtils.import(url))( "chrome://user_chrome_files/content/custom_scripts/scriptName" ); (async url => ChromeUtils.import(url))( "chrome://user_chrome_files/content/custom_scripts/scriptName" ); Добавляем его в стандартный импорт CustomStylesScripts.jsm: скрытый текст Выделить код Код:scriptsbackground: [ // В фоне [System Principal] ... { path: "custom_js/name.js", }, |
Dobrov > 18-02-2022 04:52:09 |
Vitaliy V. пишет
Не работает на скрипте "Замена текста в имени вкладки", у которого надо грузить функцию, я попробовал перенести код, но не получилось: Выделить код Код:var jsmImport = (name, funcName) => ` // подключить jsm [выполнить функцию] var {href, pathname} = new URL("chrome://user_chrome_files/content/custom_scripts/${name}"); var obj = ChromeUtils.import(href); funcName && obj[funcName](); `; { func: jsmImport("UCFTitleChangedChild.jsm", "registerUCFTitleChanged"), }, UCFTitleChangedChild.jsm — Замена текста в имени вкладки Выделить код Код:var EXPORTED_SYMBOLS = ["registerUCFTitleChanged", "UCFTitleChangedChild"]; var reg = /-\sПоиск\sв\sGoogle$| \| Форум Mozilla Россия$|^Смотреть дораму |^Смотреть бесплатно дораму |^Сериал \| Фильм | - DoramaTV/; var hosts = ["https://www.google.com/search?*", "https://www.google.ru/search?*", "https://doramatv.live/*", "https://forum.mozilla-russia.org"]; function registerUCFTitleChanged() { // исправление заголовка вкладки ChromeUtils.registerWindowActor("UCFTitleChanged", { child: { moduleURI: "chrome://user_chrome_files/content/custom_scripts/UCFTitleChangedChild.jsm", events: { DOMTitleChanged: { capture: true }, }, }, matches: hosts, messageManagerGroups: ["browsers"], }); } class UCFTitleChangedChild extends JSWindowActorChild { handleEvent(e) { if (reg.test(this.document.title)) this.document.title = this.document.title.replace(reg, ""); } } Но работает в custom_script_win.js (а желательно подключать в CustomStylesScripts.jsm?) Выделить код Код:var loadscript = (name, funcName) => { try { var {href, pathname} = new URL(`chrome://user_chrome_files/content/custom_scripts/${name}`); if (/\.jsm$/i.test(pathname)) { var obj = ChromeUtils.import(href); funcName && obj[funcName](); } else Services.scriptloader.loadSubScript(href); return true; } catch(ex) {Cu.reportError(ex);} } loadscript("ucf_aom-button.js"); loadscript("UCFTitleChangedChild.jsm", "registerUCFTitleChanged"); |
Dobrov > 18-02-2022 12:30:27 |
Dumby - Просьба убрать longPress из скрипта перехвата кликов - я пробовал, но срабатывает и обычный и двойной клик сразу… Можешь набросать только часть кода для перехвата кликов/$id кнопок ? (я сам переделаю скрипт по ссылке) Выделить код Код:data = { "#downloads-button": { mousedownTarget: true, 2(trg, forward) { bright(trg, forward); // яркость по wheel ± }, 128() { saveSelectionToTxt();}, // СКМ Click 260(btn) { // Double ПКМ Click |
Vitaliy V. > 18-02-2022 13:31:47 |
Dobrov пишет
и в чем проблема, не надо там ничего переделывать с функцией jsmImport 18-02-2022 13:55:47 Dobrov пишет
это же опечатка или действительно в win запускаешь? |
Dobrov > 18-02-2022 14:13:27 |
Vitaliy V. пишет
Спасибо! Но в будущих версиях UCF возможно сделать подключение jsm-скриптов попроще? Без всяких `` кавычек, так, как для js сделано ? Было так и имена вкладок менялись, но сейчас прописал правильно в CustomStylesScripts.jsm: |
Vitaliy V. > 18-02-2022 18:35:37 |
del |
Dobrov > 25-02-2022 01:51:13 |
Dumby - В скрипте "Simple Session Manager" одна иконка прописана 2 раза. Как сократить код и передать её как переменную в regStyle() ? Выделить код Код:onCreated(btn) { ………… btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8………… regStyle() { ………… #${pid} > menu { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8…………… Кроме того, восстановление сессий в новые вкладки с кликом средней кнопки + Ctrl не очень удобно, добавил для этого пункт меню: "Восстановить в новых вкладках" Simple Session Manager mod Выделить код Код:// https://forum.mozilla-russia.org/viewtopic.php?pid=798085#p798085 (async (pid, mp) => CustomizableUI.createWidget(({ id: "797321", label: "Simple Session Manager", tooltiptext: "Управление сессиями", localized: false, init() { this.handleEvent = e => this[e.type](e); this.onTimeout = () => this.saveSession() || this.save(); Services.obs.addObserver(this, "quit-application"); var {openMenu} = this; this.render = function() { this.openMenu = openMenu; this.constructor.prototype.render.call(this); } delete this.init; return this; }, onCreated(btn) { btn.type = "menu"; btn.phTimestamp = 0; btn.render = this.render; btn._handleClick = this.click; // btn.setAttribute("image", "chrome://user_chrome_files/content/custom_styles/svg/download-resume.svg"); btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAEnQAABJ0BfDRroQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGxSURBVDiNnZE/T1NRGMZ/7zn3lmKLkIKpaUxZFINEJZ0YHXRwcnBxMQ6aOJi4+FH8Dm5OOjA4+AEYGCTRook1JlVIVUrbW/rnPg63UtReIr7bOXmf5/ye59jDlanHS3O+wn/Mu+/DF8HFeVe5f+vaPTdfPpF4UNvk6frmhwAvXOEsvrR0IoN47xM4CHCADmDQBkAHbdTrTBRZdgYLs6NTD/MiMC+gC8MO6ke8ffWsXv3S3JpksHouv7Z4/UEeM8z6IwKfEGjYRt0G1d3m1p3n0Y1JBi/vTtfKw1Yec2CHBDFmXYjboAgL4tTc5pXsmcNcDxIDUFQHuqgfYT69OAuE9qqAoX4jIcAL7b9H+0deOYYg3tkYXxx2EAo7dQYEBF/TEULD5oow7KHut18RhGVD3GwxMZ36YWn6IJd37vQCSMSNBpYQCMs43PQMAJXlwtr6k7CGfo9iznN1ebGY7Ak1NSJwYERYJgM+Q+nClVzp/OXc3wWMwdT+jAVKCMwLC2PUeoMrrEI4m94BQq0a6mxjoca/YKFgUCfeqR8jPhoHcIAHe3ST2+UFLv2T8o/5uMvrnx9Wn65p5nMEAAAAAElFTkSuQmCC"); var popup = btn.ownerDocument.createXULElement("menupopup"); popup.filler = this; popup.id = pid; popup.setAttribute("onpopupshowing", "event.defaultPrevented || filler.fill(event)"); btn.prepend(popup); btn.addEventListener("mousedown", this); popup.addEventListener("command", this); btn.ownerGlobal.addEventListener("unload", () => { btn.removeEventListener("mousedown", this); popup.removeEventListener("command", this); if (popup.filler != this) popup.removeEventListener("dragstart", this), popup.removeEventListener("popuphidden", this); }, {once: true}); }, openMenu(arg) { var pos; if (this.matches(".widget-overflow-list > :scope")) pos = "after_start"; else var win = this.ownerGlobal, {width, height, top, bottom, left, right} = this.closest("toolbar").getBoundingClientRect(), pos = width > height ? `${win.innerHeight - bottom > top ? "after" : "before"}_start` : `${win.innerWidth - right > left ? "end" : "start"}_before`; this.firstChild.setAttribute("position", pos); delete this.openMenu; this.openMenu(arg); }, mousedown(e) { if (e.button) return; var trg = e.target; if (trg.nodeName.startsWith("t")) { trg.mdTimestamp = Cu.now(); trg.tid = e.view.setTimeout(this.onTimeout, 500); return e.preventDefault(); } e.detail == 2 && trg.nodeName == "menu" && this.boot(trg); }, boot(trg) { var popup = trg.parentNode; var old = popup.querySelector("[boot]"); if (old != trg) old?.removeAttribute("boot"); trg.toggleAttribute("boot"); popup.dblMD = true; }, click() { var win = this.ownerGlobal; if (win.event.target != this) return; win.clearTimeout(this.tid); if (this.mdTimestamp - this.phTimestamp > 50) this.open = true; }, command(e) { var arg, trg = e.target, cmd = trg.value; if (cmd.startsWith("r")) { arg = trg.parentNode.parentNode.label; if (cmd.startsWith("res")) return this[cmd](arg, (trg.label.indexOf("вклад")>0) && e.view); // Восстановить в новых вкладках } this[cmd](arg) || this.save(); }, dragstart(e) { var trg = e.target; if (trg.nodeName != "menu") return; var popup = trg.parentNode; this.dragData = {trg, mouse: true}; trg.menupopup.hidePopup(); var win = trg.ownerGlobal; win.setCursor("grabbing"); var {width} = trg.getBoundingClientRect(); trg.setAttribute("maxwidth", width); win.addEventListener("mouseup", this); popup.addEventListener("mousemove", this); }, mousemove(e) { var trg = e.target, dtrg = this.dragData.trg; if (trg == dtrg || trg.nodeName != "menu") return; e.movementY > 0 ? trg.nextSibling != dtrg && trg.after(dtrg) : trg.previousSibling != dtrg && trg.before(dtrg); }, mouseup(arg) { if (arg.constructor.isInstance?.(arg)) { arg.preventDefault(); var {trg} = this.dragData; this.dragData.mouse = false; } else var trg = arg; trg.removeAttribute("maxwidth"); trg.ownerGlobal.setCursor("auto"); trg.ownerGlobal.removeEventListener("mouseup", this); trg.parentNode.removeEventListener("mousemove", this); }, popuphidden(e) { if (!e.target.id) return; e.view.removeEventListener("keydown", this, true); var popup = e.target; popup.parentNode.phTimestamp = Cu.now(); if (!this.dragData && !popup.dblMD) return; var save; if (this.dragData) { var {trg, mouse} = this.dragData; mouse && this.mouseup(trg); delete this.dragData; var order = Array.from(popup.getElementsByTagName("menu"), m => m.label); if (order.toString() != this.meta.order.toString()) { var hasBoot = this.meta.boot != null; if (hasBoot) var bootName = this.meta.order[this.meta.boot]; this.meta.order = order; if (hasBoot) this.meta.boot = this.meta.order.indexOf(bootName); save = true; } } if (popup.dblMD) { delete popup.dblMD; var {boot} = this.meta; var bootNode = e.target.querySelector("[boot]"); var ind = bootNode && this.meta.order.indexOf(bootNode.label); if (ind != boot) this.meta.boot = ind, save = true; } save && this.save(e.view); }, sku: `#${pid} > menu[maxwidth]`, skd: `#${pid} > menu:is([maxwidth],[_moz-menuactive]):not([open])`, keydown(e) { if (e.repeat && e.key == "Shift" || !e.shiftKey) return; var func = this.keyHandlers[e.key]; if (!func) return; var menu = e.view.windowRoot .ownerGlobal.document.querySelector(this.skd); if (menu) e.stopImmediatePropagation(), func.call(this, menu); }, keyup(e) { if (e.key != "Shift") return; var win = e.view.windowRoot.ownerGlobal; win.removeEventListener("keyup", this, true); win.document.querySelector(this.skd)?.removeAttribute("maxwidth"); }, keyHandlers: { Enter(menu) { this.boot(menu); }, ArrowDown(menu) { var ns = menu.nextSibling; if (ns) ns.after(menu), this.arrow(menu); }, ArrowUp(menu) { var ps = menu.previousSibling; if (ps.nodeName == "menu") ps.before(menu), this.arrow(menu); } }, arrow(menu) { if (menu.hasAttribute("maxwidth")) return; menu.setAttribute("maxwidth", menu.getBoundingClientRect().width); menu.ownerGlobal.addEventListener("keyup", this, true); this.dragData = {trg: menu}; }, fill(e) { var mxe = e.view.MozXULElement; var initFrag = mxe.parseXULToFragment(` <menuitem value="saveSession" class="menuitem-iconic" label="Сохранить сессию"/> <menuitem value="deleteAllSessions" class="menuitem-iconic" label="Удалить все сессии"/> <menuseparator/> `); this.menuFrag = mxe.parseXULToFragment(`<menu class="menu-iconic"><menupopup> <menuitem label="Восстановить" class="menuitem-iconic" value="restoreSession"/> <menuitem label="Восстановить в новых вкладках" class="menuitem-iconic" value="restoreSession"/> <menuitem label="Переименовать" class="menuitem-iconic" value="renameSession"/> <menuitem label="Удалить" class="menuitem-iconic" value="removeSession"/> </menupopup></menu>`); this.regStyle(); var filler = {fill: e => e.target.id ? e.view.addEventListener("keydown", this, true) || e.target.fillFlag || this.fillSessions(e.target) : this.dragData?.mouse && e.preventDefault() }; (this.fill = e => { var trg = e.target; trg.setAttribute("context", ""); trg.append(trg.ownerDocument.importNode(initFrag, true)); (trg.filler = filler).fill(e); trg.addEventListener("dragstart", this); trg.addEventListener("popuphidden", this); })(e); }, fillSessions(popup) { while(popup.lastChild.nodeName == "menu") popup.lastChild.remove(); var ind = 0, {boot} = this.meta; for(var name of this.meta.order) { var df = popup.ownerDocument.importNode(this.menuFrag, true); df.firstChild.setAttribute("label", name); if (ind++ == boot) df.firstChild.toggleAttribute("boot"); popup.append(df); } popup.fillFlag = true; }, regStyle() { delete this.regStyle; var subst = "ucf-ssm-style-resurl"; Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler).setSubstitution( subst, Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(` @-moz-document url-prefix(chrome://browser/content/browser.xhtml) { #${pid} > menu { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAEnQAABJ0BfDRroQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGxSURBVDiNnZE/T1NRGMZ/7zn3lmKLkIKpaUxZFINEJZ0YHXRwcnBxMQ6aOJi4+FH8Dm5OOjA4+AEYGCTRook1JlVIVUrbW/rnPg63UtReIr7bOXmf5/ye59jDlanHS3O+wn/Mu+/DF8HFeVe5f+vaPTdfPpF4UNvk6frmhwAvXOEsvrR0IoN47xM4CHCADmDQBkAHbdTrTBRZdgYLs6NTD/MiMC+gC8MO6ke8ffWsXv3S3JpksHouv7Z4/UEeM8z6IwKfEGjYRt0G1d3m1p3n0Y1JBi/vTtfKw1Yec2CHBDFmXYjboAgL4tTc5pXsmcNcDxIDUFQHuqgfYT69OAuE9qqAoX4jIcAL7b9H+0deOYYg3tkYXxx2EAo7dQYEBF/TEULD5oow7KHut18RhGVD3GwxMZ36YWn6IJd37vQCSMSNBpYQCMs43PQMAJXlwtr6k7CGfo9iznN1ebGY7Ak1NSJwYERYJgM+Q+nClVzp/OXc3wWMwdT+jAVKCMwLC2PUeoMrrEI4m94BQq0a6mxjoca/YKFgUCfeqR8jPhoHcIAHe3ST2+UFLv2T8o/5uMvrnx9Wn65p5nMEAAAAAElFTkSuQmCC"); } #${pid} > [value=saveSession] { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKVSURBVHjajFNNTBNREJ6+7na73bLbQn8I0BKNCYWKGr0oYoiJPxeNh6oHozcOxgSVi4le1JNHQRPigRsewURNPKiJMQicSISUACelRVJ2tz/bdktpy9adBzT8xTjJ5L35ezNv5hsLHEAv7noEntguChx7EuV8oTydKRhfno8kCnt9LTuFZ7f87mAz/8rnl86GOoOBBq+LQX1S1ioLs0txWdEmsulS38Phlcy+BwZ6W0L+JsfolcjpsFDnBKNcgQ193bRUwSrwQFgr6Dkd3o9NzilqMdI/FF+sPYCZ245I4zdunw9DtQr6LxlK6bVdpdrcPAiHfGBYLDD69ltUXsmfw0oIGoPNjkHMjMHa3J9asDyRpoyEOrQR0+dq5MxR0c29Rj3Bhvn8YjeWjZmN9cpWcApSkzpkptYg8T1FdWjTfysg1Ang9YtdT+80OogTbJc7OlsD+OftzOqsBrMflqHe6QKXIEL00zLV0UpSBbM/G9DeEQy6OXKJsfPsCbdXYjb0Yu2/nmMS9LSGYGlYpXLPkxCwkq1mR98Gn8Q4XexxYhhgYKf3TPTfRDaPqklkvViaSSpaxSpw/x1v5e0UG8W10k+iW8qfF2ZiccIydFQ7ScsXKO8ep4NiYj4ai6k5+Eoev1F1Wcn8QJDgnAnHbGYRWTh800cZ77Ryzmr6eCGXzYGiZCcQ2vQ32XT5PiIMTJBI4Waw1ZtZzLu7XaSMd1s9b9paKJA+vpuKqols3y4ov7wXaPN67GPXIl1hnDOOansyVicHhGHMzHkzeDKqqPnr/UOJxX3LNNDb5BJd3KC3Uexu7wgEGxq3limRqcxH47FVWRtPreYePBpJagdu4zYhwjx1cMFus59CuVgqTmPDDlrnvwIMAGS8IFCLagHpAAAAAElFTkSuQmCC"); } #${pid} [value=restoreSession] { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAACzElEQVQ4jX2QPWwbZRjHf+/5vfPdObZjO3Ga2pVpGtxCP4QIDKgqDCDUNQwgJCS2qFI3hBCRCvXSCcTAAu0GY0Fi4kuq+IjUCpWAgCTq4IpS3Di2G8c+x/bZ57t7mSJFMfBf/3p+z+95BPvy3pufxqKmcVY3ZFFKmQtFGIReuNnrDze6lv5TqfSyx4EIgA/e+fzkZML6MDmVnD80mz1kxW3DMAxQCs/z6Hb6g3q1Xt1ttdfa7dbFN668vrkHkADJhPntufNnc0LTDi7AjFkkUknzcGF2LvCDuZVvfiwCj+/1GoAmhL3x6x2cZhsVqjFIGIZs15ts/LJOJCLt/Z0EiE3Y9eLpR1ONaoMH9zbHAGiC9FSKkwunWF1Z3RoDABhRg/zRPPmj+XHA/0QDaLectFLj6gcT+AHdTm9mzMC27e766lrWtCwy2Qz2hIUeNVDAaDCku9ujWW/ij3wsO9oaMzCiunf66TMU5gt4wyGbf1Upr5W5u15mq1JDhYqZQo6HIuqtueLw4vLXzwC89NZXeQFw/ePv7zx5buHEf6nf3qgMVipOGE0ko6EKhoQi3NnZ+c51BwsaQLOxM9N1uv86vNtz+aHSDn0pH9S2tl6r/Pn3s/VG/WYunzs/NZ2OSID0dKpRrzZS98v3kYbEsi1004BQcbtc9Q07bdYb229/dvmFL5aWVvVts9mq1Wo/e54vJIAQqGOPzQHgj3zcvos39BAIBshRqJQYjYZ/AFy79tQIeHVx+ctiIDRTA+g43Xud9q4PIHVJPBknk82QzqY5VZg2UUrEYhOX9s5aXL5RnMykb8Rj9kcC4OrSVZ1Hpt+PJ5PPz+SzR5KpyYRpGgRKMei7fHLr7lBmZ1XHcX4LgsCxLPt4JBLRm82Hr4j9DyuVSprdO/ZELGafkXpkXtPA94OK03Vv/R4/csEw5XOGbuieN6y6bv/S9XdfvPkPTgcoDlpQJpwAAAAASUVORK5CYII="); } #${pid} [value=renameSession] { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPFJREFUeNrEU0sOgkAMbc1IIHoQT+KeY7hkBW5ccwLdsOICxI2X8peIGhggI21gggpCwsImM01f+tpOO0WlFIwR0efgeR5nsG0boihizPd91A5UwZDjuq5qwycwUkQYhttSr4Y4l76fDdtBEAQqz3OVZdnPQ09o2sQhrpBSQgnAen/qzLxZzljHcawxy7KAuCJNUyiKAm53SS0FBGQNlUW3lFO2iVCLYRhAXJEkCQPn65NGAswpL/4fWAebt1ZGXB3geHlw9maXsKqjS94CHNxF7xRM0/wKgI7jDBojvbnZAz3Gv/9E7NvGvmXCsev8EmAAWocA9ofpaRIAAAAASUVORK5CYII="); } #${pid} :is([value=removeSession], [value=deleteAllSessions]) { list-style-image: url("data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAABt0lEQVQ4ja2RT2sTURTFz8tk0nntFAQrVLBQxIUg/tkkMoLyIEVECHZhNrrxI+hOP5Mb6eBCcEipYIjZ2LpvhFasUtBSkwzOve+6mE6YSScuxLt67753fudyLvA/a7T+qCHmiTfrfWCMd3j9diPfq2SHX+uPnzJx71gP33w3bX9avBcE2j+SkK30Di7ffJ71VebMxD1hC2GGEEfH41prpftynIm92A0t2aYQQYgBThrndz/2KwCgf9Z2LNtImFOAtc356ijcCwJdJrZEUWzPfJpMAAAStPWR/h2Ktc10CoIQRUKEabFNvNbKfndcAKSjtrVfHW5YorWTzxDKYAxLtOWM+P7yt51hIYPpsDTNTyB/EwNAtWxdMuV8GCfbgxjxIviUYSV/SQOrbVjitbx4N8alBeXcdZR+3Tl3xS8FlIkt0dbnWH3xlbPgKgUo3HEq+tX7C4EuAAbGeOmqCuLIJt69s3PeQ1epKGfapCQJO6vGmwAWf/C1Wau6td8dV123BaAAUfHw6gSwtP3ugxA/y6X9INszAOQgbwFAIC/MQb9/Kv2vF2/UByejlVVn1Xiby/X6rPd/qj/1ak71UYKuwQAAAABJRU5ErkJggg=="); } #${pid} > menuseparator:last-child, #${pid} > menu[maxwidth] > .menu-right, #${pid} > [value=deleteAllSessions]:nth-last-child(2) { display: none; } #${pid} > menu[boot] { color: red; font-weight: bold; } #${pid} > menu[maxwidth] { color: blue; font-weight: bold; outline-offset: -2px; outline: 2px solid orangered; } } `.replace(/;$/gm, " !important;")))); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(Services.io.newURI("resource://" + subst), sss.USER_SHEET); }, get gs() { delete this.gs; return this.gs = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}); }, getState() { return JSON.parse(this.gs.SessionStore.getBrowserState()); }, splice(name, newName) { var ind = this.meta.order.indexOf(name); if (ind == -1) return; var args = [ind, 1]; if (1 in arguments) args.push(newName); else { if (ind == this.meta.boot) this.meta.boot = null; else if (ind < this.meta.boot) this.meta.boot--; } this.meta.order.splice(...args); }, get meta() { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("simple_session_manager.json"); this.path = file.path; try { this.data = JSON.parse(Cu.readUTF8File(file)); } catch { this.pp = file.parent.path; this.data = Object.create(null); } var meta = this.data[mp]; if (!meta) { var order = Object.keys(this.data); meta = this.data[mp] = {order, boot: null}; } delete this.meta; return this.meta = meta; }, async save(excWin) { var io = Cu.getGlobalForObject(Cu).IOUtils; if (this.pp) await io.makeDirectory(this.pp), delete this.pp; (this.save = excWin => { this.meta.order.length ? io.writeJSON(this.path, this.data) : io.remove(this.path, {ignoreAbsent: true}); for(var win of CustomizableUI.windows) { if (win == excWin) continue; var popup = win.document.getElementById(pid); if (popup) popup.fillFlag = false; } })(excWin); }, get prompter() { var {prompt} = Services; var p = {}, args = [null, null, "UCF Simple Session Manager"]; p.alert = prompt.alert.bind(...args); p.confirm = prompt.confirm.bind(...args); var pr = prompt.prompt.bind(...args); p.prompt = (msg, value) => { var res = {value}; return pr(msg, res, null, {}) ? res.value : null; } delete this.prompter; return this.prompter = p; }, observe(s, t, data) { Services.obs.removeObserver(this, "quit-application"); if (data.includes("restart")) return; var {boot} = this.meta; if (boot == null) return; var state = this.data[this.meta.order[boot]]; //this.gs.SessionStoreInternal.getCurrentState = () => state; var ssi = this.gs.SessionStoreInternal; ssi.getCurrentState = () => state; Services.obs.removeObserver(ssi, "browser:purge-session-history"); Services.prefs.setBoolPref("browser.sessionstore.resume_session_once", true); }, get bwt() { delete this.bwt; var url = "resource:///modules/BrowserWindowTracker.jsm"; return this.bwt = ChromeUtils.import(url).BrowserWindowTracker; }, getName(state) { var wl = state.windows.length, tl = 0; for(var w of state.windows) tl += w.tabs.length; return `${ this.bwt.getTopWindow().gBrowser.selectedTab.label.slice(0, 70) } ${wl}/${tl} [${ new Date().toLocaleString("mn").replace(" ", "-") }]`; }, exists(name) { this.meta; return (this.exists = name => name in this.data && !this.prompter.alert("Сессия с тем же именем уже существует!"))(name); }, saveSession(state = this.getState(), name = this.getName(state)) { var name = this.prompter.prompt("Сохранить:", name); if (name == null) return true; if (this.exists(name)) return this.saveSession(state, name); this.data[name] = state; this.meta.order.push(name); //this.meta.order.unshift(name); //if (this.meta.boot != null) this.meta.boot++; }, restoreSession(name, win) { var ss = this.gs.SessionStore; var state = JSON.stringify(this.data[name]); win ? ss.setWindowState(win, state) : ss.setBrowserState(state); }, renameSession(name, newName = name) { var newName = this.prompter.prompt(`Переименовать "${name}" в:`, newName); if (newName == null || newName == name) return true; if (this.exists(newName)) return this.renameSession(name, newName); var {data} = this; this.splice(name, newName); data[newName] = data[name]; delete data[name]; }, removeSession(name) { if (!this.prompter.confirm(`Вы уверены, что хотите удалить ${name} ?`)) return true; delete this.data[name]; this.splice(name); }, deleteAllSessions() { if (!this.prompter.confirm(`Вы уверены, что хотите удалить все сессии?`)) return true; delete this.dragData; delete this.bwt.getTopWindow().document.getElementById(pid).dblMD; this.meta = (this.data = Object.create(null))[mp] = {order: [], boot: null}; } }).init()))("ucf-ssm-menupopup", "{07cae4f5-18b0-487b-80eb-973304af9528}"); |
Dumby > 26-02-2022 10:02:38 |
Dobrov пишет
Например, задать её как свойство объекта, и далее использовать, типа this.image
Там же двойной левый mousedown устанавливает скрытый текст Выделить код Код:(async (pid, mp, self) => CustomizableUI.createWidget((self = { id: "797321", label: "Simple Session Manager", tooltiptext: "Управление сессиями", localized: false, init() { this.handleEvent = e => this[e.type](e); this.onTimeout = () => this.saveSession() || this.save(); Services.obs.addObserver(this, "quit-application"); var {openMenu} = this; this.render = function() { this.openMenu = openMenu; this.constructor.prototype.render.call(this); } delete this.init; return this; }, image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAEnQAABJ0BfDRroQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGxSURBVDiNnZE/T1NRGMZ/7zn3lmKLkIKpaUxZFINEJZ0YHXRwcnBxMQ6aOJi4+FH8Dm5OOjA4+AEYGCTRook1JlVIVUrbW/rnPg63UtReIr7bOXmf5/ye59jDlanHS3O+wn/Mu+/DF8HFeVe5f+vaPTdfPpF4UNvk6frmhwAvXOEsvrR0IoN47xM4CHCADmDQBkAHbdTrTBRZdgYLs6NTD/MiMC+gC8MO6ke8ffWsXv3S3JpksHouv7Z4/UEeM8z6IwKfEGjYRt0G1d3m1p3n0Y1JBi/vTtfKw1Yec2CHBDFmXYjboAgL4tTc5pXsmcNcDxIDUFQHuqgfYT69OAuE9qqAoX4jIcAL7b9H+0deOYYg3tkYXxx2EAo7dQYEBF/TEULD5oow7KHut18RhGVD3GwxMZ36YWn6IJd37vQCSMSNBpYQCMs43PQMAJXlwtr6k7CGfo9iznN1ebGY7Ak1NSJwYERYJgM+Q+nClVzp/OXc3wWMwdT+jAVKCMwLC2PUeoMrrEI4m94BQq0a6mxjoca/YKFgUCfeqR8jPhoHcIAHe3ST2+UFLv2T8o/5uMvrnx9Wn65p5nMEAAAAAElFTkSuQmCC", onCreated(btn) { btn.type = "menu"; btn.phTimestamp = 0; btn.render = this.render; btn.onclick = this.click; // btn.setAttribute("image", "chrome://user_chrome_files/content/custom_styles/svg/download-resume.svg"); btn.setAttribute("image", this.image); var popup = btn.ownerDocument.createXULElement("menupopup"); popup.filler = this; popup.id = pid; popup.setAttribute("onpopupshowing", "event.defaultPrevented || filler.fill(event)"); btn.prepend(popup); btn.addEventListener("mousedown", this); popup.addEventListener("command", this); btn.ownerGlobal.addEventListener("unload", () => { btn.removeEventListener("mousedown", this); popup.removeEventListener("command", this); if (popup.filler != this) popup.removeEventListener("dragstart", this), popup.removeEventListener("popuphidden", this); }, {once: true}); }, openMenu(arg) { var pos; if (this.matches(".widget-overflow-list > :scope")) pos = "after_start"; else var win = this.ownerGlobal, {width, height, top, bottom, left, right} = this.closest("toolbar").getBoundingClientRect(), pos = width > height ? `${win.innerHeight - bottom > top ? "after" : "before"}_start` : `${win.innerWidth - right > left ? "end" : "start"}_before`; this.firstChild.setAttribute("position", pos); delete this.openMenu; this.openMenu(arg); }, mousedown(e) { if (e.button) return; var trg = e.target; if (trg.nodeName.startsWith("t")) trg.mdTimestamp = Cu.now(), trg.tid = e.view.setTimeout(this.onTimeout, 500), e.preventDefault(); }, boot(trg) { var popup = trg.parentNode; var old = popup.querySelector("[boot]"); if (old != trg) old?.removeAttribute("boot"); trg.toggleAttribute("boot"); popup.bootChanged = true; }, muTimestamp: 0, click(e) { var trg = e.target; if (trg.nodeName == "menu") { if (e.button > 1) self.boot(trg); else if (Cu.now() - self.muTimestamp > 50) e.view.closeMenus(trg.menupopup), self.restoreSession(trg.label, (e.button || e.ctrlKey) && e.view); } else if (trg != this || e.button) return; e.view.clearTimeout(this.tid); if (this.mdTimestamp - this.phTimestamp > 50) this.open = true; }, command(e) { var arg, trg = e.target, cmd = trg.value; if (cmd.startsWith("r")) arg = trg.parentNode.parentNode.label; this[cmd](arg) || this.save(); }, dragstart(e) { var trg = e.target; if (trg.nodeName != "menu") return; var popup = trg.parentNode; this.dragData = {trg, mouse: true}; trg.menupopup.hidePopup(); var win = trg.ownerGlobal; win.setCursor("grabbing"); var {width} = trg.getBoundingClientRect(); trg.setAttribute("maxwidth", width); win.addEventListener("mouseup", this); popup.addEventListener("mousemove", this); }, mousemove(e) { var trg = e.target, dtrg = this.dragData.trg; if (trg == dtrg || trg.nodeName != "menu") return; e.movementY > 0 ? trg.nextSibling != dtrg && trg.after(dtrg) : trg.previousSibling != dtrg && trg.before(dtrg); }, mouseup(arg) { if (arg.constructor.isInstance?.(arg)) { arg.preventDefault(); var {trg} = this.dragData; this.dragData.mouse = false; this.muTimestamp = Cu.now(); } else var trg = arg; trg.removeAttribute("maxwidth"); trg.ownerGlobal.setCursor("auto"); trg.ownerGlobal.removeEventListener("mouseup", this); trg.parentNode.removeEventListener("mousemove", this); }, popuphidden(e) { if (!e.target.id) return; e.view.removeEventListener("keydown", this, true); var popup = e.target; popup.parentNode.phTimestamp = Cu.now(); var save; if (this.dragData) { var {trg, mouse} = this.dragData; mouse && this.mouseup(trg); delete this.dragData; var order = Array.from(popup.getElementsByTagName("menu"), m => m.label); if (order.toString() != this.meta.order.toString()) { var hasBoot = this.meta.boot != null; if (hasBoot) var bootName = this.meta.order[this.meta.boot]; this.meta.order = order; if (hasBoot) this.meta.boot = this.meta.order.indexOf(bootName); save = true; } } if (popup.bootChanged) { delete popup.bootChanged; var {boot} = this.meta; var bootNode = e.target.querySelector("[boot]"); var ind = bootNode && this.meta.order.indexOf(bootNode.label); if (ind != boot) this.meta.boot = ind, save = true; } save && this.save(e.view); }, sku: `#${pid} > menu[maxwidth]`, skd: `#${pid} > menu:is([maxwidth],[_moz-menuactive]):not([open])`, keydown(e) { if (e.repeat && e.key == "Shift" || !e.shiftKey && e.key != " ") return; var func = this.keyHandlers[e.key]; if (!func) return; var menu = e.view.windowRoot .ownerGlobal.document.querySelector(this.skd); if (menu) e.stopImmediatePropagation(), func.call(this, menu, e); }, keyup(e) { if (e.key != "Shift") return; var win = e.view.windowRoot.ownerGlobal; win.removeEventListener("keyup", this, true); win.document.querySelector(this.skd)?.removeAttribute("maxwidth"); }, keyHandlers: { Enter(menu) { this.boot(menu); }, ArrowDown(menu) { var ns = menu.nextSibling; if (ns) ns.after(menu), this.arrow(menu); }, ArrowUp(menu) { var ps = menu.previousSibling; if (ps.nodeName == "menu") ps.before(menu), this.arrow(menu); }, " "(menu, e) { e.preventDefault(); menu.ownerGlobal.closeMenus(menu.parentNode); this.restoreSession(menu.label, e.ctrlKey && menu.ownerGlobal); } }, arrow(menu) { if (menu.hasAttribute("maxwidth")) return; menu.setAttribute("maxwidth", menu.getBoundingClientRect().width); menu.ownerGlobal.addEventListener("keyup", this, true); this.dragData = {trg: menu}; }, fill(e) { var mxe = e.view.MozXULElement; var initFrag = mxe.parseXULToFragment(` <menuitem value="saveSession" class="menuitem-iconic" label="Сохранить сессию"/> <menuitem value="deleteAllSessions" class="menuitem-iconic" label="Удалить все сессии"/> <menuseparator/> `); this.menuFrag = mxe.parseXULToFragment(`<menu class="menu-iconic"><menupopup> <menuitem label="Переименовать" class="menuitem-iconic" value="renameSession"/> <menuitem label="Удалить" class="menuitem-iconic" value="removeSession"/> </menupopup></menu>`); this.regStyle(); var filler = {fill: e => e.target.id ? e.view.addEventListener("keydown", this, true) || e.target.fillFlag || this.fillSessions(e.target) : this.dragData?.mouse && e.preventDefault() }; (this.fill = e => { var trg = e.target; trg.setAttribute("context", ""); trg.append(trg.ownerDocument.importNode(initFrag, true)); (trg.filler = filler).fill(e); trg.addEventListener("dragstart", this); trg.addEventListener("popuphidden", this); })(e); }, fillSessions(popup) { while(popup.lastChild.nodeName == "menu") popup.lastChild.remove(); var ind = 0, {boot} = this.meta; for(var name of this.meta.order) { var df = popup.ownerDocument.importNode(this.menuFrag, true); df.firstChild.setAttribute("label", name); if (ind++ == boot) df.firstChild.toggleAttribute("boot"); popup.append(df); } popup.fillFlag = true; }, regStyle() { delete this.regStyle; var subst = "ucf-ssm-style-resurl"; Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler).setSubstitution( subst, Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(` @-moz-document url-prefix(chrome://browser/content/browser.xhtml) { #${pid} > menu { list-style-image: url("${this.image}"); } #${pid} > [value=saveSession] { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKVSURBVHjajFNNTBNREJ6+7na73bLbQn8I0BKNCYWKGr0oYoiJPxeNh6oHozcOxgSVi4le1JNHQRPigRsewURNPKiJMQicSISUACelRVJ2tz/bdktpy9adBzT8xTjJ5L35ezNv5hsLHEAv7noEntguChx7EuV8oTydKRhfno8kCnt9LTuFZ7f87mAz/8rnl86GOoOBBq+LQX1S1ioLs0txWdEmsulS38Phlcy+BwZ6W0L+JsfolcjpsFDnBKNcgQ193bRUwSrwQFgr6Dkd3o9NzilqMdI/FF+sPYCZ245I4zdunw9DtQr6LxlK6bVdpdrcPAiHfGBYLDD69ltUXsmfw0oIGoPNjkHMjMHa3J9asDyRpoyEOrQR0+dq5MxR0c29Rj3Bhvn8YjeWjZmN9cpWcApSkzpkptYg8T1FdWjTfysg1Ang9YtdT+80OogTbJc7OlsD+OftzOqsBrMflqHe6QKXIEL00zLV0UpSBbM/G9DeEQy6OXKJsfPsCbdXYjb0Yu2/nmMS9LSGYGlYpXLPkxCwkq1mR98Gn8Q4XexxYhhgYKf3TPTfRDaPqklkvViaSSpaxSpw/x1v5e0UG8W10k+iW8qfF2ZiccIydFQ7ScsXKO8ep4NiYj4ai6k5+Eoev1F1Wcn8QJDgnAnHbGYRWTh800cZ77Ryzmr6eCGXzYGiZCcQ2vQ32XT5PiIMTJBI4Waw1ZtZzLu7XaSMd1s9b9paKJA+vpuKqols3y4ov7wXaPN67GPXIl1hnDOOansyVicHhGHMzHkzeDKqqPnr/UOJxX3LNNDb5BJd3KC3Uexu7wgEGxq3limRqcxH47FVWRtPreYePBpJagdu4zYhwjx1cMFus59CuVgqTmPDDlrnvwIMAGS8IFCLagHpAAAAAElFTkSuQmCC"); } #${pid} [value=restoreSession] { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAACzElEQVQ4jX2QPWwbZRjHf+/5vfPdObZjO3Ga2pVpGtxCP4QIDKgqDCDUNQwgJCS2qFI3hBCRCvXSCcTAAu0GY0Fi4kuq+IjUCpWAgCTq4IpS3Di2G8c+x/bZ57t7mSJFMfBf/3p+z+95BPvy3pufxqKmcVY3ZFFKmQtFGIReuNnrDze6lv5TqfSyx4EIgA/e+fzkZML6MDmVnD80mz1kxW3DMAxQCs/z6Hb6g3q1Xt1ttdfa7dbFN668vrkHkADJhPntufNnc0LTDi7AjFkkUknzcGF2LvCDuZVvfiwCj+/1GoAmhL3x6x2cZhsVqjFIGIZs15ts/LJOJCLt/Z0EiE3Y9eLpR1ONaoMH9zbHAGiC9FSKkwunWF1Z3RoDABhRg/zRPPmj+XHA/0QDaLectFLj6gcT+AHdTm9mzMC27e766lrWtCwy2Qz2hIUeNVDAaDCku9ujWW/ij3wsO9oaMzCiunf66TMU5gt4wyGbf1Upr5W5u15mq1JDhYqZQo6HIuqtueLw4vLXzwC89NZXeQFw/ePv7zx5buHEf6nf3qgMVipOGE0ko6EKhoQi3NnZ+c51BwsaQLOxM9N1uv86vNtz+aHSDn0pH9S2tl6r/Pn3s/VG/WYunzs/NZ2OSID0dKpRrzZS98v3kYbEsi1004BQcbtc9Q07bdYb229/dvmFL5aWVvVts9mq1Wo/e54vJIAQqGOPzQHgj3zcvos39BAIBshRqJQYjYZ/AFy79tQIeHVx+ctiIDRTA+g43Xud9q4PIHVJPBknk82QzqY5VZg2UUrEYhOX9s5aXL5RnMykb8Rj9kcC4OrSVZ1Hpt+PJ5PPz+SzR5KpyYRpGgRKMei7fHLr7lBmZ1XHcX4LgsCxLPt4JBLRm82Hr4j9DyuVSprdO/ZELGafkXpkXtPA94OK03Vv/R4/csEw5XOGbuieN6y6bv/S9XdfvPkPTgcoDlpQJpwAAAAASUVORK5CYII="); } #${pid} [value=renameSession] { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPFJREFUeNrEU0sOgkAMbc1IIHoQT+KeY7hkBW5ccwLdsOICxI2X8peIGhggI21gggpCwsImM01f+tpOO0WlFIwR0efgeR5nsG0boihizPd91A5UwZDjuq5qwycwUkQYhttSr4Y4l76fDdtBEAQqz3OVZdnPQ09o2sQhrpBSQgnAen/qzLxZzljHcawxy7KAuCJNUyiKAm53SS0FBGQNlUW3lFO2iVCLYRhAXJEkCQPn65NGAswpL/4fWAebt1ZGXB3geHlw9maXsKqjS94CHNxF7xRM0/wKgI7jDBojvbnZAz3Gv/9E7NvGvmXCsev8EmAAWocA9ofpaRIAAAAASUVORK5CYII="); } #${pid} :is([value=removeSession], [value=deleteAllSessions]) { list-style-image: url("data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAABt0lEQVQ4ja2RT2sTURTFz8tk0nntFAQrVLBQxIUg/tkkMoLyIEVECHZhNrrxI+hOP5Mb6eBCcEipYIjZ2LpvhFasUtBSkwzOve+6mE6YSScuxLt67753fudyLvA/a7T+qCHmiTfrfWCMd3j9diPfq2SHX+uPnzJx71gP33w3bX9avBcE2j+SkK30Di7ffJ71VebMxD1hC2GGEEfH41prpftynIm92A0t2aYQQYgBThrndz/2KwCgf9Z2LNtImFOAtc356ijcCwJdJrZEUWzPfJpMAAAStPWR/h2Ktc10CoIQRUKEabFNvNbKfndcAKSjtrVfHW5YorWTzxDKYAxLtOWM+P7yt51hIYPpsDTNTyB/EwNAtWxdMuV8GCfbgxjxIviUYSV/SQOrbVjitbx4N8alBeXcdZR+3Tl3xS8FlIkt0dbnWH3xlbPgKgUo3HEq+tX7C4EuAAbGeOmqCuLIJt69s3PeQ1epKGfapCQJO6vGmwAWf/C1Wau6td8dV123BaAAUfHw6gSwtP3ugxA/y6X9INszAOQgbwFAIC/MQb9/Kv2vF2/UByejlVVn1Xiby/X6rPd/qj/1ak71UYKuwQAAAABJRU5ErkJggg=="); } #${pid} > menuseparator:last-child, #${pid} > menu[maxwidth] > .menu-right, #${pid} > [value=deleteAllSessions]:nth-last-child(2) { display: none; } #${pid} > menu[boot] { color: red; font-weight: bold; } #${pid} > menu[maxwidth] { color: blue; font-weight: bold; outline-offset: -2px; outline: 2px solid orangered; } } `.replace(/;$/gm, " !important;")))); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(Services.io.newURI("resource://" + subst), sss.USER_SHEET); }, get gs() { delete this.gs; return this.gs = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}); }, getState() { return JSON.parse(this.gs.SessionStore.getBrowserState()); }, splice(name, newName) { var ind = this.meta.order.indexOf(name); if (ind == -1) return; var args = [ind, 1]; if (1 in arguments) args.push(newName); else { if (ind == this.meta.boot) this.meta.boot = null; else if (ind < this.meta.boot) this.meta.boot--; } this.meta.order.splice(...args); }, get meta() { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("simple_session_manager.json"); this.path = file.path; try { this.data = JSON.parse(Cu.readUTF8File(file)); } catch { this.pp = file.parent.path; this.data = Object.create(null); } var meta = this.data[mp]; if (!meta) { var order = Object.keys(this.data); meta = this.data[mp] = {order, boot: null}; } delete this.meta; return this.meta = meta; }, async save(excWin) { var io = Cu.getGlobalForObject(Cu).IOUtils; if (this.pp) await io.makeDirectory(this.pp), delete this.pp; (this.save = excWin => { this.meta.order.length ? io.writeJSON(this.path, this.data) : io.remove(this.path, {ignoreAbsent: true}); for(var win of CustomizableUI.windows) { if (win == excWin) continue; var popup = win.document.getElementById(pid); if (popup) popup.fillFlag = false; } })(excWin); }, get prompter() { var {prompt} = Services; var p = {}, args = [null, null, "UCF Simple Session Manager"]; p.alert = prompt.alert.bind(...args); p.confirm = prompt.confirm.bind(...args); var pr = prompt.prompt.bind(...args); p.prompt = (msg, value) => { var res = {value}; return pr(msg, res, null, {}) ? res.value : null; } delete this.prompter; return this.prompter = p; }, observe(s, t, data) { Services.obs.removeObserver(this, "quit-application"); if (data.includes("restart")) return; var {boot} = this.meta; if (boot == null) return; var state = this.data[this.meta.order[boot]]; //this.gs.SessionStoreInternal.getCurrentState = () => state; var ssi = this.gs.SessionStoreInternal; ssi.getCurrentState = () => state; Services.obs.removeObserver(ssi, "browser:purge-session-history"); Services.prefs.setBoolPref("browser.sessionstore.resume_session_once", true); }, get bwt() { delete this.bwt; var url = "resource:///modules/BrowserWindowTracker.jsm"; return this.bwt = ChromeUtils.import(url).BrowserWindowTracker; }, getName(state) { var wl = state.windows.length, tl = 0; for(var w of state.windows) tl += w.tabs.length; return `${ this.bwt.getTopWindow().gBrowser.selectedTab.label.slice(0, 70) } ${wl}/${tl} [${ new Date().toLocaleString("mn").replace(" ", "-") }]`; }, exists(name) { this.meta; return (this.exists = name => name in this.data && !this.prompter.alert("Сессия с тем же именем уже существует!"))(name); }, saveSession(state = this.getState(), name = this.getName(state)) { var name = this.prompter.prompt("Сохранить:", name); if (name == null) return true; if (this.exists(name)) return this.saveSession(state, name); this.data[name] = state; this.meta.order.push(name); //this.meta.order.unshift(name); //if (this.meta.boot != null) this.meta.boot++; }, restoreSession(name, win) { var ss = this.gs.SessionStore; var state = JSON.stringify(this.data[name]); win ? ss.setWindowState(win, state) : ss.setBrowserState(state); }, renameSession(name, newName = name) { var newName = this.prompter.prompt(`Переименовать "${name}" в:`, newName); if (newName == null || newName == name) return true; if (this.exists(newName)) return this.renameSession(name, newName); var {data} = this; this.splice(name, newName); data[newName] = data[name]; delete data[name]; }, removeSession(name) { if (!this.prompter.confirm(`Вы уверены, что хотите удалить ${name} ?`)) return true; delete this.data[name]; this.splice(name); }, deleteAllSessions() { if (!this.prompter.confirm(`Вы уверены, что хотите удалить все сессии?`)) return true; delete this.dragData; delete this.bwt.getTopWindow().document.getElementById(pid).bootChanged; this.meta = (this.data = Object.create(null))[mp] = {order: [], boot: null}; } }).init()))("ucf-ssm-menupopup", "{07cae4f5-18b0-487b-80eb-973304af9528}"); |
kokoss > 26-02-2022 10:59:18 |
Vitaliy V. |
Dobrov > 27-02-2022 00:53:01 |
Dumby пишет
Вот этого в предыдущем коде не понял. Желательно в подсказку добавлять справку по действиям, как в большинстве примеров: Ещё проблема - сохраняю пару сессий по две или три вкладки. При клике по имени сохранённой сессии (не boot) восстанавливается только последняя вкладка, первые пустые. (Firefox 97.0.1) А что должно происходить, если имя сессии правым кликом выделено Красным? Оставляю одну пустую вкладку, при перезапуске браузера выделенная сессия не загружается… |
Wave > 27-02-2022 01:21:04 |
О, а скажите, можно ли посредством сабжа организовать такую штуку? |
Dobrov > 27-02-2022 07:40:28 |
Wave пишет
В шапке темы скрипт hookClicks сохраняет выделенный текст или всю страницу в текстовый файл – правый клик по кнопке Загрузки. К имени файла добавляется заголовок вкладки и дата, но имя можно фиксированное прописать… |
Wave > 27-02-2022 13:31:27 |
Dobrov пишет
Остаётся чтобы этот скрипт а) автоматически запускал текстовый редактор с этим файлом, б) по сохранению файла «снаружи» загружал его и обновлял содержимое страницы. |
xrun1 > 27-02-2022 14:42:08 |
Wave 27-02-2022 14:54:56 |
_zt > 27-02-2022 17:42:37 |
xrun1 |
xrun1 > 27-02-2022 19:29:13 |
_zt |
Wave > 27-02-2022 19:48:21 |
xrun1 пишет
У меня аналогичное расширение стоит, Textarea Cache. Оно, конечно, спасает от случайного перехода на другую страницу, закрытия вкладки и прочих неприятностей (на самом деле нет, потому что за всё время, что оно у меня стоит, так ни разу и не пригодилось). xrun1 пишет
Ну вот как поступаете вы. Придя куда-то, где нужно написать длинный пост, вы, вероятно, копируете в буфер обмена содержимое textarea (например, если там уже есть цитаты), запускаете редактор, вставляете из буфера обмена текст, пишете пост, копируете в буфер обмена текст, закрываете редактор, предварительно сказав «не сохранять» или введя имя файла и выбрав путь, и вставляете текст туда, куда писали. |
Dumby > 27-02-2022 21:09:19 |
kokoss пишет
Да уж, мягко говоря, не слишком понятный вопрос. скрытый текст Выделить код Код:(async bmrk => { await delayedStartupPromise; var popupshown = e => { var trg = e.target; if (trg.nodeName.startsWith("t")) return; var {curid, curbut} = autopopup; if (curid && trg.id == curid || curbut && ( curbut.className == "bookmark-item" && trg.matches(bmrk) || curbut.open && curbut.contains(trg.anchorNode || trg) && (curbut.type != "menu" || curbut.menupopup) )) trg.addEventListener("mouseleave", mouseleave), trg.addEventListener("popuphidden", popuphidden); } var popuphidden = function(e) { if (e.target == this) this.removeEventListener("mouseleave", mouseleave), this.removeEventListener("popuphidden", popuphidden); } var tid; var mouseleave = e => { tid && clearTimeout(tid); tid = setTimeout(check, 350, e.target); } var check = popup => { tid = null; popup.closest(":is(menupopup,panel):hover") || autopopup.curbut?.matches(":hover") || (popup.nodeName.startsWith("m") ? closeMenus(popup) : popup.hidePopup()); } var autopopup = ucf_custom_script_win.mouseoveropentoolbarbutton; var {destructor} = autopopup; autopopup.destructor = () => { destructor.call(autopopup); removeEventListener("popupshown", popupshown); } addEventListener("popupshown", popupshown); })("toolbarbutton.bookmark-item :scope"); Dobrov скрытый текст
История у него есть, не вдруг появился, а из даденого,
Вот и займись этим. Если туда еще добавить про двиганье мышью,
И не должна, перезапуск есть перезапуск, это действие определённого характера.
Прямо в реальном времени это не работает. Если очень надо, то можно попробовать так: Выделить код Код:(async (pid, mp, self) => CustomizableUI.createWidget((self = { id: "797321", label: "Simple Session Manager", tooltiptext: "Управление сессиями", localized: false, init() { this.handleEvent = e => this[e.type](e); this.onTimeout = async () => await this.saveSession() || this.save(); Services.obs.addObserver(this, "quit-application"); var {openMenu} = this; this.render = function() { this.openMenu = openMenu; this.constructor.prototype.render.call(this); } delete this.init; return this; }, image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAEnQAABJ0BfDRroQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGxSURBVDiNnZE/T1NRGMZ/7zn3lmKLkIKpaUxZFINEJZ0YHXRwcnBxMQ6aOJi4+FH8Dm5OOjA4+AEYGCTRook1JlVIVUrbW/rnPg63UtReIr7bOXmf5/ye59jDlanHS3O+wn/Mu+/DF8HFeVe5f+vaPTdfPpF4UNvk6frmhwAvXOEsvrR0IoN47xM4CHCADmDQBkAHbdTrTBRZdgYLs6NTD/MiMC+gC8MO6ke8ffWsXv3S3JpksHouv7Z4/UEeM8z6IwKfEGjYRt0G1d3m1p3n0Y1JBi/vTtfKw1Yec2CHBDFmXYjboAgL4tTc5pXsmcNcDxIDUFQHuqgfYT69OAuE9qqAoX4jIcAL7b9H+0deOYYg3tkYXxx2EAo7dQYEBF/TEULD5oow7KHut18RhGVD3GwxMZ36YWn6IJd37vQCSMSNBpYQCMs43PQMAJXlwtr6k7CGfo9iznN1ebGY7Ak1NSJwYERYJgM+Q+nClVzp/OXc3wWMwdT+jAVKCMwLC2PUeoMrrEI4m94BQq0a6mxjoca/YKFgUCfeqR8jPhoHcIAHe3ST2+UFLv2T8o/5uMvrnx9Wn65p5nMEAAAAAElFTkSuQmCC", onCreated(btn) { btn.type = "menu"; btn.phTimestamp = 0; btn.render = this.render; btn.onclick = this.click; // btn.setAttribute("image", "chrome://user_chrome_files/content/custom_styles/svg/download-resume.svg"); btn.setAttribute("image", this.image); var popup = btn.ownerDocument.createXULElement("menupopup"); popup.filler = this; popup.id = pid; popup.setAttribute("onpopupshowing", "event.defaultPrevented || filler.fill(event)"); btn.prepend(popup); btn.addEventListener("mousedown", this); popup.addEventListener("command", this); btn.ownerGlobal.addEventListener("unload", () => { btn.removeEventListener("mousedown", this); popup.removeEventListener("command", this); if (popup.filler != this) popup.removeEventListener("dragstart", this), popup.removeEventListener("popuphidden", this); }, {once: true}); }, openMenu(arg) { var pos; if (this.matches(".widget-overflow-list > :scope")) pos = "after_start"; else var win = this.ownerGlobal, {width, height, top, bottom, left, right} = this.closest("toolbar").getBoundingClientRect(), pos = width > height ? `${win.innerHeight - bottom > top ? "after" : "before"}_start` : `${win.innerWidth - right > left ? "end" : "start"}_before`; this.firstChild.setAttribute("position", pos); delete this.openMenu; this.openMenu(arg); }, mousedown(e) { if (e.button) return; var trg = e.target; if (trg.nodeName.startsWith("t")) trg.mdTimestamp = Cu.now(), trg.tid = e.view.setTimeout(this.onTimeout, 500), e.preventDefault(); }, boot(trg) { var popup = trg.parentNode; var old = popup.querySelector("[boot]"); if (old != trg) old?.removeAttribute("boot"); trg.toggleAttribute("boot"); popup.bootChanged = true; }, muTimestamp: 0, click(e) { var trg = e.target; if (trg.nodeName == "menu") { if (e.button > 1) self.boot(trg); else if (Cu.now() - self.muTimestamp > 50) e.view.closeMenus(trg.menupopup), self.restoreSession(trg.label, (e.button || e.ctrlKey) && e.view); } else if (trg != this || e.button) return; e.view.clearTimeout(this.tid); if (this.mdTimestamp - this.phTimestamp > 50) this.open = true; }, async command(e) { var arg, trg = e.target, cmd = trg.value; if (cmd.startsWith("r")) arg = trg.parentNode.parentNode.label; await this[cmd](arg) || this.save(); }, dragstart(e) { var trg = e.target; if (trg.nodeName != "menu") return; var popup = trg.parentNode; this.dragData = {trg, mouse: true}; trg.menupopup.hidePopup(); var win = trg.ownerGlobal; win.setCursor("grabbing"); var {width} = trg.getBoundingClientRect(); trg.setAttribute("maxwidth", width); win.addEventListener("mouseup", this); popup.addEventListener("mousemove", this); }, mousemove(e) { var trg = e.target, dtrg = this.dragData.trg; if (trg == dtrg || trg.nodeName != "menu") return; e.movementY > 0 ? trg.nextSibling != dtrg && trg.after(dtrg) : trg.previousSibling != dtrg && trg.before(dtrg); }, mouseup(arg) { if (arg.constructor.isInstance?.(arg)) { arg.preventDefault(); var {trg} = this.dragData; this.dragData.mouse = false; this.muTimestamp = Cu.now(); } else var trg = arg; trg.removeAttribute("maxwidth"); trg.ownerGlobal.setCursor("auto"); trg.ownerGlobal.removeEventListener("mouseup", this); trg.parentNode.removeEventListener("mousemove", this); }, popuphidden(e) { if (!e.target.id) return; e.view.removeEventListener("keydown", this, true); var popup = e.target; popup.parentNode.phTimestamp = Cu.now(); var save; if (this.dragData) { var {trg, mouse} = this.dragData; mouse && this.mouseup(trg); delete this.dragData; var order = Array.from(popup.getElementsByTagName("menu"), m => m.label); if (order.toString() != this.meta.order.toString()) { var hasBoot = this.meta.boot != null; if (hasBoot) var bootName = this.meta.order[this.meta.boot]; this.meta.order = order; if (hasBoot) this.meta.boot = this.meta.order.indexOf(bootName); save = true; } } if (popup.bootChanged) { delete popup.bootChanged; var {boot} = this.meta; var bootNode = e.target.querySelector("[boot]"); var ind = bootNode && this.meta.order.indexOf(bootNode.label); if (ind != boot) this.meta.boot = ind, save = true; } save && this.save(e.view); }, sku: `#${pid} > menu[maxwidth]`, skd: `#${pid} > menu:is([maxwidth],[_moz-menuactive]):not([open])`, keydown(e) { if (e.repeat && e.key == "Shift" || !e.shiftKey && e.key != " ") return; var func = this.keyHandlers[e.key]; if (!func) return; var menu = e.view.windowRoot .ownerGlobal.document.querySelector(this.skd); if (menu) e.stopImmediatePropagation(), func.call(this, menu, e); }, keyup(e) { if (e.key != "Shift") return; var win = e.view.windowRoot.ownerGlobal; win.removeEventListener("keyup", this, true); win.document.querySelector(this.skd)?.removeAttribute("maxwidth"); }, keyHandlers: { Enter(menu) { this.boot(menu); }, ArrowDown(menu) { var ns = menu.nextSibling; if (ns) ns.after(menu), this.arrow(menu); }, ArrowUp(menu) { var ps = menu.previousSibling; if (ps.nodeName == "menu") ps.before(menu), this.arrow(menu); }, " "(menu, e) { e.preventDefault(); menu.ownerGlobal.closeMenus(menu.parentNode); this.restoreSession(menu.label, e.ctrlKey && menu.ownerGlobal); } }, arrow(menu) { if (menu.hasAttribute("maxwidth")) return; menu.setAttribute("maxwidth", menu.getBoundingClientRect().width); menu.ownerGlobal.addEventListener("keyup", this, true); this.dragData = {trg: menu}; }, fill(e) { var mxe = e.view.MozXULElement; var initFrag = mxe.parseXULToFragment(` <menuitem value="saveSession" class="menuitem-iconic" label="Сохранить сессию"/> <menuitem value="deleteAllSessions" class="menuitem-iconic" label="Удалить все сессии"/> <menuseparator/> `); this.menuFrag = mxe.parseXULToFragment(`<menu class="menu-iconic"><menupopup> <menuitem label="Переименовать" class="menuitem-iconic" value="renameSession"/> <menuitem label="Удалить" class="menuitem-iconic" value="removeSession"/> </menupopup></menu>`); this.regStyle(); var filler = {fill: e => e.target.id ? e.view.addEventListener("keydown", this, true) || e.target.fillFlag || this.fillSessions(e.target) : this.dragData?.mouse && e.preventDefault() }; (this.fill = e => { var trg = e.target; trg.setAttribute("context", ""); trg.append(trg.ownerDocument.importNode(initFrag, true)); (trg.filler = filler).fill(e); trg.addEventListener("dragstart", this); trg.addEventListener("popuphidden", this); })(e); }, fillSessions(popup) { while(popup.lastChild.nodeName == "menu") popup.lastChild.remove(); var ind = 0, {boot} = this.meta; for(var name of this.meta.order) { var df = popup.ownerDocument.importNode(this.menuFrag, true); df.firstChild.setAttribute("label", name); if (ind++ == boot) df.firstChild.toggleAttribute("boot"); popup.append(df); } popup.fillFlag = true; }, regStyle() { delete this.regStyle; var subst = "ucf-ssm-style-resurl"; Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler).setSubstitution( subst, Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(` @-moz-document url-prefix(chrome://browser/content/browser.xhtml) { #${pid} > menu { list-style-image: url("${this.image}"); } #${pid} > [value=saveSession] { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKVSURBVHjajFNNTBNREJ6+7na73bLbQn8I0BKNCYWKGr0oYoiJPxeNh6oHozcOxgSVi4le1JNHQRPigRsewURNPKiJMQicSISUACelRVJ2tz/bdktpy9adBzT8xTjJ5L35ezNv5hsLHEAv7noEntguChx7EuV8oTydKRhfno8kCnt9LTuFZ7f87mAz/8rnl86GOoOBBq+LQX1S1ioLs0txWdEmsulS38Phlcy+BwZ6W0L+JsfolcjpsFDnBKNcgQ193bRUwSrwQFgr6Dkd3o9NzilqMdI/FF+sPYCZ245I4zdunw9DtQr6LxlK6bVdpdrcPAiHfGBYLDD69ltUXsmfw0oIGoPNjkHMjMHa3J9asDyRpoyEOrQR0+dq5MxR0c29Rj3Bhvn8YjeWjZmN9cpWcApSkzpkptYg8T1FdWjTfysg1Ang9YtdT+80OogTbJc7OlsD+OftzOqsBrMflqHe6QKXIEL00zLV0UpSBbM/G9DeEQy6OXKJsfPsCbdXYjb0Yu2/nmMS9LSGYGlYpXLPkxCwkq1mR98Gn8Q4XexxYhhgYKf3TPTfRDaPqklkvViaSSpaxSpw/x1v5e0UG8W10k+iW8qfF2ZiccIydFQ7ScsXKO8ep4NiYj4ai6k5+Eoev1F1Wcn8QJDgnAnHbGYRWTh800cZ77Ryzmr6eCGXzYGiZCcQ2vQ32XT5PiIMTJBI4Waw1ZtZzLu7XaSMd1s9b9paKJA+vpuKqols3y4ov7wXaPN67GPXIl1hnDOOansyVicHhGHMzHkzeDKqqPnr/UOJxX3LNNDb5BJd3KC3Uexu7wgEGxq3limRqcxH47FVWRtPreYePBpJagdu4zYhwjx1cMFus59CuVgqTmPDDlrnvwIMAGS8IFCLagHpAAAAAElFTkSuQmCC"); } #${pid} [value=restoreSession] { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAACzElEQVQ4jX2QPWwbZRjHf+/5vfPdObZjO3Ga2pVpGtxCP4QIDKgqDCDUNQwgJCS2qFI3hBCRCvXSCcTAAu0GY0Fi4kuq+IjUCpWAgCTq4IpS3Di2G8c+x/bZ57t7mSJFMfBf/3p+z+95BPvy3pufxqKmcVY3ZFFKmQtFGIReuNnrDze6lv5TqfSyx4EIgA/e+fzkZML6MDmVnD80mz1kxW3DMAxQCs/z6Hb6g3q1Xt1ttdfa7dbFN668vrkHkADJhPntufNnc0LTDi7AjFkkUknzcGF2LvCDuZVvfiwCj+/1GoAmhL3x6x2cZhsVqjFIGIZs15ts/LJOJCLt/Z0EiE3Y9eLpR1ONaoMH9zbHAGiC9FSKkwunWF1Z3RoDABhRg/zRPPmj+XHA/0QDaLectFLj6gcT+AHdTm9mzMC27e766lrWtCwy2Qz2hIUeNVDAaDCku9ujWW/ij3wsO9oaMzCiunf66TMU5gt4wyGbf1Upr5W5u15mq1JDhYqZQo6HIuqtueLw4vLXzwC89NZXeQFw/ePv7zx5buHEf6nf3qgMVipOGE0ko6EKhoQi3NnZ+c51BwsaQLOxM9N1uv86vNtz+aHSDn0pH9S2tl6r/Pn3s/VG/WYunzs/NZ2OSID0dKpRrzZS98v3kYbEsi1004BQcbtc9Q07bdYb229/dvmFL5aWVvVts9mq1Wo/e54vJIAQqGOPzQHgj3zcvos39BAIBshRqJQYjYZ/AFy79tQIeHVx+ctiIDRTA+g43Xud9q4PIHVJPBknk82QzqY5VZg2UUrEYhOX9s5aXL5RnMykb8Rj9kcC4OrSVZ1Hpt+PJ5PPz+SzR5KpyYRpGgRKMei7fHLr7lBmZ1XHcX4LgsCxLPt4JBLRm82Hr4j9DyuVSprdO/ZELGafkXpkXtPA94OK03Vv/R4/csEw5XOGbuieN6y6bv/S9XdfvPkPTgcoDlpQJpwAAAAASUVORK5CYII="); } #${pid} [value=renameSession] { list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPFJREFUeNrEU0sOgkAMbc1IIHoQT+KeY7hkBW5ccwLdsOICxI2X8peIGhggI21gggpCwsImM01f+tpOO0WlFIwR0efgeR5nsG0boihizPd91A5UwZDjuq5qwycwUkQYhttSr4Y4l76fDdtBEAQqz3OVZdnPQ09o2sQhrpBSQgnAen/qzLxZzljHcawxy7KAuCJNUyiKAm53SS0FBGQNlUW3lFO2iVCLYRhAXJEkCQPn65NGAswpL/4fWAebt1ZGXB3geHlw9maXsKqjS94CHNxF7xRM0/wKgI7jDBojvbnZAz3Gv/9E7NvGvmXCsev8EmAAWocA9ofpaRIAAAAASUVORK5CYII="); } #${pid} :is([value=removeSession], [value=deleteAllSessions]) { list-style-image: url("data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAABt0lEQVQ4ja2RT2sTURTFz8tk0nntFAQrVLBQxIUg/tkkMoLyIEVECHZhNrrxI+hOP5Mb6eBCcEipYIjZ2LpvhFasUtBSkwzOve+6mE6YSScuxLt67753fudyLvA/a7T+qCHmiTfrfWCMd3j9diPfq2SHX+uPnzJx71gP33w3bX9avBcE2j+SkK30Di7ffJ71VebMxD1hC2GGEEfH41prpftynIm92A0t2aYQQYgBThrndz/2KwCgf9Z2LNtImFOAtc356ijcCwJdJrZEUWzPfJpMAAAStPWR/h2Ktc10CoIQRUKEabFNvNbKfndcAKSjtrVfHW5YorWTzxDKYAxLtOWM+P7yt51hIYPpsDTNTyB/EwNAtWxdMuV8GCfbgxjxIviUYSV/SQOrbVjitbx4N8alBeXcdZR+3Tl3xS8FlIkt0dbnWH3xlbPgKgUo3HEq+tX7C4EuAAbGeOmqCuLIJt69s3PeQ1epKGfapCQJO6vGmwAWf/C1Wau6td8dV123BaAAUfHw6gSwtP3ugxA/y6X9INszAOQgbwFAIC/MQb9/Kv2vF2/UByejlVVn1Xiby/X6rPd/qj/1ak71UYKuwQAAAABJRU5ErkJggg=="); } #${pid} > menuseparator:last-child, #${pid} > menu[maxwidth] > .menu-right, #${pid} > [value=deleteAllSessions]:nth-last-child(2) { display: none; } #${pid} > menu[boot] { color: red; font-weight: bold; } #${pid} > menu[maxwidth] { color: blue; font-weight: bold; outline-offset: -2px; outline: 2px solid orangered; } } `.replace(/;$/gm, " !important;")))); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(Services.io.newURI("resource://" + subst), sss.USER_SHEET); }, get gs() { delete this.gs; return this.gs = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}); }, splice(name, newName) { var ind = this.meta.order.indexOf(name); if (ind == -1) return; var args = [ind, 1]; if (1 in arguments) args.push(newName); else { if (ind == this.meta.boot) this.meta.boot = null; else if (ind < this.meta.boot) this.meta.boot--; } this.meta.order.splice(...args); }, get meta() { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("simple_session_manager.json"); this.path = file.path; try { this.data = JSON.parse(Cu.readUTF8File(file)); } catch { this.pp = file.parent.path; this.data = Object.create(null); } var meta = this.data[mp]; if (!meta) { var order = Object.keys(this.data); meta = this.data[mp] = {order, boot: null}; } delete this.meta; return this.meta = meta; }, async save(excWin) { var io = Cu.getGlobalForObject(Cu).IOUtils; if (this.pp) await io.makeDirectory(this.pp), delete this.pp; (this.save = excWin => { this.meta.order.length ? io.writeJSON(this.path, this.data) : io.remove(this.path, {ignoreAbsent: true}); for(var win of CustomizableUI.windows) { if (win == excWin) continue; var popup = win.document.getElementById(pid); if (popup) popup.fillFlag = false; } })(excWin); }, get prompter() { var {prompt} = Services; var p = {}, args = [null, null, "UCF Simple Session Manager"]; p.alert = prompt.alert.bind(...args); p.confirm = prompt.confirm.bind(...args); var pr = prompt.prompt.bind(...args); p.prompt = (msg, value) => { var res = {value}; return pr(msg, res, null, {}) ? res.value : null; } delete this.prompter; return this.prompter = p; }, observe(s, t, data) { Services.obs.removeObserver(this, "quit-application"); if (data.includes("restart")) return; var {boot} = this.meta; if (boot == null) return; var state = this.data[this.meta.order[boot]]; var ssi = this.gs.SessionStoreInternal; ssi.getCurrentState = () => state; Services.obs.removeObserver(ssi, "browser:purge-session-history"); Services.prefs.setBoolPref("browser.sessionstore.resume_session_once", true); }, get bwt() { delete this.bwt; var url = "resource:///modules/BrowserWindowTracker.jsm"; return this.bwt = ChromeUtils.import(url).BrowserWindowTracker; }, getName(state) { var wl = state.windows.length, tl = 0; for(var w of state.windows) tl += w.tabs.length; return `${ this.bwt.getTopWindow().gBrowser.selectedTab.label.slice(0, 70) } ${wl}/${tl} [${ new Date().toLocaleString("mn").replace(" ", "-") }]`; }, exists(name) { this.meta; return (this.exists = name => name in this.data && !this.prompter.alert("Сессия с тем же именем уже существует!"))(name); }, getState() { return JSON.parse(this.gs.SessionStore.getBrowserState()); }, get spref() { var pref = "browser.sessionstore.interval"; var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); var wait = cb => timer.initWithCallback(cb, 1e3, timer.TYPE_ONE_SHOT); delete this.spref; return this.spref = async cb => { var val = Services.prefs.getIntPref(pref); Services.prefs.setIntPref(pref, 100); await new Promise(wait); Services.prefs.setIntPref(pref, val); } }, async saveSession(name = this.getName(this.getState())) { var name = this.prompter.prompt("Сохранить:", name); if (name == null) return true; if (this.exists(name)) return this.saveSession(name); await this.spref(); this.data[name] = this.getState(); this.meta.order.push(name); //this.meta.order.unshift(name); //if (this.meta.boot != null) this.meta.boot++; }, restoreSession(name, win) { var ss = this.gs.SessionStore; var state = JSON.stringify(this.data[name]); win ? ss.setWindowState(win, state) : ss.setBrowserState(state); }, renameSession(name, newName = name) { var newName = this.prompter.prompt(`Переименовать "${name}" в:`, newName); if (newName == null || newName == name) return true; if (this.exists(newName)) return this.renameSession(name, newName); var {data} = this; this.splice(name, newName); data[newName] = data[name]; delete data[name]; }, removeSession(name) { if (!this.prompter.confirm(`Вы уверены, что хотите удалить ${name} ?`)) return true; delete this.data[name]; this.splice(name); }, deleteAllSessions() { if (!this.prompter.confirm(`Вы уверены, что хотите удалить все сессии?`)) return true; delete this.dragData; delete this.bwt.getTopWindow().document.getElementById(pid).bootChanged; this.meta = (this.data = Object.create(null))[mp] = {order: [], boot: null}; } }).init()))("ucf-ssm-menupopup", "{07cae4f5-18b0-487b-80eb-973304af9528}"); |
kokoss > 28-02-2022 01:00:25 |
Dumby пишет
Спасибо! |
Dobrov > 28-02-2022 05:58:59 |
Dumby пишет
Доработал код Менеджера сессий, добавил описание: (про двиганье мышью записал только сортирровку перетаскиванием) Выделить код Код:tooltiptext: `Менеджер сессий: Браузер каждые 0.25 мин сохраняет сессии, это снижает ресурс SSD\n Правый клик на Имени сессии: Выделить и Открывать при запуске Колёсико или Клик + Ctrl: Открыть сессию в новых вкладках Сортировка: тащите строки мышью или курсором, удерживая Shift`, ……… btn.addEventListener("mouseenter", this); ……… btn.removeEventListener("mouseenter", this); ……… mouseenter(e) { // обновить время сохранения сессии браузера e.view.document.getElementById(self.id).tooltipText = self.tooltiptext.replace(new RegExp(/ые .* ми/,''),'ые '+ Services.prefs.getIntPref('browser.sessionstore.interval',15e3)/60e3 + ' ми'); }, |
Dobrov > 12-03-2022 03:52:49 |
Всем привет! Значительно переработал расширенный профиль Firefox (в шапке темы), добавил скриптов и сократил объём архива до 3,3 Мб: Визуальное представление: 4 режима Прокси разным фоном ≡ Меню, запрет графики фоном кнопки ⤓ «Загрузки», различные сообщения статуса при наведении на кнопки, например показ пути к папке Загрузок, масштаб шрифта, переключение прокси, предупреждение о включенном HTTPS и прочее… На любых кнопках разрешены все клики мыши ⦺, градиентный Прогресс загрузки страниц, Четыре режима чтения, Меню переключения скрытых настроек (долгое нажатие 0.5 сек на пункте меню откроет эту опцию в about:config), Управления дополнениями, расширенный Инспектор атрибутов, Добавление закладки без запроса, Перевод сайта/текста, Проиграть/скачать видео или ссылку программой из контекстного меню, Поиск похожих фото, Сохранение картинок, которые нельзя сохранить обычным способом, Жесты мыши например перетаскивание ссылки вправо копирует её в буфер, Расположение страниц в Закладках показывается в подсказке Звёздочки, Авто-коррекция имён вкладок, Яркость колёсиком ± на Замке, показ Ссылок и прочее… — читайте подсказки кнопкок при наведении мыши и встроенную Справку (долгий клик по кнопке «Печать»). Возможности кнопок вкратце: ◧ левая кнопка мыши, ◨ правая, ⦿ средняя 1) ⤓ кнопка Загрузки добавлены клики мыши, в списке есть Пауза\Старт Правый клик: сохранить Страницу | Выделен. текст в единый .html ◨ клик + Shift Графика вкл/откл, Левый клик + Alt папка Загрузки Колёсико ⦿ клик мыши: Сохранить | Выделенный текст как файл .txt Alt+⇧+S сохранить Страницу в единый html расширением SingleFile единый html - файл, содержащий все данные: графику, текст, стили… 2) ≡ стандартная кнопка Меню — вне курсора составной значок 3) Избранное + боковая панель с кнопками, Колёсико ± Масштаб 4) Менеджер сессий — сохранить вкладки и положение страниц в базу удалите папку startupCache перед запуском, рекомендуется Firefox 90+ |
kokoss > 18-03-2022 23:31:54 |
Dumby пишет
А можно ещё сделать что бы работал на кнопках CB |
Dumby > 19-03-2022 11:10:11 |
kokoss пишет
Не требуется, «скрытый текст» и так работает на кнопках CB.
Ууу, сам бы от такой не отказался. |
kokoss > 19-03-2022 11:43:08 |
Dumby пишет
Проверял в предыдущей версии UCF. В актуальной версии UCF у меня тоже не работает, походу не туда запихнул, пока не до конца разобрался куда добавлять...
Надеюсь такая возможность со временем появится! |
xrun1 > 19-03-2022 17:45:37 |
kokoss пишет
Есть перезапуск для меню или горячая клавиша Ctrl+Alt+Q. В меню гамбургера не показывает иконку. https://forum.mozilla-russia.org/viewto … 07#p785107 |
kokoss > 19-03-2022 17:54:35 |
xrun1 пишет
Это не то, таких кнопок у меня несколько Add, просто что бы заработали некоторые скрипты, приходится удалять эту папку |
xrun1 > 19-03-2022 20:59:06 |
Dumby пишет
Я сейчас проверил. Удаляется. Там ещё файл появляется .startup-incomplete, но он или само-удаляется при удалении папки, либо просто исчезает через некоторое время после запуска . |
Dumby > 19-03-2022 21:30:13 |
xrun1 пишет
Увы, это не то, что можно «проверить». Services.appinfo.invalidateCachesOnRestart(), разумеется, в основном, работает. Дело в том, что работает это не всегда. Очень неприятный глюк, особенно при возне с кодом, |
xrun1 > 20-03-2022 02:50:13 |
egorsemenov06 |
manuk > 04-05-2022 11:49:02 |
DEL. |
_zt > 09-05-2022 13:33:21 |
Dumby |
Dumby > 09-05-2022 21:23:05 |
_zt пишет
Надеюсь это только
Тут бы хорошо что-то более персонализированное говорить. Если не собираешься использовать скрипт на других осях Иначе, если обратная совместимость не нужна, Иначе пишем какую-нибудь дополнительную проверку. скрытый текст Выделить код Код:(async tit => { if (AppConstants.platform != "win") return; var key = parseInt(Services.appinfo.platformVersion) >= 99 ? "platform" : "os-version"; if (!matchMedia(`(-moz-${key}: windows-win7), (-moz-${key}: windows-win8)`).matches) return; Object.assign(tit, eval(`({${tit._update}})`.replace('"0,2,2,2"', "this.margin"))); var glass = matchMedia("(-moz-windows-glass)"); (glass.onchange = () => { tit.margin = glass.matches ? "0,7,7,7" : "0,0,0,0"; tit.enabled && document.documentElement.setAttribute("chromemargin", tit.margin); })(); })(window.TabsInTitlebar); |
_zt > 10-05-2022 13:07:04 |
Dumby |
_zt > 12-05-2022 00:48:51 |
Dumby |
Dumby > 12-05-2022 07:23:42 |
_zt Или сугубо под 91? скрытый текст Выделить код Код:try {({ run(func) { var topics = ["quit-application-granted", "chrome-document-loaded"]; var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); for(var t of topics) obs.addObserver(this, t, false); this.observe = (subj, topic) => this[topic[0]](subj); this.q = () => topics.forEach(t => obs.removeObserver(this, t)); this.run = async doc => { var code = `(${func})(document.getElementById("placesContext_editSeparator"));`; var ps = await doc.ownerGlobal.ChromeUtils .compileScript("data:charset=utf-8," + encodeURIComponent(code)); (this.run = ps.executeInGlobal.bind(ps))(doc); } var re = /\/(?:places|bookmarksSidebar)\.xhtml$/; this.c = doc => re.test(doc.documentURI) && this.run(doc); } }).run(sep => { var label = "\u041F\u0430\u043F\u043A\u0430 \u0437\u0430\u043A\u043B\u0430\u0434\u043A\u0438"; var popup = sep.parentNode, listener = { handleEvent() { if (this.shouldHide) return; var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("label", label); menuitem.setAttribute("oncommand", "creator.goParentFolder();"); menuitem.creator = this; sep.before(menuitem); this.handleEvent = e => { if (e.target != popup) return; var sh = this.shouldHide; if (Boolean(menuitem.clientHeight) ^ sh) return; if ((menuitem.hidden = sh)) return; menuitem.disabled = false; } }, get shouldHide() { var node = popup._view.selectedNodes.length == 1 && popup._view.selectedNode; return !(node && PlacesUtils.nodeIsBookmark(node) && node.parent.type == node.RESULT_TYPE_QUERY); }, get goParentFolder() { var tree = popup._view; if (tree.id.startsWith("b")) { delete this.library; var func = () => this.sidebar(tree); } else { delete this.sidebar; var list = document.getElementById("placesList"); var func = () => this.library(popup._view, list); } delete this.goParentFolder; return this.goParentFolder = func; }, sidebar(tree) { var {bookmarkGuid} = tree.selectedNode; if (tree.result.root.uri.startsWith("place:terms=")) tree.place = tree.place; tree.selectItems([bookmarkGuid]); this.scroll(tree); }, async library(tree, list) { var {bookmarkGuid} = tree.selectedNode; var {parentGuid} = await PlacesUtils.bookmarks.fetch(bookmarkGuid); if (PlacesUtils.getConcreteItemGuid(list.selectedNode) == parentGuid) list.selectItems([PlacesUtils.virtualAllBookmarksGuid]); else { var rows = list.view._rows, lastRow = rows[rows.length - 1]; if (lastRow.bookmarkGuid == PlacesUtils.virtualAllBookmarksGuid) lastRow.containerOpen = true; } list.selectItems([parentGuid]); this.scroll(list); tree.selectItems([bookmarkGuid]); await new Promise(requestAnimationFrame); this.scroll(tree); }, scroll(tree) { var pos = .4, visibleRows = tree.getPageLength(); var ind = tree.view.selection.currentIndex; var first = tree.getFirstVisibleRow(); var newFirst = ind - pos*visibleRows + 1; tree.scrollByLines(Math.round(newFirst - first)); } }; popup.addEventListener("popupshowing", listener); addEventListener("unload", () => popup.removeEventListener("popupshowing", listener) , {once: true}); });} catch(ex) {Cu.reportError(ex);} |
_zt > 12-05-2022 23:54:25 |
Dumby |
Dumby > 13-05-2022 02:42:36 |
_zt пишет
Быть этого не может. скришотцы с 91 Выделить код Код:data:image/png;base64,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 |
_zt > 13-05-2022 09:53:59 |
Dumby |
_zt > 13-05-2022 16:15:24 |
Dumby js Выделить код Код:// var {classes: Cc, interfaces: Ci, utils: Cu} = Components; // var {console} = Cu.import("resource://gre/modules/Console.jsm", {}); try {CustomizableUI.createWidget({ id: "ucf-cbbtn-Save", tooltiptext: "Сохранить страницу\n/ часть / выбранное", localized: false, get initCode() { delete this.initCode; return this.initCode = Cu.readUTF8URI(Services.io.newURI( "chrome://user_chrome_files/content/custom_scripts/custom_js/Save_Script.jsm" )); }, cbu: { types: { 128: "Bool", boolean: "Bool", 64: "Int", number: "Int", 32: "String", string: "String" }, getPrefs(pref) { try { return Services.prefs[`get${ this.types[Services.prefs.getPrefType(pref)] }Pref`](pref); } catch {return null;} }, setPrefs(pref, val) { Services.prefs[`set${this.types[typeof val]}Pref`](pref, val); } }, gClipboard: { get ch() { delete this.ch; return this.ch = Cc["@mozilla.org/widget/clipboardhelper;1"] .getService(Ci.nsIClipboardHelper); }, write(str) { this.ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard); } }, custombuttonsUtils: { writeFile(path, data) { try { if (path.includes(":\\")) path = path.replace(/\//g, "\\"); var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); file.exists() && file.remove(false); var strm = Cc["@mozilla.org/network/file-output-stream;1"] .createInstance(Ci.nsIFileOutputStream); strm.init(file, 0x04 | 0x08, 420, 0); strm.write(data, data.length); strm.flush(); strm.close(); } catch(ex) { Cu.reportError("Custom Buttons: " + [path, "---", ex, ex.stack].join("\n")); } } }, addDestructor(destructor, context) { this._destructors.push({destructor, context}); }, addEventListener(...args) { var trg = args[3]; if (!trg) trg = args[3] = this.ownerGlobal; trg.addEventListener(...args); this._handlers.push(args); }, onCreated(btn) { var win = btn.ownerGlobal; btn._handlers = new win.Array(); btn._destructors = new win.Array(); win.addEventListener("unload", this, {once: true}); new win.Function( "self,_id,cbu,xhtmlns,addDestructor,addEventListener,gClipboard,custombuttonsUtils", this.initCode ).call( btn, btn, this.id, this.cbu, "http://www.w3.org/1999/xhtml", this.addDestructor.bind(btn), this.addEventListener.bind(btn), this.gClipboard, this.custombuttonsUtils ); }, handleEvent(e) { var btn = e.target.getElementById(this.id); for(var args of btn._handlers) args.pop().removeEventListener(...args); delete btn._handlers; for(var {destructor, context} of btn._destructors) try {destructor.call(context, "destructor");} catch(ex) {Cu.reportError(ex);} delete btn._destructors; } });} catch(ex) {Cu.reportError(ex);} jsm Выделить код Код:self.label = "Save"; self._handleClick =()=> menuPopup.openPopup(this, "after_start"); self.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAABGklEQVQ4EaWSvQ4BQRSFd/3EUouGksIDiNBLvMAqtVoaiShUHkItIRGd1iN4A0ql2l8wvruxw67FJuR87p05d85OFsP482PKeaVUjWpDDKpwgyAd2GyZprmiPkXAWFbUIvSld2EdgQ5UYApzKLl+xG2+VAuvDjZcoAldQspUI0yAzMXlS+D6e6qEtKlvAVc2o/CqI4sJTMF5Z4Qc6OU2hrw0eq01XZLrjah+ldhYgEeeAJIVbg9CyxMgp3j6kFqAIK15SP/V8ARwOI95ZqhBfRP+QCmVx9+4pv9XiGNc4JPEkxnt+wO0EbbRAVwtwyELfsl6zDpzOoBVFlLwSzIjs86c88cgscbKhgSkYQtByrG5gxPMeJlL6n+6A9I+WoE5cj6LAAAAAElFTkSuQmCC"; var folderpath="E:\Download"; // папка для сохранения иконок для ярлыков и ярлыков сайтов // Создать меню для кнопки ............. var array = [ { label: "Сохранить favicon сайта", func: "saveFavicon()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACPVBMVEX09ff////C3L+Uq8+Vq8+Uqs+Zr9CZrtCZr9Gfu+ear8+mt9JRf8ORxl3t8vfF06+Twojs8/d9otl8o9s+aquZrs/X9KLp8Pft8fZhisf//+DBzN2hveihv+pii8hti9pgicl6oNlojs1zncNsi836/P2duebx8/eYyWqBp+Gn0IKBvlKHsm9qmaVuk8zt7/FEbauEv1Tp7/JdhL9oi9Pl8e2LwlmdsdD7/P76+/3H7ofo8+peh8eHwFaSteZ0pkp2gl7q8/Ohy5OApt2by2eZuOqbuOWaezWuvtd7nN2HvWxul9Ty9feQxV5ljcqBp+JEcLCVtOOo0nR7odx5n9suX6Z1mtBzmtSXyGPv9PewzfOzx+O6zu/s8fd9o95Xfrthi8lYhMN5oNnw9ffw9Pjw9Pf8/f6ewO/m8O9zmdE6aapsjdyUwouPxWPDzd6XteOSs9B5nNVpnpqHt7h/s6F6n9d7ntSTttGHwVh4qp+Ev1HH7ox6qk5wj+Hm8e3t9fOm0IKAtqOBpNrx+P9ljcyhs9FpkM2hv+/u8/fF0eOLu4N+vFKgzX3p9OSFqN13qExekIl4n9j7/P3x9PhxmNDm8e9Vg8Zfkozr8veq0YTX9qL//92AtamOwnHFz96Fot1diMh+pd13ntmatu+YyW/3+/+Tqs5UgcShzJNbhsdTf8GHs7bo8PaXtuqMr+Ty8/SZt+SUqs7r7Ox3ndb9/f7t8feZyXGYyWWCpNbz9PRuiteNtNDn7/V4ntjx8fGo3JqNAAAAv3RSTlP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AEVuhDkAAAD+SURBVBhXY5jHzcUMAqxAICq9bx8D96adDFAgaGQOFOBaH7h7zoqZDTlFyptncAAFWBjyi52CXCI0unRLxcECPhsatbbzmlXMnS60hg0kkOxW0uNrq93tNaFpD1ggUm21QK532ZQdSm1hmXKdDCwdnOWVOi1RjNGMQCCrwMDMJ8NZ4LAynVGPkXFp8zpJBubYmn579wXtqhZb0iwn9a1iWLaViYmJ3891obOwYtLEvcYMGyWAAkwJdv6accEhi8LjGVr11SenpC5f61g3NcO0vjCAIc+DjZ2dnWexddWSbYa9nlkM+8BgWsxsK7FZ1VLzRaACNokmtdnyu1QMQgF7Rlh4zWWTAwAAAABJRU5ErkJggg=="}, { label: "Копировать favicon в base64", func: "copyFaviconData()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAI2bv/9RVpf/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAACIkvD/Jia6/ywpq/8AAAAAAAAAAAAAAAAAAAD/AAAA/wbwAf90qpv/Ymic/1RWqP9OUKr/W2Ch/2dumf9YYKT/Ly/B/xQP3/8MB9P/JCGb/wAAAAAAAAAAAAAAAAAAAP8G8AH/U5ea/ycr8f8VIP3/HiP4/ywo8v8sIvb/LCL2/ywi9v8KBOj/BQDe/wQAtv8tK4P/AAAAAAAAAAAAAAD/BvAB/3Sqm/9iaJz/Tim3/0UuuP9GPrT/R0ex/zk8uf8gIMz/FRDe/xEMzv8jIJz/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8AAAD/SqOR/yImvP8sLKj/AAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/BvAB/3Sqm/9KW5r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAABvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAG8AH/AAAAAAAAAP8G8AH/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BvAB/wbwAf8AAAAAAAAA/wAAAP8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAG8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOesQQBjrEGAAaxBwACsQcABrEHDg6xBwAesQcAPrEHAD6xBw8+sQcPprEHD8axBwAGsQQABrEGAAaxB//+sQQ=="}, { separator: ''}, { label: "Сохранить ярлык страницы как…", func: "saveShortcuts()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP8E/yT/BP8k/5XLDv/zqgD/86oA//I1///yNf//86oA//OqAP/zqgD/86oA//OqAP+Vyw7/lcsO/wT/JP8E/yT/BP8k/5XLDv+Vyw7/86oA//OqAP/yNf//8jX///OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//02AP/9NgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/9NgD//TYA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA/wA31v8AN9b/86oA//9If///SH//86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP8AN9b/ADfW//OqAP//SH///0h///OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/5XLDv+Vyw7/86oA//OqAP/zqgD/86oA/0CA//9AgP//86oA/07+9f9O/vX/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP9AgP//QID///OqAP9O/vX/Tv71//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ=="}, { separator: ''}, { label: "Копировать изображение / текст в base64", func: "copyFaviconbase()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AIAQ/wCAEf8AgA//AIAR/wCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AgBX/AIAVAAAAAAAAAAD/AIAo/wCA//8AgP//AID//wCA//8AgP//AIAoAAAAAAAAAAAAAAAAAAAAAP8AgBL/AID//wCA//8AgA3/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgBAAAAAAAAAAAAAAAAD/AIAR/wCA//8AgP//AIAK/wCACv8AgP//AID//wCAIf8AgAX/AIAh/wCA//8AgP//AIAQAAAAAAAAAAAAAAAA/wCACv8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAUAAAAA/wCABf8AgP//AID//wCACgAAAAD/AIAQ/wCADP8AgCH/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCABf8AgCH/AID//wCA//8AgAv/AIAh/wCA//8AgP//AID//wCA//8AgP//AIAH/wCAB/8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AIAg/wCA//8AgP//AID//wCA//8AgP//AID//wCAB/8AgAf/AID//wCA//8AgP//AID//wCA//8AgP//AIAh/wCAC/8AgP//AID//wCAHP8AgBz/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCACf8AgA7/AIAMAAAAAP8AgAj/AID//wCA//8AgAP/AIAD/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCABQAAAAAAAAAA/wCADf8AgAr/AIAL/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCAB/8AgAr/AID//wCA//8AgCH/AIAH/wCAJf8AgP//AID//wCAI/8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAf/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgCT/AID//wCA//8AgAr/AIAK/wCA//8AgP//AIAKAAAAAP8AgCj/AID//wCA//8AgP//AID//wCA//8AgCP/AIAM/wCA//8AgP//AIAN/wCADf8AgP//AID//wCADQAAAAAAAAAA/wCAEP8AgBH/AIAP/wCAEf8AgBAAAAAAAAAAAP8AgBT/AIAVAAAAAAAAAAD/AIAV/wCAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQcH5rEGA8KxBAHCsQQBwrEEIQKxBAACsQQAArEEAAKxBAQCsQQwArEEAAKxBAACsQYAArEHBmaxB//+sQQ=="}, { separator: ''}, { label: "Сохранить страницу как PDF", func: "savePageToPDF()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYUw4pJt3V/+Rb1D8lnFP/55zTf+VcVH/lXJS/5VyUv+VclL/lXJS/5VyUv+VclL/k3BR/J56Wv9cRzSkAAAAAJNvUKTto2L/4ppe/uehZf/Pmmr/noZv/9Scav/Wl17/1plh/9eZYf/XmWH/15lh/9eZYf/WmGD/2Jlg/suRXP9mRiuk8rWA/397dP1akKn/rqqi/3LF3f8Mntj/4dLJ///+9f/48u3/9e7n//bt5v/47+f/+O/n//jv5//rvZP/1ZJX/a9/VP9+lrD8AIvz/xOt+f8Douv/ALb6/wC28/9tmar/z8jJ//Lq5/////7//v////n9///6/P3//////+Ta0P/PjVP/pnpT/IWds/+aiXj/5efl/8Px//951/3/LMz//wCx8/8GltL/NIu3/4ycqf/l29L////+//n6+//8/v//3tXM/8+OVP+oe1P/6K57/86QWP/r6Ob////////++v/r9/z/oOb9/zDL//8Arf//AI/r/ydysv+hpqr//PTr///////d1Mz/0I5U/6h7U//osH//wo5g/+fm5P/7/f//9vf5//z7+////vv/9/r8/5Dc/P8Oqv7/AJf//wF02v9ffZ7/8Ojh/+Ha1P/NjFL/qHtT/+ewf//Ej1//7O3r///////+/v7//v7+//f5+v/6+vv////8/8Tq/f8hp/7/AJH//wB18/8/bqj/1MGu/9mXXv+leVH/569+/8iSYv+/tKn/wLew/8O5sf/P0M////////7+/v/3+fv////7/9Hv/v8hoP3/AIn//wB4/v84ZqL/w4NH/619VP/nsYD/x45c/9W5of/bv6j/0Jxt/6J/YP+spqD/2N3i//7////6+/3///76/8vr/v8Slv7/AIb+/wBz//83VH7/nW1B/+ewfv/Fjl7/7Ozr///////9+/r/9d7K/9Ghdv+jd1D/pJ6Y/+jt8f/9///////7/6fb/v8Ahv7/AYD//wRp6f95YlT/57B//8SOXv/n5uT//v7///r7/P/8/v////////XRsv/DhEv/loBu/9DX3P/9/v/////7/2O6/f8Afv//FnTU/5JtTf/nsH//xY9e/+jn5f/+/f//+fj5//n4+P/5+Pn/+/////Xbxf/Wj1D/nX1h/+Ll6P////7/3+/3/w+V//8tcbP/qHJB/+WuffzCjV7/5efn///////+/v7//////////////v7///////XRsP/TnW3/8fT3//////////z/ddD//0Nxl/+zdkH88LmH/9CRWP2+qJT/0M7N/8/Jxv/Pysf/z8rH/8/Kxv/Py8n/zsO6/7+pmP/PzMv/zsnG/9bNyP+nsK7/h4R3/b2BT/+Sb1Ck7qxw/9GSW/69hlb/wYhX/8CIV//AiFf/wIhX/8CIVv/BiVj/xI1d/8CIVv/BiFf/vYZW/9STW/7ppmv/bE80pAAAAACUd16k+sui/+7AmPzwwpr/8MKa//DCmv/wwpr/8MKa//DCmf/vwZj/8MKa//DCmv/uwJj8+cui/5N3XaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, { label: "Сохранить страницу / выбор как HTML", func: "savePageToHTML()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzElEQVQ4jV2STW8bZRDHf/Psrr11nZhgVKcKaSmUiArRKBRVIMgH4BKJ7xAp5MSFiA+Rc28ckBAoipC4koJQLyAaVFChIlQllDRWmjRev8Qvu14/+wwHx6ZlpNFcZn7zn79GVJW1tbXc6urqijHGqKoAPF3TgcVaq8owXJbphx99fOOnWzcHoqqsr68/t7y83BARVBXnHHraXo3a3HoUU8gFAHRTS2Bg/7C2Zx7vXPIBwjA0p3BU9Zns9i3vvVrhr6MWzlpee+EsRqAbHc3+/Pee7wPkcrkx4P+g0IMvb/5Iv5/iXEaWZQS+By578MaVy9YH8H3fE5FnANZajqMmgcAnH7yN73mICMYMd21sbLy7srKiPkA+n3/qBLhzv8p+EuOfTUjShPbODvOVWa5fnRsvKBaLAcAIMFbw+bc/EBVn8At7SPcQ60LSiVm++P0fGu0e7y++yalvHoABCILAiAj7hzU+vfcVT6zPVGmR3x4/xJoLSH6BVu4cN777nnQwQETI5XL/AYwxRkS4ff8BEk6Q2pBfq3dxUuHMmWt0kgFGStTDY/7YrTLybQwYPU2cpgzsCd1OgmSzWHeOR7VjWicxaT9lxn+HfjoYmWnGHgAiIsydf5HKnUXiThehQDG4Tr3e5KR7hN8XilnGKxfOoyrDgZECwIgIb125xIxxTGVdgjRG4pR2+zbG/sIkD7l2cYJyaYLMOZxzjBV4nueLCI1GnaWFab65t4OXt4gUuFqYJ8gGuPYBCxdLHNciys9PkaapjAHGGM8YQ7lcZv71OaYmC/xZPaJHTN4cUgpDXrr8MtOVaUqTRXzfY3t7u7O0tDR82a2trfkkSTSOY+31etrpdLTZbGoURRpFkdbrTY3qTW00mhrHse7u7t4tl8uhqg4VxHHcPDg4+ExVHeBU1YmIU1WnisucZtamLszn01ar9WRzc/PrWq2WAPwLJ7l2ULfXOAMAAAAASUVORK5CYII="}, { label: "Сохранить выбранный текст как TXT", func: "saveSelectionToTxt()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAQE6AAAAZAAAAGgAAAJmAAACZgAAAGYAAABmAAAAZgAAAGYAAABmAAAAZgAAAGYAAABlAAAAaQABAmYAAQEjAAAAADlVkOdVcKHxVXKi8kdklPJLZpfyU3Cg8lJvn/JRbZ7yUW+g8lFun/JRbp/yUG6e8lVyofFVdKjzLkV45wAAAFABAQEAaIzF/3y34v9wsuL/cJe0/0lpgv9bjLP/dLLh/2+v3v9sq9v/cK3d/3Gv3v9sqtv/b7Df/4G77P9VcqT2AAAAVAMDAQBnir/+ZqfU/pDB4/7a3uD+j46N/kxYXv6To6/+1er4/tXp+P7J3/D+1ej4/svg8v6Gut/9aqzd/lhxnvAAAABSAwIBAGaIvv9pptX/ocfj//f4/P/P0tX/g4CA/1xZWf+Woqr/2uz8/9Hl+f/W5fT/2Of3/5fC4v5tq93/Vm+e8QAAAFIDAgEAaYm+/3mw2/+iyeX/9Pn8/+z0+//IzNL/d3h5/0tMTv+Mkpn/xdvs/9Hp/f/O4PL/msXk/nmz4/9XcJ/xAAAAUgMDAQBti7//k7/h/6fL5v/v9fn/4u73/9Dk9P+8wMT/YGpx/zJJWv94iJf/ztzo/9Pp/P+ZwuD+gLfk/1dwnvEAAABSAwMBAHOPwf+myub/sNHp//j7/P/6/P3/8fr///r39P+sxdP/IXWq/xJJcv+NjZD/0+Lu/6TN7f6Ft+L/WXGf8QAAAFIDAwEAd5LD/7PR6/+ZxOP/0ePx/97r9f/Y5/L/3e32/8Tc7f9gseT/CHK3/zBYdv+HiY7/lL/f/pLE7/9bcJ3xAAAAUgMDAQB4k8P/xNvx/5/F5f+kyOX/qMrn/6TH5f+kyOX/sM/q/5e51P9Mm83/GHm3/xxIav9fdYf+pMvs/1x1pfIAAABTAwMBAHmSxf/O4/T/y9/y/8Hb9P/C3PX/wNv0/7vW7/+93ff/utDm/42fsf9Gjbn/EXS2/ytSbv6Fj5r/WnGc8gAAAFICAwEBepPE/tHk9f/S5PX/vMjV/7fCzP+3w8//uMPP/7XBzP+6ytf/qa+4/3h/hv9Ghaz/JoO+/jNXdP82PVnyAAAAVgACAgCBmcb/2+r3/dHh8fyPkpX/kI6N/5yam/+dnJ3/paWk/6enpf+sr6//mpSR/3Bubf9SjbD8H4C+/QsrSvcCAAB/AAAAA3yVx//j8///3u/7/52gpf6pqKf+uLm5/rq7u/7Ly8v+ycnI/paWlf6LjY/+np2f/Xh+g/5gnL7/MX+y/xcgJ80BAgNNN1OUs6W84fDA1O73mJyj/ainpv+2trb/t7e4/8fHyP/Fxsb/kZGQ/4eGhP+vucT/j6G+/W53k/NlkbnwNoOv/AgiNb8CCBsQDRo/YwsaO3B0d33arKyp9q2trfWvr6/2u7u79ru7vPawr7H1sbCt9nJ2gOQIGD6bFCFEYB0qPE1Bf6SpEz9cggAAAAMCAQEBAQAAADIyMmlDQ0ONQUFBhUFBQYVCQkGFQkJBhUhISIRNTU2OKysrZAEAAAUBAQAAAgEAAAkEAAEDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, { separator: ''}, { label: "(Меню ПКМ) Сохранить текст в файл", value: "Save.SelectionToFile" }, { label: "(Меню ПКМ) Открыть текст в редакторе", value: "Save.TextToEditor"}, ]; var menuPopup = self.appendChild(document.createXULElement("menupopup")); array.forEach((m,i)=> { if ("separator" in m) { menuPopup.appendChild(document.createXULElement("menuseparator")); return }; var mItem = menuPopup.appendChild(document.createXULElement("menuitem")); mItem.setAttribute("label", m.label); mItem.setAttribute("class", "menuitem-iconic"); if ("image" in m) mItem.setAttribute("image", m.image || array[i-1].image); if ("value" in m) { mItem.setAttribute('type', 'checkbox'); mItem.setAttribute('checked', cbu.getPrefs(m.value) ); mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value)); } if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString())); }); menuPopup.setAttribute("onclick", "event.stopPropagation()"); function aDate() { var t=new Date(); var y=1900+t.getYear(); var min=t.getMinutes(); if (min<10){min="0"+min}; var h=t.getHours(); var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";} var d=t.getDate(); var curdate=d+" "+m+" "+y+" "+"г"; var myfilename=curdate; return myfilename; } function WebScreenShotonImage(image) { var canvas = document.createElementNS(xhtmlns, 'canvas'); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; var ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); var base64 = canvas.toDataURL(); gClipboard.write(base64); // стиль для изображение в сплывающей подсказке .... var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(base64, self.label, "Изображение копировано как base64", false, "", (s, t)=> { if (t == 'alertfinished') sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается }, ""); }; var saveToFile = function (fileContent, fileName) { var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); uc.charset = 'utf-8'; fileContent = uc.ConvertFromUnicode(fileContent); var nsIFilePicker = Components.interfaces.nsIFilePicker; var fp = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker); fp.init(window, '', fp.modeSave); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); fp.open(function (rv) { if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) { var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream); stream.init(fp.file, 0x02|0x20|0x08, 0666, 0); stream.write(fileContent, fileContent.length); stream.close(); } }); }; function savePageToHTML() { var vert=`javascript:(function(){var getSelWin=function(w){if(w.getSelection().toString())return w;for(var i=0,f,r;f=w.frames[i];i++){try{if(r=getSelWin(f))return r}catch(e){}}};var selWin=getSelWin(window),win=selWin||window,doc=win.document,loc=win.location;var qualifyURL=function(url,base){if(!url||/^([a-z]+:|%23)/.test(url))return url;var a=doc.createElement('a');if(base){a.href=base;a.href=a.protocol+(url.charAt(0)=='/'%3F(url.charAt(1)=='/'%3F'':'//'+a.host):'//'+a.host+a.pathname.slice(0,(url.charAt(0)!='%3F'&&a.pathname.lastIndexOf('/')+1)||a.pathname.length))+url}else{a.href=url};return a.href};var encodeImg=function(src,obj){var canvas,img,ret=src;if(/^https%3F:%5C/%5C//.test(src)){canvas=doc.createElement('canvas');if(!obj||obj.nodeName.toLowerCase()!='img'){img=doc.createElement('img');img.src=src}else{img=obj};if(img.complete)try{canvas.width=img.width;canvas.height=img.height;canvas.getContext('2d').drawImage(img,0,0);ret=canvas.toDataURL((/%5C.jpe%3Fg/i.test(src)%3F'image/jpeg':'image/png'))}catch(e){};if(img!=obj)img.src='about:blank'};return ret};var toSrc=function(obj){var strToSrc=function(str){var chr,ret='',i=0,meta={'%5Cb':'%5C%5Cb','%5Ct':'%5C%5Ct','%5Cn':'%5C%5Cn','%5Cf':'%5C%5Cf','%5Cr':'%5C%5Cr','%5Cx22':'%5C%5C%5Cx22','%5C%5C':'%5C%5C%5C%5C'};while(chr=str.charAt(i++)){ret+=meta[chr]||chr};return'%5Cx22'+ret+'%5Cx22'},arrToSrc=function(arr){var ret=[];for(var i=0;i<arr.length;i++){ret[i]=toSrc(arr[i])||'null'};return'['+ret.join(',')+']'},objToSrc=function(obj){var val,ret=[];for(var prop in obj){if(Object.prototype.hasOwnProperty.call(obj,prop)&&(val=toSrc(obj[prop])))ret.push(strToSrc(prop)+': '+val)};return'{'+ret.join(',')+'}'};switch(Object.prototype.toString.call(obj).slice(8,-1)){case'Array':return arrToSrc(obj);case'Boolean':case'Function':case'RegExp':return obj.toString();case'Date':return'new Date('+obj.getTime()+')';case'Math':return'Math';case'Number':return isFinite(obj)%3FString(obj):'null';case'Object':return objToSrc(obj);case'String':return strToSrc(obj);default:return obj%3F(obj.nodeType==1&&obj.id%3F'document.getElementById('+strToSrc(obj.id)+')':'{}'):'null'}};var ele,pEle,clone,reUrl=/(url%5C(%5Cx22%3F)(.+%3F)(%5Cx22%3F%5C))/g;if(selWin){var rng=win.getSelection().getRangeAt(0);pEle=rng.commonAncestorContainer;ele=rng.cloneContents()}else{pEle=doc.documentElement;ele=(doc.body||doc.getElementsByTagName('body')[0]).cloneNode(true)};while(pEle){if(pEle.nodeType==1){clone=pEle.cloneNode(false);clone.appendChild(ele);ele=clone};pEle=pEle.parentNode};var sel=doc.createElement('div');sel.appendChild(ele);for(var el,all=sel.getElementsByTagName('*'),i=all.length;i--;){el=all[i];if(el.style&&el.style.backgroundImage)el.style.backgroundImage=el.style.backgroundImage.replace(reUrl,function(a,b,c,d){return b+encodeImg(qualifyURL(c))+d});switch(el.nodeName.toLowerCase()){case'link':case'style':case'script':el.parentNode.removeChild(el);break;case'a':case'area':if(el.hasAttribute('href')&&el.getAttribute('href').charAt(0)!='%23')el.href=el.href;break;case'img':case'input':if(el.hasAttribute('src'))el.src=encodeImg(el.src,el);break;case'audio':case'video':case'embed':case'frame':case'iframe':if(el.hasAttribute('src'))el.src=el.src;break;case'object':if(el.hasAttribute('data'))el.data=el.data;break;case'form':if(el.hasAttribute('action'))el.action=el.action;break}};var head=ele.insertBefore(doc.createElement('head'),ele.firstChild);var meta=doc.createElement('meta');meta.httpEquiv='content-type';meta.content='text/html; charset=utf-8';head.appendChild(meta);var title=doc.getElementsByTagName('title')[0];if(title)head.appendChild(title.cloneNode(true));head.copyScript=function(){if('$'in win)return;var f=doc.createElement('iframe');f.src='about:blank';f.setAttribute('style','position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;');doc.documentElement.appendChild(f);var str,script=doc.createElement('script');script.type='text/javascript';for(var name in win){if(name in f.contentWindow||!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name))continue;try{str=toSrc(win[name]);if(!/%5C{%5Cs*%5C[native code%5C]%5Cs*%5C}/.test(str)){script.appendChild(doc.createTextNode('var '+name+' = '+str.replace(/<%5C/(script>)/ig,'<%5C%5C/$1')+';%5Cn'))}}catch(e){}};f.parentNode.removeChild(f);if(script.childNodes.length)this.nextSibling.appendChild(script)};head.copyScript();head.copyStyle=function(s){if(!s)return;var style=doc.createElement('style');style.type='text/css';if(s.media&&s.media.mediaText)style.media=s.media.mediaText;try{for(var i=0,rule;rule=s.cssRules[i];i++){if(rule.type!=3){if((!rule.selectorText||rule.selectorText.indexOf(':')!=-1)||(!sel.querySelector||sel.querySelector(rule.selectorText))){style.appendChild(doc.createTextNode(rule.cssText.replace(reUrl,function(a,b,c,d){var url=qualifyURL(c,s.href);if(rule.type==1&&rule.style&&rule.style.backgroundImage)url=encodeImg(url);return b+url+d})+'%5Cn'))}}else{this.copyStyle(rule.styleSheet)}}}catch(e){if(s.ownerNode)style=s.ownerNode.cloneNode(false)};this.appendChild(style)};var sheets=doc.styleSheets;for(var j=0;j<sheets.length;j++)head.copyStyle(sheets[j]);head.appendChild(doc.createTextNode('%5Cn'));var doctype='',dt=doc.doctype;if(dt&&dt.name){doctype+='<!DOCTYPE '+dt.name;if(dt.publicId)doctype+=' PUBLIC %5Cx22'+dt.publicId+'%5Cx22';if(dt.systemId)doctype+=' %5Cx22'+dt.systemId+'%5Cx22';doctype+='>%5Cn'};var href = 'data:text/html;charset=utf-8,' + encodeURIComponent(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->');var a = document.documentElement.appendChild(document.createElement("a"));a.setAttribute("href", href);var name = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());name=name.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');name += (function () {var d = new Date(), z=function(n){return '_' + (n < 10 ? '0' : '') + n};return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());})();a.setAttribute("download", name + ".html");a.click();a.remove();})();`; gBrowser. loadURI(vert, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }; function saveShortcuts() { var file = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsIFile); file.initWithPath(folderpath); if( !file.exists() || !file.isDirectory() ) { file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0x1B6);} var savetodir=folderpath+"\\"; var urllink=gBrowser.currentURI.spec; var out=getTabLabel(); var filename=savetodir+out+'.url'; var data="[InternetShortcut]\r\nURL="+urllink+"\r\n"; saveToFile(data, filename); // стиль для изображения во всплывающей подсказке .... var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); // подсказка var notific = 'Сохранил в: ' + folderpath; var image = gBrowser.selectedBrowser.mIconURL; Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(image, filename, notific); }; // Кодировать изображение или текстовой файл в base64 ............. function copyFaviconbase(){ var fp = window.makeFilePicker(); fp.init(window, "Открыть файл", fp.modeOpen); fp.appendFilter("Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml; *.xhtml; *.jpe; *.jpg; *.jpeg;\ *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw"); fp.open(re=> { if ( re != fp.returnOK ) return; var file = fp.file; var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); inputStream.init(file, 0x01, 0600, 0); var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); stream.setInputStream(inputStream); var encoded = btoa(stream.readBytes(stream.available())); var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file); var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded; gClipboard.write(dataURI); //Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Текст скопирован как base64"); // стиль для изображение в сплывающей подсказке .... var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); // alertsService.showAlertNotification(base64, self.label, "Изображение скопировано как base64", false, "", (s, t)=> { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Изображение скопировано как base64", false, "", (s, t)=> { if (t == 'alertfinished') sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается }, ""); }); }; // Сохранить страницу как PDF файл через сервис 'pdfmyurl.com' ............. function savePageToPDF() { var loc = gBrowser.currentURI.spec; var vert = "http://pdfmyurl.com?url=" + loc; gBrowser. loadURI(vert, { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }); }; if (typeof window.saveImageURL != "function") var saveImageURL = internalSave.length == 15 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, a7, a5, null, priv, prin); // Сохранить иконку текущего сайта с диалогом сохранения ............. function saveFavicon() { var uri = gBrowser.currentURI; function getSiteName() { try { var domain = uri.host.split('.') } catch(e) { return "" }; domain = (domain.length == 2) ? domain[0] : domain[1] return domain.charAt(0).toUpperCase() + domain.slice(1).split('.')[0] + " "; }; var url = gBrowser.selectedTab.image; url && saveImageURL( url, getSiteName(), null, false, false, null, null, /^data:(image\/[^;,]+)/i.test(url) ? RegExp.$1.toLowerCase() : Cc["@mozilla.org/mime;1"] .getService(Ci.nsIMIMEService).getTypeFromURI(Services.io.newURI(url)), null, PrivateBrowsingUtils.isContentWindowPrivate(content || window), document.nodePrincipal ); }; // Копировать иконку текущего сайта в base64 ............. function copyFaviconData() { var img = new Image(); img.src = gBrowser.selectedTab.image; WebScreenShotonImage(img); }; // Сохранить выделенный текст или весь текст на странице как txt файл ............. function saveSelectionToTxt() { let browserMM = gBrowser.selectedBrowser.messageManager; browserMM.addMessageListener('getSelection', function listener(message) { var sel = message.data; !sel && document.getElementById("cmd_selectAll").doCommand(); // создать название файла из заголовка страницы и текущего времени и сохранить текст .... var fileTitle = getTabLabel() + ' ' + aDate().replace(/:/g, "."); saveURL("data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + ("\r\n\r\n" + sel)), fileTitle + ".txt", null, false, false, null, window.document); !sel && goDoCommand("cmd_selectNone"); browserMM.removeMessageListener('getSelection', listener, true); }); browserMM.loadFrameScript('data:,sendAsyncMessage("getSelection", content.document.getSelection().toString())', false); }; // Добавляем в контекстного меню страницы новые пункты ............. ((contextMenu, el)=> { // в контекстного меню выделенного текста .... var saveItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el); saveItem.id = "content-saveItem"; saveItem.setAttribute("label", "Сохранить выбранный текст в файл"); saveItem.setAttribute("class", "menuitem-iconic"); saveItem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); saveItem.onclick =()=> saveSelectionToFile(); var editorItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el); editorItem.id = "content-editorItem"; editorItem.setAttribute("label", "Открыть выбранный текст в редакторе"); editorItem.setAttribute("class", "menuitem-iconic"); editorItem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAA////AIiafwC85K4AS1ZGANLsyABKU0UAy+m+AL/lsQC14aQAn9WMAJ/QjQCsrKwAqNyXAOPz3ADe8dcA2e/QANPtyQDM68EAxei4AL7lrwC14aUArt6dAJfOhACdz4sAgICAALThpQDg8doA3vHVANjuzgDR7MYAyum+AMLmtQC7460AsuCjAK3dmgCUy4AArdedANDsxQDL6sAAz+PIAMviwwDH4L4Awd62ALvbrwC02KcArdafAKbTlgCEu3EAtNWoANPqywDa8NIA1u7NANHtxwDK6cAAw+e3ALzkrwC14aYAr9+dAKXbkQCJwnMA1+3QAKncmADd8dQAyuLBAMbgvAC6264AttmoAK/XoACn1JYAotKPAJbNgwB9tWgA4+zfANju0ADT7coAz+vFAMPntgC95K8Art6eAKndlQCa1IYAi8R3AP3+/QDD37kAvt2yALjarACz2KYArdaeAKHRjwCXzoUAj8V6AI6/ewDu8e4Awea2AMrqwQDG6LoAweazALnjqwCz4KQAr9+cAKbbkwCd2IkAlc1/AKbTlQC73K8At9qqALDXowCp1ZsApdOVAKDRjQCYzoUAksx7AIi+cwCu0aEAp9yUAMXougDC5rYAveSuALfipwCw4J8AqdyXAKLajwCd2IcAlNR9AI3FdwDU6ssAqdWZAKPSkgCe0YsAmc6GAJDLfQB/tmoA3enZAJfWhACc2IkApNuRAKTbkACj2pAAodqOAKHZjgCl25IAotmOAIzHdgAPAAAA2JIKAAAA9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOzARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcrkUA9CUMAAAAAAAAAAAAAAAAAAAAAAAAAA8AAQAAAAEAAAAAAAAAVCIMAAAAAAABAAAAuwP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAACZDSMAAQAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAABAEAABHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGRkZGRkZGRkZAAAAAAAZAQEBAQEBAQEBARkAAIeHiImKi4yNjY5+AQEZAD4mJlZXRH+AgYKDhIVdGQBzJnR1dnd4eXp7fH1+ARkAGiYnaWprbG1ub3Bxcl0ZACdeJl9gYWJjZGVmZ2gBGQAAAyZUVVZXWEVZWltcXRkAAA1KS0wfTU45T1BRUlMZAAA+P0BBK0JDREVGR0hJGQAAAzIzNDU2Nzg5Ojs8PRkAACYnKCkqKywtLi8YMDEZAAAAGhscHR4fICEiIyQlGQAAAA0ODxAREhMUFRYXGBkAAAADBAUGBwYIBgkGChkAAAAAAAACAAIAAgACAAIAAPgBAADwAAAAwAAAAIAAAACAAAAAgAAAAIAAAADAAAAAwAAAAMAAAADAAAAAwAAAAOAAAADgAAAA4AEAAPqrAAA="); editorItem.onclick =()=> textToEditor(); // устанавливаем где и при каких настройках показывать новые пункты .... addEventListener('popupshowing', e=> { if (e.target != e.currentTarget) return; var sel = gContextMenu.isTextSelected; saveItem.hidden = !sel || !cbu.getPrefs("Save.SelectionToFile"); editorItem.hidden = !sel || !cbu.getPrefs("Save.TextToEditor"); }, false, contextMenu); // удалять новые пункти при изминениях .... addDestructor(()=> { saveItem.remove(); editorItem.remove(); }); })(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open")); // Сохранить выделенный текст в файл на рабочем столе ............. function saveSelectionToFile() { let browserMM = gBrowser.selectedBrowser.messageManager; browserMM.addMessageListener('getSelect', function listener(message) { // создать текст для записи var url = gBrowser.currentURI.spec; if (/\.рф/.test(url.host)) url = convertFromUnicode("UTF-8", url); var time = convertFromUnicode("UTF-8", aDate().replace(/:/g, ".")); var text = convertFromUnicode("UTF-8", message.data); var title = convertFromUnicode("UTF-8", getTabLabel()); var text = "..............................................................\n" + title + " - " + time + "\n" + url + "\n\n" + text + "\n\n\n"; var text = text.replace(/\u000A/g, "\u000D\u000A").replace(/\u000D\u000D\u000A/g, "\u000D\u000A"); // путь к файлу и название файла var file = Services.dirsvc.get("Desk", Ci.nsIFile); file.append("Save - " + (aDate().replace(/:/g, ".")) + ".txt"); // создать файл с текстом или добавлять текст в файл var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); file.exists() ? foStream.init(file, 0x02 | 0x10, 0664, 0) : foStream.init(file, 0x02|0x08|0x20, 0666, 0); foStream.write(text, text.length); foStream.close(); // всплывающая подсказка дает возможность открыть файл если кликнуть на подсказке var notificat = 'Сохранил выделенный текст в файл на рабочий стол'; var image = gBrowser.selectedTab.image || self.image; Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService) .showAlertNotification(image, notificat, "Кликни чтобы открыть файл", true, "", (s, t)=> { if (t == 'alertclickcallback') file.launch(); }, ""); browserMM.removeMessageListener('getSelect', listener, true); }); browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false); }; // Создать текстовой файл с выделенным текстом в папке профиля и открыть в редакторе ............. function textToEditor() { let browserMM = gBrowser.selectedBrowser.messageManager; browserMM.addMessageListener('getSelect', function listener(message) { // создать текст для записи var text = convertFromUnicode("UTF-8", message.data); var file = Services.dirsvc.get('ProfD', Ci.nsIFile); file.append("TextToEditor.txt"); custombuttonsUtils.writeFile(file.path, text); file.launch(); browserMM.removeMessageListener('getSelect', listener, true); }); browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false); }; // Конвертировать текст в юникод ............. function convertFromUnicode(charset, str) { var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); converter.charset = charset; str = converter.ConvertFromUnicode(str); return str + converter.Finish(); }; // Получить название вкладки без не сохраняемых символов и лишних пробелов .............. function getTabLabel() { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); }; ((main, parts) => this.onmousedown = e => { if (e.button) return; this.onmousedown = null; var df = MozXULElement.parseXULToFragment(` <menugroup orient="vertical"> <menuseparator/> <menuitem class="menuitem-iconic" image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" label="Сохранить всю страницу как PNG" value="all"/> <menuitem class="menuitem-iconic" image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" label="Сохранить видимую часть как PNG" value="page"/> <menuitem class="menuitem-iconic" image="data:image/x-icon;base64,AAABAAEAIBkAAAEAIAAMDQAAFgAAACgAAAAgAAAAMgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29fT/2tra/8jIyP/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8jIyP/a2tr/9vX0/+zs7P/ak0b/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/9qTRv/s7Oz/7Ozs/+J9Dv/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+/6SdmP/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/+vn4//z7+v/6+fj/4n0O/+zs7P/s7Oz/4n0O//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/aFtT//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//j39v/ifQ7/7Ozs/+zs7P/ifQ7/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P9oW1P/7+zq/+/s6v/v7Or/8O3r//Dt6//w7ev/8O3r//Dt6//w7ev/8O3r/+/s6v/w7ev/9fTy/+J9Dv/s7Oz/7Ozs/+J9Dv/49/b/+Pf2//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4/2hbU//q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/y8O//4n0O/+zs7P/s7Oz/4n0O//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/aFtT/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe//Dt6//ifQ7/7Ozs/+zs7P/ifQ7/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P9oW1P/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/7uro/+J9Dv/s7Oz/7Ozs/+J9Dv/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx/2hbU//x7+3/8vDv//Hv7f/x7+3/8e/t//Lw7//x7+3/8e/t//Lw7//x7+3/8vDv//Hv7f/29fT/4n0O/+zs7P/s7Oz/4n0O//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//aFtT/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/8vGwf/ifQ7/7Ozs/+zs7P/ifQ7/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f9nWlL/aFtT/2hbU/9nWlL/Z1pS/2hbU/9oW1P/Z1pS/2daUv9oW1P/aFtT/2hbU/9nWlL/pJyX/+J9Dv/s7Oz/7Ozs/+J9Dv/w7ev/8O3r//Dt6//w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Hv7f/w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Dt6//w7ev/4n0O/+zs7P/s7Oz/4n0O/+/s6v/v7Or/7uro/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/u6uj/7+zq/+/s6v/ifQ7/7Ozs/+zs7P/ifQ7/7uro/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7Ojm/+J9Dv/s7Oz/7Ozs/+J9Dv/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/4n0O/+zs7P/s7Oz/4n0O/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/ifQ7/7Ozs/+zs7P/ifQ7/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+J9Dv/s7Oz/7Ozs/+J9Dv/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/4n0O/+zs7P/s7Oz/4n0O/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/ifQ7/7Ozs/+zs7P/ifQ7/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+J9Dv/s7Oz/7Ozs/+J9Dv/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/k39z/4n0O/+zs7P/s7Oz/4n0O/+Lc2f/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/ifQ7/7Ozs/+zs7P/ifQ7/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+J9Dv/s7Oz/9fTy/+J9Dv/8+/r/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/4n0O//X08v/8+/r/6KFU/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ooVT//Pv6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" label="Сохранить выбранный элемент как PNG" value="click"/> <menuitem class="menuitem-iconic" image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAADDn2Hfz5pE/8eVQP7IlkH/yJZB/8iWQf/IlUH/yJVA/8iVQP/IlED/yJQ//8iUP//IlD//yJM+/8iTPv/Hkj3/nI1w//bDbP//8OH//+zW///s1///69b//+rV///p1P//59L//+XQ///izf//38n//9vG///ZxP//1b///dG////Prf/KlkX/88N4/v37///99Pj//fT6//vy9v/68fT/+u/y//rt8P/66u3/+ufq//rl6P/64eT/+93h//3a3//71d7//9LK/86XR//0xHb//vv////18///9fT///f5///4////9f7///P8///v+f//7Pb//+nz///m8f//4eb//9vZ//3Y2v//1Mb/zphH//TGd//+/////Pj1///7///Q58r/m9aV/6TZnv+i15r/otWY/6LTlv+j0pb/mc6M/9DXuf//3+P//Nnc///Wyf/OmUf/9MZ3//7////8+/j//////53WnP+Y5pn/rvGv/6PvpP+e7p//me6b/5nvm/95533/mM+L///j7f/629z//9jL/86ZR//0xnf//v////z9+v//////qtup/8Xzxf/a/tn/z/vO/8n7yf/D+sL/xPvD/6Hzo/+j05b//+Tu//re3///2cz/zplI//XGeP/+/////P36//////+n26f/uvC6/9T71P/K+Mr/xvjG/8D3wP+/+L//nfCf/6LTlf//5u//+t/g///cz//OmUj/9MZ3//7////8/fr//////6rcqv/G9MX/3//f/9n92f/V/NX/0PzQ/9H+0P+s9a7/pdSY///o8f/64OL//9zP/86aSP/0xnf//v////z9+f//////ndid/5TjlP+v7q//qeyp/6jsqf+k7KX/p+6n/4Tlh/+Z0Y7//+r0//rh4v//3tH/zppI//TGd//+/////v77///////Y8Nj/p9+n/6/jr/+t4a3/rd2p/67bpv+u2ab/p9Wc/9jgx///6Oz//OPl///e0f/Omkj/9MV1//7//////fr///78///+/f///////////////////P////j////0+///8fn//+vu///m4v/94+P//97P/86ZSP/zx3v//v/////+/f///////f////v////7////+/////v+///7+///+/f///vz/P/98Pr//+33//3p9///5OL/zppL//a1Sv/0xoL/9cR7//XEfP/1xHz/9cR8//XEfP/1xH3/9cR8//XCev/1wXr/9b94//W9d//1u3X/87l0//y6bP/Llj7/+pMA/vWBAP/1gwD/9YMA//WDAP/1gwD/9YMA//WDAP/1gwD/9YQA//WEAP/1hAD/9YQA//WEAP/zhAH//okA/8qLIv3xpzP/4ptV/+OdU//jnVP/451T/+OdU//jnVP/451T/+OdU//jnVL/451S/+OdUv/jnVL/451S/+GdVf/qnUf/2aRJ/9q0c9/8yn7/98V5/vjGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6/vrIe/+jj2y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" label="Сохранить выбранную область как PNG" value="clipping"/> </menugroup> `); var menugroup = df.firstChild; menugroup.setAttribute("context", ""); menugroup.setAttribute("oncommand", "handleCommand(event);"); menugroup.handleCommand = e => { var name = _id + ":DataURLReady"; main = main.replace("%MESSAGE_NAME%", name); var urls = {}, configurable = true, enumerable = true; Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, { configurable, enumerable, get() { var value = `data:;charset=utf-8,({${ encodeURIComponent(main + part) }%0A}).init("${key}")`; Object.defineProperty(urls, key, {configurable, enumerable, value}); return value; }})); var getTabLabel = () => { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); } var listener = msg => { var fp = makeFilePicker(); fp.init(window, "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); fp.defaultString = getTabLabel() + ".png"; fp.open(res => { if (res == fp.returnCancel || !fp.file) return; var wbp = makeWebBrowserPersist(), args = [ Services.io.newURI(msg.data), document.nodePrincipal, null, null, null, null, fp.file, null ]; //wbp.saveURI.length == 9 && splice(args); var {length} = wbp.saveURI; length >= 9 && splice(args); length == 10 && args.splice(3, 0, null); wbp.saveURI(...args); }); } var splice = arr => { var fox74 = parseInt(Services.appinfo.platformVersion) >= 74; var args = [fox74 ? 7 : 2, 0, fox74 ? Ci.nsIContentPolicy.TYPE_IMAGE : null]; (splice = arr => arr.splice(...args))(arr); } messageManager.addMessageListener(name, listener); addDestructor(() => messageManager.removeMessageListener(name, listener)); (menugroup.handleCommand = e => gBrowser.selectedBrowser.messageManager .loadFrameScript(urls[e.target.value], false) )(e); } menuPopup.querySelector('menuitem[label*="ярлык"]').after(df); })(` init(cmd) { cmd.startsWith("c") ? this[cmd].init(this[cmd].parent = this) : this[cmd](); }, capture(win, x, y, width, height) { var canvas = win.document.createElementNS("${xhtmlns}", "canvas"); canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); var tryDraw = ind => { try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")} catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);} } tryDraw(17); sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png")); }, `, { all: `all() { var win = content; this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY); }`, page: `page() { var win = content, doc = win.document, body = doc.body, html = doc.documentElement; var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft; var scrY = (body.scrollTop || html.scrollTop) - html.clientTop; this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight); }`, clipping: `clipping: { handleEvent(e) { if (e.button) return false; e.preventDefault(); e.stopPropagation(); switch(e.type) { case "mousedown": this.downX = e.pageX; this.downY = e.pageY; this.bs.left = this.downX + "px"; this.bs.top = this.downY + "px"; this.body.appendChild(this.box); this.flag = true; break; case "mousemove": if (!this.flag) return; this.moveX = e.pageX; this.moveY = e.pageY; if (this.downX > this.moveX) this.bs.left = this.moveX + "px"; if (this.downY > this.moveY) this.bs.top = this.moveY + "px"; this.bs.width = Math.abs(this.moveX - this.downX) + "px"; this.bs.height = Math.abs(this.moveY - this.downY) + "px"; break; case "mouseup": this.uninit(); break; } }, init() { var win = {}; Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, win); this.win = win.value; this.doc = this.win.document; this.body = this.doc.body; if (!HTMLBodyElement.isInstance(this.body)) { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService) .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!"); return false; } this.flag = null; this.box = this.doc.createElement("div"); this.bs = this.box.style; this.bs.border = "#0f0 dashed 2px"; this.bs.position = "absolute"; this.bs.zIndex = "2147483647"; this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor; this.body.style.cursor = "crosshair"; ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)]; this.body.style.cursor = this.defaultCursor; this.body.removeChild(this.box); this.parent.capture.apply(this, pos); ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }`, click: `click: { getPosition() { var html = this.doc.documentElement; var body = this.doc.body; var rect = this.target.getBoundingClientRect(); return [ this.win, Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft, Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop, parseInt(rect.width), parseInt(rect.height) ]; }, highlight() { this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false; this.target.style.cssText += "outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;"; }, lowlight() { if (this.orgStyle) this.target.style.cssText = this.orgStyle; else this.target.removeAttribute("style"); }, handleEvent(e) { switch(e.type){ case "click": if (e.button) return; e.preventDefault(); e.stopPropagation(); this.lowlight(); this.parent.capture.apply(this, this.getPosition()); this.uninit(); break; case "mouseover": if (this.target) this.lowlight(); this.target = e.target; this.highlight(); break; } }, init() { this.win = content; this.doc = content.document; ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { this.target = false; ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }` }); |
sandro79 > 13-05-2022 23:18:16 |
Dumby скрытый текст Пунт переименован скрытый текст Чувствую я, не придётся мне переходить на 102 ESR. Для меня больше минусов чем плюсов, единственное - плавающие полосы прокрутки впечатлили. Начиная с 99, указатель переходит в режим захвата для изменения размера окна, ещё не успев дойти до внутреннего края окна, что очень неудобно при использовании кнопок панели меню и автоскрываемой боковой панели, постоянно приходится прицеливаться. И, как я понял, из-за неотключаемого WebRender, с 92+ у меня пропадают кнопки управления окном в Win7 при использовании инструментов веб-разработчика, если используется нестандартная тема в браузере. Да ещё и в Ютуб, когда плейлист играет, если открыть сайдбар, когда затемняется страница, то кнопки тоже пропадают скрытый текст |
sonyas75 > 14-05-2022 08:00:04 |
sandro79 пишет
аналогично. вот прям в точку. я никак ночнушку 102, которая будет ЕСР, не могу привести в чувство. вроде и внешний вид сделал аналогичным, и кнопки важные работают, а куча мелочей не поддаются. какой-то дискомфорт необъяснимый. совсем не зашло. |
Dumby > 14-05-2022 08:03:39 |
_zt пишет
Почему jsm? Нет, расширение здесь, наверно,
pdf там через какой-то сторонний сайт, так что это без меня. А html — я не вижу такого. Кстати, хорошо бы в savePageToHTML() в строку var vert=`javascript:(function(){…
Да, у saveURL() аргументов, определённо, больше. скрытый текст Выделить код Код:/* saveURL("data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + ("\r\n\r\n" + sel)), fileTitle + ".txt", null, false, false, null, window.document); */ saveURL( "data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\r\n\r\n" + sel), fileTitle + ".txt", null, false, false, null, null, null, gBrowser.selectedBrowser.browsingContext.originAttributes.privateBrowsingId > 0, document.nodePrincipal );
Ну да, так там и задумано, и даже прокомментировано. sandro79 пишет
То есть с этого бага перерисовать? скрытый текст Выделить код Код:Services.prefs.getBoolPref("browser.privatebrowsing.autostart", false) || (async css => { var obs = doc => { var win = doc.ownerGlobal; if (win.browsingContext.usePrivateBrowsing) return; var menuitem = doc.getElementById("placesContext_open:newtab"); if (!menuitem) return; var df = win.MozXULElement.parseXULToFragment( `<menu id="placesContext_open:newcontainertab" label="Открыть в контейнере" accesskey="й" nodetype="link" node-type="link" selectiontype="single" selection-type="single" > <menupopup oncommand="openInContainerTab(event);" onpopupshowing="return createUserContextMenu(event, {isContextMenu: true});"/> </menu>` ); df.firstChild.firstChild.openInContainerTab = open; menuitem.after(df); win.location != "chrome://browser/content/browser.xhtml" && win.windowUtils.loadSheetUsingURIString(css, win.windowUtils.AUTHOR_SHEET); } var open = e => { var win = e.view, pui = win.PlacesUIUtils; var tn = pui.lastContextMenuTriggerNode; if (tn.closest("#managed-bookmarks")) var url = tn.link, arg = {}; else { var node = pui.getViewForNode(tn).selectedNode; if (!pui.checkURLSecurity(node, win)) return; var url = node.uri; win.PlacesUtils.nodeIsBookmark(node) ? pui.markPageAsFollowedBookmark(url) : pui.markPageAsTyped(url); var js = url.startsWith("javascript:"); var arg = { allowPopups: js, allowInheritPrincipal: js, inBackground: pui.loadBookmarksInBackground }; } arg.userContextId = +e.target.dataset.usercontextid; win.openTrustedLinkIn(url, "tab", arg); } var topic = "chrome-document-loaded"; Services.obs.addObserver(obs, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(obs, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); })("chrome://browser/content/usercontext/usercontext.css"); |
sandro79 > 14-05-2022 08:41:20 |
Dumby пишет
Да-да, с него. Новый баг добавлен и отлично работает! Огромное Спасибо! |
_zt > 14-05-2022 13:52:59 |
Dumby пишет
Возможно я сам это добавил, что бы сразу видеть зависимость. Dumby пишет
Сохраняет то не сайт, а скрипт или браузер, но если бы был браузер, то он сохранял бы стандартно. Dumby пишет
Да, я забыл настроить папку на одном из профилей. Dumby пишет
C этим все в порядке. Спасибо. Dumby пишет
1. Так сохраняет в профиль. 91, 100 |
kokoss > 15-05-2022 17:21:44 |
Dumby |
Dumby > 16-05-2022 09:19:07 |
_zt пишет
Скрипт ничего не сохраняет. Мне вот стало любопытно, а сохранялка в pdf,
Путь к папке сохранения должен браться из настройки browser.download.dir
Даже и не предусмотрено. Как и работа в (i)frame'ах.
Вроде не должно быть сложностей, это же контекстное меню, скрытый текст Выделить код Код:function saveSelectionToFile() { var line = ".".repeat(62) + "\n"; var hint = "Кликни чтобы открыть файл"; var prfx = "Сохранил выделенный текст в файл "; var img = self.getAttribute("image"); var desk = Services.dirsvc.get("Desk", Ci.nsIFile); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); (saveSelectionToFile = async () => { var time = aDate(), url = gBrowser.currentURI.displaySpec; var text = `${line}${getTabLabel()} - ${time}\n${url}\n\n${ gContextMenu.contentData.selectionInfo.fullText }\n\n\n`; try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); var msg = prfx + "в папку " + file.leafName; await IOUtils.makeDirectory(file.path); } catch(ex) { file && Cu.reportError(ex); file = desk.clone(); var msg = prfx + "на рабочий стол"; } file.append(`Save - ${time}.txt`); await IOUtils.writeUTF8(file.path, text, {mode: file.exists() ? "append" : "create"}); var name = "sstf-" + Cu.now(); as.showAlertNotification( gBrowser.selectedTab.image || img, msg, hint, true, "", (s, t) => t == "alertclickcallback" && file.launch(), name ); setTimeout(as.closeAlert, 8e3, name); })(); } kokoss пишет
В смысле чтобы кнопки в окне появлялись раньше? скрытый текст Выделить код Код:(async url => { var manager = ChromeUtils.import(url).ExtensionParent.apiManager; var onReady = (e, addon) => { if (addon.id == "add_toolbar_buttons@vitaliy.ru") onAddon(addon), manager.off("ready", onReady); } var onAddon = async addon => { var mgr = addon.experimentAPIManager; var loaded = mgr.getModule("addToolbarButtons").asyncLoaded; loaded ? await loaded : mgr.getAPI("addToolbarButtons", addon); mgr.global.baseUri = (mgr.global.contExt = addon).baseURL; var atb = mgr.global.add_toolbar_buttons; style(atb, addon); atb.init(); } var style = (atb, addon) => { var noop = () => {}; var sss = atb.styleSS; var subst = "v-add-toolbar-buttons-style"; var args = [Services.io.newURI(`resource://${subst}/`), sss.USER_SHEET]; var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var shutdown = (e, isAppShutdown) => { if (isAppShutdown) return; sss.unregisterSheet(...args), rph.setSubstitution(subst, null); manager.on("ready", onReady); } (style = async (atb, addon) => { atb.loadButtonStyle = atb.removeButtonStyle = noop; var css = `@-moz-document url(chrome://browser/content/browser.xhtml) {\n${ await (await fetch(addon.baseURI.resolve("button.css"))).text() }\n}`; rph.setSubstitution(subst, Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(css))); sss.loadAndRegisterSheet(...args); addon.once("shutdown", shutdown); })(atb, addon); } manager.on("ready", onReady); })("resource://gre/modules/ExtensionParent.jsm"); |
_zt > 16-05-2022 12:53:48 |
Dumby пишет
Ага, только вы написали менять var file = Services.dirsvc.get("Desk", Ci.nsIFile);, ну я его и заменил, а это совсем не там, менять нужно было var file = Services.dirsvc.get('ProfD', Ci.nsIFile); Dumby пишет
В конце ";" не нужен? Dumby пишет
Лучше, так как там хоть немного можно настроить вывод. У меня и без расширений пункт Печать позволяет сохранить PDF. Конечно надо заменить этот атавизм (сервис) на встроенную функцию. Вот только как, с выводом окна настроек или с чтением уже имеющихся настроек и моментальным сохранением? Я за второй вариант, если он возможен (настройки печати браузер сохраняет). |
kokoss > 16-05-2022 15:09:23 |
Dumby пишет
Благодарю, в актуальной версии UCF работает, а можно сделать что бы работало и в этой версии UCF ? |
Dumby > 16-05-2022 16:00:22 |
_zt пишет
Скриншот с форума.
Вообще, после функций не принято, и, за редким исключением, не нужно.
Я так предполагал: ты настроишь тот WebExtensions так, как нужно, вариант публикации Идём в отладочную консоль аддона, например, открываем вкладку с адресом about:devtools-toolbox?id=%7B9ab38051-cd73-4e46-b7bd-dc147f6f6b29%7D&type=extension&tool=webconsole Там запускаем код. Должна открыться вкладка с настройками. Выделить код Код:(async () => { var data = JSON.stringify( await browser.storage.local.get(), null, "\t" ); var url = URL.createObjectURL( new Blob([data], {type: "text/plain;charset=utf-8"}) ); browser.tabs.create({url}) .finally(() => URL.revokeObjectURL(url)); })(); Останется определиться с тем, откуда брать путь к папке для сохранения, и как формировать имя файла. kokoss пишет
Даже не знаю, может так попробуй скрытый текст Выделить код Код:… //manager.on("ready", onReady); var policy = Cu.getGlobalForObject(Cu) .WebExtensionPolicy.getByID("add_toolbar_buttons@vitaliy.ru"); policy ? onAddon(policy.extension) : manager.on("ready", onReady); |
kokoss > 16-05-2022 17:04:26 |
Dumby пишет
заработало Выделить код Код:(async url => { var manager = ChromeUtils.import(url).ExtensionParent.apiManager; var onReady = (e, addon) => { if (addon.id == "add_toolbar_buttons@vitaliy.ru") onAddon(addon), manager.off("ready", onReady); } var onAddon = async addon => { var mgr = addon.experimentAPIManager; var loaded = mgr.getModule("addToolbarButtons").asyncLoaded; loaded ? await loaded : mgr.getAPI("addToolbarButtons", addon); mgr.global.baseUri = (mgr.global.contExt = addon).baseURL; var atb = mgr.global.add_toolbar_buttons; style(atb, addon); atb.init(); } var style = (atb, addon) => { var noop = () => {}; var sss = atb.styleSS; var subst = "v-add-toolbar-buttons-style"; var args = [Services.io.newURI(`resource://${subst}/`), sss.USER_SHEET]; var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var shutdown = (e, isAppShutdown) => { if (isAppShutdown) return; sss.unregisterSheet(...args), rph.setSubstitution(subst, null); manager.on("ready", onReady); } (style = async (atb, addon) => { atb.loadButtonStyle = atb.removeButtonStyle = noop; var css = `@-moz-document url(chrome://browser/content/browser.xhtml) {\n${ await (await fetch(addon.baseURI.resolve("button.css"))).text() }\n}`; rph.setSubstitution(subst, Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(css))); sss.loadAndRegisterSheet(...args); addon.once("shutdown", shutdown); })(atb, addon); } manager.on("ready", onReady); var policy = Cu.getGlobalForObject(Cu) .WebExtensionPolicy.getByID("add_toolbar_buttons@vitaliy.ru"); policy ? onAddon(policy.extension) : manager.on("ready", onReady); })("resource://gre/modules/ExtensionParent.jsm"); |
_zt > 16-05-2022 18:26:01 |
Dumby пишет
Ну да, и оно сохраняло в профиль, пока не изменил var file = Services.dirsvc.get('ProfD', Ci.nsIFile);, да еще и папку левую там создавало, с названием как папка загрузок браузера. скрытый текст Выделить код Код:{ "footerCenter": "", "footerLeft": "&PT", "footerRight": "&D", "headerCenter": "", "headerLeft": "&T", "headerRight": "&U", "marginBottom": 0.2, "marginLeft": 0.2, "marginRight": 0.2, "marginTop": 0.2, "orientation": 0, "paperHeight": 11, "paperSizeUnit": 1, "paperWidth": 8.5, "scaling": 1, "showBackgroundColors": true, "showBackgroundImages": false, "shrinkToFit": true, } И подскажите как добавить в кнопку пункт "Печать" браузера (шоб имя свое задать можно было), сразу после нынешнего (и будущего) "Сохранить страницу в PDF". Преднастройки это хорошо, но хотелось бы иметь возможность настройки из UI. |
Dumby > 17-05-2022 09:48:44 |
_zt пишет
Странно, paperSizeUnit единица. Наверно имелся в виду ноль. Вобщем, пока такой набросок замены функции savePageToPDF() скрытый текст Выделить код Код:function savePageToPDF() { var ps = Ci.nsIPrintSettings, cfg = { paperWidth: 8.5, paperHeight: 11, paperSizeUnit: ps.kPaperSizeInches, // kPaperSizeMillimeters marginLeft: 2, marginRight: .2, marginTop: .2, marginBottom: .2, edgeLeft: .1, edgeRight: .1, edgeTop: 0, edgeBottom: 0, headerStrLeft: "&T", headerStrCenter: "", headerStrRight: "&U", footerStrLeft: "&PT", footerStrCenter: "", footerStrRight: "&D", printBGColors: true, printBGImages: false, scaling: 1, shrinkToFit: true, // overrides scaling orientation: ps.kPortraitOrientation, // kLandscapeOrientation printerName: "", printSilent: true, printToFile: true, showPrintProgress: false, isInitializedFromPrefs: false, isInitializedFromPrinter: false, outputFormat: ps.kOutputFormatPDF, outputDestination: ps.kOutputDestinationFile, }; ps = Cc["@mozilla.org/gfx/printsettings-service;1"] .getService(Ci.nsIPrintSettingsService).newPrintSettings; for(var key in cfg) if (key in ps) ps[key] = cfg[key]; (savePageToPDF = async () => { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } file.append(`Snap ${new Date().toLocaleString("mn").replace(/:/g, "\ua789")}.pdf`); ps.toFileName = file.path; await gBrowser.selectedBrowser.browsingContext.print(ps); //file.launch(); })(); }
Пункт который из гамбургера? скрытый текст Выделить код Код:{ label: "Союзпечать", func: document.getElementById(document.getElementById("appMenu-viewCache").content.querySelector("[key=printKb]").getAttribute("command")).getAttribute("oncommand"), image: "chrome://global/skin/icons/print.svg"}, |
_zt > 17-05-2022 20:21:00 |
Dumby пишет
Забыл вернуть, я же пытался все настройки вывести. |
voqabuhe > 17-05-2022 20:38:05 |
_zt пишет
И что получилось, можно итоговый вариант? |
_zt > 18-05-2022 14:21:41 |
voqabuhe скрытый текст Выделить код Код:self.label = "Save"; self._handleClick =()=> menuPopup.openPopup(this, "after_start"); self.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAABGklEQVQ4EaWSvQ4BQRSFd/3EUouGksIDiNBLvMAqtVoaiShUHkItIRGd1iN4A0ql2l8wvruxw67FJuR87p05d85OFsP482PKeaVUjWpDDKpwgyAd2GyZprmiPkXAWFbUIvSld2EdgQ5UYApzKLl+xG2+VAuvDjZcoAldQspUI0yAzMXlS+D6e6qEtKlvAVc2o/CqI4sJTMF5Z4Qc6OU2hrw0eq01XZLrjah+ldhYgEeeAJIVbg9CyxMgp3j6kFqAIK15SP/V8ARwOI95ZqhBfRP+QCmVx9+4pv9XiGNc4JPEkxnt+wO0EbbRAVwtwyELfsl6zDpzOoBVFlLwSzIjs86c88cgscbKhgSkYQtByrG5gxPMeJlL6n+6A9I+WoE5cj6LAAAAAElFTkSuQmCC"; var folderpath="E:\Download"; // папка для сохранения иконок для ярлыков и ярлыков сайтов // Создать меню для кнопки ............. var array = [ { label: "Сохранить favicon сайта", func: "saveFavicon()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACPVBMVEX09ff////C3L+Uq8+Vq8+Uqs+Zr9CZrtCZr9Gfu+ear8+mt9JRf8ORxl3t8vfF06+Twojs8/d9otl8o9s+aquZrs/X9KLp8Pft8fZhisf//+DBzN2hveihv+pii8hti9pgicl6oNlojs1zncNsi836/P2duebx8/eYyWqBp+Gn0IKBvlKHsm9qmaVuk8zt7/FEbauEv1Tp7/JdhL9oi9Pl8e2LwlmdsdD7/P76+/3H7ofo8+peh8eHwFaSteZ0pkp2gl7q8/Ohy5OApt2by2eZuOqbuOWaezWuvtd7nN2HvWxul9Ty9feQxV5ljcqBp+JEcLCVtOOo0nR7odx5n9suX6Z1mtBzmtSXyGPv9PewzfOzx+O6zu/s8fd9o95Xfrthi8lYhMN5oNnw9ffw9Pjw9Pf8/f6ewO/m8O9zmdE6aapsjdyUwouPxWPDzd6XteOSs9B5nNVpnpqHt7h/s6F6n9d7ntSTttGHwVh4qp+Ev1HH7ox6qk5wj+Hm8e3t9fOm0IKAtqOBpNrx+P9ljcyhs9FpkM2hv+/u8/fF0eOLu4N+vFKgzX3p9OSFqN13qExekIl4n9j7/P3x9PhxmNDm8e9Vg8Zfkozr8veq0YTX9qL//92AtamOwnHFz96Fot1diMh+pd13ntmatu+YyW/3+/+Tqs5UgcShzJNbhsdTf8GHs7bo8PaXtuqMr+Ty8/SZt+SUqs7r7Ox3ndb9/f7t8feZyXGYyWWCpNbz9PRuiteNtNDn7/V4ntjx8fGo3JqNAAAAv3RSTlP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AEVuhDkAAAD+SURBVBhXY5jHzcUMAqxAICq9bx8D96adDFAgaGQOFOBaH7h7zoqZDTlFyptncAAFWBjyi52CXCI0unRLxcECPhsatbbzmlXMnS60hg0kkOxW0uNrq93tNaFpD1ggUm21QK532ZQdSm1hmXKdDCwdnOWVOi1RjNGMQCCrwMDMJ8NZ4LAynVGPkXFp8zpJBubYmn579wXtqhZb0iwn9a1iWLaViYmJ3891obOwYtLEvcYMGyWAAkwJdv6accEhi8LjGVr11SenpC5f61g3NcO0vjCAIc+DjZ2dnWexddWSbYa9nlkM+8BgWsxsK7FZ1VLzRaACNokmtdnyu1QMQgF7Rlh4zWWTAwAAAABJRU5ErkJggg=="}, { label: "Копировать favicon в base64", func: "copyFaviconData()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAI2bv/9RVpf/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAACIkvD/Jia6/ywpq/8AAAAAAAAAAAAAAAAAAAD/AAAA/wbwAf90qpv/Ymic/1RWqP9OUKr/W2Ch/2dumf9YYKT/Ly/B/xQP3/8MB9P/JCGb/wAAAAAAAAAAAAAAAAAAAP8G8AH/U5ea/ycr8f8VIP3/HiP4/ywo8v8sIvb/LCL2/ywi9v8KBOj/BQDe/wQAtv8tK4P/AAAAAAAAAAAAAAD/BvAB/3Sqm/9iaJz/Tim3/0UuuP9GPrT/R0ex/zk8uf8gIMz/FRDe/xEMzv8jIJz/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8AAAD/SqOR/yImvP8sLKj/AAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/BvAB/3Sqm/9KW5r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAABvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAG8AH/AAAAAAAAAP8G8AH/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BvAB/wbwAf8AAAAAAAAA/wAAAP8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAG8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOesQQBjrEGAAaxBwACsQcABrEHDg6xBwAesQcAPrEHAD6xBw8+sQcPprEHD8axBwAGsQQABrEGAAaxB//+sQQ=="}, { separator: ''}, { label: "Сохранить ярлык страницы как…", func: "saveShortcuts()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP8E/yT/BP8k/5XLDv/zqgD/86oA//I1///yNf//86oA//OqAP/zqgD/86oA//OqAP+Vyw7/lcsO/wT/JP8E/yT/BP8k/5XLDv+Vyw7/86oA//OqAP/yNf//8jX///OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//02AP/9NgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/9NgD//TYA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA/wA31v8AN9b/86oA//9If///SH//86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP8AN9b/ADfW//OqAP//SH///0h///OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/5XLDv+Vyw7/86oA//OqAP/zqgD/86oA/0CA//9AgP//86oA/07+9f9O/vX/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP9AgP//QID///OqAP9O/vX/Tv71//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ=="}, { separator: ''}, { label: "Копировать изображение / текст в base64", func: "copyFaviconbase()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AIAQ/wCAEf8AgA//AIAR/wCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AgBX/AIAVAAAAAAAAAAD/AIAo/wCA//8AgP//AID//wCA//8AgP//AIAoAAAAAAAAAAAAAAAAAAAAAP8AgBL/AID//wCA//8AgA3/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgBAAAAAAAAAAAAAAAAD/AIAR/wCA//8AgP//AIAK/wCACv8AgP//AID//wCAIf8AgAX/AIAh/wCA//8AgP//AIAQAAAAAAAAAAAAAAAA/wCACv8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAUAAAAA/wCABf8AgP//AID//wCACgAAAAD/AIAQ/wCADP8AgCH/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCABf8AgCH/AID//wCA//8AgAv/AIAh/wCA//8AgP//AID//wCA//8AgP//AIAH/wCAB/8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AIAg/wCA//8AgP//AID//wCA//8AgP//AID//wCAB/8AgAf/AID//wCA//8AgP//AID//wCA//8AgP//AIAh/wCAC/8AgP//AID//wCAHP8AgBz/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCACf8AgA7/AIAMAAAAAP8AgAj/AID//wCA//8AgAP/AIAD/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCABQAAAAAAAAAA/wCADf8AgAr/AIAL/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCAB/8AgAr/AID//wCA//8AgCH/AIAH/wCAJf8AgP//AID//wCAI/8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAf/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgCT/AID//wCA//8AgAr/AIAK/wCA//8AgP//AIAKAAAAAP8AgCj/AID//wCA//8AgP//AID//wCA//8AgCP/AIAM/wCA//8AgP//AIAN/wCADf8AgP//AID//wCADQAAAAAAAAAA/wCAEP8AgBH/AIAP/wCAEf8AgBAAAAAAAAAAAP8AgBT/AIAVAAAAAAAAAAD/AIAV/wCAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQcH5rEGA8KxBAHCsQQBwrEEIQKxBAACsQQAArEEAAKxBAQCsQQwArEEAAKxBAACsQYAArEHBmaxB//+sQQ=="}, { separator: ''}, { label: "Сохранить страницу как PDF", func: "savePageToPDF()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYUw4pJt3V/+Rb1D8lnFP/55zTf+VcVH/lXJS/5VyUv+VclL/lXJS/5VyUv+VclL/k3BR/J56Wv9cRzSkAAAAAJNvUKTto2L/4ppe/uehZf/Pmmr/noZv/9Scav/Wl17/1plh/9eZYf/XmWH/15lh/9eZYf/WmGD/2Jlg/suRXP9mRiuk8rWA/397dP1akKn/rqqi/3LF3f8Mntj/4dLJ///+9f/48u3/9e7n//bt5v/47+f/+O/n//jv5//rvZP/1ZJX/a9/VP9+lrD8AIvz/xOt+f8Douv/ALb6/wC28/9tmar/z8jJ//Lq5/////7//v////n9///6/P3//////+Ta0P/PjVP/pnpT/IWds/+aiXj/5efl/8Px//951/3/LMz//wCx8/8GltL/NIu3/4ycqf/l29L////+//n6+//8/v//3tXM/8+OVP+oe1P/6K57/86QWP/r6Ob////////++v/r9/z/oOb9/zDL//8Arf//AI/r/ydysv+hpqr//PTr///////d1Mz/0I5U/6h7U//osH//wo5g/+fm5P/7/f//9vf5//z7+////vv/9/r8/5Dc/P8Oqv7/AJf//wF02v9ffZ7/8Ojh/+Ha1P/NjFL/qHtT/+ewf//Ej1//7O3r///////+/v7//v7+//f5+v/6+vv////8/8Tq/f8hp/7/AJH//wB18/8/bqj/1MGu/9mXXv+leVH/569+/8iSYv+/tKn/wLew/8O5sf/P0M////////7+/v/3+fv////7/9Hv/v8hoP3/AIn//wB4/v84ZqL/w4NH/619VP/nsYD/x45c/9W5of/bv6j/0Jxt/6J/YP+spqD/2N3i//7////6+/3///76/8vr/v8Slv7/AIb+/wBz//83VH7/nW1B/+ewfv/Fjl7/7Ozr///////9+/r/9d7K/9Ghdv+jd1D/pJ6Y/+jt8f/9///////7/6fb/v8Ahv7/AYD//wRp6f95YlT/57B//8SOXv/n5uT//v7///r7/P/8/v////////XRsv/DhEv/loBu/9DX3P/9/v/////7/2O6/f8Afv//FnTU/5JtTf/nsH//xY9e/+jn5f/+/f//+fj5//n4+P/5+Pn/+/////Xbxf/Wj1D/nX1h/+Ll6P////7/3+/3/w+V//8tcbP/qHJB/+WuffzCjV7/5efn///////+/v7//////////////v7///////XRsP/TnW3/8fT3//////////z/ddD//0Nxl/+zdkH88LmH/9CRWP2+qJT/0M7N/8/Jxv/Pysf/z8rH/8/Kxv/Py8n/zsO6/7+pmP/PzMv/zsnG/9bNyP+nsK7/h4R3/b2BT/+Sb1Ck7qxw/9GSW/69hlb/wYhX/8CIV//AiFf/wIhX/8CIVv/BiVj/xI1d/8CIVv/BiFf/vYZW/9STW/7ppmv/bE80pAAAAACUd16k+sui/+7AmPzwwpr/8MKa//DCmv/wwpr/8MKa//DCmf/vwZj/8MKa//DCmv/uwJj8+cui/5N3XaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, { label: "Печать / печать в PDF", func: document.getElementById(document.getElementById("appMenu-viewCache").content.querySelector("[key=printKb]").getAttribute("command")).getAttribute("oncommand"), image: "chrome://global/skin/icons/print.svg"}, { label: "Сохранить страницу / выбор как HTML", func: "savePageToHTML()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzElEQVQ4jV2STW8bZRDHf/Psrr11nZhgVKcKaSmUiArRKBRVIMgH4BKJ7xAp5MSFiA+Rc28ckBAoipC4koJQLyAaVFChIlQllDRWmjRev8Qvu14/+wwHx6ZlpNFcZn7zn79GVJW1tbXc6urqijHGqKoAPF3TgcVaq8owXJbphx99fOOnWzcHoqqsr68/t7y83BARVBXnHHraXo3a3HoUU8gFAHRTS2Bg/7C2Zx7vXPIBwjA0p3BU9Zns9i3vvVrhr6MWzlpee+EsRqAbHc3+/Pee7wPkcrkx4P+g0IMvb/5Iv5/iXEaWZQS+By578MaVy9YH8H3fE5FnANZajqMmgcAnH7yN73mICMYMd21sbLy7srKiPkA+n3/qBLhzv8p+EuOfTUjShPbODvOVWa5fnRsvKBaLAcAIMFbw+bc/EBVn8At7SPcQ60LSiVm++P0fGu0e7y++yalvHoABCILAiAj7hzU+vfcVT6zPVGmR3x4/xJoLSH6BVu4cN777nnQwQETI5XL/AYwxRkS4ff8BEk6Q2pBfq3dxUuHMmWt0kgFGStTDY/7YrTLybQwYPU2cpgzsCd1OgmSzWHeOR7VjWicxaT9lxn+HfjoYmWnGHgAiIsydf5HKnUXiThehQDG4Tr3e5KR7hN8XilnGKxfOoyrDgZECwIgIb125xIxxTGVdgjRG4pR2+zbG/sIkD7l2cYJyaYLMOZxzjBV4nueLCI1GnaWFab65t4OXt4gUuFqYJ8gGuPYBCxdLHNciys9PkaapjAHGGM8YQ7lcZv71OaYmC/xZPaJHTN4cUgpDXrr8MtOVaUqTRXzfY3t7u7O0tDR82a2trfkkSTSOY+31etrpdLTZbGoURRpFkdbrTY3qTW00mhrHse7u7t4tl8uhqg4VxHHcPDg4+ExVHeBU1YmIU1WnisucZtamLszn01ar9WRzc/PrWq2WAPwLJ7l2ULfXOAMAAAAASUVORK5CYII="}, { label: "Сохранить URL вкладки / выбор как TXT", func: "saveSelectionToTxt()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAQE6AAAAZAAAAGgAAAJmAAACZgAAAGYAAABmAAAAZgAAAGYAAABmAAAAZgAAAGYAAABlAAAAaQABAmYAAQEjAAAAADlVkOdVcKHxVXKi8kdklPJLZpfyU3Cg8lJvn/JRbZ7yUW+g8lFun/JRbp/yUG6e8lVyofFVdKjzLkV45wAAAFABAQEAaIzF/3y34v9wsuL/cJe0/0lpgv9bjLP/dLLh/2+v3v9sq9v/cK3d/3Gv3v9sqtv/b7Df/4G77P9VcqT2AAAAVAMDAQBnir/+ZqfU/pDB4/7a3uD+j46N/kxYXv6To6/+1er4/tXp+P7J3/D+1ej4/svg8v6Gut/9aqzd/lhxnvAAAABSAwIBAGaIvv9pptX/ocfj//f4/P/P0tX/g4CA/1xZWf+Woqr/2uz8/9Hl+f/W5fT/2Of3/5fC4v5tq93/Vm+e8QAAAFIDAgEAaYm+/3mw2/+iyeX/9Pn8/+z0+//IzNL/d3h5/0tMTv+Mkpn/xdvs/9Hp/f/O4PL/msXk/nmz4/9XcJ/xAAAAUgMDAQBti7//k7/h/6fL5v/v9fn/4u73/9Dk9P+8wMT/YGpx/zJJWv94iJf/ztzo/9Pp/P+ZwuD+gLfk/1dwnvEAAABSAwMBAHOPwf+myub/sNHp//j7/P/6/P3/8fr///r39P+sxdP/IXWq/xJJcv+NjZD/0+Lu/6TN7f6Ft+L/WXGf8QAAAFIDAwEAd5LD/7PR6/+ZxOP/0ePx/97r9f/Y5/L/3e32/8Tc7f9gseT/CHK3/zBYdv+HiY7/lL/f/pLE7/9bcJ3xAAAAUgMDAQB4k8P/xNvx/5/F5f+kyOX/qMrn/6TH5f+kyOX/sM/q/5e51P9Mm83/GHm3/xxIav9fdYf+pMvs/1x1pfIAAABTAwMBAHmSxf/O4/T/y9/y/8Hb9P/C3PX/wNv0/7vW7/+93ff/utDm/42fsf9Gjbn/EXS2/ytSbv6Fj5r/WnGc8gAAAFICAwEBepPE/tHk9f/S5PX/vMjV/7fCzP+3w8//uMPP/7XBzP+6ytf/qa+4/3h/hv9Ghaz/JoO+/jNXdP82PVnyAAAAVgACAgCBmcb/2+r3/dHh8fyPkpX/kI6N/5yam/+dnJ3/paWk/6enpf+sr6//mpSR/3Bubf9SjbD8H4C+/QsrSvcCAAB/AAAAA3yVx//j8///3u/7/52gpf6pqKf+uLm5/rq7u/7Ly8v+ycnI/paWlf6LjY/+np2f/Xh+g/5gnL7/MX+y/xcgJ80BAgNNN1OUs6W84fDA1O73mJyj/ainpv+2trb/t7e4/8fHyP/Fxsb/kZGQ/4eGhP+vucT/j6G+/W53k/NlkbnwNoOv/AgiNb8CCBsQDRo/YwsaO3B0d33arKyp9q2trfWvr6/2u7u79ru7vPawr7H1sbCt9nJ2gOQIGD6bFCFEYB0qPE1Bf6SpEz9cggAAAAMCAQEBAQAAADIyMmlDQ0ONQUFBhUFBQYVCQkGFQkJBhUhISIRNTU2OKysrZAEAAAUBAQAAAgEAAAkEAAEDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="}, { separator: ''}, { label: "(Меню ПКМ) Сохр./добавить текст в файл", value: "Save.SelectionToFile" }, { label: "(Меню ПКМ) Открыть текст в редакторе", value: "Save.TextToEditor"}, ]; var menuPopup = self.appendChild(document.createXULElement("menupopup")); array.forEach((m,i)=> { if ("separator" in m) { menuPopup.appendChild(document.createXULElement("menuseparator")); return }; var mItem = menuPopup.appendChild(document.createXULElement("menuitem")); mItem.setAttribute("label", m.label); mItem.setAttribute("class", "menuitem-iconic"); if ("image" in m) mItem.setAttribute("image", m.image || array[i-1].image); if ("value" in m) { mItem.setAttribute('type', 'checkbox'); mItem.setAttribute('checked', cbu.getPrefs(m.value) ); mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value)); } if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString())); }); menuPopup.setAttribute("onclick", "event.stopPropagation()"); function aDate() { var t=new Date(); var y=1900+t.getYear(); var min=t.getMinutes(); if (min<10){min="0"+min}; var h=t.getHours(); var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";} var d=t.getDate(); var curdate=d+" "+m+" "+y+" "+"г"; var myfilename=curdate; return myfilename; } function WebScreenShotonImage(image) { var canvas = document.createElementNS(xhtmlns, 'canvas'); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; var ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); var base64 = canvas.toDataURL(); gClipboard.write(base64); // стиль для изображение в сплывающей подсказке .... var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(base64, self.label, "Изображение копировано как base64", false, "", (s, t)=> { if (t == 'alertfinished') sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается }, ""); }; var saveToFile = function (fileContent, fileName) { var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); uc.charset = 'utf-8'; fileContent = uc.ConvertFromUnicode(fileContent); var nsIFilePicker = Components.interfaces.nsIFilePicker; var fp = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker); fp.init(window, '', fp.modeSave); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); fp.open(function (rv) { if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) { var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream); stream.init(fp.file, 0x02|0x20|0x08, 0666, 0); stream.write(fileContent, fileContent.length); stream.close(); } }); }; function savePageToHTML() { var vert = String.raw`javascript:(function(){var getSelWin=function(w){if(w.getSelection().toString())return w;for(var i=0,f,r;f=w.frames[i];i++){try{if(r=getSelWin(f))return r}catch(e){}}};var selWin=getSelWin(window),win=selWin||window,doc=win.document,loc=win.location;var qualifyURL=function(url,base){if(!url||/^([a-z]+:|%23)/.test(url))return url;var a=doc.createElement('a');if(base){a.href=base;a.href=a.protocol+(url.charAt(0)=='/'%3F(url.charAt(1)=='/'%3F'':'//'+a.host):'//'+a.host+a.pathname.slice(0,(url.charAt(0)!='%3F'&&a.pathname.lastIndexOf('/')+1)||a.pathname.length))+url}else{a.href=url};return a.href};var encodeImg=function(src,obj){var canvas,img,ret=src;if(/^https%3F:%5C/%5C//.test(src)){canvas=doc.createElement('canvas');if(!obj||obj.nodeName.toLowerCase()!='img'){img=doc.createElement('img');img.src=src}else{img=obj};if(img.complete)try{canvas.width=img.width;canvas.height=img.height;canvas.getContext('2d').drawImage(img,0,0);ret=canvas.toDataURL((/%5C.jpe%3Fg/i.test(src)%3F'image/jpeg':'image/png'))}catch(e){};if(img!=obj)img.src='about:blank'};return ret};var toSrc=function(obj){var strToSrc=function(str){var chr,ret='',i=0,meta={'%5Cb':'%5C%5Cb','%5Ct':'%5C%5Ct','%5Cn':'%5C%5Cn','%5Cf':'%5C%5Cf','%5Cr':'%5C%5Cr','%5Cx22':'%5C%5C%5Cx22','%5C%5C':'%5C%5C%5C%5C'};while(chr=str.charAt(i++)){ret+=meta[chr]||chr};return'%5Cx22'+ret+'%5Cx22'},arrToSrc=function(arr){var ret=[];for(var i=0;i<arr.length;i++){ret[i]=toSrc(arr[i])||'null'};return'['+ret.join(',')+']'},objToSrc=function(obj){var val,ret=[];for(var prop in obj){if(Object.prototype.hasOwnProperty.call(obj,prop)&&(val=toSrc(obj[prop])))ret.push(strToSrc(prop)+': '+val)};return'{'+ret.join(',')+'}'};switch(Object.prototype.toString.call(obj).slice(8,-1)){case'Array':return arrToSrc(obj);case'Boolean':case'Function':case'RegExp':return obj.toString();case'Date':return'new Date('+obj.getTime()+')';case'Math':return'Math';case'Number':return isFinite(obj)%3FString(obj):'null';case'Object':return objToSrc(obj);case'String':return strToSrc(obj);default:return obj%3F(obj.nodeType==1&&obj.id%3F'document.getElementById('+strToSrc(obj.id)+')':'{}'):'null'}};var ele,pEle,clone,reUrl=/(url%5C(%5Cx22%3F)(.+%3F)(%5Cx22%3F%5C))/g;if(selWin){var rng=win.getSelection().getRangeAt(0);pEle=rng.commonAncestorContainer;ele=rng.cloneContents()}else{pEle=doc.documentElement;ele=(doc.body||doc.getElementsByTagName('body')[0]).cloneNode(true)};while(pEle){if(pEle.nodeType==1){clone=pEle.cloneNode(false);clone.appendChild(ele);ele=clone};pEle=pEle.parentNode};var sel=doc.createElement('div');sel.appendChild(ele);for(var el,all=sel.getElementsByTagName('*'),i=all.length;i--;){el=all[i];if(el.style&&el.style.backgroundImage)el.style.backgroundImage=el.style.backgroundImage.replace(reUrl,function(a,b,c,d){return b+encodeImg(qualifyURL(c))+d});switch(el.nodeName.toLowerCase()){case'link':case'style':case'script':el.parentNode.removeChild(el);break;case'a':case'area':if(el.hasAttribute('href')&&el.getAttribute('href').charAt(0)!='%23')el.href=el.href;break;case'img':case'input':if(el.hasAttribute('src'))el.src=encodeImg(el.src,el);break;case'audio':case'video':case'embed':case'frame':case'iframe':if(el.hasAttribute('src'))el.src=el.src;break;case'object':if(el.hasAttribute('data'))el.data=el.data;break;case'form':if(el.hasAttribute('action'))el.action=el.action;break}};var head=ele.insertBefore(doc.createElement('head'),ele.firstChild);var meta=doc.createElement('meta');meta.httpEquiv='content-type';meta.content='text/html; charset=utf-8';head.appendChild(meta);var title=doc.getElementsByTagName('title')[0];if(title)head.appendChild(title.cloneNode(true));head.copyScript=function(){if('$'in win)return;var f=doc.createElement('iframe');f.src='about:blank';f.setAttribute('style','position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;');doc.documentElement.appendChild(f);var str,script=doc.createElement('script');script.type='text/javascript';for(var name in win){if(name in f.contentWindow||!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name))continue;try{str=toSrc(win[name]);if(!/%5C{%5Cs*%5C[native code%5C]%5Cs*%5C}/.test(str)){script.appendChild(doc.createTextNode('var '+name+' = '+str.replace(/<%5C/(script>)/ig,'<%5C%5C/$1')+';%5Cn'))}}catch(e){}};f.parentNode.removeChild(f);if(script.childNodes.length)this.nextSibling.appendChild(script)};head.copyScript();head.copyStyle=function(s){if(!s)return;var style=doc.createElement('style');style.type='text/css';if(s.media&&s.media.mediaText)style.media=s.media.mediaText;try{for(var i=0,rule;rule=s.cssRules[i];i++){if(rule.type!=3){if((!rule.selectorText||rule.selectorText.indexOf(':')!=-1)||(!sel.querySelector||sel.querySelector(rule.selectorText))){style.appendChild(doc.createTextNode(rule.cssText.replace(reUrl,function(a,b,c,d){var url=qualifyURL(c,s.href);if(rule.type==1&&rule.style&&rule.style.backgroundImage)url=encodeImg(url);return b+url+d})+'%5Cn'))}}else{this.copyStyle(rule.styleSheet)}}}catch(e){if(s.ownerNode)style=s.ownerNode.cloneNode(false)};this.appendChild(style)};var sheets=doc.styleSheets;for(var j=0;j<sheets.length;j++)head.copyStyle(sheets[j]);head.appendChild(doc.createTextNode('%5Cn'));var doctype='',dt=doc.doctype;if(dt&&dt.name){doctype+='<!DOCTYPE '+dt.name;if(dt.publicId)doctype+=' PUBLIC %5Cx22'+dt.publicId+'%5Cx22';if(dt.systemId)doctype+=' %5Cx22'+dt.systemId+'%5Cx22';doctype+='>%5Cn'};var href = 'data:text/html;charset=utf-8,' + encodeURIComponent(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->');var a = document.documentElement.appendChild(document.createElement("a"));a.setAttribute("href", href);var name = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());name=name.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');name += (function () {var d = new Date(), z=function(n){return '_' + (n < 10 ? '0' : '') + n};return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());})();a.setAttribute("download", name + ".html");a.click();a.remove();})();`; gBrowser. loadURI(vert, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }; function saveShortcuts() { var file = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsIFile); file.initWithPath(folderpath); if( !file.exists() || !file.isDirectory() ) { file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0x1B6);} var savetodir=folderpath+"\\"; var urllink=gBrowser.currentURI.spec; var out=getTabLabel(); var filename=savetodir+out+'.url'; var data="[InternetShortcut]\r\nURL="+urllink+"\r\n"; saveToFile(data, filename); // стиль для изображения во всплывающей подсказке .... var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); // подсказка var notific = 'Сохранил в: ' + folderpath; var image = gBrowser.selectedBrowser.mIconURL; Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(image, filename, notific); }; // Кодировать изображение или текстовой файл в base64 ............. function copyFaviconbase(){ var fp = window.makeFilePicker(); fp.init(window, "Открыть файл", fp.modeOpen); fp.appendFilter("Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml; *.xhtml; *.jpe; *.jpg; *.jpeg;\ *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw"); fp.open(re=> { if ( re != fp.returnOK ) return; var file = fp.file; var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); inputStream.init(file, 0x01, 0600, 0); var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); stream.setInputStream(inputStream); var encoded = btoa(stream.readBytes(stream.available())); var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file); var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded; gClipboard.write(dataURI); //Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Текст скопирован как base64"); // стиль для изображение в сплывающей подсказке .... var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); // alertsService.showAlertNotification(base64, self.label, "Изображение скопировано как base64", false, "", (s, t)=> { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Изображение скопировано как base64", false, "", (s, t)=> { if (t == 'alertfinished') sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается }, ""); }); }; // Сохранить страницу как PDF, скриптом ............. function savePageToPDF() { var ps = Ci.nsIPrintSettings, cfg = { paperWidth: 8.5, paperHeight: 11, paperSizeUnit: ps.kPaperSizeInches, // kPaperSizeMillimeters marginLeft: .2, marginRight: .2, marginTop: .2, marginBottom: .2, edgeLeft: .1, edgeRight: .1, edgeTop: 0, edgeBottom: 0, headerStrLeft: "&T", headerStrCenter: "", headerStrRight: "&U", footerStrLeft: "&PT", footerStrCenter: "", footerStrRight: "&D", printBGColors: true, printBGImages: false, scaling: 1, shrinkToFit: true, // overrides scaling orientation: ps.kPortraitOrientation, // kLandscapeOrientation printerName: "", printSilent: true, printToFile: true, showPrintProgress: false, isInitializedFromPrefs: false, isInitializedFromPrinter: false, outputFormat: ps.kOutputFormatPDF, outputDestination: ps.kOutputDestinationFile, }; ps = Cc["@mozilla.org/gfx/printsettings-service;1"] .getService(Ci.nsIPrintSettingsService).newPrintSettings; for(var key in cfg) if (key in ps) ps[key] = cfg[key]; (savePageToPDF = async () => { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } file.append(`Snap ${new Date().toLocaleString("mn").replace(/:/g, "\ua789")}.pdf`); ps.toFileName = file.path; await gBrowser.selectedBrowser.browsingContext.print(ps); //file.launch(); })(); }; if (typeof window.saveImageURL != "function") var saveImageURL = internalSave.length == 15 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, a7, a5, null, priv, prin); // Сохранить иконку текущего сайта с диалогом сохранения ............. function saveFavicon() { var uri = gBrowser.currentURI; function getSiteName() { try { var domain = uri.host.split('.') } catch(e) { return "" }; domain = (domain.length == 2) ? domain[0] : domain[1] return domain.charAt(0).toUpperCase() + domain.slice(1).split('.')[0] + " "; }; var url = gBrowser.selectedTab.image; url && saveImageURL( url, getSiteName(), null, false, false, null, null, /^data:(image\/[^;,]+)/i.test(url) ? RegExp.$1.toLowerCase() : Cc["@mozilla.org/mime;1"] .getService(Ci.nsIMIMEService).getTypeFromURI(Services.io.newURI(url)), null, PrivateBrowsingUtils.isContentWindowPrivate(content || window), document.nodePrincipal ); }; // Копировать иконку текущего сайта в base64 ............. function copyFaviconData() { var img = new Image(); img.src = gBrowser.selectedTab.image; WebScreenShotonImage(img); }; // Сохранить выделенный текст или весь текст на странице как txt файл ............. function saveSelectionToTxt() { let browserMM = gBrowser.selectedBrowser.messageManager; browserMM.addMessageListener('getSelection', function listener(message) { var sel = message.data; !sel && document.getElementById("cmd_selectAll").doCommand(); // создать название файла из заголовка страницы и текущего времени и сохранить текст .... var fileTitle = getTabLabel() + ' ' + aDate().replace(/:/g, "."); saveURL( "data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\r\n\r\n" + sel), fileTitle + ".txt", null, false, false, null, null, null, gBrowser.selectedBrowser.browsingContext.originAttributes.privateBrowsingId > 0, document.nodePrincipal ); !sel && goDoCommand("cmd_selectNone"); browserMM.removeMessageListener('getSelection', listener, true); }); browserMM.loadFrameScript('data:,sendAsyncMessage("getSelection", content.document.getSelection().toString())', false); }; // Добавляем в контекстного меню страницы новые пункты ............. ((contextMenu, el)=> { // в контекстного меню выделенного текста .... var saveItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el); saveItem.id = "content-saveItem"; saveItem.setAttribute("label", "Сохр./добавить выбранный текст в файл"); saveItem.setAttribute("class", "menuitem-iconic"); saveItem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); saveItem.onclick =()=> saveSelectionToFile(); var editorItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el); editorItem.id = "content-editorItem"; editorItem.setAttribute("label", "Открыть выбранный текст в редакторе"); editorItem.setAttribute("class", "menuitem-iconic"); editorItem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAA////AIiafwC85K4AS1ZGANLsyABKU0UAy+m+AL/lsQC14aQAn9WMAJ/QjQCsrKwAqNyXAOPz3ADe8dcA2e/QANPtyQDM68EAxei4AL7lrwC14aUArt6dAJfOhACdz4sAgICAALThpQDg8doA3vHVANjuzgDR7MYAyum+AMLmtQC7460AsuCjAK3dmgCUy4AArdedANDsxQDL6sAAz+PIAMviwwDH4L4Awd62ALvbrwC02KcArdafAKbTlgCEu3EAtNWoANPqywDa8NIA1u7NANHtxwDK6cAAw+e3ALzkrwC14aYAr9+dAKXbkQCJwnMA1+3QAKncmADd8dQAyuLBAMbgvAC6264AttmoAK/XoACn1JYAotKPAJbNgwB9tWgA4+zfANju0ADT7coAz+vFAMPntgC95K8Art6eAKndlQCa1IYAi8R3AP3+/QDD37kAvt2yALjarACz2KYArdaeAKHRjwCXzoUAj8V6AI6/ewDu8e4Awea2AMrqwQDG6LoAweazALnjqwCz4KQAr9+cAKbbkwCd2IkAlc1/AKbTlQC73K8At9qqALDXowCp1ZsApdOVAKDRjQCYzoUAksx7AIi+cwCu0aEAp9yUAMXougDC5rYAveSuALfipwCw4J8AqdyXAKLajwCd2IcAlNR9AI3FdwDU6ssAqdWZAKPSkgCe0YsAmc6GAJDLfQB/tmoA3enZAJfWhACc2IkApNuRAKTbkACj2pAAodqOAKHZjgCl25IAotmOAIzHdgAPAAAA2JIKAAAA9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOzARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcrkUA9CUMAAAAAAAAAAAAAAAAAAAAAAAAAA8AAQAAAAEAAAAAAAAAVCIMAAAAAAABAAAAuwP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAACZDSMAAQAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAABAEAABHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGRkZGRkZGRkZAAAAAAAZAQEBAQEBAQEBARkAAIeHiImKi4yNjY5+AQEZAD4mJlZXRH+AgYKDhIVdGQBzJnR1dnd4eXp7fH1+ARkAGiYnaWprbG1ub3Bxcl0ZACdeJl9gYWJjZGVmZ2gBGQAAAyZUVVZXWEVZWltcXRkAAA1KS0wfTU45T1BRUlMZAAA+P0BBK0JDREVGR0hJGQAAAzIzNDU2Nzg5Ojs8PRkAACYnKCkqKywtLi8YMDEZAAAAGhscHR4fICEiIyQlGQAAAA0ODxAREhMUFRYXGBkAAAADBAUGBwYIBgkGChkAAAAAAAACAAIAAgACAAIAAPgBAADwAAAAwAAAAIAAAACAAAAAgAAAAIAAAADAAAAAwAAAAMAAAADAAAAAwAAAAOAAAADgAAAA4AEAAPqrAAA="); editorItem.onclick =()=> textToEditor(); // устанавливаем где и при каких настройках показывать новые пункты .... addEventListener('popupshowing', e=> { if (e.target != e.currentTarget) return; var sel = gContextMenu.isTextSelected; saveItem.hidden = !sel || !cbu.getPrefs("Save.SelectionToFile"); editorItem.hidden = !sel || !cbu.getPrefs("Save.TextToEditor"); }, false, contextMenu); // удалять новые пункти при изминениях .... addDestructor(()=> { saveItem.remove(); editorItem.remove(); }); })(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open")); // Сохранить или добавить выделенный текст в файл в папке загрузок, если назначена, // иначе на Рабочий стол ............. function saveSelectionToFile() { var line = ".".repeat(62) + "\n"; var hint = "Нажмите чтобы открыть файл"; var prfx = "Выделенный текст сохранен в файл "; var img = self.getAttribute("image"); var desk = Services.dirsvc.get("Desk", Ci.nsIFile); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); (saveSelectionToFile = async () => { var time = aDate(), url = gBrowser.currentURI.displaySpec; var text = `${line}${getTabLabel()} - ${time}\n${url}\n\n${ gContextMenu.contentData.selectionInfo.fullText }\n\n\n`; try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); var msg = prfx + "в папку " + file.leafName; await IOUtils.makeDirectory(file.path); } catch(ex) { file && Cu.reportError(ex); file = desk.clone(); var msg = prfx + "на рабочий стол"; } file.append(`Save - ${time}.txt`); await IOUtils.writeUTF8(file.path, text, {mode: file.exists() ? "append" : "create"}); var name = "sstf-" + Cu.now(); as.showAlertNotification( gBrowser.selectedTab.image || img, msg, hint, true, "", (s, t) => t == "alertclickcallback" && file.launch(), name ); setTimeout(as.closeAlert, 8e3, name); })(); }; // Создать текстовой файл с выделенным текстом в папке загрузок, если назначена, // иначе на Рабочий стол, и открыть в редакторе ............. function textToEditor() { let browserMM = gBrowser.selectedBrowser.messageManager; browserMM.addMessageListener('getSelect', function listener(message) { // создать текст для записи var text = convertFromUnicode("UTF-8", message.data); try {var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {file = Services.dirsvc.get("Desk", Ci.nsIFile);} file.append("TextToEditor.txt"); custombuttonsUtils.writeFile(file.path, text); file.launch(); browserMM.removeMessageListener('getSelect', listener, true); }); browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false); }; // Конвертировать текст в юникод ............. function convertFromUnicode(charset, str) { var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); converter.charset = charset; str = converter.ConvertFromUnicode(str); return str + converter.Finish(); }; // Получить название вкладки без не сохраняемых символов и лишних пробелов .............. function getTabLabel() { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); }; ((main, parts) => this.onmousedown = e => { if (e.button) return; this.onmousedown = null; var df = MozXULElement.parseXULToFragment(` <menugroup orient="vertical"> <menuseparator/> <menuitem class="menuitem-iconic" image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" label="Сохранить всю страницу как PNG" value="all"/> <menuitem class="menuitem-iconic" image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" label="Сохранить видимую часть как PNG" value="page"/> <menuitem class="menuitem-iconic" image="data:image/x-icon;base64,AAABAAEAIBkAAAEAIAAMDQAAFgAAACgAAAAgAAAAMgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29fT/2tra/8jIyP/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8jIyP/a2tr/9vX0/+zs7P/ak0b/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/9qTRv/s7Oz/7Ozs/+J9Dv/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+/6SdmP/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/+vn4//z7+v/6+fj/4n0O/+zs7P/s7Oz/4n0O//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/aFtT//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//j39v/ifQ7/7Ozs/+zs7P/ifQ7/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P9oW1P/7+zq/+/s6v/v7Or/8O3r//Dt6//w7ev/8O3r//Dt6//w7ev/8O3r/+/s6v/w7ev/9fTy/+J9Dv/s7Oz/7Ozs/+J9Dv/49/b/+Pf2//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4/2hbU//q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/y8O//4n0O/+zs7P/s7Oz/4n0O//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/aFtT/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe//Dt6//ifQ7/7Ozs/+zs7P/ifQ7/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P9oW1P/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/7uro/+J9Dv/s7Oz/7Ozs/+J9Dv/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx/2hbU//x7+3/8vDv//Hv7f/x7+3/8e/t//Lw7//x7+3/8e/t//Lw7//x7+3/8vDv//Hv7f/29fT/4n0O/+zs7P/s7Oz/4n0O//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//aFtT/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/8vGwf/ifQ7/7Ozs/+zs7P/ifQ7/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f9nWlL/aFtT/2hbU/9nWlL/Z1pS/2hbU/9oW1P/Z1pS/2daUv9oW1P/aFtT/2hbU/9nWlL/pJyX/+J9Dv/s7Oz/7Ozs/+J9Dv/w7ev/8O3r//Dt6//w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Hv7f/w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Dt6//w7ev/4n0O/+zs7P/s7Oz/4n0O/+/s6v/v7Or/7uro/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/u6uj/7+zq/+/s6v/ifQ7/7Ozs/+zs7P/ifQ7/7uro/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7Ojm/+J9Dv/s7Oz/7Ozs/+J9Dv/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/4n0O/+zs7P/s7Oz/4n0O/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/ifQ7/7Ozs/+zs7P/ifQ7/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+J9Dv/s7Oz/7Ozs/+J9Dv/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/4n0O/+zs7P/s7Oz/4n0O/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/ifQ7/7Ozs/+zs7P/ifQ7/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+J9Dv/s7Oz/7Ozs/+J9Dv/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/k39z/4n0O/+zs7P/s7Oz/4n0O/+Lc2f/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/ifQ7/7Ozs/+zs7P/ifQ7/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+J9Dv/s7Oz/9fTy/+J9Dv/8+/r/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/4n0O//X08v/8+/r/6KFU/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ooVT//Pv6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" label="Сохранить выбранный элемент как PNG" value="click"/> <menuitem class="menuitem-iconic" image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAADDn2Hfz5pE/8eVQP7IlkH/yJZB/8iWQf/IlUH/yJVA/8iVQP/IlED/yJQ//8iUP//IlD//yJM+/8iTPv/Hkj3/nI1w//bDbP//8OH//+zW///s1///69b//+rV///p1P//59L//+XQ///izf//38n//9vG///ZxP//1b///dG////Prf/KlkX/88N4/v37///99Pj//fT6//vy9v/68fT/+u/y//rt8P/66u3/+ufq//rl6P/64eT/+93h//3a3//71d7//9LK/86XR//0xHb//vv////18///9fT///f5///4////9f7///P8///v+f//7Pb//+nz///m8f//4eb//9vZ//3Y2v//1Mb/zphH//TGd//+/////Pj1///7///Q58r/m9aV/6TZnv+i15r/otWY/6LTlv+j0pb/mc6M/9DXuf//3+P//Nnc///Wyf/OmUf/9MZ3//7////8+/j//////53WnP+Y5pn/rvGv/6PvpP+e7p//me6b/5nvm/95533/mM+L///j7f/629z//9jL/86ZR//0xnf//v////z9+v//////qtup/8Xzxf/a/tn/z/vO/8n7yf/D+sL/xPvD/6Hzo/+j05b//+Tu//re3///2cz/zplI//XGeP/+/////P36//////+n26f/uvC6/9T71P/K+Mr/xvjG/8D3wP+/+L//nfCf/6LTlf//5u//+t/g///cz//OmUj/9MZ3//7////8/fr//////6rcqv/G9MX/3//f/9n92f/V/NX/0PzQ/9H+0P+s9a7/pdSY///o8f/64OL//9zP/86aSP/0xnf//v////z9+f//////ndid/5TjlP+v7q//qeyp/6jsqf+k7KX/p+6n/4Tlh/+Z0Y7//+r0//rh4v//3tH/zppI//TGd//+/////v77///////Y8Nj/p9+n/6/jr/+t4a3/rd2p/67bpv+u2ab/p9Wc/9jgx///6Oz//OPl///e0f/Omkj/9MV1//7//////fr///78///+/f///////////////////P////j////0+///8fn//+vu///m4v/94+P//97P/86ZSP/zx3v//v/////+/f///////f////v////7////+/////v+///7+///+/f///vz/P/98Pr//+33//3p9///5OL/zppL//a1Sv/0xoL/9cR7//XEfP/1xHz/9cR8//XEfP/1xH3/9cR8//XCev/1wXr/9b94//W9d//1u3X/87l0//y6bP/Llj7/+pMA/vWBAP/1gwD/9YMA//WDAP/1gwD/9YMA//WDAP/1gwD/9YQA//WEAP/1hAD/9YQA//WEAP/zhAH//okA/8qLIv3xpzP/4ptV/+OdU//jnVP/451T/+OdU//jnVP/451T/+OdU//jnVL/451S/+OdUv/jnVL/451S/+GdVf/qnUf/2aRJ/9q0c9/8yn7/98V5/vjGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6/vrIe/+jj2y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" label="Сохранить выбранную область как PNG" value="clipping"/> </menugroup> `); var menugroup = df.firstChild; menugroup.setAttribute("context", ""); menugroup.setAttribute("oncommand", "handleCommand(event);"); menugroup.handleCommand = e => { var name = _id + ":DataURLReady"; main = main.replace("%MESSAGE_NAME%", name); var urls = {}, configurable = true, enumerable = true; Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, { configurable, enumerable, get() { var value = `data:;charset=utf-8,({${ encodeURIComponent(main + part) }%0A}).init("${key}")`; Object.defineProperty(urls, key, {configurable, enumerable, value}); return value; }})); var getTabLabel = () => { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); } var listener = msg => { var fp = makeFilePicker(); fp.init(window, "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); fp.defaultString = getTabLabel() + ".png"; fp.open(res => { if (res == fp.returnCancel || !fp.file) return; var wbp = makeWebBrowserPersist(), args = [ Services.io.newURI(msg.data), document.nodePrincipal, null, null, null, null, fp.file, null ]; //wbp.saveURI.length == 9 && splice(args); var {length} = wbp.saveURI; length >= 9 && splice(args); length == 10 && args.splice(3, 0, null); wbp.saveURI(...args); }); } var splice = arr => { var fox74 = parseInt(Services.appinfo.platformVersion) >= 74; var args = [fox74 ? 7 : 2, 0, fox74 ? Ci.nsIContentPolicy.TYPE_IMAGE : null]; (splice = arr => arr.splice(...args))(arr); } messageManager.addMessageListener(name, listener); addDestructor(() => messageManager.removeMessageListener(name, listener)); (menugroup.handleCommand = e => gBrowser.selectedBrowser.messageManager .loadFrameScript(urls[e.target.value], false) )(e); } menuPopup.querySelector('menuitem[label*="ярлык"]').after(df); })(` init(cmd) { cmd.startsWith("c") ? this[cmd].init(this[cmd].parent = this) : this[cmd](); }, capture(win, x, y, width, height) { var canvas = win.document.createElementNS("${xhtmlns}", "canvas"); canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); var tryDraw = ind => { try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")} catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);} } tryDraw(17); sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png")); }, `, { all: `all() { var win = content; this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY); }`, page: `page() { var win = content, doc = win.document, body = doc.body, html = doc.documentElement; var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft; var scrY = (body.scrollTop || html.scrollTop) - html.clientTop; this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight); }`, clipping: `clipping: { handleEvent(e) { if (e.button) return false; e.preventDefault(); e.stopPropagation(); switch(e.type) { case "mousedown": this.downX = e.pageX; this.downY = e.pageY; this.bs.left = this.downX + "px"; this.bs.top = this.downY + "px"; this.body.appendChild(this.box); this.flag = true; break; case "mousemove": if (!this.flag) return; this.moveX = e.pageX; this.moveY = e.pageY; if (this.downX > this.moveX) this.bs.left = this.moveX + "px"; if (this.downY > this.moveY) this.bs.top = this.moveY + "px"; this.bs.width = Math.abs(this.moveX - this.downX) + "px"; this.bs.height = Math.abs(this.moveY - this.downY) + "px"; break; case "mouseup": this.uninit(); break; } }, init() { var win = {}; Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, win); this.win = win.value; this.doc = this.win.document; this.body = this.doc.body; if (!HTMLBodyElement.isInstance(this.body)) { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService) .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!"); return false; } this.flag = null; this.box = this.doc.createElement("div"); this.bs = this.box.style; this.bs.border = "#0f0 dashed 2px"; this.bs.position = "absolute"; this.bs.zIndex = "2147483647"; this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor; this.body.style.cursor = "crosshair"; ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)]; this.body.style.cursor = this.defaultCursor; this.body.removeChild(this.box); this.parent.capture.apply(this, pos); ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }`, click: `click: { getPosition() { var html = this.doc.documentElement; var body = this.doc.body; var rect = this.target.getBoundingClientRect(); return [ this.win, Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft, Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop, parseInt(rect.width), parseInt(rect.height) ]; }, highlight() { this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false; this.target.style.cssText += "outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;"; }, lowlight() { if (this.orgStyle) this.target.style.cssText = this.orgStyle; else this.target.removeAttribute("style"); }, handleEvent(e) { switch(e.type){ case "click": if (e.button) return; e.preventDefault(); e.stopPropagation(); this.lowlight(); this.parent.capture.apply(this, this.getPosition()); this.uninit(); break; case "mouseover": if (this.target) this.lowlight(); this.target = e.target; this.highlight(); break; } }, init() { this.win = content; this.doc = content.document; ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { this.target = false; ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }` }); |
voqabuhe > 19-05-2022 00:41:41 |
_zt |
voqabuhe > 21-05-2022 11:11:09 |
Dumby |
Dumby > 21-05-2022 13:20:13 |
_zt пишет
Набросок: три фрагмента (если оседание фавиконов в загрузках не ценность). скрытый текст Выделить код Код:if (typeof window.saveImageURL != "function") var saveImageURL = internalSave.length == 15 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, a7, a5, null, priv, prin); // Сохранить иконку текущего сайта с диалогом сохранения ............. function saveFavicon() { var uri = gBrowser.currentURI; function getSiteName() { try { var domain = uri.host.split('.') } catch(e) { return "" }; domain = (domain.length == 2) ? domain[0] : domain[1] return domain.charAt(0).toUpperCase() + domain.slice(1).split('.')[0] + " "; }; var url = gBrowser.selectedTab.image; url && saveImageURL( url, getSiteName(), null, false, false, null, null, /^data:(image\/[^;,]+)/i.test(url) ? RegExp.$1.toLowerCase() : Cc["@mozilla.org/mime;1"] .getService(Ci.nsIMIMEService).getTypeFromURI(Services.io.newURI(url)), null, PrivateBrowsingUtils.isContentWindowPrivate(content || window), document.nodePrincipal ); }; Выделить код Код:function saveShortcuts() { var file = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsIFile); file.initWithPath(folderpath); if( !file.exists() || !file.isDirectory() ) { file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0x1B6);} var savetodir=folderpath+"\\"; var urllink=gBrowser.currentURI.spec; var out=getTabLabel(); var filename=savetodir+out+'.url'; var data="[InternetShortcut]\r\nURL="+urllink+"\r\n"; saveToFile(data, filename); // стиль для изображения во всплывающей подсказке .... var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); // подсказка var notific = 'Сохранил в: ' + folderpath; var image = gBrowser.selectedBrowser.mIconURL; Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(image, filename, notific); }; Выделить код Код:async function pick(fileName) { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } var fp = makeFilePicker(); fp.init(window, "", fp.modeSave); fp.displayDirectory = file; fp.defaultString = fileName; return await new Promise(fp.open) != fp.returnCancel && fp.file; } function saveFavicon() { var dn = "favicon"; var re = /^data:(image\/[^;,]+)/i; var ms = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService); (saveFavicon = async () => { var url = gBrowser.selectedTab.image; if (!url) return; if (re.test(url)) { try {var name = gBrowser.currentURI.host || dn;} catch {name = dn;} name += "." + ms.getPrimaryExtension(RegExp.$1, "ico"); } else var name = Services.io.newURI(url).QueryInterface(Ci.nsIURL).fileName; var file = await pick(name); file && IOUtils.write(file.path, new Uint8Array(await (await fetch(url)).arrayBuffer())); })(); } function saveShortcuts() { var img = self.getAttribute("image"); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); (saveShortcuts = async () => { var file = await pick(getTabLabel() + ".url"); if (file) await IOUtils.writeUTF8(file.path, `[InternetShortcut]\r\nURL=${gBrowser.currentURI.spec}\r\n`), as.showAlertNotification( gBrowser.selectedTab.image || img, file.leafName, "Сохранил в: " + file.parent.path ); })(); } voqabuhe пишет
Говорят что нет. |
voqabuhe > 21-05-2022 13:39:57 |
Dumby |
_zt > 21-05-2022 21:22:00 |
Dumby |
Dumby > 25-05-2022 19:34:31 |
voqabuhe пишет
У меня не получилось какой-нибудь browser.js или about:license. Кстати, imgIEncoder способен собрать PNG большего размера чем canvas, скрытый текст Выделить код Код:(async cid => { var fp = makeFilePicker(); fp.init(window, "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); var lab = DownloadPaths.sanitize(gBrowser.selectedTab.label); fp.defaultString = lab.slice(0, 50).trimRight() + ".png"; var res = await new Promise(fp.open); if (res == fp.returnCancel || !fp.file) return; var {file} = fp; var br = gBrowser.selectedBrowser; var name = "extrem-encoder:de-xy-dpr-info"; var url = "data:,(" + encodeURIComponent((de, name) => sendAsyncMessage( name, [de.scrollWidth, de.scrollHeight, content.devicePixelRatio] )) + `)(content.document.documentElement, "${name}")`; var mm = br.messageManager; mm.loadFrameScript(url, false); var res = await new Promise(r => { var lst = msg => mm.removeMessageListener(name, lst, r(msg.data)); mm.addMessageListener(name, lst); }); var [width, height, k] = res; var rectWidth = width; width = Math.floor(width * k); height = Math.floor(height * k); var step = 2000; var rectHeight = step / k; var canvas = document.createElement("canvas"); canvas.width = width; canvas.height = step; var ctx = canvas.getContext("2d"); var stride = width * 4; var encoder = Cc[cid].createInstance(Ci.imgIEncoder); var RGBA = encoder.INPUT_FORMAT_RGBA; encoder.startImageEncode(width, height, RGBA, ""); var cwg = br.browsingContext.currentWindowGlobal; for(var y = 0; y < height; y += step) { var rect = new DOMRect(0, y / k, rectWidth, rectHeight); ctx.drawImage(await cwg.drawSnapshot(rect, k, "white"), 0, 0); var {data} = ctx.getImageData(0, 0, width, step); encoder.addImageFrame(data, data.length, width, step, stride, RGBA, ""); } encoder.endImageEncode(); var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); stream.setInputStream(encoder.QueryInterface(Ci.nsIInputStream)); var bytes = stream.readByteArray(stream.available()); await IOUtils.write(file.path, new Uint8Array(bytes)); file.reveal(); })("@mozilla.org/image/encoder;2?type=image/png"); _zt пишет
Увы, я не знаток существования скриптов.
Если формат списка внутренний (только для этого скрипта), скрытый текст Выделить код Код:(async () => CustomizableUI.createWidget({ id: "799775", label: "799775", tooltiptext: "799775", localized: false, marker: "[ucf_tabs_linkset]\n\n", onCreated(btn) { btn.setAttribute("image", "resource://usercontext-content/pet.svg"); btn.setAttribute("type", "menu"); btn.prepend(btn.ownerGlobal.MozXULElement.parseXULToFragment( `<menupopup oncommand="creator.cmd(event);"> <menuitem label="Сохранить адреса вкладок" value="1"/> <menuitem label="Сохранить адреса всех вкладок" value="2"/> <menuseparator/> <menuitem label="Копировать адреса вкладок" value="3"/> <menuitem label="Копировать адреса всех вкладок" value="4"/> <menuseparator/> <menuitem label="Открыть из файла" value="5"/> <menuitem label="Открыть из буфера" value="6"/> </menupopup>` )); btn.firstChild.creator = this; }, async cmd(e) { var win = e.view, num = e.target.value; if (num < 5) { var tabs = num % 2 ? win.gBrowser.selectedTabs : win.gBrowser.visibleTabs; if (num > 2) return this.copy(this.text(tabs)); var file = await this.pick( win, `Linkset ${new Date().toLocaleString("mn").replace(/:/g, "\ua789")} [${tabs.length}] .txt` ); return file && win.IOUtils.writeUTF8(file.path, this.text(tabs)); } if (num == 6) var text = win.readFromClipboard(); else { var file = await this.pick(win); if (!file) return; var text = await win.IOUtils.readUTF8(file.path); } if (!text?.startsWith(this.marker)) return; var gb = win.gBrowser; var arg = { index: gb.selectedTab._tPos + 1, triggeringPrincipal: win.document.nodePrincipal }; var arr = text.split("\n"); for(var ind = arr.length - 1; ind > 2; ind -= 3) var tab = gb.addTab(arr[ind], arg); if (!e.button && !e.shiftKey) gb.selectedTab = tab; }, text(tabs) { var res = []; for(var tab of tabs) { var br = tab.linkedBrowser; var url = br.currentURI.spec, beg = url.slice(0, 40); var title = br.contentTitle || "untitled"; if (title.startsWith(beg)) title = beg; res.push(title + "\n" + url); } return this.marker + res.join("\n\n"); }, copy(text) { var cb = Services.clipboard.kGlobalClipboard; var ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); (this.copy = text => ch.copyStringToClipboard(text, cb))(text); }, async pick(win, fileName) { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } var fp = win.makeFilePicker(); fp.init(win, "", fileName ? fp.modeSave : fp.modeOpen); fp.displayDirectory = file; fp.appendFilter("", "*.txt"); fp.appendFilters(fp.filterAll); if (fileName) fp.defaultString = fileName; return await new Promise(fp.open) != fp.returnCancel && fp.file; } }))(); |
_zt > 25-05-2022 21:00:00 |
Dumby |
Dumby > 26-05-2022 09:28:53 |
_zt пишет
Я же совершенно не разбираюсь в урлах и их списках. скрытый текст Выделить код Код:/* if (!text?.startsWith(this.marker)) return; var gb = win.gBrowser; var arg = { index: gb.selectedTab._tPos + 1, triggeringPrincipal: win.document.nodePrincipal }; var arr = text.split("\n"); for(var ind = arr.length - 1; ind > 2; ind -= 3) var tab = gb.addTab(arr[ind], arg); if (!e.button && !e.shiftKey) gb.selectedTab = tab; }, */ if (!text) return; var own = text.startsWith(this.marker); if (own) var arr = text.split("\n"); else { var urls = this.parse(text); if (!urls?.length) return; } var gb = win.gBrowser; var arg = { index: gb.selectedTab._tPos + 1, triggeringPrincipal: win.document.nodePrincipal }; if (own) for(var ind = arr.length - 1; ind > 2; ind -= 3) var tab = gb.addTab(arr[ind], arg); else for(var url of urls) var tab = gb.addTab(url, arg); if (!e.button && !e.shiftKey) gb.selectedTab = tab; }, parse(text) { var result = new Set(); var candidates = new Set( text.split(this.space).filter(this.colon) ); for(var str of candidates) { var url = this.url(str); if (url) result.add(str); else { for(var splitter of this.splitters) { var arr = str.split(splitter).filter(Boolean); for(var sub of arr) url = this.url(sub), url && result.add(url); } } } var {size} = result; if (size) { result = Array.from(result); if (size > 1) result.reverse(); return result; } }, space: /\s+/, colon: str => str.includes(":"), splitters: [",", ";", '"', "'", /[\[\]]/, /()/], url(str) { try { var scheme = Services.io.extractScheme(str); if (scheme.length + 1 == str.length || scheme == "default") return; var ph = Services.io.getProtocolHandler(scheme); if (ph.scheme == scheme) return Services.io.newURI(str).spec; } catch {} },
Да, мой косяк. Конечно же await win.IOUtils.makeDirectory(file.path); |
_zt > 26-05-2022 18:30:43 |
Dumby Пример списка с перечисленными проблемами Выделить код Код:Создание гиперссылок - Изучение веб-разработки | MDN https://developer.mozilla.org/ru/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks // afgaga Управление дополнениями about:addons Ресурс resource://usercontext-content/pet.svg HTML <a href="https://en.wikipedia.org/wiki/Percent-encoding">Percent-encoding - Wikipedia</a> BB-code без заголовка [url]https://forum.mozilla-russia.org/index.php[/url] /* Проблемные ссылки */ Ссылка с запятой в конце адреса (открывает вместе с запятой) https://github.com/Aris-t2/CustomCSSforFx/blob/master/classic/css/tabs/tabs_multiple_lines.css, BB-code с заголовком (не открывает) [url=https://forum.mozilla-russia.org/viewtopic.php?id=76642&p=14]UCF-скрипты на этом форуме | Форум Mozilla Россия[/url] markdown 1 (не открывает) [Ссылка на корень сайта](https://planshet-info.ru/kompjutery/ssylka-na-koren-sajta) markdown 2 (не открывает) ![Image and Preview Themes on the toolbar](https://markdownmonster.west-wind.com/docs/images/EditorPreviewThemeUi.png) Ссылка с пробелами (обрезает по первому пробелу) https://yandex.ru/yandsearch?text=команда на копирование файлов и папок в bat&lr=213 ps^ Исправил пост, сам пытался парсер править и сломал BB-code без заголовка. |
Dumby > 27-05-2022 09:02:28 |
_zt
А что за спецсимволы? Написал так: singleSpace: / (?![\s"])/g, скрытый текст Выделить код Код://....... onCreated(btn) { btn.setAttribute("image", "resource://usercontext-content/pet.svg"); btn.setAttribute("type", "menu"); btn.prepend(btn.ownerGlobal.MozXULElement.parseXULToFragment( `<menupopup oncommand="creator.cmd(event);" onpopupshowing="creator.check(this.lastChild);"> <menuitem label="Сохранить адреса вкладок" value="1"/> <menuitem label="Сохранить адреса всех вкладок" value="2"/> <menuseparator/> <menuitem label="Копировать адреса вкладок" value="3"/> <menuitem label="Копировать адреса всех вкладок" value="4"/> <menuseparator/> <menuitem label="Открыть из файла" value="5"/> <menuitem label="Открыть из буфера" value="6"/> <menuitem label="Заменять одиночные пробелы процентами" closemenu="none" type="checkbox" value="7"/> </menupopup>` )); btn.firstChild.creator = this; }, check(item) { var pref = "ucf.linkset-widget.replspace"; this.checked = Services.prefs.getBoolPref(pref, false); this.setPref = Services.prefs.setBoolPref.bind(null, pref); (this.check = item => { this.checked ? item.setAttribute("checked", true) : item.removeAttribute("checked"); })(item); }, singleSpace: / (?![\s"])/g, async cmd(e) { var num = e.target.value; if (num == 7) return this.setPref(this.checked = e.target.hasAttribute("checked")); var win = e.view; if (num < 5) { var tabs = num % 2 ? win.gBrowser.selectedTabs : win.gBrowser.visibleTabs; if (num > 2) return this.copy(this.text(tabs)); var file = await this.pick( win, `Linkset ${new Date().toLocaleString("mn").replace(/:/g, "\ua789")} [${tabs.length}] .txt` ); return file && win.IOUtils.writeUTF8(file.path, this.text(tabs)); } if (num == 6) var text = win.readFromClipboard(); else { var file = await this.pick(win); if (!file) return; var text = await win.IOUtils.readUTF8(file.path); } if (!text) return; // if (!text || text.length > 500_000) return; // limit? var own = text.startsWith(this.marker); if (this.checked && !own) text = text.replace(this.singleSpace, "%20"); var gb = win.gBrowser, tl = gb.visibleTabs.length; if (own) for(var ind = 3, arr = text.split("\n"), len = arr.length; ind < len; ind += 3) gb.addTrustedTab(arr[ind]); else { var urls = this.parse(text); if (urls?.size) for(var url of urls) gb.addTrustedTab(url); } if (!e.button && !e.shiftKey) gb.selectedTab = gb.visibleTabs[tl]; }, parse(text) { var result = new Set(); var candidates = new Set( text.split(this.space).filter(this.colon) ); for(var str of candidates) { var url = this.url(str); if (url) result.add(str); else { var bb = true; for(var splitter of this.splitters) { var arr = str.split(splitter).filter(this.colon); for(var sub of arr) { if (bb) { // [] var ind = sub.indexOf("="); if (ind != -1 && ind < sub.indexOf(":")) sub = sub.slice(ind + 1); } url = this.url(sub); url && result.add(url); } bb = false; } } } // console log instead of open //if (true) return Services.console.logStringMessage(Array.from(result).join("\n")); //var {size} = result; //if (size > 100 && !Services.prompt.confirm(null, null, `Количество вкладок: ${size}! Открыть?`)) return; // limit? return result; }, space: /\s+/, colon: str => str.includes(":"), splitters: [/[\[\]]/, /[()]/, ",", ";", '"', "'"], unwanedEnds: /,$/, url(str) { try { var scheme = Services.io.extractScheme(str); if (scheme.length + 1 == str.length || scheme == "default") return; var ph = Services.io.getProtocolHandler(scheme); if (ph.scheme == scheme) return Services.io.newURI(str.replace(this.unwanedEnds, "")).spec; } catch {} }, text(tabs) { var res = []; for(var tab of tabs) { var br = tab.linkedBrowser; var url = br.currentURI.spec, beg = url.slice(0, 40); var title = br.contentTitle || "untitled"; if (title.startsWith(beg)) title = beg; res.push(title + "\n" + url); } return this.marker + res.join("\n\n"); }, copy(text) { var cb = Services.clipboard.kGlobalClipboard; var ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); (this.copy = text => ch.copyStringToClipboard(text, cb))(text); }, async pick(win, fileName) { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await win.IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } var fp = win.makeFilePicker(); fp.init(win, "", fileName ? fp.modeSave : fp.modeOpen); fp.displayDirectory = file; fp.appendFilter("", "*.txt"); fp.appendFilters(fp.filterAll); if (fileName) fp.defaultString = fileName; return await new Promise(fp.open) != fp.returnCancel && fp.file; } }))(); |
_zt > 27-05-2022 14:32:14 |
Dumby Выделить код Код:<a href="https://en.wikipedia.org/">https://en.wikipedia.org/</a>, [https://en.wikipedia.org/](https://en.wikipedia.org/), [url=https://en.wikipedia.org/]https://en.wikipedia.org/[/url], Всегда получается "https://en.wikipedia.org/," при копировании. |
Dumby > 29-05-2022 12:41:57 |
_zt пишет
Да, есть опечатки в коде.
Насколько мне известно, в Firefox нет API для определения кодировки. или Есть ещё такой жуткий вариант: загружаем добро в невидимое окно как документ, где Firefox сам определит кодировку по содержимому, и забираем результат. В многопроцессном режиме, естественно, грузится не захочет, поэтому ещё и свой протокол надо регистрировать. Ну и в консоли будет спам, что мол кодировка не указана, что ожидаемо. Вобщем, только на крайний случай, если первый вариант не подойдёт. скрытый текст Выделить код Код://....... async cmd(e) { var num = e.target.value; if (num == 7) return this.setPref(this.checked = e.target.hasAttribute("checked")); var win = e.view; if (num < 5) { var tabs = num % 2 ? win.gBrowser.selectedTabs : win.gBrowser.visibleTabs; if (num > 2) return this.copy(this.text(tabs)); var file = await this.pick( win, `Linkset ${new Date().toLocaleString("mn").replace(/:/g, "\ua789")} [${tabs.length}] .txt` ); return file && win.IOUtils.writeUTF8(file.path, this.text(tabs)); } if (num == 6) var text = win.readFromClipboard(); else { var file = await this.pick(win); if (!file) return; var text = await this.read(file); } if (!text) return; // if (!text || text.length > 500_000) return; // limit? var own = text.startsWith(this.marker); if (this.checked && !own) text = text.replace(this.singleSpace, "%20"); var gb = win.gBrowser, tl = gb.visibleTabs.length; if (own) for(var ind = 3, arr = text.split("\n"), len = arr.length; ind < len; ind += 3) gb.addTrustedTab(arr[ind]); else { var urls = this.parse(text); if (urls?.size) for(var url of urls) gb.addTrustedTab(url); } if (!e.button && !e.shiftKey) gb.selectedTab = gb.visibleTabs[tl]; }, read(file) { var read1251 = async file => { var suc = Cc["@mozilla.org/intl/scriptableunicodeconverter"] .createInstance(Ci.nsIScriptableUnicodeConverter); suc.charset = "windows-1251"; var reader = new FileReader(); return (read1251 = async file => { reader.readAsBinaryString(file); await new Promise(resolve => reader.onloadend = resolve); return suc.ConvertToUnicode(reader.result); })(file); } var {IOUtils} = Cu.getGlobalForObject(Cu); return (this.read = async file => { try {return await IOUtils.readUTF8(file.path);} catch {return read1251(file);} })(file); }, parse(text) { var result = new Set(); var candidates = new Set( text.split(this.space).filter(this.colon) ); for(var str of candidates) { var url = this.url(str); if (url) result.add(url); else { var bb = true; for(var splitter of this.splitters) { var arr = str.split(splitter).filter(this.colon); for(var sub of arr) { if (bb) { // [] var ind = sub.indexOf("="); if (ind != -1 && ind < sub.indexOf(":")) sub = sub.slice(ind + 1); } url = this.url(sub); url && result.add(url); } bb = false; } } } // console log instead of open //if (true) return Services.console.logStringMessage(Array.from(result).join("\n")); //var {size} = result; //if (size > 100 && !Services.prompt.confirm(null, null, `Количество вкладок: ${size}! Открыть?`)) return; // limit? return result; }, space: /\s+/, colon: str => str.includes(":"), splitters: [/[\[\]]/, /[()]/, ",", ";", '"', "'"], unwantedEnds: /[,;]$/, url(str) { try { var scheme = Services.io.extractScheme(str); if (scheme.length + 1 == str.length || scheme == "default") return; var ph = Services.io.getProtocolHandler(scheme); if (ph.scheme == scheme) return Services.io.newURI(str.replace(this.unwantedEnds, "")).spec; } catch {} }, text(tabs) { var res = []; for(var tab of tabs) { var br = tab.linkedBrowser; var url = br.currentURI.spec, beg = url.slice(0, 40); var title = br.contentTitle || "untitled"; if (title.startsWith(beg)) title = beg; res.push(title + "\n" + url); } return this.marker + res.join("\n\n"); }, copy(text) { var cb = Services.clipboard.kGlobalClipboard; var ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); (this.copy = text => ch.copyStringToClipboard(text, cb))(text); }, async pick(win, fileName) { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await win.IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } var fp = win.makeFilePicker(); fp.init(win, "", fileName ? fp.modeSave : fp.modeOpen); fp.displayDirectory = file; fp.appendFilter("", "*.txt"); fp.appendFilters(fp.filterAll); if (fileName) fp.defaultString = fileName; if (await new Promise(fp.open) == fp.returnCancel) return; if (fileName) var file = fp.file; else { var file = fp.domFileOrDirectory; file.path = fp.file.path; } return file; } }))();
Ой, даже затрудняюсь ответить. А можно экранировать, наоборот, те, которые при экранировании не образуют другой смысл. |
_zt > 30-05-2022 02:45:58 |
Dumby пишет
Это не про скрипт, это про список, а он может быть откуда угодно, в том числе скопирован со страницы. Dumby пишет
Как то сложно все. Не надо наверное, я потестирую то что есть. |
Dumby > 30-05-2022 09:38:10 |
_zt пишет
Если именно при открытии вкладок, то можно так попробовать скрытый текст Выделить код Код:/* if (own) for(var ind = 3, arr = text.split("\n"), len = arr.length; ind < len; ind += 3) gb.addTrustedTab(arr[ind]); else { var urls = this.parse(text); if (urls?.size) for(var url of urls) gb.addTrustedTab(url); } if (!e.button && !e.shiftKey) gb.selectedTab = gb.visibleTabs[tl]; }, */ if (own) for(var ind = 3, arr = text.split("\n"), len = arr.length; ind < len; ind += 3) gb.addTrustedTab(this.decode(arr[ind])); else { var urls = this.parse(text); if (urls?.size) for(var url of urls) gb.addTrustedTab(this.decode(url)); } if (!e.button && !e.shiftKey) gb.selectedTab = gb.visibleTabs[tl]; }, decode: url => url.startsWith("data:") ? url : decodeURI(url), А так-то, было бы неплохо самому Автору дополнения рассмотреть возможность ограничения ширины списка адресов, а то у меня тут попался data:… адрес, так окно расколбасило не просто «во все окно браузера по ширине», а далеко за пределы экрана, овер шестнадцать тысяч (!) пикселей. Ну или пользовательский смирительный стиль какой-нибудь запилить. |
_zt > 30-05-2022 23:23:42 |
Dumby Dumby пишет
Ну так как то. userContent.css Выделить код Код:@-moz-document url-prefix(moz-extension://uuid) { /* Не позволять растягивать дополнительные окна больше заданного размера */ .rich-confirm-dialog { max-width: 800px !important; } } |
voqabuhe > 31-05-2022 04:26:32 |
Dumby |
Dumby > 31-05-2022 08:03:32 |
voqabuhe пишет
ChromeUtils.import(…, null) сто лет как считался "не по понятиям". скрытый текст Выделить код Код:/* XPCOMUtils.defineLazyGetter(this, "GlobalManager", () => { const { GlobalManager } = ChromeUtils.import("resource://gre/modules/Extension.jsm", null); return GlobalManager; }); */ XPCOMUtils.defineLazyGetter(this, "GlobalManager", () => ChromeUtils.import("resource://gre/modules/ExtensionParent.jsm").ExtensionParent.GlobalManager ); |
voqabuhe > 31-05-2022 08:44:26 |
Dumby Dumby пишет
Гениально! Спасибо! |
kokoss > 31-05-2022 17:04:45 |
Dumby пишет
Благодарю |
_zt > 01-06-2022 01:36:31 |
Dumby |
Dumby > 01-06-2022 18:17:57 |
_zt пишет
Следуем за ними. скрытый текст Выделить код Код:/* var z = win.windowUtils.screenPixelsPerCSSPixel; */ var z = win.devicePixelRatio; |
_zt > 02-06-2022 19:17:32 |
Dumby |
Dumby > 02-06-2022 21:19:50 |
_zt пишет
Ну да, я упоминал. Если грузить скрипт снаружи в объект Это не касается доживающих последние времена NSVO. Пока сам Cu.import() ещё с нами, можно так попробовать скрытый текст Выделить код Код:/* if (!g[key]) { Services.scriptloader.loadSubScript( `data:,this.${key}=TransactionsHistory.proxifiedToRaw;`, g ); var raws = g[key]; */ var raws = g.TransactionsHistory?.proxifiedToRaw; if (raws) g = raws; if (!g[key]) { if (!raws) { Services.scriptloader.loadSubScript( `data:,this.${key}=TransactionsHistory.proxifiedToRaw;`, g ); raws = g[key]; } |
_zt > 03-06-2022 00:10:35 |
Dumby |
Dumby > 03-06-2022 08:02:23 |
_zt пишет
Так 102 всё уже, готова. Почти весь отвал делается в Nightly. |
xrun1 > 06-06-2022 11:54:42 |
В 101 (может и раньше) отвалилась кнопка "Дополнения" из расширения Add Toolbar Buttons. скрытый текст Выделить код Код:try {(() => { var id = "ucf-aom-button", label = "Дополнения", tooltiptext = "ЛКМ: Меню дополнений\nShift+ЛКМ: Меню дополнений + открыть менеджер\nСКМ: Открыть менеджер дополнений", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 24,4.5 18,12 3,23.7 12,32.7 3.9,44.1 7.8,48 H 45 C 46.7,48 48,46.7 48,45 V 26.1 L 34.8,12.9 31.8,12.3 Z'/><path style='fill:white;' d='M 19.88,3 C 16.93,3 14.55,4.662 14.55,6.701 14.63,7.474 15.11,8.438 15.37,8.762 16.59,10.41 16.59,11.44 16.29,12.06 H 6.299 C 4.476,12.06 3,13.53 3,15.35 V 23.68 C 3.625,24 4.65,24 6.299,22.77 6.625,22.52 7.587,22.02 8.363,21.94 10.4,21.94 12.06,24.35 12.06,27.29 12.06,30.24 10.4,32.65 8.363,32.65 7.725,32.63 6.774,32.07 6.299,31.82 4.65,30.59 3.625,30.59 3,30.91 V 41.71 C 3,43.53 4.476,45 6.299,45 H 19.58 C 19.88,44.38 19.88,43.35 18.65,41.71 18.4,41.38 17.91,40.42 17.82,39.65 17.82,37.6 20.23,35.94 23.18,35.94 26.14,35.94 28.55,37.6 28.55,39.65 28.53,40.28 27.97,41.23 27.71,41.71 26.47,43.35 26.47,44.38 26.79,45 H 32.65 C 34.47,45 35.96,43.53 35.96,41.71 V 32.55 C 36.56,32.23 37.59,32.23 39.23,33.47 39.72,33.73 40.68,34.29 41.29,34.29 43.35,34.29 45,31.91 45,28.94 45,25.99 43.35,23.59 41.29,23.59 40.54,23.67 39.58,24.17 39.23,24.41 37.59,25.65 36.56,25.65 35.96,25.33 V 15.35 C 35.96,13.53 34.47,12.06 32.65,12.06 H 23.49 C 23.19,11.44 23.19,10.41 24.41,8.762 24.66,8.287 25.22,7.337 25.23,6.713 25.23,4.662 22.85,3 19.88,3' /></g></svg>", checked = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='M 4,5 7.5,8.5 12,4 V 8 L 8,12 H 7 L 4,9 Z' style='fill:white'/></svg>", show_version = true, show_description = true, user_permissions = true, show_hidden = true, show_disabled = true, enabled_first = true, exceptions_listset = new Set([ ]); exceptions_type_listset = new Set([ ]); if (!("AddonManager" in this)) ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm"); if (!("GlobalManager" in this)) XPCOMUtils.defineLazyGetter(this, "GlobalManager", () => { const { GlobalManager } = ChromeUtils.import("resource://gre/modules/Extension.jsm", null); return GlobalManager; }); var extensionOptionsMenu = { get alertsService() { delete this.alertsService; return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); }, get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, get exceptions_type_listarr() { delete this.exceptions_type_listarr; var arr = ["extension", "theme", "locale", "dictionary"]; if (!exceptions_type_listset.size) return this.exceptions_type_listarr = arr; return this.exceptions_type_listarr = arr.filter(type => !exceptions_type_listset.has(type)); }, populateMenu: async function(e) { var popup = e.target, doc = e.view.document; var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr); var addonsMap = new WeakMap(), setAttributesMenu = (mi, addon, extension) => { var permissions, uuid, props = { label: `${addon.name}${show_version ? ` ${addon.version}` : ""}`, class: "menuitem-iconic", tooltiptext: `${(show_description && addon.description) ? `${addon.description}\n` : ""}ID: ${addon.id}${addon.isActive && (uuid = extension?.uuid) ? `\nUUID: ${uuid}` : ""}${(user_permissions && (permissions = addon.userPermissions?.permissions)?.length) ? `\nРазрешения: ${permissions.join(", ")}` : ""}\n${addon.optionsURL ? "\nЛКМ: Настройки" : ""}\nCtrl+ЛКМ: Копировать ID${uuid ? "\nShift+ЛКМ: Копировать UUID" : ""}${addon.creator?.url ? "\nCtrl+Shift+ЛКМ: Автор" : ""}${addon.homepageURL ? "\nСКМ: Домашняя страница" : ""}${!addon.isBuiltin ? "\nCtrl+СКМ: Просмотр источника" : ""}\nShift+СКМ: Просмотр источника во вкладке\nПКМ: Включить/Отключить${(!addon.isSystem && !addon.isBuiltin) ? "\nCtrl+ПКМ: Удалить" : ""}`, }; for (let p in props) mi.setAttribute(p, props[p]); if (addon.iconURL) mi.setAttribute("image", addon.iconURL); var cls = mi.classList; addon.isActive ? cls.remove("ucf-disabled") : cls.add("ucf-disabled"); addon.optionsURL ? cls.remove("ucf-notoptions") : cls.add("ucf-notoptions"); addon.isSystem ? cls.add("ucf-system") : cls.remove("ucf-system"); cls.add(`ucf-type-${addon.type}`); }; addons.filter(a => !(a.iconURL || "").startsWith("resource://search-extensions/")).sort((a, b) => { var ka = `${(enabled_first ? a.isActive ? "0" : "1" : "")}${a.type || ""}${a.name.toLowerCase()}`; var kb = `${(enabled_first ? b.isActive ? "0" : "1" : "")}${b.type || ""}${b.name.toLowerCase()}`; return (ka < kb) ? -1 : 1; }).forEach(addon => { if (!exceptions_listset.has(addon.id) && (!addon.hidden || show_hidden) && (!addon.userDisabled || show_disabled)) { let extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.append(mi); addonsMap.set(addon, mi); } }); var click = (e) => { this.handleClick(e); }; popup.addEventListener("click", click); var listener = { onEnabled: addon => { var mi = addonsMap.get(addon); if (mi) setAttributesMenu(mi, addon, mi._Extension); }, onDisabled: addon => { listener.onEnabled(addon); }, onInstalled: addon => { var extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.prepend(mi); addonsMap.set(addon, mi); }, onUninstalled: addon => { var mi = addonsMap.get(addon); if (mi) { mi.remove(); addonsMap.delete(addon); } }, }; AddonManager.addAddonListener(listener); popup.addEventListener("popuphiding", (e) => { AddonManager.removeAddonListener(listener); popup.removeEventListener("click", click); addonsMap = null; while (popup.hasChildNodes()) popup.firstChild.remove(); }, { once: true }); }, handleClick: function(e) { var win = e.view, mi = e.target; if (!("_Addon" in mi) || !("_Extension" in mi)) return; var addon = mi._Addon, extension = mi._Extension; switch (e.button) { case 0: if (e.ctrlKey && e.shiftKey) { if (addon.creator?.url) win.gBrowser.selectedTab = this.addTab(win, addon.creator.url); } else if (e.ctrlKey) { this.clipboardHelp.copyString(addon.id); try { this.alertsService.showAlertNotification(`${img}`, "ID в буфере обмена!", addon.id, false); } catch(e) {} } else if (e.shiftKey) { if (extension?.uuid) { this.clipboardHelp.copyString(extension.uuid); try { this.alertsService.showAlertNotification(`${img}`, "UUID в буфере обмена!", extension.uuid, false); } catch(e) {} } } else if (addon.isActive && addon.optionsURL) this.openAddonOptions(addon, win); win.closeMenus(mi); break; case 1: if (e.ctrlKey) { if (!addon.isBuiltin) this.browseDir(addon); } else if (e.shiftKey) this.browseDir(addon, win); else if (addon.homepageURL) win.gBrowser.selectedTab = this.addTab(win, addon.homepageURL); win.closeMenus(mi); break; case 2: if (!e.ctrlKey) { let endis = addon.userDisabled ? "enable" : "disable"; if (addon.id == "screenshots@mozilla.org") Services.prefs.setBoolPref("extensions.screenshots.disabled", !addon.userDisabled); else if (addon.id == "webcompat-reporter@mozilla.org") Services.prefs.setBoolPref("extensions.webcompat-reporter.enabled", addon.userDisabled); addon[endis]({ allowSystemAddons: true }); } else if (!addon.isSystem && !addon.isBuiltin && Services.prompt.confirm(win, null, `Удалить ${addon.name}?`)) addon.uninstall(); break; } }, openAddonOptions: function(addon, win) { switch (addon.optionsType) { case 5: win.BrowserOpenAddonsMgr(`addons://detail/${encodeURIComponent(addon.id)}/preferences`); break; case 3: win.switchToTabHavingURI(addon.optionsURL, true); break; } }, browseDir: function(addon, win) { try { if (!win) { let file = Services.io.getProtocolHandler("file") .QueryInterface(Ci.nsIFileProtocolHandler) .getFileFromURLSpec(addon.getResourceURI().QueryInterface(Ci.nsIJARURI).JARFile.spec); if (file.exists()) file.launch(); } else win.gBrowser.selectedTab = this.addTab(win, addon.getResourceURI().spec); } catch (e) {} }, addTab: function(win, url, params = {}) { params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); params.relatedToCurrent = true; return win.gBrowser.addTab(url, params); }, }; CustomizableUI.createWidget({ id: id, type: "custom", label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(doc) { var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView, props = { id: id, label: label, tooltiptext: tooltiptext, type: "menu", class: "toolbarbutton-1 chromeclass-toolbar-additional", }; for (let p in props) btn.setAttribute(p, props[p]); btn.addEventListener("click", (e) => { if (e.button == 0) { if (e.shiftKey) win.BrowserOpenAddonsMgr(); } else if (e.button == 1) win.BrowserOpenAddonsMgr(); }); var mp = doc.createXULElement("menupopup"); mp.id = `${id}-popup`; mp.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); }); mp.addEventListener("contextmenu", (e) => { e.preventDefault(); e.stopPropagation(); }); mp.addEventListener("popupshowing", (e) => { extensionOptionsMenu.populateMenu(e); }); btn.append(mp); var btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(` #${id}, #${id}-popup menuitem { list-style-image: url("${img}") !important; } #${id}-popup menuitem::after { display: -moz-box !important; content: "" !important; height: 16px !important; width: 16px !important; padding: 0 !important; border: 1px solid rgb(0, 116, 232) !important; border-radius: 0 !important; background-repeat: no-repeat !important; background-position: center !important; background-size: 16px !important; background-color: rgb(0, 116, 232) !important; background-image: url("${checked}") !important; opacity: 1 !important; } #${id}-popup menuitem.ucf-disabled::after { border-color: currentColor !important; background-color: transparent !important; background-image: none !important; opacity: .6 !important; } #${id}-popup menuitem.ucf-disabled > label, #${id}-popup menuitem.ucf-notoptions > label { opacity: .6 !important; } #${id}-popup menuitem.ucf-system > label { text-decoration: underline !important; text-decoration-style: dotted !important; } #${id}-popup menuitem > label { margin-inline-end: 0 !important; } #${id}-popup menuitem > .menu-accel-container { display: -moz-box !important; padding: 4px !important; margin: 0 !important; opacity: 1 !important; } #${id}-popup menuitem > .menu-accel-container .menu-iconic-accel { display: -moz-box !important; margin: 0 !important; height: 8px !important; width: 8px !important; border-radius: 4px !important; background-color: transparent !important; opacity: 1 !important; font-size: 0 !important; } #${id}-popup menuitem.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel { background-color: rgb(227, 27, 93) !important; } #${id}-popup menuitem.ucf-type-locale > .menu-accel-container .menu-iconic-accel { background-color: rgb(48, 172, 55) !important; } #${id}-popup menuitem.ucf-type-theme > .menu-accel-container .menu-iconic-accel { background-color: rgb(219, 106, 0) !important; } `); try { win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} return btn; }, }); })();} catch (e) {} Есть новее? |
sandro79 > 06-06-2022 12:20:13 |
xrun1 пишет
Я здесь добавил обновлённый вариант. |
xrun1 > 06-06-2022 12:27:10 |
sandro79 пишет
Ваш пост не увидел. Спасибо. |
_zt > 19-06-2022 07:23:40 |
Dumby |
Dumby > 19-06-2022 09:36:05 |
_zt Таким образом, трюк с переопределением Object.freeze() больше не работает. скрытый текст Выделить код Код:// try {(jsval => { var dbg, gref, genv = func => { var sandbox = new Cu.Sandbox(g, {freshCompartment: true}); Cc["@mozilla.org/jsdebugger;1"].createInstance(Ci.IJSDebugger).addClass(sandbox); (dbg = new sandbox.Debugger()).addDebuggee(g); gref = dbg.makeGlobalObjectReference(g); return (genv = func => func && gref.makeDebuggeeValue(func).environment)(func); } var g = Cu.getGlobalForObject(jsval), o = g.Object, {freeze} = o, disleg; var AC = "AppConstants", uac = `resource://gre/modules/${AC}.`; var lexp = () => lockPref("extensions.experiments.enabled", true); if (o.isFrozen(o)) { // Fx 102.0b7+ lexp(); disleg = true; var env, def = g.ChromeUtils.defineModuleGetter; g.ChromeUtils.defineModuleGetter = (...args) => { try { genv(); dbg.addDebuggee(globalThis); var e = dbg.getNewestFrame().older.environment; var obj = e.parent.type == "object" && e.parent.object; if (obj && obj.class.startsWith("N")) // JSM, NSVO obj.unsafeDereference().Object = { freeze: ac => (ac.MOZ_REQUIRE_SIGNING = false) || freeze(ac) }; else env = e; // ESM, Lexy "var"(?) } catch(ex) {Cu.reportError(ex);} (g.ChromeUtils.defineModuleGetter = def)(...args); } ChromeUtils.import(uac + "jsm"); // (?) env && env.setVariable(AC, gref.makeDebuggeeValue(freeze(o.assign( new o(), env.getVariable(AC).unsafeDereference(), {MOZ_REQUIRE_SIGNING: false} )))); } else o.freeze = obj => { if (!Components.stack.caller.filename.startsWith(uac)) return freeze(obj); obj.MOZ_REQUIRE_SIGNING = false; if ((disleg = "MOZ_ALLOW_ADDON_SIDELOAD" in obj)) lexp(); else obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true, lockPref("extensions.legacy.enabled", true); return (o.freeze = freeze)(obj); } lockPref("xpinstall.signatures.required", false); lockPref("extensions.langpacks.signatures.required", false); var useDbg = true, xpii = "resource://gre/modules/addons/XPIInstall.jsm"; if (Ci.nsINativeFileWatcherService) { // Fx < 100 jsval = Cu.import(xpii, {}); var shouldVerify = jsval.shouldVerifySignedState; if (shouldVerify.length == 1) useDbg = false, jsval.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon); } if (useDbg) { jsval = g.ChromeUtils.import(xpii); var env = genv(jsval.XPIInstall.installTemporaryAddon); var ref = name => {try {return env.find(name).getVariable(name).unsafeDereference();} catch {}} jsval.XPIDatabase = (ref("lazy") || {}).XPIDatabase || ref("XPIDatabase"); var proto = ref("Package").prototype; var verify = proto.verifySignedState; proto.verifySignedState = function(id) { return id ? {cert: null, signedState: undefined} : verify.apply(this, arguments); } dbg.removeAllDebuggees(); } if (disleg) jsval.XPIDatabase.isDisabledLegacy = () => false; })( "permitCPOWsInScope" in Cu ? Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}) : Cu );} catch(ex) {Cu.reportError(ex);} Однако напомню, что в 91ESR антиподписячий код не обязателен, можно обойтись только настройками. Есть вероятность того, что это будет верно и для 102ESR. А дурацкие надписи на about:addons можно убрать скриптом, или, в крайнем случае, стилем. |
_zt > 20-06-2022 06:25:13 |
Dumby |
_zt > 25-06-2022 12:15:36 |
Dumby |
Dumby > 25-06-2022 14:24:39 |
_zt пишет
Не совсем так. Это, скорее, proof of concept, что стиль будет перечитан с диска. Можно после строки, где функция reg определяется, добавить строку с её вызовом: reg(); |
_zt > 25-06-2022 18:41:41 |
Dumby |
Dumby > 28-06-2022 10:33:07 |
egorsemenov06 пишет
В base64 всё примет.
Да, вижу. Увы, ничего лучше не придумал скрытый текст Выделить код Код:/* var evt = new node.ownerGlobal.KeyboardEvent( "keypress", {bubbles: true, cancelable: true, ...e} ); node.dispatchEvent(evt); }, */ if(ChromeUtils.domProcessChild.childID) { var cmd = this.beh2cmd[e.ctrlKey + "_" + e.shiftKey + "_" + e.keyCode]; cmd && docShell.doCommand(cmd); } else node.dispatchEvent(new node.ownerGlobal.KeyboardEvent( "keypress", {bubbles: true, cancelable: true, ...e} )); }, beh2cmd: { // Ctrl_Shift_VK false_true_36: "cmd_selectLinePrevious", // Shift+Home }, |
Dumby > 28-06-2022 11:45:07 |
egorsemenov06 пишет
Ух ты! Хотел написать
Но получил: «500 Internal Server Error». |
Inko7 > 28-06-2022 13:51:53 |
Dumby |
antialt > 28-06-2022 22:58:37 |
Dumby пишет
Подскажите, как вернуть к жизни add_toolbar_buttons.2021.9.5.xpi на 102 (Final или ESR), очень уж удобный плагин ! |
kokoss > 28-06-2022 23:57:33 |
antialt пишет
Вы же процитировали решение, просто обновите код для отключения... на тот что под спойлером! |
antialt > 29-06-2022 00:10:54 |
Извиняюсь, вставлял код на профиль после запуска со старой "антиподпиской", не сработал. Сейчас вытащил из бэкапа профиль от 101 версии, накатил обнову и новый код. Всё отлично, спасибо ! |
_zt > 03-07-2022 09:14:02 |
Dumby |
Inko7 > 03-07-2022 16:54:37 |
Dumby скрытый текст Выделить код Код:// MiddleMouse.Paste с заменой выделенного текста (порт с СВ) try {((id, code, gmon) => { var d = "data:,", ref = "globalThis." + id, dref = d + ref; var psi = `${dref} = ${encodeURIComponent(code)};`; var psd = `${d}delete ${ref};`; var e10s = Services.appinfo.browserTabsRemoteAutostart; if (e10s) var fsi = `${dref}.listen(this, "add");`, fsd = `${dref}.listen(this);`; var g = Cu.getGlobalForObject(Cu), pref = "middlemouse.paste"; var obs = { pref: Services.prefs.getBoolPref.bind(null, pref), startup() { Services.prefs.addObserver(pref, this); Services.obs.addObserver(this, "quit-application-granted", false); this.pref() && this.init(); this.gmon(); }, async gmon() { Cu.importGlobalProperties(["fetch"]); var url = "chrome://custombuttons/content/editExternal.js"; try {var src = await (await fetch(url)).text();} catch(ex) {return;} src = src.replace(/function gmon_edit_mouseclick[^}]+?}/, gmon); var arr = [["override", url, "data:," + encodeURIComponent(src)]]; url = Services.io.getProtocolHandler("resource").getSubstitution("gre"); this.gmonHelper = Cc["@mozilla.org/addons/addon-manager-startup;1"] .getService(Ci.amIAddonManagerStartup).registerChrome(url, arr); }, shutdown() { this.pref() && this.destroy(); e10s && Services.ppmm.removeDelayedProcessScript(psi), Services.ppmm.loadProcessScript(psd, false); Services.prefs.removeObserver(pref, this); Services.obs.removeObserver(this, "quit-application-granted"); this.gmonHelper && this.gmonHelper.destruct(); }, init() { e10s && Services.mm.loadFrameScript(fsi, true); Services.obs.addObserver(this, "widget-first-paint", false); this.wins("add"); }, destroy() { if (e10s) Services.mm.removeDelayedFrameScript(fsi), Services.mm.loadFrameScript(fsd, false); Services.obs.removeObserver(this, "widget-first-paint"); this.wins(); }, observe(subj, topic) { var char = topic[0]; if (char == "w") return this.call(subj, "add"); if (char == "q") return this.shutdown(); this[this.pref() ? "init" : "destroy"](); }, wins(arg) { for(var win of Services.wm.getEnumerator(null)) this.call(win, arg); }, listen() {} }; Services.ppmm.loadProcessScript(psi, e10s); g[id].call = g[id].listen; Object.assign(g[id], obs).startup(); })("ucf_custom_script_js_MiddleMousePaste", `{ listen(trg, prfx = "remove") { var meth = prfx + "EventListener"; trg[meth]("auxclick", this, true); trg[meth]("unload", this); }, handleEvent(e) {this[e.type](e);}, unload(e) {this.listen(e.target);}, sn: Ci.nsISelectionController.SELECTION_NORMAL, inRect: (r, x, y) => y > r.top && y < r.bottom && x < r.right && x > r.left, auxclick(e) { if (e.button != 1) return; var trg = (e.originalTarget || e.target).closest( "input:not([disabled]),textarea:not([disabled])" ); if (!trg) return; var ed = trg.editor; if (!ed || ed.selection.isCollapsed || !ed.canPaste(this.sn)) return; var x = e.clientX, y = e.clientY, rng = ed.selection.getRangeAt(0); if (!this.inRect(rng.getBoundingClientRect(), x, y)) return; var list = rng.getClientRects(); if (list.length == 1 || Array.from(list).some( rect => this.inRect(rect, x, y) )) ed.paste(this.sn, e.preventDefault()); } }`, `\ function gmon_edit_mouseclick(e) { var mmp = Cc["@mozilla.org/preferences-service;1"] .getService(Ci.nsIPrefBranch).getBoolPref.bind(null, "middlemouse.paste"); (gmon_edit_mouseclick = e => e.button != 1 || mmp() || edittarget(e.target))(e); }`); } catch(ex) {Cu.reportError(ex);} ((bu, bm, {star} = bu) => addEventListener("mouseenter", { async handleEvent() { if (!this.starred) return; star.tooltipText = "\u3164"; var result = []; await this.fetch(); for(var guid of this.guids) { var arr = []; while(true) { if (!this.hover) return; var res = await bm.fetch(guid); if ((guid = res.parentGuid) == bm.rootGuid) { arr.unshift(bm.getLocalizedTitle(res)); break; } arr.unshift(res.title || "[Безымянная папка]"); } result.push(arr.join("\\")); } this.hover && this.setTooltip(result); }, get fetch() { addDestructor(() => this.starred && document.l10n.translateElements([star])); var set = this.guids = new Set(); var args = [b => set.add(b.parentGuid), {concurrent: true}]; delete this.fetch; return this.fetch = () => set.clear() || bm.fetch({url: gBrowser.currentURI.spec}, ...args); }, setTooltip(arr) { var m = arr.length > 1; var text = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${arr.join("\n")}`; document.tooltipNode == star ? this.tt.label = text : star.tooltipText = text; }, get tt() { var list = InspectorUtils.getChildrenForNode(document.documentElement, true); delete this.tt; return this.tt = list.item(list.length - 1); }, get starred() {return bu._itemGuids.size;}, get hover() {return star.matches(":hover");} }, false, star || 1))(BookmarkingUI, PlacesUtils.bookmarks); когда-то вы его уже приводили в чувство, теперь снова сломался... |
kokoss > 03-07-2022 19:05:43 |
Dumby |
Dumby > 03-07-2022 19:49:53 |
_zt пишет
Это не расширение, а WebExtensions. скрытый текст
И где же мне взять это «иногда»? Не́где.
Смотреть там особо неначто. запрашивает пользовательскую аддонскую настройку, тогда идёт перебор всех элементов <a>, которые присутствуют в DOM-дереве документа Вот и всё. Атрибут либо уставливается, либо нет. А так-то, допустим, если уже установлена какая-либо обезьяна, Inko7 пишет
Это ты мне что-то совсем левое древнее впариваешь. Последний вариант вроде как здесь. Но, железная поступь проекта «JSM-геноцид»,
Да видел я пост про «Б». Ин-валидно. С «Ж», да, есть проблемы. Но код-то не мой, я просто перегонял исходник из пустого в порожнее. скрытый текст Выделить код Код:/* if(c in this.convTableForward) return true; if(c in this.convTableBackward) return false; */ var primary = c in this.convTableForward; if(primary ^ c in this.convTableBackward) return primary; kokoss пишет
Увы, делам контентским, вебским, я весьма посторонен. |
Inko7 > 03-07-2022 21:06:23 |
Dumby пишет
Как-то пропустил его, но он все равно не работает в строке адреса и в строке поиска на стартовой странице FF. Может оно и не особо критично... Dumby пишет
изменений пока не заметил |
Dumby > 03-07-2022 21:18:03 |
Inko7 |
Inko7 > 03-07-2022 21:28:11 |
Dumby пишет
Точно! Думаю, где же он спрятался))) скрытый текст этот наверное новее Выделить код Код:// Показать адрес существующей закладки при наведении на звездочку try {((bu, bm, {star} = bu) => { var listener = { async handleEvent() { if (!bu._itemGuids.size) return; star.tooltipText = "\u3164"; var result = []; await this.fetch(); for(var guid of this.guids) { var arr = []; while(true) { if (!this.hover) return; var res = await bm.fetch(guid); if ((guid = res.parentGuid) == bm.rootGuid) { arr.unshift(bm.getLocalizedTitle(res)); break; } arr.unshift(res.title || "[Безымянная папка]"); } result.push(arr.join("\\")); } this.hover && this.setTooltip(result); }, get fetch() { var set = this.guids = new Set(); var args = [b => set.add(b.parentGuid), {concurrent: true}]; delete this.fetch; return this.fetch = () => set.clear() || bm.fetch({url: gBrowser.currentURI.spec}, ...args); }, setTooltip(arr) { var m = arr.length > 1; var text = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${arr.join("\n")}`; document.tooltipNode == star ? this.tt.label = text : star.tooltipText = text; }, get tt() { var list = InspectorUtils.getChildrenForNode(document.documentElement, true); delete this.tt; return this.tt = list.item(list.length - 1); }, get hover() {return star.matches(":hover");} }; star.addEventListener("mouseenter", listener); addEventListener("unload", () => star.removeEventListener("mouseenter", listener) , {once: true}); })(BookmarkingUI, PlacesUtils.bookmarks);} catch(ex) {Cu.reportError(ex);} скрытый текст Выделить код Код:// Показать адрес существующей закладки при наведении на звездочку ((bu, bm, {star} = bu) => addEventListener("mouseenter", { async handleEvent() { if (!this.starred) return; star.tooltipText = "\u3164"; var result = []; await this.fetch(); for(var guid of this.guids) { var arr = []; while(true) { if (!this.hover) return; var res = await bm.fetch(guid); if ((guid = res.parentGuid) == bm.rootGuid) { arr.unshift(bm.getLocalizedTitle(res)); break; } arr.unshift(res.title || "[Безымянная папка]"); } result.push(arr.join("\\")); } this.hover && this.setTooltip(result); }, get fetch() { addDestructor(() => this.starred && document.l10n.translateElements([star])); var set = this.guids = new Set(); var args = [b => set.add(b.parentGuid), {concurrent: true}]; delete this.fetch; return this.fetch = () => set.clear() || bm.fetch({url: gBrowser.currentURI.spec}, ...args); }, setTooltip(arr) { var m = arr.length > 1; var text = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${arr.join("\n")}`; document.tooltipNode == star ? this.tt.label = text : star.tooltipText = text; }, get tt() { var list = InspectorUtils.getChildrenForNode(document.documentElement, true); delete this.tt; return this.tt = list.item(list.length - 1); }, get starred() {return bu._itemGuids.size;}, get hover() {return star.matches(":hover");} }, false, star || 1))(BookmarkingUI, PlacesUtils.bookmarks); 03-07-2022 21:46:08 Dumby пишет
тут спору нет |
Dumby > 03-07-2022 22:38:43 |
Inko7 пишет
скрытый текст Выделить код Код:/* if (!bu._itemGuids.size) return; */ if (!bu._itemGuids.size) return star.removeAttribute("tooltiptext");
Об обоих двух. |
voqabuhe > 04-07-2022 00:02:31 |
Dumby пишет
У меня везде всё вставляет, без проблем. |
Dumby > 04-07-2022 00:16:34 |
voqabuhe пишет
Премного благодарен, спасибо за взгляд со стороны. |
Inko7 > 04-07-2022 09:46:53 |
Dumby
а у меня скрипты загружались уже через сам файл custom_script.js в нем прописан вот такой код: Выделить код Код:(() => { var loadscript = name => { try { Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${name}`, globalThis, "UTF-8"); } catch(e) {} }; loadscript("./js/kbd_layout.js"); loadscript("./js/MiddleMouse_Paste.js"); })(); но так же они тоже подгружались, просто как-то не совсем корректно? |
Dumby > 04-07-2022 11:01:46 |
Inko7 пишет
Это что ещё за дот-слэш в начале?
kbd_layout.js — это просто скрипт. А Middle Mouse Paste — это модуль (jsm'ка, пока ещё). |
Inko7 > 04-07-2022 11:43:27 |
Dumby |
_zt > 05-07-2022 14:17:27 |
Dumby
Да, есть маленько.
Уже не хочу, так как найденный скрипт работает лучше, например на github внешние ссылки корректно открывает в новой вкладке, ну и т.п. |
Dobrov > 06-07-2022 04:33:54 |
Dumby пишет
Раз jsm-ки скоро отвалится, то весь UCF и CustomStylesScripts.jsm и CustomStylesScriptsChild.jsm тоже перестанут работать? если поддержку jsm уберут, просьба переделать в JS модуль сохранения картинок ClickPicSave.jsm Выделить код Код:var EXPORTED_SYMBOLS = ["MouseImgSaverChild", "MouseImgSaverParent"]; // by Dumby сохранить картинку колёсиком или перетащив вправо; DBL поиск похожих var u = {get it() { // https://forum.mozilla-russia.org/viewtopic.php?pid=793837#p793837 delete this.it; return this.it = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools); }}; for(let name of ["E10SUtils", "PrivateBrowsingUtils"]) ChromeUtils.defineModuleGetter(u, name, `resource://gre/modules/${name}.jsm`); class MouseImgSaverChild extends JSWindowActorChild { handleEvent(e) { // клики мышью if (e.button > 1) return; // только ЛКМ, СКМ var trg = e.explicitOriginalTarget; // dragstart trg.nodeType == Node.ELEMENT_NODE && trg instanceof Ci.nsIImageLoadingContent && this[e.type](trg, e); } handleDragEvent(e) { this[e.type](e); } dragstart(trg, e) { this.trg = trg; this.x = e.screenX; this.y = e.screenY; this.drag("add"); this.handleEvent = this.handleDragEvent; this.checkTextLinkyTool(trg.ownerDocument); } events = ["dragover", "drop", "dragend"]; drag(meth = (delete this.handleEvent, delete this.trg, "remove")) { meth += "EventListener"; var win = this.contentWindow; for(var type of this.events) win[meth](type, this, true); } drop() { this.drag(); } dragover(e) { var {x, y} = this, cx = e.screenX, cy = e.screenY, dx = cx - x, ax = Math.abs(dx), ay = Math.abs(cy - y); if (ax < 10 && ay < 10) return; if (dx < 0 || ax < ay) return this.drag(); this.x = cx; this.y = cy; } dragend(e) { // перетаскивание рисунка var dt = e.dataTransfer, {trg} = this; this.drag(); dt.mozUserCancelled || this.send(trg, e.screenX); // сохранить // dt.mozUserCancelled || this.sendAsyncMessage("dragend", (trg.currentRequestFinalURI || uri).spec); } auxclick(trg) { // клик СКМ trg.matches(":any-link :scope") || this.send(trg); } dblclick(trg) { // ЛКМ trg.matches(":any-link :scope") || this.sendAsyncMessage("dblclick", (trg.currentRequestFinalURI || uri).spec); } send(trg, sx) { var uri = trg.currentURI; if (!uri) return; var doc = trg.ownerDocument; var cookieJarSettings = u.E10SUtils .serializeCookieJarSettings(doc.cookieJarSettings); var referrerInfo = Cc["@mozilla.org/referrer-info;1"] .createInstance(Ci.nsIReferrerInfo); referrerInfo.initWithElement(trg); referrerInfo = u.E10SUtils.serializeReferrerInfo(referrerInfo); var contentType = null, contentDisposition = null; try { var props = u.it.getImgCacheForDocument(doc).findEntryProperties(uri, doc); var cs = Ci.nsISupportsCString; try {contentType = props.get("type", cs).data;} catch {} try {contentDisposition = props.get("content-disposition", cs).data;} catch {} } catch {} this.sendAsyncMessage("", { title: trg.closest("[title]")?.title, url: (trg.currentRequestFinalURI || uri).spec, contentType, referrerInfo, cookieJarSettings, contentDisposition, sx, isPrivate: u.PrivateBrowsingUtils.isContentWindowPrivate(trg.ownerGlobal) }); } checkTextLinkyTool(doc) { if (doc.title || !doc.documentURI.startsWith("moz-extension:")) return; var lab = doc.querySelector("body > label#lblFrom:first-child")?.textContent; if (lab) doc.title = lab.slice(0, lab.lastIndexOf("(")); } } if (!ChromeUtils.domProcessChild.childID) { ChromeUtils.registerWindowActor("MouseImgSaver", { allFrames: true, parent: {moduleURI: __URI__}, messageManagerGroups: ["browsers"], child: {moduleURI: __URI__, events: {auxclick: {capture: true}, dblclick: {capture: true}, dragstart: {capture: true}}} }); var wref, titles = Object.create(null); var data = Object.assign(Object.create(null), { "browser.download.dir": {type: "String", get set() { var win = wref.get(), {prefs, dirsvc} = win.Services var {DownloadPaths, FileUtils} = win; var map = val => DownloadPaths.sanitize(val); win.Downloads.getList(win.Downloads.ALL).then(list => list.addView({ onDownloadChanged(download) { if (!download.stopped) return; var {url} = download.source, title = titles[url]; if (!title) return; delete titles[url]; if (!download.succeeded) return; var file = FileUtils.File(download.target.path), {leafName} = file; var ext = leafName.slice(leafName.lastIndexOf(".")); var newName = map(title) + ext, {parent} = file; var newFile = parent.clone(); newFile.append(newName); try { newFile.createUnique(file.NORMAL_FILE_TYPE, file.permissions); file.renameTo(parent, newFile.leafName); download.target.path = newFile.path; download.refresh(); } catch {} } })); Object.defineProperty(this, "set", {get() { try {var dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {var dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("ucf.savedirs", "_Web||_Images|0").split('|').slice(2, 4); // подпапки в [Загрузках]: нет | папка графики | имя вкладки | домен arr[1] = (arr[1]) ? wref.get().gBrowser.selectedTab.label.slice(0, 64).replace(/ \| — Mozilla Firefox|[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim() : ""; // имя вкладки arr.map(map).forEach(dir.append); dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); return dir.path; }}); return this.set; }}, "browser.download.folderList": {type: "Int", set: 2}, "browser.download.useDownloadDir": {type: "Bool", set: true} }); var MouseImgSaverParent = class extends JSWindowActorParent { receiveMessage(msg) { var win = msg.target.browsingContext.topChromeWindow, {name} = msg; if (name) return this[name](win, msg.data); var {url, contentType, contentDisposition, sx, title, isPrivate, referrerInfo, cookieJarSettings} = msg.data; if (sx && sx > win.mozInnerScreenX + win.innerWidth) return; if (title) titles[url] = title; wref = Cu.getWeakReference(win); var p = win.Services.prefs; for(var pref in data) { var obj = data[pref], meth = `et${obj.type}Pref`; obj.val = p.prefHasUserValue(pref) ? p["g" + meth](pref) : null; p["s" + meth](pref, obj.set); } try {win.internalSave( url, null, // document null, // file name contentDisposition, contentType, false, // do not bypass the cache null, // filepicker title key null, // chosen data u.E10SUtils.deserializeReferrerInfo(referrerInfo), u.E10SUtils.deserializeCookieJarSettings(cookieJarSettings), win.document, // initiating doc true, // skip prompt for where to save null, // cache key isPrivate, win.document.nodePrincipal );} finally { for(var pref in data) data[pref].val === null ? p.clearUserPref(pref) : p[`set${data[pref].type}Pref`](pref, data[pref].val); } } dblclick(win, imgURL) { var gb = win.gBrowser, index = gb.selectedTab._tPos + 1; gb.selectedTab = gb.addTrustedTab('https://yandex.ru/images/search?rpt=imageview&url=' + imgURL, {index}); } } } |
Vitaliy V. > 06-07-2022 14:38:26 |
Dobrov пишет
ESM модули вместо них, несложная конвертация модулей jsm --> mjs, у меня уже работает на FF 103 |
Dumby > 06-07-2022 19:22:45 |
_zt пишет
Что-то мне в голову не влезает то, что там навёрнуто, Могу попробовать просто процитировать, без осознания, скрытый текст Выделить код Код:var cfg = { rootzone: false, parent: true, neighbor: true, host: true, child: true, background: false, insert: true, setParent: true }; var name = "ExternalLinkNewtaber"; if (ChromeUtils.domProcessChild.childID) { var empty = new RegExp("^$"); var click = function(e) { e.preventDefault(); e.stopImmediatePropagation(); this.ownerGlobal.windowGlobalChild .getActor(name).sendAsyncMessage("", this.href); } var EXPORTED_SYMBOLS = [name + "Child"]; var ExternalLinkNewtaberChild = class extends JSWindowActorChild { actorCreated() { this.pp = this.ph = empty; var host = this.contentWindow.location.hostname; // quot =========================================================================== let parent = host.replace(/^[^.]*\./, '').replace(/\./g, '\\\.'); host = host.replace(/\./g, '\\\.'); if (cfg.parent){this.pp = new RegExp(`^${parent}$`);} // abc.x => ^abc\.x$ if (cfg.neighbor){ const flat = host.replace(/\..*/, ''); if (cfg.parent){ this.pp = new RegExp(`[^(${flat}\.)]?${parent}$`); // abc.x + *.abc.x => [^(w\.)]?abc\.x$ } else {this.pp = new RegExp(`[^(${flat})]?\.${parent}$`);} // *.abc.x => [^(w)]?\.abc\.x$ } if (!cfg.rootzone && parent.search(/\..+\./) == -1){this.pp = empty;} if (cfg.host){this.ph = new RegExp(`^${host}$`);} // w.abc.x => ^w\.abc\.x$ if (cfg.child){ if (cfg.host){ this.ph = new RegExp(`(.+\.)?${host}$`); // w.abc.x + *.w.abc.x => (.+\.)?w\.abc\.x$ } else {this.ph = new RegExp(`.+\.${host}$`);} // *.w.abc.x => .+\.w\.abc\.x$ } // =========================================================================== quot } handleEvent(e) { for(var a of this.document.getElementsByTagName("a")) if (a.hasAttribute("href")) { var {host} = a; !host || empty.test(host) || this.pp.test(host) || this.ph.test(host) || a.addEventListener("click", click); } } } } else { var {background, insert, setParent} = cfg; var arg = insert || setParent, fg = !background; var EXPORTED_SYMBOLS = [name + "Parent"]; var ExternalLinkNewtaberParent = class extends JSWindowActorParent { receiveMessage(msg) { var opts, gb = this.browsingContext.topChromeWindow.gBrowser; if (arg) { opts = {}; var st = gb.selectedTab; if (insert) opts.index = st._tPos + 1; if (setParent) opts.ownerTab = st; } var tab = gb.addTrustedTab(msg.data, opts); if (fg) gb.selectedTab = tab; } } ChromeUtils.registerWindowActor(name, { allFrames: true, matches: ["*://*/*"], messageManagerGroups: ["browsers"], parent: {moduleURI: __URI__}, child: {moduleURI: __URI__, events: {load: {capture: true}}} }); } Dobrov пишет
Сейчас пока не очень удобно, поскольку лисьи jsm'ки ещё не сконвертированы. А вообще это не очень сложно (и, нужен Firefox 103+). ClickPicSave.mjs Выделить код Код:export {MouseImgSaverChild, MouseImgSaverParent}; var u = {get it() { delete this.it; return this.it = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools); }}; ["E10SUtils", "PrivateBrowsingUtils"].forEach(name => Object.defineProperty(u, name, { configurable: true, enumerable: true, get() { var url = `resource://gre/modules/${name}.`; try {var exp = ChromeUtils.importESModule(url + "sys.mjs");} catch {exp = ChromeUtils.import(url + "jsm");} delete this[name]; return this[name] = exp[name]; } })); class MouseImgSaverChild extends JSWindowActorChild { handleEvent(e) { // клики мышью if (e.button > 1) return; // только ЛКМ, СКМ var trg = e.explicitOriginalTarget; // dragstart trg.nodeType == Node.ELEMENT_NODE && trg instanceof Ci.nsIImageLoadingContent && this[e.type](trg, e); } handleDragEvent(e) { this[e.type](e); } dragstart(trg, e) { this.trg = trg; this.x = e.screenX; this.y = e.screenY; this.drag("add"); this.handleEvent = this.handleDragEvent; this.checkTextLinkyTool(trg.ownerDocument); } events = ["dragover", "drop", "dragend"]; drag(meth = (delete this.handleEvent, delete this.trg, "remove")) { meth += "EventListener"; var win = this.contentWindow; for(var type of this.events) win[meth](type, this, true); } drop() { this.drag(); } dragover(e) { var {x, y} = this, cx = e.screenX, cy = e.screenY, dx = cx - x, ax = Math.abs(dx), ay = Math.abs(cy - y); if (ax < 10 && ay < 10) return; if (dx < 0 || ax < ay) return this.drag(); this.x = cx; this.y = cy; } dragend(e) { // перетаскивание рисунка var dt = e.dataTransfer, {trg} = this; this.drag(); dt.mozUserCancelled || this.send(trg, e.screenX); // сохранить // dt.mozUserCancelled || this.sendAsyncMessage("dragend", (trg.currentRequestFinalURI || uri).spec); } auxclick(trg) { // клик СКМ trg.matches(":any-link :scope") || this.send(trg); } dblclick(trg) { // ЛКМ trg.matches(":any-link :scope") || this.sendAsyncMessage("dblclick", (trg.currentRequestFinalURI || uri).spec); } send(trg, sx) { var uri = trg.currentURI; if (!uri) return; var doc = trg.ownerDocument; var cookieJarSettings = u.E10SUtils .serializeCookieJarSettings(doc.cookieJarSettings); var referrerInfo = Cc["@mozilla.org/referrer-info;1"] .createInstance(Ci.nsIReferrerInfo); referrerInfo.initWithElement(trg); referrerInfo = u.E10SUtils.serializeReferrerInfo(referrerInfo); var contentType = null, contentDisposition = null; try { var props = u.it.getImgCacheForDocument(doc).findEntryProperties(uri, doc); var cs = Ci.nsISupportsCString; try {contentType = props.get("type", cs).data;} catch {} try {contentDisposition = props.get("content-disposition", cs).data;} catch {} } catch {} this.sendAsyncMessage("", { title: trg.closest("[title]")?.title, url: (trg.currentRequestFinalURI || uri).spec, contentType, referrerInfo, cookieJarSettings, contentDisposition, sx, isPrivate: u.PrivateBrowsingUtils.isContentWindowPrivate(trg.ownerGlobal) }); } checkTextLinkyTool(doc) { if (doc.title || !doc.documentURI.startsWith("moz-extension:")) return; var lab = doc.querySelector("body > label#lblFrom:first-child")?.textContent; if (lab) doc.title = lab.slice(0, lab.lastIndexOf("(")); } } if (!ChromeUtils.domProcessChild.childID) { var esModuleURI = Components.stack.filename; ChromeUtils.registerWindowActor("MouseImgSaver", { allFrames: true, parent: {esModuleURI}, messageManagerGroups: ["browsers"], child: {esModuleURI, events: {auxclick: {capture: true}, dblclick: {capture: true}, dragstart: {capture: true}}} }); var wref, titles = Object.create(null); var data = Object.assign(Object.create(null), { "browser.download.dir": {type: "String", get set() { var win = wref.get(), {prefs, dirsvc} = win.Services var {DownloadPaths, FileUtils} = win; var map = val => DownloadPaths.sanitize(val); win.Downloads.getList(win.Downloads.ALL).then(list => list.addView({ onDownloadChanged(download) { if (!download.stopped) return; var {url} = download.source, title = titles[url]; if (!title) return; delete titles[url]; if (!download.succeeded) return; var file = FileUtils.File(download.target.path), {leafName} = file; var ext = leafName.slice(leafName.lastIndexOf(".")); var newName = map(title) + ext, {parent} = file; var newFile = parent.clone(); newFile.append(newName); try { newFile.createUnique(file.NORMAL_FILE_TYPE, file.permissions); file.renameTo(parent, newFile.leafName); download.target.path = newFile.path; download.refresh(); } catch {} } })); Object.defineProperty(this, "set", {get() { try {var dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {var dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("ucf.savedirs", "_Web||_Images|0").split('|').slice(2, 4); // подпапки в [Загрузках]: нет | папка графики | имя вкладки | домен arr[1] = (arr[1]) ? wref.get().gBrowser.selectedTab.label.slice(0, 64).replace(/ \| — Mozilla Firefox|[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim() : ""; // имя вкладки arr.map(map).forEach(dir.append); dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); return dir.path; }}); return this.set; }}, "browser.download.folderList": {type: "Int", set: 2}, "browser.download.useDownloadDir": {type: "Bool", set: true} }); var MouseImgSaverParent = class extends JSWindowActorParent { receiveMessage(msg) { var win = msg.target.browsingContext.topChromeWindow, {name} = msg; if (name) return this[name](win, msg.data); var {url, contentType, contentDisposition, sx, title, isPrivate, referrerInfo, cookieJarSettings} = msg.data; if (sx && sx > win.mozInnerScreenX + win.innerWidth) return; if (title) titles[url] = title; wref = Cu.getWeakReference(win); var p = win.Services.prefs; for(var pref in data) { var obj = data[pref], meth = `et${obj.type}Pref`; obj.val = p.prefHasUserValue(pref) ? p["g" + meth](pref) : null; p["s" + meth](pref, obj.set); } try {win.internalSave( url, null, // original url null, // document null, // file name contentDisposition, contentType, false, // do not bypass the cache null, // filepicker title key null, // chosen data u.E10SUtils.deserializeReferrerInfo(referrerInfo), u.E10SUtils.deserializeCookieJarSettings(cookieJarSettings), win.document, // initiating doc true, // skip prompt for where to save null, // cache key isPrivate, win.document.nodePrincipal );} finally { for(var pref in data) data[pref].val === null ? p.clearUserPref(pref) : p[`set${data[pref].type}Pref`](pref, data[pref].val); } } dblclick(win, imgURL) { var gb = win.gBrowser, index = gb.selectedTab._tPos + 1; gb.selectedTab = gb.addTrustedTab('https://yandex.ru/images/search?rpt=imageview&url=' + imgURL, {index}); } } } |
_zt > 06-07-2022 22:36:01 |
Dumby |
Dumby > 07-07-2022 00:05:19 |
_zt пишет
Да обычная jsm'ка, как и другие. То есть ChromeUtils.import("урл"); |
_zt > 07-07-2022 01:02:46 |
Dumby |
ez7pac > 12-07-2022 23:42:49 |
Привет мастерам! |
xrun1 > 13-07-2022 01:06:23 |
ez7pac Это иконка из , можно взять то, что между двойными кавычками, вставить в адресную строку и посмотреть. Заменяете на свой код. Механизм такой же - заменяете на свой код то, что между двойными кавычками. |
ez7pac > 13-07-2022 02:06:19 |
xrun1 Т.е. иконка не дефолтная, а своя. С конвертацией и заменой разберусь, думаю. Но тогда другой вопрос возник - а нельзя вместо кода иконки, вот этого "непонятного", воткнуть в код кнопки дефолтную иконку? Я там (chrome://browser/skin/browser.css) глянул - подходящие для меня есть. |
xrun1 > 13-07-2022 03:55:35 |
ez7pac |
kokoss > 13-07-2022 14:04:05 |
ez7pac скрытый текст варианты: Выделить код Код:#ID кнопки> .toolbarbutton-icon { list-style-image: url("chrome://browser/skin/history.svg"); }
|
ez7pac > 13-07-2022 17:51:53 |
xrun1 скрытый текст Выделить код Код:try {(() => { var id = "ucf-aom-button", label = "Дополнения", tooltiptext = "ЛКМ: Меню дополнений\nShift+ЛКМ: Меню дополнений + открыть менеджер\nСКМ: Открыть менеджер дополнений", img = "chrome://mozapps/skin/extensions/extension.svg", show_version = true, show_description = true, user_permissions = true, show_hidden = true, show_disabled = true, enabled_first = true, exceptions_listset = new Set([ ]); exceptions_type_listset = new Set([ ]); if (!("AddonManager" in this)) ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm"); if (!("GlobalManager" in this)) XPCOMUtils.defineLazyGetter(this, "GlobalManager", () => ChromeUtils.import("resource://gre/modules/ExtensionParent.jsm").ExtensionParent.GlobalManager); var extensionOptionsMenu = { get alertsService() { delete this.alertsService; return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); }, get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, get exceptions_type_listarr() { delete this.exceptions_type_listarr; var arr = ["extension", "theme", "locale", "dictionary"]; if (!exceptions_type_listset.size) return this.exceptions_type_listarr = arr; return this.exceptions_type_listarr = arr.filter(type => !exceptions_type_listset.has(type)); }, populateMenu: async function(e) { var popup = e.target, doc = e.view.document; var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr); var addonsMap = new WeakMap(), setAttributesMenu = (mi, addon, extension) => { var permissions, uuid, props = { label: `${addon.name}${show_version ? ` ${addon.version}` : ""}`, class: "menuitem-iconic", tooltiptext: `${(show_description && addon.description) ? `${addon.description}\n` : ""}ID: ${addon.id}${addon.isActive && (uuid = extension?.uuid) ? `\nUUID: ${uuid}` : ""}${(user_permissions && (permissions = addon.userPermissions?.permissions)?.length) ? `\nРазрешения: ${permissions.join(", ")}` : ""}\n${addon.optionsURL ? "\nЛКМ: Настройки" : ""}\nCtrl+ЛКМ: Копировать ID${uuid ? "\nShift+ЛКМ: Копировать UUID" : ""}${addon.creator?.url ? "\nCtrl+Shift+ЛКМ: Автор" : ""}${addon.homepageURL ? "\nСКМ: Домашняя страница" : ""}${!addon.isBuiltin ? "\nCtrl+СКМ: Просмотр источника" : ""}\nShift+СКМ: Просмотр источника во вкладке\nПКМ: Включить/Отключить${(!addon.isSystem && !addon.isBuiltin) ? "\nCtrl+ПКМ: Удалить" : ""}`, }; for (let p in props) mi.setAttribute(p, props[p]); if (addon.iconURL) mi.setAttribute("image", addon.iconURL); var cls = mi.classList; addon.isActive ? cls.remove("ucf-disabled") : cls.add("ucf-disabled"); addon.optionsURL ? cls.remove("ucf-notoptions") : cls.add("ucf-notoptions"); addon.isSystem ? cls.add("ucf-system") : cls.remove("ucf-system"); cls.add(`ucf-type-${addon.type}`); }; addons.filter(a => !(a.iconURL || "").startsWith("resource://search-extensions/")).sort((a, b) => { var ka = `${(enabled_first ? a.isActive ? "0" : "1" : "")}${a.type || ""}${a.name.toLowerCase()}`; var kb = `${(enabled_first ? b.isActive ? "0" : "1" : "")}${b.type || ""}${b.name.toLowerCase()}`; return (ka < kb) ? -1 : 1; }).forEach(addon => { if (!exceptions_listset.has(addon.id) && (!addon.hidden || show_hidden) && (!addon.userDisabled || show_disabled)) { let extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.append(mi); addonsMap.set(addon, mi); } }); var click = (e) => { this.handleClick(e); }; popup.addEventListener("click", click); var listener = { onEnabled: addon => { var mi = addonsMap.get(addon); if (mi) setAttributesMenu(mi, addon, mi._Extension); }, onDisabled: addon => { listener.onEnabled(addon); }, onInstalled: addon => { var extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.prepend(mi); addonsMap.set(addon, mi); }, onUninstalled: addon => { var mi = addonsMap.get(addon); if (mi) { mi.remove(); addonsMap.delete(addon); } }, }; AddonManager.addAddonListener(listener); popup.addEventListener("popuphiding", (e) => { AddonManager.removeAddonListener(listener); popup.removeEventListener("click", click); addonsMap = null; while (popup.hasChildNodes()) popup.firstChild.remove(); }, { once: true }); }, handleClick: function(e) { var win = e.view, mi = e.target; if (!("_Addon" in mi) || !("_Extension" in mi)) return; var addon = mi._Addon, extension = mi._Extension; switch (e.button) { case 0: if (e.ctrlKey && e.shiftKey) { if (addon.creator?.url) win.gBrowser.selectedTab = this.addTab(win, addon.creator.url); } else if (e.ctrlKey) { this.clipboardHelp.copyString(addon.id); try { this.alertsService.showAlertNotification(`${img}`, "ID в буфере обмена!", addon.id, false); } catch(e) {} } else if (e.shiftKey) { if (extension?.uuid) { this.clipboardHelp.copyString(extension.uuid); try { this.alertsService.showAlertNotification(`${img}`, "UUID в буфере обмена!", extension.uuid, false); } catch(e) {} } } else if (addon.isActive && addon.optionsURL) this.openAddonOptions(addon, win); win.closeMenus(mi); break; case 1: if (e.ctrlKey) { if (!addon.isBuiltin) this.browseDir(addon); } else if (e.shiftKey) this.browseDir(addon, win); else if (addon.homepageURL) win.gBrowser.selectedTab = this.addTab(win, addon.homepageURL); win.closeMenus(mi); break; case 2: if (!e.ctrlKey) { let endis = addon.userDisabled ? "enable" : "disable"; if (addon.id == "screenshots@mozilla.org") Services.prefs.setBoolPref("extensions.screenshots.disabled", !addon.userDisabled); else if (addon.id == "webcompat-reporter@mozilla.org") Services.prefs.setBoolPref("extensions.webcompat-reporter.enabled", addon.userDisabled); addon[endis]({ allowSystemAddons: true }); } else if (!addon.isSystem && !addon.isBuiltin && Services.prompt.confirm(win, null, `Удалить ${addon.name}?`)) addon.uninstall(); break; } }, openAddonOptions: function(addon, win) { switch (addon.optionsType) { case 5: win.BrowserOpenAddonsMgr(`addons://detail/${encodeURIComponent(addon.id)}/preferences`); break; case 3: win.switchToTabHavingURI(addon.optionsURL, true); break; } }, browseDir: function(addon, win) { try { if (!win) { let file = Services.io.getProtocolHandler("file") .QueryInterface(Ci.nsIFileProtocolHandler) .getFileFromURLSpec(addon.getResourceURI().QueryInterface(Ci.nsIJARURI).JARFile.spec); if (file.exists()) file.launch(); } else win.gBrowser.selectedTab = this.addTab(win, addon.getResourceURI().spec); } catch (e) {} }, addTab: function(win, url, params = {}) { params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); params.relatedToCurrent = true; return win.gBrowser.addTab(url, params); }, }; CustomizableUI.createWidget({ id: id, type: "custom", label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(doc) { var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView, props = { id: id, label: label, tooltiptext: tooltiptext, type: "menu", class: "toolbarbutton-1 chromeclass-toolbar-additional", }; for (let p in props) btn.setAttribute(p, props[p]); btn.addEventListener("click", (e) => { if (e.button == 0) { if (e.shiftKey) win.BrowserOpenAddonsMgr(); } else if (e.button == 1) win.BrowserOpenAddonsMgr(); }); var mp = doc.createXULElement("menupopup"); mp.id = `${id}-popup`; mp.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); }); mp.addEventListener("contextmenu", (e) => { e.preventDefault(); e.stopPropagation(); }); mp.addEventListener("popupshowing", (e) => { extensionOptionsMenu.populateMenu(e); }); btn.append(mp); var btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(` #${id}, #${id}-popup menuitem { list-style-image: url("${img}") !important; } #${id}-popup menuitem::after { display: -moz-box !important; content: "" !important; height: 16px !important; width: 16px !important; padding: 0 !important; border: 1px solid rgb(0, 116, 232) !important; border-radius: 0 !important; background-repeat: no-repeat !important; background-position: center !important; background-size: 16px !important; background-color: rgb(0, 116, 232) !important; background-image: url("${checked}") !important; opacity: 1 !important; } #${id}-popup menuitem.ucf-disabled::after { border-color: currentColor !important; background-color: transparent !important; background-image: none !important; opacity: .6 !important; } #${id}-popup menuitem.ucf-disabled > label, #${id}-popup menuitem.ucf-notoptions > label { opacity: .6 !important; } #${id}-popup menuitem.ucf-system > label { text-decoration: underline !important; text-decoration-style: dotted !important; } #${id}-popup menuitem > label { margin-inline-end: 0 !important; } #${id}-popup menuitem > .menu-accel-container { display: -moz-box !important; padding: 4px !important; margin: 0 !important; opacity: 1 !important; } #${id}-popup menuitem > .menu-accel-container .menu-iconic-accel { display: -moz-box !important; margin: 0 !important; height: 8px !important; width: 8px !important; border-radius: 4px !important; background-color: transparent !important; opacity: 1 !important; font-size: 0 !important; } #${id}-popup menuitem.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel { background-color: rgb(227, 27, 93) !important; } #${id}-popup menuitem.ucf-type-locale > .menu-accel-container .menu-iconic-accel { background-color: rgb(48, 172, 55) !important; } #${id}-popup menuitem.ucf-type-theme > .menu-accel-container .menu-iconic-accel { background-color: rgb(219, 106, 0) !important; } `); try { win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} return btn; }, }); })();} catch (e) {} |
kokoss > 13-07-2022 18:08:57 |
ez7pac пишет
скрытый текст Да вроде работает, просто обновите код для отключения проверки... -> https://forum.mozilla-russia.org/viewto … 59#p800159, там ещё была проблема с кнопкой "Дополнения", здесь решение -> https://forum.mozilla-russia.org/viewto … 83#p799883 |
voqabuhe > 13-07-2022 18:12:36 |
ez7pac пишет
Всё работает, спасибо Dumby, №340 |
ez7pac > 13-07-2022 18:28:28 |
kokoss |
kokoss > 13-07-2022 20:55:06 |
ez7pac пишет
В папке установки , в файле config.js. |
ez7pac > 13-07-2022 21:17:55 |
kokoss пишет
В папке браузера? И добавлял этот код - https://forum.mozilla-russia.org/viewtopic.php?pid=800159#p800159, и заменял то, что там было - пофиг скрытый текст |
kokoss > 13-07-2022 21:24:14 |
ez7pac пишет
Инструкция, с описанием куда добавить: https://forum.mozilla-russia.org/viewtopic.php?id=70326 |
ez7pac > 13-07-2022 21:44:05 |
kokoss |
xrun1 > 13-07-2022 22:00:25 |
ez7pac пишет
ссылки в коде Выделить код Код:/* https://forum.mozilla-russia.org/viewtopic.php?pid=788786#p788786 есть для окна куков другой код, запоминает положение окна https://forum.mozilla-russia.org/viewtopic.php?pid=788799#p788799 */ try {CustomizableUI.createWidget({ label: "ПАРОЛИ/КУКИ", tooltiptext: "ЛКМ: См. ПАРОЛИ\nПКМ: См. КУКИ", id: "ucf-logins-sitedata", localized: false, onCreated(btn) { btn._handleClick = btn.oncontextmenu = e => this.view(e, btn.ownerGlobal); btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAADo0lEQVR42pWUf0idVRzGP+d4vVfbFFeu/SErV1bUBiI6ivajUcEiiiBoaTEEo7Lsj2W1P6Q2xFiL0Qp0q/7pB2GLijZGG/aDSPuBxBbkGm3O7IJuRJmod+t6r+89p+d9b6TWhu17uefe97zn+5zn+3yfcwznCz9e7c2S5fr3i8Ec5yLCzHtq96txdGNZSoE+a8mxgRG2cx/t5uTFAd7u17GOPrbl9oDdibGjdPgrtOIlwd7TtI2aN8zCbGcBn/dJJb7LdtP2n1XP+Q8Z+a2St5bVzVPmlPInBVKHnw/Y7tdr7OE7yjhksnM2sTxrHJ/7Sr0booIbaDSDeC9pjec8EQH6TdRzgofNALddqBR/HWNU84B5n0+j533EWcYKKZwyjZyZz/BJ36XxVkrpZPDnOMUJy4xmCmOSsxDSZwPKrtylhjXwqtnvR3mGczxBwOXEbIaU+4YMLWYNSUPTcA9pt1GLFQEUFek3fBCQE6oNp204NUXvWIUfrGsmyS6mNV/bo+F6bfg0HP/gNHWsMmwaDCKLhGGtwwks5mweKcS2OawrYOJchz9Y08ExsjgxTweOm/pNhhvD3YPE+B0JPv5kh2HzcEogi0XOEQtfCcxGdKeEWRqRDfHHf7/L71hjuYSDpFVFThQvXeGpOkqaJa6YPsPXt/xqaBhWoitRWi4PmFH2oja6K3fyYLILm20hq6ljRzb6vfUZyvmS6bi2KTBk0lpaDtVbHGO9hhOf/WFoTKaEIoaiFdO6YMZhF9fyzvIBGpJ3knOHKEy8RnfFY35AJnexVn1d1FAn/81MezUklC3Bn7wSAk4JpYRpARa5nMovJBv7iKnE/ZS508RzX/B2ZYP/kRcFslXsQq3lQSeHSPrY338X5Yaoyq6eZZgVYFyAQUbtLe7lK1fP0p+2cvTuVn9SzNK05hsVWslGWNhgMqqqwB0W10fN1fLkPxo6aRjHRQydPUV31bWRgb+3ezT/ePiGbNwSm56Uo/qY4GW1bUgbeXMvo7PG3jw8KcDSqMs2ZBgaMPYm+65qkoFfV+IjODVBFlUFlkTwgrmGNi4QAkz6yHuhP0JtstYwemaV79xQBdkDcnq+UiffpYNmbuY9Y0jNOZQS0My5HJpGugTYooLziamz8EP/Wn/4oRpm4p1IAbl4QjrtNytp+n/XV/PYSpV5GaYge2RvSXHtt/JaGVsk9O6o1BKekuC7FwKbfx/++3Y5oINvdFBzGsvpN+uj07tg/AUtF37/2LRsMgAAAABJRU5ErkJggg=="); }, view(e, win) { if (e && (e.ctrlKey || e.shiftKey)) return; var uri = win.gBrowser.selectedBrowser.currentURI; try { var url = win.ReaderMode.getOriginalUrl(uri.spec); if (url) uri = Services.io.newURI(url); } catch {} try {var tld = Services.eTLD.getBaseDomain(uri);} catch {var tld = uri.asciiHost;} e ? this.viewCookies(tld, win) : this.viewPasswords(tld, uri, win); return false; }, viewPasswords(tld, uri, win) { try { tld = Services.io.newURI(`${uri.scheme}://${tld}`).displayHost; } catch {} var params = new win.URLSearchParams({...(tld && {filter: tld})}); var gb = win.gBrowser; var separator = params.toString() ? "?" : ""; var tabToSelect, url = `about:logins${separator}${params}`; for (var tab of gb.visibleTabs) { var {spec} = tab.linkedBrowser.currentURI; if (!spec.startsWith("about:logins")) continue; if (spec != url) { var pending = tab.hasAttribute("pending"); if (pending) gb.selectedTab = tab; tab.linkedBrowser.loadURI( url, {triggeringPrincipal: tab.nodePrincipal} ); if (pending) return; } tabToSelect = tab; break; } gb.selectedTab = tabToSelect || gb.addTrustedTab(url); }, async viewCookies(tld, window) { var notFound, wt = "Browser:SiteDataSettings"; var url = "chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml"; var win = Services.wm.getMostRecentWindow(wt); if (!win) { notFound = true; await window.SiteDataManager.updateSites(); win = window.openDialog(url, wt, "chrome,dialog=no,centerscreen,resizable"); var e = await new Promise(resolve => win.windowRoot.addEventListener("DOMContentLoaded", resolve, {once: true}) ); win = e.target.ownerGlobal; } var doc = win.document, de = doc.documentElement; de.setAttribute("persist", "screenX screenY width height"); if (notFound) { de.setAttribute("windowtype", wt); var xs = Services.xulStore, {id} = de; var x = xs.getValue(url, id, "screenX"); var y = xs.getValue(url, id, "screenY"); x && de.setAttribute("screenX", x); y && de.setAttribute("screenY", y); } var sb = doc.querySelector("#searchBox"); sb.inputField.setUserInput(tld); setTimeout(() => sb.editor.selection.collapseToEnd(), 50); notFound || win.focus(); } });} catch(ex) {Cu.reportError(ex);} 13-07-2022 22:02:50 |
ez7pac > 13-07-2022 22:13:58 |
xrun1, спасибо.
Не работало одно только выпадающее меню с расширениями, с другими кнопками все было нормально. Но теперь уже подсказали как поправить само расширение, теперь все работает без вопросов, так что коды кнопок уже не нужны. С ATB мне гораздо проще. Пользуюсь обычно четырьмя кнопками - восстановить закрытую вкладку, пароли, перезагрузка браузера и меню расширений. Иногда прокси вытаскиваю. |
kokoss > 13-07-2022 22:17:04 |
ez7pac пишет
А перезапустить с очисткой кэша запуска... Add. если проблема только в окошке с предупреждением... скрыть Выделить код Код:@-moz-document url-prefix("chrome://mozapps/content/extensions/aboutaddons.html"), url("about:addons"){ div.container { display: none !important; } } добавить в userContent.css |
ez7pac > 13-07-2022 22:38:39 |
kokoss
Само собой.
Так пропало предупреждение. Спасибо |
kokoss > 13-07-2022 22:57:32 |
ez7pac отключающие проверку... |
ez7pac > 13-07-2022 23:23:29 |
kokoss |
kokoss > 13-07-2022 23:32:47 |
ez7pac пишет
С этого и надо было начать, тогда код для отключения... не нужен, достаточно переключить настройки в конфиге, которые я привёл выше + стиль для скрытия..., а не активны они потому что автор сборки видимо закинул их в файл config.js. |
ez7pac > 14-07-2022 19:20:43 |
kokoss, дружище! Странный глюк вылез вот с этим кодом в userContent.css: Заметил не сразу, потому что он ломает только некоторые сайты. Вот хороший пример - http://tundra-japonamat.ru/index.html скрытый текст Выделить код Код:@namespace url(http://www.w3.org/1999/xhtml); @-moz-document domain("www.google.ru") { #newsbox span.tl>a, #newsbox span.tl>a.l { font-size: 13px; text-decoration: underline; } #res h3 { font-size: medium; text-decoration: underline; } #tads a, #tadsb a, #res a, #rhs a, #taw a { text-decoration: underline ; } div.nrg-title>a, div.irg-title>a { font-size: medium; } span.tl>a { font-size: 13px; } .rgsep, .g-blk, #extrares { display: none !important; } div#pushdown, div.pdp-psy, div.pmoabs { display: none !important; } div.rhsvw.kno-ftr { display: none !important; } #res h3 { font-size: medium !important; } .spell { font-size: 15px !important; } #_L8b { display: none !important; } div._eNq span { font-size: 15px !important; text-decoration: underline !important; } div.gb_g.gb_Lc.gb_Xc.gb_Wc > .gb_ha { display: none !important; } .mslg .l { font-size: 15px !important; } ._dTj { font-size: 14px !important; } ._vSj { line-height: 16px !important; } .xIqs0b { font-size: 15px !important; } html, body { text-shadow: 0px 0px 0px !important; } } @-moz-document domain("www.google.com") { #botstuff { display: none !important; } #brs { display: none !important; } div.vk_c.rhsvw.vk_rhsc.kp-blk { display: none !important; } h3.r { font-size: 15px; text-decoration: underline; } h3.r a { font-size: 15px; } #newsbox span.tl > a { font-size: 13px; text-decoration: underline; } div.nrg-title._Hb>a, div.irg-title._Hb>a, div.nrg-title._zb>a, div._qi._zb>a, a._ef.nrg-footer, a._ef.irg-footer { font-size: 15px ; text-decoration: underline; } span.spell.ng,a.spell b i { font-size: 15px; } ._Dk, ._wI, ._wI a { font-size: 15px !important; } #res h3 { font-size: medium !important; } .spell { font-size: 15px !important; } #_L8b { display: none !important; } div._eNq span { font-size: 15px !important; text-decoration: underline !important; } div.gb_g.gb_Lc.gb_Xc.gb_Wc > .gb_ha { display: none !important; } .mslg .l { font-size: 15px !important; } ._dTj { font-size: 14px !important; } ._vSj { line-height: 16px !important; } .xIqs0b { font-size: 15px !important; } html, body { text-shadow: 0px 0px 0px !important; } } @-moz-document domain("yandex.ru") { .b-advertizing-and-wizards,.b-serp-item_last_yes { display: none !important; } .b-body-items_type_main .b-serp-item:nth-child(11), .b-body-items_type_main .b-serp-item:nth-child(12), .b-body-items_type_main .b-serp-item:nth-child(13), .b-body-items_type_main .b-serp-item:nth-child(14), .b-body-items_type_main .b-serp-item:nth-child(15), .b-body-items_type_main .b-serp-item:nth-child(16), .b-body-items_type_main .b-serp-item:nth-child(17) { display: none !important; } a.b-spec-adv__direct { display: none !important; } div.b-person-results.g-gap-vertical.g-gap-horizontal { display: none !important; } div.b-related.g-gap-vertical.g-gap-horizontal { display: none !important; } div.b-spec-adv.b-spec-adv_serp-margin_yes.g-gap-vertical.b-spec-adv.b-spec-adv_type_highlighted.i-bem { background-color: #fff; font-size: 0; height: 0; margin-left: -1200px; padding: 0; width: 0; } div.z-audio__flash { display: none !important; } li.z-audio.b-serp-item.i-bem.z-audio_js_inited { display: none !important; } p.b-filters__intents.b-filters__intents_level_1 { display: none !important; } .logo, .b-logo { opacity: 0.3 !important; } .logo:hover { opacity: 1 !important; } .serp-item__title { font-size: medium !important; font-weight: normal !important; text-decoration: underline; } a.link.serp-item__title-link { font-size: 15px !important; text-decoration: underline !important; } a.link.distro__link.distro__item, div.distro__item { display: none !important; } div.distro.scroll-spy, div.z-default-search { display: none !important; } div.footer-stripe, div.footer-stripe__content { display: none !important; } } @-moz-document domain("ya.ru") { .suggest2-form__input { background-color: #eee !important; } .input__control { color: #444 !important; } .button_theme_websearch { background-color: #eee !important; color: #aaa !important; } } @-moz-document domain("new-rutor.org") { body { background-image: none !important; padding: 0 !important; } #pluso-panel, #all, div#ws { width: 100% !important; } div#ws div#content { width: 75% !important; } .sideblock2 { display: none !important; } } @-moz-document domain("bing.com") { h2, h3, .b_no h1 { font-size: medium !important; } } @-moz-document domain("duckduckgo.com") { a.large, a.result__a { font-size: medium !important; } .add-to-browser-badge, div.foot-home.js-foot-home, div.tag-home.tag-home--slide.no-js__hide.js-tag-home, div.results--powered { display: none !important; } div.header-wrap--home.js-header-wrap { opacity: .5 !important; } div.logo-wrap--home, span.header__logo, img#logo { opacity: .3 !important; } div.logo-wrap--home:hover, span.header__logo:hover, img#logo:hover { opacity: 1 !important; } .logo_homepage { background-size: 130px 100px !important; height: 100px !important; width: 130px !important; } a.badge-link__wrap.js-badge-main-msg, div.badge-link.badge-link--top.js-badge-link, div.tag-home, div.onboarding-bottom-bathroomguy-slide, div.onboarding-bottom.onboarding-bottom-bathroomguy { display: none !important; } div.tag-home__wrapper,div.hide--screen-xs { display: none !important; } div.onboarding-ed__slide,div.onboarding-ed,div.badge-link { display: none !important; } } @-moz-document domain("1tv.ru") { body { background-color: #000 !important; } .navbar, .menu { background-color: #eee !important; } article.live, .theme-main { background-color: #f4f4f4 !important; } header#page-title { color: #b4b4b4 !important; } .theme-main > .live, .theme-main > .live > .player-wrapper { background-color: #000 !important; } .footer { background-color: #000 !important; color: #f4f4f4 !important; } #mainalert, #popupContainer, #yandex_ad, .itv-push-suggest, .welcome-popup, .promo-place, .branding_promo_place, .header-promo-place, .side-promo-place-right, .footer-promo-place, .social-buttons-compact, .social-widgets, .small-social-buttons, .footer-menu, .yashare-auto-init.b-share_theme_counter, .links > li:nth-of-type(7) { display: none !important; } } @-moz-document domain("ntv.ru") { div.intop { display: none !important; } #newplayer { top: 0 !important; } div#push_alert, div.wrap_top_flash, input.check_rez, ul.likeBtm.custom, div.outtop, #x8831 a img { display: none !important; } } input:not([type="submit"]):not([type="reset"]):not([type="button"]):not([type="checkbox"]):not([type="radio"]), textarea { background: #ffff33 !important; } Собирал давно, таскал из версии в версию. Вполне возможно, что там куча лишнего или даже вредного. Может из-за этого и сайты ломаются, а твой код только катализатором выступает ... |
kokoss > 14-07-2022 19:47:18 |
ez7pac скрытый текст Выделить код Код:@-moz-document url-prefix("chrome://mozapps/content/extensions/aboutaddons.html"), url("about:addons"){ div.container { display: none !important; } } |
ez7pac > 14-07-2022 19:57:13 |
kokoss |
ez7pac > 15-07-2022 00:03:10 |
Парни, а Simple Session Manager из шапки - куда код кидать? |
Dobrov > 15-07-2022 02:01:59 |
ez7pac пишет
смотрите в шапке Демо-профиль, в нём множество скриптов/стилей уже подключено - файл CustomStylesScripts.jsm Выделить код Код:scriptsbackground: [ // В фоне [System Principal] { path: "custom_script.js", }, { path: "ucf_SessionManager.js", }, |
ez7pac > 15-07-2022 03:27:06 |
Dobrov, спасибо, но мне этого мало. В том смысле, что я в этих вопросах почти полный валенок. Так, вершков некоторых нахватался... |
xrun1 > 15-07-2022 03:54:58 |
ez7pac |
Dobrov > 15-07-2022 04:19:12 |
ez7pac пишет
повторюсь - файл CustomStylesScripts.jsm – добавить строку в секцию scriptsbackground: [ // В фоне [System Principal] |
xrun1 > 15-07-2022 04:25:38 |
Dobrov |
Dobrov > 15-07-2022 04:32:07 |
xrun1 пишет
Дополнил шапку, добавил custom_script.js - скрипты добавлять здесь: (async () => { ["ucf_SessionManager.js"]. Процитирую скрипт из шапки: Выделить код Код:// Этот скрипт можно использовать для создания кнопок с помощью CustomizableUI.createWidget (async (scripts) => { // подключить внешние скрипты [['ucf_QuickToggle.js'], ['UCFTitleChangedChild.jsm', 'registerUCFTitleChanged'], ['Test.jsm']] .forEach(function(js) { try { if (/\.jsm$/i.test(js[0])) { // [скрипт js или jsm, инициализация] var obj = ChromeUtils.import(scripts + js[0]); js[1] && obj[js[1]](); } else Services.scriptloader.loadSubScript(scripts + js[0]); } catch(ex) {Cu.reportError(ex);} }); })('chrome://user_chrome_files/content/custom_scripts/'); /* вариант с отдельными скриптами: (async () => { var loadscript = (name, funcName) => { try { var {href, pathname} = new URL(`chrome://user_chrome_files/content/custom_scripts/${name}`); if (/\.jsm$/i.test(pathname)) { var obj = ChromeUtils.import(href); funcName && obj[funcName](); } else Services.scriptloader.loadSubScript(href); } catch(ex) {Cu.reportError(ex);} } loadscript("ucf_aom-button.js"); loadscript("UCFTitleChangedChild.jsm", "registerUCFTitleChanged"); })(); */ ez7pac пишет
Какие фишки непонятны? Описание есть в спойлере шапки и встроенной справке (спойлер "Полный список▼"). Ещё можно убрать ненужные скрипты из CustomStylesScripts.jsm и CustomStylesScriptsChild.jsm, оставив базовый ucf_hookClicks.js и нужный вам ucf_SessionManager.js. Впрочем дополнительные скрипты требуют значительно меньше памяти, чем дополнения. |
kokoss > 15-07-2022 19:26:54 |
ez7pac Add, добавить в user_chrome_files/custom_scripts/custom_script.js |
ez7pac > 15-07-2022 19:58:29 |
Dobrov пишет
Да не то, чтобы непонятны, просто я мельком пробежался, сильно не вникал. Я ставлю обычно только то, что мне нужно и полезно на данный момент. Ставить пак, пусть и хороший, "шоб було" , ради одной фишки - не мое. Вот сейчас из всего списка меня заинтересовал только менеджер сессий. А перебирать пак, удаляя ненужное мне - это косяки, глюки, нервотрепка и т.п. Элементарно не хватит знаний. kokoss пишет
Спасибо. Но код - это хорошо, но еще бы знать куда его впихнуть и не накосячить при этом... |
ez7pac > 16-07-2022 03:13:10 |
kokoss пишет
Только сейчас увидел ответ. И снова спасибо! Добавил, кнопка появилась, работает менеджер. Я извиняюсь, конечно, но возникли пара вопросов. |
Dobrov > 16-07-2022 03:33:00 |
ez7pac пишет
Сесии храняться в «Профиль Firefox//chrome/simple_session_manager.json» |
ez7pac > 16-07-2022 14:16:43 |
Dobrov, понял, спасибо. |
kazarin > 22-07-2022 05:51:36 |
Уважаемые гуру, подскажите, пожалуйста. Есть вот такой скрипт, прекрасно работает на 78. А на 101 не грузится меню с подключёнными стилями (остальное работает). Это реально поправить? |
Farby > 22-07-2022 13:38:45 |
kazarin пишет
Пробуй, проверял на 103, в консоли ошибок нет... UserCSSLoader.uc.js Выделить код Код:// ==UserScript== // @name UserCSSLoader // @description Stylish みたいなもの // @namespace http://d.hatena.ne.jp/Griever/ // @author Griever // @include main // @license MIT License // @compatibility Firefox 4 // @charset UTF-8 // @version 0.0.4改 // @startup UCL.init(); // @note 0.0.4 Remove E4X // @note CSSEntry クラスを作った // @note スタイルのテスト機能を作り直した // @note ファイルが削除された場合 rebuild 時に CSS を解除しメニューを消すようにした // @note uc で読み込まれた .uc.css の再読み込みに仮対応 // ==/UserScript== /****** 使い方 ****** chrome フォルダに CSS フォルダが作成されるのでそこに .css をぶち込むだけ。 ファイル名が "xul-" で始まる物、".as.css" で終わる物は AGENT_SHEET で、それ以外は USER_SHEET で読み込む。 ファイルの内容はチェックしないので @namespace 忘れに注意。 メニューバーに CSS メニューが追加される メニューを左クリックすると ON/OFF 中クリックするとメニューを閉じずに ON/OFF 右クリックするとエディタで開く エディタは "view_source.editor.path" に指定されているものを使う フォルダは "UserCSSLoader.FOLDER" にパスを入れれば変更可能 **** 説明終わり ****/ (function(){ let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; if (!window.Services) Cu.import("resource://gre/modules/Services.jsm"); // 起動時に他の窓がある(2窓目の)場合は抜ける let list = Services.wm.getEnumerator("navigator:browser"); while(list.hasMoreElements()){ if(list.getNext() != window) return; } if (window.UCL) { window.UCL.destroy(); delete window.UCL; } const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; window.UCL = { IN_TOOLMENU: false, // true: ツールメニュー内、 false:メインメニューのヘルプの前 USE_UC: "UC" in window, AGENT_SHEET: Ci.nsIStyleSheetService.AGENT_SHEET, USER_SHEET : Ci.nsIStyleSheetService.USER_SHEET, readCSS : {}, get disabled_list() { let obj = []; try { obj = decodeURIComponent(this.prefs.getCharPref("disabled_list")).split("|"); } catch(e) {} delete this.disabled_list; return this.disabled_list = obj; }, get prefs() { delete this.prefs; return this.prefs = Services.prefs.getBranch("UserCSSLoader.") }, get styleSheetServices(){ delete this.styleSheetServices; return this.styleSheetServices = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); }, get FOLDER() { let aFolder; try { // UserCSSLoader.FOLDER があればそれを使う let folderPath = this.prefs.getCharPref("FOLDER"); aFolder = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile) aFolder.initWithPath(folderPath); } catch (e) { aFolder = Services.dirsvc.get("UChrm", Ci.nsIFile); aFolder.appendRelativePath("CSS"); } if (!aFolder.exists() || !aFolder.isDirectory()) { aFolder.create(Ci.nsIFile.DIRECTORY_TYPE, 0664); } delete this.FOLDER; return this.FOLDER = aFolder; }, getFocusedWindow: function() { let win = document.commandDispatcher.focusedWindow; if (!win || win == window) win = content; return win; }, init: function() { const cssmenu = $C("menu", { id: "usercssloader-menu", label: "CSS", accesskey: "C" }); const menupopup = $C("menupopup", { id: "usercssloader-menupopup" }); cssmenu.appendChild(menupopup); let menu = $C("menu", { label: "メニュ━━━(゚∀゚)━━━!!", accesskey: "C" }); menupopup.appendChild(menu); let mp = $C("menupopup", { id: "usercssloader-submenupopup" }); menu.appendChild(mp); mp.appendChild($C("menuitem", { label: "Rebuld", accesskey: "R", acceltext: "Alt + R", oncommand: "UCL.rebuild();" })); mp.appendChild($C("menuseparator")); mp.appendChild($C("menuitem", { label: "新規作成", accesskey: "N", oncommand: "UCL.create();" })); mp.appendChild($C("menuitem", { label: "CSS フォルダを開く", accesskey: "O", oncommand: "UCL.openFolder();" })); mp.appendChild($C("menuitem", { label: "userChrome.css を編集", // hidden: true, oncommand: "UCL.editUserCSS(\'userChrome.css\');" })); mp.appendChild($C("menuitem", { label: "userContent.css を編集", // hidden: true, oncommand: "UCL.editUserCSS(\'userContent.css\');" })); mp.appendChild($C("menuseparator")); mp.appendChild($C("menuitem", { label: "スタイルのテスト (Chrome)", id: "usercssloader-test-chrome", hidden: true, accesskey: "C", oncommand: "UCL.styleTest(window);" })); mp.appendChild($C("menuitem", { label: "スタイルのテスト (Webページ)", id: "usercssloader-test-content", hidden: true, accesskey: "W", oncommand: "UCL.styleTest();" })); mp.appendChild($C("menuitem", { label: "userstyles.org でスタイルを検索", accesskey: "S", oncommand: "UCL.searchStyle();" })); menu = $C("menu", { label: ".uc.css", accesskey: "U", hidden: !UCL.USE_UC }); menupopup.appendChild(menu); mp = $C("menupopup", { id: "usercssloader-ucmenupopup" }); menu.appendChild(mp); mp.appendChild($C("menuitem", { label: "Rebuild(.uc.js)", oncommand: "UCL.UCrebuild();" })); mp.appendChild($C("menuseparator", { id: "usercssloader-ucsepalator" })); if (this.IN_TOOLMENU) { $('menu_ToolsPopup').insertBefore(cssmenu, $('menu_preferences')); } else { $('main-menubar').insertBefore(cssmenu, $('helpMenu')); } $("mainKeyset").appendChild($C("key", { id: "usercssloader-rebuild-key", oncommand: "UCL.rebuild();", key: "R", modifiers: "alt", })); this.rebuild(); this.initialized = true; if (UCL.USE_UC) { setTimeout(function() { UCL.UCcreateMenuitem(); }, 1000); } window.addEventListener("unload", this, false); }, uninit: function() { const dis = []; for (let x of Object.keys(this.readCSS)) { if (!this.readCSS[x].enabled) dis.push(x); } this.prefs.setCharPref("disabled_list", encodeURIComponent(dis.join("|"))); window.removeEventListener("unload", this, false); }, destroy: function() { var i = document.getElementById("usercssloader-menu"); if (i) i.parentNode.removeChild(i); var i = document.getElementById("usercssloader-rebuild-key"); if (i) i.parentNode.removeChild(i); this.uninit(); }, handleEvent: function(event) { switch(event.type){ case "unload": this.uninit(); break; } }, rebuild: function() { let ext = /\.css$/i; let not = /\.uc\.css/i; let files = this.FOLDER.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator); while (files.hasMoreElements()) { let file = files.getNext().QueryInterface(Ci.nsIFile); if (!ext.test(file.leafName) || not.test(file.leafName)) continue; let CSS = this.loadCSS(file); CSS.flag = true; } for (let leafName of Object.keys(this.readCSS)) { const CSS = this.readCSS[leafName]; if (!CSS.flag) { CSS.enabled = false; delete this.readCSS[leafName]; } delete CSS.flag; this.rebuildMenu(leafName); } if (this.initialized) { if (typeof(StatusPanel) !== "undefined") StatusPanel._label = "Rebuild しました"; else XULBrowserWindow.statusTextField.label = "Rebuild しました"; } }, loadCSS: function(aFile) { var CSS = this.readCSS[aFile.leafName]; if (!CSS) { CSS = this.readCSS[aFile.leafName] = new CSSEntry(aFile); if (this.disabled_list.indexOf(CSS.leafName) === -1) { CSS.enabled = true; } } else if (CSS.enabled) { CSS.enabled = true; } return CSS; }, rebuildMenu: function(aLeafName) { var CSS = this.readCSS[aLeafName]; var menuitem = document.getElementById("usercssloader-" + aLeafName); if (!CSS) { if (menuitem) menuitem.parentNode.removeChild(menuitem); return; } if (!menuitem) { menuitem = $C("menuitem", { label : aLeafName, id : "usercssloader-" + aLeafName, class : "usercssloader-item " + (CSS.SHEET == this.AGENT_SHEET? "AGENT_SHEET" : "USER_SHEET"), type : "checkbox", autocheck : "false", oncommand : "UCL.toggle('"+ aLeafName +"');", onclick : "UCL.itemClick(event);" }); document.getElementById("usercssloader-menupopup").appendChild(menuitem); } menuitem.setAttribute("checked", CSS.enabled); }, toggle: function(aLeafName) { var CSS = this.readCSS[aLeafName]; if (!CSS) return; CSS.enabled = !CSS.enabled; this.rebuildMenu(aLeafName); }, itemClick: function(event) { if (event.button == 0) return; event.preventDefault(); event.stopPropagation(); let label = event.currentTarget.getAttribute("label"); if (event.button == 1) { this.toggle(label); } else if (event.button == 2) { closeMenus(event.target); this.edit(this.getFileFromLeafName(label)); } }, getFileFromLeafName: function(aLeafName) { let f = this.FOLDER.clone(); f.QueryInterface(Ci.nsIFile); // use appendRelativePath f.appendRelativePath(aLeafName); return f; }, styleTest: function(aWindow) { aWindow || (aWindow = this.getFocusedWindow()); new CSSTester(aWindow, function(tester){ if (tester.saved) UCL.rebuild(); }); }, searchStyle: function() { let word; try { word = gBrowser.currentURI.host; } catch { word = gBrowser.currentURI.spec; } let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); openLinkIn("https://userstyles.org/styles/search/" + word, "tab", { private: false, inBackground: false, relatedToCurrent: true, triggeringPrincipal: systemPrincipal, }); }, openFolder: function() { this.FOLDER.launch(); }, editUserCSS: function(aLeafName) { let file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.appendRelativePath(aLeafName); this.edit(file); }, edit: function(aFile) { var editor = Services.prefs.getCharPref("view_source.editor.path"); if (!editor) return alert("エディタのパスが未設定です。\n view_source.editor.path を設定してください"); try { var UI = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); UI.charset = window.navigator.platform.toLowerCase().indexOf("win") >= 0? "Shift_JIS": "UTF-8"; var path = UI.ConvertFromUnicode(aFile.path); var app = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); app.initWithPath(editor); var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); process.init(app); process.run(false, [path], 1); } catch (e) {} }, create: function(aLeafName) { if (!aLeafName) aLeafName = prompt("ファイル名を入力してください", dateFormat(new Date(), "%Y_%m%d_%H%M%S")); if (aLeafName) aLeafName = aLeafName.replace(/\s+/g, " ").replace(/[\\/:*?\"<>|]/g, ""); if (!aLeafName || !/\S/.test(aLeafName)) return; if (!/\.css$/.test(aLeafName)) aLeafName += ".css"; let file = this.getFileFromLeafName(aLeafName); this.edit(file); }, UCrebuild: function() { let re = /^file:.*\.uc\.css(?:\?\d+)?$/i; let query = "?" + new Date().getTime(); Array.prototype.slice(document.styleSheets).forEach(function(css){ if (!re.test(css.href)) return; if (css.ownerNode) { css.ownerNode.parentNode.removeChild(css.ownerNode); } let pi = document.createProcessingInstruction('xml-stylesheet','type="text/css" href="'+ css.href.replace(/\?.*/, '') + query +'"'); document.insertBefore(pi, document.documentElement); }); UCL.UCcreateMenuitem(); }, UCcreateMenuitem: function() { let sep = $("usercssloader-ucsepalator"); let popup = sep.parentNode; if (sep.nextSibling) { let range = document.createRange(); range.setStartAfter(sep); range.setEndAfter(popup.lastChild); range.deleteContents(); range.detach(); } let re = /^file:.*\.uc\.css(?:\?\d+)?$/i; Array.prototype.slice(document.styleSheets).forEach(function(css) { if (!re.test(css.href)) return; let fileURL = decodeURIComponent(css.href).split("?")[0]; let aLeafName = fileURL.split("/").pop(); let m = $C("menuitem", { label : aLeafName, tooltiptext : fileURL, id : "usercssloader-" + aLeafName, type : "checkbox", autocheck : "false", checked : "true", oncommand : "this.setAttribute('checked', !(this.css.disabled = !this.css.disabled));", onclick : "UCL.UCItemClick(event);" }); m.css = css; popup.appendChild(m); }); }, UCItemClick: function(event) { if (event.button == 0) return; event.preventDefault(); event.stopPropagation(); if (event.button == 1) { event.target.doCommand(); } else if (event.button == 2) { closeMenus(event.target); let fileURL = event.currentTarget.getAttribute("tooltiptext"); let file = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getFileFromURLSpec(fileURL); this.edit(file); } }, }; function CSSEntry(aFile) { this.path = aFile.path; this.leafName = aFile.leafName; this.lastModifiedTime = 1; this.SHEET = /^xul-|\.as\.css$/i.test(this.leafName) ? Ci.nsIStyleSheetService.AGENT_SHEET: Ci.nsIStyleSheetService.USER_SHEET; } CSSEntry.prototype = { sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService), _enabled: false, get enabled() { return this._enabled; }, set enabled(isEnable) { var aFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile) aFile.initWithPath(this.path); var isExists = aFile.exists(); // ファイルが存在したら true var lastModifiedTime = isExists ? aFile.lastModifiedTime : 0; var isForced = this.lastModifiedTime != lastModifiedTime; // ファイルに変更があれば true var fileURL; try { fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromFile(aFile); } catch { fileURL = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler).getURLSpecFromActualFile(aFile); } var uri = Services.io.newURI(fileURL, null, null); if (this.sss.sheetRegistered(uri, this.SHEET)) { // すでにこのファイルが読み込まれている場合 if (!isEnable || !isExists) { this.sss.unregisterSheet(uri, this.SHEET); } else if (isForced) { // 解除後に登録し直す this.sss.unregisterSheet(uri, this.SHEET); this.sss.loadAndRegisterSheet(uri, this.SHEET); } } else { // このファイルは読み込まれていない if (isEnable && isExists) { this.sss.loadAndRegisterSheet(uri, this.SHEET); } } if (this.lastModifiedTime !== 1 && isEnable && isForced) { log(this.leafName + " の更新を確認しました。"); } this.lastModifiedTime = lastModifiedTime; return this._enabled = isEnable; }, }; function CSSTester(aWindow, aCallback) { this.win = aWindow || window; this.doc = this.win.document; this.callback = aCallback; this.init(); } CSSTester.prototype = { sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService), preview_code: "", saved: false, init: function() { this.dialog = openDialog( "data:text/html;charset=utf8,"+encodeURIComponent('<!DOCTYPE HTML><html lang="ja"><head><title>CSSTester</title></head><body></body></html>'), "", "width=550,height=400,dialog=no"); this.dialog.addEventListener("load", this, false); }, destroy: function() { this.preview_end(); this.dialog.removeEventListener("unload", this, false); this.previewButton.removeEventListener("click", this, false); this.saveButton.removeEventListener("click", this, false); this.closeButton.removeEventListener("click", this, false); }, handleEvent: function(event) { switch(event.type) { case "click": if (event.button != 0) return; if (this.previewButton == event.currentTarget) { this.preview(); } else if (this.saveButton == event.currentTarget) { this.save(); } else if (this.closeButton == event.currentTarget) { this.dialog.close(); } break; case "load": var doc = this.dialog.document; doc.body.innerHTML = '\ <style type="text/css">\ :not(input):not(select) { padding: 0px; margin: 0px; }\ table { border-spacing: 0px; }\ body, html, #main, #textarea { width: 100%; height: 100%; }\ #textarea { font-family: monospace; }\ </style>\ <table id="main">\ <tr height="100%">\ <td colspan="4"><textarea id="textarea"></textarea></td>\ </tr>\ <tr height="40">\ <td><input type="button" value="Preview" /></td>\ <td><input type="button" value="Save" /></td>\ <td width="80%"><span class="log"></span></td>\ <td><input type="button" value="Close" /></td>\ </tr>\ </table>\ '; this.textbox = doc.querySelector("textarea"); this.previewButton = doc.querySelector('input[value="Preview"]'); this.saveButton = doc.querySelector('input[value="Save"]'); this.closeButton = doc.querySelector('input[value="Close"]'); this.logField = doc.querySelector('.log'); var code = "@namespace url(" + this.doc.documentElement.namespaceURI + ");\n"; code += this.win.location.protocol.indexOf("http") === 0? "@-moz-document domain(" + this.win.location.host + ") {\n\n\n\n}": "@-moz-document url(" + this.win.location.href + ") {\n\n\n\n}"; this.textbox.value = code; this.dialog.addEventListener("unload", this, false); this.previewButton.addEventListener("click", this, false); this.saveButton.addEventListener("click", this, false); this.closeButton.addEventListener("click", this, false); this.textbox.focus(); let p = this.textbox.value.length - 3; this.textbox.setSelectionRange(p, p); break; case "unload": this.destroy(); this.callback(this); break; } }, preview: function() { var code = this.textbox.value; if (!code || !/\:/.test(code)) return; code = "data:text/css;charset=utf-8," + encodeURIComponent(this.textbox.value); if (code == this.preview_code) return; this.preview_end(); var uri = Services.io.newURI(code, null, null); this.sss.loadAndRegisterSheet(uri, Ci.nsIStyleSheetService.AGENT_SHEET); this.preview_code = code; this.log("Preview"); }, preview_end: function() { if (this.preview_code) { let uri = Services.io.newURI(this.preview_code, null, null); this.sss.unregisterSheet(uri, Ci.nsIStyleSheetService.AGENT_SHEET); this.preview_code = ""; } }, save: function() { var data = this.textbox.value; if (!data) return; var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(window, "", Ci.nsIFilePicker.modeSave); fp.appendFilter("CSS Files","*.css"); fp.defaultExtension = "css"; if (window.UCL) fp.displayDirectory = UCL.FOLDER; var res = fp.show(); if (res != fp.returnOK && res != fp.returnReplace) return; var suConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); suConverter.charset = "UTF-8"; data = suConverter.ConvertFromUnicode(data); var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); foStream.init(fp.file, 0x02 | 0x08 | 0x20, 0664, 0); foStream.write(data, data.length); foStream.close(); this.saved = true; }, log: function() { this.logField.textContent = dateFormat(new Date(), "%H:%M:%S") + ": " + $A(arguments); } }; UCL.init(); function $(id) { return document.getElementById(id); } function $A(arr) { return Array.prototype.slice(arr); } function $C(name, attr) { const el = document.createElementNS(XULNS, name); if (attr) Object.keys(attr).forEach(function(n) { el.setAttribute(n, attr[n]) }); return el; } function dateFormat(date, format) { format = format.replace("%Y", ("000" + date.getFullYear()).substr(-4)); format = format.replace("%m", ("0" + (date.getMonth()+1)).substr(-2)); format = format.replace("%d", ("0" + date.getDay()).substr(-2)); format = format.replace("%H", ("0" + date.getHours()).substr(-2)); format = format.replace("%M", ("0" + date.getMinutes()).substr(-2)); format = format.replace("%S", ("0" + date.getSeconds()).substr(-2)); return format; } function log() { Application.console.log(Array.prototype.slice(arguments)); } })(); |
kazarin > 22-07-2022 23:24:10 |
Farby UPD Скрипт заработал! Правда, запускается он каким-то извращённым способом: во-первых, ему нужен пустой (ну или запиканный звёздочками) userChrome.css. В принципе, он его и так игнорит, но ни в 78, ни в доквантумных версиях наличие записей там ему не мешало. А во-вторых, после редактирования userChrome.css обновить надо через кнопку Reload user{Chrome, Content}.css. Тогда он видит изменения и потом уже начинает нормально работать. Спасибо, что починили, очень уж удобный скрипт, приходилось держать вместо него три кнопки, которые не охватывали полностью его функций |
Dumby > 26-07-2022 16:26:44 |
egorsemenov06 пишет
Опять изменили аргументы в internalSave() скрытый текст Выделить код Код:/* if (typeof window.saveImageURL != "function") var saveImageURL = internalSave.length == 15 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, a7, a5, null, priv, prin); */ if (typeof window.saveImageURL != "function") var saveImageURL = internalSave.length == 16 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : internalSave.length == 15 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, a7, a5, null, priv, prin); |
Northtech > 26-07-2022 19:37:03 |
Заметил, что если включить стили в настройках расширения - перестают работать клавиши вызова боковой панели (ctrl+B, ctrl+H). Это можно как-то починить? (на всякий случай выложил папку https://disk.yandex.ru/d/SCyAqLNnyxbTRw) скрытый текст upd: виновник этого безобразия - auto_hide_sidebar.css |
Dumby > 02-08-2022 10:52:53 |
egorsemenov06 пишет
А, saveURL() тоже скрытый текст Выделить код Код:… //var splice = saveURL.length == 10; var {length} = saveURL, splice = length > 9, l11 = length == 11; … //splice && args.splice(5, 0, null); splice && args.splice(5, 0, null) && l11 && args.splice(1, 0, null); |
Dobrov > 02-08-2022 11:21:55 |
Dumby - получается, что теперь нужны два скрипта? |
Dumby > 02-08-2022 11:26:24 |
Dobrov пишет
О чём речь, позволь поинтересоваться? |
Dobrov > 02-08-2022 11:28:56 |
о проверке версий: Это наверное поможет, если Опять изменили аргументы в internalSave() |
Dumby > 02-08-2022 11:40:15 |
Dobrov |
Dobrov > 02-08-2022 11:43:01 |
Dumby пишет
Не знаю, если новая правка работает на всех Firefox, начиная с 90, тогда ладно. Я откатился на FF97, когда страницы стали непонятно тормозить и долго загружаться на FF102. |
Dumby > 04-08-2022 09:44:19 |
egorsemenov06 пишет
Это значило бы, что надо загрузчик смотреть, если бы дело было в этом. Но дело в другом (см. также). скрытый текст Выделить код Код:… let g = Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm", {}); if("lazy" in g) g = g.lazy; |
kazarin > 18-08-2022 22:43:30 |
Dobrov, уважаемый, можно вопрос по вашей кнопке Quick toggle for about:config preferences (Dobrov mod)? скрытый текст Выделить код Код:window.SetDownloadDir = function (path, path_old) { path = window.convertFromUnicode("UTF-8", path); path_old = window.convertFromUnicode("UTF-8", path_old) || ''; if ( path != path_old ) { cbu.setPrefs("browser.download.folderList", 2); cbu.setPrefs("browser.download.useDownloadDir", true); cbu.setPrefs("browser.download.dir", path); } return path; }; window.PathToDownloadDir = function (change) { // null возврат папки загрузки true тоже + открыть папку загрузки 2 изменить папку загрузки - обзор. возврат папки загрузки раньше диалога выбора // try { var path = Services.prefs.getComplexValue("browser.download.dir", Ci.nsISupportsString).data } try { var path = Services.downloads.userDownloadsDirectory.path } catch(e) { path = Services.downloads.defaultDownloadsDirectory.path }; if ( change == true ) { var file = Services.dirsvc.get('ProfD', Ci.nsIFile); file.initWithPath(path); file.launch(); } if (typeof change == 'string') path = window.SetDownloadDir(change, path); // изменить путь загрузок if (change == 2) { var fp = window.makeFilePicker(); fp.init(window, "Выберите папку для загрузок!", 2); fp.open(re=> { if ( re == fp.returnOK ) return window.SetDownloadDir(fp.file.path, path) }); } return path; }; window.PathToDownloadFolder = function (change) { // Получить\Открыть (change=false)\Изменить путь к папке загрузки (change=true или текст) try { var path = Services.downloads.userDownloadsDirectory.path } catch(e) { path = Services.downloads.defaultDownloadsDirectory.path }; if ( change == false ) { var file = Services.dirsvc.get('ProfD', Ci.nsIFile); file.initWithPath(path); file.launch(); } if ( !change ) return path; // arg == undefined || arg == false var fp = window.makeFilePicker(); fp.init(window, "Выберите папку для загрузок!", 2); fp.open(re=> { if ( re != fp.returnOK ) return; cbu.setPrefs("browser.download.folderList", 2); cbu.setPrefs("browser.download.useDownloadDir", true); cbu.setPrefs("browser.download.dir", window.convertFromUnicode("UTF-8", fp.file.path)); }) }; window.Title = function (type) { // заголовок (без обрезки, если type не указан), домен (type <0) var title = (content.document.title || gBrowser.mCurrentTab.label); var host = (/about:/.test(gURLBar.value)) ? // ReaderView или страница about:… decodeURIComponent(gURLBar.value).replace(/^.*url=/,'').replace(/^https?:\/\//,'').replace(/\/.*/,'') : gBrowser.currentURI.host; if (/^file:\/\//.test(gBrowser.currentURI.spec)) host = ''; // открыт локальный файл if ( !type ) return title; // заголовок if ( type > 0 ) return title.replace(/[:\\\/<>?*|"]+/g,' ').replace(/\s+/g,' ').replace(/ /g,' ').substr(0, type).trim(); // ограничить длину имени if ( type < 0 ) return host.replace(/^www\./,'').replace(/^ru\./,'').replace(/^m\./,'').replace(/^forum\./,'').replace(/^club\.dns/,'dns'); }; // Быстрое переключение параметров about:config от 24.07.2016 [FIX Dobrov] // Изменить иконку при несоответствие любого параметра пользовательскому предпочтению (см. ниже) // Иконка меняется только при изменении параметров через меню кнопки, либо после его открытия. var s='CB.hasNotUserChoice', str = ' Быстрые настройки'; // str = 'profile: '+ OS.Constants.Path.profileDir; str = str +'\n Правый клик: опции браузера'; str = str +'\n Держать: открыть about:config'; str = str +'\n\n Proxy(VPN): …порт: '+ cbu.getPrefs("network.proxy.http_port"); str = str +'\n '+ cbu.getPrefs("network.proxy.http"); this.tooltipText = str; // str = str +'\n'+ OS.Constants.Path.libxul; // str = str +'\n'+ OS.Constants.Path.homeDir; // str = str +'\n'+ OS.Constants.Path.desktopDir; // str = str +'\n'+ OS.Constants.Path.winAppDataDir; // undefined // str = str +'\n'+ OS.Constants.Path.winLocalAppDataDir; // undefined // str = str +'\n'+ OS.Constants.Path.winStartMenuProgsDir; // undefined // str = str +'\n'+ OS.Constants.Path.winStartMenuProgsDir; // undefined // str = str +'\n'+ OS.Constants.Path.macUserLibDir; // undefined // str = str +'\n'+ OS.Constants.Path.macLocalApplicationsDir; // undefined function toggleImage(){ custombuttons.getPrefs(s) ? self.style.cssText = '' : self.style.cssText = 'filter: grayscale(100%)'; }; toggleImage();Services.prefs.addObserver(s,toggleImage,false);addDestructor(()=>Services.prefs.removeObserver(s,toggleImage)); var menuPopup = self.appendChild(document.createXULElement("menupopup")); menuPopup.id='quick-aboutconfig-menupopup'; // для стиля в userChrome.css var menuContext = self.appendChild(document.createXULElement("menupopup")); // для действия Сохранить как… Web-страница будет в кодировке Win1251. на FF ниже 60 в GIT не видно выпадающего списка версий var useragent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:78.0) Gecko/20100101 Firefox/78.0"; //,,,Firefox 78/MacOSX|||\ var useragent_name = "Firefox 78/MacOSX"; [ {nodeName:"menu", name:"Прокси (VPN)", pref:"network.proxy.type", refresh:"", image:"chrome://browser/skin/privatebrowsing-mask.png", userChoice:2, strValues:"0,,,отключен,,,0|||2,,,Автонастройка,,,2|||4,,,…для текущей сети,,,4|||5,,,Системный,,,5"}, {nodeName:"menu", name:"URL автонастройки", pref:"network.proxy.autoconfig_url", refresh:"", userChoice:"https://antizapret.prostovpn.org/proxy.pac", strValues:"https://antizapret.prostovpn.org/proxy.pac,,,АнтиЗапрет,,,1|||file:///etc/proxy.pac,,,.pac файл,,,2|||https://git.io/ac-anticensority-pac,,,ac-anticensority,,,3|||127.0.0.1,,,Отключен,,,0"}, //https://rebrand.ly/ac-anticensority {nodeName:"checkbox", name:"режим 'Без прокси' при выходе", pref:"CB.Proxy.reset", userChoice:"false"}, {nodeName:"menuseparator"}, {nodeName:"menu", name:"Загружать шрифты Web", pref:"browser.display.use_document_fonts", strValues:"0,,,Выкл,,,|||1,,,Вкл,,,"}, {nodeName:"checkbox", name:"Выполнять скрипты Java", pref:"javascript.enabled", key:'j', userChoice:"true"}, {nodeName:"checkbox", name:"Сообщить о загрузке страницы", pref:"dom.enable_performance", userChoice:"false"}, {nodeName:"menuseparator"}, {nodeName:"checkbox", name:"автопроигрывание мультимедиа", pref:"media.autoplay.enabled", key:'m', userChoice:"true"}, {nodeName:"menuseparator"}, {nodeName:"menu", name:"User Agent", pref:"general.useragent.override", key:'u', refresh:"", userChoice: useragent, strValues: "\ Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:100.0.1) Gecko/20100101 Firefox/101.0.1.0,,,Firefox 101.0.1/MacOSX|||\ Mozilla/5.0 (Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727),,,MSIE 6.0/Windows|||\ Mozilla/5.0 (Linux; Android 7.0; PLUS Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36,,,Chrome61/Android7|||\ Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30,,,Safari 6/MacOSX|||\ Mozilla/5.0 (Linux; Android 5.1.1; SM-G928X Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36,,,Samsung Galaxy S6|||\ Mozilla/5.0 (PlayStation 4 3.11) AppleWebKit/537.73 (KHTML, like Gecko),,,Playstation 4|||\ Xbox (Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586,,,Xbox One (mobile)|||\ Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586,,,Microsoft Lumia 950|||\ Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; SAMSUNG; GT-I8350),,,Windows Phone|||\ Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html),,,GoogleBot|||\ ,,,Пустое значение"}, // Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots),,,YandexBot|||\ // Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm),,,BingBot|||\ // Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp),,,YahooBot|||\ // Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html),,,BaiduspiderBot|||\ // ia_archiver (+http://www.alexa.com/site/help/webmasters; crawler@alexa.com),,,AlexaCrawlerBot|||\ // DuckDuck bot/1.0; (+http://duckduckgo.com/duckduckbot.html),,,DuckDuckBot|||\ ].forEach( (m)=> { CreateMenu(m, menuPopup); // какое меню создавать }); [ {nodeName:"menu", name:"Куки", pref:"network.cookie.cookieBehavior", refresh:"", userChoice:"0", strValues:"0,,,Разрешить все сайты,,,|||2,,,Запретить все сайты,,,|||3,,,Сторонние посещённые сайты,,,|||1,,,Не принимать со сторонних сайтов,,,"}, {nodeName:"menu", name:"Загружать графику", pref:"permissions.default.image", refresh:"", userChoice:1, strValues:"1,,,Да|||3,,,Site only|||2,,,Нет"}, // 1,2,3; 1 разрешить изображения, 2 отключить; 3 изображения с основного веб-сайта, блокировать со сторонних (third-party) серверов {nodeName:"menu", name:"Анимация изображений", pref:"image.animation_mode", key:'i', refresh:"", userChoice:"normal", strValues:"normal,,,вкл.,,,|||none,,,выкл.,,,"}, {nodeName:"checkbox", name:"OnLine видео 'dom.workers'", pref:"dom.workers.enabled", key:'w', userChoice:"true"}, {nodeName:"menuseparator"}, {nodeName:"checkbox", name:"Откл. дискового кэша", pref:"browser.cache.disk.enable", userChoice:"false"}, {nodeName:"checkbox", name:"Откл. кэша в оперативной памяти", pref:"browser.cache.memory.enable", userChoice:"false"}, {nodeName:"checkbox", name:"Локальное хранилище indexedDB", pref:"dom.indexedDB.enabled", key:'d', userChoice:"true"}, {nodeName:"checkbox", name:"Откл. локального хранилища", pref:"dom.storage.enabled", key:'s'}, {nodeName:"menuseparator"}, // {nodeName:"menu", name:"Back-story-cash [Tessssttt]", pref:"browser.sessionhistory.max_total_viewers", strValues:"0,,,0"}, // {nodeName:"menuseparator"}, {nodeName:"menu", name:"useragent.locale", pref:"general.useragent.locale", key:'l', restart:"", strValues:"en-US,,,English,,,e|||ru-RU,,,Рус (ru-RU),,,r|||ru,,,русский (ru),,,"}, {nodeName:"menu", name:"language", pref:"intl.accept_languages", strValues:"en-US, en;q=0.5,,,en-US, en;q=0.5,,,e|||en-US, en, ru-RU, ru,,,en-US, en, ru-RU, ru,,,r"}, {nodeName:"menu", name:"document_color_use", pref:"browser.display.document_color_use", key:'c', userChoice:"0", strValues:"0,,,Auto,,,0|||1,,,Always,,,1|||2,,,Never,,,2"}, {nodeName:"menuseparator"}, {nodeName:"checkbox", name:"В качестве реферера корень сайта", pref:"network.http.referer.spoofSource", userChoice:"true"}, {nodeName:"menu", name:"Вкл/Выкл Referer", pref:"network.http.sendRefererHeader", userChoice:"2", strValues:"0,,,0|||2,,,2"}, {nodeName:"menu", name:"referer.trimmingPolicy", pref:"network.http.referer.trimmingPolicy", strValues:"0,,,0|||2,,,2"}, {nodeName:"menuseparator"}, {nodeName:"checkbox", pref:"media.mediasource.enabled", userChoice:"true"}, {nodeName:"checkbox", pref:"media.peerconnection.enabled"}, //WebRTC false=off! {nodeName:"checkbox", name:"Многопоточность вкладок (CPU)", pref:"browser.tabs.remote.autostart", restart:"", userChoice:"false"}, //about:support=Multiprocess Windows|forum.ru-board.com/topic.cgi?forum=5&topic=49695&start=0&limit=1&m=9#1 {nodeName:"menuseparator"}, // {nodeName:"checkbox", name:"On/Off useragentS", pref:"general.useragent.site_specific_overrides"}, // useragent +",,,"+ useragent_name +"|||\ ].forEach( (m)=> { CreateMenu(m, menuContext); // контекстное меню }); function CreateMenu(m, menuNew) { if (m.nodeName==="checkbox" || m.nodeName==="radio") var mItem = document.createXULElement('menuitem') // для checkbox, radio else var mItem = document.createXULElement(m.nodeName); var addCommand=''; // создать элементы меню if ("refresh" in m) addCommand = ' BrowserReload();'; if ("restart" in m) addCommand = ' if (custombuttons.confirmBox(null, "Restart?", "Yes", "Cancel")) Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart);'; if ("image" in m) mItem.setAttribute('image', m.image); if ("name" in m) mItem.setAttribute('name', m.name); if ("pref" in m) { mItem.setAttribute('closemenu', 'none'); mItem.setAttribute('oncontextmenu', 'event.preventDefault();custombuttons.clearPrefs("'+m.pref+'");'+ addCommand); } if ("key" in m) mItem.setAttribute('accesskey', m.key); // тип radio не добавлен !!! if (m.nodeName==="checkbox") { mItem.setAttribute('type', 'checkbox'); mItem.setAttribute('oncommand','custombuttons.setPrefs("'+m.pref+'",!custombuttons.getPrefs("'+m.pref+'"));if (event.shiftKey && event.keyCode==event.DOM_VK_RETURN){event.preventDefault();custombuttons.clearPrefs("'+m.pref+'")};'+addCommand); } // if (m.nodeName==="radio") { // if ("name" in m) mItem.setAttribute('label', m.name); // mItem.setAttribute('type', 'radio'); // mItem.setAttribute('oncommand','custombuttons.setPrefs("'+m.pref+'",!custombuttons.getPrefs("'+m.pref+'"));'+addCommand); // } if (m.nodeName === "menu") { mItem.setAttribute('class', 'menu-iconic'); var subMenu = mItem.appendChild(document.createXULElement("menupopup")); for (var value of m.strValues.split('|||')) { var submItem = document.createXULElement("menuitem"); var smVal = value.split(',,,')[0]; var smValConv = convertFromUnicode("UTF-8", smVal); var smName = value.split(',,,')[1]; var key = value.split(',,,')[2]; key && submItem.setAttribute('accesskey', key); submItem.setAttribute('type', 'radio'); submItem.setAttribute('label', smName); submItem.setAttribute('tooltiptext', smVal); submItem.setAttribute('closemenu', 'none'); submItem.setAttribute('oncommand', 'try{custombuttons.setPrefs("'+ m.pref +'","'+ smValConv.replace(/\\/g,'\\\\')+'")}catch(e){Services.prefs.setIntPref("'+ m.pref +'","'+ smValConv +'")};'+ addCommand); subMenu.appendChild(submItem); } } menuNew.appendChild(mItem); // Листенеры отслеживания переключения параметров и устанавка соответствующих названий и чекбоксов для пунктов меню при открытии меню и кликах for (var type of ['command', 'popupshowing', 'contextmenu']) { addEventListener(type, (e)=> { setTimeout(()=> { if ("pref" in m) { var val, def; def = Services.prefs.prefHasUserValue(m.pref); try { val = Services.prefs.getComplexValue(m.pref, Ci.nsISupportsString).data; } catch(e) { if (Services.prefs.getPrefType(m.pref) == 64) val = custombuttons.getPrefs(m.pref).toString(); else val = custombuttons.getPrefs(m.pref); } def ? mItem.style.setProperty('font-weight', 'bold', 'important') : mItem.style.removeProperty('font-weight'); } if (m.nodeName === 'checkbox') { mItem.setAttribute('checked', val); mItem.label = ( mItem.hasAttribute('name') ? mItem.getAttribute('name') : m.pref ); if ("userChoice" in m) { // отображение значения +' - "'+val+'"'; try {var usrChc = (val.toString() === m.userChoice)} catch(e) {usrChc = false}; mItem.setAttribute('user-choice', usrChc); usrChc ? mItem.style.removeProperty('color') : mItem.style.setProperty('color', 'orangered', 'important'); } } if (subMenu) { for (var smitem of subMenu.getElementsByTagName('menuitem')) { var smval = smitem.getAttribute('tooltiptext'); smitem.setAttribute('checked', (val === smval) ? true : false); } } if (m.nodeName === "menu") { var vname; try { vname = subMenu.getElementsByAttribute('checked', 'true')[0].getAttribute('label'); } catch(e) { if (!Services.prefs.prefHasUserValue(m.pref)) vname = 'Default'; else vname = 'Other'; } mItem.setAttribute('label', ( mItem.hasAttribute('name') ? mItem.getAttribute('name') : m.pref ) +' - "'+ vname +'"'); mItem.setAttribute('tooltiptext', val || 'This preferences has null value or does not exist.'); if ("userChoice" in m) { var smUsrChc = (val === m.userChoice.toString()); mItem.setAttribute('user-choice', smUsrChc); smUsrChc ? mItem.style.removeProperty('color') : mItem.style.setProperty('color', 'orangered', 'important'); } } if ("userChoice" in m) { var hasNotUserChoice = menuNew.getElementsByAttribute('user-choice', 'false')[0]; custombuttons.setPrefs(s, hasNotUserChoice ? true : false); } }, 0) }, false, menuNew) } }; // End CreateMenu // Конвертировать текст в юникод ............. function convertFromUnicode(charset,str) {var converter=Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); converter.charset=charset;str=converter.ConvertFromUnicode(str);return str+converter.Finish();}; var switchOffProxy = { // Переключать на режим 'Без прокси' при закрытии браузера если это разрешено в 'about:config' observe: function(subject, topic, data) { if ( data == "shutdown" && cbu.getPrefs("CB.Proxy.reset") ) cbu.setPrefs("network.proxy.type",0); } }; Services.obs.addObserver(switchOffProxy, "quit-application", false); // nodeName: checkbox - для логических(boolean) параметров, menu - для целых(integer) и строковых(string). menuseparator - для разделителя. // pref - параметр about:config. // Параметры имеющие значения отличные от дефолтных - выделены жирным стилем текста. // restart (задавать с пустым значением. т.е., restart: "") - перезапуск браузера (с подтверждением в диалоговом окне) после изменения параметра. // key - задает accesskey - клавиши для быстрой навигации по меню. // userChoice - задает предпочитаемое значение и если текущее значение с ним не совпадает, пункт меню/название меню помечаются красным цветом. // Также можно установить предупреждающую иконку для таких пунктов. См. стиль в посте ккнопки. А также меняется иконка самой кнопки (см. выше). // strValues - значения и отображаемое в меню название значения. Задавать для целых(integer) и строковых(string) параметров. // Задается в виде: значение,,,название,,,accesskey|||значение2,,,название2,,,accesskey2|||значение3,,,название3 и т.д. (accesskey - задается опционально) // Полное значение отображается в подсказках, при наведении на название подменю/пункт подменю. // Для логических(boolean) - отображается сразу после самого параметра (значение true - также ставит галочку для него). // ЛКМ по пунктам меню - переключает значения для логических(boolean) параметров, // любая кнопка по пунктам в субменю - задает это значение для целых(integer) и строковых(string) параметров. // Клавиатура: Enter - переключение параметра. // Alt + M - открыть меню кнопки. (Сочетание можно сменить на свое. См. в конце кода) // ПКМ по пунктам меню и названию субменю - сбрасывает значение параметра в дефолтное (сейчас перехватывается кликом по кнопке). // Спецклавиша вызова контекстного меню / Shift+Enter - сброс в дефолтное значение (убрал это действие). // Настройка функций кликов мыши для кнопки, учитывая долгое нажатие var longPress = false; // долгое нажатие function handleEvent(event) { switch(event.type) { case"mouseover": // можно обновлять tooltip кнопки 0 // this.setAttribute('Popup.state', menuPopup.state); // состояние меню: открыто/скрыто // this.setAttribute('menuContext.state', menuContext.state); // состояние меню: открыто/скрыто break; case"mousedown": self.timer = setTimeout(()=> { // удержание if ( event.target.localName == "menuitem" ) return; longPress = true; // блокировка обычных кликов if ( event.button == 0 ) { // ЛКм Long window.switch_tab_url('about:config'); } else if ( event.button == 2 ) { // ПКм Long // setPathToDownloadFolder(); window.switch_tab_url('about:preferences#content'); } else if ( event.button == 1 ) { // СКм Long 0 } }, 500 ); break; case"mouseup": // отжатие кнопки clearTimeout(self.timer); // сброс таймера долгих нажатий if ( longPress ) { longPress = false } // выполнялась команда долгих нажатий, сброс флага и выход else if ( event.button == 0 ) { // ЛКм if ( /open|showing/.test(this.getAttribute('Popup.state')) || /open|showing/.test(this.getAttribute('menuContext.state')) ) {// показать/скрыть меню, замена функции this._handleClick menuPopup.hidePopup(); menuContext.hidePopup() } else menuPopup.openPopup(this,'after_start'); if ( !/open|showing/.test(this.getAttribute('menuContext.state')) ) // показать/скрыть меню, замена функции this._handleClick this.setAttribute('Popup.state', menuPopup.state); // видимость Popup. выполнить также на "mouseover" ( или один раз глобально в конце handleEvent) this.setAttribute('menuContext.state', menuContext.state); // видимость Popup. выполнить также на "mouseover" ( или один раз глобально в конце handleEvent) } else if ( event.button == 2 && !event.altKey && !event.metaKey) { // ПКм if ( event.ctrlKey && event.shiftKey ) { // +Ctrl +Shift var host = gURLBar.inputField; var str = 'host ' + host + "\n" + decodeURIComponent(gBrowser.currentURI.spec) + "\n" + '+1 '+ window.Title(33) + "\n" + '=0 '+ window.Title(0) + "\n" + '-1 '+ decodeURIComponent(window.Title(-1)) + "\n"; // URLBarInput.value + '/n'; // gURLBar.mInputField; // window.show_tooltip(0, '', str, 5000); } if ( event.ctrlKey) { // +Ctrl // window.SavSnapshot(); var info = custombuttons.cbService.readFromClipboard(); // info = document.getElementById('tabbrowser-tabs').clientWidth; // info = gBrowser.tabs.clientWidth; window.statusTextField(info); } else if ( event.shiftKey) { // +Shift window.PathToDownloadFolder("/home"); } else { // window.switch_tab_url('about:config'); if (/open|showing/.test(this.getAttribute('menuContext.state'))) // показать/скрыть меню, замена функции this._handleClick menuContext.hidePopup() else menuContext.openPopup(this,'after_start'); this.setAttribute('menuContext.state', menuContext.state); // видимость Popup. выполнить также на "mouseover" ( или один раз глобально в конце handleEvent) } event.preventDefault(); event.stopPropagation(); } else if ( event.button == 1 ) { // СКм custombuttons.editButton(this); // Редактировать кнопку… } break; case"DOMMouseScroll": // ролик мыши над кнопкой event.detail > 0 ? FullZoom.reduce() : FullZoom.enlarge(); break; case"contextmenu": // ПКм+Alt или Meta откроет контекстное меню menuContext.hidePopup(); if(!event.altKey && !event.metaKey) event.preventDefault(); // event.stopPropagation(); // break; } // команды при выполнении любых событий }; // var this_event = ["mousedown", "mouseup", "mouseover", "contextmenu", "draggesture", "DOMMouseScroll"] var this_event = ["mousedown", "mouseup", "mouseover", "draggesture", "DOMMouseScroll"] .forEach((type)=> this.addEventListener(type, handleEvent, false)); // Горячие клавиши: действия. коды: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Constants_for_keyCode_value addEventListener("keyup", (e)=>{ if (e.altKey && !e.shiftKey && !e.ctrlKey && e.keyCode==77){ // сочетание клавиш Alt+M e.preventDefault();e.stopPropagation(); menuPopup.showPopup(this,-1,-1,"popup","bottomleft","topleft"); } }, false,window); // Блокировать контекстное меню при клике ПКМ, +Ctrl, +Shift this.oncontextmenu = function(e) { if(e.button == 2 && !e.altKey && !e.metaKey) { e.preventDefault(); e.stopPropagation(); } }; // Листенер позволяющий сброс параметров с субменю по Shift + Enter // За код спасибо Dumby // addEventListener("popupshown", { // handleEvent: function(e) { // this[e.type](e); // }, // popupshown: function(e) { // if (e.target != menuPopup) return; // menuPopup.addEventListener("popuphidden", this, false); // window.addEventListener("keydown", this, true); // }, // popuphidden: function(e) { // if (e.target != menuPopup) return; // menuPopup.removeEventListener("popuphidden", this, false); // window.removeEventListener("keydown", this, true); // }, // popupshowing: function(e) { // e.target.parentNode.removeEventListener("popupshowing", this, false); // e.preventDefault(); // }, // get old() { // delete this.old; // this.e = new MouseEvent("contextmenu", {}); // return this.old = parseInt(Services.appinfo.platformVersion) < 25; // }, // get prop() { // delete this.prop; // if ("key" in KeyboardEvent.prototype) this.prop = "key", this.val = "Enter"; // else this.prop = "keyCode", this.val = KeyboardEvent.DOM_VK_RETURN; // return this.prop; // }, // keydown: function(e) { // if (!e.shiftKey || e.ctrlKey || e.altKey || e[this.prop] != this.val) return; // var target = menuPopup.querySelector("menu[_moz-menuactive]:not([open])"); // if (!target) return; // this.old ? target.addEventListener("popupshowing", this, false) : e.stopPropagation(); // target.dispatchEvent(this.e); // menuPopup.dispatchEvent(this.e); // } // }, false, menuPopup); // pref:"network.proxy.autoconfig_url", refresh:"", userChoice:"https://antizapret.prostovpn.org/proxy.pac", strValues:"https://antizapret.prostovpn.org/proxy.pac,,,АнтиЗапрет,,,1|||file:///etc/proxy.pac,,,.pac файл,,,2|||https://git.io/ac-anticensority-pac,,,ac-anticensority,,,3"}, //https://rebrand.ly/ac-anticensority // {nodeName:"checkbox", pref:"xpinstall.signatures.required"}, //Check is compatibility // {nodeName:"checkbox", pref:"browser.bookmarks.autoExportHTML"}, //BookmarksHtml [false=places.sqlite] // {nodeName: "menu", pref: "CB.TEST", key: 't', userChoice: "C:\\Downloads\\TEST1", strValues: "C:\\Downloads\\TEST1,,,TEST1,,,1|||C:\\Downloads\\TEST2,,,TEST2,,,2"}, // var mPrefs = "network.proxy.autoconfig_url"; // }, 100); // window.statusTextField(gBrowser.docShell.charset +' '+ m.value +'_'+ decodeURIComponent(window.hostname())); // tmp = (self.image == imgFlashToPlayer || self.image == imgFlashMinimize || self.image == imgFlashMaximize); // if(m.value.substring(0,9)=='videotopl') // self.image = tmp ? imgFlashToPlayer : imgHTML5ToPlayer; // Menu_n_TooltipTxts.forEach((m) => { // // window.show_tooltip(0, '', m, 5000); // var mItem = document.createXULElement("menuitem"); // if("radio" in m) { // // 0 // // l = l + ( cbu.getPrefs(mPrefs) == m.value ) + '\n'; // mItem.setAttribute('checked', cbu.getPrefs(mPrefs) == m.value); // } // // menuContext.appendChild(mItem); // }); // mItem.getAttribute('name') // mItem.setAttribute("type", "radio"); // mItem.setAttribute('label', ( mItem.hasAttribute('name') ? mItem.getAttribute('name') : m.pref ) +' - "'+ vname +'"'); // mItem.setAttribute('tooltiptext', val || 'This preferences has null value or does not exist.'); // {nodeName:"checkbox", name:"Загружать графику", radio:"", pref:"permissions.default.image", refresh:"", userChoice:1, strValues:"1,,,On"}, // {nodeName:"checkbox", name:"не Загружать графику", radio:"", pref:"permissions.default.image", refresh:"", strValues:"2,,,Off"}, Код привёл, потому что тут на форуме было много вариаций, а мне нравится именно эта. Обычно у меня всегда включен по умолчанию Автонастройка - Антизапрет, и до этого никакие сайты на это не ругались. Но сегодня (вчера ещё всё было в порядке) forum.ru-board.com выдал: "Прокси-сервер отказывается принимать соединения". Поскольку ничего другогоу меня подключено не было, я отключил антизапрет, и форум загрузился. Почему он стал реагировать на кнопку, и можно ли это как-то поправить? Захожу часто, постоянно включать-отключать не радует. |
Dobrov > 19-08-2022 02:21:38 |
kazarin - Антизапрет переодически не работает на некоторых сайтах - флибуста и прочие. в моём профиле (в шапке темы) переключение прокси делается проще: долгий клик по Замку или кнопке Quick toggle. |
kazarin > 19-08-2022 23:37:17 |
Dobrov |
Dumby > 27-08-2022 17:52:45 |
egorsemenov06 скрытый текст Выделить код Код:… scriptsbackground: [ // В фоне [System Principal] … { path: "long_left_click/startup.js" }, Настройки — about:llc скрытый текст Выделить код Код:data:application/x-zip-compressed;base64,UEsDBBQAAgAIAPzuQwCbaREKbAgAADcnAAAkAAAAbG9uZ19sZWZ0X2NsaWNrL0xMQ1dpbkFjdG9yQ2hpbGQubWpz7Rrvc+I29jP5K7y+TmO31KS9uS9k0t6WMNvcZbOZDdv2Jk1ZYwvQRpYYScCmCf9735NsIxtDyN3t3M5N+AC23k+9X3rPZhFLr//t0dU7TZnyTjxOlt6lFB/vgvtV27s/aE2IDrSctD0eZyTEldYCaOaSAbYviRJzmZBupzORpJOJdM6I6pQcI/8YCLS88+6RinycAVVvKkVGLJxmMyF1/+q1oQyQ7deer+5UlH1Qfni8AvIk1snUu99GXBB9UFlOIImeS+4F7saAOirvw2vczU00ojxdY4Wg6+pgBT+oK5swndwCpTUCMNCviP5RxjyZBtYQKWFEE09PqYpc8PFahw0YMLwickEToqKZJGMVTUquPiASrqjgKmKCT4aMjPUwYTS5jXyjXdvqomlGeoIDsm5QxYHWNXFAoMiGcqjLGdeXoFfgO7gV4YTHI0bOsnhCVJMhHPCGIRzYNvk/CsGsAi52RQOAEimJbJBegOqSi/XHpRaY1T1/TNg8JekgnjTu2QFvOn8NyxPsCnLq2qd8Ntd+29egSyxJDJcKeCa4JmYaosC/cXUYxcntRIo5T3uNbq/A61pUgI8boYJesQQHooHozcFEXDcrUkep61KHP65OnaLQaHV8cACJDUXAS1islHd+3vuF8peJFrI3pSz1TEalyvvHFaynYumAQO0EMk3LOa7l+1DzGcaVqVo2bjKxID1MQXTenLESxFiCKYIh1Uuu/b9n4g/KWBwJOekYwPG3/k2UgGc1OQM5sC0S9GjE1dkAwbbctFKanhLQQtzlKtTl/hBZfVwTF7ItC0kSQhfkNVEKciXI1MRyKuogXrd8xzZdN7e7Hgg++d5QlFJs9auXklZrcx22DwKjNNaxWTZ4GC01kZVs3iWzXkBKobXqUUql2cTi0bEXNOCGBpg7jfJbIc+ySRF0w3LF8iBMkZ34NYKGnULo7ths7pRtm23gV1akXVZzC19pMafqldaCtW2Cqlm/S9pGrSlF1gtNKdcAtkneSPBdwpvqSym/obiUKiBsrcEqvEaI6QTyHINcEjPCz8HDARcpaWOfY77Q6evuB2x4xscirwhtbyYpT+gsZk6NwGCsELZgD14qEsQB3pFYciJPRTLPiuxCEn03I2Js+ytosMToA54I3pdf4lIUc5r9HLOcoW2sbLTahqxsLaiA3S7fvT0LHLJ2rm4DFugFHlIErsMwUjOSWKuuPNN9BaQQmcdvDj0ovpzUK4KuQUlmD++millQfUPBsNsr59scDc0fWiWMbHvV+mnw+vwlHB9C9hlBu0ZUlRzQ6qH38ODigoz9MDEmtmFatPwHDDSOKKf6F6qnOYVFy9VdV5gKahEJ6IoCdR1n645aEUljRv8grikCwAw3PeatHbT2ghusDWwvC7CJCVS8XLESXAHIepUH+4v6wRV661gxMAVH8Ut1x5PipKrUgEzMFYEjmvsweGCqdrclfNvDrOra5ISdd4uEdDKxu75c5aldFu48t8lC2xjddW7sc2oUHt3rxKgiOapYJYd7aen0lNE0VgYVRoYkZhc4prmWx3plRoicHcvwApS7QJr+ef91/2IwvHhz2m97S8or1ekVE6OYVbjgKFUW5rrHbaNio6GU6SrTIjj0LMCNp2Qcz5nOKUiktJjB4DmLJzG2vpX1sywjKYVisImwR1wZRTCmzAnUbTzCTIi0VvgFNojiNO2jkudUwVEODaFfMDG/bQ+aRrKtSXQOLuRlgXuy29V0ropTBSICImAGYKrfSDqhPGaDWELb8YPJ1wEcIXB45B4e9H+17s3rcSryOoCsjKtLmhdAk8dH6EFvrCmfk+Mqcoa5D4Of34353TcYrH5Yng2bWNdTSM2Tw78c3rTN5e8nhx/iRawSSWe666yCyaEZhxW/Er3wKQMJE0oWCllL1U5rIxsZuiZtOrK8JYwAxCpbRPyYxRrdkw4kIZcx1pqLsmyvWRTlrmq6E9d09wf7WuxTGKzZXvuby+G1at4INNzXSiY3XS5gkIWrk8PDm3C9Kzzmh45pLd8nmHwjnvYJ0T1j9NME6bYofUqYVuLU2j7/3selQ8vb/ETgkx3evPr51bZW5tmFn8iF5kwEwzfbflgxvrG+WmAHMVwfxmtKx1iAVfSdhbtgyek0S5vlviuwhnt5r4yXnWoXuK0RtNO3hSlWjrMe3/lWw6EtEib4Wmlzh2oGjunNInQC+qXWko7mGrqAjxnjCk5Zf6r1rNvpLJfLaPlXM258d3R01AFL+Tm5mc1gRgQhhtO1L4CFxM7fvzmuzzE5JuEJaAEjU09kMyCC5v39F/cIXL1v6MafnMvvkVWXYjOKun4N+2nX+Del96/vzhsMjV2DqHQLZbw9p/W/ndZN9seg6cUc1Hyusp/FQQljQ0YVifBtFVuQIIz0lPDAfcK06zDV4hRS7t3b8yAssnpL9qE/RzCVllNQMLLPZXAQgIzDOgFlJb3SdywPBWcOMVNnGMHUisOdCg6BNvAPbXl9ePAeZQaVrtuNxxpfXvzX+Y7IWEiyF+Pn8P7f94HoUwj4GYuh6HR+j76C+98C/8H/LYy++qIzAZ/6YXMYr/J5v4jkJzvsKe76vxqTntP9Od0//3Rfd+l5tuNjx9pzx+dHjs+PHHPtigeGn21Vd6bO/7So11LjiY8JgWYa85RZ0wdOEkETaQ3m+eY1x3xmXultmB4tisYPveY4t7xgutWCb7xeKf4UECU4aTCXoirdvGTx4CiAWJ/Ssf4nubN3MVtfJ1oyuKnndW4KgOPMq7Ag4CxpaarzpV3T5rpQ5UU9PZ0S4/6p4Hvvb0fO+5diZ8XLsl7MGGZT3sM3v1MJ2w1/Y2h7zl8wosG/LvvDNxf94dVPbwbh9nc5JUv7F7GDPwFQSwMEFAACAAgA/O5DAIJwvCtuAgAATgUAACUAAABsb25nX2xlZnRfY2xpY2svTExDV2luQWN0b3JQYXJlbnQubWpzfVNNaxsxED3bv0LJIexSI5qrjWsaE0pKAiFOyCGEopVmN8JayUjyR9r4v2ekXa3XrakPizUz782bL9itjPWEK+Ycub2dP0v9nXtj75kF7QnsPGjhyM8FOoTZ9n1/hgMLHOQG7sA5VkFWuyoP5kEWPoPzHt+4NmsHyKDPxyTLyfRbDBwMNsySwpqtA0umxL9JR+NT6mputEcB1JsVhboAIcBeK6gx+SRiZUmysxacRwsq8murJx21YJ4hLyqj4e/BsZUa7S2Yoi6wP5QpmBqR6qrTg1E0PSfDDiwF+pKdOlDAPYhHVlAs0ra6b0STrTQ2ixmJKSNhi2s6+mgZXwYFFqsD0RhdW00ocIv1G1UwSzfSyUJBThKjD4wYkJTMqGeFIx8f5OU1bykih6dK6iWILo6vbZjh08PNjLoVcDKdxlbFOHJxQfxxJcEvRd7ODH9xUJgtzGySjIUFtkyv/bCLe2PuevcYg6+wFmA6S/i87WrHN5v1OstEaGrWKRslARZKwArsjS7NuFGOJjKL/b2+/Lp48lI5KgBZJFPyNzz0EFkC5GRM9FqpUdtuLWDX0mmsG/lODvmXvzeOfCGXx3BvZVVhPl3d44fLFVMt2Sq9/6ewA2XHmCByAXYjOTjquJUrvwAcoPTvd0zj3VlagV+8Ow/1gaMZ/z6P49iP/rlHriRf/nWL8Z7SqdACF7OKu5Bmc4ZbEOoNG3Y02G4x4lay4jkeV8L1r2tyiNsegk5c/PzNmhqac2hBDTE9NZJetqPgsLchTxDcoEvD1y5r2tLf0WaXQ3WTk4tbMuWgaeYw9PUl9EmzGl5nNNLth/vhJ1BLAwQUAAIACAD87kMAtc5ulGsEAAB3EwAAGwAAAGxvbmdfbGVmdF9jbGljay9vcHRpb25zLmNzc7VY667iNhD+DU/hgiqBFtOEPSxnU7Xqe1T94SQO8Z4kjmyHc6l4906cu+MEOKsShMBzn/nsGROrNEH/LhcRz5SHUiolOVPs8zf0C0tzLhTJ1O/LRUrEmWUecobLOQlDlp1H6ynLcEzZOQadruP8OqS+slDFFsJ16fPwvfOGZTEVTBkmuWSKcfBF0IQodqFj07WBJ4emZhhvc8QmRlIoPhGoa0r5JHg5C15koYcynhneBDzhYiISSDKW7EOr9bkIqRjl/bpkWV6oMiWNd1/zt4fVzOTzugzZZV8GkJdSPUMHMOQYvAnxqYZLyGSekHcPRQk1bcEKDpmgQV0m/jpkIAk7Z5gpmkoPBTRTVAwZCgkxSJqABktOr8uI0SSUVKelitjKVgXGwoG/emFgrVzB4AzQFcVQsCLNwLESRwGkDfyz4GEoRAQlILIiyF+hVYCC1YMR/yikYtF7Y9BDUhGhbFDQEbWg0G6U1j1EbKXS3G3Retz+REq1QD+/PZlg3h8v42rjBTENXmi4RV+Q6cEXNGmF5yRgCsqzP5q7nZXZwvQCaZHWMv+V0pARtIm4CGiI9Y6rObel7rg+4QY7dR09wXMaGmt269p9hsc3iBhfcL2/aj5x9snG2aH6vT8ctw2jzsiAHVMhtBANDabWrUbvOtKveTYc8aCQI2a/UIpnFqWms07n7IQMjvmFWiTdm4IkKM9li2RnM4bmkJQNwha/45ye6PNt1sbDtXt69rsczAg0noGJ43ebCXsJZCB4kvikLf2FiM28qW1Px3W5aFCaCxpRIWt3JGyXFNwJiXjRYO3QOoTr4Ss8xsHV4TU6wUNM6hiw6ycHHtJSJwHo+q5/ON7gaxFocM9D8HA87lD30QLxbiSOFLh3KBggcqyhU/C5Sjv6VSq56mqXVdyhZppZdErr4UPFLDPKNWnYIGyHcmCs7QYLnPIPTPKcEkGygNoGksU8uVH3t3rP6R+rrEh9Klb/2LUr+qb0KT5jYoLnWrbk4dyx4IVKWAYyLkwekifQqJsc9GFsJKARwzyKoJt4CLvmhATG9mVnhTxKbWl+wFjUIxBYBTClHjrNKvwT9TNWAbDO2N0QqgBuRlZObfi1HqN9PspzUAhZ6q+bpEGdH0ynB6eG1IZf5jOE7zS0pqkcmI9mhiZvBovmWjCeqYa3hv3RnLQXuswdw2HM0ULIiuxbNfP0gba7g1GXqxoq+rnCUr0nYL0C78Pmq1OuOqoexE8ltJ0r5Lxztl2/Gy7r0Q42aw3uBkCP7dZbqBw1jUapvQdtZ+QTlk/fiGZvZr3rHgR3GIH7TgwfxpL6shaTkL/O7TxBQlZ2VucheNtK2ELaXsiK3AfyA13v5ypXTQ/b+6LwqsMa7pPGJP95fycF57qsfScMzq1vk2ixkJp/Qr7df3724hIU+qzuYPXXadbuXxPb9bPPKdkHtXk0mYLmyvc/o+hTOlhKzhBNIZLNSl7OvzVe7+HH6k7s6bGnYADjC0nYXJhTl76RoevyP1BLAwQUAAIACAD87kMA3jpxtAIBAADVAQAAGgAAAGxvbmdfbGVmdF9jbGljay9vcHRpb25zLmpzbZDRToQwEEWf26+YND60ydoP0KDZPzDxkZBs7Q66WaBYCpFs+HdnKK6a7ANhOvTew7361PVjGqB4gosUk4twdMlBAX3EerDvmF5o0FKIfNG2rtfryJJ1sKwYMFmWGCnMoxR1iJrNSt7tYHJNBaFevQ2DVtJmA8fgxxa7ZD9HjPMrNugT6Q8lX79nh0LdXfi9qOrA9vlnyoxPc49QFKD8B/rzW/hS8Lwd8KjgARThR1QVoWgi+ZKTUhRaXcOUP77/Au2u25uc/GmDESufV6AUFbEGNyG10drQ+ebkz0TUhnG54GEr+E+79BgKKRej9zG62dYxtPp2Sfum0eq3p0oZln4DUEsDBBQAAgAIAPzuQwAUBTKeYgMAACcMAAAdAAAAbG9uZ19sZWZ0X2NsaWNrL29wdGlvbnMueGh0bWzVVsFuEzEQPTdfYfkEUpsFcWmrTSpUCQmpCAnKufLuOolVrx15vUl6a2kRQkWtxIUbiD9IAykhDeUXvH/E2LuBJC2iAVTRSKt4PeOZ957Hs/bXOjFHLaoSJkUF3y3fwYiKUEZM1Cv42eaDpWW8Vi2V/IYGP/AVSQU3tG6uel673S6375Wlqnt3V1ZWvI71wdXSgt+gJIL/BT+mmqCwQVRCdQWnuraMPWfQTHNaNe9NN9s1XTMy/ex5tpsdog0p6miD1jRa5yzc9r3cE4J6RVQ/kNGOCxKxFgo5SQBSKIVWkic2PViYaKYa6Z0mreAg1VoKjFhUwQlp0ZpUMUYtwlMwmg/mPHvhMHw1A8DwGsGgm+1ZOObcfDFDMygwe5BvNm9dsWgqp81CBQk4XQdIVGg86ep8cAEsbNBwO5AdjCKiyVJT0Rqs7cAiuxlJmYMUWxyk2AqtFOXpsF6elZOA8skUbgIjYDkLpOonTSKq5g1wOsuOspcFYWw+AdMz89EMzBeMrBVGQwTTZ9kxAi32skOYOzdD33MhfM9lyRHUGOUR7O8kiPFcLs0MSg0cl3IlcvP0fok0DqjCKGZQkFCOMelU8Mr4h1Gidzi4tVmkG6vLNL6qfJrFM+JB4kIR2Ou+GVmy+8C6D6+nRUUcI9NDcVIQz9lMsC+oXcZj3u0NSLhdVzIV0fpFhO+y52ZoD4jpQXW6Mu2h7AD25Cs8PVupMOO2rgsMhqZ/DYgF2DbleqoUaHol0PBy7KptBGWFwNwHh/3sFfzP4AdC18AA7BTQq8uQf3NdoWfPQIEdCuPAFQc81wAuP70PY1KnyQWA5sTBO3HCTlRFcXjNAJlv5hzB+DNomTufgsyups3oV/B9b3x0/6jlNZSM6T/veHnUORpevuAP+x0I1v1RiNDzFkFE+z2AD8Uu+A1ufA+clPO/bYHxDeyA8c1rgCGXCX1ERXqhw7y1p2Ba75HtH9mR6yzZHiDt/+w33Xk7yoTHbwkESrYTqsqaBEmZCRjqJ5QTTaP7NU1Vof+4QzgcV1uCbpFApnoVro81Vr/9k8MEg79FOg/EObH5XnEX9pNQsaauPqWqxUKalCWEFFKz2s7jAALbC/6tNhORbC8ibIvA1oArAQc8N+FFJFLObao8XAku3XCnr5a+A1BLAwQUAAIACAD87kMAraNUZx8NAACWLQAAGQAAAGxvbmdfbGVmdF9jbGljay9wYXJlbnQuanPFGl1z28bxmfoVED3TgFMKTh7yQk3iyoxss5VlVaLiZDQe5gicSFggjr07iGYczrTpTDud6bTvfelfSB/cpk2b/gXqH3X3PoADCFKUW6cPooC73b29vf0+XBPufXL4aHDeHfQ+8T7yzii/jkMqAhHyeCrPaJjxWM6fkpSMKA8A9OD8qD84Pzs8HXSfHfcPP+sD4v7ONdA5OQVCD08PjrtPgFKTvpI0FTFLRZCwdDRI6KUchEkcXgXNtseGL2kon5IpgKZ05sGT39J0KtAA8HqnMZhyeik6XpolSRteZTyh3TFnE9rxPnz/fRwakvBqxFmWRt1Jx7skiaA4nAIjfdbNOKepxBnJMzURJkzQpzTNhANNUzJMcsoW1IyyFLYk82GepWmcjhSXBYk4jaXfQp4buJshJ2k4dkWrdhKMqPyEXpIskQ8VhO+IDwTRaGjEQFD5kLHkBJD8pssdCBH5uA1W81wP3EulhlXSzCFBnhsB7fKrcMXq7mEAqBLONsCKgc3QlQO9TQ5l8HWiKODhhwIs306+vQkYhrgNtlC10u5QP7Rig37IcSyC/G1VW9aoiUZzFQOwBwVWve44qMWRlhDrjtzBcs93zYIlFXBQK+e3Brt6yg6BQpprcB1xK7T40vNLctKqvllQxhxaLSCgF+Z0FAtJ+fM4jdjsIJSMo8+C+cppkSh6NhQwRrl7Xm11xsjRAr1HHTXlNiSfq/8F2ZghiyecSRay5AlJowRIg6oKlvEQDgahG8HPM8rncHCUX5KQ+t04SEXvlIoKooEGDT3LhkLGMpPgpv1mxfGCqroMgJc+P+35Icjl8JUM7Nrnp0ctJeSGVpJzGSf1omoeHXXhXb0AbbXDxhUAdLzmT88cyGZbTU0JV95WAzaoeMqiLIEFe4Bgl+/cv19h+76zzIkiEUxeCkNzof+F4ziJ/ivKXaTgEG7Qa1hJ5DQbE5YJCjtKYcgLyVRm3AQUzzBhYLLpBoiIk5GQhMsNMIImEEpvgVqU9k+S5BEnEyryWIbcUCHAmZlY/xgsdwrzF80hZzNQZtF8oeAW5rQzIdkk/hJt5bwXhJwSSZ/HEeipr2UQ48Eme0p0Yi9GR7k3hR8jsYQMaQIQyz8tv1t+u/zH8ltv+e/l9x48/235/fIvN79cfrP86/LN8l/Lb2/+uPynQZNgpxJSE3APiPzn5RsAfAPo39384ea3APr1ze89fN2GpgcP33g3XyOBm1/f/A7+/927+RXQQEAE+s3yjeWXhSSJv6RREerxgHQMP4Dtd7yKTA5ODw8GxwefPjw41cBizGa99ITH1yCrhyhWSB86njWpaXniIEnYjEbeV1+5C7K0q0Qd+UOZtqy6wXMg5DyhaNVg7lPK5RwsGoxwT41r+YPZvZfxxN+k5OJ6pMb0wQXw2my91/aa8WTKuCToEvddXQKG2GQCnsWnOTvocKtJn5sttTxOQUlTTaixCRQjI6iogcSIOYtTGKTBdUxnZhiGgtFDraeBtgca2fehkafy6CDmUMcU7XAeJ2xIEvSuNU5KO0r0lGmkfGtpugNIpSSgFcgxTX2wRAmx9OPcFVS3h+SeamPrMzhlH9gHAbukK8nF63gCerKrKC+cXGML4SnVMbALe3KFHS/AX0hIK/DsvIWOTFm6RWxyvX09QlmUdU4jokJyNjdeo9ZXaLz/eyDEsmOtvMAvJM9jOT4k4VgLwL/M0lAL7JJxsAUqldqyy9zYZwrQFlaof6AILWNBuZQbSAj1w8C3kUwQR1osLjM6rkG1xcAJQAILB2B0BE/bcMp0VuKLTJVfoElsGodtD9MWTUP77k3Fm5MPdjzQilzRa9JJJ6fdmFMaX3LrsiYnq1m35gyUn8itUEFtYXnlUug1vnY278Mmirl1bbulUoJcJ8tKkl3hYlOmfbfV37FIq+XdazXQ2Wo/byXYau1QJ9vVKmQtO7WlyJ3ZeMdCrilzX6cqSdpyX28l6bxYfpdbcyry1/C8YUc55N13Uoq473I3taF97Y7KCcadd+VUwnVGUKqk1/JQLae3lmZtmFBNj0q/oraJcYtMSvFj7RnpA4CfXuTwoJhgw5ewSt6IxDV8DbhfZLElpkw+CGH0JeyYRHoNPYeoFpFCyuWADrJ0Bfrt1LM+ALoSzTsb9f2O22RqY5nmzhWAnmk5ur6mHVIWgIJck1AWW1+0LpCnFw8C37ZH6i3J1KhtLyKStD2b6ts812276qIVZnZzqAdeqVDIYaDK3VRBvNh38ziDhbmcJWDSL5wNdZEh+uzTWMQo8othfR2iqDZm4zihnl9BCxKajuTYpnWKsHHTGhDoVlGmbGrFj/AjVdggXAnxQV35U5z2rkYzx4xLxKktvpAqwZMDoqONZZOGV7DKIx6IeRqaw/RLR2hAV/aSibEfBEGZ90C1bWBgJa9F84KkjBWOObd5qxDa2vGqAU3rqItWpeVlrTm34MIlCOsS1IWFVU1tzo/Ajov17FJ17iTQCH6FeARaJmnhcpD0Y6ozy5RMHGWW8ymt7QkjbB8mNTySF7MYKgLPRxSjPiERtIqru5LPnh11lPx1NV7XdLYOIl9gPbnecf8WajZv3oLYWf+0d/z4FnpnkoM9lUkajThzBNn2rkmS/ZDyrMyKiiAtQ1r5h5ySqy1Fu0rYlemd6bpSXiVdEe8a6nnTwLn4us3r3ylaG2K1NqcYUL8V9jmdsGu6uQvfKF+5YI2PZriz2N/JLyK1o0A3mhAhkCGssSXP3J4IktFdKUPDBkjkwRKomXqq+7/VSawqeXWQcE7m4DGwUrl4ofhs5F6rygb85ojrEhWDvzKlaKlYUM1ByrmQ08Ircd0NL5o/mbAv4yQhAeOj+2pi/4PmC9Mk7oH8SJq3Zfo4nV+Hudtc2TcG6YiF2QSb+r/AHs+ZitSMY4LwBSrLvZRcxyMCQ3vYKR6yVyq1uifiiA4J37MDEC2zKej4vQmJ0xN8AY+hQU28BlAp2cQiKGqE3yNRtAd/MXaKSLIHyiVj0OQ9mCvBZeHlOjgA+6JVyinU/iChyDdrXM1FM79GgFKhae4L8DG/GACxAhm0IV+7NZsVIhm8iTrEi4kjtMMUDAFhtAW4bUTTC9RaUZetvq1SrEt9YZnB2nVWxFJWhP+VbLQN3k08tQYKm2FTmh7F6ZVPr9teyiIn2CQw3Pb0ZVbbNK+tqVqtt81aWnZ6jgMxqZ0+AqBY6qBTdHq4D/NFgQGmgZBsircBBCwCO5vueG8yoVEM9rgCsLBsTXL/VMuYcV8/OGvoBlYUu2lbteq/c3r10IW6mCcHo8Z5O+UW0qtTnbUMbAoGi7URYZsVN21ic5xZ2Gtx1NVAXW0dE6y6P/KaklNqM+2mU9rgOJJADK3Ox/AI+6VJom5pKMUcqguvBxIMIQBBANBnbS9//rxQFcQKwNPiknsf4CWXGlELHyZSczKDrc6bJYVCThSaXhAvgQJk6RHjfRjopRF9lRMvloOXQPsAiFAq7hyT6ydAnvH5KRWgmbiZ4PTwDL9v6n9+cjg4P+3pOgiVGtZDEhmP9S0AVrjeGgFCeMpiSSdN3FWdgHWIGGYQX3IJ57QG04RAHoPsPHgblm3NqJmukrQ7sNfr3uqJmquF8g4H43g0TuBP1i6QzwL9ZCv6uRR38gx/f8fxIig7/B8oTy4wUfSbL8k10V+mdUBuALG7quWFthgvRl+hwUR9MjQx11e3iBhY0LJMka/jUJ+T8ApqdcYjyqkJTqJlDwh0SJ8d6J2IIey1PEtPIj0AsE0EODsyFMjjxQv9DYn+DCXATeWthbwch5N7EIgpDfG01f5/9CMPpAkwpvrtRTiVf6yX37UW20ObMB2oIvdXklYMKgAHGlgrdT3AScKwr+OV1kk0po63EvKrvfMHnl/bPwFywUCeMOH92Pug5eVf7+EFVzwaUV1exGkYT0nSue3jQyz45sD8JEfxWyb9N4pT3txqquLekxj5Gck812EZ+IV0gnKnLaIna/emMXIXY8jsqjzVaqEhDnlImAkTwyy7u8ZEanktmq6u+9PJgtO0LTrQimKKxNBpgDIqVpq631D2oQjazH1S0wOuU7fXBFNIunBbRYNITRU+rExXO7EAi0UxJfhtUE8Bj6Wcdu7fn81mgVsYXNH5hGB9eB9CPL2idAqPcgyGF4BRszSZB6+ypImWkK+LvlXl7sq52tGaEZLSxHy81WikwRjyf5Xm2x5ZIUXguHBOTmsJnxwoDWOS17G6QFbh2N6+KgXUDhvlbmOz495X8oDdj3REbnkb0r2aOF6LV8rGFjlDOsrUV2tQgkMdlvj5R3JV/lVyjWKFvGwcX8qf0bl+I0nxHEqewEtVTdHrq+80QjaZghTBYjiYsMZhYP8x1EXumFTPeRDQWXSZJnINNFeMpbhPzj/3Q8iPvQ/fLz7f01vGLgUGky5JEvQHvk60FESRxZskvq1WbHtOpRqoQPvs+HBw9uRZX0nORrF6Gm5RVW6PrKmMFjv/AVBLAwQUAAIACAD87kMAD+6U+7oEAACrCQAAGgAAAGxvbmdfbGVmdF9jbGljay9zdGFydHVwLmpzjVVdb9s2FH1OfoWgJwqz6bpNGiBBt2Ve2hpwkTZu0AFBENDUtcyGIjWSsusW/u+7l5Q/0iHYHhLR1P0895wrJvzayMxZG7I3v2Y/jo+WwmWrhcCfWa61zC/S1VyLyuPdSHHjx5cz24YPtmw18MvJ5PrLw3R0M/74eWssZLBujeYY8MjAarQQxoBmnHPhKl/E+2iKyd9kU3BLJcFzZfne+q2z9e3N+IsKi4kV5djM7cXWrXXq335ozGInv2T5wDZBWeP5t0WodV7sPO3KgKPK4uF8H8NLp5owBYmxw/qDMKICxysI07UPUH90ykjVCM2KTQzmILTOZCwslD+oGkOztpfpruKCYL2efQUZuPBeVYYZyTDFgUkvFVUUO3wowaaH/zA9dvWWwD/PWAwWJ0HvpAMRYGx8EEbC7nXCngw+teDWYxPA4SUajBaIKNwGpT32hRnR/dOY3eVPJ5rfF8dH1OPI1o01YILndQfH05AssWFndwOV8sEJV3AXj+DepnIYlnMQbvwny3+cnZzB2Wn5uv9qePK6fyJPT/uzlyfD/vzsdDgXL+Hs1ex0kyM6ptWa+sl/r+13pbXg1lUDA2Fl3eOgcTZYafVAUAsXw9+IvW9yJAEdeltAjo8Q1URPVeKQVsoQXPjgM2dXXplqZLGxb4EjAxyW+UWZ0q7eaTsTmmNocOlmXHY0r0WzD8R+rOLbc7roYY5z/GN4LjZFZ49yIuJJTHP1LZxHETROLXEMf3QlXGptV4C+wbXQywaDzEPI1rZ1mVxY5Cm6pDwdQTEKcgTdtvO/dE6s+RwnzUatD7ZW38VMw+2YJz/fo7qLyC4HHiNLuL2ZIDvk3VOAZaRL9+ingbr1xTC/J/pHZSTtdDT463aSGNbRYF1wbHUJLnTEu5mwZxRbFNw3IJF2m+2QtPeHCk/qJMkgC+kxbWfTeIfgou1O+I2g2fGvPu8R4IQ9S8Djf/Q01YOGeXiQWsnHgiujAtsxozUUGm2BoCSHdEOrKA2f4VCBB1QpBB5lmwhS7GLURAoj6hjijg6xEP4OwkcHc0Y3xX1HiQZvfLcnq2RwngnnyBcfqLuG1U1Bw/KdP153+3NuHaMgtDIyO8/iG0o17UyfrJOk6bgCZ9uUeEKAaXdE0gbbKBlZhC/u4q/7SOGovigTcP0StFhD2ce940Lb9OeIoV9AmUfTVFrCmvZbsB1wnSyiUVrHpD1RlldLHNiEtgWiyfKEOE4vHXq4qeN6I0Vs9psxp1HSJOMg+wRkIvhhGfFj1iaRdvyP6y+lbxORFoBLlsSHbJwGXPPVjkzbj4j0RCd0uLz9/P765mH6/urq8/6bopV57JKUVrY1ETBt5ysN9IvlZNJ9hejIcZqXAZPNcK+w3IHG+LlCvTxvtMAW0Wpbm19WA3J4GL7meM73mO5qWIAouWgaMCWjgHuTLe/iMyU80NC27SgiQvMnAkVmkPvdf5MC23p2UqSCLYljTGJxCl7spY9cJJpcJ646hr+3VEX/Z83mrZHURvZ3ixInl0SKJw4OaruEnQ+ZkiH1+/8K+ynA09o22DyF7OMMsHdB5fQrJ/AzU9K8jjcFO/gqInbykc+VBtoR3GvarS96WX/4AhXzD1BLAwQUAAIACAAw7EMAHNCFlXoAAACRAAAAIAAAAGxvbmdfbGVmdF9jbGljay9zdmcvY2hlY2tib3guc3ZnLY1BDsIgFETXcoqf77qFWoMJAncxKQUihab8iN7e2jizmZdMZnR9eXgvKVeDgWhVnLfW+jb2ZfP8IoTgewOhxYmCwUEiBBd9oCNbdtLrgwJU+iRncI4pqVyyu1faytOp83zoj92xogaEyeAywg2uu2UnkVumf0eWfQFQSwMEFAACAAgAMOxDAM0vFhAqAQAA8QEAABwAAABsb25nX2xlZnRfY2xpY2svc3ZnL2ljb24uc3ZndVG7csIwEKzDV9worXzWw0/AFEmTIrQp6AgY7BknMKDB8PdZHaRIEY9m73S7ezpZ8/NlT9ev4fvcqC6E4zRNx3Hk0fPhtE+dMSaFQtHYb0PXKFso6tp+34V7funb8eVwbZQhQ7bAUovJ0/zUbgLFqqKb4D/2EzQe4SbhHG5D26hdPwzTZ//pXLGdqTT2O65D95feyTdTtG3Ukkpt2FhHr5TFzJPTjnNgDrxQThsy2j/2ueBAlutaG3is03H0TFsPIkYjtiSPZCatoEniGRXVQNhWtKRCW3bo5LHfkOMMGvJcoVxLzNiDNvo+AASUWPZSTn75Nyrj3IxmGVew2VpbJw3cfZJ3SSsoCzm2xFU+xFXqCnz9wBJVjyr8XIKzXIh2pQh/cR4fcjH5AVBLAwQUAAIACAAw7EMA8MfWxR4BAADdAQAAHwAAAGxvbmdfbGVmdF9jbGljay9zdmcvaWNvbl8xNi5zdmdtUblywjAQrcNX7CitvNbhEzBNmhShTUEXDNiecRIGNBj+Pk8LKTITF29X+w6t7eX50tH1c/w6N6oP4ThP02maePL8fepSZ4xJoVA0DbvQN8oWivr90PVB+tXsaXnat4GujTKKboL/S+kEjUe5STmH27hv1GEYx/mz3zpX7BYqjXnHj9D/pQ/yLBTtGrWmUhs21tELZbHz5LTjHJgDL5RTS0b7xzkXHMlyXWsDj3XaFmQzbT2IWI3YkjySmURBk8Q7KqqBsG1oTYW27JDkcW7JcQYNea4wrqVm7EEbfV8AAkosexknv/wrlXFvRljGFWy21tZJgLtv8iZtBWUh15Z4lXdxlboCXz+wxNRjCj+X4CwXot0owldcxp+2mv0AUEsDBBQAAgAIADDsQwDEjeTTEQEAALQBAAAiAAAAbG9uZ19sZWZ0X2NsaWNrL3N2Zy9sb25nLWNsaWNrLnN2Z1VRO2+DMBCey684ebYPPwDjBFi6dGjWDtkiQgGJBlSskPz7np1k6PL57nucz3K1Xnu4/UyXtWaD98suTbdtw83g/NunWkqZkoPBNp79UDNVMBi6sR98rJvkrVpOfoDV36euZt/jNO3a+eK7mxeh2QcQ83JqR3//p7zIPYNzzQ5guUSpNLxDFioDmmvMCXPCK+TQguTm2ecRJ1DoHJeUUZqrAlTGlSEhnDLGRB7ELI4ijwh3lOAIKXaEAxRcoaZJhvoWNGbkAYMl0S6eGRqSJX8sQAYQCk2kxUv/ABv2RhqWYUkx5bjScYB+bPIZy5KcRbzW0lO+YsryknT3REusIZbyaElTWETvkUHaJFX4iyb5A1BLAQIUABQAAgAIAPzuQwCbaREKbAgAADcnAAAkAAAAAAAAAAEAgAAAAAAAAABsb25nX2xlZnRfY2xpY2svTExDV2luQWN0b3JDaGlsZC5tanNQSwECFAAUAAIACAD87kMAgnC8K24CAABOBQAAJQAAAAAAAAABAIAAAACuCAAAbG9uZ19sZWZ0X2NsaWNrL0xMQ1dpbkFjdG9yUGFyZW50Lm1qc1BLAQIUABQAAgAIAPzuQwC1zm6UawQAAHcTAAAbAAAAAAAAAAEAgAAAAF8LAABsb25nX2xlZnRfY2xpY2svb3B0aW9ucy5jc3NQSwECFAAUAAIACAD87kMA3jpxtAIBAADVAQAAGgAAAAAAAAABAIAAAAADEAAAbG9uZ19sZWZ0X2NsaWNrL29wdGlvbnMuanNQSwECFAAUAAIACAD87kMAFAUynmIDAAAnDAAAHQAAAAAAAAABAIAAAAA9EQAAbG9uZ19sZWZ0X2NsaWNrL29wdGlvbnMueGh0bWxQSwECFAAUAAIACAD87kMAraNUZx8NAACWLQAAGQAAAAAAAAABAIAAAADaFAAAbG9uZ19sZWZ0X2NsaWNrL3BhcmVudC5qc1BLAQIUABQAAgAIAPzuQwAP7pT7ugQAAKsJAAAaAAAAAAAAAAEAgAAAADAiAABsb25nX2xlZnRfY2xpY2svc3RhcnR1cC5qc1BLAQIUABQAAgAIADDsQwAc0IWVegAAAJEAAAAgAAAAAAAAAAEAgAAAACInAABsb25nX2xlZnRfY2xpY2svc3ZnL2NoZWNrYm94LnN2Z1BLAQIUABQAAgAIADDsQwDNLxYQKgEAAPEBAAAcAAAAAAAAAAEAgAAAANonAABsb25nX2xlZnRfY2xpY2svc3ZnL2ljb24uc3ZnUEsBAhQAFAACAAgAMOxDAPDH1sUeAQAA3QEAAB8AAAAAAAAAAQCAAAAAPikAAGxvbmdfbGVmdF9jbGljay9zdmcvaWNvbl8xNi5zdmdQSwECFAAUAAIACAAw7EMAxI3k0xEBAAC0AQAAIgAAAAAAAAABAIAAAACZKgAAbG9uZ19sZWZ0X2NsaWNrL3N2Zy9sb25nLWNsaWNrLnN2Z1BLBQYAAAAACwALAEUDAADqKwAAAAA= |
kokoss > 27-08-2022 19:27:54 |
Dumby пишет
Интересный вариант, запихнуть расширение в UCF |
Dumby > 28-08-2022 23:50:10 |
egorsemenov06 пишет
В скрипт? Это принципиально? |
kazarin > 02-09-2022 18:52:31 |
Уважаемые форумчане, опять я с вопросом. скрытый текст Выделить код Код:try { CustomizableUI.createWidget({ id: "FFTools", type: "custom", tooltiptext: [ "FFTools" ].join("\n"), onBuild: function(document) { var toolbarbutton_0 = document.createXULElement("toolbarbutton"); toolbarbutton_0.id = this.id; toolbarbutton_0.tooltipText = this.tooltiptext; toolbarbutton_0.label = "FFTools"; toolbarbutton_0.setAttribute("image", "data:image/png;base64,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"); toolbarbutton_0.addEventListener("click", function(event) { (n => { var inBackground = false; var data = [{ lab: "about:config", url: "about:config", img: "chrome://browser/skin/developer.svg" },{ lab: "about:config old", url: "chrome://global/content/config.xhtml", img: "chrome://browser/skin/developer.svg" },{ lab: "about:support", url: "about:support", img: "chrome://global/skin/icons/info.svg" },{ lab: "about:performance", url: "about:performance", img: "chrome://global/skin/icons/performance.svg" },{ lab: "about:memory", url: "about:memory", img: "chrome://global/skin/icons/warning.svg" },{ lab: "about:profiling", url: "about:profiling", img: "chrome://devtools/skin/images/profiler-stopwatch.svg" },,{ lab: "about:debugging", url: "about:debugging#/runtime/this-firefox", img: "chrome://browser/skin/developer.svg" }, null, { lab: "Библиотека", url: "chrome://browser/content/places/places.xhtml", img: "chrome://browser/skin/library.svg" }, { lab: "О сборочной конфигурации", url: "about:buildconfig", img: "chrome://devtools/skin/images/settings.svg" }]; this.type = "menu"; var popup = n("menupopup"), dummy = n("menuitem"); popup.toggleAttribute("context"); dummy.render = () => { dummy.remove(); data.forEach((o, ind) => { if (!o) return popup.append(n("menuseparator")); var menuitem = n("menuitem"); menuitem.setAttribute("label", o.lab || o.url); if (o.img) menuitem.className = "menuitem-iconic", menuitem.setAttribute("image", o.img); menuitem.ind = ind; popup.append(menuitem); }); popup.setAttribute("oncommand", "tab(event.target.ind);"); popup.tab = ind => { var {url, params} = data[ind]; var tab = gBrowser.addTrustedTab(url, params); if (!(params?.inBackground || inBackground)) gBrowser.selectedTab = tab; } } popup.append(dummy); this.prepend(popup); //this.onmouseover = () => this.open = true; this.removeAttribute("tooltiptext"); var tt = this.appendChild(n("box")).appendChild(n("tooltip")); tt.setAttribute("onpopupshowing", "return !(parentNode.parentNode.open = true);"); this.setAttribute("tooltip", tt.id = _id + "-tooltip"); })(nn => document.createXULElement(nn)); }, false); toolbarbutton_0.classList.add("toolbarbutton-1"); toolbarbutton_0.classList.add("chromeclass-toolbar-additional"); return toolbarbutton_0; } }); } catch(e) {} |
Dumby > 02-09-2022 23:23:26 |
kazarin пишет
Это-то зачем, type = "menu" вполне достаточно. скрытый текст Выделить код Код:(async data => CustomizableUI.createWidget({ id: "FFTools", label: "FFTools", localized: false, onCreated(btn) { var doc = btn.ownerDocument; var n = nn => doc.createXULElement(nn); btn.type = "menu"; btn.setAttribute("image", "data:image/png;base64,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"); var popup = n("menupopup"), dummy = n("menuitem"); popup.toggleAttribute("context"); dummy.n = n; dummy.render = this.render; popup.append(dummy); btn.prepend(popup); var tt = btn.appendChild(n("box")).appendChild(n("tooltip")); tt.btn = dummy.btn = btn; tt.setAttribute("onpopupshowing", "return !(this.btn.open = true);"); btn.setAttribute("tooltip", tt.id = btn.id + "-tooltip"); }, render() { var {n, btn, parentNode: popup} = this; this.remove(); for(var o of data) { if (!o) { popup.append(n("menuseparator")); continue; } var {lab, url, img} = o; var menuitem = n("menuitem"); menuitem.setAttribute("label", lab || url); if (img) menuitem.className = "menuitem-iconic", menuitem.setAttribute("image", img); menuitem.url = url; popup.append(menuitem); } popup.setAttribute( "oncommand", "gBrowser.selectedTab = gBrowser.addTrustedTab(event.target.url);" ); } }))([{ url: "about:config", img: "chrome://browser/skin/developer.svg" },{ lab: "about:config old", url: "chrome://global/content/config.xhtml", img: "chrome://browser/skin/developer.svg" },{ url: "about:support", img: "chrome://global/skin/icons/info.svg" },{ url: "about:performance", img: "chrome://global/skin/icons/performance.svg" },{ url: "about:memory", img: "chrome://global/skin/icons/warning.svg" },{ url: "about:profiling", img: "chrome://devtools/skin/images/profiler-stopwatch.svg" },{ lab: "about:debugging", url: "about:debugging#/runtime/this-firefox", img: "chrome://browser/skin/developer.svg" }, null,{ lab: "Библиотека", url: "chrome://browser/content/places/places.xhtml", img: "chrome://browser/skin/library.svg" },{ lab: "О сборочной конфигурации", url: "about:buildconfig", img: "chrome://devtools/skin/images/settings.svg" }]); P.S. Если в UA поста вопроса гуглятина, то хорошая практика — указывать о какой версии Firefox речь. |
kazarin > 03-09-2022 01:16:29 |
Dumby Опять... агент сменил, а страницу не обновил |
Dumby > 03-09-2022 23:36:59 |
kazarin пишет
Что-то не слишком подробный вопрос. Может типа как-то так скрытый текст Выделить код Код:(async data => CustomizableUI.createWidget({ id: "WinFolders", label: "Some Label", localized: false, onCreated(btn) { var doc = btn.ownerDocument; var n = nn => doc.createXULElement(nn); btn.type = "menu"; btn.setAttribute("image", this.image); var popup = n("menupopup"), dummy = n("menuitem"); popup.toggleAttribute("context"); dummy.n = n; dummy.render = this.render; popup.append(dummy); btn.prepend(popup); var tt = btn.appendChild(n("box")).appendChild(n("tooltip")); tt.setAttribute("onpopupshowing", "return !(this.btn.open = true);"); btn.setAttribute("tooltip", tt.id = (tt.btn = btn).id + "-tooltip"); }, render() { var {n, parentNode: popup} = this; this.remove(); for(var o of data) { if (!o) { popup.append(n("menuseparator")); continue; } var {lab, file, img} = o; var menuitem = n("menuitem"); menuitem.setAttribute("label", lab || file.leafName); menuitem.className = "menuitem-iconic"; menuitem.setAttribute("image", img || "moz-icon://file:///" + file.path); menuitem.tooltipText = file.path; menuitem.file = file; popup.append(menuitem); } popup.setAttribute( "oncommand", 'var {file} = event.target; file.exists() ? file.reveal() : Services.prompt.alert(null, "Not found!", file.path);' ); }, get image() { var sym = Symbol.iterator; data[sym] = () => { delete data[sym]; var it = data[sym](), {next} = it; var f = Components.Constructor("@mozilla.org/file/local;1", "nsIFile", "initWithPath"); it.next = () => { var res = next.call(it), obj = res.value; if (obj) { var {file} = obj; //if (typeof file == "function") obj.file = obj.file(f); if (typeof file == "string") { var ind = file.indexOf("\\"), has = ind > 0; var root = has ? file.slice(0, ind) : file; if (root.length > 2) file = Services.dirsvc.get(root, Ci.nsIFile).path + (has ? file.slice(ind) : ""); obj.file = f(file); } } return res; } return it; } delete this.image; return this.image = "chrome://browser/skin/save.svg"; } }))([{ file: "WinD" },{ lab: "Автозагрузка", file: "Progs\\Startup" },{ file: "SysD\\drivers\\etc" }, null, { lab: "Fox", file: "GreD", img: "chrome://branding/content/icon16.png" },{ file: "UChrm\\user_chrome_files\\custom_scripts", img: "data:image/svg+xml, <svg xmlns='http://www.w3.org/2000/svg' fill='%23fee082' stroke='%23b28501'><path d='M 7.7500004,3.5 H 13.5 a 2,2 45 0 1 2,2 v 7 a 2,2 135 0 1 -2,2 h -11 a 2,2 45 0 1 -2,-2 v -9 a 2,2 135 0 1 2,-2 H 5.0000004 A 1.3150997,1.3150997 20.81677 0 1 5.8737051,1.8321819 L 7.7500004,3.5 5.8737051,5.1678181 A 1.3150997,1.3150997 159.18323 0 1 5.0000004,5.5 H 0.5'/></svg>" },{ file: "D:\\Folder\\SubFolder" }]); |
kazarin > 04-09-2022 00:29:38 |
Dumby |
kokoss > 07-09-2022 14:31:26 |
Dumby пишет
Как переместить эту закладку на панель навигации ? |
Farby > 08-09-2022 10:11:46 |
kokoss пишет
как вариант добавить в эту кнопку код: скрытый текст Выделить код Код:},{ lab: "LLC Config", url: "about:llc", img: "resource://long_left_click/svg/long-click.svg" |
Dumby > 08-09-2022 13:24:56 |
kokoss пишет
Никак. Закладка — это же всего лишь запись в places.sqlite, |
kokoss > 08-09-2022 15:59:17 |
Farby пишет
Мне для этого достаточно и дефолтной кнопки "Закладки", но это не то. Dumby пишет
Ясненько. |
kazarin > 10-09-2022 01:40:43 |
Dumby |
Dumby > 10-09-2022 13:09:28 |
kazarin пишет
Уж не знаю что за форк, а на квантумной лисе 68 скрытый текст |
kazarin > 10-09-2022 19:41:30 |
Dumby |
kokoss > 10-09-2022 21:25:49 |
Dumby |
Dumby > 11-09-2022 10:23:45 |
kokoss пишет
Дело в том, что «этот скрипт» ничего не открывает, скрытый текст Выделить код Код:(async url => { try {var exp = ChromeUtils.importESModule(url + "sys.mjs");} catch {exp = ChromeUtils.import(url + "jsm");} var bu = exp.BrowserUtils, {whereToOpenLink} = bu; var ts, ind; var args = ["TabOpen", e => Cu.now() - ts < 100 && e.target.ownerGlobal.gBrowser.moveTabTo(e.target, ind) , {once: true}]; var rn = Ci.nsINavHistoryResultNode, notRn = o => !(o instanceof rn); bu.whereToOpenLink = function(e) { var beg, res = whereToOpenLink.apply(bu, arguments); if (!Event.isInstance(e) || "ws".includes(beg = res[0])) return res; try { var trg = e.composedTarget, win = trg.ownerGlobal; var node = trg._placesNode; if (notRn(node)) { node = trg.closest("tree")?.selectedNode; if (notRn(node)) return res; win = win.BrowserWindowTracker.getTopWindow(); } //if ((e.button == 1 || e.ctrlKey) && res == "tab") return "current"; var gb = win.gBrowser; if (beg == "c") { if (gb.selectedTab.isEmpty || node.uri.startsWith("javascript:")) return res; res = "tab"; } if (res.startsWith("t")) { ts = Cu.now(); ind = gb.selectedTab._tPos + 1; gb.tabContainer.addEventListener(...args); } return res; } catch(ex) {return res;} } })("resource://gre/modules/BrowserUtils.");
Прости великодушно, но я слишком глуп чтобы такие загадки разгадывать. |
kokoss > 11-09-2022 13:27:25 |
Dumby пишет
Благодарю , работает, а если нужно что бы открывало в новой вкладке, то изменяем "TabOpen" на "whereToOpenLink". |
xrun1 > 12-09-2022 21:14:56 |
Тут потребовалось, а оказалось, что у меня не работает. скрытый текст Выделить код Код:(async repl => { var obj = `{\n ${ (await (await fetch("chrome://browser/content/places/controller.js")).text()) .match(/async _removeRange\(.+?\n\ +}(?=,\n)/s)[0] .replace("// This is a common bookmark item.", repl) }\n}` var ps = await ChromeUtils.compileScript("data:,(" + encodeURIComponent(`${obj => { var patch = async ctor => { var proto = ctor.prototype, meth = proto?._removeRange; meth && Object.assign(proto, obj); } var key = "PlacesController"; var desc = Object.getOwnPropertyDescriptor(window, key); if (!desc) return; var {get} = desc; if (get) desc.get = () => { var val = get(); patch(val); return val; }, Object.defineProperty(window, key, desc); else patch(desc.value); }})(${obj});`)); var obs = doc => "PlacesController" in doc.ownerGlobal && ps.executeInGlobal(doc); var topic = "chrome-document-loaded"; Services.obs.addObserver(obs, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(obs, topic); }, "quit-application-granted"); })( `$& if (!removedFolders.ignore) { /* let info = await PlacesUtils.bookmarks.fetch(node.bookmarkGuid); */ let args = [node.bookmarkGuid]; let isBookmark = PlacesUtils.nodeIsBookmark(node); isBookmark && args.push(null, {includePath: true}); let info = await PlacesUtils.bookmarks.fetch(...args); if (isBookmark) info.parentGuid = info.path[0].guid; if ( info?.parentGuid == "${PlacesUtils.bookmarks.toolbarGuid}" && !(removedFolders.ignore ??= Services.prompt.confirm( null, null, "Удалить закладку/папку?" )) ) { totalItems--; continue; } }` ); 2. "Восстановить удалённое". Ссылки в коде. скрытый текст Выделить код Код:// Исходная версия https://github.com/alice0775/userChrome.js/blob/master/undoBookmarksContextMenu.uc.js // более свежая https://github.com/alice0775/userChrome.js/blob/master/91/undoBookmarksContextMenu.uc.js // Версия _zt https://forum.mozilla-russia.org/viewtopic.php?pid=792868#p792868 // Версия ВВП https://forum.mozilla-russia.org/viewtopic.php?pid=798662#p798662 // Это вариант от Dumby https://forum.mozilla-russia.org/viewtopic.php?pid=798678#p798678 // иконка моя (async sep => { if (!sep) return; var key = "hasRemoveTransaction"; var g = Cu.import("resource://gre/modules/PlacesTransactions.jsm", {}); if (!g[key]) { Services.scriptloader.loadSubScript( `data:,this.${key}=TransactionsHistory.proxifiedToRaw;`, g ); var raws = g[key]; g[key] = entry => { for(var tr of entry) if (raws.get(tr) instanceof PlacesTransactions.Remove) return true; } } var menuitem = document.createXULElement("menuitem"); for(var args of Object.entries({ closemenu: "single", class: "menuitem-iconic", id: "placesCmd_undoRemove", label: "Восстановить удалённое", oncommand: "PlacesTransactions.undo().catch(Cu.reportError);", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAAEd0lEQVRIx53Ve2yW5RkG8N/7ft8Hxa/9CgjSSDnMA4xVTUMQWzadhzhnjSCC0y0jSjom+JdGp844ZhSjHLJsowaNZoCCHOWglXGoQbo2fBW3obDNUBfXKpsUVhxn6OHdH8+31GXGmL3/3M913ffzPNed93qeBxvmI8umCNjyPFEDSRJw40qKa9jyHSbdzY77Ar+9FTvZ+nHAb9T7P76YcwlOktlBdJia2SSthfRvaR/Mync5tp85Q2mbEHJ/X0bqRTpOBJyehog3C3j1HV9RQP91xG9T8z2SofyphMELWH4zW5s40s7kQ/T0cnYfXfPD1OgM0TlGzSN1DZkzxG1EdURjaa9HCfddEupfuSkIfHXJ5wVENA8Iw9QcRnbzXj31++g8w+WVZHMhXzaKhu2MGMtd36f5CTrn8WAJyf001KCYpA6dDBtLlOfoYuI6kgp6XuLsbhQRfw39ovDPx7/JgYS1b3NkCxcvoPgTevIULyFVTm4jyinp4uRJiirYt5BMLc15kvE0lnCsgZaE2wdx6LVCo9/ghQn4LhdFxEOonELv8ogVV9Iyjd9fx8T1FE2nq5XSQWQuJbsmrJH9JclMsldhFsW3EU0iuxsb6f9zTA3dHj1J1yPsKaPrIOtnkn6KDY2cvYF/vkfmINGuiPdnUD6Pd/7Mur/x0RCqXqTfj+m5glyO1B8ovR1pijeil6KvBw8V1QaB/QYWzNgSYu+TmMm5GVhKT47OBWR28kgnvxvKS/OjvuMGuTSr72FtBR/WctNe4l+H3GUt7DxB2TKe+CmnF5IZRzSZzFmS4wy9n2QGY2eR3Mx193DqAao+4vh04lZS2/EkQyqo7cWux4Kjwf4gKF3N5hEs+QsLlwVuVRPLP2FeTSh95hZSpSx6OOAkwWCWLSEqYWVz4JtLqd3GiuX0/oS6XKjd/BQbF6SRJynij4eJKpl7WSg8cCdzxjHjH3QuIsaorQx7NCx8QQdxCYM2kzxL423BbGN6SP+I6tmcO86hahqu4MA2To3mX+eTxbA2er6VJjcA/Yl2kOzlrutJxrDraaI1XH09j3fQVk7pcG5sCgIOttLVzejpmMPrnxJvYnIZXelwxGHTCOaX0PorsmUMOC/wpeNofg4fjg9EW3+k6CzcYJ99M7h6fSfxFFJrMZzFm0I+fzXxlTQ1EHf3eSlJyI3mlYGs/yEPx4F7/NkQ11zEymFhnDoY9RnwcHmIZ34Q1CcTkBD9FSM58gu8SmUHbmVuJbYRt2AiE/cwZT/tG3h+Gh29lH3A+VPZ+zMq1rHwcq6tY1U31ReQXPgFt3M+/9+xJRvM9f5S3NnX6btLqfqYt1p44xQrFnH0aX6zmBXIj+Hae0N95qG+ea/PJjrB7tV47csE7CzEJqKXyTcW8CquaibfwTOX0FjPLSfYk+G8XWyb+rlTUcndVUQjWXOK+FiBn/QfQen/FVBVVdhoc4FIkczqM5WBvPMWp4fQMpzFHeEN2NCFCcyNSH2b1AiSl3nhVnrnkjpNkqP9jrBvdzX8G2rIlxvMK3a7AAAAInpUWHRTb2Z0d2FyZQAAeNorLy/Xy8zLLk5OLEjVyy9KBwA22AZYEFPKXAAAAABJRU5ErkJggg==", })) menuitem.setAttribute(...args); var desc = Object.getOwnPropertyDescriptor(XULElement.prototype, "hidden"); var {set} = desc; desc.set = () => { var entry = PlacesTransactions.topUndoEntry; var vis = entry && g[key](entry); vis && menuitem.removeAttribute("disabled"); set.call(menuitem, !vis); } Object.defineProperty(menuitem, "hidden", desc); sep.before(menuitem); })(document.getElementById("placesContext_deleteSeparator")); Поделитесь, кто пользуется и у кого работает. |
Dobrov > 13-09-2022 01:58:37 |
xrun1 пишет
Вопрос на удаление работал, но зачем нужен? Только время отнимает. 2. второй очень полезный: пережал иконку в Восстановить закладки, сократив на 800 байт. |
xrun1 > 13-09-2022 03:28:23 |
Dobrov пишет
1. Меня заставляет ещё раз подумать. Код работает в боковой панели, а хотелось бы ещё в панели закладок. Помнится, раньше и там работал. |
Dumby > 13-09-2022 08:20:59 |
egorsemenov06 пишет
Конечно же нет, это ведь не расширение, а WebExtensions.
Разве что можно попытаться забрать у него browser.runtime.sendNativeMessage() себе, скрытый текст Выделить код Код:var UcfStylesScripts = { /** ************************▼ Настройки ▼************************ */ ....... scriptsbackground: [ // В фоне [System Principal] ....... { func: 'ChromeUtils.importESModule("chrome://user_chrome_files/content/custom_scripts/DownloadMaster.mjs");' }, ], /** ************************▲ Настройки ▲************************ */ }; скрытый текст Выделить код Код:if (!ChromeUtils.domProcessChild.childID) { var path = "C:\\Portable Program Files\\Download Master Portable\\dmaster.exe"; var urlsListURL = "download_master.urls"; // Relative to "chrome" folder, use "/" var U = Services.io.newFileURI, CC = Components.Constructor; var F = CC("@mozilla.org/file/local;1", "nsIFile", "initWithPath"); var file = F(path); if (!file.exists()) throw "Download Master Portable Not Found!\n" + path; var proc = CC("@mozilla.org/process/util;1", "nsIProcess", "init").bind(null, file); var urlsListPath = Services.io.newURI( U(Services.dirsvc.get("UChrm", Ci.nsIFile)).resolve(urlsListURL) ).QueryInterface(Ci.nsIFileURL).file.path; var esModuleURI = Components.stack.filename; ChromeUtils.registerWindowActor("DownloadMaster", { parent: {esModuleURI}, remoteTypes: ["extension"], child: {esModuleURI, events: {DOMDocElementInserted: {}}}, matches: ["moz-extension://*/_generated_background_page.html"] }); var DownloadMasterParent = class extends JSWindowActorParent { async receiveMessage(msg) { var id = msg.name, d = msg.data; if (id == "D") return file.launch(); // openDownloadMaster var args = []; if (id == "A") var arg = d.url; // openAddURLWindow else { var push, url, arg = "", dwnld = id == "l"; if (dwnld) url = d.url; // downloadFile else { // addUrls if (d.urls.length == 1) url = d.urls[0]; else await IOUtils.writeUTF8( push = url = urlsListPath, d.urls.join("\n") ); } arg += `<url>${url}</url><referer>${d.referrer}</referer>`; var str = "<cookies>" for(var {name, value} of d.cookies) str += `${name}=${value}; `; arg += str + "</cookies>"; if (dwnld) { // downloadFile var uri = U(F(d.filename)).QueryInterface(Ci.nsIFileURL); if (d.isNameSelected) arg += `<savepath>${uri.file.parent.path}</savepath>` + `<filename>${uri.fileName}</filename>`; var ext = uri.fileExtension; if (ext) arg += `<fileExtension>.${ext}</fileExtension>` } else if (d.urlsdata?.title) // addUrls [1] arg += `<filename>${d.urlsdata.title}</filename>`; args.push(push || "-addurl"); } args.push(arg); proc().runwAsync(args, args.length); } } } export {DownloadMasterParent}; export class DownloadMasterChild extends JSWindowActorChild { handleEvent(e) { var win = this.contentWindow; if (WebExtensionPolicy.getByHostname(win.location.host).id != "dm@westbyte.com") return; win = win.wrappedJSObject; var o = win.Object, res = new o(); res.downloadState = "DOWNLOAD_ACCEPTED"; var desc = new o(); desc.configurable = true; Cu.exportFunction(() => { delete res.protocolVersion; return res.protocolVersion = win.BRDEP.protocolVersion; }, desc, {defineAs: "get"}); o.defineProperty(res, "protocolVersion", desc); var dummy = win.Promise.resolve(res); var sendMethods = new Set([ "downloadFile", "addUrls", "openAddURLWindow", "openDownloadMaster" ]); win.browser.runtime.sendNativeMessage = (s, data) => { if (sendMethods.has(data.method)) { var id = data.method[4]; delete data.method; this.sendAsyncMessage(id, data); } return dummy; } } } xrun1 пишет
Видимо, симилярно этому. Заведи уже наконец "новый" UCF.
Тоже вроде обсуждалось. Но, наверно, без lazy. скрытый текст Выделить код Код:(async sep => { if (!sep) return; var key = "hasRemoveTransaction"; var g = Cu.import("resource://gre/modules/PlacesTransactions.jsm", {}); var raws = (g.lazy || g).TransactionsHistory?.proxifiedToRaw; if (raws) g = raws; if (!g[key]) { if (!raws) { Services.scriptloader.loadSubScript( `data:,this.${key}=TransactionsHistory.proxifiedToRaw;`, g ); raws = g[key]; } g[key] = entry => { for(var tr of entry) if (raws.get(tr) instanceof PlacesTransactions.Remove) return true; } } var menuitem = document.createXULElement("menuitem"); for(var args of Object.entries({ closemenu: "single", class: "menuitem-iconic", id: "placesCmd_undoRemove", label: "Восстановить удалённое", oncommand: "PlacesTransactions.undo().catch(Cu.reportError);", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAAEd0lEQVRIx53Ve2yW5RkG8N/7ft8Hxa/9CgjSSDnMA4xVTUMQWzadhzhnjSCC0y0jSjom+JdGp844ZhSjHLJsowaNZoCCHOWglXGoQbo2fBW3obDNUBfXKpsUVhxn6OHdH8+31GXGmL3/3M913ffzPNed93qeBxvmI8umCNjyPFEDSRJw40qKa9jyHSbdzY77Ar+9FTvZ+nHAb9T7P76YcwlOktlBdJia2SSthfRvaR/Mync5tp85Q2mbEHJ/X0bqRTpOBJyehog3C3j1HV9RQP91xG9T8z2SofyphMELWH4zW5s40s7kQ/T0cnYfXfPD1OgM0TlGzSN1DZkzxG1EdURjaa9HCfddEupfuSkIfHXJ5wVENA8Iw9QcRnbzXj31++g8w+WVZHMhXzaKhu2MGMtd36f5CTrn8WAJyf001KCYpA6dDBtLlOfoYuI6kgp6XuLsbhQRfw39ovDPx7/JgYS1b3NkCxcvoPgTevIULyFVTm4jyinp4uRJiirYt5BMLc15kvE0lnCsgZaE2wdx6LVCo9/ghQn4LhdFxEOonELv8ogVV9Iyjd9fx8T1FE2nq5XSQWQuJbsmrJH9JclMsldhFsW3EU0iuxsb6f9zTA3dHj1J1yPsKaPrIOtnkn6KDY2cvYF/vkfmINGuiPdnUD6Pd/7Mur/x0RCqXqTfj+m5glyO1B8ovR1pijeil6KvBw8V1QaB/QYWzNgSYu+TmMm5GVhKT47OBWR28kgnvxvKS/OjvuMGuTSr72FtBR/WctNe4l+H3GUt7DxB2TKe+CmnF5IZRzSZzFmS4wy9n2QGY2eR3Mx193DqAao+4vh04lZS2/EkQyqo7cWux4Kjwf4gKF3N5hEs+QsLlwVuVRPLP2FeTSh95hZSpSx6OOAkwWCWLSEqYWVz4JtLqd3GiuX0/oS6XKjd/BQbF6SRJynij4eJKpl7WSg8cCdzxjHjH3QuIsaorQx7NCx8QQdxCYM2kzxL423BbGN6SP+I6tmcO86hahqu4MA2To3mX+eTxbA2er6VJjcA/Yl2kOzlrutJxrDraaI1XH09j3fQVk7pcG5sCgIOttLVzejpmMPrnxJvYnIZXelwxGHTCOaX0PorsmUMOC/wpeNofg4fjg9EW3+k6CzcYJ99M7h6fSfxFFJrMZzFm0I+fzXxlTQ1EHf3eSlJyI3mlYGs/yEPx4F7/NkQ11zEymFhnDoY9RnwcHmIZ34Q1CcTkBD9FSM58gu8SmUHbmVuJbYRt2AiE/cwZT/tG3h+Gh29lH3A+VPZ+zMq1rHwcq6tY1U31ReQXPgFt3M+/9+xJRvM9f5S3NnX6btLqfqYt1p44xQrFnH0aX6zmBXIj+Hae0N95qG+ea/PJjrB7tV47csE7CzEJqKXyTcW8CquaibfwTOX0FjPLSfYk+G8XWyb+rlTUcndVUQjWXOK+FiBn/QfQen/FVBVVdhoc4FIkczqM5WBvPMWp4fQMpzFHeEN2NCFCcyNSH2b1AiSl3nhVnrnkjpNkqP9jrBvdzX8G2rIlxvMK3a7AAAAInpUWHRTb2Z0d2FyZQAAeNorLy/Xy8zLLk5OLEjVyy9KBwA22AZYEFPKXAAAAABJRU5ErkJggg==", })) menuitem.setAttribute(...args); var desc = Object.getOwnPropertyDescriptor(XULElement.prototype, "hidden"); var {set} = desc; desc.set = () => { var entry = PlacesTransactions.topUndoEntry; var vis = entry && g[key](entry); vis && menuitem.removeAttribute("disabled"); set.call(menuitem, !vis); } Object.defineProperty(menuitem, "hidden", desc); sep.before(menuitem); })(document.getElementById("placesContext_deleteSeparator")); |
xrun1 > 13-09-2022 13:15:00 |
Dumby пишет
Нет, я не трус, но я боюсь. Боюсь, смогу ли я, способен ли? |
Dumby > 13-09-2022 14:04:17 |
xrun1 пишет
Не понял. А 1. что, не работает что ли?
Так склонируй браузер, и там пробуй разобраться. |
xrun1 > 14-09-2022 03:23:46 |
Dumby пишет
Работает в боковой панели. На панели закладок не спрашивает. Пока гром не грянет, мужик не перекрестится — констатация того, что люди ленивы и не предусмотрительны, идут вслед за событиями, а не опережая их; предпочитают полагаться на случай, на судьбу, а не формировать её; не думать, анализировать ситуацию, моделировать грядущие события, чтобы встретить их последствия во всеоружии, а пускать дело на самотек, как кривая вывезет. P.S. Например, у меня нет стилей AGENT_SHEET, AUTHOR_SHEET или USER_SHEET. У меня просто стили, которые работают. Как-то так... |
kokoss > 14-09-2022 09:15:34 |
xrun1 пишет
А у меня наоборот, этот скрипт на панели закладок работает, а в боковой нет. |
Dobrov > 14-09-2022 15:08:38 |
Dumby пишет
В панели закладок вернуть удалённое работает. А как насчёт окна "Управление закладками"? Dumby - возможно добавить восстановление удалённых закладок было и в окне Библиотеки? Ещё вопрос по стилям UCF в CustomStylesScripts.jsm - подскажите, как подключать стили в зависимости от операционной системы? Выделить код Код:var UcfStylesScripts = { /** ************************▼ Настройки ▼************************ */ …………………………… stylesall: [ // Для всех документов - ЗДЕСЬ разделить стили по типу операционной системы { path: "custom_styles_all_agent.css", type: "AGENT_SHEET", sheet() { registerSheet(this); }, }, { path: "custom_styles_all_user.css", type: "USER_SHEET", sheet() { registerSheet(this); }, }, ], |
Farby > 14-09-2022 17:43:36 |
Dobrov Пример Выделить код Код:@media (-moz-platform: windows) { /* some rules targeting windows OS */ } @media (-moz-platform: osx) { /* some rules targeting mac OS */ } @media (-moz-platform: linux) { /* some rules targeting linux (by which I think we normally mean gtk in practice? */ } |
voqabuhe > 14-09-2022 18:18:30 |
xrun1 пишет
kokoss пишет
У меня и в боковой, и на панели закладок работает. Dumby, спасибо. |
bezuma > 14-09-2022 18:30:05 |
kokoss пишет
Хех, у меня аналогично, в боковой панели спасает Ctrl+Z |
voqabuhe > 14-09-2022 18:42:28 |
bezuma |
Dumby > 14-09-2022 19:20:29 |
xrun1 пишет
Это я понял ещё из изначального вопроса. kokoss пишет
Этого не может быть. Наверно ты не понял что скрипт делает. Подтверждение появляется если: Dobrov пишет
Оно там есть. В смысле должно работать Ctrl+Z.
Так а в чём, собственно, затруднение? В начале скрипта импортируем лисий модуль AppConstants, Farby пишет
Не osx, а macos. К тому же, Firefox 99+, а не 97. |
kokoss > 14-09-2022 19:44:58 |
bezuma пишет
У меня просто старая версия UCF, видимо поэтому у меня так работает. |
bezuma > 14-09-2022 19:50:32 |
kokoss |
kokoss > 14-09-2022 20:18:20 |
bezuma пишет
Если только из за этого, то просто замените в новом UCF, папку svg и файл icons_in_menu на свои. |
bezuma > 14-09-2022 20:33:10 |
kokoss |
Dobrov > 15-09-2022 02:51:42 |
Dumby пишет
с @media (-moz-platform не совсем подходит, так как хочу, чтобы работало на "быстрых" старых версиях, как UCF для FF78+. Так нормально? Выделить код Код:const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); var os = name => `${name}_${AppConstants.platform}.css`; var UcfStylesScripts = { /** ************************▼ Настройки ▼ + доп. подключение слилей для вашей ОС */ ……………………… stylesall: [ // Для всех документов { path: "custom_styles_all_agent.css", type: "AGENT_SHEET", sheet() { registerSheet(this); }, }, { path: "custom_styles_all_user.css", type: "USER_SHEET", sheet() { registerSheet(this); }, }, // добавить стиль для вашей операционной системы: "*_macosx.css" "*_linux.css" "*_win.css" { path: os("custom_styles_all_agent"), type: "AGENT_SHEET", sheet() { registerSheet(this); }, }, { path: os("custom_styles_all_user"), type: "AGENT_SHEET", sheet() { registerSheet(this); }, }, ], |
xrun1 > 15-09-2022 12:17:34 |
Dumby пишет
Ссылка помогла после повторного прочтения. Меня смутило слово "симилярно". скрытый текст |
kokoss > 15-09-2022 17:26:11 |
bezuma пишет
|
bezuma > 16-09-2022 09:56:54 |
voqabuhe пишет
Никуда - тупо жмакаю клаву kokoss |
Yeesha > 16-09-2022 16:19:16 |
Вот пара моих скриптов, надеюсь кому пригодятся. Скриншот Код Выделить код Код:// QUICK BOOKMARK // Replacement for QuickMark extension for Firefox 57+ // https://addons.mozilla.org/firefox/addon/quickmark/ // https://github.com/TarekJor/Firefox-52-ESR-legacy-addon/blob/master/xpi/quickmark-1.2.11-fx.xpi // Required Firefox version: min 54, max tested 70a // Changelog // 2017.11.14 - initial release for FF 57 // 2018.08.28 - edits for FF 62-63 // 2019.08.18 - edits for FF 68-70: // Some operations with folderTree variable moved from initialization code into panel.popupshowing listener as node #editBMPanel_folderTree is no longer present in DOM until popup initialized and toggleFolderTreeVisibility() called. // createElement() replaced with createXULElement() (used in makeResizer() and makeFolderContextMenu()). // 2020.05.08 - edits for FF 76 // Bookmarks panel is now accessed via StarUI.panel as getElementById(...) returns null in FF 76 // 2020.06.02 - edits for FF 78 or 79 // Popup hint is now accessed via ConfirmationHint._panel as getElementById(...) returns null since FF 78 or 79 // 2022.06.19 - edits for FF ≈101 // Small fixes let settings = { // If false, you can set any folder as default via its context menu useLastSelectedFolderAsDefault: false, // Comment out any element to unhide it menuElementsToHide: [ // '.panel-header', '#editBookmarkPanelImage', // FF62+ '#editBookmarkPanelFaviconContainer', // FF62+ // '#editBMPanel_nameRow', // '#editBMPanel_folderRow', '#editBMPanel_folderRow > hbox', // ≈FF101 '#editBMPanel_newFolderBox', // '#editBMPanel_tagsRow', '#editBookmarkPanel_showForNewBookmarks', // FF63+ '#editBookmarkHeaderSeparator', // ≈FF101 ], makeMenuNarrower: true, makeButtonsSmaller: false, hideBookmarksToolbarIfEmpty: true, hideThatStupidGreenTooltipOnSaving: true, // FF62+ useOneClickMode: true, }; let strings = { 'en': { 'setAsDefault': 'Set as default folder', 'rename': 'Rename', 'addNewFolder': 'New folder...', }, 'ru': { 'setAsDefault': 'Сделать папкой по умолчанию', 'rename': 'Переименовать', 'addNewFolder': 'Новая папка...', }, }; strings['en-US'] = strings['en']; strings['ru-RU'] = strings['ru']; if (Services.vc.compare(Services.appinfo.platformVersion, '54.*') == -1) { let path = Components.stack.filename; path = path.substring(path.lastIndexOf('///') + 3); alert('“Quick Bookmark” userscript will not work with this version of Firefox. \nMinimal supported version is 54. \nPlease delete the script to avoid such alerts and possible malfunctioning. \n' + path); } let storage = Services.prefs.getBranch('extensions.userScripts.quickBookmark.'); let starButton = document.getElementById('star-button-box'); // let panel = document.getElementById('editBookmarkPanel'); // Null since FF76 because of “lazy load” (see browser-places.js) let panel = StarUI.panel; // This creates the panel in FF76 if missed or just gets it in older versions let folderTree = panel.querySelector('#editBMPanel_folderTree'); // Null in FF 68-70 let folderTreeRow = panel.querySelector('#editBMPanel_folderTreeRow'); let defaultFolderGuid = storage.getCharPref('defaultFolderGuid', PlacesUtils.bookmarks.unfiledGuid); let lastSelectedFolderGuid = defaultFolderGuid; // Used to distinguish if user really selected the folder or just expanded/collapsed it let shouldCloseOnClick = true; makeResizer(); makeFolderContextMenu(); let folderTreeHeight = storage.getCharPref('folderTreeHeight', '300px'); folderTreeRow.style.height = folderTreeHeight; for (let sel of settings.menuElementsToHide) { if (sel == '#editBookmarkPanel_showForNewBookmarks') continue; // This must be done later let el = panel.querySelector(sel); if (el) el.style.display = 'none'; if (sel == '#editBMPanel_folderRow > hbox' && el) folderTreeRow.style.padding = '0px'; } if (settings.makeMenuNarrower) { if (folderTree) folderTree.style.minWidth = '260px'; // Fix for ~FF62b18, probably will not be needed in latest builds panel.querySelector('#editBookmarkPanelBottomButtons').removeAttribute('style'); } if (settings.makeButtonsSmaller) { panel.querySelector('#editBookmarkPanelDoneButton').style.padding = '5px 2px 7px'; panel.querySelector('#editBookmarkPanelRemoveButton').style.padding = '5px 2px 7px'; } if (settings.hideThatStupidGreenTooltipOnSaving) { // document.querySelector('#confirmation-hint').style.display = 'none'; // Null since FF78 or 79 because of “lazy load” (see browser.js) let hint = document.querySelector('#confirmation-hint') || ConfirmationHint._panel; // This creates the hint in FF78-79 if missed or just gets it in older versions hint.style.display = 'none'; } // let tagsSelectorCollapsed = storage.getBoolPref('tagsSelectorCollapsed', true); // Add/remove bookmark silently when middle-clicking on the star button or pressing Ctrl+Alt+D // This may interfere with typographic keyboard layouts; possible solution - use Ctrl+Shift+D starButton.addEventListener('click', function(e) { if (e.button == 1 || (e.button == 0 && (e.ctrlKey || e.shiftKey))) { e.stopPropagation(); toggleBookmark(); } }, true); document.addEventListener('keydown', function(e) { if (e.ctrlKey && e.altKey && e.code == 'KeyD') { e.preventDefault(); toggleBookmark(); } // In FF63a1, if typographic layout is used and we are pressing Ctrl+Alt+D, both e.ctrlKey and e.altKey are false // This is a temporary workaround else if (e.key == '°' && e.code == 'KeyD') { e.preventDefault(); toggleBookmark(); } }); panel.addEventListener('popupshowing', function() { gEditItemOverlay.toggleFolderTreeVisibility(); if (!folderTree) folderTree = panel.querySelector('#editBMPanel_folderTree'); if (settings.makeMenuNarrower) folderTree.style.minWidth = '260px'; folderTree.contextMenu = 'editBMPanel_folderTree_contextMenu'; if (settings.menuElementsToHide.includes('#editBookmarkPanel_showForNewBookmarks')) { let el = panel.querySelector('#editBookmarkPanel_showForNewBookmarks'); if (el) el.style.display = (el.checked) ? 'none' : ''; } // if (!settings.menuElementsToHide.includes('#editBMPanel_tagsRow') && !tagsSelectorCollapsed) // gEditItemOverlay.toggleTagsSelector(); }); panel.addEventListener('popupshown', onPopupShown); panel.addEventListener('popuphidden', onPopupHidden); function onPopupShown() { folderTree.focus(); if (StarUI._isNewBookmark) gEditItemOverlay._folderTree.selectItems([defaultFolderGuid]); lastSelectedFolderGuid = gEditItemOverlay.selectedFolderGuid; // Reset var shouldCloseOnClick = true; if (settings.useOneClickMode) { folderTree.addEventListener('select', onFolderTreeSelect); folderTreeRow.addEventListener('click', onFolderTreeClick); folderTreeRow.addEventListener('keydown', onFolderTreeClick, true); // NB: keydown listener must be attached to folderTreeRow, not folderTree, // to be able to prevent default folderTree action (expand/collapse folder) when pressing Enter } }; function onFolderTreeSelect(e) { // Stop undesirable calls before the panel is shown if (!panel.hasAttribute('panelopen')) return; if (gEditItemOverlay.selectedFolderGuid == lastSelectedFolderGuid) // 'Select' event fired, but folder not changed? Seems user expanded/collapsed some folder, so panel shouldn’t be closed shouldCloseOnClick = false; else lastSelectedFolderGuid = gEditItemOverlay.selectedFolderGuid; }; function onFolderTreeClick(e) { // Cancel one-click mode when Alt pressed, e.g. user can rename folder with Alt+DoubleClick if (e.altKey) return; // Rename folder with F2 if (e.code == 'F2') { let g = gEditItemOverlay; g._folderTree.startEditing(g._folderTree.view.selection.currentIndex, g._folderTree.columns.getFirstColumn()); } // Close menu with Enter or left click else if (e.code == 'Enter' || e.button == 0) { // Prevent folder from expand/collapse when pressing Enter e.stopPropagation(); if (shouldCloseOnClick || e.code == 'Enter') { setTimeout(function() { StarUI.panel.hidePopup(); }, 100); } shouldCloseOnClick = true; } }; function onPopupHidden() { // Hide bookmarks toolbar if empty if (settings.hideBookmarksToolbarIfEmpty) { setTimeout(function() { let toolbarFolder = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.toolbarGuid).root; let toolbarNode = document.getElementById('PersonalToolbar'); if (toolbarNode && !toolbarNode.collapsed && !toolbarFolder.hasChildren) BookmarkingUI.toggleBookmarksToolbar(); }, 500); } // Save panel height let height = folderTreeRow.style.height; if (height && height != '0' && height != '0px' && height != folderTreeHeight) { storage.setCharPref('folderTreeHeight', height); folderTreeHeight = height; } // Save default folder guid if (settings.useLastSelectedFolderAsDefault && gEditItemOverlay.selectedFolderGuid && gEditItemOverlay.selectedFolderGuid != defaultFolderGuid) { storage.setCharPref('defaultFolderGuid', gEditItemOverlay.selectedFolderGuid); defaultFolderGuid = gEditItemOverlay.selectedFolderGuid; } // Save tags selector state /* let collapsed = panel.querySelector('#editBMPanel_tagsSelectorRow').collapsed; if (collapsed != tagsSelectorCollapsed) { storage.setBoolPref('tagsSelectorCollapsed', collapsed); tagsSelectorCollapsed = collapsed; } */ }; // Visible resizer above OK/Cancel buttons /* function makeResizer() { let el = document.createXULElement('resizer'); el.setAttribute('dir', 'bottom'); el.setAttribute('element', 'editBMPanel_folderTreeRow'); el.style.MozAppearance = 'none'; el.style.backgroundSize = 'auto'; el.style.backgroundPosition = 'bottom right'; el.style.backgroundImage = 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAABmJLR0QAUABQAFDGhwvwAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4gcVDwIBDNJ+vQAAADdJREFUKM9jYCARMDIwMDD8//+fOMWMjAxMhBQdOHDg/4EDB+AmMg2Mk5CdMYBOwuUM+juJZAAAHy0zBdN01HIAAAAASUVORK5CYII=)'; el.style.marginTop = '-16px'; // panel.querySelector('#editBookmarkPanelRows').style.paddingBottom = "0px"; panel.querySelector('#editBookmarkPanelContent').appendChild(el); }; */ // Invisible resizer at the bottom edge of panel function makeResizer() { let el = document.createXULElement('resizer'); el.setAttribute('dir', 'bottom'); el.setAttribute('element', 'editBMPanel_folderTreeRow'); el.style.MozAppearance = 'none'; el.style.background = 'none'; el.style.height = '6px'; el.style.margin = '-2px 0 -4px'; panel.appendChild(el); }; function makeFolderContextMenu() { let menu = document.createXULElement('menupopup'); menu.id = 'editBMPanel_folderTree_contextMenu'; let items = ['rename', 'addNewFolder']; if (!settings.useLastSelectedFolderAsDefault) items.unshift('setAsDefault'); for (let item of items) { let z = document.createXULElement('menuitem'); z.setAttribute('label', lang(item)); z.setAttribute('action', item); menu.appendChild(z); } document.querySelector('#mainPopupSet').appendChild(menu); // folderTree.contextMenu = 'editBMPanel_folderTree_contextMenu'; if (!settings.useLastSelectedFolderAsDefault) { menu.firstChild.setAttribute('type', 'checkbox'); menu.addEventListener('popupshowing', function(e) { menu.firstChild.setAttribute('checked', (defaultFolderGuid == gEditItemOverlay.selectedFolderGuid)); }); } menu.addEventListener('command', onFolderContextMenuCommand); }; function onFolderContextMenuCommand(e) { let g = gEditItemOverlay; switch (e.target.getAttribute('action')) { case 'setAsDefault': storage.setCharPref('defaultFolderGuid', g.selectedFolderGuid); defaultFolderGuid = g.selectedFolderGuid; break; case 'rename': g._folderTree.startEditing(g._folderTree.view.selection.currentIndex, g._folderTree.columns.getFirstColumn()); break; case 'addNewFolder': g.newFolder(); } }; function lang(string) { let l = strings[navigator.language]; return (l && l[string]) ? l[string] : strings['en'][string] ? strings['en'][string] : string; } function toggleBookmark() { if (BookmarkingUI.status == BookmarkingUI.STATUS_STARRED) { let uri = gBrowser.currentURI.spec; try { uri = decodeURIComponent(uri); } catch {} PlacesUtils.bookmarks.search(uri).then((foundItems) => { if (foundItems.length) PlacesUtils.bookmarks.remove(foundItems); }); } else PlacesUtils.bookmarks.insert({url: gBrowser.currentURI.spec, title: gBrowser.contentTitle, parentGuid: defaultFolderGuid}); } Tab Wheel Scroll Переключение между вкладками вращением колеса мыши. Код Выделить код Код:(function() { // FF65- // let tabbox = document.getElementById('tabbrowser-tabs').arrowScrollbox._scrollbox; // FF66+ let tabbox = document.getElementById('tabbrowser-tabs').arrowScrollbox.scrollbox; tabbox.addEventListener('wheel', wheelHandler); function wheelHandler(event) { // Preserve original behaviour if meta (Windows) key is held if (event.metaKey) return; if (event.deltaY < 0) { gBrowser.tabContainer.advanceSelectedTab(-1, false); } else { gBrowser.tabContainer.advanceSelectedTab(1, false); } event.stopPropagation(); event.preventDefault(); } })(); Input Language Assistant Это аналог старого расширения с таким же названием, и работает точно так же. Поставили курсор в адресную строку - раскладка переключилась на английскую, убрали оттуда курсор - раскладка вернулась к прежней (русской). Работает только на Windows. Код Выделить код Код:window.inputLanguageAssistant = { init: function() { let urlbar = document.getElementById('urlbar-input'); // Since FF 68-70 (I don't know exact version) if (!urlbar) urlbar = document.getElementById('urlbar'); if (!urlbar) return; try { Components.utils.import("resource://gre/modules/ctypes.jsm"); this.lib = ctypes.open("user32.dll"); this.ActivateKeyboardLayout = this.lib.declare("ActivateKeyboardLayout", ctypes.winapi_abi, ctypes.voidptr_t, // return HKL ctypes.voidptr_t, // HKL hkl ctypes.uint32_t); // UINT Flags this.KLF_SETFORPROCESS = 0x00000100; this.HKL_ENGLISH = ctypes.voidptr_t(0x00000409); // United States (US) } catch (err) { // console.log(err); } urlbar.addEventListener('focus', function(e) { window.inputLanguageAssistant.focus(); }); urlbar.addEventListener('blur', function(e) { window.inputLanguageAssistant.blur(); }); }, focus: function() { try { if (this.ActivateKeyboardLayout) { this.hkl = this.ActivateKeyboardLayout(this.HKL_ENGLISH, this.KLF_SETFORPROCESS); } } catch (err) { // console.log(err); } }, blur: function() { try { if (this.ActivateKeyboardLayout && this.hkl) { this.ActivateKeyboardLayout(this.hkl, this.KLF_SETFORPROCESS); } } catch (err) { // console.log(err); } } }; window.inputLanguageAssistant.init(); |
kazarin > 16-09-2022 19:21:42 |
Yeesha, спасибо! |
Yeesha > 16-09-2022 20:19:40 |
kazarin, через userChrome.js, про rebuild не знаю
Увы, нет |
kazarin > 16-09-2022 21:38:06 |
Yeesha |
xrun1 > 17-09-2022 01:41:38 |
Попробовал поставить "новый" UCF. До кнопок пока не добрался, попробовал стили. Мои все заработали, кроме одного. В нём можно было регулировать ширину боковой и высоту доп.панелей. С "новым" UCF не работает или я его не туда воткнул. скрытый текст Выделить код Код:/* Сжать доп.панели https://forum.mozilla-russia.org/viewtopic.php?pid=775867#p775867 */ #add-additional-top-bar, #add-additional-bottom-bar { --toolbarbutton-outer-padding: 2px !important; /* было 0px */ --toolbarbutton-inner-padding: 2px !important; min-height: 20px !important; } :-moz-any(#add-additional-top-bar,#add-additional-bottom-bar) .toolbarbutton-badge { margin-inline-end: calc(-1 * (var(--toolbarbutton-outer-padding) + var(--toolbarbutton-inner-padding))) !important; } #add-additional-bottom-closebutton { padding: 0 !important; } #add-additional-vertical-bar { --toolbarbutton-outer-padding: 2px !important; /* было 0px */ --toolbarbutton-inner-padding: 3px !important; min-width: 20px !important; } #add-additional-vertical-bar .toolbarbutton-badge { margin-inline-end: calc(-1 * (var(--toolbarbutton-outer-padding) + var(--toolbarbutton-inner-padding))) !important; } Как ширину/высоту панелей отрегулировать в "новом" UCF? |
kazarin > 17-09-2022 03:03:41 |
xrun1 скрытый текст Вертикальная меня устраивает (она прозрачная и автоскрывается), но, наверно, можно попробовать margin-left. |
Dobrov > 17-09-2022 05:45:54 |
Опять в Firefox 103+ перестал работать скрипт от Виталия - нужно скрывать панель вкладок, если открыта одна вкладка. Выделить код Код:var menubarvisibilitychance = { buttons: null, buttonsfullscreen: null, init(that) { var menubar = this.menubar = document.querySelector("#toolbar-menubar"); if (!menubar) return; this.autohidechange = new MutationObserver(() => { this.settoolbarvisibility(); }); this.autohidechange.observe(menubar, { attributeFilter: ["autohide", "inactive"], attributes: true, }); this.sizemodechange = new MutationObserver(() => { this.setbuttonboxwidth(); }); this.sizemodechange.observe(document.documentElement, { attributeFilter: ["sizemode"], attributes: true, }); that.unloadlisteners?.push("menubarvisibilitychance"); this.settoolbarvisibility(); }, settoolbarvisibility() { var docElm = document.documentElement; if (this.menubar.getAttribute("autohide") == "true" && this.menubar.getAttribute("inactive") == "true") { docElm.setAttribute("v_menubar_autohide", true); this.setbuttonboxwidth(); } else docElm.setAttribute("v_menubar_autohide", false); }, width(outerRect, innerRect) { if (!window.RTL_UI) this.width = (outerRect, innerRect) => outerRect.right - innerRect.left; else this.width = (outerRect, innerRect) => innerRect.right - outerRect.left; return this.width(outerRect, innerRect); }, setbuttonboxwidth() { var buttons, docElm = document.documentElement; if (docElm.getAttribute("sizemode") != "fullscreen") buttons = (this.buttons || (this.buttons = this.menubar.querySelector(".titlebar-buttonbox-container"))); else buttons = (this.buttonsfullscreen || (this.buttonsfullscreen = document.querySelector("#window-controls"))); var innerRect = buttons.getBoundingClientRect(); if (innerRect.width < 1) { docElm.style.setProperty("--v-titlebar-buttonbox-container-width", "0px"); return; } var outerRect = docElm.getBoundingClientRect(); docElm.style.setProperty("--v-titlebar-buttonbox-container-width", `${this.width(outerRect, innerRect)}px`); }, destructor() { this.autohidechange.disconnect(); this.sizemodechange.disconnect(); this.autohidechange = null; this.sizemodechange = null; } }; menubarvisibilitychance.init(this); |
Dumby > 17-09-2022 08:18:57 |
Dobrov пишет
В комментарий прокралась опечатка: «слилей».
Не понял просьбу. menubar это не панель вкладок. xrun1 пишет
kazarin верно намекает, что в "новом" UCF |
Dobrov > 17-09-2022 09:59:09 |
Dumby пишет
Ну, именно этот этот код автоскрывает панель вкладок, но на FF103+ не пашет. |
Dumby > 17-09-2022 10:30:05 |
Dobrov пишет
Нет, он этого не делает. Он вообще ничего не автоскрывает. Код следит за атрибутами "autohide" и "inactive" toolbar-menubar'а, И, при изменении этих атрибутов, устанавливает для <html> Вот и всё. Если у тебя какой-то стиль повешен на эти атрибуты, то где стиль? |
Dobrov > 17-09-2022 10:32:49 |
Dumby пишет
Так как этот стиль связан с кодом, привожу стиль от Виталия здесь: Выделить код Код:@-moz-document url("chrome://browser/content/browser.xhtml") { :root { /* вкладки снизу: стиль плюс скрипты https://forum.mozilla-russia.org/viewtopic.php?pid=784310#p784310 */ --v-toolbar-menubar-height: 28px; /* высота панели меню, только чётные числа не меньше 20px для macos = 0 если изменяете эту переменную то и в --v-toolbar-menubar-height-content - атрибут height= нужно установить ровно в два раза больше*/ --v-toolbar-menubar-height-content: url("data:image/svg+xml,<svg width='28' height='56' xmlns='http://www.w3.org/2000/svg'><rect x='0' y='0' width='100%' height='100%' style='fill:transparent;'/></svg>"); /* height='2 * --v-toolbar-menubar-height' */ --tab-border-radius: 4px !important; /* **************************************** */ --proton-tab-block-margin: 0px !important; --tab-block-margin: 0px !important; --tabs-navbar-shadow-size: 0px !important; } #navigator-toolbox { border-block: none !important; box-shadow: none !important; padding-top: 0 !important; -moz-appearance: none !important; appearance: none !important; } :root:not([inFullscreen])[tabsintitlebar] #navigator-toolbox { position: relative !important; } #navigator-toolbox > toolbar { -moz-box-ordinal-group: 10 !important; } #navigator-toolbox > #nav-bar { margin-block: 0 !important; box-shadow: none !important; -moz-box-ordinal-group: 0 !important; padding-inline: 0 !important; } :root:not([inFullscreen]) #navigator-toolbox > #nav-bar { margin-top: var(--v-toolbar-menubar-height) !important; } #navigator-toolbox > #PersonalToolbar { -moz-box-ordinal-group: 1 !important; } :root:not([inFullscreen])[tabsintitlebar] > *|body::before { content: var(--v-toolbar-menubar-height-content) !important; display: -moz-box !important; -moz-box-flex: 0 !important; -moz-box-orient: vertical !important; -moz-box-pack: start !important; -moz-box-align: stretch !important; -moz-box-ordinal-group: 0 !important; margin-bottom: calc(-2 * var(--v-toolbar-menubar-height)) !important; box-sizing: content-box !important; } :root:not([inFullscreen])[tabsintitlebar][sizemode="normal"] > *|body::before { -moz-appearance: -moz-window-titlebar !important; appearance: -moz-window-titlebar !important; } :root:not([inFullscreen])[tabsintitlebar][sizemode="maximized"] > *|body::before { -moz-appearance: -moz-window-titlebar-maximized !important; appearance: -moz-window-titlebar-maximized !important; } :root:not([inFullscreen])[tabsintitlebar]:-moz-lwtheme > *|body::before { visibility: hidden !important; } @media not all and (-moz-os-version: windows-win7) { @media not all and (-moz-os-version: windows-win8) { :root:-moz-lwtheme { background-color: var(--lwt-accent-color, -moz-Dialog) !important; } :root:-moz-window-inactive:-moz-lwtheme { background-color: var(--lwt-accent-color-inactive, var(--lwt-accent-color, -moz-Dialog)) !important; } } } #navigator-toolbox > #titlebar { -moz-appearance: none !important; appearance: none !important; -moz-box-ordinal-group: 100 !important; position: static !important; } #toolbar-menubar { padding-block: 0 !important; margin-block: 0 !important; border: none !important; background: none !important; --toolbarbutton-outer-padding: 0px !important; --toolbarbutton-inner-padding: calc((var(--v-toolbar-menubar-height) - 16px) / 2) !important; -moz-appearance: none !important; appearance: none !important; } :root:not(:is([inFullscreen],[chromehidden~="menubar"])) #toolbar-menubar { position: absolute !important; top: 0 !important; left: 0 !important; right: 0 !important; display: flex !important; flex-wrap: nowrap !important; flex-direction: row !important; align-items: stretch !important; justify-content: flex-start !important; min-height: 0 !important; height: var(--v-toolbar-menubar-height) !important; overflow: hidden !important; } #toolbar-menubar .toolbarbutton-badge { margin-inline-end: calc(-1 * (var(--toolbarbutton-outer-padding) + var(--toolbarbutton-inner-padding))) !important; } :root:not([inFullscreen]) #toolbar-menubar > :is(toolbaritem,toolbarbutton) { align-self: center !important; } :root:not([inFullscreen]) #toolbar-menubar > :is(#menubar-items,#wrapper-menubar-items,.titlebar-buttonbox-container) { align-self: flex-start !important; } :root:not([inFullscreen]) #toolbar-menubar > * { padding-block: 0 !important; margin-block: 0 !important; } :root:not([inFullscreen]) #toolbar-menubar[autohide="true"][inactive="true"]:not([customizing="true"]) > *:not(.titlebar-buttonbox-container) { opacity: 0 !important; pointer-events: none !important; } :root[inFullscreen] #toolbar-menubar { visibility: collapse !important; } :root:not([inFullscreen]) #toolbar-menubar > :is(*[style*="-moz-box-ordinal-group: 1000;"],.titlebar-buttonbox-container) { order: 1000 !important; } :root:not([inFullscreen]) #toolbar-menubar > :is(toolbarspring,spacer,[id^="wrapper-customizableui-special-spring"]) { flex-grow: 1 !important; } :root:not([inFullscreen]) #toolbar-menubar > :is(#search-container,#wrapper-search-container) { flex-grow: 100 !important; } #toolbar-menubar #search-container { padding-block: 0 !important; } #toolbar-menubar #searchbar { min-height: calc(var(--v-toolbar-menubar-height) - 2px) !important; } #TabsToolbar { -moz-appearance: none !important; appearance: none !important; padding-block: 0 !important; margin-block: 0 !important; box-shadow: 0 -1px 0 var(--tabs-border-color, rgba(0,0,0,.3)) inset !important; position: static !important; background-color: var(--toolbar-bgcolor, -moz-dialog) !important; background-image: var(--toolbar-bgimage, none) !important; color: var(--toolbar-color, -moz-dialogtext) !important; --lwt-toolbarbutton-icon-fill: inherit !important; } #tabbrowser-tabs { padding-bottom: 0 !important; margin-bottom: 0 !important; } .tabbrowser-tab { background-color: transparent !important; border-top: none !important; } .tab-background { border-end-end-radius: 0 !important; border-end-start-radius: 0 !important; margin-block-start: 1px !important; } :root:not(:-moz-lwtheme) .tab-background { --toolbar-bgimage: none; --toolbar-non-lwt-bgimage: none; } #TabsToolbar > .toolbar-items { padding-top: 0 !important; margin-top: 0 !important; } .tabbrowser-tab[usercontextid] .tab-context-line { margin-block: 0 !important; margin-inline: calc(var(--tab-border-radius) / 2) !important; } #TabsToolbar .titlebar-buttonbox-container, #navigator-toolbox::after, #TabsToolbar::after, #TabsToolbar .titlebar-spacer:is([type="pre-tabs"],[type="post-tabs"]) { display: none !important; } #scrollbutton-up, #scrollbutton-down { border-block: none !important; border-end-end-radius: 0 !important; border-end-start-radius: 0 !important; } :root[inFullscreen] #window-controls { position: absolute !important; display: flex !important; align-items: start !important; top: 0 !important; inset-inline-start: auto !important; inset-inline-end: 0 !important; margin: 0 !important; } :root[inFullscreen] #navigator-toolbox > #nav-bar { margin-inline-end: var(--v-titlebar-buttonbox-container-width, 108px) !important; } :root:not([inFullscreen])[v_menubar_autohide="true"] #navigator-toolbox > #nav-bar { margin-top: 0 !important; margin-inline-end: var(--v-titlebar-buttonbox-container-width, 108px) !important; } :root:not([inFullscreen])[v_menubar_autohide="true"] #toolbar-menubar { pointer-events: none !important; } :root:not([inFullscreen])[v_menubar_autohide="true"] #toolbar-menubar .titlebar-buttonbox-container { pointer-events: auto !important; } @media (-moz-os-version: windows-win7), (-moz-os-version: windows-win8) { :root[sizemode="normal"] #TabsToolbar { border-inline: 1px solid hsla(240,5%,5%,0.3) !important; background-clip: padding-box !important; } @media (-moz-windows-classic: 0) { :root:not([inFullscreen])[v_menubar_autohide="true"][tabsintitlebar][sizemode="normal"] #navigator-toolbox > #nav-bar { margin-top: 1px !important; } :root:not([inFullscreen])[sizemode="normal"] #toolbar-menubar:not([autohide="true"]) > #menubar-items { margin-top: 1px !important; } } } @media (-moz-windows-classic) { :root:not([inFullscreen])[tabsintitlebar][sizemode="normal"] #navigator-toolbox::before { content: "" !important; display: -moz-box !important; height: 4px !important; -moz-box-ordinal-group: 0 !important; visibility: visible !important; } :root:not([inFullscreen])[tabsintitlebar][sizemode="normal"]:-moz-lwtheme #navigator-toolbox::before { background-image: linear-gradient(to bottom, ThreeDLightShadow 0, ThreeDLightShadow 1px, ThreeDHighlight 1px, ThreeDHighlight 2px, ActiveBorder 2px, ActiveBorder 4px, transparent 4px) !important; } :root:not([inFullscreen])[tabsintitlebar][sizemode="normal"] #toolbar-menubar { margin-top: 4px !important; } } :root[data-l10n-id="browser-main-window-mac"] { --v-toolbar-menubar-height: 0px !important; --v-toolbar-menubar-height-content: none !important; } :root:not([inFullscreen])[tabsintitlebar][data-l10n-id="browser-main-window-mac"] #nav-bar { margin-inline-start: calc(var(--toolbarbutton-outer-padding, 2px) + var(--v-titlebar-button-horizont-padding, 6px) * 6 + var(--v-titlebar-button-image-width, 12px) * 3) !important; } :root:not([inFullscreen])[tabsintitlebar][data-l10n-id="browser-main-window-mac"] #TabsToolbar .titlebar-buttonbox-container { visibility: visible !important; display: -moz-box !important; position: absolute !important; display: flex !important; top: 0 !important; } } |
Dumby > 17-09-2022 11:16:54 |
Dobrov пишет
Ну и где там хоть что-то про автоскрытие панели вкладок (TabsToolbar)? |
Dobrov > 17-09-2022 11:18:00 |
Dumby - Я не уверен, но автоскрытие панели вкладок от Виталия есть в профиле profile_ucf_dobrov, но перестало работать в новых FF. Выделить код Код::root:not([inFullscreen])[v_menubar_autohide="true"] #navigator-toolbox > #nav-bar { margin-top: 0 !important; margin-inline-end: var(--v-titlebar-buttonbox-container-width, 108px) !important; } |
kokoss > 17-09-2022 11:29:08 |
Dobrov |
Dumby > 17-09-2022 12:43:32 |
Dobrov пишет
Если ты про этот код, то его подкосил баг 1767802. скрытый текст Выделить код Код:/* .tabbrowser-tab[first-visible-tab="true"][last-visible-tab="true"] ~ #tabs-newtab-button { */ .tabbrowser-tab[first-visible-tab="true"][last-visible-tab="true"] ~ #tabs-newtab-button, .tabbrowser-tab[first-visible-tab="true"][last-visible-tab="true"] ~ #tabbrowser-arrowscrollbox-periphery > #tabs-newtab-button { |
Dobrov > 17-09-2022 14:14:00 |
Dumby - спасибо, заработало! Исправил также этот ucf_autohidetabstoolbar.js в шапке. |
LGS > 17-09-2022 18:49:53 |
Dumby, подскажите, что можно изменить в скрипте Simple Session Manager, чтобы заработало в FF68 и 78..? |
kazarin > 17-09-2022 19:46:23 |
LGS |
LGS > 17-09-2022 20:30:24 |
kazarin |
Dumby > 17-09-2022 20:53:13 |
LGS пишет
Что-то я не понял, там же четыре «?.» оператора, которые надо выгребать, Патч на сохранение. Только это, я не буду там всё тестировать, скрытый текст Выделить код Код:/* async save(excWin) { var io = Cu.getGlobalForObject(Cu).IOUtils; */ io: { get OS() { delete this.OS; Cu.import("resource://gre/modules/osfile.jsm", this); return this.OS; }, makeDirectory(path) { return (this.makeDirectory = this.OS.File.makeDir)(path); }, writeJSON(path, obj) { var wa = this.OS.File.writeAtomic; return (this.writeJSON = (path, obj) => wa(path, JSON.stringify(obj)))(path, obj); } }, async save(excWin) { var io = Cu.getGlobalForObject(Cu).IOUtils || this.io; |
kazarin > 17-09-2022 21:15:27 |
LGS (окно одно, в профиле всё as is, ничего не менялось) Проверил отдельный скрипт из шапки. Отлично работает на 102. На 68 на старых UCF ожидаемо не завёлся. На 78 - есть кнопка, подхватывает .json от CB, но не сохраняет, не переименовывает и не удаляет сессии. Покопался немного по форуму и нашёл следующее. То есть этот скрипт, по-видимому, ниже 91 работать и не будет, а более ранние версии существуют только в виде кастомной кнопки. Dumby |
Dumby > 17-09-2022 21:42:50 |
kazarin пишет
Точно. Это я глупость написал. Вторая попытка. |
LGS > 17-09-2022 21:53:43 |
Dumby Dumby пишет
На 78 (esr и Вин10 x64) заработало все: сохранение, восстановление, удаление, переименование и даже иконки у менюшек. 68esr и Вин10 x64 кнопка не создается, наверное что-то локальное у меня. Dumby пишет
Конечно, сам погоняю, посмотрю что всплывет. Только мне стыдно спросить - что такое STR..? Add: Оказывается, работало (попытка 1) до перезагрузки компа. Теперь проверяю "попытку 2". |
LGS > 17-09-2022 22:26:40 |
kazarin kazarin пишет
На 78 попытка 2 тоже работает, как и первая. Только не знаю как будет после перезагрузки компьютера. |
kazarin > 17-09-2022 22:28:20 |
Dumby LGS Да, у меня тоже не появляется в 68. А в Еноте есть)) |
LGS > 17-09-2022 22:50:16 |
kazarin kazarin пишет
Значит кэш не очистился. После правки "попытки 1" браузер (78) однозначно перезагружался с кнопки очистки кэша и все работало. После перезагрузки компа (нужно было на ВинХР енот проверить) все слетело. |
Dumby > 17-09-2022 22:58:41 |
LGS пишет
Конечно не создаётся. Оператор «?.» это не какая-то там ошибка в работе кода, Уж не знаю что за Енот68, но значит там поддержка этого оператора есть.
Steps To Reproduce (шаги по воспроизводству), Пример. Допустим, обсуждаемый код работает. STR: Запускаем Firefox 78. Инициируем в кнопке сохранение сессии. AR: Выделение не происходит. Ну, это баг такой в лисе, можно и в простом alert'е увидеть. |
LGS > 17-09-2022 23:25:57 |
Dumby Dumby пишет
Благодарю за науку и помощь со скриптами! Dumby пишет
Это MyPal, человек его на базе 68esr делает для ХР и уже, вроде, кое-что от 78 туда впихнул. Поэтому скрипт и работает. |
Dumby > 18-09-2022 00:01:16 |
LGS скрытый текст Выделить код Код:.... //if (old != trg) old?.removeAttribute("boot"); if (old != trg) old && old.removeAttribute("boot"); .... //if (arg.constructor.isInstance?.(arg)) { if (arg.constructor.isInstance && arg.constructor.isInstance(arg)) { .... //win.document.querySelector(this.skd)?.removeAttribute("maxwidth"); var menu = win.document.querySelector(this.skd); menu && menu.removeAttribute("maxwidth"); .... //: this.dragData?.mouse && e.preventDefault() : this.dragData && this.dragData.mouse && e.preventDefault() |
kazarin > 18-09-2022 00:14:26 |
Dumby LGS скрытый текст Выделить код Код:#${pid} [value=removeSession] { list-style-image: url("resource://usercontext-content/cart.svg"); } #${pid} [value=deleteAllSessions] { list-style-image: url("resource://usercontext-content/cart.svg"); } Разнёс на две, 68, видимо, не понимает перечисления, что обычный esr, что енот. |
LGS > 18-09-2022 00:40:21 |
Dumby Dumby пишет
Да, извиняюсь, не совсем точно сформулировал. Думал, что ESR не так важно. А про енота вы и так не знали. kazarin пишет
На 68esr заработало: сохраняет, восстанавливает, переименовывает. Только не удаляет. 18-09-2022 00:47:20 kazarin пишет
Спасибо, теперь совсем красиво. |
Dobrov > 18-09-2022 02:14:40 |
Dumby - спасибо за адаптацию ucf_SessionManager! Выделить код Код:(async (tc) => addEventListener("wheel", e => { if (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) return; e.stopPropagation(); e.preventDefault(); tc.advanceSelectedTab(e.deltaY < 0 ? 1 : -1, true); }, true, tc || 1))(gBrowser.tabContainer); kazarin пишет
LGS спрашивал про ucf_SessionManager.js, которому не нужен ucf_hookClicks. "Из этих" зависят только attrsInspector.js, ucf_mousedrag.js, ucf_QuickToggle.js. |
Dumby > 18-09-2022 22:54:40 |
Dobrov пишет
Что там может не пахать скрытый текст Выделить код Код:(async tc => { var args = ["wheel", e => { if (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) return; e.stopPropagation(); e.preventDefault(); tc.advanceSelectedTab(e.deltaY < 0 ? 1 : -1, true); }, true]; tc.addEventListener(...args); var id = Symbol(); this.unloadlisteners.push(id); this[id] = {destructor: () => tc.removeEventListener(...args)}; })(gBrowser.tabContainer); Выделить код Код:var UcfStylesScripts = { ....... scriptschrome: { // Для докум. окна браузера [ChromeOnly] domload: [ // По событию "DOMContentLoaded" ], load: [ // По событию "load" ....... { path: "advanceSelectedTab.js", ucfobj: true }, ], }, |
kazarin > 19-09-2022 01:39:48 |
Dobrov пишет
Да мы уже разобрались)) Просто моей первой мыслью, раз иконка есть, а скрипт не пашет, было, что взят скрипт, который работает с перехватом. Dobrov пишет
А неужели так много там экономится, чтоб он был так уж нужен? |
Dobrov > 19-09-2022 13:16:24 |
kazarin пишет
Да, например отдельно в кнопке меню ucf_QuickToggle.js такое очень сложно сделать, а используя hookClicks всё намного проще: kazarin пишет
проверил, получается, нужен Firefox 84+, на нём всё ОК, на FF78 получил ошибку создания массива: |
kazarin > 19-09-2022 15:53:30 |
Dobrov, спасибо, понятно. Ну в общем это облегчает работу для скриптодела)) Dobrov пишет
Да это понятно, интересна была работа на 78. |
LGS > 22-09-2022 13:05:02 |
Подскажите, кто знает... или как думает, можно ли этот скрипт, или этот, или вот такой скрипт+стиль впихнуть в заголовок фокса..? Ну, т.е. чтобы версия, дата и время отображались в заголовке, а не в панели меню. Или такое технически невозможно..? |
kokoss > 24-09-2022 11:34:52 |
Dumby |
_zt > 25-09-2022 03:01:14 |
kokoss |
_zt > 25-09-2022 04:05:23 |
Dumby |
Dumby > 25-09-2022 10:50:53 |
kokoss пишет
Хорошо, попробую. Это в custom_script.js скрытый текст Выделить код Код:Services.obs.addObserver(function brw(win, topic) { Services.obs.removeObserver(brw, topic); var {Downloads: d, BrowserWindowTracker: bwt} = win; var show = function(download) { download.newDownloadNotified || bwt.getTopWindow(this)?.DownloadsPanel.showPanel(); }; ["PUBLIC", "PRIVATE"].forEach(async (type, ind) => { var view = Object.create(null); view.private = Boolean(ind); view.onDownloadChanged = show; (await d.getList(d[type])).addView(view); }); }, "browser-delayed-startup-finished"); _zt пишет
«положение поиска» это какие папки развёрнуты? скрытый текст Выделить код Код:/* tree.scrollByLines(Math.round(newFirst - first)); } */ tree.scrollByLines(Math.round(newFirst - first)); this.persist(tree.view); }, persist(view) { var du = document.documentURI, xs = Services.xulStore; var obf = PlacesUIUtils.obfuscateUrlForXulStore, set = obf ? u => xs.setValue(du, obf(u), "open", "true") : u => xs.setValue(du, u, "open", "true"); (this.persist = view => { for(var node of view._rows) node.containerOpen && set(node.uri) })(view); } |
xrun1 > 25-09-2022 13:40:58 |
_zt, voqabuhe Выделить код Код:load: [ // По событию "load" { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar { path: "cs_win/SidebarBookmarkSearchOpenFolder.uc.js", ucfobj: false, }, |
kokoss > 25-09-2022 14:25:55 |
_zt пишет
Уже нет, при чём эта настройка уже не помню с какой версии перестала работать, как и настройка > browser.download.improvements_to_download_panel = false, отвалилась после обновления на 105. Dumby пишет
Благодарю!!! |
Dumby > 25-09-2022 16:32:42 |
xrun1 пишет
Special Widgets грузится в объект ucf_custom_script_win А закладки в сайдбаре — это другое окно (bookmarksSidebar.xhtml). Опусти глаза чуть пониже. Пример для Библиотеки видишь? Вот туда. Типа |
_zt > 25-09-2022 16:41:59 |
Dumby ShowBookmarkFolder_ucf.js Выделить код Код:// Пункт контекстного меню закладок "Показать в папке", от Dumby, // работает во всех документах - окно, вкладка, сайдбар. // Появляется при не пустой строке поиска. // https://forum.mozilla-russia.org/viewtopic.php?pid=799551#p799551 // + https://forum.mozilla-russia.org/viewtopic.php?pid=801732#p801732 try {({ run(func) { var topics = ["quit-application-granted", "chrome-document-loaded"]; var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); for(var t of topics) obs.addObserver(this, t, false); this.observe = (subj, topic) => this[topic[0]](subj); this.q = () => topics.forEach(t => obs.removeObserver(this, t)); this.run = async doc => { var code = `(${func})(document.getElementById("placesContext_editSeparator"));`; var ps = await doc.ownerGlobal.ChromeUtils .compileScript("data:charset=utf-8," + encodeURIComponent(code)); (this.run = ps.executeInGlobal.bind(ps))(doc); } var re = /\/(?:places|bookmarksSidebar)\.xhtml$/; this.c = doc => re.test(doc.documentURI) && this.run(doc); } }).run(sep => { var label = "Показать в папке"; var popup = sep.parentNode, listener = { handleEvent() { if (this.shouldHide) return; var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("label", label); menuitem.setAttribute("oncommand", "creator.goParentFolder();"); menuitem.creator = this; sep.before(menuitem); this.handleEvent = e => { if (e.target != popup) return; var sh = this.shouldHide; if (Boolean(menuitem.clientHeight) ^ sh) return; if ((menuitem.hidden = sh)) return; menuitem.disabled = false; } }, get shouldHide() { var node = popup._view.selectedNodes.length == 1 && popup._view.selectedNode; return !(node && PlacesUtils.nodeIsBookmark(node) && node.parent.type == node.RESULT_TYPE_QUERY); }, get goParentFolder() { var tree = popup._view; if (tree.id.startsWith("b")) { delete this.library; var func = () => this.sidebar(tree); } else { delete this.sidebar; var list = document.getElementById("placesList"); var func = () => this.library(popup._view, list); } delete this.goParentFolder; return this.goParentFolder = func; }, sidebar(tree) { var {bookmarkGuid} = tree.selectedNode; if (tree.result.root.uri.startsWith("place:terms=")) tree.place = tree.place; tree.selectItems([bookmarkGuid]); this.scroll(tree); }, async library(tree, list) { var {bookmarkGuid} = tree.selectedNode; var {parentGuid} = await PlacesUtils.bookmarks.fetch(bookmarkGuid); if (PlacesUtils.getConcreteItemGuid(list.selectedNode) == parentGuid) list.selectItems([PlacesUtils.virtualAllBookmarksGuid]); else { var rows = list.view._rows, lastRow = rows[rows.length - 1]; if (lastRow.bookmarkGuid == PlacesUtils.virtualAllBookmarksGuid) lastRow.containerOpen = true; } list.selectItems([parentGuid]); this.scroll(list); tree.selectItems([bookmarkGuid]); await new Promise(requestAnimationFrame); this.scroll(tree); }, scroll(tree) { var pos = .4, visibleRows = tree.getPageLength(); var ind = tree.view.selection.currentIndex; var first = tree.getFirstVisibleRow(); var newFirst = ind - pos*visibleRows + 1; // tree.scrollByLines(Math.round(newFirst - first)); // } tree.scrollByLines(Math.round(newFirst - first)); this.persist(tree.view); }, persist(view) { var du = document.documentURI, xs = Services.xulStore; var obf = PlacesUIUtils.obfuscateUrlForXulStore, set = obf ? u => xs.setValue(du, obf(u), "open", "true") : u => xs.setValue(du, u, "open", "true"); (this.persist = view => { for(var node of view._rows) node.containerOpen && set(node.uri) })(view); } // <<< }; popup.addEventListener("popupshowing", listener); addEventListener("unload", () => popup.removeEventListener("popupshowing", listener) , {once: true}); });} catch(ex) {Cu.reportError(ex);} Подключается или в custom_script или в CustomStylesScripts.jsm в секцию scriptsbackground: [ // В фоне [System Principal] { path: "cs/ShowBookmarkFolder_ucf.js", }, 25-09-2022 16:54:17 Dumby А можете еще переместить пункт в самый верх меню и добавить после него сепаратор? |
Inko7 > 25-09-2022 17:16:39 |
Подскажите по такому вопросу: Как подсказывают, стилем нельзя. Как это сделать с помощью скрипта? |
xrun1 > 25-09-2022 20:03:57 |
Dumby _zt пишет
Если бы загрузки тоже отображались в Sidebar'е, окно библиотек мне вообще не нужно. |
kokoss > 25-09-2022 22:11:01 |
xrun1 пишет
Может ещё работает в актуальной версии > https://forum.mozilla-russia.org/viewto … 24#p784824 |
Dumby > 25-09-2022 22:15:17 |
_zt пишет
Не исключено. Замена начала кода скрытый текст Выделить код Код:try {({ run(func) { var topics = ["quit-application-granted", "chrome-document-loaded"]; var obs = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService); for(var t of topics) obs.addObserver(this, t, false); this.observe = (subj, topic) => this[topic[0]](subj); this.q = () => topics.forEach(t => obs.removeObserver(this, t)); this.run = async doc => { var code = `(${func})(document.getElementById("placesContext"));`; var ps = await doc.ownerGlobal.ChromeUtils .compileScript("data:charset=utf-8," + encodeURIComponent(code)); (this.run = ps.executeInGlobal.bind(ps))(doc); } var re = /\/(?:places|bookmarksSidebar)\.xhtml$/; this.c = doc => re.test(doc.documentURI) && this.run(doc); } }).run(popup => { var label = "Показать в папке", listener = { handleEvent() { if (this.shouldHide) return; var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("label", label); menuitem.setAttribute("oncommand", "creator.goParentFolder();"); menuitem.creator = this; var sep = document.createXULElement("menuseparator"); popup.prepend(menuitem, sep); this.handleEvent = e => { if (e.target != popup) return; var sh = this.shouldHide; if (!( Boolean(menuitem.clientHeight) ^ sh || (menuitem.hidden = sep.hidden = sh) )) menuitem.disabled = false; } }, Inko7 пишет
Ясен пень нельзя. Стили не занимаются отслеживанием запуска и перемещением фокуса. скрытый текст Выделить код Код:Services.obs.addObserver(function wr(win, topic) { Services.obs.removeObserver(wr, topic); var re = /^about:(?:newtab|home)$/; var fs = 'data:,content.document.getElementById("newtab-search-text").focus();'; Array.from(CustomizableUI.windows).forEach(async win => { await win.gBrowserInit.firstContentWindowPaintPromise; var br = win.gBrowser.selectedBrowser; if (re.test(br.currentURI.spec)) br.focus(), br.messageManager.loadFrameScript(fs, false); }); }, "sessionstore-windows-restored"); |
xrun1 > 25-09-2022 23:07:54 |
kokoss |
_zt > 25-09-2022 23:18:31 |
Dumby kokoss пишет
Работает, только что проверил на 105. kokoss пишет
Работает. |
kokoss > 25-09-2022 23:44:14 |
_zt пишет
А у меня не работает! Работает, если в настройках включена опция"Сохранять файлы", что для меня не вариант, о чём я сообщил здесь > https://forum.mozilla-russia.org/viewtopic.php?pid=801691#p801691 |
xrun1 > 26-09-2022 02:41:39 |
Интересно, что Sidebar Tabs у меня не установлен, о чём сказал выше. А вот кнопка для него стоит, как раз для загрузок (спойлер в п.2). Запасливый, однако! |
_zt > 26-09-2022 07:06:23 |
kokoss |
Inko7 > 26-09-2022 11:01:47 |
Dumby Dumby пишет
Срабатывает как надо, но только один раз при старте браузера. |
Dumby > 27-09-2022 08:33:14 |
Inko7 пишет
Это что ещё за «но»? скрытый текст Выделить код Код:data:image/png;base64,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 |
Inko7 > 27-09-2022 13:32:33 |
Dumby |
Dumby > 27-09-2022 14:39:47 |
Inko7 пишет
Даже не знаю, может подойдёт вариант "вообще всегда"? скрытый текст Выделить код Код:(async fsu => { var beg = "resource:///actors/AboutNewTabParent."; try {var exp = ChromeUtils.importESModule(beg + "sys.mjs");} catch {exp = ChromeUtils.import(beg + "jsm");} var proto = exp.AboutNewTabParent.prototype; var rm = proto.receiveMessage; Object.assign(proto, {async receiveMessage(message) { if (message.name == "AboutNewTabVisible") { var br = this.browsingContext.top.embedderElement; br.focus(); br.messageManager.loadFrameScript(fsu, false); } return rm.call(this, message); }}); })("data:,content.document.getElementById('newtab-search-text').focus();"); |
LGS > 27-09-2022 19:31:24 |
Dumby, скажите, пожалуйста, это осуществимо или нет..? |
Inko7 > 27-09-2022 20:07:18 |
Dumby пишет
Отлично! Спасибо! |
LGS > 28-09-2022 18:15:07 |
Dumby, посоветовали ваш скрипт для удаления "Панели закладок", "Меню закладок" и "Другие закладки" в боковой панели. Срабатывает отлично на версиях с 68 по 105 с небольшим побочным эффектом: на разделителях между папками появляется разрыв: |
Dumby > 29-09-2022 16:24:35 |
LGS пишет
Да особо сказать нечего. Можно разве что текст подменить. Ещё можно какой-нибудь <panel> поверх заголовка отобразить, скрытый текст Выделить код Код:(async (n, id) => { var css = ` #${id} { margin-bottom: 2px; margin-right: 102px; border: 0; height: 18px; padding: 0 2px; -moz-appearance: none; background-color: transparent; } :root[sizemode=normal] #${id} { margin-bottom: 3px; } :root[sizemode=fullscreen] #${id} { visibility: collapse; } #${id} > hbox { color: white; height: 18px; font-weight: bold; background-color: red; } #${id} > hbox > box { padding: 0 4px; } `; var ucs = { esr: "ESR", beta: "Beta", release: "Release", nightly: "Nightly", aurora: "DevEdition", default: "Unbraindead", // ? }; var format = {weekday: "long", day: "numeric", month: "long", year: "numeric"}; var attrs = { id, noautohide: true, noautofocus: true, position: "before_end", consumeoutsideclicks: "never" }; css = css.replace(/;/g, " !important;"); var url = "data:text/css;charset=utf-8," + encodeURIComponent(css); windowUtils.loadSheetUsingURIString(url, windowUtils.USER_SHEET); var panel = n("panel"); var hbox = panel.appendChild(n("hbox")); for(var args of Object.entries(attrs)) panel.setAttribute(...args); document.getElementById("mainPopupSet").append(panel); var num = 3; while(num--) hbox.appendChild(n("box")).append(""); var [vers, time, date] = Array.from(hbox.children, b => b.firstChild); var arr = [ Services.appinfo.name, "v" + AppConstants.MOZ_APP_VERSION_DISPLAY, `(${Services.appinfo.is64Bit ? 64 : 32}-bit)` ]; var c = AppConstants.MOZ_UPDATE_CHANNEL, uc = ucs[c]; if (uc) { if (c == "esr") arr[1] = arr[1].slice(0, -3); arr.splice(1, 0, uc); } vers.data = arr.join(" "); var cd; var tick = () => { var dt = new Date(), d = dt.getDate(); if (d != cd) cd = d, upd(dt); time.data = dt.toLocaleTimeString("mn"); } var upd = d => date.data = d.toLocaleDateString("ru", format); tick(); window.setInterval(tick, 1e3); panel.ondblclick = e => { if (e.button) return; panel.collapsed = true; windowState == STATE_MAXIMIZED ? restore() : maximize(); panel.collapsed = false; } panel.openPopup(document.documentElement); var sr = panel.shadowRoot; if (sr) sr.firstChild.removeAttribute("part"); })(nn => document.createXULElement(nn), "vtd-info-panel");
Скрипт ничего не удаляет.
Не знаю. Ничего хорошего не придумал. Если пишу А если пишу
Да я пробовал раньше. И не раз. И ничего не получилось. |
LGS > 29-09-2022 18:13:08 |
Dumby Dumby пишет
На Win10 почти идеально выглядит без правок: Dumby пишет
Этот вариант мне больше понравился... сдвинутый влево почему-то глаз режет, а немного укороченный справа не напрягает совсем. Dumby пишет
Разве такое может быть..? |
xrun1 > 20-10-2022 14:09:39 |
В 106 отвалился "Пункт для контекстного меню адресной строки, подставляющий модификаторы поиска". |
Farby > 20-10-2022 15:51:22 |
xrun1 пишет
попробовал запустить код через userCromeJS от Ксяо на 106.0.1, не заработала только очистка мышкой #searchbar. брал из второго спойлера с пометкой Update, может в этом проблема... |
Dumby > 20-10-2022 16:22:25 |
xrun1 |
xrun1 > 20-10-2022 17:14:18 |
Dumby |
sn260591 > 01-11-2022 13:47:13 |
Подскажите код, который осуществляет перезапуск браузера с текущими аргументами командной строки. Взятый отсюда https://forum.mozilla-russia.org/viewto … 43#p798943 перезапускает без аргументов. |
Dobrov > 06-11-2022 06:44:50 |
Обновил UserChromeFiles и Demo-ПРОФИЛЬ для Firefox 84+ Если оформление браузера «неправильное», скачайте aris-t2 стиль, соответствующий вашей версии Firefox. |
LGS > 07-11-2022 15:06:53 |
Dumby, можно заставить работать эти скрипты FirefoxTaskManager part1, part2 (не знаю, почему автор разбил на две части) и aboutconfig_menu.uc.js в 68ESR..? Размеры, конечно, не хилые, но, может, посмотрите, что можно сделать..? |
Dumby > 07-11-2022 18:57:19 |
LGS пишет
Сначала убрать, на всякий случай, строку console.log("aboutconfig_menu.uc.js"); И должно работать. Ну, иконку ещё заменить, в 68 нет никакого «ion.svg». А FirefoxTaskManager — вот тут не знаю. |
LGS > 07-11-2022 20:53:00 |
Dumby Dumby пишет
Спасибо, работает. Dumby пишет
|
Dumby > 08-11-2022 13:38:06 |
LGS пишет
Вторжение есть, div.tabBars добавляется в табский vbox.tab-background Насчёт позиционирования, оно работает, если .tab-content'у назначить position: relative Кстати вот про «не знаю, почему автор разбил на две части», Итак, part2. part1 скрытый текст Выделить код Код:/* var insertNode = tabNode.getElementsByClassName("tab-content")[0]; */ var insertNode = document.getAnonymousElementByAttribute(tabNode, "class", "tab-content"); /* var close_button = tabNode.getElementsByClassName("tab-content")[0].getElementsByClassName("tab-close-button")[0]; */ var close_button = insertNode.querySelector(":scope > .tab-close-button"); /* if ( _btnNode ) btnNode = _btnNode.getElementsByClassName("toolbarbutton-badge-stack")[0]; */ if (_btnNode) btnNode = document.getAnonymousElementByAttribute(_btnNode, "class", "toolbarbutton-badge-stack"); /* contParent = document.createXULElement("div"); */ contParent = document.createXULElement("box"); |
LGS > 08-11-2022 18:43:43 |
Dumby, круто, как всегда, огромное спасибо: Только пришлось помимо четырех строк еще три заменить, а то консоль ошибки выдавала и по щелчку ЛКМ в окошке с голубым фоном значения не выводились: скрытый текст // var menu_task_obj = win.documen.getElementsByClassName( "fftm_widget_task" )[i; var menu_task_obj = document.getElementById( "fftm_widget_task_"+i ); // var fftm_widget = win.documen.getElementsByClassName("fftm_widget_class")[0]; // var _btnNode = win.documen.getElementsByAttribute("data-extensionid",addonId)[0]; Хорошо, что у автора они прописаны были выше под комментариями (стр. 700, к примеру)... наугад попробовал строку с ошибкой закомментировать, авторскую активировать - получилось. |
Dumby > 08-11-2022 19:14:08 |
LGS пишет
Видимо реплейс «.body» прошёл кривовато. |
LGS > 08-11-2022 19:35:15 |
Dumby пишет
Мой косяк, когда в редакторе замену делал document.body на document букву t потерял. В оригинале все нормально. Странно, что вообще сработала замена трех строк. Вернул букву t, три строки привел в первоначальное состояние - все нормально. Невнимательность повлекла за собой лишние телодвижения. |
xrun1 > 17-11-2022 16:47:05 |
Случайно заметил, что обновился скрипт от Alice0775 memoryMinimizationButton.uc.js. Убрал 3 сообщения слева снизу и заменил "всплывашкой". Кнопка у меня в боковой панели, добавил отступ - в v.107 прижалась влево к границе окна. Если кто пользуется, в CustomStylesScripts.jsm секция load: [ // По событию "load" скрытый текст Выделить код Код:// ==UserScript== // https://raw.githubusercontent.com/alice0775/userChrome.js/master/108/memoryMinimizationButton.uc.js // @name memoryMinimizationButton.uc.js // @namespace http://space.geocities.yahoo.co.jp/gl/alice0775 // @description memory minimization button // @charset utf-8 // @include main // @include about:processes?memoryMinimizationButton // @compatibility Firefox 108 // @author Alice0775 // @version 2022/10/18 10:00 fix Bug 1790616 // @version 2022/06/18 00:00 kil process // @version 2018/10/09 00:00 fix CSS // @version 2018/09/07 23:00 fix initial visual status // ==/UserScript== var memoryMinimizationButton = { get memoryMinimizationButton(){ return document.getElementById("memoryMinimizationButton"); }, get statusinfo() { if ("StatusPanel" in window) { // fx61+ return StatusPanel._labelElement.value; } else { return XULBrowserWindow.statusTextField.label; } }, set statusinfo(val) { if ("StatusPanel" in window) { // fx61+ StatusPanel._label = val; } else { XULBrowserWindow.statusTextField.label = val; } if(this._statusinfotimer) clearTimeout(this._statusinfotimer); this._statusinfotimer = setTimeout(() => {this.hideStatusInfo();}, 2000); this._laststatusinfo = val; return val; }, init: function() { let style = ` #memoryMinimizationButton { width: 16px; height: 16px; margin-left: 5px; /* со 107-й сломалось, добавил */ list-style-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAAFdSURBVFhH7VbLbsMwDMsef5dc8z/53F13GXZYm5kaZciqnKro2hxaAkRkmkqI2gI6KNZ1vStPEJluyS6WZVlB3xDpWc3q/Ewf6ASClwicLkhojc5PxaDvgQIU4dWSPjEa/Z1y1ed5fqPUeCmJVhAGUC9YNzz4ghNEelYDrI5aAozjeNyD5QBqgF34DJAN8GN4oGb3cJ527fftumEqgAVurdk7Um680zR92bXWEdMBWB+s14+TegFf93hpgF5dgylK/cFSPSGvOgKA9afWgP4y+lR/xKuOwMN6AdwFXff4H0eAqfhWnU9Mhdx+rrtMBSjER3TUtLYaqOMYjaldN8wGuBmfAWqAcmMPe1ACYF6lIBUZXXFO29I3/5IVoFMpcLoA2iX96gVLiBb0bb6gINSy/WLsgb4HDgBD0BzqXsv0i8nDm+/JCC8lKW5zY4SGvT9LBdbVS0g/64q4fxh+AZvdJHHKcZdFAAAAAElFTkSuQmCC'); } @media (min-resolution: 1.1dppx) { #memoryMinimizationButton { width: 32px; height: 32px; } } `.replace(/\s+/g, " "); let sss = Components.classes['@mozilla.org/content/style-sheet-service;1'] .getService(Components.interfaces.nsIStyleSheetService); let newURIParam = { aURL: 'data:text/css,' + encodeURIComponent(style), aOriginCharset: null, aBaseURI: null } let cssUri = Services.io.newURI(newURIParam.aURL, newURIParam.aOriginCharset, newURIParam.aBaseURI); if (!sss.sheetRegistered(cssUri, sss.AUTHOR_SHEET)) sss.loadAndRegisterSheet(cssUri, sss.AUTHOR_SHEET); if (this.memoryMinimizationButton) return; ChromeUtils.import("resource:///modules/CustomizableUI.jsm"); try { CustomizableUI.createWidget({ //must run createWidget before windowListener.register because the register function needs the button added first id: 'memoryMinimizationButton', type: 'custom', defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(aDocument) { var toolbaritem = aDocument.createElementNS('http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul', 'toolbarbutton'); var props = { id: "memoryMinimizationButton", class: "toolbarbutton-1 chromeclass-toolbar-additional", tooltiptext: "Memory minimization(shift+click; kill other tabs)", oncommand: "memoryMinimizationButton.doMinimize(event);", type: CustomizableUI.TYPE_TOOLBAR, label: "Memory minimization", removable: "true" }; for (var p in props) { toolbaritem.setAttribute(p, props[p]); } return toolbaritem; }, }); } catch(ee) {} }, doMinimize: function(event) { function doGlobalGC() { Services.obs.notifyObservers(null, "child-gc-request"); Cu.forceGC(); } function doCC() { Services.obs.notifyObservers(null, "child-cc-request"); if (typeof window.windowUtils != "undefined") window.windowUtils.cycleCollect(); else window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils).cycleCollect(); } function doMemMinimize(event) { if (event.button == 1 || event.shiftKey || event.altKey || event.ctrlKey) memoryMinimizationButton.kill(); Services.obs.notifyObservers(null, "child-mmu-request"); var gMgr = Cc["@mozilla.org/memory-reporter-manager;1"] .getService(Ci.nsIMemoryReporterManager); // gMgr.minimizeMemoryUsage(() => {if (!(event.button == 1 || event.shiftKey || event.altKey)) memoryMinimizationButton.displayStatus("Memory minimization done")}); gMgr.minimizeMemoryUsage(() => {if (!(event.button == 1 || event.shiftKey || event.altKey)) memoryMinimizationButton.displayStatus("")}); } function sendHeapMinNotifications() { function runSoon(f) { var tm = Cc["@mozilla.org/thread-manager;1"] .getService(Ci.nsIThreadManager); tm.mainThread.dispatch({ run: f }, Ci.nsIThread.DISPATCH_NORMAL); } function sendHeapMinNotificationsInner() { var os = Cc["@mozilla.org/observer-service;1"] .getService(Ci.nsIObserverService); os.notifyObservers(null, "memory-pressure", "heap-minimize"); if (++j < 3) runSoon(sendHeapMinNotificationsInner); } var j = 0; sendHeapMinNotificationsInner(); } // this.displayStatus("Memory minimization start") doGlobalGC(); doCC(); //sendHeapMinNotifications(); // Добавил всплывашку setTimeout((event)=> {doMemMinimize(event);}, 1000, event); var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); alertsService.showAlertNotification("chrome://user_chrome_files/content/custom_styles/icons/information-16.png", "Memory", "Потребление памяти минимизировано!"); setTimeout(() => alertsService.closeAlert(), 2000); }, _statusinfotimer: null, _laststatusinfo: null, displayStatus: function(val) { this.statusinfo = val; }, hideStatusInfo: function() { if(this._statusinfotimer) clearTimeout(this._statusinfotimer); this._statusinfotimer = null; if (this._laststatusinfo == this.statusinfo) this.statusinfo = ""; }, kill: function() { this.browser = document.createXULElement("browser"); this.browser.src = "about:processes?memoryMinimizationButton"; document.documentElement.appendChild(this.browser); setTimeout(() => { this.browser.src = "about:blank"; document.documentElement.removeChild(this.browser); delete this.browser; // Services.console.logStringMessage("killing done"); // this.displayStatus("Memory minimization done") }, 8000); } } if (location.href == "chrome://browser/content/browser.xhtml") { memoryMinimizationButton.init(); } else if (location.href == "about:processes?memoryMinimizationButton") { // Services.console.logStringMessage("killing start"); setTimeout(() => { let closeButtons = document.querySelectorAll("tr.process > td.close-icon"); for(let closeButton of closeButtons) { let row = closeButton.parentNode; let canKill = true; for (let childRow = row.nextSibling; childRow && !childRow.classList.contains("process"); childRow = childRow.nextSibling ) { let win = childRow.win; if (win?.tab?.tab?.selected) { canKill = false; break; } } if (canKill) Control._handleKill(closeButton); } return; /* let closeButtons = document.querySelectorAll("tr.process > td.close-icon"); for(let closeButton of closeButtons) { closeButton.click(); } */ }, 5000); } И кнопка в панель адреса, вроде от Dumby, ссылки нет. scriptsbackground: [ // В фоне [System Principal] скрытый текст Выделить код Код:(async id => ({ delay: 2e3, val: "", init(topic, mm) { Services.obs.addObserver(mm = this, topic); Services.obs.addObserver(function quit(s, t) { this.timer?.cancel(); Services.obs.removeObserver(mm, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); }, observe(win) { var df = win.MozXULElement.parseXULToFragment( `<hbox id="${id}" tooltiptext="${ "ЛКМ: Минимизировать потребление памяти
ПКМ: about:performance
Ctrl+ПКМ: about:debugging#/runtime/this-firefox" }" onclick="event.button || ${ "memoryMinimizationButton.doMinimize(event)" }"><label id="${id += "-label"}"/></hbox>` ); this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); (this.observe = async win => { this.timer.cancel(); await new Promise(ChromeUtils.idleDispatch); var clone = win.document.importNode(df, true); clone.firstChild.oncontextmenu = this.about; win.document.getElementById("star-button-box").after(clone); this.notify(); })(win); }, about(e) { var gb = e.view.gBrowser; gb.selectedTab = gb.addTrustedTab(`about:${ e.ctrlKey ? "debugging#/runtime/this-firefox" : "performance" }`); }, async notify() { var info = await ChromeUtils.requestProcInfo(); var bytes = info.memory; for(var child of info.children) bytes += child.memory; this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT); var prev = this.val; if ((this.val = this.mgb(bytes)) != prev) for(var win of CustomizableUI.windows) { var lab = win.document.getElementById(id); if (lab) lab.value = this.val; } }, mgb: bytes => bytes < 1073741824 ? Math.round(bytes / 1048576) + "MB" : (bytes / 1073741824).toFixed(2) + "GB" }).init("browser-delayed-startup-finished"))("ucf-mem-indicator"); Если что напутал, поправьте. UPD: Скрипт заменил на 108+ |
_zt > 19-11-2022 16:19:27 |
xrun1 |
xrun1 > 20-11-2022 11:07:13 |
_zt пишет
Это функция и вызов её закомментарил, там всего одно место как раз перед моей "всплывашкой". Правильно это или что-то ф-ция делает ещё - не знаю... |
_zt > 21-11-2022 09:07:26 |
xrun1 скрытый текст Выделить код Код:var memoryMinimizationButton = { get memoryMinimizationButton(){ return document.getElementById("memoryMinimizationButton"); }, doMinimize: function(event) { function doGlobalGC() { Services.obs.notifyObservers(null, "child-gc-request"); Cu.forceGC(); } function doCC() { Services.obs.notifyObservers(null, "child-cc-request"); if (typeof window.windowUtils != "undefined") window.windowUtils.cycleCollect(); else window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils).cycleCollect(); } function doMemMinimize(event) { memoryMinimizationButton.kill(); Services.obs.notifyObservers(null, "child-mmu-request"); var gMgr = Cc["@mozilla.org/memory-reporter-manager;1"] .getService(Ci.nsIMemoryReporterManager); } doGlobalGC(); doCC(); // Всплывашка setTimeout((event)=> {doMemMinimize(event);}, 1000, event); var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); alertsService.showAlertNotification("chrome://user_chrome_files/content/custom_styles/icons/information-16.png", "Memory Minimization", "Минимизация памяти выполнена!"); setTimeout(() => alertsService.closeAlert(), 2000); }, kill: function() { this.browser = document.createXULElement("browser"); this.browser.src = "about:processes?memoryMinimizationButton"; document.documentElement.appendChild(this.browser); setTimeout(() => { this.browser.src = "about:blank"; document.documentElement.removeChild(this.browser); delete this.browser; }, 8000); } } if (location.href == "about:processes?memoryMinimizationButton") { setTimeout(() => { let closeButtons = document.querySelectorAll("tr.process > td.close-icon"); for(let closeButton of closeButtons) { closeButton.click(); } }, 5000); } |
xrun1 > 21-11-2022 10:33:52 |
_zt пишет
Думаю, нет. Как я понял, по задумке автора по shift+click должны закрываться другие табы. У меня не закрываются. Может потому, что у меня нет кнопки закрытия вкладки, а в этой секции скрипт кликает по ней.)) |
Dumby > 24-11-2022 22:38:38 |
https://hg.mozilla.org/mozilla-central/rev/49cefc94b9bd |
Dumby > 30-11-2022 18:10:46 |
egorsemenov06 пишет
Посмотрел. Такой фигни не вижу. |
unter_officer > 30-11-2022 20:47:16 |
egorsemenov06 пишет
У меня окно кук в 107.0.1 выглядит так: скрытый текст Но после перезапуска окно опять принимает первоначальный вид, т.е. размеры окна не сохраняются. |
Inko7 > 07-12-2022 23:21:36 |
Dumby скрытый текст Выделить код Код:try {(keybUtils => CustomizableUI.createWidget({ type: "custom", id: "SwitchKeyboardLayout", onBuild(doc) { var btn = doc.createXULElement("toolbarbutton"); btn.id = this.id; btn.label = btn.tooltipText = "Switch Keyboard Layout"; btn.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAk1BMVEX///8/Pz8BAQF8fHwJCQkCAgIJCQl8fHx9fX0AAABJSUkBAQENDQ0wMDBVVVUAAABra2t0dHR7e3thYWEBAQEAAAAAAAABAQEAAAAgICABAQEBAQH8/Pzw8PDp6en39/fj4+Pe3t41V9I/YeWKioqDg4N9fX0jRa8wUrVoaGhkhuxWeNx1dXVCZMhvb28kRqsqTL4KidXxAAAAHHRSTlMAAABndwAAAAA0blVZcm1naWhNa6hrcJ8AAKRU4jk/3gAAAHVJREFUeF6FyMUCwjAUBdEbaQupUMOjqMv/fx1dQN6yZ3aDcWnyw6ezoRWNYc15kqKQZCFlgTKQQwgllL/dn5f3+bPb+6P3CpWNw56srdCZOMzDmA61i8O9nKvRaHLVukEryFKIFtnkj7ENYxmNdd5v+5xj1BcJ/w9Kj6K7ZAAAAABJRU5ErkJggg=="; btn.setAttribute("oncommand", "linkedObj.switch(document);"); btn.className = "toolbarbutton-1 chromeclass-toolbar-additional"; btn.linkedObj = this; return btn; }, switch(doc) { var br = doc.activeElement; br && br.localName == "browser" && br.isRemoteBrowser ? br.messageManager.loadFrameScript(this.url, false) : this.keybUtils.switchSelKeybLayout(); }, get url() { delete this.url; return this.url = `data:;charset=utf-8,(${ encodeURIComponent(keybUtils) }).switchSelKeybLayout()`; }, get keybUtils() { delete this.keybUtils; var def = "let{KeyEvent,HTMLInputElement,HTMLTextAreaElement}=Cu.getGlobalForObject(Services);"; var url = `data:;charset=utf-8,${def}%0Athis.keybUtils=${encodeURIComponent(keybUtils)}`; Services.scriptloader.loadSubScript(url, this); var {id} = this; this.keybUtils.getFocusedElement = function(_subCall, _focusFixed) { var window = Services.focus.activeWindow, {document} = window; var button = document.getElementById(id); if( !_focusFixed && "closeMenus" in window && document.commandDispatcher.focusedElement == button ) { window.closeMenus(button); window.setTimeout(function(_this) { _this.switchSelKeybLayout(_subCall, true); }, 0, this); return; } return document.commandDispatcher.focusedElement; } return this.keybUtils; } }))(`{ //== Options noSelBehavior: { // Shift+Home ctrlKey: false, altKey: false, shiftKey: true, metaKey: false, keyCode: KeyEvent.DOM_VK_HOME, charCode: 0 }, // 0 - do nothing // 1 - convert all text // Or use object like following to simulate "keypress" event: convTableForward: { // ru -> en "\\"": "@", ":": "^", ";": "$", "?": "&", ",": "?", "/": "|", ".": "/", "э": "'", "б": ",", "ю": ".", "Ж": ":", "ж": ";", "Б": "<", "Ю": ">", "Э": "\\"", "х": "[", "ъ": "]", "ё": "\`", "Х": "{", "Ъ": "}", "Ё": "~", "№": "#", "Ф": "A", "ф": "a", "И": "B", "и": "b", "С": "C", "с": "c", "В": "D", "в": "d", "У": "E", "у": "e", "А": "F", "а": "f", "П": "G", "п": "g", "Р": "H", "р": "h", "Ш": "I", "ш": "i", "О": "J", "о": "j", "Л": "K", "л": "k", "Д": "L", "д": "l", "Ь": "M", "ь": "m", "Т": "N", "т": "n", "Щ": "O", "щ": "o", "З": "P", "з": "p", "Й": "Q", "й": "q", "К": "R", "к": "r", "Ы": "S", "ы": "s", "Е": "T", "е": "t", "Г": "U", "г": "u", "М": "V", "м": "v", "Ц": "W", "ц": "w", "Ч": "X", "ч": "x", "Н": "Y", "н": "y", "Я": "Z", "я": "z", __proto__: null }, //== End of options get convTableBackward() { var ctb = { __proto__: null }; var ctf = this.convTableForward; for(var c in ctf) ctb[ctf[c]] = c; delete this.convTableBackward; return this.convTableBackward = ctb; }, inPrimaryLayout: function(s) { for(var i = 0, l = s.length; i < l; ++i) { var c = s.charAt(i); /* if(c in this.convTableForward) return true; if(c in this.convTableBackward) return false; */ var primary = c in this.convTableForward; if(primary ^ c in this.convTableBackward) return primary; } return false; }, switchKeybLayout: function(s, convTable) { var res = ""; for(var i = 0, l = s.length; i < l; ++i) { var c = s.charAt(i); res += c in convTable ? convTable[c] : c; } return res; }, getFocusedElement: function() { return Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, {}); }, switchSelKeybLayout: function(_subCall, _focusFixed) { var fe = this.getFocusedElement(_subCall, _focusFixed); if(!fe) return; if(fe instanceof HTMLInputElement || fe instanceof HTMLTextAreaElement) { var ta = fe; try { var val = ta.value; var sel = val.substring(ta.selectionStart, ta.selectionEnd); } catch(e) { // Non-text HTMLInputElement return; } if(!sel && val && this.noSelBehavior && !_subCall) { if(this.noSelBehavior == 1) { ta.selectionStart = 0; ta.selectionEnd = val.length; sel = val; } else { this.handleNoSel(ta); return; } } if(!sel) return; var res = this.switchKeybLayout( sel, this.inPrimaryLayout(sel) ? this.convTableForward : this.convTableBackward ); if(res != sel) this.insertText(ta, res); } else if(fe.contentEditable == "true") { var doc = fe.ownerDocument; var docURI = doc.documentURI; if( docURI.substr(0, 5) == "data:" && docURI.indexOf("chrome://browser/skin/devtools/") != -1 ) { //~ todo: seems like we only can use paste from clipboard here... return; } var sel = doc.defaultView.getSelection(); var rng = sel.rangeCount && sel.getRangeAt(0); var tmpNode; if(!rng || rng.collapsed) { if(!this.noSelBehavior || _subCall) return; if(this.noSelBehavior == 1) { var r = doc.createRange(); r.selectNodeContents(fe); sel.removeAllRanges(); sel.addRange(r); tmpNode = fe.cloneNode(true); } else { this.handleNoSel(fe); return; } } else { tmpNode = doc.createElementNS("http://www.w3.org/1999/xhtml", "div"); tmpNode.appendChild(rng.cloneContents()); } var orig = tmpNode.innerHTML; var convTable = this.inPrimaryLayout(tmpNode.textContent) ? this.convTableForward : this.convTableBackward; var _this = this; var parseChildNodes = function(node) { if(node instanceof Element) { var childNodes = node.childNodes; for(var i = childNodes.length - 1; i >= 0; --i) parseChildNodes(childNodes[i]); } else if(node.nodeType == node.TEXT_NODE) { var text = node.nodeValue; var newText = _this.switchKeybLayout(node.nodeValue, convTable); if(newText != text) node.parentNode.replaceChild(doc.createTextNode(newText), node); } } parseChildNodes(tmpNode); var res = tmpNode.innerHTML; if(res != orig) doc.execCommand("insertHTML", false, res); } }, handleNoSel: function(node) { this.select(node); this.switchSelKeybLayout(true); }, select: function(node) { var e = this.noSelBehavior; if(!e || typeof e != "object") return; /* var evt = new node.ownerGlobal.KeyboardEvent( "keypress", {bubbles: true, cancelable: true, ...e} ); node.dispatchEvent(evt); }, */ if(ChromeUtils.domProcessChild.childID) { var cmd = this.beh2cmd[e.ctrlKey + "_" + e.shiftKey + "_" + e.keyCode]; cmd && docShell.doCommand(cmd); } else node.dispatchEvent(new node.ownerGlobal.KeyboardEvent( "keypress", {bubbles: true, cancelable: true, ...e} )); }, beh2cmd: { // Ctrl_Shift_VK false_true_36: "cmd_selectLinePrevious", // Shift+Home }, insertText: function(ta, text) { //var editor = ta.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor var editor = ta.editor .QueryInterface(Components.interfaces.nsIPlaintextEditor || Ci.nsIEditor); if(editor.flags & editor.eEditorReadonlyMask) return; var sTop = ta.scrollTop; var sHeight = ta.scrollHeight; var sLeft = ta.scrollLeft; // var sWidth = ta.scrollWidth; if(text) editor.insertText(text); else editor.deleteSelection(0, 0); ta.scrollTop = sTop + (ta.scrollHeight - sHeight); ta.scrollLeft = sLeft; // + (ta.scrollWidth - sWidth); } }`)} catch(ex) {Cu.reportError(ex);} гляньте пожалуйста, возможно ли починить? |
Dumby > 08-12-2022 10:18:39 |
Inko7 пишет
Не вижу на 107.0.1 такого. Но, x instanceof *Element лучше заменить на *Element.isInstance(x) |
Inko7 > 08-12-2022 17:21:42 |
Dumby |
Inko7 > 08-12-2022 20:35:40 |
не долго радовался(( скрытый текст Выделить код Код:// Назначить клавишу F8 для исправления раскладки введенного текста // код SwitchKeyboardLayout в файле custom_script.js try {(id => { var listener = { get obj() { var obj = document.getElementById(id); if (obj) obj = obj.linkedObj; else { obj = Cu.import("resource:///modules/CustomizableUI.jsm", {}) .gPalette.get(id); if (obj) obj = obj.implementation; else { Services.console.logStringMessage(id + " not found"); return this.destroy() || {switch() {}}; } } delete this.obj; return this.obj = obj; }, handleEvent(e) { if (e.key != "F8" || e.ctrlKey || e.shiftKey || e.altKey || e.repeat) return; //e.preventDefault(); //e.stopPropagation(); this.obj.switch(document); }, destroy: function destroy() { removeEventListener("keydown", this, true); removeEventListener("unload", destroy); } }; addEventListener("keydown", listener, true); addEventListener("unload", listener.destroy); })("SwitchKeyboardLayout");} catch(ex) {Cu.reportError(ex);} странно, но на работе ж каким-то чудным образом заработало... Dumby |
voqabuhe > 09-12-2022 07:30:38 |
del |
Dumby > 09-12-2022 10:12:27 |
Inko7 пишет
Затруднительно починить то, что не сломано. Добавил код в custom_script_win.js, топаю по адресу
Кодом? Увы, это не всегда срабатывает. |
Inko7 > 09-12-2022 21:43:11 |
Dumby пишет
помогло |
_zt > 09-12-2022 22:00:45 |
Dumby пишет
Кнопку + батник для себя не делали? скрытый текст Выделить код Код:(this.viewcookieswithrightclick = { init(that) { var star = this.star = document.querySelector("#star-button-box"); if (!star) return; star.addEventListener("contextmenu", this, true); star.addEventListener("click", this, true); that.unloadlisteners.push("viewcookieswithrightclick"); }, handleEvent(e) { if (e.button != 2) return; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); if (e.type != "click") return; this.viewCookies(); }, getETDL(uri) { var eTLD = ""; try { eTLD = Services.eTLD.getBaseDomain(uri); } catch (e) { try { eTLD = uri.asciiHost; } catch (e) {} } return eTLD; }, async viewCookies() { var uri = gBrowser.selectedBrowser.currentURI; try { let _uri = 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); await SiteDataManager.updateSites(); if (!_win) { let url = "chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml", 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 = 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 }); }); } else if ("_gSiteDataSettings" in _win) _win._gSiteDataSettings(); else { Services.scriptloader.loadSubScript("data:," + encodeURIComponent(` var _gSiteDataSettings = gSiteDataSettings._gSiteDataSettings = (function() { SiteDataManager.getSites().then(sites => { this._sites = sites; var sortCol = document.querySelector("treecol[data-isCurrentSortCol=true]"); this._sortSites(this._sites, sortCol); this._buildSitesList(this._sites); }); }).bind(gSiteDataSettings); _gSiteDataSettings(); var updateSetInterval = setInterval(async () => { await SiteDataManager.updateSites(); _gSiteDataSettings(); }, 5000); let removeBtns = document.querySelectorAll("#removeSelected, #removeAll"); var updateClearInterval = () => { clearInterval(updateSetInterval); for (let btn of removeBtns) btn.removeEventListener("command", updateClearInterval); updateClearInterval = null; }; for (let btn of removeBtns) btn.addEventListener("command", updateClearInterval); `), _win, "UTF-8"); _win.addEventListener("unload", () => { _win.updateClearInterval?.(); }, { once: true }); } 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(); var filter = doc.querySelector("#searchBox"); if (!filter) return; filter.value = uri; filter.focus(); filter.dispatchEvent(new _win.Event("input", { bubbles: true })); }, destructor() { this.star.removeEventListener("contextmenu", this, true); this.star.removeEventListener("click", this, true); }, }).init(this); egorsemenov06 пишет
Сомневаюсь. Просто не запустили нужное кол-во раз. |
unter_officer > 09-12-2022 22:39:31 |
_zt пишет
Я в 108 бетке "приколотил высоту гвоздями". Вроде пока нормально. Выделить код Код:@-moz-document url-prefix("chrome://browser/content/preferences/dialogs/siteDataSettings.x") { #SiteDataSettingsDialog { max-height: 465px !important; } #sitesList { height: 25em !important; } } @-moz-document url-prefix("chrome://browser/content/preferences/dialogs/siteDataRemoveSelected.x") { #SiteDataRemoveSelectedDialog { max-height: 450px !important; } #removalList { height: 25em !important; } } |
_zt > 10-12-2022 00:59:56 |
unter_officer Dumby пишет
Спасибо. |
Dumby > 10-12-2022 10:15:08 |
_zt пишет
Нет, не делал.
Да, есть такое. Или динамическая хром-регистрация, viewCookies() типа скрытый текст Выделить код Код:async viewCookies() { var sds = "chrome://ucfsdswnd/content/sds.xhtml"; var type = "Browser:SiteDataSettings", g = Cu.getGlobalForObject(Cu); if (!Object.hasOwn(g, sds)) { var xhtml = (await (await fetch("chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml")).text()) .replace(/(persist=".+)"/, `$1 screenX screenY sizemode" windowtype="${type}"`); g[sds] = Cc["@mozilla.org/addons/addon-manager-startup;1"] .getService(Ci.amIAddonManagerStartup).registerChrome( Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)), [["override", sds, "data:application/xhtml+xml," + encodeURIComponent(xhtml)]] ); } (this.viewCookies = async () => { var uri = gBrowser.selectedBrowser.currentURI; try { let _uri = ReaderMode.getOriginalUrl(uri.spec); if (_uri) uri = Services.io.newURI(_uri); } catch(e) {} uri = this.getETDL(uri); var _win = Services.wm.getMostRecentWindow(type); await SiteDataManager.updateSites(); if (!_win) await new Promise(resolve => (_win = openDialog(sds, type, "chrome,dialog=no,resizable")) .addEventListener("DOMContentLoaded", resolve, {once: true}) ); else if ("_gSiteDataSettings" in _win) _win._gSiteDataSettings(); else { Services.scriptloader.loadSubScript("data:," + encodeURIComponent(` var _gSiteDataSettings = gSiteDataSettings._gSiteDataSettings = (function() { SiteDataManager.getSites().then(sites => { this._sites = sites; var sortCol = document.querySelector("treecol[data-isCurrentSortCol=true]"); this._sortSites(this._sites, sortCol); this._buildSitesList(this._sites); }); }).bind(gSiteDataSettings); _gSiteDataSettings(); var updateSetInterval = setInterval(async () => { await SiteDataManager.updateSites(); _gSiteDataSettings(); }, 5000); let removeBtns = document.querySelectorAll("#removeSelected, #removeAll"); var updateClearInterval = () => { clearInterval(updateSetInterval); for (let btn of removeBtns) btn.removeEventListener("command", updateClearInterval); updateClearInterval = null; }; for (let btn of removeBtns) btn.addEventListener("command", updateClearInterval); `), _win); _win.addEventListener("unload", () => { _win.updateClearInterval?.(); }, { once: true }); } _win.focus(); var filter = _win.document.getElementById("searchBox"); if (!filter) return; filter.value = uri; filter.focus(); filter.dispatchEvent(new _win.Event("input", { bubbles: true })); })(); }, |
Dumby > 11-12-2022 19:43:29 |
egorsemenov06 пишет
Ну тоже что-то сделать с методом viewCookies(). скрытый текст Выделить код Код:// async viewCookies(win) { var func = async sds => { await document.documentReadyForIdle; var upd, box = document.getElementById("searchBox"); (upd = site => box.setUserInput(site, box.focus()))(window.arguments[0]); var attr = "data-isCurrentSortCol", sel = `treecol[${attr}=true]`; window.updSearch = async site => { var sites = sds._sites = await SiteDataManager.getSites(); var col = document.querySelector(sel); col.removeAttribute(attr); sds._sortSites(sites, col); sds._buildSitesList(sites); window.focus(upd(site)); } } var type = "Browser:SDS"; var xhtml = (await (await win.fetch("chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml")).text()) .replace(/(persist=".+)"/, `$1 screenX screenY sizemode" windowtype="${type}"`) .replace(/<script .+>/, `$&\n <script>(${func})(gSiteDataSettings);\n </script>\n${ ["globalOverlay", "editMenuOverlay"] .map(n => ` <script src="chrome://global/content/${n}.js"/>`).join("\n") }`); var sds = "chrome://ucfsdswnd/content/sds.xhtml"; this.cr = Cc["@mozilla.org/addons/addon-manager-startup;1"] .getService(Ci.amIAddonManagerStartup).registerChrome( Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)), [["override", sds, "data:application/xhtml+xml," + encodeURIComponent(xhtml)]] ); (this.viewCookies = async win => { var uri = win.gBrowser.selectedBrowser.currentURI; try { var u = win.ReaderMode.getOriginalUrl(uri.spec); if (u) uri = Services.io.newURI(u); } catch {} uri = this.getETDL(uri); await win.SiteDataManager.updateSites(); var w = Services.wm.getMostRecentWindow(type); w ? w.updSearch(uri) : win.openDialog(sds, type, "chrome,dialog=no,resizable", uri); })(win); }, |
LGS > 12-12-2022 22:13:08 |
Dumby здесь вопрос под первым спойлером, а здесь ответ. |
Dumby > 13-12-2022 13:30:58 |
LGS пишет
Этого недостаточно. Надо ещё от этого оператора избавиться, Правки можно по-разному записать. Допустим, такой вариант скрытый текст Выделить код Код:/* var listener = e => { var doc = e.target || ({}); load_scripts_by_url[doc.documentURI]?.(doc.defaultView); }; */ var listener = e => load_scripts_by_url.x(e.target.ownerGlobal); Выделить код Код:/* if (win.arguments?.find(f => f === "Downloads" || f === "History" || f === "Tags")) return; */ if (/^(?:Downloads|History|Tags)(?:,|$)/.test(String(win.arguments))) return; Выделить код Код:/* }; load_scripts_by_url[location.href]?.(window); */ x(win) { var func = this[win.location.href]; func && func(win); } }; load_scripts_by_url.x(window); |
LGS > 13-12-2022 14:26:31 |
Dumby пишет
Да, именно на "?." консоль ругалась, а как правильно сделать, естественно, не знал, поэтому и обратился к профессионалу. Тупое удаление оператора вопрос не решало, писать про это не стал, чтобы еще глупее не выглядеть. Dumby пишет
Отличный вариант, спасибо. |
Dumby > 17-12-2022 19:00:59 |
Dumby пишет
https://github.com/xiaoxiaoflood/firefox-scripts/commit/33c69b5b959b84d3982eb6f72aefd1cca14e3ad3#diff-c8669a0b709ab73f8751d7e079d6c3b98ac1c464b5a9e1592f28e91ab7a63de7 |
mfrost > 23-12-2022 23:58:38 |
Я дико извиняюсь, на чистоустановленного лиса, залил архив из первого сообщения этой темы https://forum.mozilla-russia.org/viewto … 26#p791126, все по полочкам, пытаюсь прикрутить к нему скрипт про ненужные папки https://forum.mozilla-russia.org/viewto … 25#p777225 , а у меня, к сожалению, ничего не выходит.... Если кому не сложно скиньте свой файл заведомо рабочий, для такого криворукого идиота я |
mfrost > 24-12-2022 01:11:27 |
Не пойму может я идиот, но у меня все равно не работает скрытый текст Выделить код Код:// Скрипт для документа окна браузера [ChromeOnly] var ucf_custom_script_win = { initialized: false, get unloadlisteners() { delete this.unloadlisteners; window.addEventListener("unload", this, { once: true }); return this.unloadlisteners = []; }, load() { if (this.initialized) return; this.initialized = true; /* ************************************************ */ // Здесь может быть ваш код который сработает по событию "load" ((type, listener) => { addEventListener(type, listener); addEventListener("unload", () => removeEventListener(type, listener), {once: true}); })("MozBeforeInitialXULLayout", { handleEvent(e) { e.target.documentURI.endsWith(this.ends) && Object.defineProperty(e.target.getElementById("bookmarks-view"), "place", this); }, get ends() { delete this.ends; return this.ends = `/bookmarksSidebar.x${ parseInt(Services.appinfo.platformVersion) >= 73 ? "htm" : "u" }l`; }, configurable: true, set() { delete this.place; this.place = "place:parent=menu________"; } }); /* ************************************************ */ }, handleEvent(e) { this[e.type](e); }, unload() { this.unloadlisteners.forEach(str => { try { this[str].destructor(); } catch (e) {} }); }, }; /* ************************************************ */ // Здесь может быть ваш код который сработает по событию "DOMContentLoaded" Пробовал в разных вариантах, не работает, все равно Может я что в настройках не включил? 3й день на лисе 108 до этого сидел на 68 все работало изумительно.... ни папки меню закладок, ни других тебе закладок.... |
Dumby > 24-12-2022 01:38:45 |
mfrost пишет
Кстати, вполне возможно. Типа эту галку Включить скрипты: |
LGS > 24-12-2022 14:01:51 |
Dumby, посмотрите, пожалуйста, можно ли "оживить" этот древний скрипт, а еще лучше адаптировать dav_LinkifiesLocationBar.uc.js для 68esr. Для первого "зачистка" по вашей рекомендации у меня не помогает, для второго замены в стр.14 chrome://browser/content/browser.xhtml на xul явно недостаточно. |
Dumby > 24-12-2022 20:54:20 |
LGS пишет
Ууу, копаться в этом радости мало.
Если код в custom_script_win.js, то «стр.14» не нужна как таковая, убери её. Чтобы как-то завелось, можно попробовать заменить пару строк скрытый текст Выделить код Код:/* var urlBarInput = getWindow().document.querySelector("#urlbar-input").value; */ var urlBarInput = gURLBar.value; /* var urlbarInput = getWindow().document.querySelector("#urlbar-input"); */ var urlbarInput = gURLBar.inputField; И, там ещё есть текст стиля в var stylexul = `…`; Так вот, в нём, заменить все (три) решётки (#) на точки (.), то есть, с идентификатора на класс. |
LGS > 25-12-2022 10:18:03 |
Dumby пишет
Извиняюсь за отнятое время. Dumby пишет
Завелось и работает, благодарю! |
mfrost > 26-12-2022 19:33:01 |
Dumby пишет
Товарищи, подскажите где это включить в настройках не нашел |
kokoss > 26-12-2022 20:34:00 |
mfrost пишет
|
mfrost > 26-12-2022 22:59:04 |
kokoss пишет
Вижу кнопку выделенную вами, вижу окошко где описано как открыть данное меню, но, к сожалению, описанным способом в моей версии браузера, данное меню не открывается |
kokoss > 26-12-2022 23:37:14 |
mfrost скрытый текст |
mfrost > 26-12-2022 23:55:40 |
kokoss пишет
Огромное спасибо! Залил ваш архив и все заработало |
LZAA > 28-12-2022 18:31:36 |
Посмотрите, пожалйуста, здесь: |
_zt > 28-12-2022 20:21:32 |
LZAA |
LZAA > 29-12-2022 00:39:01 |
_zt |
_zt > 29-12-2022 15:42:02 |
LZAA |
LZAA > 29-12-2022 16:03:44 |
_zt Я вчера 'UserChromeFiles загрузчик скриптов/стилей' смотрел и даже пытался установить в FF 68. Но никакого результата не получил. То есть интерфейс не изменился вовсе. |
kokoss > 29-12-2022 22:08:56 |
LZAA пишет
Попробуйте этот комплект |
LZAA > 30-12-2022 19:18:27 |
kokoss Спасибо за файл. Это работает. |
Dumby > 30-12-2022 22:13:33 |
Можно подумать: «что за бред сивой кобылы?». Одна укфская кнопка потерялась, а у остальных пропали иконки скрытый текст Выделить код Код:data:image/png;base64,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 Весьма наглядный пример того, что такое startupCache. |
kokoss > 30-12-2022 22:31:38 |
LZAA пишет
Попробуйте так: скрытый текст Выделить код Код:#add-additional-bottom-bar { --toolbarbutton-outer-padding: 1px !important; --toolbarbutton-inner-padding: 2px !important; } #add-additional-bottom-closebutton { padding: 0px !important; } оффтоп |
_zt > 30-12-2022 22:44:58 |
Dumby |
Dumby > 30-12-2022 23:06:03 |
_zt пишет
Ну, под конец, конечно, очистил. Чтобы посмотреть как тулбары исчезнут. А сначала, напротив, даже не дышал на него. |
LZAA > 30-12-2022 23:39:54 |
_zt Всё правильно. Названия разные. Беда лишь в том, что я это только сейчас от Вас узнал. Про 'startupCache'. kokoss PM. |
xrun1 > 31-12-2022 02:38:33 |
LZAA |
Farby > 31-12-2022 19:09:05 |
xrun1 пишет
кочу спросить, кто вам дал право публиковать ссылку... |
LZAA > 31-12-2022 19:24:49 |
Farby Я тоже 'кочу' спросить, у кого здесь следует испрашивать милостивого разрешения на те или иные 'телодвижения'? Не у Вас ли? 31-12-2022 19:31:27 |
xrun1 > 01-01-2023 14:42:58 |
Farby пишет
Обоснуйте. |
Farby > 03-01-2023 12:12:35 |
xrun1 пишет
Извиняюсь не туда посмотрел |
LGS > 05-01-2023 10:33:45 |
Dumby, что можно подправить в вашем коде для СВ, чтобы срабатывало в боковой панели и библиотеке..? Загружаю с помощью UCF, поэтому спрашиваю здесь. |
Dumby > 05-01-2023 23:27:16 |
LGS пишет
Вот когда Cu.import() удалят — всё,
Ну так потому, что код для CB, а не для UCF. А размножается, наверно, потому, что листенер не может
Нее, «подправить» тут не выйдет. Вот, попробовал перерисовать под custom_script.js скрытый текст Выделить код Код:(async topic => { var imp = (m, n = m) => Cu.import(`resource://gre/modules/${m}.jsm`, {})[n]; var exporter = { get dps() { delete this.dps; return this.dps = imp("DownloadPaths"); }, get exporter() { delete this.exporter; return this.exporter = imp("BookmarkHTMLUtils", "BookmarkExporter"); }, async export(popup) { var win = popup.ownerGlobal, tn = popup.triggerNode; var node, pu = win.PlacesUtils, bm = pu.bookmarks; if (tn.nodeName == "treechildren") node = popup._view.selectedNode; else if (tn.id == "OtherBookmarks") node = {bookmarkGuid: bm.unfiledGuid, title: tn.getAttribute("label")}; else node = tn._placesNode || popup._view.result.root; var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(win, win.PlacesUIUtils.getString("EnterExport"), fp.modeSave); fp.appendFilters(fp.filterHTML); fp.defaultString = (node.title ? this.dps.sanitize(node.title) : "untitled") + ".html"; if (await new Promise(fp.open) == fp.returnCancel) return; var tree = await pu.promiseBookmarksTree(pu.getConcreteItemGuid(node), {includeItemIds: true}); tree.title = bm.getLocalizedTitle(tree); var bookmarks = {children: [ {root: "toolbarFolder"}, {root: "unfiledBookmarksFolder"}, {root: "bookmarksMenuFolder", children: [tree], guid: bm.menuGuid} ]}; new this.exporter(bookmarks).exportToFile(fp.file.path); }, observe(doc) { var popup = doc.querySelector("menupopup#placesContext"); if (!popup) return; var menuitem = (doc.createXULElement || doc.createElement).call(doc, "menuitem"); for(var args of Object.entries({ label: "Экспорт папки в HTML", selection: "folder", "node-type": "folder", "selection-type": "single|none", id: "placesContext_exportFolder", oncommand: "exporter.export(parentNode);" })) menuitem.setAttribute(...args); menuitem.exporter = this; doc.getElementById("placesContext_openSeparator").before(menuitem); } }; Services.obs.addObserver(exporter, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(exporter, topic); }, "quit-application-granted"); })("chrome-document-loaded"); |
LGS > 06-01-2023 11:39:58 |
Dumby пишет
Работает и не размножается, включая библиотеку во вкладке. Большое новогоднее "спасибо". |
unter_officer > 11-01-2023 13:41:30 |
Dumby, не посмотрите этот скриптик: скрытый текст Выделить код Код:// // Копировать ссылку в адресной строке .......... // https://forum.mozilla-russia.org/viewtopic.php?pid=793188#p793188 ..... // (async (url, pa = ChromeUtils.import(url).PageActions) => pa.addAction(new pa.Action({ title: "Копировать ссылку", tooltip: "Копировать ссылку", iconURL: "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAACiSURBVHjapFOBDcQgCNRPN2pnkpl0JpyJFpszvv1K+5KYAHJwgHoRcTPyeQvYNhI91aEMnp51DcIsRVRX32JVa+0Y45HEOaLsTAZ9NeghcK1e5jcD/tmC0gbVQy++lE7KOadrn9aQ4Mddz8AE920MEyCgCRqCLwkQzMzS2nfg2xYwbQtcE/wL/lojXhhWRXSukDn60Wtdmv0/AvTiZ7/zLsAASyfDH6YOUVUAAAAASUVORK5CYII=", id: "ucf_copyURL", pinnedToUrlbar: true, onCommand(e) { var gBrowserBundle = { GetStringFromName: () => "Скопировано в буфер обмена!" }; var show = eval(`(function ${e.view.ConfirmationHint.show})`); var helper = Cc["@mozilla.org/widget/clipboardhelper;1"] .getService(Ci.nsIClipboardHelper); (this.onCommand = e => { var win = e.view; var uri = win.gBrowser.selectedBrowser.currentURI; helper.copyString(win.gURLBar.makeURIReadable(uri).displaySpec); var anchor = win.BrowserPageActions.panelAnchorNodeForAction(this, e); show.call(win.ConfirmationHint, anchor, "", {event: e, hideArrow: true}); })(e); }, onPlacedInUrlbar: node => node.style.setProperty("--urlbar-icon-fill-opacity", ".6", "important") })))("resource:///modules/PageActions.jsm"); |
Dumby > 12-01-2023 12:28:49 |
unter_officer скрытый текст подкинуть подобного же фейка, типа скрытый текст Выделить код Код:// var MozXULElement = {insertFTLIfNeeded() {}}; var document = {l10n: {setAttributes: msg => msg.textContent = "Скопировано в буфер обмена!"}}; Ну, или править уже сам код для eval() |
unter_officer > 12-01-2023 13:59:49 |
Dumby, большое спасибо! |
Dumby > 16-01-2023 20:15:30 |
egorsemenov06 Dumby пишет
Сделано не только неполно (только третье), да ещё и неправильно. скрытый текст Выделить код Код:/* if(fe instanceof HTMLInputElement || fe instanceof HTMLTextAreaElement) { */ if(HTMLInputElement.isInstance(fe) || HTMLTextAreaElement.isInstance(fe)) { /* if(node instanceof Element.isInstance(x)) { */ if(Element.isInstance(node)) { |
LGS > 20-01-2023 15:46:08 |
Dumby, а вы не можете придумать способ, который позволял бы открывать закладки и историю в новой вкладке, когда открыта одна вкладка about:newtab..? Т.е, если поподробнее, то сейчас, когда запускаю фокс, то открыта только вкладка about:newtab, и , если жмякнуть по закладке, например, в боковой панели, то она откроется в текущей вкладке, а не в новой. То же самое и с историей. Меня почему-то это сильно напрягает... нужно, чтобы about:newtab (она же домашняя с плитками) не "затиралась", а оставалась "нетронутой". Привычка, может и вредная. 20-01-2023 16:14:11 |
kokoss > 20-01-2023 19:24:36 |
LGS > 20-01-2023 19:57:37 |
kokoss |
LGS > 20-01-2023 20:34:28 |
Это тоже не сработало. |
kokoss > 20-01-2023 21:08:28 |
LGS пишет
Этот -> https://forum.mozilla-russia.org/viewto … 05#p797605 скрипт так и работает, открывает( кроме дилов, в хотелке про открытие дилов в новой вкладке нет) закладки и историю в новой вкладке + user_pref("browser.tabs.loadBookmarksInTabs", true); 20-01-2023 21:32:15 LGS пишет
есть такое, тоже напрягает... |
LGS > 20-01-2023 21:39:18 |
kokoss пишет
Работают, если открыта хотя-бы одна вкладка. Если открыта только about:newtab (сразу после запуска фокса), то закладка или история откроются в текущей вкладке (в моем случае это about:newtab). 20-01-2023 21:41:56 kokoss пишет
Ага, значит кое-как смог объяснить, что мне нужно... |
Dumby > 21-01-2023 09:17:32 |
LGS пишет
То есть, ты хочешь забрать эту вкладку себе, Можно так попробовать, вроде не должно грузиться скрытый текст Выделить код Код:(async place => { await gBrowserInit.idleTasksFinishedPromise; var tabs = gBrowser.visibleTabs; if (tabs.length > 1) return; var re = /^about:(?:newtab|home)$/; var [tab] = tabs, br = tab.linkedBrowser; if (re.test(br.currentURI.spec)) br.loadURI = function(url, params) { if ( re.test(this.currentURI.spec) && gBrowser.selectedBrowser == this && Components.stack.formattedStack.includes(place) ) { var e = window.event || Services.focus.focusedWindow.event || Services.wm.getMostRecentWindow("Places:Organizer")?.event; if (e) { var node, trg = e.target; if (trg.nodeName == "treechildren") node = trg.parentNode.selectedNode; else if (trg.id == "placesCmd_open") { var popup = trg.ownerDocument.getElementById("placesContext"); node = popup._view.selectedNode || popup.triggerNode._placesNode; } else node = trg._placesNode; if (node) { PlacesUIUtils._openNodeIn(node, "tab", window); //gBrowser.selectedTab = tab; // force in background return; } } } delete this.loadURI; this.loadURI(url, params); } })("_openNodeIn@resource:///modules/PlacesUIUtils.");
Не написано про галку «Открыть предыдущие окна и вкладки» Кстати, можно прицепить что-нибудь к адресу, типа about:newtab# |
LGS > 21-01-2023 11:57:55 |
Dumby пишет
Скрипт почему-то не зашел, а вот ваша мысль про about:newtab# пришлась очень кстати. Назначил домашней about:newtab# - теперь открывает как мне надо в новой вкладке. Единственное, пришлось стили подправить, которые завязаны были на about:newtab, но это мелочи. Скрипт заработал... из custom_script_all_win.js. |
unter_officer > 30-01-2023 10:10:13 |
Dumby |
Dumby > 30-01-2023 21:08:05 |
unter_officer скрытый текст Выделить код Код:(async ss => { ss = ChromeUtils.importESModule(ss).SessionStore; await ss.promiseAllWindowsRestored; CustomizableUI.createWidget({ id: "803529", localized: false, onCreated(btn) { var vals, keys = [, "label", "tooltiptext"]; var disable = () => { keys[0] = "disabled"; vals = [true, "No Last Session", "No last session, nothing to clear"]; } var setState = btn => { for(var ind in keys) btn.setAttribute(keys[ind], vals[ind]); } if (ss.canRestoreLastSession) { keys[0] = "oncommand"; var cmd = `SessionStore.canRestoreLastSession = false;`; vals = [cmd, "Clear Last Session", "Clear last session"]; var qt = "quit-application-granted"; var ct = "sessionstore-last-session-cleared"; var destroy = () => { Services.obs.removeObserver(obs, ct); Services.obs.removeObserver(destroy, qt); } var obs = () => { destroy(); disable(); var widget = CustomizableUI.getWidget(this.id); for(var win of CustomizableUI.windows) { var {node} = widget.forWindow(win); setState(node); node.removeAttribute("oncommand"); } } Services.obs.addObserver(obs, ct); Services.obs.addObserver(destroy, qt); } else disable(); (this.onCreated = btn => { setState(btn); btn.setAttribute("image", "chrome://global/skin/icons/close-fill.svg"); })(btn); } }); })("resource:///modules/sessionstore/SessionStore.sys.mjs"); |
unter_officer > 30-01-2023 23:34:59 |
Dumby |
unter_officer > 08-02-2023 03:56:25 |
Dumby Понадобился мне 78 ESR. Стал подключать UCF-кнопки и столкнулся с такой проблемкой. Выделить код Код:scriptsbackground: [ // В фоне [System Principal] { func: 'ChromeUtils.import("chrome://user_chrome_files/content/custom_scripts/Script.jsm");' }, ], Версия UCF крайняя (2021-9-23). |
LGS > 08-02-2023 09:10:21 |
unter_officer пишет
У меня тоже лыжи не смазанные... правда, версия UCF старая 2021-2-14 и подключал в custom_script.js, как здесь (спойлеры внизу). |
Dumby > 08-02-2023 10:00:28 |
unter_officer пишет
Испёк портабл 78.15.0esr + UCF 2021-9-23 Создал в папке custom_scripts файл Script.jsm скрытый текст Выделить код Код:var EXPORTED_SYMBOLS = []; ChromeUtils.import("resource:///modules/CustomizableUI.jsm").CustomizableUI.createWidget({ id: "is_78esr_special_test", label: "TEST: is 78ESR Special?", tooltiptext: "TEST: is 78ESR Special?", localized: false, onCreated(btn) { btn._handleClick = function() { this.ownerGlobal.Services.prompt.alert(null, null, "Success!"); } btn.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ=="); } }); Подключил как у тебя написано. Результат: кнопка создалась и кликается. Таким образом, ответ на вопрос «Это особенность 78 версии или у меня лыжи не едут?» LGS пишет
Правильно говорит, в 78 у ChromeUtils нет свойства domProcessChild |
unter_officer > 08-02-2023 11:36:15 |
Dumby пишет
Оказалось, что дело в самих кнопках. |
LGS > 08-02-2023 11:37:06 |
Dumby пишет
Подхватился и работает... лыжи едут. Спасибо! |
Dumby > 10-02-2023 09:07:21 |
unter_officer пишет
Да, метод добавлен только c Firefox 80+ скрытый текст Выделить код Код:var name = "UCFUserCReloader", EXPORTED_SYMBOLS = [name + "Parent", name + "Child"]; var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); var find = function(sheet) { return sheet.href == this; } var getSheet = (doc, href) => InspectorUtils.getAllStyleSheets(doc).find(find, href); if (!ChromeUtils.contentChild) { var data, url; var noop = () => {}; var getURI = sub => { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append(`userC${sub}.css`); return Services.io.newFileURI(file).QueryInterface(Ci.nsIFileURL); } var oncontextmenu = e => e.ctrlKey || e.shiftKey || e.detail != 1 || contextmenu(e); var contextmenu = e => { var {file, spec} = getURI("ontent"); var wb = Services.appShell.createWindowlessBrowser(); var contentSheet = getSheet(wb.document, spec); wb.close(); if (!contentSheet) return oncontextmenu = contextmenu = noop; url = spec; var child = {moduleURI: __URI__}; ChromeUtils.registerProcessActor(name, {child, parent: child}); var ps = `data:,ChromeUtils.contentChild?.getActor("${name}").query()`; (contextmenu = async e => { if (!file.exists()) return; e.preventDefault(); data = await reload(contentSheet, Object.create(null)); if (data) for(var p in data) { Services.ppmm.loadProcessScript(ps, false); return e.view.setTimeout(restyle, 150); } })(e); } ChromeUtils.import("resource:///modules/CustomizableUI.jsm").CustomizableUI.createWidget({ label: "Reload user{Chrome, Content}.css", tooltiptext: "L: Reload userChrome.css\nR: Reload userContent.css", id: "798278", localized: false, onCreated(btn) { btn._handleClick = this.click; btn.oncontextmenu = oncontextmenu; btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIpwAACKcBMsYCAwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMwSURBVEiJ5dbNb5RVFMfxz3mmrYgYE0IN4IaKb4n4UqOwMCYu2JCoQVDiwoUrQ4j0xao7ExITQxRoodEFK1cmRkSE8AeYYKpEFF0YY4SiUSMRQW0sLe0818U8nekwHe3U7vhtnnNOzj3f89znPvderjVFK8npaSWrPSjpElahQzhvyrF4y++t1GqbF7DHOvQLj6Ozrt2EDutYRHAasMK0vXgWWZO0SX/7DlJf6Skp3UWcFeVRV4zG235tCZx6rDPtKLqqAN4XPhROm3DJEiG3LA6aKkZ14jUSKaOd1Gsco6Qz8vRiDDvTFJz63S13AjdVAg7JvBxDzs2RfrE2MP9ijolZijvJXo/h8pmmb5z6LZf7qICWJQNxwP5mM1OnzNdy03V1U0oi2x77y+/Wp16t3CDWgvDKvKGIQZepfO+iWBIpKG9s7HGW0k7dKgsJjsSQffOF1or4srAuS04U9jOp14amYGGgiF2Re6llaEWnMSbPNyl5DtNFQzvnBKdd2oRNhXt4ZvW1rCwfkbInY9jHMeiscBiEJ9Lz2mfSaovgovXC8sI7siAoYsgnMy8JkmPYhhtdbwOV6a9NdVhT69qphYIblPl0FuO2WrimVVVrcu7dZkFqd75q525uBCelqj0tXzRwvSYbwWZ1doOVi4Yad0vVDj81gjPfV+2y9YsGLnlgFrj6p9TA405irPAemwmn/raNqc/D/wO9uXj+bMhXDeDihDledLYt9VmTektb5flxebYgcOpx+yzw0aic3vXgSqY9hdUuOUx6T+WWcX/LUELYh3ZMyqq1G8FxwCl8ULjdVFd6d6tgPQbMfLIwHIPONgVXWs1OFm3Mjt6Rdlg2X2bq0yfsLtzP/OHVq3PqzuPUm/Vj9xz9ZDrcg5F/Bb6gS8mbkq1F6EdlW+IdE03Baae1pEeJb1SuO0vrMvPsPvKRArDaChf8qWRal/BQccBsxnXFiBFTtjS7czW93qYdVurQJZW6SLeK+DaGyofSLh0uGUNHk6F/SfZI3ojh2k41b3DThnrdS+1/nAnjcxzR5mDsdeG/6szrXl2nJX4w4RFJJ3LhF7lzMey3lmtdU/oHaoj4Y/PDRWgAAAAASUVORK5CYII="); }, get click() { var {file, spec} = getURI("hrome"); var chromeSheet = getSheet(Services.wm.getMostRecentWindow(null).document, spec); delete this.click; return this.click = !chromeSheet ? noop : function() { var win = this.ownerGlobal; if (win.event?.detail < 2 && file.exists()) reload(chromeSheet), win.setTimeout(restyle, 50); } } }); var restyle = () => { var subst = "u_css_reloader_restyle_substitution"; var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); rph.setSubstitution(subst, Services.io.newURI("data:text/css,:root{}")); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var args = [Services.io.newURI(`resource://${subst}/`), sss.USER_SHEET]; (restyle = () => { sss.loadAndRegisterSheet(...args); sss.unregisterSheet(...args); })(); } var reload = async (sheet, obj) => { try {var style = await (await fetch(sheet.href)).text();} catch {return obj;} InspectorUtils.parseStyleSheet(sheet, style); if (obj) obj[sheet.href] = style; for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); rule.type == rule.IMPORT_RULE && rule.styleSheet.href.startsWith("file:///") && await reload(rule.styleSheet, obj); } return obj; } var UCFUserCReloaderParent = class extends JSProcessActorParent { receiveMessage(msg) { return msg.name ? url : data; } } } else var UCFUserCReloaderChild = class extends JSProcessActorChild { async query() { var {sheet} = this; if (!sheet) { var en = Services.ww.getWindowEnumerator(null); if (en.hasMoreElements()) sheet = this.sheet = getSheet(en.getNext().document, await this.sendQuery("u")); } sheet && this.parse(sheet, await this.sendQuery("")); } parse(sheet, data) { var style = data[sheet.href]; if (!style) return; InspectorUtils.parseStyleSheet(sheet, style); for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); rule.type == rule.IMPORT_RULE && rule.styleSheet.href.startsWith("file:///") && this.parse(rule.styleSheet, data); } } }
Если бы только это. Ладно, можно попробовать что-нибудь подпаять. скрытый текст Выделить код Код:var name = "UCFSaveSnapshotToHTML", EXPORTED_SYMBOLS = [name + "Child"]; var fw = win => { var gfe = Cc["@mozilla.org/focus-manager;1"] .getService(Ci.nsIFocusManager).getFocusedElementForWindow; return (fw = win => { var res = {}; var fe = gfe(win, true, res); return [res.value, fe]; })(win); } if (!ChromeUtils.contentChild) { var click = async function() { var win = this.ownerGlobal; var bc = win.gBrowser.selectedBrowser.browsingContext, cwg = bc.currentWindowGlobal; var fp = picker(win, "", Ci.nsIFilePicker.modeSave); if (cwg.isInProcess) { var [fwin, fe] = fw(bc.window); if (fe?.matches("browser[remote=true]")) cwg = fe.browsingContext.currentWindowGlobal; } var [fileContent, fileName] = cwg.isInProcess ? snap(fwin) : await cwg.contentParent.getActor(name).sendQuery("", cwg.innerWindowId); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); await new Promise(fp.open) != fp.returnCancel && win.OS.File.writeAtomic(fp.file.path, new win.TextEncoder().encode(fileContent)); } ChromeUtils.import("resource:///modules/CustomizableUI.jsm").CustomizableUI.createWidget({ label: "796961", tooltiptext: "796961", id: "796961", localized: false, onCreated(btn) { btn._handleClick = click; btn.setAttribute("image", "chrome://devtools/skin/images/tool-application.svg"); } }); var picker = (...args) => { ChromeUtils.registerProcessActor(name, {child: {moduleURI: __URI__}}); return (picker = Components.Constructor( "@mozilla.org/filepicker;1", "nsIFilePicker", "init" ))(...args); } } else var UCFSaveSnapshotToHTMLChild = class extends JSProcessActorChild { receiveMessage(msg) { return snap(fw(WindowGlobalChild.getByInnerWindowId(msg.data).browsingContext.window)[0]); } }
Странно, там же есть старый about:config. Но если, зачем-то, надо, то можно после строки, содержащей скрытый текст Выделить код Код:// if (!L10nRegistry.registerSources) L10nRegistry = Object.assign( Object.create(L10nRegistry), {registerSources([s]) {this.registerSource(s);}, removeSources([s]) {this.removeSource(s);}} ); |
unter_officer > 10-02-2023 12:51:30 |
Dumby Огромное спасибо за помощь! |
unter_officer > 10-02-2023 19:07:14 |
Dumby HTTP Request Logger Выделить код Код:// // HTTP Request Logger .......... // https://forum.mozilla-russia.org/viewtopic.php?pid=794053#p794053 ..... // (async self => CustomizableUI.createWidget(({ label: "HTTP Request Logger", tooltiptext: "HTTP Request Logger", fileName: "http-request-log.txt", images: { true: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP/AwMD/AAAA/wAAAP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ==", false: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP/AwMD/AAAA/wAAAP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AACsQQAArEEAAKxBH/isQR/4rEEf+KxBH/isQR/4rEEf+KxBH/isQR/4rEEf+KxBH/isQQAArEEAAKxBAACsQQ==" }, id: "ucf-httpRequestLogger", localized: false, init(pref) { var topic = "http-on-modify-request"; this.toggle = () => Services.prefs.setBoolPref(pref, !this.active); var prefObs = () => { var val = Services.prefs.getBoolPref(pref, false); if (this.active ^ (this.active = val)) Services.obs[`${val ? "add" : "remove"}Observer`](this, topic); this.setBtnsState(); } prefObs(); Services.prefs.addObserver(pref, prefObs); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.prefs.removeObserver(pref, prefObs); self.active && Services.obs.removeObserver(self, topic); }, "quit-application-granted"); return self = this; }, onCreated(btn) { btn._handleClick = this.toggle; btn.setAttribute("image", this.images[this.active]); }, setBtnsState() {this.setBtnsState = () => { var img = this.images[this.active]; var widget = CustomizableUI.getWidget(this.id); for(var win of CustomizableUI.windows) widget.forWindow(win).node?.setAttribute("image", img); }}, log: "", observe(channel) { if (!(channel instanceof Ci.nsIHttpChannel)) return; this.log += `${ channel.referrerInfo?.originalReferrer?.spec || "(none)" } ${ channel.requestMethod } ${ channel.URI.spec }\r\n`; this.busy || this.write(); }, write() { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append(this.fileName); var {path} = file; var {IOUtils} = Cu.getGlobalForObject(Cu); var modes = [{mode: "create"}, {mode: "append"}]; var unbusy = () => { this.busy = false; this.log && this.write(); } (this.write = () => { this.busy = true; var {log} = this; this.log = ""; IOUtils.writeUTF8(path, log, modes[+file.exists()]) .finally(unbusy); })(); } }).init("ucf.httpRequestLogger.enabled")))(); |
Dumby > 12-02-2023 09:44:39 |
unter_officer скрытый текст Выделить код Код:// write() { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append(this.fileName); var flags = 0x02 | 0x08 | 0x10; // MODE_WRONLY | MODE_CREATE | MODE_APPEND var args = ["@mozilla.org/network/file-output-stream;1", "nsIFileOutputStream", "init"]; var fos = Components.Constructor(...args).bind(null, file, flags, 0o644, 0); var sis = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); var copier = Cc["@mozilla.org/network/async-stream-copier;1"].createInstance(Ci.nsIAsyncStreamCopier2); var ro = {onStartRequest() {}}; ro.onStopRequest = () => { this.busy = false; this.log ? this.write() : sis.setData("", 0); }; (this.write = () => { this.busy = true; sis.setUTF8Data(this.log); this.log = ""; try { copier.init(sis, fos(), null, 0, true, true); copier.asyncCopy(ro, null); } catch(ex) { this.toggle(); ro.onStopRequest(); Services.prompt.alert(null, this.label, ex.message); } })(); } |
unter_officer > 12-02-2023 12:20:16 |
Dumby |
Dumby > 16-02-2023 06:44:28 |
egorsemenov06 Содержимое файла взять из data-адреса от «<svg» и до «/svg>» включительно. скрытый текст Выделить код Код:/* img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='32'><path style='fill:none;stroke:context-fill;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>"; */ img = "chrome://user_chrome_files/content/custom_scripts/imgs/cookie-toggle.svg"; Можно и динамическую хром-регистрацию в код вписать, если очень надо. Смотрю, и как resource-адрес тоже работает скрытый текст Выделить код Код:/* img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='32'><path style='fill:none;stroke:context-fill;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>"; */ img = (rph => { var subst = "ucf-cookie-toggle-btn-img"; rph.setSubstitution(subst, Services.io.newURI( "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='32'><path style='fill:none;stroke:context-fill;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>" )); return `resource://${subst}/`; })(Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler)); Ну, или включить настройку svg.context-properties.content.enabled Но, я не знаю почему она дефолтно выключена, может тому есть какие-то веские причины. |
Dumby > 17-02-2023 10:18:53 |
egorsemenov06 Попытка наброска реплейсмента, если 16px: 1. После многочисленных trbn.setAttribute(…) — ещё один 2. Правка стиля скрытый текст Выделить код Код:/* #${id} { list-style-image: url("${img}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; } #${id}[badge="0"] { -moz-image-region: rect(16px, 16px, 32px, 0px) !important; } */ #${id} image { --h: 16px; height: var(--h); !important; object-fit: cover !important; object-position: top !important; } #${id}[badge="0"] image { object-position: 0 calc(-1 * var(--h)) !important; } |
unter_officer > 17-02-2023 16:42:29 |
Dumby пишет
У меня в этой кнопке иконка не пропадала. Видимо из-за включенного svg.context-properties.content.enabled. Но на всякий случай фикс все же накатил. |
LGS > 21-02-2023 15:06:43 |
Dumby, скажите, пожалуйста, а нельзя ли с помощью скрипта вернуть пункт в контекстном меню адресной строки "Вставить и перейти" в версиях 91 и выше..? |
Dumby > 21-02-2023 15:33:54 |
LGS пишет
Нет. Нельзя «вернуть» то, что не пропадало. |
LGS > 21-02-2023 16:36:10 |
Dumby пишет
Понятно. |
LGS > 28-02-2023 11:15:21 |
Dumby, вы, вроде как, .uc.js машинерию не особо жалуете, но, может посмотрите этот скрипт, чтобы на 110 заработал. |
Dumby > 28-02-2023 13:23:29 |
LGS пишет
С чего бы мне её не жаловать? Просто у меня её нет. Но если там своих API понатыкано, то машинерию разворачивать надо,
Может просто так скрытый текст Выделить код Код:/* let aFolderItemId = PlacesUtils.bookmarks.getFolderIdForItem(node.itemId); if (aFolderItemId) { */ if (node.parent.type == node.RESULT_TYPE_FOLDER) { |
LGS > 28-02-2023 14:44:08 |
Dumby пишет
Поэтому и уточнил сначала... вдруг, желания связываться не будет. Dumby пишет
Сработало! Только из гамбургера не подхватывает. Но я закладками оттуда не пользуюсь, поэтому и так хорошо. |
Dobrov > 01-03-2023 05:28:07 |
Dumby - просьба исправить скрипт, скрывающий панель вкладок с одной вкладкой для FF-110 (на FF97 работало) Выделить код Код:// ucf_autohidetabstoolbar.js https://forum.mozilla-russia.org/viewtopic.php?pid=790733#p790733 (this.autohidetabstoolbar = { init(that) { var newtab = this.newtab = document.querySelector("#tabs-newtab-button"); if (!newtab) return; newtab.addEventListener("animationstart", this); that.unloadlisteners.push("autohidetabstoolbar"); var style = "data:text/css;charset=utf-8," + encodeURIComponent(` :root[ucfautohidetabstoolbar="true"] #TabsToolbar:not([customizing]) { visibility: collapse !important; } #main-window[ucfautohidetabstoolbar="true"]:not([customizing]) box > #navigator-toolbox { padding-bottom: 0 !important; } #tabs-newtab-button { opacity: 1; animation-name: toolbar_visible !important; animation-timing-function: step-start !important; animation-duration: .1s !important; animation-iteration-count: 1 !important; animation-delay: 0s !important; } .tabbrowser-tab[first-visible-tab="true"][last-visible-tab="true"] ~ #tabs-newtab-button, .tabbrowser-tab[first-visible-tab="true"][last-visible-tab="true"] ~ #tabbrowser-arrowscrollbox-periphery > #tabs-newtab-button { opacity: 0; animation-name: toolbar_hide !important; } @keyframes toolbar_visible { from { opacity: 0;} to {opacity: 1;} } @keyframes toolbar_hide { from {opacity: 1;} to {opacity: 0;} } `); windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); }, handleEvent(e) { this[e.animationName]?.(); }, toolbar_visible() { document.documentElement.setAttribute("ucfautohidetabstoolbar", "false"); }, toolbar_hide() { document.documentElement.setAttribute("ucfautohidetabstoolbar", "true"); }, destructor() { this.newtab.removeEventListener("animationstart", this); } }).init(this); |
Dumby > 03-03-2023 08:12:16 |
Dobrov пишет
Не способен. То есть, атрибуты {first, last}-visible-tab выпилены, скрытый текст Выделить код Код:/* .tabbrowser-tab[first-visible-tab="true"][last-visible-tab="true"] ~ #tabs-newtab-button, .tabbrowser-tab[first-visible-tab="true"][last-visible-tab="true"] ~ #tabbrowser-arrowscrollbox-periphery > #tabs-newtab-button { opacity: 0; animation-name: toolbar_hide !important; } */ #tabs-newtab-button { animation-name: toolbar_hide !important; } .tabbrowser-tab:not([hidden]) ~ .tabbrowser-tab:not([hidden]) ~ #tabbrowser-arrowscrollbox-periphery > #tabs-newtab-button { animation-name: toolbar_visible !important; } и будет срабатывать. Но что дальше с этим делать — я без понятия. |
unter_officer > 04-03-2023 13:43:29 |
Dumby Я сам пытался что-то придумать. Вроде бы даже получился рабочий код: скрытый текст Выделить код Код:try { (this.ucf_SelectedTextToClipboard = { init(that) { document.addEventListener("keydown", this); }, destructor() { this.document.removeEventListener("keydown", this); }, handleEvent(e) { if (e.ctrlKey && e.code == "KeyC") { // выделенный текст из страницы ..... var selection = document.commandDispatcher.focusedWindow.getSelection(); // выделенный текст из текстового поля ..... if ( selection.isCollapsed ) { var theBox = document.commandDispatcher.focusedElement; if (theBox && (theBox.type == "text" || theBox.type == "textarea" || theBox.type == "textbox" || theBox.type == "input" || theBox.type == "search")) { var startPos = theBox.selectionStart; var endPos = theBox.selectionEnd; selection = theBox.value.substring(startPos, endPos); } } if ( selection !== '' ) { setTimeout(()=> selection = gClipboard.read(), 100); // читаем из буфера обмена ..... setTimeout(()=> selection = selection.toString().trim(), 100); // убираем пробелы ..... setTimeout(()=> gClipboard.write(selection), 100); // записываем в буфер обмена ..... } else { return; } } }, }).init(this); } catch(e) {} Помогите пожалуйста с кодом. |
Dumby > 04-03-2023 16:22:58 |
unter_officer Выделить код Код:// init(that) { document.addEventListener("keydown", this); }, destructor() { this.document.removeEventListener("keydown", this); }, Что ещё за «this.document»? Просто document Выделить код Код:// // выделенный текст из страницы ..... var selection = document.commandDispatcher.focusedWindow.getSelection(); // выделенный текст из текстового поля ..... if ( selection.isCollapsed ) { Какой ещё страницы? Какого ещё текстового поля?
Ну «копировать в буфер» уже произошло, ведь слушается Ctrl+C, И, код, вроде как, под UCF, но используется объект gClipboard, |
unter_officer > 04-03-2023 20:04:58 |
Dumby пишет
Для меня листенеры и деструкторы всегда были "темным лесом". Плюс, в данном случае, моя невнимательность. Dumby пишет
Вот, меня терзали смутные сомнения, что в UCF вроде как не должно быть gClipboard. Не знаю, правильно или нет..... в общем, получился у меня вот такой код: скрытый текст Выделить код Код:try { (this.ucf_SelectedTextToClipboard = { init(that) { document.addEventListener("keydown", this); }, handleEvent(e) { if (e.ctrlKey && e.code == "KeyC") { var write, read = () => { var cb = Services.clipboard, gc = cb.kGlobalClipboard, fl = "text/plain"; var ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); write = str => ch.copyStringToClipboard(str, gc); var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); trans.init(null); return (read = () => { trans.addDataFlavor(fl); cb.getData(trans, gc); var res = {}; trans.getTransferData(fl, res); res = res.value?.QueryInterface(Ci.nsISupportsString).data; trans.removeDataFlavor(fl); return res; })(); } var selection = ''; setTimeout(()=> selection = read(), 100); // читаем из буфера обмена ..... setTimeout(()=> selection = selection.toString().trim(), 100); // убираем пробелы с обоих концов текста ..... setTimeout(()=> write(selection), 100); // записываем в буфер обмена ..... } }, }).init(this); } catch(e) {} На большее, в данном вопросе, я пожалуй не способен. |
kokoss > 14-03-2023 17:41:21 |
Dumby |
voqabuhe > 14-03-2023 18:28:29 |
kokoss пишет
И ещё в кнопке поиск на странице не работает СКМ: Поиск на этой странице из буфера обмена. |
Dumby > 14-03-2023 20:00:37 |
kokoss скрытый текст Выделить код Код:/* readFromClipboard(win) { var url = ""; try { var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); var contxt = ("docShell" in win) ? win.docShell.QueryInterface(Ci.nsILoadContext) : win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsILoadContext); trans.init(contxt); trans.addDataFlavor("text/unicode"); var clipboard = Services.clipboard; clipboard.getData(trans, clipboard.kGlobalClipboard); var data = {}; trans.getTransferData("text/unicode", data, {}); if (data.value) { data = data.value.QueryInterface(Ci.nsISupportsString); url = data.data; } } catch (ex) {} return url; }, */ 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 || ""; } })(); }, |
kokoss > 14-03-2023 21:16:49 |
Dumby пишет
Благодарю! voqabuhe пишет
В этой кнопке работает только ЛКМ. |
xrun1 > 15-03-2023 02:28:27 |
kokoss пишет
Эта кнопка? https://imgsh.net/a/LYEkjcn.png |
voqabuhe > 15-03-2023 05:39:07 |
Dumby пишет
Спасибо. kokoss пишет
Но теперь то всё работает. xrun1 пишет
В смысле после правки от Dumby работают, или без неё работают? |
kokoss > 15-03-2023 09:01:06 |
voqabuhe пишет
Да, после правки вроде всё заработало. |
xrun1 > 15-03-2023 14:01:54 |
voqabuhe пишет
Наверное, после. Я не успел проверить до, сразу сделал правку. |
darex > 15-03-2023 16:52:12 |
Dumby |
Farby > 15-03-2023 17:44:51 |
darex пишет
lpa и в 111`м не работает, но можно попробовать так скрытый текст Выделить код Код:' //.embedderElement.ownerGlobal.gBrowser.loadOneTab(link, { .embedderElement.ownerGlobal.openLinkIn(link, "tab", { |
darex > 15-03-2023 17:56:33 |
Farby пишет
Благодарю, так работает. У кнопки toggle-proxy сломались значки, это возможно исправить? |
Dumby > 15-03-2023 22:16:42 |
darex пишет
Вариант скрытый текст Выделить код Код:/* img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 240'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(146, 69, 101);'/><path style='opacity:0.25;fill:black;' d='M 16.8,17.6 23.1,23.9 8,26 6.4,32.2 11.4,37.2 3.7,44.8 6.9,48 45,48 C 46.7,48 48,46.7 48,45 V 20 L 31.4,3.4'/><path style='fill:white;' d='M 17.4,3 C 16.7,3 16.2,3.82 16.2,4.91 V 15.9 C 16.2,17 16.7,17.8 17.4,17.8 H 30.6 C 31.3,17.8 31.8,17 31.8,15.9 V 4.91 C 31.8,3.82 31.3,3 30.6,3 H 17.4 M 22.4,20.5 V 23.7 H 6.41 V 32.2 H 9.35 V 28.2 H 22.4 V 32.4 H 25.5 V 28.2 H 38.5 V 32.4 H 41.5 V 23.7 H 25.5 V 20.5 H 22.4 M 4.23,35.1 C 3.55,35.1 3,35.9 3,37.1 V 43 C 3,44.1 3.55,45 4.23,45 H 12.1 C 12.8,45 13.3,44.1 13.3,43 V 37.1 C 13.3,35.9 12.8,35.1 12.1,35.1 H 4.23 M 19.9,35.1 C 19.2,35.1 18.7,35.9 18.7,37.1 V 43 C 18.7,44.1 19.2,45 19.9,45 H 27.8 C 28.5,45 29,44.1 29,43 V 37.1 C 29,35.9 28.5,35.1 27.8,35.1 H 19.9 M 35.9,35.1 C 35.2,35.1 34.7,35.9 34.7,37.1 V 43 C 34.7,44.1 35.2,45 35.9,45 H 43.7 C 44.4,45 45,44.1 45,43 V 37.1 C 45,35.9 44.4,35.1 43.7,35.1 H 35.9' /><rect x='0' y='48' width='48' height='48' rx='3' ry='3' style='fill:rgb(209, 8, 3);'/><path style='opacity:0.25;fill:black;' d='M 16.8,65.6 23.1,71.9 8,74 6.4,80.2 11.4,85.2 3.7,92.8 6.9,96 45,96 C 46.7,96 48,94.7 48,93 V 68 L 31.4,51.4'/><path style='fill:white;' d='M 17.4,51 C 16.7,51 16.2,51.8 16.2,52.9 V 63.9 C 16.2,65 16.7,65.8 17.4,65.8 H 30.6 C 31.3,65.8 31.8,65 31.8,63.9 V 52.9 C 31.8,51.8 31.3,51 30.6,51 H 17.4 M 22.4,68.5 V 71.7 H 6.41 V 80.2 H 9.35 V 76.2 H 22.4 V 80.4 H 25.5 V 76.2 H 38.5 V 80.4 H 41.5 V 71.7 H 25.5 V 68.5 H 22.4 M 4.23,83.1 C 3.55,83.1 3,83.9 3,85.1 V 91 C 3,92.1 3.55,93 4.23,93 H 12.1 C 12.8,93 13.3,92.1 13.3,91 V 85.1 C 13.3,83.9 12.8,83.1 12.1,83.1 H 4.23 M 19.9,83.1 C 19.2,83.1 18.8,83.9 18.8,85.1 V 91 C 18.8,92.1 19.2,93 19.9,93 H 27.8 C 28.5,93 29,92.1 29,91 V 85.1 C 29,83.9 28.5,83.1 27.8,83.1 H 19.9 M 35.9,83.1 C 35.2,83.1 34.7,83.9 34.7,85.1 V 91 C 34.7,92.1 35.2,93 35.9,93 H 43.7 C 44.4,93 45,92.1 45,91 V 85.1 C 45,83.9 44.4,83.1 43.7,83.1 H 35.9' /><rect x='0' y='96' width='48' height='48' rx='3' ry='3' style='fill:rgb(243, 135, 37);'/><path style='opacity:0.25;fill:black;' d='M 16.8,114 23.1,120 8,122 6.4,128 11.4,133 3.7,141 6.9,144 H 45 C 46.7,144 48,142.7 48,141 V 116 L 31.4,99.4'/><path style='fill:white;' d='M 17.4,99 C 16.7,99 16.2,99.8 16.2,101 V 112 C 16.2,113 16.7,114 17.4,114 H 30.6 C 31.3,114 31.8,113 31.8,112 V 101 C 31.8,99.8 31.3,99 30.6,99 H 17.4 M 22.4,117 V 120 H 6.41 V 128 H 9.35 V 124 H 22.4 V 128 H 25.5 V 124 H 38.5 V 128 H 41.5 V 120 H 25.5 V 117 H 22.4 M 4.23,131 C 3.55,131 3,132 3,133 V 139 C 3,140 3.55,141 4.23,141 H 12.1 C 12.8,141 13.3,140 13.3,139 V 133 C 13.3,132 12.8,131 12.1,131 H 4.23 M 19.9,131 C 19.2,131 18.8,132 18.8,133 V 139 C 18.8,140 19.2,141 19.9,141 H 27.8 C 28.5,141 29,140 29,139 V 133 C 29,132 28.5,131 27.8,131 H 19.9 M 35.9,131 C 35.2,131 34.7,132 34.7,133 V 139 C 34.7,140 35.2,141 35.9,141 H 43.7 C 44.4,141 45,140 45,139 V 133 C 45,132 44.4,131 43.7,131 H 35.9' /><rect x='0' y='144' width='48' height='48' rx='3' ry='3' style='fill:rgb(21, 161, 99);'/><path style='opacity:0.25;fill:black;' d='M 16.8,162 23.1,168 8,170 6.4,176 11.4,181 3.7,189 6.9,192 H 45 C 46.7,192 48,190.7 48,189 V 164 L 31.4,147'/><path style='fill:white;' d='M 17.4,147 C 16.7,147 16.2,148 16.2,149 V 160 C 16.2,161 16.7,162 17.4,162 H 30.6 C 31.3,162 31.8,161 31.8,160 V 149 C 31.8,148 31.3,147 30.6,147 H 17.4 M 22.4,165 V 168 H 6.41 V 176 H 9.35 V 172 H 22.4 V 176 H 25.5 V 172 H 38.5 V 176 H 41.5 V 168 H 25.5 V 165 H 22.4 M 4.23,179 C 3.55,179 3,180 3,181 V 187 C 3,188 3.55,189 4.23,189 H 12.1 C 12.8,189 13.3,188 13.3,187 V 181 C 13.3,180 12.8,179 12.1,179 H 4.23 M 19.9,179 C 19.2,179 18.8,180 18.8,181 V 187 C 18.8,188 19.2,189 19.9,189 H 27.8 C 28.5,189 29,188 29,187 V 181 C 29,180 28.5,179 27.8,179 H 19.9 M 35.9,179 C 35.2,179 34.7,180 34.7,181 V 187 C 34.7,188 35.2,189 35.9,189 H 43.7 C 44.4,189 45,188 45,187 V 181 C 45,180 44.4,179 43.7,179 H 35.9' /><rect x='0' y='192' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 16.8,210 23.1,216 8,218 6.4,224 11.4,229 3.7,237 6.9,240 H 45 C 46.7,240 48,238.7 48,237 L 48,212 31.4,195'/><path style='fill:white;' d='M 17.4,195 C 16.7,195 16.2,196 16.2,197 V 208 C 16.2,209 16.7,210 17.4,210 H 30.6 C 31.3,210 31.8,209 31.8,208 V 197 C 31.8,196 31.3,195 30.6,195 H 17.4 M 22.4,213 V 216 H 6.41 V 224 H 9.4 V 220 H 22.4 V 224 H 25.5 V 220 H 38.5 V 224 H 41.5 V 216 H 25.5 V 213 H 22.4 M 4.23,227 C 3.55,227 3,228 3,229 V 235 C 3,236 3.55,237 4.23,237 H 12.1 C 12.8,237 13.3,236 13.3,235 V 229 C 13.3,228 12.8,227 12.1,227 H 4.23 M 19.9,227 C 19.2,227 18.7,228 18.7,229 V 235 C 18.7,236 19.2,237 19.9,237 H 27.8 C 28.5,237 29,236 29,235 V 229 C 29,228 28.5,227 27.8,227 H 19.9 M 35.9,227 C 35.2,227 34.7,228 34.7,229 V 235 C 34.7,236 35.2,237 35.9,237 H 43.7 C 44.4,237 45,236 45,235 V 229 C 45,228 44.4,227 43.7,227 H 35.9' /></g></svg>", imgmenu = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 240'><g><circle cy='24' cx='24' style='fill:rgb(146, 69, 101);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,41.8 22.3,31.1 36.7,17.9 44,25.2 C 43.5,30.6 41,37.7 33,41.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,19 H 13 L 24,30 35,19' /><circle cy='72' cx='24' style='fill:rgb(209, 8, 3);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,89.8 22.3,79.1 36.7,65.9 44,73.2 C 43.5,78.6 41,85.7 33,89.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,67 H 13 L 24,78 35,67' /><circle cy='120' cx='24' style='fill:rgb(243, 135, 37);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.8,138 22,127 36.7,114 44,121 C 43.5,127 40.9,134 32.8,138 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 34.9,115 H 13.1 L 24,126 34.9,115' /><circle cy='168' cx='24' style='fill:rgb(21, 161, 99);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.9,186 22,175 36.7,162 44,169 C 43.5,175 40.9,182 32.9,186 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,163 H 13 L 24,174 35,163' /><circle cy='216' cx='24' style='fill:rgb(0, 120, 173);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.8,234 22,223 36.7,210 44,217 C 43.5,223 40.9,230 32.8,234 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,211 H 13 L 24,222 35,211' /></g></svg>"; */ img = "<rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(RGB);'/><path style='opacity:0.25;fill:black;' d='M 16.8,17.6 23.1,23.9 8,26 6.4,32.2 11.4,37.2 3.7,44.8 6.9,48 45,48 C 46.7,48 48,46.7 48,45 V 20 L 31.4,3.4'/><path style='fill:white;' d='M 17.4,3 C 16.7,3 16.2,3.82 16.2,4.91 V 15.9 C 16.2,17 16.7,17.8 17.4,17.8 H 30.6 C 31.3,17.8 31.8,17 31.8,15.9 V 4.91 C 31.8,3.82 31.3,3 30.6,3 H 17.4 M 22.4,20.5 V 23.7 H 6.41 V 32.2 H 9.35 V 28.2 H 22.4 V 32.4 H 25.5 V 28.2 H 38.5 V 32.4 H 41.5 V 23.7 H 25.5 V 20.5 H 22.4 M 4.23,35.1 C 3.55,35.1 3,35.9 3,37.1 V 43 C 3,44.1 3.55,45 4.23,45 H 12.1 C 12.8,45 13.3,44.1 13.3,43 V 37.1 C 13.3,35.9 12.8,35.1 12.1,35.1 H 4.23 M 19.9,35.1 C 19.2,35.1 18.7,35.9 18.7,37.1 V 43 C 18.7,44.1 19.2,45 19.9,45 H 27.8 C 28.5,45 29,44.1 29,43 V 37.1 C 29,35.9 28.5,35.1 27.8,35.1 H 19.9 M 35.9,35.1 C 35.2,35.1 34.7,35.9 34.7,37.1 V 43 C 34.7,44.1 35.2,45 35.9,45 H 43.7 C 44.4,45 45,44.1 45,43 V 37.1 C 45,35.9 44.4,35.1 43.7,35.1 H 35.9'/>", imgmenu = "<circle cy='24' cx='24' style='fill:rgb(RGB);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,41.8 22.3,31.1 36.7,17.9 44,25.2 C 43.5,30.6 41,37.7 33,41.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,19 H 13 L 24,30 35,19'/>"; Выделить код Код:/* get btnstyle() { delete this.btnstyle; return this.btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(` #${id}-button { list-style-image: url("${img}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; } #${id}-button-menu { list-style-image: url("${imgmenu}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; } #${id}[activated="1"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(16px, 16px, 32px, 0px) !important; } #${id}[activated="2"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(32px, 16px, 48px, 0px) !important; } #${id}[activated="4"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(48px, 16px, 64px, 0px) !important; } #${id}[activated="5"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(64px, 16px, 80px, 0px) !important; } */ get btnstyle() { var rgb = ["146,69,101", "209,8,3", "243,135,37", null, "21,161,99", "0,120,173"]; var beg = 'list-style-image: url("data:image/svg+xml;charset=utf-8,' + "<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g>"; var lsi = (ind, isMenu) => `${beg}${(isMenu ? imgmenu : img).replace("RGB", rgb[ind])}</g></svg>") !important;`; delete this.btnstyle; return this.btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(` #${id}-button { ${lsi(0)} } #${id}-button-menu { ${lsi(0, true)} }\n${ (ws => { var n, arr = []; var r = m => `${ws}#${id}[activated="${n}"] > #${id}-button${m} {\n${ws} ${lsi(n, m)}\n${ws}}`; for(n of "1245") arr.push(r(""), r("-menu")); return arr.join("\n"); })(" ".repeat(20)) } |
darex > 16-03-2023 06:23:26 |
Dumby пишет
Большое спасибо, всё исправилось. |
Dumby > 16-03-2023 16:36:17 |
egorsemenov06 пишет
Не буду. Про readFromClipboard() обсуждалось отсюда, |
b0ttle > 17-03-2023 12:48:29 |
Здравствуйте, можно ли сделать что-то подобное. Как на сайте translit .cc 17-03-2023 13:05:32 |
unter_officer > 17-03-2023 14:53:01 |
b0ttle пишет
|
b0ttle > 18-03-2023 13:56:28 |
Кто знает, как изменить размер vertical-toolbar, какой-то он широкий. Или в каком файле эти настройки хранятся. Последняя user-chrome-files которая в шапке. Кстати, мне кажется, или там есть проблемы с auto_hide_sidebar и special_widgets. Ну при них, кнопка не работает открытия закладки. При этом не всегда реагирует на открытие, не октрывает автоматом. В общем, убрал их. Только мешаются. Наверно в новых версиях их нужно править. |
xrun1 > 18-03-2023 14:40:24 |
b0ttle скрытый текст Выделить код Код:/* Сжать доп.панели https://forum.mozilla-russia.org/viewtopic.php?pid=775867#p775867 */ #ucf-additional-top-bar, #ucf-additional-bottom-bar { --toolbarbutton-outer-padding: 2px !important; /* было 0px */ --toolbarbutton-inner-padding: 2px !important; min-height: 18px !important; } :-moz-any(#ucf-additional-top-bar,#ucf-additional-bottom-bar) .toolbarbutton-badge { margin-inline-end: calc(-1 * (var(--toolbarbutton-outer-padding) + var(--toolbarbutton-inner-padding))) !important; } #ucf-additional-bottom-closebutton { padding: 0 !important; } #ucf-additional-vertical-bar { --toolbarbutton-outer-padding: 2px !important; /* было 0px */ --toolbarbutton-inner-padding: 3px !important; min-width: 18px !important; } #ucf-additional-vertical-bar .toolbarbutton-badge { margin-inline-end: calc(-1 * (var(--toolbarbutton-outer-padding) + var(--toolbarbutton-inner-padding))) !important; } P.S. По ссылке исходное сообщение. Обратите внимание, название панелей изменились. P.P.S. special_widgets работают, auto_hide_sidebar не пользуюсь, не знаю. И вообще никаких проблем с открытием закладки. |
b0ttle > 18-03-2023 18:53:36 |
xrun1 |
kokoss > 18-03-2023 19:39:22 |
b0ttle пишет
Что бы появились в файле CustomStylesScripts.jsm включите пункты;
и в настройках user_chrome_files эти настройки;
и после этого перезапустить браузер с очисткой кэша запуска. |
b0ttle > 18-03-2023 20:34:33 |
Спасибо за стиль с доп.панелями, помогло. С интервалами тоже решилось. 18-03-2023 20:39:02 |
kokoss > 18-03-2023 22:38:25 |
b0ttle |
xrun1 > 19-03-2023 15:00:26 |
В расширении Async Run Applications 2021.9.7 правка parent.js тоже сработала. |
unter_officer > 19-03-2023 22:09:37 |
Dumby P.S. Если на любую другую панель очень сложно, то лично меня устроил бы перенос этой кнопки на "Дополнительную панель" из UCF. |
Dumby > 20-03-2023 09:18:16 |
unter_officer пишет
Не располагаю сейчас временем задуматься. custom_script_win.js, "DOMContentLoaded" (не "load"). скрытый текст Выделить код Код:(async id => { if (!Services.prefs.getStringPref("browser.uiCustomization.state").includes(`"${id}"`)) await delayedStartupPromise; var btn = document.getElementById(id); btn.setAttribute("removable", true); document.getElementById("nav-bar-customization-target").append(btn); })("unified-extensions-button"); |
unter_officer > 20-03-2023 12:00:07 |
Dumby |
b0ttle > 20-03-2023 22:40:02 |
Можно ли сделать код, который бы открывал ссылки правым кликом? Может есть у кого? |
xrun1 > 21-03-2023 04:35:24 |
b0ttle |
6e73epo > 21-03-2023 10:33:43 |
Dumby, возможно ли адаптировать код, который делает кнопку съемной, под config.js? |
b0ttle > 21-03-2023 12:05:40 |
xrun1 |
xrun1 > 21-03-2023 12:39:04 |
b0ttle |
Dumby > 21-03-2023 13:34:37 |
6e73epo пишет
Не совсем так. Она, вроде как, задумана использоваться не только Вобщем, не нашёл сходу подходящего топика, поэтому "chrome-document-interactive". скрытый текст Выделить код Код:// (async topic => { var id = "unified-extensions-button", qid = `"${id}"`; var obs = async doc => { var btn = doc.getElementById(id); if (!btn) return; if (!Services.prefs.getStringPref("browser.uiCustomization.state").includes(qid)) await doc.ownerGlobal.delayedStartupPromise; btn.setAttribute("removable", true); doc.getElementById("nav-bar-customization-target").append(btn); } Services.obs.addObserver(obs, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(obs, topic); }, "quit-application-granted"); })("chrome-document-interactive"); |
6e73epo > 21-03-2023 15:11:12 |
Dumby, а если бы речь шла только о том, чтобы сделать кнопку съемной, например alltabs-button, то в только что приведенном вами коде не достаточно было бы просто сменить id на "alltabs-button" и присутствует что-то лишнее? Если мне не изменяет память, то раньше эта кнопка была съемной, а по какой причине эту возможность убрали, мне не ясно |
Dumby > 21-03-2023 20:45:35 |
6e73epo пишет
Ну, почему не достаточно, достаточно. И да, лишнее, для alltabs-button, определённо, присутствует. |
6e73epo > 21-03-2023 23:17:12 |
Dumby, благодарю, получилось. Раньше для того, чтобы сделать кнопку съемной, я в манифесте через override подсовывал измененный файл. |
b0ttle > 22-03-2023 20:45:22 |
6e73epo |
_zt > 22-03-2023 22:31:35 |
Dumby пишет
А как использовать, (async () => { ... })(); , или типа того, нужен? |
Dumby > 23-03-2023 00:15:35 |
_zt пишет
Искуство быть непонятным? |
_zt > 23-03-2023 05:22:25 |
Dumby для unified-extensions-button А для alltabs-button этого не надо? Просто строку данную выше вписываем? |
Dumby > 23-03-2023 09:55:26 |
_zt Была просьба перерисовать код для unified-extensions-button Поэтому обсёрвер, и даже async так же используется Затем, вдогонку, вопрос, как бы это могло выглядеть уже для alltabs-button скрытый текст Выделить код Код:(async topic => { var obs = doc => doc.getElementById("alltabs-button")?.setAttribute("removable", true); Services.obs.addObserver(obs, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(obs, topic); }, "quit-application-granted"); })("chrome-document-interactive"); А если для alltabs-button под custom_script_win.js то хватит и одной строки document.getElementById("alltabs-button").setAttribute("removable", true); Тоже "DOMContentLoaded" (не "load"). |
_zt > 23-03-2023 18:03:54 |
Dumby |
unter_officer > 24-03-2023 03:11:15 |
Dumby скрытый текст Выделить код Код:try { (this.ucf_DblclickTabUpPage = { init(that) { gBrowser.tabContainer.addEventListener("dblclick", this); }, handleEvent(e) { if ( e.button == 0 && e.target.matches("tab :scope:not(.tab-close-button):not(.tab-icon-sound), tab") ) { e.preventDefault(); var vert = `javascript:(function(d,scrT){scrT=d.documentElement.scrollTop||d.body.scrollTop;if(scrT>window.innerHeight){localStorage['bmk_'+d.location.href]=scrT;scrollTo(0,0)}else{scrollTo(0,localStorage['bmk_'+d.location.href]||0)}})(document)`; gBrowser.loadURI(vert, { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }); } }, }).init(this); } catch(e) {} Не поможете реанимировать. |
Dumby > 24-03-2023 10:16:57 |
unter_officer пишет
Это Bug 1810141 - Loading URIs should be done with URI objects by default, rather than strings, to help avoid unnecessary parsing / fixup / allocations То есть, либо |
unter_officer > 24-03-2023 11:33:28 |
Dumby |
b0ttle > 25-03-2023 09:48:22 |
Можно реанимировать? скрытый текст Выделить код Код:// https://web.archive.org/web/20211130053336/https://forum.mozilla-russia.org/viewtopic.php?pid=785023#p785023 ... try {(() => { var id = "ucf-aom-button", label = "Дополнения", tooltiptext = "ЛКМ: Меню дополнений\nСКМ: Отладка дополнений\nПКМ: Открыть менеджер дополнений", img="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAt0lEQVR42mP4//8/AzK269D+zxDPAMYgNro8OsYUsGf4L5IrAMYgNskGPHrzkAHmAhCbZAPAglFAA6II2w5WC/ZzGEQDDMO9gCQGUmNYr4dhKANPBgdcAyEMMgSrAWA/R0H8jdcALN5iQHYWLABJMgBbABJjACiKweFHigHwgIW6Eux1UryA1QD0QISzsQQqVi+gKEBLfeguwhqIBEM5ihQD4rEoQHaBLwEDQOGBHKggNiyl4sreAEpLK4gRQN5TAAAAAElFTkSuQmCC", //img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 24,4.5 18,12 3,23.7 12,32.7 3.9,44.1 7.8,48 H 45 C 46.7,48 48,46.7 48,45 V 26.1 L 34.8,12.9 31.8,12.3 Z'/><path style='fill:white;' d='M 19.88,3 C 16.93,3 14.55,4.662 14.55,6.701 14.63,7.474 15.11,8.438 15.37,8.762 16.59,10.41 16.59,11.44 16.29,12.06 H 6.299 C 4.476,12.06 3,13.53 3,15.35 V 23.68 C 3.625,24 4.65,24 6.299,22.77 6.625,22.52 7.587,22.02 8.363,21.94 10.4,21.94 12.06,24.35 12.06,27.29 12.06,30.24 10.4,32.65 8.363,32.65 7.725,32.63 6.774,32.07 6.299,31.82 4.65,30.59 3.625,30.59 3,30.91 V 41.71 C 3,43.53 4.476,45 6.299,45 H 19.58 C 19.88,44.38 19.88,43.35 18.65,41.71 18.4,41.38 17.91,40.42 17.82,39.65 17.82,37.6 20.23,35.94 23.18,35.94 26.14,35.94 28.55,37.6 28.55,39.65 28.53,40.28 27.97,41.23 27.71,41.71 26.47,43.35 26.47,44.38 26.79,45 H 32.65 C 34.47,45 35.96,43.53 35.96,41.71 V 32.55 C 36.56,32.23 37.59,32.23 39.23,33.47 39.72,33.73 40.68,34.29 41.29,34.29 43.35,34.29 45,31.91 45,28.94 45,25.99 43.35,23.59 41.29,23.59 40.54,23.67 39.58,24.17 39.23,24.41 37.59,25.65 36.56,25.65 35.96,25.33 V 15.35 C 35.96,13.53 34.47,12.06 32.65,12.06 H 23.49 C 23.19,11.44 23.19,10.41 24.41,8.762 24.66,8.287 25.22,7.337 25.23,6.713 25.23,4.662 22.85,3 19.88,3' /></g></svg>", checked = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='M 3,7 7,11 13,5' style='fill:none;stroke:white;stroke-width:1;'/></svg>", show_version = false, show_description = true, user_permissions = true, show_hidden = true, show_disabled = true, enabled_first = true, exceptions_listset = new Set([ ]), exceptions_type_listset = new Set([ ]); if (!("AddonManager" in this)) ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm"); if (!("GlobalManager" in this)) XPCOMUtils.defineLazyGetter(this, "GlobalManager", () => { const { GlobalManager } = ChromeUtils.import("resource://gre/modules/Extension.jsm", null); return GlobalManager; }); var extensionOptionsMenu = { get alertsService() { delete this.alertsService; return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); }, get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, get exceptions_type_listarr() { delete this.exceptions_type_listarr; var arr = ["extension", "theme", "locale", "dictionary"]; if (!exceptions_type_listset.size) return this.exceptions_type_listarr = arr; return this.exceptions_type_listarr = arr.filter(type => !exceptions_type_listset.has(type)); }, async populateMenu(e) { var popup = e.target, doc = e.view.document; var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr); var addonsMap = new WeakMap(), setAttributesMenu = (mi, addon, extension) => { var permissions, uuid, props = { label: `${addon.name}${show_version ? ` ${addon.version}` : ""}`, class: "menuitem-iconic", tooltiptext: `${(show_description && addon.description) ? `${addon.description}\n` : ""}ID: ${addon.id}${addon.isActive && (uuid = extension?.uuid) ? `\nUUID: ${uuid}` : ""}${(user_permissions && (permissions = addon.userPermissions?.permissions)?.length) ? `\nРазрешения: ${permissions.join(", ")}` : ""}\n${addon.optionsURL ? "\nЛКМ: Настройки" : ""}\nCtrl+ЛКМ: Копировать ID${uuid ? "\nShift+ЛКМ: Копировать UUID" : ""}${addon.creator?.url ? "\nCtrl+Shift+ЛКМ: Автор" : ""}${addon.homepageURL ? "\nСКМ: Домашняя страница" : ""}${!addon.isBuiltin ? "\nCtrl+СКМ: Просмотр источника" : ""}\nShift+СКМ: Просмотр источника во вкладке\nПКМ: Включить/Отключить${(!addon.isSystem && !addon.isBuiltin) ? "\nCtrl+ПКМ: Удалить" : ""}`, }; for (let p in props) mi.setAttribute(p, props[p]); if (addon.iconURL) mi.setAttribute("image", addon.iconURL); var cls = mi.classList; addon.isActive ? cls.remove("ucf-disabled") : cls.add("ucf-disabled"); addon.optionsURL ? cls.remove("ucf-notoptions") : cls.add("ucf-notoptions"); addon.isSystem ? cls.add("ucf-system") : cls.remove("ucf-system"); cls.add(`ucf-type-${addon.type}`); }; addons.filter(a => !(a.iconURL || "").startsWith("resource://search-extensions/")).sort((a, b) => { var ka = `${(enabled_first ? a.isActive ? "0" : "1" : "")}${a.type || ""}${a.name.toLowerCase()}`; var kb = `${(enabled_first ? b.isActive ? "0" : "1" : "")}${b.type || ""}${b.name.toLowerCase()}`; return (ka < kb) ? -1 : 1; }).forEach(addon => { if (!exceptions_listset.has(addon.id) && (!addon.hidden || show_hidden) && (!addon.userDisabled || show_disabled)) { let extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.append(mi); addonsMap.set(addon, mi); } }); var click = e => { 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(`${img}`, "ID в буфере обмена!", addon.id, false); }, 100); } else if (e.shiftKey) { if (extension?.uuid) { this.clipboardHelp.copyString(extension.uuid); win.setTimeout(() => { this.alertsService.showAlertNotification(`${img}`, "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: win.BrowserOpenAddonsMgr(`addons://detail/${encodeURIComponent(addon.id)}/preferences`); 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); }, }; CustomizableUI.createWidget({ id: id, type: "custom", label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild(doc) { var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView, props = { id: id, label: label, context: "", tooltiptext: tooltiptext, type: "menu", class: "toolbarbutton-1 chromeclass-toolbar-additional", }; for (let p in props) btn.setAttribute(p, props[p]); btn.addEventListener("click", e => { if (e.button == 0) e.view.switchToTabHavingURI("about:debugging#/runtime/this-firefox", true, { ignoreFragment: "whenComparing", triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), }); else if (e.button == 2) e.view.BrowserOpenAddonsMgr("addons://list/extension"); }); 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}, #${id}-popup menuitem { list-style-image: url("${img}") !important; } #${id}-popup menuitem::after { display: -moz-box !important; content: "" !important; height: 16px !important; width: 16px !important; padding: 0 !important; border: 1px solid rgb(0, 116, 232) !important; border-radius: 0 !important; background-repeat: no-repeat !important; background-position: center !important; background-size: 16px !important; background-color: rgb(0, 116, 232) !important; background-image: url("${checked}") !important; opacity: 1 !important; } #${id}-popup menuitem.ucf-disabled::after { border-color: currentColor !important; background-color: transparent !important; background-image: none !important; opacity: .6 !important; } #${id}-popup menuitem.ucf-disabled > label, #${id}-popup menuitem.ucf-notoptions > label { opacity: .6 !important; } #${id}-popup menuitem.ucf-system > label { text-decoration: underline !important; text-decoration-style: dotted !important; } #${id}-popup menuitem > label { margin-inline-end: 0 !important; } #${id}-popup menuitem > .menu-accel-container { display: -moz-box !important; padding: 4px !important; margin: 0 !important; opacity: 1 !important; } #${id}-popup menuitem > .menu-accel-container .menu-iconic-accel { display: -moz-box !important; margin: 0 !important; height: 8px !important; width: 8px !important; border-radius: 4px !important; background-color: transparent !important; opacity: 1 !important; font-size: 0 !important; } #${id}-popup menuitem.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel { background-color: rgb(227, 27, 93) !important; } #${id}-popup menuitem.ucf-type-locale > .menu-accel-container .menu-iconic-accel { background-color: rgb(48, 172, 55) !important; } #${id}-popup menuitem.ucf-type-theme > .menu-accel-container .menu-iconic-accel { background-color: rgb(219, 106, 0) !important; } `); try { win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} return btn; }, }); })();} catch (e) {} |
LGS > 25-03-2023 10:01:21 |
b0ttle > 25-03-2023 10:22:11 |
LGS |
b0ttle > 25-03-2023 11:04:57 |
del |
xrun1 > 25-03-2023 11:20:19 |
b0ttle |
b0ttle > 25-03-2023 12:04:27 |
xrun1 |
xrun1 > 25-03-2023 14:16:42 |
b0ttle пишет
№694 и дальше (решения от ув. Dumby). |
LGS > 31-03-2023 12:44:10 |
Dumby, вы не могли бы кнопку about:config из Add Toolbar Buttons 2021.9.5 сделать отдельной для UCF..? |
_zt > 31-03-2023 18:19:37 |
LGS > 31-03-2023 19:04:54 |
_zt, отлично, спасибо. В итоге, ваш вариант сейчас "причесываю". Dumby, надеюсь, что не успел время отобрать. Уже не надо, выше подсказали. |
LGS > 31-03-2023 20:05:09 |
_zt, а причесать то не получается. Теперь не знаю как about:cfg заменить на chrome://user_chrome_files/content/aboutconfig/config.xhtml. Замена в строке aboutoldurl = "about:cfg" ничего не дает. Мне, в принципе, кнопка и нужна была для старого about:config. Added: причесал, работает. |
_zt > 01-04-2023 11:13:45 |
LGS Выделить код Код:document.getElementById("configDeck").setAttribute("selectedIndex", 0); вместо document.getElementById("configDeck").selectedIndex = 0; Ссылку не сохранил, где то в этой теме, вроде. |
xrun1 > 01-04-2023 13:55:22 |
_zt пишет
https://forum.mozilla-russia.org/viewtopic.php?pid=802633#p802633 |
LGS > 01-04-2023 15:53:35 |
_zt пишет
Нет, без замены about:cfg на chrome://user_chrome_files/content/aboutconfig/config.xhtml вскрипте от Vitaly V. в вашей редакции (2-й спойлер) не срабатывает. Может это у меня что-то особенное: |
xrun1 > 01-04-2023 21:05:26 |
_zt |
_zt > 01-04-2023 21:47:33 |
LGS |
LGS > 02-04-2023 08:59:58 |
_zt пишет
На 102 с пол-пинка завелось... на 111 тоже about:cfg заработал. Что мешало - не пойму, наверное что-то локальное. |
xrun1 > 02-04-2023 14:46:05 |
_zt |
voqabuhe > 10-04-2023 19:40:52 |
Dumby |
Farby > 10-04-2023 21:14:47 |
voqabuhe пишет
я, думал что это скрипт, но... |
Dumby > 11-04-2023 12:38:07 |
voqabuhe пишет
Да, как-то пробовал нарезать тамошние SVG'шки вручную. скрытый текст Выделить код Код:data:text/html;charset=utf-8,<!DOCTYPE html>%0A<html>%0A%09<head>%0A%09%09<title>ATB Bug 1817071</title>%0A%09%09<meta http-equiv="Content-Type" content="text/html; charset=utf-8">%0A%09</head>%0A%09<body style="padding-top: 16vh;">%0A%09%09<center><h1 style="font-family: Consolas, Verdana;">%0A%09%09%09<a%0A%09%09%09%09download="ATB_Bug_1817071.zip"%0A%09%09%09%09href="data:application/x-zip-compressed;base64,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"%0A%09%09%09>%0A%09%09%09%09ATB_Bug_1817071.zip</a>%0A%09%09</h1></center>%0A%09</body>%0A</html> |
doud > 11-04-2023 15:29:46 |
Можно ли создать скрипт для создания кнопки расширений, как в старых версиях Firefox? Нажал кнопку левой кнопкой мыши -открылась страница управление дополнениями.А больше ничего и не надо.. |
kokoss > 11-04-2023 16:39:05 |
Dumby пишет
Благодарю |
kokoss > 11-04-2023 17:24:07 |
doud |
Dumby > 11-04-2023 18:37:15 |
doud пишет
Да, пока что можно, откуда сомнение (?).
Это просьба? скрытый текст Выделить код Код:(async () => CustomizableUI.createWidget({ id: "804471", label: "???", tooltiptext: "??? ???", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { btn._handleClick = this.click; btn.image = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABMAAAATAAAAEwAAABMAAAATAAAAAAAAAAAAAAAAAAAAEwAAABMAAAATAAAAEwAAAAAAAAAAAAAAAAAAAL8AAADEAAAAxgAAAMYAAADGAAAAEwAAAAAAAAAAAAAAvwAAAMQAAADGAAAAxgAAABMAAAAAAAAAAAAAAAAAAAC/wP/M/wD/AP8A/wD/AAAAxgAAABMAAAATAAAAEwAAAMQA/wD/J/9U/wAAAMYAAAATAAAAAAAAAAAAAAAAAAAAv6b/wP+m/8D/VP+G/wAAAMYAAADGAAAAxgAAAMYAAADGAP8A/wD/Lf8AAADGAAAAEwAAABMAAAATAAAAAAAAAL8AAAC/AAAAvwDzAP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AAAAxgAAAMYAAADGAAAAEwAAAAAAAAAAAAAAAAAAAL8A4AD/APMA/wDzAP8A8wD/APMA/wDzAP8A8wD/AP8A/wD/AP8A/wD/AAAAxgAAABMAAAAAAAAAAAAAAAAAAAC/AMwA/wDgAP8A4AD/AOAA/wDgAP8A4AD/AOAA/wDgAP8A4AD/AP8A/wAAAMYAAAATAAAAAAAAAAAAAAATAAAAxACzAP8AzAD/AMwA/wDMAP8AzAD/AMwA/wDMAP8A/wD/AP8A/wD/AP8AAADEAAAADwAAAAAAAAC/AAAAxAAAAMYAoAD/ALMA/wCzAP8AswD/ALMA/wCzAP8AswD/AP8A/wAAAMYAAADEAAAAkQAAAAAAAAAAAAAAvwD/R/8A/0f/AP9H/wCgAP8AoAD/AKAA/wCgAP8AoAD/AKAA/wD/AP8AAADGAAAAEwAAAAAAAAAAAAAAAAAAAL8A/zT/AIYA/wCGAP8AhgD/AIYA/wCGAP8AhgD/AIYA/wCGAP8A7AD/AAAAxgAAABMAAAAAAAAAAAAAAAAAAAC/AP8g/wD/IP8A/yD/AP8g/wD/IP8AegD/AP8g/wD/IP8A/yD/AP8A/wAAAMQAAAATAAAAAAAAAAAAAAAAAAAAvwAAAL8AAAC/AAAAvwAAAL8A/w3/AGcA/wD/Df8AAADGAAAAxAAAAL8AAAC/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC/APMA/wDzAP8A8wD/AAAAxAAAABMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkQAAAL8AAAC/AAAAvwAAAL8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwcOsQYGDrEGAA6xBgACsQYAArEHgAKxB4ACsQcAArEGAAaxBgAOsQYADrEGAA6xBgAesQfgfrEH4P6xB//+sQQ=="; }, click() { this.ownerGlobal.openTrustedLinkIn("about:addons", "current"); } }))(); |
voqabuhe > 11-04-2023 18:54:35 |
Dumby пишет
Замечательно. Большое спасибо. |
doud > 11-04-2023 19:13:06 |
Dumby, Спасибо!Работает без всяких id'шников, имен, тултипов.Только как сделать, чтобы страница дополнений открывалась в новой вкладке? |
Dumby > 11-04-2023 19:59:34 |
doud пишет
Ясно, я был непонят, абсолютно вообще.
Ну, если так ставишь вопрос, то можно заменить в коде current на tab |
unter_officer > 12-04-2023 00:21:22 |
egorsemenov06 пишет
|
Vitaliy V. > 12-04-2023 00:22:42 |
Dumby пишет
Когда иконки разделены на отдельные файлы то при первом нажатии иконка не загруженная в память может появлятся с задержкой. скрытый текст Выделить код Код:<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> <view id="5" viewBox="0 16 16 16"/> <view id="1" viewBox="0 32 16 16"/> <g style="fill:none;stroke:context-fill;stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;"> <path d="M4.4 5.4V1.6H.6m3.4.2C3.1 2.1.6 4 .6 8S4 15.4 8 15.4 15.4 12 15.4 8s-2.9-6-3.8-6.5M4.4 21.4v-3.8H.6m3.4.2C3.1 18.1.6 20 .6 24S4 31.4 8 31.4s7.4-3.4 7.4-7.4-2.9-6-3.8-6.5M4.4 37.4v-3.8H.6m3.4.2C3.1 34.1.6 36 .6 40S4 47.4 8 47.4s7.4-3.4 7.4-7.4-2.9-6-3.8-6.5"/> <path d="M6.6 4.6 10 8l-3.4 3.4ZM6.6 27.4v-6.8m3 0v6.8M6.6 43.4v-6.8M9.6 36.6 13 40l-3.4 3.4Z"/> </g> </svg> button.css скрытый текст Выделить код Код:#b-autoplay { list-style-image: url("resource://add_toolbar_buttons/svg/autoplay.svg") !important; } #b-autoplay[activated="false"], #b-autoplay[activated="5"] { list-style-image: url("resource://add_toolbar_buttons/svg/autoplay.svg#5") !important; } #b-autoplay[activated="1"] { list-style-image: url("resource://add_toolbar_buttons/svg/autoplay.svg#1") !important; } |
kokoss > 12-04-2023 01:19:56 |
egorsemenov06 пишет
Что бы не пропадала, необходимо применить 1. пункт по ссылке что вам дали. |
Dumby > 12-04-2023 15:12:15 |
Vitaliy V. пишет
Ух-ты, круть-то какая! насколько понятно, сперва меняем рутский width-height, затем, добавляем ему неких дочерних <view> со своим viewBox'ом, P.S. Отче, мы осиротевши без тебя, видишь же, без присмотра, творится бардак. egorsemenov06 пишет
Нет, не буду. |
xrun1 > 12-04-2023 20:42:34 |
Dumby |
Dumby > 12-04-2023 22:41:27 |
xrun1 |
xrun1 > 13-04-2023 00:58:00 |
Dumby |
LGS > 13-04-2023 10:12:54 |
Dumby, а мне в каком направлении двигаться, если у меня Add Toolbar Buttons 2021.9.5, но с svg(цветными) и button.css от АТВ 2020.8.14..? В 112 иконки стали узкими, некоторые на разноцветные столбики похожие: |
Farby > 13-04-2023 11:06:39 |
LGS пишет
выложите на посмотреть |
LGS > 13-04-2023 12:51:59 |
Farby пишет
https://www.upload.ee/files/15113333/AT … d.rar.html |
Dumby > 13-04-2023 14:03:55 |
LGS пишет
Как в каком? Например, для «Переключить прокси» world-network.svg & buttons-for-toolbars-menu.svg Выделить код Код:<!-- <svg xmlns="http://www.w3.org/2000/svg" height="80" width="16" viewBox="0 0 48 240"> --> <svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 48 48"> <view id="1" viewBox="0 48 48 48"/> <view id="2" viewBox="0 96 48 48"/> <view id="4" viewBox="0 144 48 48"/> <view id="5" viewBox="0 192 48 48"/> button.css Выделить код Код:/************ #b-toggle-proxy { list-style-image: url("svg/world-network.svg") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; margin-inline-end: 0 !important; } #b-toggle-proxy-menu { list-style-image: url("svg/buttons-for-toolbars-menu.svg") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; margin-inline-start: 0px !important; } #toolbaritem-b-toggle-proxy[activated="1"] :-moz-any(#b-toggle-proxy,#b-toggle-proxy-menu) { -moz-image-region: rect(16px, 16px, 32px, 0px) !important; } #toolbaritem-b-toggle-proxy[activated="2"] :-moz-any(#b-toggle-proxy,#b-toggle-proxy-menu) { -moz-image-region: rect(32px, 16px, 48px, 0px) !important; } #toolbaritem-b-toggle-proxy[activated="4"] :-moz-any(#b-toggle-proxy,#b-toggle-proxy-menu) { -moz-image-region: rect(48px, 16px, 64px, 0px) !important; } #toolbaritem-b-toggle-proxy[activated="5"] :-moz-any(#b-toggle-proxy,#b-toggle-proxy-menu) { -moz-image-region: rect(64px, 16px, 80px, 0px) !important; } ************/ #b-toggle-proxy { list-style-image: url("svg/world-network.svg") !important; margin-inline-end: 0 !important; } #toolbaritem-b-toggle-proxy[activated="1"] > #b-toggle-proxy { list-style-image: url("svg/world-network.svg#1") !important; } #toolbaritem-b-toggle-proxy[activated="2"] > #b-toggle-proxy { list-style-image: url("svg/world-network.svg#2") !important; } #toolbaritem-b-toggle-proxy[activated="4"] > #b-toggle-proxy { list-style-image: url("svg/world-network.svg#4") !important; } #toolbaritem-b-toggle-proxy[activated="5"] > #b-toggle-proxy { list-style-image: url("svg/world-network.svg#5") !important; } #b-toggle-proxy-menu { list-style-image: url("svg/buttons-for-toolbars-menu.svg") !important; margin-inline-start: 0px !important; } #toolbaritem-b-toggle-proxy[activated="1"] > #b-toggle-proxy-menu { list-style-image: url("svg/buttons-for-toolbars-menu.svg#1") !important; } #toolbaritem-b-toggle-proxy[activated="2"] > #b-toggle-proxy-menu { list-style-image: url("svg/buttons-for-toolbars-menu.svg#2") !important; } #toolbaritem-b-toggle-proxy[activated="4"] > #b-toggle-proxy-menu { list-style-image: url("svg/buttons-for-toolbars-menu.svg#4") !important; } #toolbaritem-b-toggle-proxy[activated="5"] > #b-toggle-proxy-menu { list-style-image: url("svg/buttons-for-toolbars-menu.svg#5") !important; } |
LGS > 13-04-2023 16:21:32 |
Dumby пишет
Жаль, неведомо отче, что скуден ум мой науку эту постичь. Живем тем, что люд добрый подскажет, да направит на путь истинный. Dumby пишет
Что-то не подхватываются иконки. В world-network.svg и buttons-for-toolbars-menu.svg прописывал: скрытый текст Выделить код Код:<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" viewBox="0 0 48 48"> <view id="1" viewBox="0 48 48 48"/> <view id="2" viewBox="0 96 48 48"/> <view id="4" viewBox="0 144 48 48"/> <view id="5" viewBox="0 192 48 48"/>
и с </svg> в конце тоже не работает. В buttons.css тяжело что-то напутать. Правил и вживую в установленном расширении, и в распакованном с последующей заменой. startupCache выжигал каленым железом - не помогло. Кнопки есть и работают, но без значков: Добавлено: разобрался, благодаря Farby, как правильно код в svg-ку прописывать. Теперь заработало. |
kokoss > 13-04-2023 16:23:50 |
Add, лучше так -> Add Toolbar Buttons 2021.9.5 с правками от Dumby, для firefox 112+ |
Farby > 13-04-2023 16:34:49 |
LGS пишет
или файлы на замену, как Сам отец-основатель рекомендовал скрытый текст Выделить код Код:data:application/zip;base64,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 |
LGS > 13-04-2023 17:06:56 |
Farby пишет
Снизошла благодать господня, спасибо вам, добрый человек! Просто воткнул содержимое архива в расширение с заменой - заработало: |
Farby > 13-04-2023 17:53:39 |
LGS пишет
Да именно там метода от отца-основателя. Это как, например docx ковырять без word, так и svg без векторного редактора ковырять в блокноте... |
kokoss > 13-04-2023 19:21:49 |
Dumby |
doud > 13-04-2023 20:19:25 |
После выхода Firefox 110 перестал работать скрипт URL tooltip |
kokoss > 13-04-2023 20:27:35 |
doud пишет
У меня в 112 работает -> https://forum.mozilla-russia.org/viewtopic.php?pid=792745#p792745 |
doud > 13-04-2023 20:34:41 |
kokos, этот пробовал, тоже не работает... |
kokoss > 13-04-2023 20:56:01 |
doud пишет
Какую версию UCF используйте ? |
doud > 13-04-2023 21:02:22 |
А хрен его знает, я в этом не особенно разбираюсь.Года 2021 наверно... |
Farby > 13-04-2023 21:08:33 |
kokoss пишет
Это файл diff, если про linux, но если про вообще это файл в котором отображен лог изменения одной версии и другой. |
kokoss > 13-04-2023 21:21:44 |
doud пишет
Там же есть текстовый файл с названием -> version. У меня в последней версии 2021-9-23 работает. Farby пишет
ясненько... |
doud > 13-04-2023 21:26:51 |
Версия-2021-6-5 |
kokoss > 13-04-2023 21:37:01 |
doud пишет
Тоже до недавнего времени сидел на этой версии, вламы было обновляться, но пришлось, что и вам советую, скорее всего причина в этом! скрытый текст https://www.mediafire.com/file/a4tm1zgcczefr8p/VitaliyVstyle.github.io-master.zip/file |
LGS > 14-04-2023 19:15:07 |
doud пишет
Попробуйте код прописать в custom_script_win.js или custom_script_all_win.js. У меня старый UCF только на 78 фоксе, там проверил - работает. |
Farby > 15-04-2023 18:11:30 |
kokoss пишет
на данный момент это уже устарело, слишком много изменений была... |
kokoss > 15-04-2023 20:25:39 |
Farby пишет
Это последняя версия комплекта от автора, а что касаймо user_chrome_files, то там вроде незначительные изменения... |
_zt > 16-04-2023 15:03:05 |
Farby пишет
Farby пишет
Да вроде и стараться особо не надо. ) |
Farby > 16-04-2023 15:15:26 |
_zt пишет
ну наконец нашелся владелец русского языка, который исправит ошибки _zt пишет
больше не будет.... 16-04-2023 15:21:14 _zt пишет
программа максимум!!!!!!!!!!!!????????????????? 16-04-2023 15:22:51 Farby пишет
в который раз не редактировал................................................................ |
Farby > 16-04-2023 16:04:26 |
_zt пишет
а так нужно было..??? |
xrun1 > 16-04-2023 16:38:29 |
doud |
doud > 16-04-2023 16:47:46 |
xrun1 пишет
Не работает даже в новом UCF |
xrun1 > 16-04-2023 17:06:30 |
doud |
doud > 16-04-2023 17:25:43 |
xrun1 пишет
У меня этого файла нет. скрипт добавлялся в custom_script.js. config.js не менял. |
Inko7 > 16-04-2023 18:12:57 |
Dumby ЕСЛИ ТЕКУЩАЯ ВКЛАДКА ПУСТАЯ, ТО ОТКРЫВАТЬ ЗАКЛАДКИ (ПАПКИ) ПО СКМ В ТЕКУЩЕЙ ВКЛАДКЕ Выделить код Код:// ЕСЛИ ТЕКУЩАЯ ВКЛАДКА ПУСТАЯ, ТО ОТКРЫВАТЬ ЗАКЛАДКИ (ПАПКИ) ПО СКМ В ТЕКУЩЕЙ ВКЛАДКЕ // FindBar, листание результатов поиска колесиком мыши (Mouse Scroll find) try {({ init(tabpanels) { var dsp = e => this[e.type](e); addEventListener("click", dsp, true); tabpanels.addEventListener("wheel", dsp); addEventListener("unload", () => { removeEventListener("click", dsp, true); tabpanels.removeEventListener("wheel", dsp); }, {once: true}); }, e: {ctrlKey: true, shiftKey: true}, p: {triggeringPrincipal: document.nodePrincipal}, s: "menu.bookmark-item,toolbarbutton.bookmark-item[type=menu]", k: (k => k in PlacesUIUtils ? k : "_" + k)("openTabset"), click(e) { if ( e.button == 1 && isBlankPageURL(gBrowser.currentURI.spec) && !e.ctrlKey && !e.shiftKey && !e.altKey && e.target.matches(this.s) && !gBrowser.webProgress.isLoadingDocument ) { var trg = e.target, pn = trg._placesNode; if (!pn) return; e.stopPropagation(); var urls = PlacesUtils.getURLsForContainerNode(pn); PlacesUIUtils.openInTabClosesMenu && trg.tagName == "menu" && closeMenus(trg); if (urls.length && OpenInTabsUtils.confirmOpenInTabs(urls.length, window)) gBrowser.loadURI(urls.shift().uri, this.p), urls.length && PlacesUIUtils[this.k](urls, this.e, window); } }, wheel(e) { var findbar = gBrowser.selectedTab._findBar; findbar?.matches(":hover") && e.deltaY && findbar.onFindAgainCommand(e.deltaY < 0); } }).init(document.getElementById("tabbrowser-tabpanels"))} catch(ex) {Cu.reportError(ex);} тут два кода в одном, просто я их нормально разделить не могу в FF112 заметил некорректную работу: если при старте браузера открыта начальная (домашняя) страница или я нахожусь на ней при других открытых вкладках, то СКМ по папке вообще ничего не открывает. Но если вместо пустой вкладки активна вкладка уже с чем-то, то всё ок. Можно пофиксить? |
xrun1 > 16-04-2023 19:22:49 |
doud |
doud > 16-04-2023 19:36:51 |
Попробовал все версии, так и не заработало... |
LGS > 16-04-2023 19:43:37 |
doud, а в custom_script_win.js или custom_script_all_win.js..? |
xrun1 > 16-04-2023 19:48:09 |
doud |
doud > 16-04-2023 20:57:14 |
LGS пишет
Пробовал и туда и сюда... |
Dumby > 16-04-2023 22:27:30 |
Inko7 пишет
Снова это, надо полагать. |
doud > 17-04-2023 09:48:47 |
Уважаемые xrun1, kokoss и LGS! Спасибо за помощь! Методом тыка выяснилось, что скрипт работает только при установки browser.chrome.toolbar_tips в true! |
Inko7 > 17-04-2023 11:00:52 |
Dumby пишет
Вроде помогло, спасибо. Потом назад не нужно будет исправлять? |
kokoss > 17-04-2023 19:37:16 |
xrun1 пишет
Странно, у меня появляется без перемещения мышки. |
xrun1 > 18-04-2023 00:29:29 |
kokoss скрытый текст Вообще, чисто визуально, мне больше нравится javascript с моими правками "Hover Links (v2)" Выделить код Код:// ==UserScript== // @name Hover Links (v2) // @version 2023.04.17 // @namespace http://userscripts-mirror.org/scripts/show/30002 // @description A tooltip pops up when hovering over links. // @include * // ==/UserScript== // define const popTTDelay = 0; // было 300 amount of time(in ms) after mouseover before popup (0 for immediatly) var bg_color = "#ffffe0"; var border_color = "#ffd700"; var font_color = "#4682b4"; var font_face = "verdana"; var font_size = "10px"; // sorry, change slyles manually in function create_window :-) const offSBRRight = 18; // было 24 horizontal constant. if the popup makes horizontal scrollbars appear, increase this constant until it doesn't (default:18) const offSBRTop = 18; // было 24 vertical constant. if the popup makes vertical scrollbars appear, increase this constant until it doesn't (default:18) // variables var ttH, ttW; (function() { function locate(event) { var ttWin = find_window(); if (ttWin) { var tempLeft=(event.clientX + window.pageXOffset)+13; // было 9 var tempTop=(event.clientY + window.pageYOffset)+17; // было 10 if ((tempLeft+ttW) > (window.innerWidth+window.pageXOffset-offSBRRight)) { //if its too far right tempLeft= (window.innerWidth+window.pageXOffset-offSBRRight-ttW-10); } if((tempTop+ttH) > (window.innerHeight+window.pageYOffset-offSBRTop)) { //if its too far down tempTop-=(ttH+offSBRTop); } if (tempLeft < window.pageXOffset) { //if it is too far left, i.e. it is a super-wide box tempLeft=window.pageXOffset+1; //set it all the way to the left } ttWin.style.top = tempTop + "px"; ttWin.style.left = tempLeft + "px"; } } function find_window() { return document.getElementById("link_tt"); } function create_window(id, ttTitle) { var tt_err =''; var tt_div = document.createElement("div"); tt_div.setAttribute("id", "link_tt"); tt_div.setAttribute("style", "text-align: left; background: " + bg_color + "; border: 1px solid " + border_color + "; padding: 2px; color: " + font_color + "; font-family: " + font_face + "; font-size: " + font_size + "; position: absolute; z-index:1000000; " + 'padding-left: 8px; padding-right: 8px; padding-top: 3px; padding-bottom: 3px; ' + 'max-width: 35% !important; line-height: 1.2 !important; width: auto !important; ' + '-moz-border-radius: 0.7em !important;' ); try {var decodedUrl=decodeURIComponent(id.href); } catch (err) { tt_err += '<br><font style="font-size: 8px; color: grey;">' + ' bad url )' + '</font>'; decodedUrl=id.href; } // ?? :) var ttUrlHost = decodedUrl.split('/'); ttUrlHost = ttUrlHost[2]; // var favIco = ''; // изменил if (ttUrlHost) {favIco="<img style='display: none;' onLoad=this.style.display=''; src=http://"+ttUrlHost+"/favicon.ico> ";} // if (ttUrlHost) {favIco='';} // Закомментировал if, вроде, без иконки не нужно // else {ttUrlHost='';}{ttUrlHost='';} var dUrlLeng = decodedUrl.length; var urlPage = decodedUrl.slice(decodedUrl.indexOf(ttUrlHost) + ttUrlHost.length,decodedUrl.length); if (urlPage == '/') { urlPage = ''; } else { urlPage = '<br>' + urlPage; } if (ttTitle) { ttTitle = '<font style = "font-size: 13px; color: #8b0000;">' + ttTitle + '</font><br>'; } else { ttTitle = ''; } // изменил tt_div.innerHTML = ttTitle+favIco + tt_div.innerHTML = ttTitle + '<font style = "font-size: 12px; color: #007700;">' + ttUrlHost + '</font>' + urlPage + tt_err; // цвет добавил для домена document.body.appendChild(tt_div); ttH = tt_div.offsetHeight; ttW = tt_div.offsetWidth; // if (popTTDelay) // { find_window().style.display='none'; // window.setTimeout('show_windowTT()', popTTDelay); // } } function show_windowTT() { if (find_window()) { find_window().style.display = ''; } } function kill_window() { if (find_window()) find_window().parentNode.removeChild(find_window()); } function create_event(id) { if (id.title) { var ttTitle = id.title; id.addEventListener("mouseover", function() { create_window(id, ttTitle); }, false); id.title=''; // Прибивает всплывашку у ссылки на сайте и делает всплывашку заголовком } else {id.addEventListener("mouseover", function() { create_window(id); }, false); } id.addEventListener("mouseout", function() { kill_window(); }, false); id.addEventListener("click", function() { kill_window(); }, false); // добавил действие на клик, чтобы окно убивалось id.addEventListener("mousemove", function(event) { locate(event); }, true); } unsafeWindow.show_windowTT = show_windowTT; var link = document.getElementsByTagName("a"); var i; for (i = 0; i < link.length; i++) { create_event(link[i]); } })(); Скрипт ловит ссылки по тегу "a" и отлавливает не все, даже с тегом. И не работает на youtube. У Виталия ловится больше ссылок по matches. В скрипте надо менять var link = document.getElementsByTagName("a");, но пока не представляю как. Хотел попробовать скрестить (т.е. добавить цветное окно вместо просто "всплывашки" у ссылки в UcfTooltipUrlChild.jsm), но вообще не представляю, как добавить функцию окна и стиль в jsm-ку. Идеи есть, знаний не хватает. Вот и сижу со скриптом, а кнопка от Виталия на всякий случай. |
Dumby > 18-04-2023 12:08:42 |
egorsemenov06 пишет
Хмм, интересно, что там может не получиться? Посмотреть прямо полностью в работе, разумеется, не могу, судя по коду букмарклета, он создаёт и суёт на страницу в элемент <body> |
kokoss > 18-04-2023 12:39:15 |
xrun1 пишет
На чистом профиле только с этим скриптом без расширений также ? |
_zt > 18-04-2023 12:51:34 |
xrun1 |
xrun1 > 18-04-2023 13:35:43 |
kokoss |
kokoss > 18-04-2023 14:18:38 |
xrun1 пишет
Если не принципиально в jsm-ке, то можно в scrollbars_tooltips.css немного изменить стиль автора... тултипы Выделить код Код:/* Тултипы */ tooltip { -moz-appearance: none !important; appearance: none !important; } tooltip[hasbeenopened="true"] { color: InfoText !important; background: InfoBackground !important; border: 1px solid color-mix(in srgb, currentColor 20%, transparent) !important; padding: 2px !important; } @media (prefers-color-scheme: light), (-moz-toolbar-prefers-color-scheme: light) { tooltip[hasbeenopened="true"] { color: rgb(12, 12, 22) !important; background: rgb(245, 245, 255) !important; border: 1px solid rgb(204, 204, 214) !important; } } @media (prefers-color-scheme: dark), (-moz-toolbar-prefers-color-scheme: dark) { tooltip[hasbeenopened="true"] { color: rgb(0, 0, 0) !important; background-image: linear-gradient(#FFFFDB, yellow) !important; border-color: rgb(64, 64, 75) !important; border-radius: 1px !important; font-size: 15px !important; } } tooltip[hasbeenopened="true"] :is(description,label) { color: inherit !important; } |
xrun1 > 18-04-2023 17:30:05 |
kokoss |
kokoss > 18-04-2023 18:40:10 |
xrun1 пишет
Он из комплекта "full_theme". |
xrun1 > 18-04-2023 18:45:58 |
kokoss |
LGS > 19-04-2023 10:55:08 |
Dumby, имеется такой скрипт от немецких камрадов для версии 112, показывает количество закладок/папок (можно наоборот) в меню и кнопке избранного, здесь вариант для версий ниже 112. Можно на его основе что-то придумать, чтобы подобное работало в боковой панели..? |
_zt > 19-04-2023 12:19:01 |
Открытие "about:addons" по ПКМ на кнопке нового меню дополнений 111+ Выделить код Код:// Открытие "about:addons" по ПКМ на кнопке нового меню дополнений 111+ (this.openaboutaddonsthisfirefox = { async init(that) { await window.delayedStartupPromise; var btn = CustomizableUI.getWidget("unified-extensions-button")?.forWindow(window).node; if (!btn) return; btn.setAttribute("context", ""); btn.tooltipText = ` ЛКМ : Меню дополнений\n ПКМ : Менеджер\nCtrl+ПКМ : Отладка`; var listener = e => { if (e.button != 2) return; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); var gb = e.view.gBrowser; gb.selectedTab = gb.addTrustedTab(`about:${ e.ctrlKey ? "debugging#/runtime/this-firefox" :"addons" }`); }; btn.addEventListener("click", listener); that.unloadlisteners.push("openaboutaddonsthisfirefox"); this.destructor = () => { btn.removeEventListener("click", listener); }; } }).init(this); В scriptschrome >> load +стиль Выделить код Код:/* Настройка меню кнопки расширений 111+ * https://forum.mozilla-russia.org/viewtopic.php?pid=804620#p804620 ***/ #unified-extensions-view { /* background: transparent !important; /* прозрачность меню, если настроено глобально */ --uei-icon-size: 18px; /* значки */ } /* бейджи - ~ три символа, например, у uBlock 1000+ пишется как >1k */ #unified-extensions-view .toolbarbutton-badge { margin: -3px 0 0 0 !important; margin-inline-end: -4px !important; font-size: 10px !important; line-height: 14px !important; max-width: 4em !important; padding: 0 !important; } /* нижняя часть списка - дополнения без кнопок на панели - на выбор */ #unified-extensions-view .unified-extensions-list, /* целиком */ /*#unified-extensions-view .unified-extensions-list .unified-extensions-item:not([extension-id="например-полный-ID-@Imagus"],[extension-id^="например-начало-ID-select-after-closing"]), /* или с исключениями */ #unified-extensions-view .panel-header /* заголовок меню */ { display: none !important; } #unified-extensions-view toolbaritem, #unified-extensions-view unified-extensions-item { height: 29px !important; padding: 0 0 0 2px !important; /* margin: 0 4px 0 0 !important; /* если шестеренки скрыты */ } #unified-extensions-view toolbarbutton { height: 29px !important; padding: 0 0 0 4px !important; } #unified-extensions-view .unified-extensions-item { height: 30px !important; } #unified-extensions-view .unified-extensions-item-menu-button { /* display: none !important; /* скрыть шестеренки */ padding: 0 !important; margin: 0 4px 0 0 !important; } #unified-extensions-view .unified-extensions-item-name, #unified-extensions-view .unified-extensions-item-message { height: 1.2em !important; width: 15em !important; /* длина заголовка и сообщения */ padding-right: 0 !important; margin-right: 0 !important; padding-inline: 0 !important; margin-inline: 0 !important; } #unified-extensions-view .unified-extensions-item-message { /* display: none !important; /* скрыть сообщения */ font-size: 12px !important; } /* нижняя кнопка */ #unified-extensions-manage-extensions { background: rgba(50,50,50,0.5) !important; min-height: 28px !important; padding: 2px 8px 4px 8px !important; margin: -6px 0 0 0 !important; } #unified-extensions-manage-extensions:hover { background: rgba(70,70,70,0.8) !important; } #unified-extensions-manage-extensions label { margin-block: 0; margin-inline: 10px !important; } /* Изменить, убрать пункты контекстного меню */ menuitem.unified-extensions-context-menu-pin-to-toolbar[label="Закрепить на панели инструментов"] > .menu-iconic-text { display: none !important; } menuitem.unified-extensions-context-menu-pin-to-toolbar[label="Закрепить на панели инструментов"] > .menu-accel-container::before { content: "Закрепить на панели"; display: inline-block; -moz-box-flex: 1; } menuitem.unified-extensions-context-menu-report-extension { display: none !important; } Компактное меню новой кнопки "Расширения", скрывает - заголовок, дополнения без кнопок на панели (на выбор - целиком или со списком исключений), пункт контекстного меню "пожаловаться", сообщения (по желанию). И еще, по мелочи. |
_zt > 19-04-2023 15:59:21 |
Dumby скрытый текст Выделить код Код:// (async (name, id, func) => { if (name == "Object") return CustomizableUI.createWidget(func()); 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 = [ // ]; var secondary = [ // ]; return { label: "Quick toggle", id: "QuickToggleAboutConfigSettings", localized: false, image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFPSURBVDhPnVPNSsNAEJ5tamnBk+A7BMEcikohp/gi9i18nRafQoT00kK16tnn8CJo4vp9m5m41eSgH0zmd3d+diJ/gfdedvl0QW7k1PcLwem+3TjowZagK+Nn6yc3gNCJ+LCCh9LzzTMdqeoNbkQSFZmpJLGCW5Gx2hZaQahMbZ52VuDSfHpnAVJXOb4FKzianbzCXiLrHLYl5C3t5NTRwtxaKJxUTZ/JcOTr6q2Rxwf0aVb2/hLs4KqL3Isckz/mmSdRRksjyg+z7IM6LzDCBfuvAEOJmIKBOqAWmo1YodxLlQNsyO0rsIV/AZM+JGc2a4GgzhZ2p9mFmrpboCMqNYBDdMlwompoTWN6F2nFT5hBXb0PEpmo/Gk+oH+RrqNZINPeIlnZViV1jQuLFJQuWGB0gJdwgShvqdPXZv6J+F/QS7oXqQ9xBTFZ5oa8fAGs9fed5YhPSwAAAABJRU5ErkJggg==", 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/9hAAACRUlEQVR42qWTS2gTQRjH/zPJZo2BDfgkB62vYg5CjQdvRUE8WB8HKyahYotIQQOeFKGCF7EgvQlBqOCjWFKlevBRDyL4uHloLXhYqWJroaEqlETSptndGb+ZPDH0ojN8O8vA98vv+/Itw38u1nSRYRE6UhKyg4FF1R292/Q+xhhLi4TIrgjgIzwe4MbgmR2nrZMtxxEN63zYORuPZp7gzpehvCu9XjfuPmwCUHIiEtw4fK89zVvD2+FHAD56quXBpV3CVO4ret6nxHzxZxdBRuqADCKmz7RHD9y2tlmbYbBVfwE8DXBkEd/y39H5+mze8ZyoSIpsFXC9u/VE3/ldpyg5AAMEoJMTQi2hANKBgyKdy0h/eoChqcf9MimvVAHjd/fdiG0NRwgQpDAp1agBpDZwdHKJLKZzc+h5e3kCSexh5c5j8fmhW0HGpNZXFkqfsQpAKgcFKGmAlAxHXp5bkkmsrhosjh4cCIJ5pG5qfQXgtMslqO1qgEMWTPrR+eriEhoA4wN7L8TWh0KVXzfgY2RQAUjVBenWLH4UCrj04Wa9BNXEo5va+w63xCiJ6WRVP2MVgNQIgjgEA17MTODZ7Lt+AtSaGDG4377a1m2FAkKrc11/dUwIID1dSKHEcW3yft4RbpR6kK1PYgaJtaY1nNp5jIeMsjKNbs1AWRUcjvTnp2Kh9LtLJGTDINUhcTIZ3L+hzdq9ZgvWmSF9/Wu5gI8L03gzP5l3hddL/3/zKDdA9MdE0UERrdzaFGMUaap75Y/pX9Yfap76EQYaCeEAAAAASUVORK5CYII=", notUserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACNUlEQVR42qXTT2jTUBwH8G9e0ta2ks5ND0Ww/qX1oGyevEwQnOBA6EHXwLwoUh3eRGRs501RPE6xgp6KrexQECZY8DBPXmbRS4Z/K0gRtmmDa2yb5PlLX7p2Gwpi4EfCy8sn3/dPwn9e0saGnCRF6XYFnA9DkhKtRs51ep6jmtEcp/JHIM9Yivl9mf0XNDV2Ngn1YLzVxdB1lJ8U8P5hzuCWnR6xrPwmIM8kLRjdkT326BaLHNgLKAFA9ouXdhOw6qi++4j589cd89vSaMqyc2sAPUXlgF8fyt9WI3t2Av4w4NsCMJ8AHAKav6hqqH76iuLINcNuNhOawyttYCp+7tRE/6XT9GFQAG4CpniATQkIaNQIMVG6/xSL2WfTGueTbWDh5L2rA9t29QGBrQQEPUDuAuoEmFSr+P5lGc8v33mtAUfaQO3M4/GgDOoYCIkUin8D0BDDoBQ2ZMxqN0wCQh0gMxaUnYb4uzt+dwIZ8wBHTGQbYAHMpu+uAxaGxpMDvSr3AHcFaAIlD+BtoN6ag5WqhOLNwrohTMWPH5roP7pdLIwb3wW6EziWGAZhpVdLWHzxdpqAyc4yKrJ+4uKg2oMV+lgRK9CdwAVsG1WpF8UH84Zt2QkCKmsbiRAtFAllB5OHWQ9fpr81OwlcgBL9kPrwsvDGMQ1zNMV5ZyN1ISlZYZl9/TE1tjuMSFgA1VWO8uef+FAqG47tpFMcm7dyFyIOEzBMlfCadao5qhk39l9P479evwFbiOcRSXKueAAAAABJRU5ErkJggg==", UserAltImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIfSURBVDhPpVM9b9NQFD02cSKKFVGKIFFREFsmFiCA1AEQQrQjC0gssLCkC0jJj0iFWFoGdiT4Ay0SEmJBhPI5FBokikL4SCC0Te2UxInt13Mdu1CVrVc6713fe86x/T6w09DCeTNKJ7Q0pzyUmoCmZYOiUhXms8RMcd6vB7UwthhM5fTLWix2L3PmYjKdOwdz9DDFGtr1KuovnqD29JGlfO9Goew9DCV/DaZy2pXE8PD9Y/mbupk6xE6cVWPQhEujHo2+4fXdO76ztnq1UPYfSCcwKB1HWjeMyunCraSZOsDqbkBPsBOTNoMGvkOTLto/f+F56bble262OK/qesiYzIydTJojFLjrgEe4bcIOEdXWYe6LITN2KgmFSRFGBuPpo0eAngX0SexTJHD5LOgLpEZTcgKuUuMijAyy5l7+r0NSb21g5LQI5gGYSy2AjYBLjQyRAUniTnJXsBoayBzm3RBBndwwIoOK3fgNdIREQYCV/0DqLdiNZqCRITKYayx85RfQuUNiZ3k7IgO+vfGeXGpkiAyma++WLHtZhZ8o5H/FEVpos1V7u8TFwLQId8nw+Afa51Oq2vyycmlk9KCW0GXFZeu63IUO8z88Bx5s28SbuUXfddzrxVcobxpI0GTh7H734/dPzQt9d0/CGBpCPB7nbhmwbAPVxR4+PPtsuU7/WuElth/lKORUcsoTE8TgMg0WbJaY4Zu3XKYdBrABARUk+ls4DfQAAAAASUVORK5CYII=", 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.BrowserReloadSkipCache() : win.BrowserReload(); } }, maybeClosePopup(e, trg) { !e.ctrlKey && prefs.getBoolPref(this.closePref, undefined) && trg.parentNode.hidePopup(); }, command(e) { var trg = e.target; if (trg.btn) return 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); } }; }); xrun1 А туда то я не заглянул. ) Спасибо. |
xrun1 > 19-04-2023 18:50:16 |
_zt пишет
Работает с правкой в Firefox 111+, поломали Ctrl+Shift+C копирование с тултипа |
Dumby > 20-04-2023 10:10:05 |
LGS пишет
???
Смотря что считать за «на основе». Но можно попробовать сочинить что-нибудь подобное. скрытый текст Выделить код Код://... scriptsallchrome: { // Для докум. всех окон [ChromeOnly] domload: [ // По событию "DOMContentLoaded" // ... { path: "places_sidebar_folders_statistics.js", urlregxp: /chrome:\/\/browser\/content\/places\/(bookmarks|history)Sidebar.xhtml/ }, ], и places_sidebar_folders_statistics.js скрытый текст Выделить код Код:(async () => { var addFolderStats = node => { var title = PlacesUIUtils.getBestTitle(node, true); if (PlacesUtils.nodeIsContainer(node)) { var wasClosed = !node.containerOpen; if (wasClosed) node.containerOpen = true; var urls = 0, containers = 0; for(var ind = 0, max = node.childCount; ind < max; ind++) { var child = node.getChild(ind); if (PlacesUtils.nodeIsURI(child)) urls++; else if (PlacesUtils.nodeIsContainer(child)) containers++; } if (wasClosed) node.containerOpen = false; title += ` (${urls}/${containers})`; } return title; } var proto = PlacesTreeView.prototype; Object.assign(proto, eval(`({getCellText: ${proto.getCellText}})`.replace( "PlacesUIUtils.getBestTitle(node, true)", "addFolderStats(node)" ))); })(); _zt пишет
Да, вижу, это довольно странно. скрытый текст Выделить код Код:..... //if (trg.btn) return this.openPopup(trg.primaryPopup); if (trg.btn) return trg.secondaryPopup.state == "closed" && this.openPopup(trg.primaryPopup); |
xrun1 > 20-04-2023 11:17:30 |
Dumby пишет
Спасибо, очень важная кнопочка. |
LGS > 20-04-2023 11:23:06 |
Dumby пишет
Так еще со школы помню (хоть и давно это было) стараться избегать повтора слов в предложении и применять, по-возможности, синонимы. Вот я и применил). То, что "избранное" будет понято правильно, я как-то не сомневался. Dumby пишет
Отлично, спасибо! |
xrun1 > 20-04-2023 11:56:33 |
_zt |
kokoss > 20-04-2023 14:43:41 |
Dumby пишет
У меня если дополнительная панель скрыта, то блокирует всплывающее окно для установки расширения с АМО. В чём может быть причина ? |
_zt > 20-04-2023 15:44:27 |
Dumby |
Dumby > 20-04-2023 22:30:41 |
kokoss пишет
Понятия не имею. Можно попробовать, на такой случай, скрытый текст Выделить код Код:(async id => { var anchor = "notification-popup-box"; // urlbar //var anchor = "PanelUI-menu-button"; // hamburger var btn = document.getElementById(id); var orig = gUnifiedExtensions.getPopupAnchorID; var custom = eval(`(function ${orig})`.replace(id, anchor)); gUnifiedExtensions.getPopupAnchorID = (...args) => (btn.matches("toolbar[collapsed=true] :scope") ? custom : orig)(...args); })("unified-extensions-button"); _zt пишет
Может здесь посмотри (в самом конце сообщения).
Ну да, nsINavBookmarkObserver — всё, удалили. скрытый текст Выделить код Код:(async (id, sel) => { var g = Cu.getGlobalForObject(Cu), stt = g[id]; if (!stt) { var {obs, prefs} = Services, {bookmarks: bm, observers: pobs} = PlacesUtils; stt = g[id] = { bm, pref: `ucf.${id}Guid`, async init() { this.args = [b => this.bguids.add(b.parentGuid), {concurrent: true}]; this.pobsArgs = [ ["bookmark-added", "bookmark-moved"], this.record = this.record.bind(this) ]; pobs.addListener(...this.pobsArgs); obs.addObserver(this, "quit-application-granted"); var guid = prefs.getCharPref(this.pref, ""); if (!guid) try {var [guid] = await PlacesUtils.metadata.get( PlacesUIUtils.LAST_USED_FOLDERS_META_KEY, [] )} catch {} this.guids.push(guid || await PlacesUIUtils.defaultParentGuid || bm.unfiledGuid); }, observe() { pobs.removeListener(...this.pobsArgs); obs.removeObserver(this, "quit-application-granted"); prefs.setCharPref(this.pref, this.guids[0]); }, record(events) { for(var e of events) if ( e.itemType == bm.TYPE_BOOKMARK && e.source == bm.SOURCES.DEFAULT && !(e.type == "bookmark-moved" && e.parentGuid == e.oldParentGuid) ) this.guids[0] = e.parentGuid; }, bguids: new g.Set(), guids: new g.Array(), fetch(win) { this.bguids.clear(); return bm.fetch({url: win.gBrowser.currentURI.spec}, ...this.args); }, tt(de) { var kids = InspectorUtils.getChildrenForNode; return (this.tt = kids.length == 2 ? de => { var list = kids(de, true); return list.item(list.length - 1); } : de => kids(de, true, false).at(-1) )(de); } }; stt.init(); var func = id => this[id].handleEvent = async function(e) { var win = e.view; var star = e.target; star.tooltipText = "\u3164"; var starred = star.hasAttribute("starred"); starred && await this.fetch(win); var result = []; for(var guid of (starred ? this.bguids : this.guids)) { var arr = [], num = 50; while(--num) { if (!star.matches(":hover")) return; var res = await this.bm.fetch(guid); if (!res) break; if ((guid = res.parentGuid) == this.bm.rootGuid) { arr.unshift(this.bm.getLocalizedTitle(res)); break; } arr.unshift(res.title || "[Безымянная папка]"); } arr.length && result.push(arr.join("\\")); } if (!star.matches(":hover")) return; if (!result.length) return win.document.l10n.translateElements([star]); var text = result.join("\n"); if (starred) { var m = result.length > 1; text = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${text}`; } star.defaultTT.state == "open" ? star.defaultTT.label = text : star.tooltipText = text; } var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})("${id}")`); g.ChromeUtils.compileScript(url).then(ps => ps.executeInGlobal(g)); } await delayedStartupPromise; var tt = stt.tt(document.documentElement); var stars = Array.from(document.querySelectorAll(sel)); for(var star of stars) star.defaultTT = tt, star.addEventListener("mouseenter", stt); var destructor = () => { for(var star of stars) star.removeEventListener("mouseenter", stt); } var ucf = window.ucf_custom_script_win; if (ucf) ucf[id] = {destructor}, ucf.unloadlisteners.push(id); else window.addEventListener("unload", destructor, {once: true}); })("ucfBookmarksStarFTooltipHelper", "#star-button, #context-bookmarkpage");
У, это надо чистую сборку собирать с чистым UCF, |
kokoss > 20-04-2023 22:48:43 |
Dumby пишет
Спасибо, теперь ОК! Dumby пишет
Использую дополнительную панель из UCF |
Dumby > 20-04-2023 23:26:00 |
_zt скриншот Выделить код Код:data:image/png;base64,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 |
xrun1 > 21-04-2023 02:52:18 |
Dumby
Поискал у себя в кнопках текст nsINavBookmarkObserver, нашёл одну. Если правильно понял, это аналог кнопки из-под цитаты выше. tooltip скриншот Выделить код Код:data:image/png;charset=utf-8;base64,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 Или подскажите, куда эту новую вместо моей вставлять. Старая работает так, новая нет. скрытый текст Выделить код Код:scriptschrome: { // Для докум. окна браузера [ChromeOnly] domload: [ // По событию "DOMContentLoaded" ], load: [ // По событию "load" // { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar { path: "cs_win/bookmark-added.js", ucfobj: false, }, // для звёздочки показывать папку https://forum.mozilla-russia.org/viewtopic.php?pid=790890#p790890 Или это вообще не о том... |
Dumby > 21-04-2023 06:03:13 |
xrun1 пишет
Это потому, что соответствующий стафф находится
Да, мой косяк. Но, это версия без заголовка в тултипе, Если заголовок желателен, то дай знать, может попробую добавить. |
_zt > 21-04-2023 10:24:41 |
Dumby Выделить код Код:// Убираем строку перед адресом закладки // text = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${text}`; text = `${text}`; |
Dumby > 21-04-2023 15:04:49 |
_zt пишет
Bug 1820743 - Allow to move unified extensions button on the navbar
Как видно из бага, случилось уже в 113. |
xrun1 > 21-04-2023 15:10:30 |
Dumby пишет
Что уж тебя по пустякам мучить. С заголовком симпатичнее, сделал вручную. скрытый текст Выделить код Код:text = `Редактировать эту закладку (Ctrl+D)\n\nАдрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${text}`; } else text = "Добавить страницу в закладки (Ctrl+D)\n\nНедавняя папка:\n" + text; |
_zt > 22-04-2023 16:02:25 |
Dumby скрытый текст Выделить код Код:// Сохранить страницу как PDF, скриптом ............. function savePageToPDF() { var ps = Ci.nsIPrintSettings, cfg = { paperWidth: 8.5, paperHeight: 11, paperSizeUnit: ps.kPaperSizeInches, // kPaperSizeMillimeters marginLeft: .2, marginRight: .2, marginTop: .2, marginBottom: .2, edgeLeft: .1, edgeRight: .1, edgeTop: 0, edgeBottom: 0, headerStrLeft: "&T", headerStrCenter: "", headerStrRight: "&U", footerStrLeft: "&PT", footerStrCenter: "", footerStrRight: "&D", printBGColors: true, printBGImages: false, scaling: 1, shrinkToFit: true, // overrides scaling orientation: ps.kPortraitOrientation, // kLandscapeOrientation printerName: "", printSilent: true, printToFile: true, showPrintProgress: false, isInitializedFromPrefs: false, isInitializedFromPrinter: false, outputFormat: ps.kOutputFormatPDF, outputDestination: ps.kOutputDestinationFile, }; ps = Cc["@mozilla.org/gfx/printsettings-service;1"] .getService(Ci.nsIPrintSettingsService).newPrintSettings; for(var key in cfg) if (key in ps) ps[key] = cfg[key]; (savePageToPDF = async () => { try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); await IOUtils.makeDirectory(file.path); } catch { file = Services.dirsvc.get("Desk", Ci.nsIFile); } file.append(`Snap ${new Date().toLocaleString("mn").replace(/:/g, "\ua789")}.pdf`); ps.toFileName = file.path; await gBrowser.selectedBrowser.browsingContext.print(ps); //file.launch(); })(); }; |
LGS > 22-04-2023 16:32:23 |
Dumby, можно попросить сочинить или поправить текущий еще и для библиотеки..? скрытый текст Выделить код Код:scriptsallchrome: { // Для докум. всех окон [ChromeOnly] domload: [ // По событию "DOMContentLoaded" { path: "custom_js_win/places_sidebar_folders_statistics.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/ }, - счетчик появляется, но не цепляет закладки/историю и папки отображаются без названия: |
Dumby > 22-04-2023 17:37:23 |
_zt пишет
Хмм, судя по этому багу, в таком виде, скрытый текст Выделить код Код:/* .getService(Ci.nsIPrintSettingsService).newPrintSettings; */ .getService(Ci.nsIPrintSettingsService).createNewPrintSettings(); LGS пишет
Может так скрытый текст Выделить код Код:/* var wasClosed = !node.containerOpen; */ var wasClosed = !node.QueryInterface(Ci.nsINavHistoryContainerResultNode).containerOpen; |
LGS > 22-04-2023 18:35:51 |
Dumby пишет
Почти идеально, единственное в "Журнале" в левой колонке (поле) количество url-ов не показывается, а в правом поле их число отображается: |
_zt > 23-04-2023 00:25:57 |
Dumby пишет
Ну да, не работает. Не приходилось пользоваться, видимо. Другие варианты компактнее и удобнее, если печать не нужна, а она редко нужна. На 112 просто системно перепроверяю все. |
LGS > 23-04-2023 13:45:45 |
_zt пишет
С правкой Dumby заработал, но у меня сохраняет без запроса и на рабочий стол. Как директорию для сохранения pdf-ок поменять не знаете..? |
_zt > 23-04-2023 14:19:38 |
LGS Т.е browser.download.dir должен быть назначен, иначе (по умолчанию) его нет, а следовательно и сохранять будет, наверное, в зависимости от параметра browser.download.folderList - 0=desktop, 1=downloads (default), 2=last used. |
Dumby > 23-04-2023 14:22:19 |
LGS пишет
В левой колонке вообще нигде количество url-ов не показывается. А ещё, наткнулся на такой феномен: если навести мышь Видимо, из-за открытия контейнера, образуется некая инвалидация, Вобщем, такой вариант скрытый текст Выделить код Код:(async (CRN, QRN) => { var addFolderStats = node => { var title = PlacesUIUtils.getBestTitle(node, true); if (PlacesUtils.nodeIsContainer(node)) { node.QueryInterface(CRN).QueryInterface(QRN); if (node.queryOptions.excludeItems) { var opts = node.queryOptions.clone(); opts.excludeItems = false; } if (opts || !node.containerOpen) { node = PlacesUtils.history .executeQuery(node.query, opts || node.queryOptions).root; node.containerOpen = true; } var urls = 0, containers = 0; for(var ind = 0, max = node.childCount; ind < max; ind++) { var child = node.getChild(ind); if (PlacesUtils.nodeIsURI(child)) urls++; else if (PlacesUtils.nodeIsContainer(child)) containers++; } title += ` (${containers}/${urls})`; } return title; } var proto = PlacesTreeView.prototype; Object.assign(proto, eval(`({getCellText: ${proto.getCellText}})`.replace( "PlacesUIUtils.getBestTitle(node, true)", "addFolderStats(node)" ))); })(Ci.nsINavHistoryContainerResultNode, Ci.nsINavHistoryQueryResultNode); |
LGS > 23-04-2023 16:23:52 |
Dumby пишет
У себя такого эффекта не наблюдаю, проверил для чистоты эксперимента на версиях 112, 102, 91 и 78. Везде ровно, без признаков отжора. Наверное, от железа и настроек каких-нибудь зависит, я в about:config редко лазаю, и user.js не пользуюсь, если что и наворочено, то по-минимуму. _zt пишет
Не реагирует ни на какие значения, как кидал на рабочий стол, так и кидает. _zt пишет
А какой синтаксис будет правильный: browser.download.dir=, или как? |
_zt > 23-04-2023 17:38:24 |
LGS
А я наблюдаю по CPU, у меня виджет на панель задач выведен, а вот по памяти было ровно. Теперь все нормально, если не считать того, что в библиотеку не подключается, но там уже работает пара скриптов, так что скорее всего конфликт. |
LGS > 23-04-2023 17:55:57 |
_zt _zt пишет
Вообщем, как ни крути - все равно результата нет, решил пока встроенной сохранялкой в PDF пользоваться, которая через "Печать" вызывается, Могу ошибаться, но по-моему вы как раз и обсуждали с Dumby этот вариант: скрытый текст Выделить код Код:if (typeof window.saveImageURL != "function") var saveImageURL = internalSave.length == 15 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, a7, a5, null, priv, prin); скрытый текст Выделить код Код:{ label: "Печать / печать в PDF", func: document.getElementById(document.getElementById("appMenu-viewCache").content.querySelector("[key=printKb]").getAttribute("command")).getAttribute("oncommand"), image: "chrome://global/skin/icons/print.svg"}, { label: "Сохранить страницу / выбор как HTML", func: "savePageToHTML()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzElEQVQ4jV2STW8bZRDHf/Psrr11nZhgVKcKaSmUiArRKBRVIMgH4BKJ7xAp5MSFiA+Rc28ckBAoipC4koJQLyAaVFChIlQllDRWmjRev8Qvu14/+wwHx6ZlpNFcZn7zn79GVJW1tbXc6urqijHGqKoAPF3TgcVaq8owXJbphx99fOOnWzcHoqqsr68/t7y83BARVBXnHHraXo3a3HoUU8gFAHRTS2Bg/7C2Zx7vXPIBwjA0p3BU9Zns9i3vvVrhr6MWzlpee+EsRqAbHc3+/Pee7wPkcrkx4P+g0IMvb/5Iv5/iXEaWZQS+By578MaVy9YH8H3fE5FnANZajqMmgcAnH7yN73mICMYMd21sbLy7srKiPkA+n3/qBLhzv8p+EuOfTUjShPbODvOVWa5fnRsvKBaLAcAIMFbw+bc/EBVn8At7SPcQ60LSiVm++P0fGu0e7y++yalvHoABCILAiAj7hzU+vfcVT6zPVGmR3x4/xJoLSH6BVu4cN777nnQwQETI5XL/AYwxRkS4ff8BEk6Q2pBfq3dxUuHMmWt0kgFGStTDY/7YrTLybQwYPU2cpgzsCd1OgmSzWHeOR7VjWicxaT9lxn+HfjoYmWnGHgAiIsydf5HKnUXiThehQDG4Tr3e5KR7hN8XilnGKxfOoyrDgZECwIgIb125xIxxTGVdgjRG4pR2+zbG/sIkD7l2cYJyaYLMOZxzjBV4nueLCI1GnaWFab65t4OXt4gUuFqYJ8gGuPYBCxdLHNciys9PkaapjAHGGM8YQ7lcZv71OaYmC/xZPaJHTN4cUgpDXrr8MtOVaUqTRXzfY3t7u7O0tDR82a2trfkkSTSOY+31etrpdLTZbGoURRpFkdbrTY3qTW00mhrHse7u7t4tl8uhqg4VxHHcPDg4+ExVHeBU1YmIU1WnisucZtamLszn01ar9WRzc/PrWq2WAPwLJ7l2ULfXOAMAAAAASUVORK5CYII="}, Там и диалог сохранения имеется, и качество на выходе неплохое... |
_zt > 23-04-2023 17:59:10 |
LGS |
LGS > 23-04-2023 19:20:52 |
_zt пишет
Оказывается, дело было в том, что у меня папка "Загрузки" находится не на С: , а перенесена на другой диск-помойку. Если выбрать любую другую папку, то пожалуйста - сохраняет в указанную. |
LGS > 23-04-2023 19:50:55 |
Вернул, ради проверки, путь для сохранения "Загрузки" (у меня там путь: "F:\Windows 7\Documents\Downloads") - скрипт начал отрабатывать как положено, грузить в "Загрузки". |
_zt > 23-04-2023 22:28:49 |
LGS |
LGS > 28-04-2023 08:24:50 |
Dumby, посмотрите, пожалуйста, эту кнопку, последняя функция внизу "Общее количество закладок". Не работает в 112, консоль пишет: |
Farby > 28-04-2023 09:27:47 |
LGS пишет
Dumby про это писал здесь |
unter_officer > 28-04-2023 12:19:09 |
LGS Выделить код Код:var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService); На: Пока работает. |
LGS > 28-04-2023 12:37:01 |
unter_officer пишет
Спасибо, работает. |
LGS > 05-05-2023 18:38:16 |
Dumby, можно придумать скрипт, чтобы показывал версию отключенных расширений на странице about:addons..? Стиль от Aris. Посмотрел скрипты ("Дополнения", extensionOptionsMenu) - они у себя версию у отключенных дополнений отображают. Может, для about:addons что-то получится сделать..? |
xrun1 > 05-05-2023 18:59:48 |
LGS |
LGS > 05-05-2023 19:18:21 |
xrun1 пишет
Я про кнопки упоминал в посте в скобках... Хотелка именно именно для about:addons. |
Dumby > 05-05-2023 23:04:41 |
LGS пишет
Скорее интереснее, куда она девается.
Ой, сейчас немного неохота, и некогда. |
LGS > 06-05-2023 15:21:05 |
Dumby пишет
Только этот: скрытый текст Выделить код Код:(async (css, self) => ({ //===[ Buttons ]=================================================================== vertical: true, btnActions: ["preferences", "toggle-disabled", "remove", "install-update"], cn: "ucf-cloned-button", update(e) { var trg = e.target; trg.nodeName == "ADDON-CARD" && trg.addon.type != "theme" && this.onCard(trg); }, onCard(card, again) { var btnsParent = card.querySelector("addon-options"); if (!btnsParent) return again || card.ownerGlobal .requestAnimationFrame(() => this.onCard(card, true)); var doc = card.ownerDocument; var [span] = card.getElementsByClassName(this.ccn); if (span) span.textContent = ""; else card.querySelector("button.more-options-button") .before(span = doc.createElement("span")), span.className = this.ccn; var item, num = 0; for(var sel of this.btnActions) { if (num++ == this.tInd) { if (!card.querySelector(this.ts)) continue; item = this.createPanelItem(doc); item.setAttribute("action", "toggle-disabled"); doc.l10n.setAttributes(item, `${ btnsParent.parentNode.getAttribute("active") == "true" ? "dis" : "en" }able-addon-button`); } else { item = btnsParent.querySelector(sel); if (!item) continue; item = this.clone(item); } span.append(item); item.shadowRoot.querySelector("button").classList.add(this.cn); } }, //===[ Popup ]===================================================================== items: { "Копировать имя": [ addon => self.copy(addon.name), "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByUlEQVQ4jY2TTUhUURiGn5tD0Sp00iAwXM1iFu4kWkUZg/9MoZQhdoUCV7ooItq4atFORRGkuLMwoc0kNBGKDLSwFpEIQgspqGUUNsjI3HvPX4s7I3Nn7oW+1fn5vvd8z3vOsYiIgXuPneFMr21ZVmh9+m7GisoPxcTsM2d46on5c1gy9bHgvDVR+afqJzNzy870xIgNUJGGkqf4XVEAuJ4XeWCiNpibX3MGr/XYPd0pADxlOK0MQgf7Xw++sfJq0zRiJQAWcgWndHRkr28UWcrlAfCVwa8KrK4XOPxbYqz/MsnWcyfFi7lCIPD9x0/70YNRykKz+eELQkny74sIJbnQmqQ71UVhe+cES2hoP9uC63mBgO/7dF7s4NexZPRmBqlBaMPHnc+kL7UTh1VxqwKuGxjkaUP+zRZCSVqwKJeP2dvdj8SqGZuod9hXhr6hGwgNL5ZfEoc1PnaL2sFNAlvvthFKxmJJbfCUqXbghhHSyTOkJwcBmHr4vAnLVwKhJEPZbLgDXwh678yG7rfjfLIJS2qD0IEP9R6kiq8XrzS+sOz9p5+asKodXB0YCQkcNBbHYUXlxP6u67dnIj9PY8QJpIC2/6iX/wDxeTOAfNDrywAAAABJRU5ErkJggg==", ], "Копировать ID": [ addon => self.copy(addon.id), "Копировать имя" ], "Копировать версию": [ addon => self.copy(addon.version), "Копировать имя", addon => !addon.version ], "Копировать имя и версию": [ addon => self.copy(addon.name + " " + addon.version), "Копировать имя", addon => !addon.version ], "Копировать URL кнопки": [ (addon, win) => { var btn = Object.assign({ parameters: {}, get initcode() {return this.initCode;}, setText(doc, name, t, cds) { win.custombutton.buttonSetText(doc, name, this[name], cds); } }, win.custombuttons.cbService.getButtonParameters(addon.buttonLink)); self.copy(win.custombutton.buttonGetURI(btn)); }, "Копировать имя", addon => addon.type != "custombuttons" ], "Домашняя страница": [ (addon, win) => win.openURL(addon.homepageURL || addon.reviewURL.replace(/\/reviews\/.*$/, "/")), "data:image/png;base64,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", addon => !addon.homepageURL && !addon.reviewURL ], "Поиск на АМО": [ (addon, win) => win.openURL( addon.homepageURL || ("https://addons.mozilla.org/search/?q=" + encodeURIComponent(addon.name)) ), "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJGSURBVDjLjdJLSNRBHMDx78yqLZaKS75DPdgDDaFDbdJmde5QlhCJGxgpRJfqEEKnIsJLB7skQYQKZaSmdLaopPCgEvSCShCMzR5a7oq7/3l12RVtjfzBMA/4fWZ+MyOccwBM3g8HEbIdfCEhfAFnLVapOa28Uevpjrqz/WOsERJgsu9Uq5CZQzgqrJfo9BajNd5irEYn4p3OUiFExtCLmw2tawFi4l5zUMjMIau9u7K+qxeoAcoAA0wDb2OPwmfA16LiiaOHLj1edRLpkO3WmIis7+oBDgJbgQ2AH6gC6jY19N62RkcctKeVIJAhp9QgUA3kJXdONZVcq9JxPSgQoXRAyIDRth8oAXQyKdWnoCKrTD9CBv4GMqx1WGNZkeRWJKbG2hiD1Cb9FbTnzWFdY/LCdLKlgNQ84gyNKqHm0gDjqVHnxDHgA/B9RQkpaB6YklkZl62np9KBhOqwjpKFgeY2YAz4BESBWHI8Hhs6PVVSvc3v98ye4fP7T676B845nt040ip98qpWJmI9PWiU6bfWgXGN2YHcKwU7tsuc4kpUPMbU0+f8+vKt+Pitl7PLAMDI9cNBoB0hQwICzjqUp6MZvsy8yvp95BRuQUjJ75mPvH4wYo1NlJ64Mza7DPwrhi8cCOeXl/aUB4P4c/NJxKLMvpngycCrzxVFG2v/CwAMnguF80oLe8p27cQh+fnpPV/fTc95S6piXQDAw7a9YbWkezZXFbAwMx/xPFXb1D3+Y90AQF/L7kAsri9mZ4lrTd0TcYA/Kakr+x2JSPUAAAAASUVORK5CYII=", ["custombuttons", "theme", "plugin"] ], "Папка установки": [ addon => self.getFile(addon).reveal(), "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABAklEQVR42mNkoBAwAjEXEAcCMTsW+U9AvB6I/+I0gJ2Noe3QJoZKASEgjwkq+h+C795lYPCKZMgC8mZg0fsfbICIIMOcF6cZkrGZ/v8fA0PndIa/7z8BXfAPqgVKv//A8GPeZoYERmE+hjmP1+AwAOgiTjOIP7HZLyjLMJNRmB/ogjMMyYzsUC8wIhQwsgCFWHAHoKAy0AARIYY5r69idwEhIKgBMgAYBq8vkGmALsyAU2QaYAwz4CiZBliADBAAGnCATANsYQbsJtMAJ5ABwGh8uZE8A4R9gAYwMzHkT8hl6Bfgxp5ecIH3Xxj+F05hyIdpUmXAnpnwge9AfJckW7EBAC/gSzisxsnmAAAAAElFTkSuQmCC", ["custombuttons", "theme", "plugin"] ], "Файл установки": [ addon => self.getFile(addon).launch(), "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA51AAAOdQG5Y1EyAAAAhklEQVQ4y6WT0QnAIAxE78Bt2v1cod3PznP9kVLTRKUGBD+Sd5eQUBJWggCWCAkAJPGXOqlUPyVKkrSPQIoCQJGE6AF4HFyGuBmrR3cGQX8Wmp2cL8Cqv5JPD5Zm1D0nFZjTjHpQ7DuI1L3iBjBS9/pvhtjr21OukVkXiX/ug6SWj4mr53wDMz1vldHlLJkAAAAASUVORK5CYII=", ["custombuttons", "theme", "plugin"] ], "Проверить обновления": [ Cr.NS_ERROR_NET_TIMEOUT_EXTERNAL // Fx 87+ ? (addon, win) => win.content.checkForUpdate(addon) : (addon, win) => win.content.frames[0].checkForUpdate(addon), "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAACVUlEQVQ4jXWT30vTYRTGP3Mb+ZbiXmm6DGUO0pkQGQR2URBdKZWWIHRlFHYhXnQRdVUEBUn/gBddFZERaalUoAUhYUglVIjO5TKbjMDtq2vDQ9t8u0jnr3Xgvfuch/M87zk2rTX/K+u05QROUMBVlrmkn+lvWxlHzsbjVj4uzlHFFec15/7UYCrFU6xcrF0ptbn5jNVADS9o47yvxed24yZRnchLz6dbpUSUlMhHNavSa3zeNskMIZzYOQChPyGmolNIXGz+Tn/lvu59d6jhtdVkZX1vm0AFVFSKpZfPNHKQ3SSBPsxCfMEWi8Rwtbkq5L3UqnH1OCtgNVleqRaf+MUjXrH0Sx2TUuklQAt+XPRykyAzFHNIfgkUUyV58k4FVOifhVLe0sUnGhknnyoAPaAjzHGUbkYxjOlHup0R7iPATqCI9vUMHHhwAR7SGCJrdnS/DjPOMd2nhwD4zS2CZEgCBRxZF8gQJgrkYwcqNmaiJ3QGMADMMMsyMeyAE/e6QII3TEP54XIbhXSufqfXarEebEwcH7swFBIDUqSyIYpPFrFzIV4ZhwLqBDGskOE6XUxwUsqkRwWVyF6xscw0P3lOgodqSgXRWqO1tnGZVwxiiGAYw3CbpWbTbDpMh+EGH2jDvcpuetk9EK8ME6UBQwkOoJUdc445RodHqb9YXxaeDJ8StwyogIrnXGUVUEkplx7mKWKJWn7gTH1PwQqEv4bBQRHzLKlJNbJRwJbrGq2zlps9fKEOD5MIEZ6Q5K7u1xNb2ZzXiEFYxDBEF8I9PaBDOTngLwkg8PzzO00cAAAAAElFTkSuQmCC", addon => !addon.applyBackgroundUpdates || addon.isBuiltin ], }, listContainerId: "ucf-aa-extra-items-container", showing(e) { var card = e.target.closest("addon-card"); if (!card) return; this.labs = []; var imgs = new Map(); var set = (key, val) => imgs.set(key, imgs.has(key) ? imgs.get(key).concat(val) : [val]); var entries = Object.entries(this.items); entries.forEach(([lab, [func, img, hideOn]], ind) => { this.labs.push(lab); (this[lab] = func).hideOn = hideOn; img && set(this.items[img]?.[1] ? entries.findIndex(a => a[0] == img): ind, ind); }); if (imgs.size) { var cspRe = /^(?:chrome|file|jar|resource|moz-extension|https?):/; var [s, p, o] = this.vers >= 110 ? ["::part(button)", "background-image", "AUTHO"] : ["", "--icon", "USE"]; var reg = [], push = (ind, icon) => { var chromeImg = "chrome://user_chrome_files/content/aaepiimg_" + ind; reg.push(["override", chromeImg, icon]); return chromeImg; } var rules = []; for(var [ind, nums] of imgs) { var sel = [], img = entries[ind][1][1]; for(var num of nums) sel.push( `\t#${this.listContainerId} > panel-item:nth-child(${num + 1})${s}` ); rules.push(`${sel.join(",\t\n")} {\n\t\t${p}: url(${ cspRe.test(img) ? img : push(ind, img) }) !important;\n\t}`); } if (reg.length) { var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"] .getService(Ci.amIAddonManagerStartup); var mUri = Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)); this.chromeReg = ams.registerChrome(mUri, reg); } this.regSheet(`\n${rules.join("\n")}\n}`, o + "R_SHEET"); } delete this.items; self = this; this.sym = Symbol.for(this.listContainerId); (this.showing = e => { var card = e.target.closest("addon-card"); card && this.onListShowind(card.addon, e.target); })(e); this.onListShowind(card.addon, e.target); }, async onListShowind(addon, list) { var doc = list.ownerDocument, win = doc.ownerGlobal; var container = doc[this.sym]; if (!container) { container = doc[this.sym] = doc.createElement("div"); container.onclick = this.cclick; container.id = this.listContainerId; for(var lab of this.labs) container.appendChild(this.createPanelItem(doc)).append(lab); var mo = new win.MutationObserver(this.mut); (container.mo = mo).container = container; } for(var item of container.children) { var h = this[item.textContent].hideOn; item.hidden = h && (h.call ? h(addon) : h.includes(addon.type)); } var {mo} = container; mo.disconnect(); list.contains(container) || list.prepend(container); mo.count = 0; mo.ts = Date.now(); mo.observe(list, {childList: true}); }, mut(muts, mo) { if (++mo.count > 10 || Date.now() - mo.ts > 100) return mo.disconnect(); var list = muts[0].target, {container} = mo; if (list.firstElementChild != container) mo.disconnect(), list.prepend(container), mo.observe(list, {childList: true}); }, cclick(e) { e.stopImmediatePropagation(); this.parentNode.hide(); self[e.target.textContent]( e.target.closest("addon-card").addon, e.view.windowRoot.ownerGlobal ); }, copy: str => (self.copy = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper).copyString )(str), getFile(addon) { var file, uri = addon.getResourceURI(); if (uri instanceof Ci.nsIJARURI) uri = uri.JARFile; if (uri instanceof Ci.nsIFileURL) file = uri.file; return file; }, //================================================================================ init(topic, quit) { Services.obs.addObserver(this, topic); Services.obs.addObserver(quit = (s, t) => { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(this, topic); }, "quit-application-granted"); }, isTargetDoc: doc => doc.ownerGlobal.docShell .currentDocumentChannel.name.endsWith("/aboutaddons.html"), observe(doc) { if (!this.isTargetDoc(doc)) return; var vers = this.vers = parseInt(Services.appinfo.platformVersion); this.ts = `${vers >= 111 ? "moz-toggle" : "input"}[action="toggle-disabled"]`; css = css.replace("%TS%", this.ts) .replace(/%CN%/g, this.cn) .replace(/;$/gm, " !important;") .replace("%FD%", this.vertical ? "column" : "row"); this.regSheet(css, "USER_SHEET"); var unload = e => { e.target.removeEventListener("update", this, true); e.target.removeEventListener("showing", this, true); } var load = doc => { doc.addEventListener("update", this, true); doc.addEventListener("showing", this, true); doc.ownerGlobal.addEventListener("unload", unload, {once: true}); } this.handleEvent = e => this[e.type](e); this.observe = doc => this.isTargetDoc(doc) && load(doc); this.ccn = this.cn + "s-container"; this.tInd = this.btnActions.findIndex(s => s == "toggle-disabled"); this.btnActions = this.btnActions.map( action => `panel-list > panel-item[action="${action}"]` ); this.createPanelItem = vers == 110 ? doc => new (doc.ownerGlobal.customElements.get("panel-item")) : doc => doc.createElement("panel-item"); if (vers >= 89) this.clone = item => item.cloneNode(true); else { var cf = function(e) { var win = e.view; win.InspectorUtils.removeContentState(this, 4, true); Services.focus.clearFocus(win); } this.clone = item => { var clone = item.cloneNode(true); clone.onclick = cf; return clone; } } load(doc); }, regSheet(...args) { var prfx = "data:text/css;charset=utf8,@-moz-document url(about:addons),%0A" + "url(chrome://mozapps/content/extensions/aboutaddons.html) {"; var sss = Cc["@mozilla.org/content/style-sheet-service;1"] .getService(Ci.nsIStyleSheetService); (this.regSheet = (code, origin) => sss.loadAndRegisterSheet( Services.io.newURI(prfx + encodeURIComponent(code)), sss[origin] ))(...args); } }).init("chrome-document-loaded"))(`\ span.%CN%s-container { display: flex; flex-direction: %FD%; row-gap: 1px; } addon-card[expanded] span.%CN%s-container { flex-direction: row; } button.%CN% { -moz-appearance: none; margin: 0 1px; padding: 1px 6px 3px 6px; background-image: none; background-color: rgba(174, 236, 235, 0.9); border-radius: 0; border: 1px solid #bbb; font-size: 13px; white-space: nowrap; font-family: Segoe UI; } button.%CN%:hover { background-color: gold; } button.%CN%:after, %TS% { display: none; } }`); В основном стилями обходился. Dumby пишет
Не вопрос, конечно. Только, если можно, в мусорку просьбу мою не выкидывать... когда желание и время появятся - посмотреть, что можно сделать. |
Dumby > 06-05-2023 20:40:00 |
LGS пишет
OK. Возвращаю модифицированный. скрытый текст Выделить код Код:(async (css, self) => ({ //===[ Buttons ]=================================================================== vertical: true, btnActions: ["preferences", "toggle-disabled", "remove", "install-update"], cn: "ucf-cloned-button", update(e) { var trg = e.target; trg.nodeName == "ADDON-CARD" && trg.addon.type != "theme" && this.onCard(trg); }, onCard(card, again) { var btnsParent = card.querySelector("addon-options"); if (!btnsParent) return again || card.ownerGlobal .requestAnimationFrame(() => this.onCard(card, true)); var doc = card.ownerDocument; var [span] = card.getElementsByClassName(this.ccn); if (span) span.textContent = ""; else card.querySelector("button.more-options-button") .before(span = doc.createElement("span")), span.className = this.ccn; var item, num = 0; for(var sel of this.btnActions) { if (num++ == this.tInd) { if (!card.querySelector(this.ts)) continue; item = this.createPanelItem(doc); item.setAttribute("action", "toggle-disabled"); doc.l10n.setAttributes(item, `${ btnsParent.parentNode.getAttribute("active") == "true" ? "dis" : "en" }able-addon-button`); } else { item = btnsParent.querySelector(sel); if (!item) continue; item = this.clone(item); } span.append(item); item.shadowRoot.querySelector("button").classList.add(this.cn); } }, //===[ Popup ]===================================================================== items: { "Копировать имя": [ addon => self.copy(addon.name), "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByUlEQVQ4jY2TTUhUURiGn5tD0Sp00iAwXM1iFu4kWkUZg/9MoZQhdoUCV7ooItq4atFORRGkuLMwoc0kNBGKDLSwFpEIQgspqGUUNsjI3HvPX4s7I3Nn7oW+1fn5vvd8z3vOsYiIgXuPneFMr21ZVmh9+m7GisoPxcTsM2d46on5c1gy9bHgvDVR+afqJzNzy870xIgNUJGGkqf4XVEAuJ4XeWCiNpibX3MGr/XYPd0pADxlOK0MQgf7Xw++sfJq0zRiJQAWcgWndHRkr28UWcrlAfCVwa8KrK4XOPxbYqz/MsnWcyfFi7lCIPD9x0/70YNRykKz+eELQkny74sIJbnQmqQ71UVhe+cES2hoP9uC63mBgO/7dF7s4NexZPRmBqlBaMPHnc+kL7UTh1VxqwKuGxjkaUP+zRZCSVqwKJeP2dvdj8SqGZuod9hXhr6hGwgNL5ZfEoc1PnaL2sFNAlvvthFKxmJJbfCUqXbghhHSyTOkJwcBmHr4vAnLVwKhJEPZbLgDXwh678yG7rfjfLIJS2qD0IEP9R6kiq8XrzS+sOz9p5+asKodXB0YCQkcNBbHYUXlxP6u67dnIj9PY8QJpIC2/6iX/wDxeTOAfNDrywAAAABJRU5ErkJggg==", ], "Копировать ID": [ addon => self.copy(addon.id), "Копировать имя" ], "Копировать версию": [ addon => self.copy(addon.version), "Копировать имя", addon => !addon.version ], "Копировать имя и версию": [ addon => self.copy(addon.name + " " + addon.version), "Копировать имя", addon => !addon.version ], "Копировать URL кнопки": [ (addon, win) => { var btn = Object.assign({ parameters: {}, get initcode() {return this.initCode;}, setText(doc, name, t, cds) { win.custombutton.buttonSetText(doc, name, this[name], cds); } }, win.custombuttons.cbService.getButtonParameters(addon.buttonLink)); self.copy(win.custombutton.buttonGetURI(btn)); }, "Копировать имя", addon => addon.type != "custombuttons" ], "Домашняя страница": [ (addon, win) => win.openURL(addon.homepageURL || addon.reviewURL.replace(/\/reviews\/.*$/, "/")), "data:image/png;base64,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", addon => !addon.homepageURL && !addon.reviewURL ], "Поиск на АМО": [ (addon, win) => win.openURL( addon.homepageURL || ("https://addons.mozilla.org/search/?q=" + encodeURIComponent(addon.name)) ), "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJGSURBVDjLjdJLSNRBHMDx78yqLZaKS75DPdgDDaFDbdJmde5QlhCJGxgpRJfqEEKnIsJLB7skQYQKZaSmdLaopPCgEvSCShCMzR5a7oq7/3l12RVtjfzBMA/4fWZ+MyOccwBM3g8HEbIdfCEhfAFnLVapOa28Uevpjrqz/WOsERJgsu9Uq5CZQzgqrJfo9BajNd5irEYn4p3OUiFExtCLmw2tawFi4l5zUMjMIau9u7K+qxeoAcoAA0wDb2OPwmfA16LiiaOHLj1edRLpkO3WmIis7+oBDgJbgQ2AH6gC6jY19N62RkcctKeVIJAhp9QgUA3kJXdONZVcq9JxPSgQoXRAyIDRth8oAXQyKdWnoCKrTD9CBv4GMqx1WGNZkeRWJKbG2hiD1Cb9FbTnzWFdY/LCdLKlgNQ84gyNKqHm0gDjqVHnxDHgA/B9RQkpaB6YklkZl62np9KBhOqwjpKFgeY2YAz4BESBWHI8Hhs6PVVSvc3v98ye4fP7T676B845nt040ip98qpWJmI9PWiU6bfWgXGN2YHcKwU7tsuc4kpUPMbU0+f8+vKt+Pitl7PLAMDI9cNBoB0hQwICzjqUp6MZvsy8yvp95BRuQUjJ75mPvH4wYo1NlJ64Mza7DPwrhi8cCOeXl/aUB4P4c/NJxKLMvpngycCrzxVFG2v/CwAMnguF80oLe8p27cQh+fnpPV/fTc95S6piXQDAw7a9YbWkezZXFbAwMx/xPFXb1D3+Y90AQF/L7kAsri9mZ4lrTd0TcYA/Kakr+x2JSPUAAAAASUVORK5CYII=", ["custombuttons", "theme", "plugin"] ], "Папка установки": [ addon => self.getFile(addon).reveal(), "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABAklEQVR42mNkoBAwAjEXEAcCMTsW+U9AvB6I/+I0gJ2Noe3QJoZKASEgjwkq+h+C795lYPCKZMgC8mZg0fsfbICIIMOcF6cZkrGZ/v8fA0PndIa/7z8BXfAPqgVKv//A8GPeZoYERmE+hjmP1+AwAOgiTjOIP7HZLyjLMJNRmB/ogjMMyYzsUC8wIhQwsgCFWHAHoKAy0AARIYY5r69idwEhIKgBMgAYBq8vkGmALsyAU2QaYAwz4CiZBliADBAAGnCATANsYQbsJtMAJ5ABwGh8uZE8A4R9gAYwMzHkT8hl6Bfgxp5ecIH3Xxj+F05hyIdpUmXAnpnwge9AfJckW7EBAC/gSzisxsnmAAAAAElFTkSuQmCC", ["custombuttons", "theme", "plugin"] ], "Файл установки": [ addon => self.getFile(addon).launch(), "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA51AAAOdQG5Y1EyAAAAhklEQVQ4y6WT0QnAIAxE78Bt2v1cod3PznP9kVLTRKUGBD+Sd5eQUBJWggCWCAkAJPGXOqlUPyVKkrSPQIoCQJGE6AF4HFyGuBmrR3cGQX8Wmp2cL8Cqv5JPD5Zm1D0nFZjTjHpQ7DuI1L3iBjBS9/pvhtjr21OukVkXiX/ug6SWj4mr53wDMz1vldHlLJkAAAAASUVORK5CYII=", ["custombuttons", "theme", "plugin"] ], "Проверить обновления": [ Cr.NS_ERROR_NET_TIMEOUT_EXTERNAL // Fx 87+ ? (addon, win) => win.content.checkForUpdate(addon) : (addon, win) => win.content.frames[0].checkForUpdate(addon), "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAACVUlEQVQ4jXWT30vTYRTGP3Mb+ZbiXmm6DGUO0pkQGQR2URBdKZWWIHRlFHYhXnQRdVUEBUn/gBddFZERaalUoAUhYUglVIjO5TKbjMDtq2vDQ9t8u0jnr3Xgvfuch/M87zk2rTX/K+u05QROUMBVlrmkn+lvWxlHzsbjVj4uzlHFFec15/7UYCrFU6xcrF0ptbn5jNVADS9o47yvxed24yZRnchLz6dbpUSUlMhHNavSa3zeNskMIZzYOQChPyGmolNIXGz+Tn/lvu59d6jhtdVkZX1vm0AFVFSKpZfPNHKQ3SSBPsxCfMEWi8Rwtbkq5L3UqnH1OCtgNVleqRaf+MUjXrH0Sx2TUuklQAt+XPRykyAzFHNIfgkUUyV58k4FVOifhVLe0sUnGhknnyoAPaAjzHGUbkYxjOlHup0R7iPATqCI9vUMHHhwAR7SGCJrdnS/DjPOMd2nhwD4zS2CZEgCBRxZF8gQJgrkYwcqNmaiJ3QGMADMMMsyMeyAE/e6QII3TEP54XIbhXSufqfXarEebEwcH7swFBIDUqSyIYpPFrFzIV4ZhwLqBDGskOE6XUxwUsqkRwWVyF6xscw0P3lOgodqSgXRWqO1tnGZVwxiiGAYw3CbpWbTbDpMh+EGH2jDvcpuetk9EK8ME6UBQwkOoJUdc445RodHqb9YXxaeDJ8StwyogIrnXGUVUEkplx7mKWKJWn7gTH1PwQqEv4bBQRHzLKlJNbJRwJbrGq2zlps9fKEOD5MIEZ6Q5K7u1xNb2ZzXiEFYxDBEF8I9PaBDOTngLwkg8PzzO00cAAAAAElFTkSuQmCC", addon => !addon.applyBackgroundUpdates || addon.isBuiltin ], }, listContainerId: "ucf-aa-extra-items-container", showing(e) { var card = e.target.closest("addon-card"); if (!card) return; this.labs = []; var imgs = new Map(); var set = (key, val) => imgs.set(key, imgs.has(key) ? imgs.get(key).concat(val) : [val]); var entries = Object.entries(this.items); entries.forEach(([lab, [func, img, hideOn]], ind) => { this.labs.push(lab); (this[lab] = func).hideOn = hideOn; img && set(this.items[img]?.[1] ? entries.findIndex(a => a[0] == img): ind, ind); }); if (imgs.size) { var cspRe = /^(?:chrome|file|jar|resource|moz-extension|https?):/; var [s, p, o] = this.vers >= 110 ? ["::part(button)", "background-image", "AUTHO"] : ["", "--icon", "USE"]; var reg = [], push = (ind, icon) => { var chromeImg = "chrome://user_chrome_files/content/aaepiimg_" + ind; reg.push(["override", chromeImg, icon]); return chromeImg; } var rules = []; for(var [ind, nums] of imgs) { var sel = [], img = entries[ind][1][1]; for(var num of nums) sel.push( `\t#${this.listContainerId} > panel-item:nth-child(${num + 1})${s}` ); rules.push(`${sel.join(",\t\n")} {\n\t\t${p}: url(${ cspRe.test(img) ? img : push(ind, img) }) !important;\n\t}`); } if (reg.length) { var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"] .getService(Ci.amIAddonManagerStartup); var mUri = Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)); this.chromeReg = ams.registerChrome(mUri, reg); } this.regSheet(`\n${rules.join("\n")}\n}`, o + "R_SHEET"); } delete this.items; self = this; this.sym = Symbol.for(this.listContainerId); (this.showing = e => { var card = e.target.closest("addon-card"); card && this.onListShowind(card.addon, e.target); })(e); this.onListShowind(card.addon, e.target); }, async onListShowind(addon, list) { var doc = list.ownerDocument, win = doc.ownerGlobal; var container = doc[this.sym]; if (!container) { container = doc[this.sym] = doc.createElement("div"); container.onclick = this.cclick; container.id = this.listContainerId; for(var lab of this.labs) container.appendChild(this.createPanelItem(doc)).append(lab); var mo = new win.MutationObserver(this.mut); (container.mo = mo).container = container; } for(var item of container.children) { var h = this[item.textContent].hideOn; item.hidden = h && (h.call ? h(addon) : h.includes(addon.type)); } var {mo} = container; mo.disconnect(); list.contains(container) || list.prepend(container); mo.count = 0; mo.ts = Date.now(); mo.observe(list, {childList: true}); }, mut(muts, mo) { if (++mo.count > 10 || Date.now() - mo.ts > 100) return mo.disconnect(); var list = muts[0].target, {container} = mo; if (list.firstElementChild != container) mo.disconnect(), list.prepend(container), mo.observe(list, {childList: true}); }, cclick(e) { e.stopImmediatePropagation(); this.parentNode.hide(); self[e.target.textContent]( e.target.closest("addon-card").addon, e.view.windowRoot.ownerGlobal ); }, copy: str => (self.copy = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper).copyString )(str), getFile(addon) { var file, uri = addon.getResourceURI(); if (uri instanceof Ci.nsIJARURI) uri = uri.JARFile; if (uri instanceof Ci.nsIFileURL) file = uri.file; return file; }, //================================================================================ init(topic, quit) { Services.obs.addObserver(this, topic); Services.obs.addObserver(quit = (s, t) => { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(this, topic); }, "quit-application-granted"); }, isTargetDoc: doc => doc.ownerGlobal.docShell .currentDocumentChannel.name.endsWith("/aboutaddons.html"), observe(doc) { if (!this.isTargetDoc(doc)) return; var vers = this.vers = parseInt(Services.appinfo.platformVersion); this.ts = `${vers >= 111 ? "moz-toggle" : "input"}[action="toggle-disabled"]`; css = css.replace("%TS%", this.ts) .replace(/%CN%/g, this.cn) .replace(/;$/gm, " !important;") .replace("%FD%", this.vertical ? "column" : "row"); this.regSheet(css, "USER_SHEET"); var unload = e => { e.target.removeEventListener("update", this, true); e.target.removeEventListener("showing", this, true); } var load = doc => { doc.addEventListener("update", this, true); doc.addEventListener("showing", this, true); var win = doc.ownerGlobal; win.addEventListener("unload", unload, {once: true}); this.inactiveAddonsVersion(win); } this.handleEvent = e => this[e.type](e); this.observe = doc => this.isTargetDoc(doc) && load(doc); this.ccn = this.cn + "s-container"; this.tInd = this.btnActions.findIndex(s => s == "toggle-disabled"); this.btnActions = this.btnActions.map( action => `panel-list > panel-item[action="${action}"]` ); this.createPanelItem = vers == 110 ? doc => new (doc.ownerGlobal.customElements.get("panel-item")) : doc => doc.createElement("panel-item"); if (vers >= 89) this.clone = item => item.cloneNode(true); else { var cf = function(e) { var win = e.view; win.InspectorUtils.removeContentState(this, 4, true); Services.focus.clearFocus(win); } this.clone = item => { var clone = item.cloneNode(true); clone.onclick = cf; return clone; } } load(doc); }, inactiveAddonsVersion(win) { var desc = win.Object.getOwnPropertyDescriptor(win.HTMLElement.prototype, "title"); var {set} = desc, cfg = {attributes: true, attributeFilter: ["title"]}; var handleMuts = function(m, {trg, val}) { this.disconnect(); var txt = trg.firstChild; if (txt) txt.data = txt.data.replace(trg.closest("addon-card").addon.name, val); } desc.set = function(val) { set.call(this, val); if (this.getAttribute("data-l10n-id") != "addon-name-disabled") return; var mo = new win.MutationObserver(handleMuts); mo.val = val; mo.observe(mo.trg = this, cfg); } for(var Elm of [win.HTMLAnchorElement, win.HTMLHeadingElement]) win.Object.defineProperty(Elm.prototype, "title", desc); }, regSheet(...args) { var prfx = "data:text/css;charset=utf8,@-moz-document url(about:addons),%0A" + "url(chrome://mozapps/content/extensions/aboutaddons.html) {"; var sss = Cc["@mozilla.org/content/style-sheet-service;1"] .getService(Ci.nsIStyleSheetService); (this.regSheet = (code, origin) => sss.loadAndRegisterSheet( Services.io.newURI(prfx + encodeURIComponent(code)), sss[origin] ))(...args); } }).init("chrome-document-loaded"))(`\ span.%CN%s-container { display: flex; flex-direction: %FD%; row-gap: 1px; } addon-card[expanded] span.%CN%s-container { flex-direction: row; } button.%CN% { -moz-appearance: none; margin: 0 1px; padding: 1px 6px 3px 6px; background-image: none; background-color: rgba(174, 236, 235, 0.9); border-radius: 0; border: 1px solid #bbb; font-size: 13px; white-space: nowrap; font-family: Segoe UI; } button.%CN%:hover { background-color: gold; } button.%CN%:after, %TS% { display: none; } }`); |
LGS > 06-05-2023 21:25:02 |
Dumby пишет
|
_zt > 07-05-2023 19:09:40 |
Dumby |
_zt > 07-05-2023 22:03:26 |
Попытался скрестить этот стиль со скриптом и максимум что у меня получилось: |
Dumby > 07-05-2023 23:28:49 |
_zt пишет
Далее, ожидалось «, затем …», но найдено «.»
Не исключено скрытый текст Выделить код Код://... "копирование uuid": [ addon => self.copy(addon.isActive ? Cu.getGlobalForObject(Cu).WebExtensionPolicy.getByID(addon.id).mozExtensionHostname : JSON.parse(Services.prefs.getCharPref("extensions.webextensions.uuids", "{}"))[addon.id] ), "Копировать имя", addon => addon.type != "extension" || !(addon.isWebExtension ?? true) ],
Ожидался код стиля попытки получившегося максимума, но найдено ничего. |
_zt > 08-05-2023 00:39:11 |
Dumby пишет
Затем userContent.css скрытый текст Dumby пишет
Так это просто заготовка. Я ни в чем не уверен и тестировал только на full_theme от VitalyV. скрипт стиль |
_zt > 08-05-2023 01:17:09 |
Dumby пишет
Спасибо, работает. |
Dumby > 08-05-2023 08:25:49 |
_zt пишет
Ааа, вот оно что.
Ух, неслабо ты его покрамсал. Я так понимаю, предпочтение отдано Если бы наоборот, то хоть что-то можно было бы попробовать. скрытый текст Выделить код Код:addon-card panel-list { position: static !important; display: block !important; background: none !important; border: none !important; border-radius: 0 !important; padding: 0 !important; margin: 0 !important; box-shadow: none !important; min-width: 0 !important; } а в скрипте поменял скрытый текст Выделить код Код:/* vertical: true, btnActions: ["toggle-disabled"], */ vertical: false, btnActions: ["remove", "install-update", "preferences"], Выделить код Код:/* onCard(card, again) { var btnsParent = card.querySelector("addon-options"); if (!btnsParent) return again || card.ownerGlobal .requestAnimationFrame(() => this.onCard(card, true)); var doc = card.ownerDocument; var [span] = card.getElementsByClassName(this.ccn); if (span) span.textContent = ""; else card.querySelector("button.more-options-button") .before(span = doc.createElement("span")), span.className = this.ccn; }, */ onCard(card, again) { var btnsParent = card.querySelector("addon-options"); if (!btnsParent) return again || card.ownerGlobal .requestAnimationFrame(() => this.onCard(card, true)); var doc = card.ownerDocument; var [span] = card.getElementsByClassName(this.ccn); var moreOptionsButton = card.querySelector("button.more-options-button"); if (span) span.textContent = ""; else moreOptionsButton.before(span = doc.createElement("span")), span.className = this.ccn; for(var sel of this.btnActions) { var item = btnsParent.querySelector(sel); if (item) span.append(item = this.clone(item)), item.shadowRoot.querySelector("button").classList.add(this.cn); } span.querySelector("[action=remove]").before(moreOptionsButton); }, и, у меня, в 113, выглядит так (отображение добра в <panel-list>'е, конечно, надо править) скрытый текст Выделить код Код:data:image/png;base64,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
Ну, не то, чтобы прямо совсем неверно, но выражение |
_zt > 08-05-2023 17:59:18 |
Dumby gif-ки скрипт Выделить код Код:(async (css, self) => ({ //===[ Buttons ]=================================================================== vertical: false, btnActions: ["remove", "install-update", "preferences"], cn: "ucf-cloned-button", update(e) { var trg = e.target; trg.nodeName == "ADDON-CARD" && trg.addon.type != "theme" && this.onCard(trg); }, onCard(card, again) { var btnsParent = card.querySelector("addon-options"); if (!btnsParent) return again || card.ownerGlobal .requestAnimationFrame(() => this.onCard(card, true)); var doc = card.ownerDocument; var [span] = card.getElementsByClassName(this.ccn); if (span) span.textContent = ""; else card.querySelector("button.more-options-button") .before(span = doc.createElement("span")), span.className = this.ccn; var item, num = 0; for(var sel of this.btnActions) { if (num++ == this.tInd) { if (!card.querySelector(this.ts)) continue; item = this.createPanelItem(doc); item.setAttribute("action", "toggle-disabled"); doc.l10n.setAttributes(item, `${ btnsParent.parentNode.getAttribute("active") == "true" ? "dis" : "en" }able-addon-button`); } else { item = btnsParent.querySelector(sel); if (!item) continue; item = this.clone(item); } span.append(item); item.shadowRoot.querySelector("button").classList.add(this.cn); } }, //===[ Popup ]===================================================================== items: { "Копировать имя": [ addon => self.copy(addon.name), ], "Копировать ID": [ addon => self.copy(addon.id), "Копировать имя" ], "Копировать UUID": [ addon => self.copy(addon.isActive ? Cu.getGlobalForObject(Cu).WebExtensionPolicy.getByID(addon.id).mozExtensionHostname : JSON.parse(Services.prefs.getCharPref("extensions.webextensions.uuids", "{}"))[addon.id] ), "Копировать имя", addon => addon.type != "extension" || !(addon.isWebExtension ?? true) ], // "Копировать версию": [ // addon => self.copy(addon.version), // "Копировать имя", // addon => !addon.version // ], // "Копировать имя и версию": [ // addon => self.copy(addon.name + " " + addon.version), // "Копировать имя", // addon => !addon.version // ], "Коп. URL кнопки": [ (addon, win) => { var btn = Object.assign({ parameters: {}, get initcode() {return this.initCode;}, setText(doc, name, t, cds) { win.custombutton.buttonSetText(doc, name, this[name], cds); } }, win.custombuttons.cbService.getButtonParameters(addon.buttonLink)); self.copy(win.custombutton.buttonGetURI(btn)); }, "Копировать имя", addon => addon.type != "custombuttons" ], "Домашняя страница": [ (addon, win) => win.openURL(addon.homepageURL || addon.reviewURL.replace(/\/reviews\/.*$/, "/")), addon => !addon.homepageURL && !addon.reviewURL ], "Поиск на АМО": [ (addon, win) => win.openURL( ("https://addons.mozilla.org/search/?q=" + encodeURIComponent(addon.name)) ), ["custombuttons", "theme", "plugin"] ], "Папка установки": [ addon => self.getFile(addon).reveal(), ["custombuttons", "theme", "plugin"] ], "Файл установки": [ addon => self.getFile(addon).launch(), ["custombuttons", "theme", "plugin"] ], "Проверить обновления": [ Cr.NS_ERROR_NET_TIMEOUT_EXTERNAL // Fx 87+ ? (addon, win) => win.content.checkForUpdate(addon) : (addon, win) => win.content.frames[0].checkForUpdate(addon), addon => !addon.applyBackgroundUpdates || addon.isBuiltin ], }, listContainerId: "ucf-aa-extra-items-container", showing(e) { var card = e.target.closest("addon-card"); if (!card) return; this.labs = []; var imgs = new Map(); var set = (key, val) => imgs.set(key, imgs.has(key) ? imgs.get(key).concat(val) : [val]); var entries = Object.entries(this.items); entries.forEach(([lab, [func, img, hideOn]], ind) => { this.labs.push(lab); (this[lab] = func).hideOn = hideOn; img && set(this.items[img]?.[1] ? entries.findIndex(a => a[0] == img): ind, ind); }); self = this; this.sym = Symbol.for(this.listContainerId); (this.showing = e => { var card = e.target.closest("addon-card"); card && this.onListShowind(card.addon, e.target); })(e); this.onListShowind(card.addon, e.target); }, async onListShowind(addon, list) { var doc = list.ownerDocument, win = doc.ownerGlobal; var container = doc[this.sym]; if (!container) { container = doc[this.sym] = doc.createElement("div"); container.onclick = this.cclick; container.id = this.listContainerId; for(var lab of this.labs) container.appendChild(this.createPanelItem(doc)).append(lab); var mo = new win.MutationObserver(this.mut); (container.mo = mo).container = container; } for(var item of container.children) { var h = this[item.textContent].hideOn; item.hidden = h && (h.call ? h(addon) : h.includes(addon.type)); } var {mo} = container; mo.disconnect(); list.contains(container) || list.prepend(container); mo.count = 0; mo.ts = Date.now(); mo.observe(list, {childList: true}); }, mut(muts, mo) { if (++mo.count > 10 || Date.now() - mo.ts > 100) return mo.disconnect(); var list = muts[0].target, {container} = mo; if (list.firstElementChild != container) mo.disconnect(), list.prepend(container), mo.observe(list, {childList: true}); }, cclick(e) { e.stopImmediatePropagation(); this.parentNode.hide(); self[e.target.textContent]( e.target.closest("addon-card").addon, e.view.windowRoot.ownerGlobal ); }, copy: str => (self.copy = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper).copyString )(str), getFile(addon) { var file, uri = addon.getResourceURI(); if (uri instanceof Ci.nsIJARURI) uri = uri.JARFile; if (uri instanceof Ci.nsIFileURL) file = uri.file; return file; }, //================================================================================ init(topic, quit) { Services.obs.addObserver(this, topic); Services.obs.addObserver(quit = (s, t) => { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(this, topic); }, "quit-application-granted"); }, isTargetDoc: doc => doc.ownerGlobal.docShell .currentDocumentChannel.name.endsWith("/aboutaddons.html"), observe(doc) { if (!this.isTargetDoc(doc)) return; var vers = this.vers = parseInt(Services.appinfo.platformVersion); this.ts = `${vers >= 111 ? "moz-toggle" : "input"}[action="toggle-disabled"]`; css = css.replace("%TS%", this.ts) .replace(/%CN%/g, this.cn) .replace(/;$/gm, " !important;") .replace("%FD%", this.vertical ? "column" : "row"); this.regSheet(css, "USER_SHEET"); var unload = e => { e.target.removeEventListener("update", this, true); e.target.removeEventListener("showing", this, true); } var load = doc => { doc.addEventListener("update", this, true); doc.addEventListener("showing", this, true); var win = doc.ownerGlobal; win.addEventListener("unload", unload, {once: true}); this.inactiveAddonsVersion(win); } this.handleEvent = e => this[e.type](e); this.observe = doc => this.isTargetDoc(doc) && load(doc); this.ccn = this.cn + "s-container"; this.tInd = this.btnActions.findIndex(s => s == "toggle-disabled"); this.btnActions = this.btnActions.map( action => `panel-list > panel-item[action="${action}"]` ); this.createPanelItem = vers == 110 ? doc => new (doc.ownerGlobal.customElements.get("panel-item")) : doc => doc.createElement("panel-item"); if (vers >= 89) this.clone = item => item.cloneNode(true); else { var cf = function(e) { var win = e.view; win.InspectorUtils.removeContentState(this, 4, true); Services.focus.clearFocus(win); } this.clone = item => { var clone = item.cloneNode(true); clone.onclick = cf; return clone; } } load(doc); }, inactiveAddonsVersion(win) { var desc = win.Object.getOwnPropertyDescriptor(win.HTMLElement.prototype, "title"); var {set} = desc, cfg = {attributes: true, attributeFilter: ["title"]}; var handleMuts = function(m, {trg, val}) { this.disconnect(); var txt = trg.firstChild; if (txt) txt.data = txt.data.replace(trg.closest("addon-card").addon.name, val); } desc.set = function(val) { set.call(this, val); if (this.getAttribute("data-l10n-id") != "addon-name-disabled") return; var mo = new win.MutationObserver(handleMuts); mo.val = val; mo.observe(mo.trg = this, cfg); } for(var Elm of [win.HTMLAnchorElement, win.HTMLHeadingElement]) win.Object.defineProperty(Elm.prototype, "title", desc); }, regSheet(...args) { var prfx = "data:text/css;charset=utf8,@-moz-document url(about:addons),%0A" + "url(chrome://mozapps/content/extensions/aboutaddons.html) {"; var sss = Cc["@mozilla.org/content/style-sheet-service;1"] .getService(Ci.nsIStyleSheetService); (this.regSheet = (code, origin) => sss.loadAndRegisterSheet( Services.io.newURI(prfx + encodeURIComponent(code)), sss[origin] ))(...args); } }).init("chrome-document-loaded"))(`\ span.%CN%s-container { display: flex; flex-direction: %FD%; row-gap: 1px; } addon-card[expanded] span.%CN%s-container { flex-direction: row; } }`); стиль Выделить код Код:@media (prefers-color-scheme: dark) { #details-deck .inline-options-stack { background-color: rgba(43,42,51,.8) !important; } } #categories button.category { border: none !important; } /********* Показывает версии дополнений ***************************************/ @-moz-document url("about:addons"), url("chrome://mozapps/content/extensions/aboutaddons.html") { *|*[current-view="list"] .addon-name-link[title] { font-size: 0 !important; display: flex !important; flex-direction: row !important; } *|*[current-view="list"] .addon-name-link[title]::after { display: block !important; content: attr(title) !important; font-size: 1rem !important; line-height: 1em !important; } /* hide version number on updates category */ div[current-view="updates"] .addon-name-link[title]::after { display: none !important; visibility: collapse !important; opacity: 0 !important; } } /* Добавляет кнопки вместо меню: включить, отключить, удалить, настройки... ***/ /* https://forum.mozilla-russia.org/viewtopic.php?pid=793823#p793823 * Чтобы вернуть текст кнопкам, то в #main: * --v-buttons-font-size: Xrem; * Чтобы убрать текст для кнопок определенного типа там есть пример * addon-card panel-item[action="report"] * Убрать иконки: --v-buttons-icon-size: 0px; */ @-moz-document url("about:addons"), url("chrome://mozapps/content/extensions/aboutaddons.html") { :root { --v-content-button-border-color: var(--in-content-box-border-color, rgba(12, 12, 13, 0.3)); --v-content-button-border-color-hover: var(--in-content-border-hover, rgba(12, 12, 13, 0.5)); --v-content-button-background: var(--in-content-button-background, rgba(12, 12, 13, 0.1)); --v-content-button-background-hover: var(--in-content-button-background-hover, rgba(12, 12, 13, 0.15)); --v-content-button-background-active: var(--in-content-button-background-active, rgba(12, 12, 13, 0.2)); --v-content-button-color: var(--in-content-button-text-color, #0c0c0d); --v-content-button-color-hover: var(--in-content-button-text-color-hover, #0c0c0d); --v-content-button-color-active: var(--in-content-button-text-color-hover, #0c0c0d); --v-buttons-tooltip-color: var(--in-content-page-color, #0c0c0d); --v-buttons-tooltip-background: var(--in-content-box-background, #ffffff); --v-buttons-tooltip-border-color: var(--in-content-box-border-color, rgba(12, 12, 13, 0.3)); --v-main-max-width: 1000px; --card-padding: 8px !important; --section-width: 664px !important; --addon-icon-size: 32px !important; } #main { --v-buttons-font-size: 0.8rem; // 0; --v-buttons-font-weight: bold; --v-buttons-border-radius: 4px; --v-buttons-border-width: 1px; --v-buttons-min-height: 26px; --v-buttons-tooltip-font-size: 0.8rem; --v-buttons-tooltip-border-radius: 2px; --v-buttons-tooltip-delay: .5s; --v-buttons-tooltip-translate-x: -132px; --v-buttons-tooltip-translate-y: 15px; --v-buttons-width: auto; --v-list-display-flex: flex; } @media (prefers-color-scheme: dark) { :root { --v-content-button-border-color: var(--in-content-box-border-color, rgba(200, 200, 210, 0.2)); --v-content-button-border-color-hover: var(--in-content-border-hover, rgba(249, 249, 250, 0.3)); --v-content-button-background: var(--in-content-button-background, rgba(249, 249, 250, 0.1)); --v-content-button-background-hover: var(--in-content-button-background-hover, rgba(249, 249, 250, 0.15)); --v-content-button-background-active: var(--in-content-button-background-active, rgba(249, 249, 250, 0.2)); --v-content-button-color: var(--in-content-button-text-color, #f9f9fa); --v-content-button-color-hover: var(--in-content-button-text-color-hover, #f9f9fa); --v-content-button-color-active: var(--in-content-button-text-color-hover, #f9f9fa); --v-buttons-tooltip-color: var(--in-content-page-color, rgba(200, 200, 210, 0.5)); --v-buttons-tooltip-background: rgba(40, 40, 50, 0.85); --v-buttons-tooltip-border-color: rgba(120, 120, 120, 0.3); } } #moz-toggle-button.toggle-button, addon-card .theme-enable-button { --v-buttons-font-size: 0; --v-buttons-toggle-button-content: "Включить"; --v-buttons-tooltip-content: "Включить дополнение"; --v-buttons-tooltip-display: block; --icon: url("chrome://global/skin/icons/check-partial.svg"); } #moz-toggle-button.toggle-button[aria-pressed="true"], addon-card .card[active="true"] .theme-enable-button { --v-buttons-toggle-button-content: "Отключить"; --v-buttons-tooltip-content: "Отключить дополнение"; --v-buttons-tooltip-display: block; --icon: url("chrome://global/skin/icons/check.svg"); --v-content-button-background: rgba(85,255,85, 0.2); } addon-card panel-item[action="remove"] { --v-buttons-font-size: 0; --v-buttons-tooltip-content: "Удалить дополнение"; --v-buttons-tooltip-display: block; --icon: url("chrome://global/skin/icons/delete.svg"); --v-content-button-background: rgba(255,85,85, 0.3); --v-content-button-background-hover: rgba(255,85,85, 0.8); } addon-card panel-item[action="install-update"] { --v-buttons-font-size: 0; --v-buttons-tooltip-content: "Обновить дополнение"; --v-buttons-tooltip-display: block; --icon: url("chrome://global/skin/icons/update-icon.svg"); --v-content-button-background: rgba(49,140,231, 0.3); --v-content-button-background-hover: rgba(49,140,231, 0.8); } addon-card panel-item[action="preferences"] { --v-buttons-font-size: 0; --v-buttons-tooltip-content: "Настройки дополнения"; --v-buttons-tooltip-display: block; --icon: url("chrome://global/skin/icons/settings.svg"); --v-content-button-background: rgba(85,85,255, 0.3); --v-content-button-background-hover: rgba(85,85,255, 0.8); } /* Скрыть "Пожаловаться на дополнение" */ addon-card panel-item[action="report"] { display: none !important; } addon-list[type="plugin"] addon-card panel-item:not([checked]) { --icon: url("chrome://global/skin/icons/check-partial.svg"); } addon-card button.more-options-button { --v-buttons-tooltip-content: "Дополнительные действия"; --v-buttons-tooltip-display: block; --v-buttons-tooltip-translate-x: 0px !important; width: 26px !important; height: 26px !important; margin: 0 0 0 2px !important; padding: 0 0 0 0 !important; border-radius: 4px !important; } body { margin: 0 !important; } #main { max-width: var(--v-main-max-width) !important; margin-inline-start: 16px !important; margin-inline-end: 16px !important; } addon-card message-bar { --card-padding: inherit !important; } addon-card .card-contents { width: auto !important; overflow-x: hidden !important; flex-grow: 1 !important; } addon-card .card { display: grid !important; grid-template-columns: 1fr auto !important; } addon-card .card > * { grid-column-start: 1 !important; grid-column-end: 3 !important; } addon-card .card > .addon-card-collapsed { grid-column-start: 1 !important; grid-column-end: 2 !important; grid-row-start: 1 !important; overflow-x: hidden !important; } addon-card .card > addon-options { grid-column-start: 2 !important; grid-column-end: 3 !important; grid-row-start: 1 !important; align-self: start !important; min-width: 0 !important; overflow-x: hidden !important; } img.card-heading-image { margin: calc(var(--card-padding) * -1) calc(var(--card-padding) * -1) var(--card-padding) !important; width: calc(var(--card-padding) * 2 + 100%) !important; height: auto !important; object-fit: cover !important; } addon-card .card > img.card-heading-image:not([hidden]) { display: inline !important; } addon-card .card > img.card-heading-image:not([hidden]) + .addon-card-collapsed, addon-card .card > img.card-heading-image:not([hidden]) + .addon-card-collapsed ~ addon-options { grid-row-start: 2 !important; } addon-card .addon-name-container { margin-top: 0 !important; } div.arrow.top ~ div.list { display: var(--v-list-display-flex, block) !important; justify-content: end !important; } #ucf-aa-extra-items-container panel-item { --v-buttons-font-size: 0.8rem; --v-buttons-font-weight: normal; --v-buttons-border-radius: 2px; --v-buttons-border-width: 1px; --v-buttons-min-height: 16px; --v-buttons-width: 100%; } addon-card panel-list { border: 1px solid var(--v-buttons-tooltip-border-color) !important; padding: 1px 0 !important; margin: 1px !important; opacity: 0.9 !important; /**/ } addon-card panel-list panel-item[data-l10n-id="remove-addon-button"], addon-card panel-list panel-item[data-l10n-id="install-update-button"], addon-card panel-list panel-item[data-l10n-id="preferences-addon-button"], addon-card panel-list panel-item[data-l10n-id="report-addon-button"], addon-card panel-list panel-item[data-l10n-id="manage-addon-button"] { display: none !important; } addon-card panel-list panel-item { margin: 1px !important; } addon-card panel-item:where(:not([hidden])) { padding: 0 !important; margin: 0 !important; display: flex !important; align-items: center !important; } style + div.container { padding-top: 0 !important; padding-bottom: 0 !important; } addon-card panel-item[action="expand"], div.arrow.top, div.arrow.bottom, addon-card panel-item-separator { display: none !important; } #moz-toggle-button.toggle-button, addon-card button.theme-enable-button, link[href$="panel-item.css"] ~ button { display: flex !important; align-items: center !important; width: var(--v-buttons-width, 100%) !important; min-height: var(--v-buttons-min-height, 26px) !important; height: auto !important; line-height: 1.25em !important; padding: 0px calc(4px + .25em) !important; margin: 0 2px !important; background-image: var(--icon, none) !important; background-repeat: no-repeat !important; background-size: var(--v-buttons-icon-size, 16px) !important; background-position-y: center !important; background-position-x: left 4px !important; padding-inline-start: calc(4px + .25em + var(--v-buttons-icon-size, 16px)) !important; background-color: var(--v-content-button-background) !important; border-color: var(--v-content-button-border-color) !important; border-style: solid !important; border-width: var(--v-buttons-border-width, 0px) !important; color: var(--v-content-button-color) !important; border-radius: var(--v-buttons-border-radius, 0) !important; font-weight: var(--v-buttons-font-weight, inherit) !important; font-size: var(--v-buttons-font-size, inherit) !important; appearance: none !important; box-shadow: none !important; outline: none !important; -moz-context-properties: fill; fill: currentColor; } #moz-toggle-button.toggle-button, addon-card button.theme-enable-button { padding-inline-start: 0 !important; } #moz-toggle-button.toggle-button { border-color: var(--v-content-button-border-color) !important; } #moz-toggle-button.toggle-button:enabled:hover, addon-card button.theme-enable-button:enabled:hover, addon-card button.more-options-button:enabled:hover, link[href$="panel-item.css"] ~ button:enabled:hover { background-color: var(--v-content-button-background-hover) !important; color: var(--v-content-button-color-hover) !important; border-color: var(--v-content-button-border-color-hover) !important; } #moz-toggle-button.toggle-button:hover:active, addon-card button.theme-enable-button:enabled:hover:active, link[href$="panel-item.css"] ~ button:enabled:hover:active { background-color: var(--v-content-button-background-active) !important; color: var(--v-content-button-color-active) !important; } #moz-toggle-button.toggle-button::-moz-focus-inner, addon-card button.theme-enable-button::-moz-focus-inner, link[href$="panel-item.css"] ~ button::-moz-focus-inner { border: none !important; } link[href$="panel-item.css"] ~ button::after { inset: 0px !important; bottom: auto !important; height: 3px !important; width: auto !important; border-radius: 0 !important; } #moz-toggle-button.toggle-button::before { all: unset !important; display: inline-block !important; content: var(--v-buttons-toggle-button-content, none) !important; white-space: nowrap !important; margin-inline-start: calc(4px + .25em + var(--v-buttons-icon-size, 16px)) !important; } #moz-toggle-button.toggle-button:dir(rtl), addon-card button.theme-enable-button:dir(rtl), addon-card button.more-options-button:dir(rtl), link[href$="panel-item.css"] ~ button:dir(rtl) { background-position-x: right 4px !important; } link[href$="panel-item.css"] ~ button > label { padding: 0 !important; margin: 0 !important; } addon-card .more-options-menu { flex-grow: 0 !important; position: static !important; margin: 0 !important; align-self: start !important; } addon-card .addon-name, addon-card .addon-description { white-space: nowrap !important; overflow-x: hidden !important; text-overflow: ellipsis !important; } #moz-toggle-button.toggle-button::after, addon-card button.theme-enable-button::after, addon-card button.more-options-button::after, addon-card panel-item::after { display: var(--v-buttons-tooltip-display, none) !important; content: ""; max-width: 0; pointer-events: none !important; } #moz-toggle-button.toggle-button:hover::after, addon-card button.theme-enable-button:hover::after, addon-card button.more-options-button:hover::after, addon-card panel-item:hover::after { animation-name: tooltip_delay !important; animation-timing-function: step-end !important; animation-duration: 0s !important; animation-iteration-count: 1 !important; animation-fill-mode: forwards !important; animation-delay: var(--v-buttons-tooltip-delay, .5s) !important; --v-buttons-tooltip-transform: translate(calc(1px + var(--v-buttons-tooltip-translate-x)), calc(100% + var(--v-buttons-tooltip-translate-y))); } @keyframes tooltip_delay { from { max-width: 0; } to { content: var(--v-buttons-tooltip-content, ""); align-self: flex-end; position: absolute; color: var(--v-buttons-tooltip-color); background: var(--v-buttons-tooltip-background); border: 1px solid var(--v-buttons-tooltip-border-color); border-radius: var(--v-buttons-tooltip-border-radius, 0); padding: 2px 0px 4px 0px; min-width: 15em; max-width: 50em; line-height: 1.25em; font-size: 0.7rem; font-weight: normal; text-align: center; z-index: var(--z-index-popup, 10); overflow: hidden; text-overflow: ellipsis; transform: var(--v-buttons-tooltip-transform, none); } } addon-card .toggle-button:hover::after, addon-card button.theme-enable-button:hover::after { --v-buttons-tooltip-transform: translate(calc(var(--v-buttons-tooltip-translate-x) - 1px), calc(100% + 1px + var(--v-buttons-tooltip-translate-y))); } addon-card button.theme-enable-button::before { content: ""; display: inline-block; width: calc(4px + .25em + var(--v-buttons-icon-size, 16px)); } } /* custom_css_for_fx - recentupdates_category_always_visible ******************/ /* Github: https://github.com/aris-t2/customcssforfx **************************/ @-moz-document url-prefix(about:addons), url-prefix(chrome://mozapps/content/extensions/aboutaddons.html) { #categories .category[name="recent-updates"][disabled], #category-recentUpdates[disabled] { overflow: visible !important; height: 48px !important; min-height: 48px !important; opacity: 1 !important; transition-property: unset !important; transition-duration: unset !important; -moz-user-input: unset !important; } #categories .category[name="recent-updates"][hidden], #category-recentUpdates[hidden] { opacity: 1 !important; min-height: 48px !important; height: 48px !important; display: inherit !important; transition: unset !important; } } |
Dumby > 08-05-2023 21:17:06 |
_zt пишет
Увы, не получилось воспроизвести. Может добавить в @keyframes, в to {…}, какой-нибудь min-height |
_zt > 08-05-2023 22:32:48 |
Dumby |
voqabuhe > 09-05-2023 07:07:04 |
Dumby, в 113 вертикальная панель отвалилась. Есть уже решение? |
unter_officer > 09-05-2023 11:49:53 |
voqabuhe пишет
|
Dumby > 09-05-2023 12:03:13 |
voqabuhe скрытый текст Выделить код Код:/* #ucf-additional-vertical-container { display: -moz-box !important; } */ @supports (display: -moz-box) { #ucf-additional-vertical-container { display: -moz-box !important; } } @supports not (display: -moz-box) { #ucf-additional-vertical-container { display: flex !important; } #ucf-additional-vertical-bar { flex-grow: 1 !important; } } |
voqabuhe > 09-05-2023 12:22:40 |
Dumby пишет
Во, спасибо, появилась. unter_officer пишет
Спасибо. Но вариант от Dumby требует меньше движений. |
unter_officer > 09-05-2023 12:26:48 |
voqabuhe пишет
Пожалуйста. |
voqabuhe > 09-05-2023 12:28:27 |
Dumby, а посмотри ещё пожайлуста, чего-то Findbar вниз уехал. скрытый текст Выделить код Код:@-moz-document url("chrome://browser/content/browser.xhtml") { :root { --v-findbar-flex-direction: row; /* row-reverse - findbar справа */ --v-findbar-container-start: 4px; /* 100%; */ /* 1px - findbar справа */ --v-findbar-container-end: 1px; /* 100% - findbar справа */ --v-findbar-margin-right: 17px; /* отступ для скроллбара */ --v-findbar-duration: 150ms; /* длительность анимации */ --v-findbar-border-radius: 6px; /* радиус скругления findbar */ --v-findbar-textbox-radius: 3px; /* радиус скругления поля ввода */ --v-findbar-textbox-width: 14em; /* длина поля ввода */ --v-findbar-toolbarbutton-border-radius: 3px; /* радиус скругления кнопок */ --v-findbar-toolbarbutton-inner-padding: 3px; /* влияет на размер кнопок и поля ввода */ --v-findbar-toolbarbutton-icon-display: -moz-box; /* none - скрыть иконки на кнопках */ --v-findbar-toolbarbutton-text-display: none; /* -moz-box - показать текст на кнопках */ } .browserContainer > findbar { -moz-box-ordinal-group: 0 !important; height: 0 !important; min-height: 0 !important; max-height: 0 !important; padding: 0 !important; margin: 0 !important; margin-right: var(--v-findbar-margin-right) !important; border: none !important; display: flex !important; flex-direction: var(--v-findbar-flex-direction) !important; transition: none !important; visibility: visible !important; opacity: 1 !important; color: var(--toolbar-color, -moz-DialogText) !important; box-shadow: none !important; overflow: visible !important; --toolbarbutton-inner-padding: var(--v-findbar-toolbarbutton-inner-padding); --toolbarbutton-border-radius: var(--v-findbar-toolbarbutton-border-radius); } .browserContainer > findbar > .findbar-container { position: fixed !important; display: flex !important; align-items: center !important; flex-direction: var(--v-findbar-flex-direction) !important; inset: auto !important; margin: -1px 0 0 0 !important; height: auto !important; min-width: 0 !important; padding: 1px !important; padding-inline-start: min(calc(2 * var(--toolbarbutton-inner-padding) + 19px), var(--v-findbar-container-start)) !important; padding-inline-end: min(calc(2 * var(--toolbarbutton-inner-padding) + 19px), var(--v-findbar-container-end)) !important; overflow: hidden !important; border: 1px solid var(--chrome-content-separator-color, rgba(0,0,0,.25)) !important; border-top-width: 0 !important; box-shadow: none !important; z-index: 2 !important; border-radius: 0 0 var(--v-findbar-border-radius) var(--v-findbar-border-radius) !important; background-color: var(--toolbar-bgcolor, -moz-Dialog) !important; background-image: var(--toolbar-bgimage, linear-gradient(rgba(255,255,255,.15), rgba(255,255,255,.15))) !important; opacity: 1; animation-name: findbar-animation, findbar-animation-opacity !important; animation-delay: 0s !important; animation-duration: var(--v-findbar-duration) !important; animation-timing-function: linear, ease-out !important; animation-iteration-count: 1 !important; animation-fill-mode: none !important; } .browserContainer > findbar > #findbar-close-container, .browserContainer > findbar > toolbarbutton.findbar-closebutton { margin: 1px 3px !important; padding: 0 !important; border: none !important; border-radius: var(--v-findbar-toolbarbutton-border-radius) !important; -moz-appearance: none !important; appearance: none !important; position: fixed !important; /* display: flex !important; */ display: none !important; z-index: 2 !important; height: calc(2 * var(--toolbarbutton-inner-padding) + 16px) !important; width: calc(2 * var(--toolbarbutton-inner-padding) + 16px) !important; opacity: 1; animation-name: findbar-animation, findbar-animation-opacity !important; animation-delay: 0s !important; animation-duration: var(--v-findbar-duration) !important; animation-timing-function: linear, ease-out !important; animation-iteration-count: 1 !important; animation-fill-mode: none !important; } .browserContainer > findbar > #findbar-close-container > toolbarbutton.findbar-closebutton { appearance: none !important; margin: 0 !important; padding: 0 !important; height: 100% !important; width: 100% !important; border: none !important; border-radius: var(--v-findbar-toolbarbutton-border-radius) !important; } .browserContainer > findbar toolbarbutton.findbar-closebutton > .toolbarbutton-icon { margin: 0 !important; padding: 0 !important; border: none !important; height: 16px !important; width: 16px !important; border-radius: var(--v-findbar-toolbarbutton-border-radius) !important; } .browserContainer > findbar[hidden="true"] > .findbar-container, .browserContainer > findbar[hidden="true"] > #findbar-close-container, .browserContainer > findbar[hidden="true"] > toolbarbutton.findbar-closebutton { transform: translateY(-100%); animation-name: findbar-animation-hide, findbar-animation-opacity-hide !important; animation-timing-function: linear, ease-in !important; pointer-events: none !important; opacity: 0; } @keyframes findbar-animation { from { transform: translateY(-100%); pointer-events: none; } to { transform: translateY(0%); pointer-events: none; } } @keyframes findbar-animation-opacity { from { opacity: 0; } to { opacity: 1; } } @keyframes findbar-animation-hide { from { transform: translateY(0%); } to { transform: translateY(-100%); } } @keyframes findbar-animation-opacity-hide { from { opacity: 1; } to { opacity: 0; } } .browserContainer > findbar:-moz-lwtheme { color: var(--toolbar-color, inherit) !important; } .browserContainer > findbar:-moz-lwtheme > .findbar-container { background-color: var(--lwt-accent-color, white) !important; background-image: linear-gradient(var(--toolbar-bgcolor, rgba(255,255,255,.4)), var(--toolbar-bgcolor, rgba(255,255,255,.4))) !important; } .browserContainer > findbar:-moz-lwtheme-brighttext > .findbar-container { background-color: var(--lwt-accent-color, black) !important; } :root[lwtheme-image] .browserContainer > findbar:-moz-lwtheme > .findbar-container { background-repeat: repeat-y !important; background-size: auto auto !important; background-attachment: fixed !important; background-position: right top !important; background-image: linear-gradient(var(--toolbar-bgcolor, rgba(255,255,255,.4)), var(--toolbar-bgcolor, rgba(255,255,255,.4))), var(--lwt-header-image, none) !important; } .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton) { align-self: normal !important; } .browserContainer > findbar > .findbar-container > * { margin: 1px !important; outline: none !important; } .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] { display: flex !important; flex-direction: row !important; align-items: normal !important; } .browserContainer > findbar > .findbar-container > description:empty { margin: 0 !important; } .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] > toolbarbutton.tabbable, .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] > .findbar-textbox { padding-block: 0 !important; margin-inline: 0 !important; min-height: 22px !important; box-sizing: border-box !important; } .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] > toolbarbutton.findbar-find-previous { margin-inline: 2px !important; } .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] > toolbarbutton.tabbable { min-width: calc(2 * var(--toolbarbutton-inner-padding) + 16px) !important; border: none !important; border-radius: var(--toolbarbutton-border-radius) !important; background-color: transparent !important; padding-inline: var(--toolbarbutton-inner-padding) !important; outline: none !important; } .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] > .findbar-textbox { border-radius: var(--v-findbar-textbox-radius) !important; min-height: calc(2 * var(--toolbarbutton-inner-padding) + 16px) !important; width: var(--v-findbar-textbox-width) !important; } .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] > .findbar-textbox, .browserContainer > findbar > .findbar-container > description, .browserContainer > findbar > .findbar-container > label { padding-bottom: 1px !important; } .browserContainer > findbar > .findbar-container > checkbox > .checkbox-label-box > .checkbox-icon, .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] > toolbarbutton.tabbable > .toolbarbutton-text, .browserContainer > findbar > .findbar-container > .find-status-icon { display: none !important; } .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton) > :is(.checkbox-label-box,.toolbarbutton-text) { display: var(--v-findbar-toolbarbutton-text-display) !important; margin-inline: 2px !important; } .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] > toolbarbutton.tabbable > .toolbarbutton-icon, .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton) > :is(.checkbox-check,.toolbarbutton-icon) { margin: 0 !important; padding: 0 !important; border: none !important; height: 16px !important; width: 16px !important; } .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton) > :is(.checkbox-check,.toolbarbutton-icon) { display: var(--v-findbar-toolbarbutton-icon-display) !important; appearance: none !important; background: none !important; color: inherit !important; filter: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='0'><filter id='fill'><feComposite in='FillPaint' in2='SourceGraphic' operator='in'/></filter></svg>#fill"); fill: currentColor; } .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton) { appearance: none !important; padding: var(--toolbarbutton-inner-padding) !important; border-radius: var(--toolbarbutton-border-radius) !important; } .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] > toolbarbutton.tabbable:not([disabled="true"]):hover, .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton):not([disabled="true"]):hover { background-color: var(--toolbarbutton-hover-background, color-mix(in srgb, currentColor 17%, transparent)) !important; } .browserContainer > findbar > .findbar-container > hbox[anonid="findbar-textbox-wrapper"] > toolbarbutton.tabbable:not([disabled="true"]):is([checked="true"],:hover:active), .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton):not([disabled="true"]):is([checked="true"],:hover:active) { background-color: var(--toolbarbutton-active-background, color-mix(in srgb, currentColor 30%, transparent)) !important; } .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton).findbar-highlight { list-style-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path style='fill:rgb(142, 142, 152);' d='M 2,3 V 4.2 H 6 V 12 h 1.2 l 0,-7.8 h 4 L 11.2,3 Z M 12.5,6 C 11.8,8.39 10,10.3 10,11.6 10,12.9 11.1,14 12.5,14 13.9,14 15,12.9 15,11.6 15,10.3 13.2,8.39 12.5,6 Z m 0,6.8 c -1,0 -1.3,-0.8 -1.3,-1.2 0,-1.1 0.8,-2.1 1.3,-3 0.5,0.9 1.3,1.9 1.3,3 0,0.4 -0.3,1.2 -1.3,1.2 z' /></svg>") !important; } .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton).findbar-case-sensitive { list-style-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path style='fill:rgb(142, 142, 152);' d='m 6,3 -5,9 h 1.2 l 1.1,-2 h 2.5 v 2 H 7 V 3 Z M 5.8,5.5 5.8,9 H 3.9 Z M 13,6 V 6.77 C 12.5,6.28 11.7,6 11,6 9.34,6 8,7.34 8,9 c 0,1.7 1.34,3 3,3 0.7,0 1.5,-0.3 2,-0.8 V 12 h 1 V 6 Z m -2,1 c 1.1,0 2,0.9 2,2 0,1.1 -0.9,2 -2,2 C 9.9,11 9,10.1 9,9 9,7.9 9.9,7 11,7 Z' /></svg>") !important; } .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton).findbar-match-diacritics { list-style-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path style='fill:rgb(142, 142, 152);' d='M 5,3 3,0 H 0 M 12,5 10,2 H 7 M 6,3 1,12 h 1.2 l 1.1,-2 h 2.5 v 2 H 7 V 3 M 5.8,5.5 V 9 H 3.9 Z M 13,6 V 6.77 C 12.5,6.28 11.7,6 11,6 9.34,6 8,7.34 8,9 c 0,1.7 1.34,3 3,3 0.7,0 1.5,-0.3 2,-0.8 V 12 h 1 V 6 Z m -2,1 c 1.1,0 2,0.9 2,2 0,1.1 -0.9,2 -2,2 C 9.9,11 9,10.1 9,9 9,7.9 9.9,7 11,7 Z'/></svg>") !important; } .browserContainer > findbar > .findbar-container > :is(checkbox,toolbarbutton).findbar-entire-word { list-style-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path style='fill:rgb(142, 142, 152);' d='M 15,13.8 V 15 H 1 V 13.8 M 15,2.2 15,1 H 1 V 2.2 M 6,3 1,12 h 1.2 l 1.1,-2 h 2.5 v 2 H 7 V 3 M 5.8,5.5 V 9 H 3.9 Z M 13,6 V 6.77 C 12.5,6.28 11.7,6 11,6 9.34,6 8,7.34 8,9 c 0,1.7 1.34,3 3,3 0.7,0 1.5,-0.3 2,-0.8 V 12 h 1 V 6 Z m -2,1 c 1.1,0 2,0.9 2,2 0,1.1 -0.9,2 -2,2 C 9.9,11 9,10.1 9,9 9,7.9 9.9,7 11,7 Z' /></svg>") !important; } } 09-05-2023 12:30:33 unter_officer пишет
Да, где ты его нашёл? |
unter_officer > 09-05-2023 12:35:48 |
voqabuhe пишет
Здесь, через личку. |
voqabuhe > 09-05-2023 12:54:41 |
unter_officer |
unter_officer > 09-05-2023 12:59:47 |
voqabuhe |
voqabuhe > 09-05-2023 13:05:30 |
unter_officer |
unter_officer > 09-05-2023 13:11:57 |
Мой vertical_top_bottom_bar.css: скрытый текст Выделить код Код:toolbarpaletteitem[place="palette"] > toolbaritem.ucf-additional-springs { background: white url("./svg/spring.svg") center no-repeat; border: none; outline: 1px solid currentColor; outline-offset: -1px; min-height: 37px; opacity: 0.3; } toolbarpaletteitem[place="toolbar"] > toolbaritem.ucf-additional-springs, toolbarpaletteitem[place="panel"] > toolbaritem.ucf-additional-springs, toolbarpaletteitem[place="menu-panel"] > toolbaritem.ucf-additional-springs { background: white url("./svg/spring.svg") center no-repeat; border: none; min-width: 34px; min-height: 14px; outline: 1px solid currentColor; outline-offset: -1px; margin-block: 2px !important; margin-inline: 1px !important; opacity: 0.3; } toolbarpaletteitem[place="palette"][id*="ucf-additional-top-spring"], toolbarpaletteitem[place="palette"][id*="ucf-additional-vertical-spring"], toolbarpaletteitem[place="palette"][id*="ucf-additional-bottom-spring"] { vertical-align: top; } toolbarpaletteitem[place] > toolbaritem.ucf-additional-springs { -moz-window-dragging: no-drag !important; } #ucf-restart-app { list-style-image: url("./svg/restart-app-16.svg") !important; fill: #f38725 !important; } #ucf-additional-vertical-toggle-button { list-style-image: url("./svg/vert-toolbar.svg") !important; } #ucf-additional-top-toggle-button { list-style-image: url("./svg/top-toolbar.svg") !important; } #ucf-additional-bottom-toggle-button { list-style-image: url("./svg/bottom-toolbar.svg") !important; } #ucf-view-history-sidebar-button { list-style-image: url("./svg/history-16.svg") !important; } #ucf-view-bookmarks-sidebar-button { list-style-image: url("./svg/bookmark-16.svg") !important; } #ucf-open-directories-button { list-style-image: url("./svg/user-home-16.svg") !important; } #browser-bottombox:not([lwthemefooter="true"]):-moz-lwtheme { background-color: transparent !important; } #ucf-additional-vertical-box { background: none !important; border: none !important; box-shadow: none !important; position: relative !important; z-index: 3 !important; margin: -1px 0 !important; } #ucf-additional-top-bar, #ucf-additional-vertical-bar, #ucf-additional-bottom-bar { -moz-appearance: none !important; appearance: none !important; padding: 0 !important; border-block: none !important; overflow: -moz-hidden-unscrollable; overflow: clip; } #ucf-additional-bottom-bar { border-top: 1px solid var(--chrome-content-separator-color, var(--toolbox-border-bottom-color, rgba(0,0,0,0.1))) !important; } #ucf-additional-bottom-bar #ucf-additional-bottom-closebutton { margin: 0 var(--toolbarbutton-outer-padding, 1px) !important; padding: var(--toolbarbutton-inner-padding, 4px) !important; } #ucf-additional-bottom-bar #ucf-additional-bottom-closebutton .toolbarbutton-icon { margin: 0 !important; padding: 0 !important; height: 16px !important; width: 16px !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar, #ucf-additional-bottom-bar { -moz-window-dragging: no-drag !important; background-clip: border-box !important; background-origin: border-box !important; background-color: var(--toolbar-bgcolor, -moz-Dialog) !important; background-image: var(--toolbar-bgimage, linear-gradient(rgba(255,255,255,.15), rgba(255,255,255,.15))) !important; color: var(--toolbar-color, -moz-DialogText) !important; border-inline: none !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar { padding: 1px 0 !important; margin: 0 !important; font-size: 1rem !important; min-width: 20px !important; width: auto !important; flex-grow: 1 !important; align-items: stretch !important; justify-content: start !important; flex-direction: column !important; } :root:-moz-lwtheme[style*="--lwt-additional-images"] #navigator-toolbox { background-attachment: fixed !important; } #ucf-additional-vertical-box:-moz-lwtheme > #ucf-additional-vertical-bar, #ucf-additional-bottom-bar:-moz-lwtheme { color: var(--toolbar-color, inherit) !important; background-repeat: no-repeat, var(--lwt-background-tiling, repeat-y) !important; background-size: auto auto !important; background-attachment: fixed !important; background-position: right top, var(--lwt-background-alignment, right top) !important; background-color: transparent !important; background-image: linear-gradient(var(--toolbar-bgcolor, rgba(255,255,255,.4)), var(--toolbar-bgcolor, rgba(255,255,255,.4))), var(--lwt-header-image, var(--lwt-additional-images, none)) !important; } :root[lwtheme-image="true"] #ucf-additional-vertical-box:-moz-lwtheme > #ucf-additional-vertical-bar, :root[lwtheme-image="true"] #ucf-additional-bottom-bar:-moz-lwtheme { background-repeat: no-repeat, repeat-y !important; } :root #browser-bottombox[lwthemefooter="true"] #ucf-additional-bottom-bar:-moz-lwtheme { background-repeat: initial !important; background-attachment: initial !important; background-position: initial !important; background-color: var(--toolbar-bgcolor, rgba(255,255,255,.4)) !important; background-image: none !important; } #ucf-additional-vertical-box[vertautohide="true"]:-moz-lwtheme > #ucf-additional-vertical-bar { background-color: var(--lwt-accent-color, white) !important; } #ucf-additional-vertical-box[vertautohide="true"]:-moz-lwtheme-brighttext > #ucf-additional-vertical-bar { background-color: var(--lwt-accent-color, black) !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar:not([collapsed="true"]) { border-inline-end: 1px solid var(--chrome-content-separator-color, var(--toolbox-border-bottom-color, rgba(0,0,0,0.1))) !important; } #ucf-additional-vertical-box[v_vertical_bar_start="false"] > #ucf-additional-vertical-bar:not([collapsed="true"]) { border-inline-end: none !important; border-inline-start: 1px solid var(--chrome-content-separator-color, var(--toolbox-border-bottom-color, rgba(0,0,0,0.1))) !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar[collapsed="true"] { padding: 0 !important; border: none !important; min-width: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbaritem.toolbaritem-combined-buttons { flex-direction: column !important; margin-inline: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbaritem.toolbaritem-combined-buttons > toolbarbutton.toolbarbutton-combined > .toolbarbutton-text { padding-inline: 1px !important; margin-inline: 0 !important; min-width: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbaritem.toolbaritem-combined-buttons separator { display: none !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbarspring { min-width: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbarseparator { -moz-appearance: none !important; appearance: none !important; padding: 0 !important; margin: 2px !important; margin-top: 4px !important; margin-bottom: 0 !important; border: none !important; border-top: 1px solid currentColor !important; width: auto !important; max-width: none !important; height: 5px !important; min-height: 5px !important; max-height: 5px !important; opacity: 0.3 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbarspacer { height: 15px !important; } #ucf-additional-vertical-container { display: flex !important; } #ucf-additional-vertical-container[vertautohide="true"] { position: relative !important; min-width: 100px !important; width: 100px !important; max-width: 100px !important; overflow: visible !important; margin-inline-start: 0 !important; margin-inline-end: -100px !important; pointer-events: none !important; visibility: hidden !important; } #ucf-additional-vertical-container[vertautohide="true"][v_vertical_bar_start="false"] { margin-inline-start: -100px !important; margin-inline-end: 0 !important; } #ucf-additional-vertical-box[vertautohide="true"] { position: absolute !important; display: block !important; top: 0 !important; bottom: 0 !important; left: 0 !important; right: auto !important; font-size: 0px !important; } #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"], #ucf-additional-vertical-box[vertautohide="true"]:-moz-locale-dir(rtl) { left: auto !important; right: 0 !important; } #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"]:-moz-locale-dir(rtl) { left: 0 !important; right: auto !important; } #ucf-additional-vertical-box[vertautohide="true"] > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: calc(-1 * (100% - 5px)); right: auto; opacity: 0; animation-name: toolbar-hide !important; animation-timing-function: linear !important; animation-duration: 0.2s !important; animation-iteration-count: 1 !important; animation-delay: 0s !important; transition-property: opacity !important; transition-timing-function: step-start !important; transition-duration: 0s !important; transition-delay: 0.2s !important; pointer-events: auto !important; height: 100% !important; visibility: visible !important; position: relative !important; } #ucf-additional-vertical-box[vertautohide="true"]:-moz-locale-dir(rtl) > #ucf-additional-vertical-bar:not([collapsed="true"]), #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"] > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: auto; right: calc(-1 * (100% - 5px)); animation-name: toolbar-hide-rtl !important; } #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"]:-moz-locale-dir(rtl) > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: calc(-1 * (100% - 5px)); right: auto; animation-name: toolbar-hide !important; } #ucf-additional-vertical-container > #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_visible] > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: 0px; right: auto; opacity: 1; animation-name: toolbar-visible !important; transition-delay: 0s !important; } #ucf-additional-vertical-container > #ucf-additional-vertical-box[vertautohide="true"]:-moz-locale-dir(rtl)[v_vertical_bar_visible] > #ucf-additional-vertical-bar:not([collapsed="true"]), #ucf-additional-vertical-container > #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"][v_vertical_bar_visible] > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: auto; right: 0px; animation-name: toolbar-visible-rtl !important; } #ucf-additional-vertical-container > #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"]:-moz-locale-dir(rtl)[v_vertical_bar_visible] > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: 0px; right: auto; animation-name: toolbar-visible !important; } @keyframes toolbar-hide { from { left: 0px; } to { left: calc(-1 * (100% - 5px)); } } @keyframes toolbar-hide-rtl { from { right: 0px; } to { right: calc(-1 * (100% - 5px)); } } @keyframes toolbar-visible { from { left: calc(-1 * (100% - 5px)); } to { left: 0px; } } @keyframes toolbar-visible-rtl { from { right: calc(-1 * (100% - 5px)); } to { right: 0px; } } :root[inDOMFullscreen] #ucf-additional-vertical-box > #ucf-additional-vertical-bar:not([collapsed="true"]), :root[inFullscreen]:not([OSXLionFullscreen]) #ucf-additional-vertical-box > #ucf-additional-vertical-bar:not([collapsed="true"]):not([fullscreentoolbar="true"]), #ucf-additional-bottom-bar[collapsed="true"][customizable="true"][customizing="true"] { visibility: collapse !important; padding: 0 !important; border: none !important; min-width: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > #personal-bookmarks { width: 0 !important; flex-grow: 0 !important; margin: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > #search-container { width: 0 !important; max-height: 0 !important; overflow-y: visible !important; flex-grow: 0 !important; min-width: 80px !important; margin: 0 !important; } :root[chromehidden~="location"][chromehidden~="toolbar"] #ucf-additional-vertical-container { display: none !important; } @supports (fill: color-mix(in srgb, currentColor 20%, transparent)) { #ucf-restart-app { fill: color-mix(in srgb, currentColor 20%, #f38725) !important; } } |
Dumby > 09-05-2023 13:16:43 |
voqabuhe пишет
Рядом с (или вместо) -moz-box-ordinal-group: 0 !important; order: -1 !important; |
voqabuhe > 09-05-2023 13:22:54 |
Dumby пишет
Вот спасибо большое. Теперь всё на месте. 09-05-2023 13:29:38 unter_officer пишет
Спасибо, с вашим действительно всё нормально. Таки значит я где-то ошибся. Теперь два рабочих варианта. |
unter_officer > 09-05-2023 13:36:00 |
voqabuhe пишет
Вот и ладушки. |
Dumby > 09-05-2023 14:21:19 |
voqabuhe пишет
Это не одно и то же. А то, что выложил unter_officer — это памятка типа такой, Там же не только тулбар, но ещё и чтобы на нём "дропмаркер" |
voqabuhe > 09-05-2023 15:47:48 |
unter_officer пишет
Ну да, я и говорю, спасибо Виталию в вашем лице, как его представителю. Dumby пишет
Ну теперь понятно, спасибо за разъяснения. |
kokoss > 09-05-2023 17:00:16 |
Dumby пишет
Спасибо! unter_officer пишет
Спасибо! Add, и всех С Днём Победы!!! |
voqabuhe > 11-05-2023 02:02:03 |
Dumby |
_zt > 11-05-2023 02:15:00 |
voqabuhe |
voqabuhe > 11-05-2023 04:52:40 |
_zt пишет
Спасибо. Блин, ещё 20.04.23 оказывается починили, а парюсь. Dumby, спасибо за полезную кнопочку. |
xrun1 > 11-05-2023 09:34:08 |
voqabuhe |
kokoss > 13-05-2023 11:40:10 |
Dumby скрытый текст Выделить код Код:try { CustomizableUI.createWidget({ id: "reload-skip-cache-ToolBarButton", type: "custom", onBuild: function(aDocument) { let toolbaritem = aDocument.createXULElement("toolbarbutton"); let props = { id: "reload-skip-cache-ToolBarButton", class: "toolbarbutton-1 chromeclass-toolbar-additional", label: "Tab neu laden", tooltiptext: "Обновить вкладку минуя кеш", style: "list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAOOSURBVHjabNPNb5RVFMfx77n3eZlnpjMMDNIOSCsvKoTgAmO6cuNKFP4ENrIBElyIoRtcqVg1JlZimrjGhQYTA8aNijsljUaIgCWATQTaQgCZlpl55nmee4+LTisY7/58cs49vyND732BFjm9u7ex5QpxY5DO7LVqsr65RWx51ETBNkHwWT7tfXcqnZu7ljS3Lrpum6BaJ7s3O6i9zMujkIlLRKvrr9hK5WBp/YY9SXMjQa0KQLHwkHT+L9K52W+Lh+1Jzf03EkYjJo7OFK3W2RUovT1biweHjlWf3XGkvGGz0dTjeimoBwAx2DhGkoDOzeu+M3P1M0ywozH60ov3fj57QobGv8SnHUDerz03ejSurcZ12iAgIoAsQSiqCgqmlFCkbUQMQZxw99wPEzL4zuf4tLu3vGn710lzo/GdNhiDIPi8h7rCAWCstVGMouAVCUJQBZQHv09NSO3Au+XS+uGv6jtHX9a0A/0uevdutx7OXDmdzt84hxHKzaeeT57ctCdeO7hOMID2J7a0pn+bkDVHPtmVNIenkuaI1bwHxtK7f2dhYfr8fjHmFICJS5iotMHEpe+qT+/cLs4/Bi1evzgha8cmD1RGtk6aIAYU7wpa0xdOum57X1ipYssDqCu2m1Ll5MDmbbtwOZrn/c5BjGFx5soJaRz9dLwyvHUMVRDB91L39/mfDosxkyapIDYEeCOqNz4yYZRqnq0gy8/10relcWRiPBkaHltajuCL3LUu/nIYmDSlBIzFhFEUDtSsFrliLbK8SRFQRb3Ppf76hwdKawYnTRj15xbat/48WbQX95m4jGYpJk6wUYzvdQlqdawN8F5R7xAbLA1TO3R8VxiXp8Ja3eI9GIv3bqFza2a/2OCU5hmqiolKiLVPxGvXBaYo7vgsdS5NwQZLcRl47a2yjeJTpfqa3ar9TQQRHlrZwoPTRev+OWAxWNVoRLVVGLiiRXZJ83zOZb1c3VLMZNXB46grXrWBPR2UymYFMxZsgISRAzqaZ/O44pJ69ytwAfjD5/kt9a4LgtQPjaOuwGe98SCKx0wYLEek/6ErF5IBN4DLCBd9Xlx2Lv9ejJ0HliC8o+h2qqDHbBC8KTYw/9Y/5jmFlnfFeV8UH4ixP5ooylB9DFou2w16UET2mv8crVdFVc+IyMeKnBUxmCjifyExBl/kA4JsQeQF4Jm+dhXVKUWv2zBc9F55FPpnAAjpv6gFuxLzAAAAAElFTkSuQmCC)", oncommand: "BrowserReloadSkipCache();" }; for (let p in props) toolbaritem.setAttribute(p, props[p]); return toolbaritem; } }); } catch(e) {} |
_zt > 13-05-2023 12:45:17 |
kokoss |
Dumby > 13-05-2023 12:47:15 |
kokoss скрытый текст Выделить код Код:(async () => CustomizableUI.createWidget({ id: "reload-skip-cache-ToolBarButton", label: "Tab neu laden", tooltiptext: "ЛКМ: Обновить вкладку\n" + "ПКМ: Обновить вкладку минуя кеш", localized: false, onCreated(btn) { btn.oncontextmenu = this.context; btn.setAttribute("oncommand", "BrowserReload()"); btn.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAOOSURBVHjabNPNb5RVFMfx77n3eZlnpjMMDNIOSCsvKoTgAmO6cuNKFP4ENrIBElyIoRtcqVg1JlZimrjGhQYTA8aNijsljUaIgCWATQTaQgCZlpl55nmee4+LTisY7/58cs49vyND732BFjm9u7ex5QpxY5DO7LVqsr65RWx51ETBNkHwWT7tfXcqnZu7ljS3Lrpum6BaJ7s3O6i9zMujkIlLRKvrr9hK5WBp/YY9SXMjQa0KQLHwkHT+L9K52W+Lh+1Jzf03EkYjJo7OFK3W2RUovT1biweHjlWf3XGkvGGz0dTjeimoBwAx2DhGkoDOzeu+M3P1M0ywozH60ov3fj57QobGv8SnHUDerz03ejSurcZ12iAgIoAsQSiqCgqmlFCkbUQMQZxw99wPEzL4zuf4tLu3vGn710lzo/GdNhiDIPi8h7rCAWCstVGMouAVCUJQBZQHv09NSO3Au+XS+uGv6jtHX9a0A/0uevdutx7OXDmdzt84hxHKzaeeT57ctCdeO7hOMID2J7a0pn+bkDVHPtmVNIenkuaI1bwHxtK7f2dhYfr8fjHmFICJS5iotMHEpe+qT+/cLs4/Bi1evzgha8cmD1RGtk6aIAYU7wpa0xdOum57X1ipYssDqCu2m1Ll5MDmbbtwOZrn/c5BjGFx5soJaRz9dLwyvHUMVRDB91L39/mfDosxkyapIDYEeCOqNz4yYZRqnq0gy8/10relcWRiPBkaHltajuCL3LUu/nIYmDSlBIzFhFEUDtSsFrliLbK8SRFQRb3Ppf76hwdKawYnTRj15xbat/48WbQX95m4jGYpJk6wUYzvdQlqdawN8F5R7xAbLA1TO3R8VxiXp8Ja3eI9GIv3bqFza2a/2OCU5hmqiolKiLVPxGvXBaYo7vgsdS5NwQZLcRl47a2yjeJTpfqa3ar9TQQRHlrZwoPTRev+OWAxWNVoRLVVGLiiRXZJ83zOZb1c3VLMZNXB46grXrWBPR2UymYFMxZsgISRAzqaZ/O44pJ69ytwAfjD5/kt9a4LgtQPjaOuwGe98SCKx0wYLEek/6ErF5IBN4DLCBd9Xlx2Lv9ejJ0HliC8o+h2qqDHbBC8KTYw/9Y/5jmFlnfFeV8UH4ixP5ooylB9DFou2w16UET2mv8crVdFVc+IyMeKnBUxmCjifyExBl/kA4JsQeQF4Jm+dhXVKUWv2zBc9F55FPpnAAjpv6gFuxLzAAAAAElFTkSuQmCC" }, context(e) { return e.ctrlKey || e.shiftKey || Boolean(e.view.BrowserReloadSkipCache()); } }))(); |
kokoss > 13-05-2023 13:24:53 |
Dumby пишет
Благодарю!!! _zt пишет
Интересный вариант, а как отключить анимацию(кнопку СТОП) кнопки при обновлении вкладки ? |
_zt > 13-05-2023 13:53:44 |
kokoss скрытый текст Выделить код Код:#stop-button { list-style-image: url("chrome://global/skin/icons/reload.svg") !important } |
_zt > 14-05-2023 02:02:13 |
Dumby скрытый текст Выделить код Код:// Копировать значок сайта в base64 function WebScreenShotonImage(image) { var canvas = document.createElementNS(xhtmlns, 'canvas'); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; var ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); var base64 = canvas.toDataURL(); gClipboard.write(base64); // стиль для значка во всплывающей подсказке ... var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(base64, self.label, "\nЗначок скопирован как base64", false, "", (s, t)=> { if (t == 'alertfinished') sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается }, ""); }; Выделить код Код:// Копировать изображение или текстовой файл в base64 ... function copyFileToBase(){ var fp = window.makeFilePicker(); fp.init(window, "Открыть файл", fp.modeOpen); fp.appendFilter("Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml; *.xhtml; *.jpe; *.jpg; *.jpeg;\ *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw"); fp.open(re=> { if ( re != fp.returnOK ) return; var file = fp.file; var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); inputStream.init(file, 0x01, 0600, 0); var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); stream.setInputStream(inputStream); var encoded = btoa(stream.readBytes(stream.available())); var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file); var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded; gClipboard.write(dataURI); // стиль для значка во всплывающей подсказке ... var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Файл скопирован как base64", false, "", (s, t)=> { if (t == 'alertfinished') sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается }, ""); }); }; |
Dumby > 14-05-2023 08:35:48 |
_zt скрытый текст Выделить код Код:var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); var alertName = "abrakadabra"; as.showAlertNotification( "about:logo", "Title", "Message", false, "", (subject, topic) => console.log(topic), alertName ); setTimeout(as.closeAlert, 2e3, alertName); |
xrun1 > 14-05-2023 10:24:48 |
_zt скрытый текст Выделить код Код:#alertNotification { padding: 5px !important; } #alertImage { max-height: 24px !important; max-width: 24px !important; margin: 4px 7px !important; padding: unset !important; } #alertTextBox { flex-direction: row !important; align-items: center !important; justify-content: center !important; } #alertBox { padding-block-end: 7px !important; box-shadow: rgba(84, 83, 87, 0.32) 0 0 5px !important; } |
_zt > 14-05-2023 15:56:35 |
Dumby скрытый текст Выделить код Код:as.showAlertNotification( base64, "Скрипт Save - FaviconToBase", "Значок скопирован как base64", false, "", (subject, topic) => console.log(topic), alertName ); setTimeout(as.closeAlert, 5e3, alertName); А удаление стиля как прикрутить? Оно нужно вообще? Если его из оригинала вставить после "", то таймаут перестает работать. xrun1 Да, что то я не подумал об этом. скрытый текст Выделить код Код:@-moz-document url("chrome://global/content/alerts/alert.xhtml") { #alertTitleBox { padding: 0 10px !important; font-size: 14px !important; } #alertImage { max-height: 36px !important; max-width: 36px !important; margin: 4px 10px !important; padding: unset !important; } #alertTextBox { min-width: 300px !important; font-weight: bold; flex-direction: row !important; align-items: center !important; justify-content: center !important; } #alertBox { box-shadow: rgba(10, 10, 12, 0.32) 0 0 5px !important; } @media (prefers-color-scheme: dark) { #alertBox { border-color: rgb(0, 116, 232) !important; background-color: var(--menu-background-color, var(--arrowpanel-background, Field)) !important; color: var(--menu-color, var(--arrowpanel-color, FieldText)) !important; } } } |
b0ttle > 14-05-2023 17:00:32 |
Здравствуйте всем. Кто знает, они работают до сих пор? Просто, второй вроде отвалился. Есть какой-то аналог, или посвежее? |
stvol > 14-05-2023 21:16:26 |
Dumby пишет
Отлично! Панелька появилась, спасибо!!))) |
Dumby > 14-05-2023 21:49:23 |
_zt пишет
Раз стилизировал алерт снаружи, то, наверно, b0ttle пишет
Что-то мешает самому проверить? скрытый текст Выделить код Код:/* showBrowserPageActionFeedback(PageActions.actionForID("copyURL")); }, */ this.hint(); }, hint() { var anchor = window.document.getElementById("identity-icon"); var document = {l10n: {setAttributes(lab) { lab.textContent = "Скопировано в буфер обмена!"; }}}; (this.hint = eval(`(function ${ConfirmationHint.show})`) .bind(ConfirmationHint, anchor, "") )(); },
Что второй? По ссылке — лишь фрагмент кода. |
b0ttle > 14-05-2023 21:56:37 |
Dumby А тут моя каша, когда-то сделанная из двух примеров. Не мог решить, что использовать. Так и осталось, пару лет не возвращался. скрытый текст Выделить код Код:/* https://forum.mozilla-russia.org/viewtopic.php?pid=786917#p786917 ||000|001Alt|101Ctrl+Alt|100Ctrl|110Ctrl+Shift {Vit.V.786906#p786906||786926#p786926 https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code/code_values Console> document.addEventListener("keydown",(e)=>console.log(e.code));||e.preventDefault(); (prevent default!..) https://forum.mozilla-russia.org/viewtopic.php?pid=787019#p787019 }*/ // https://support.mozilla.org/ru/kb/sochetaniya-klavish#w_okna-i-vkladki || https://support.mozilla.org/en-US/kb/keyboard-shortcuts-perform-firefox-tasks-quickly //============================================================ //forum.mozilla-russia.org/viewtopic.php?pid=777255#p777255||forum.ru-board.com/topic.cgi?forum=5&topic=50187&start=1640#21 //addEventListener('keydown',e=>{if(e.ctrlKey&&!e.altKey&&!e.shiftKey&&(e.keyCode==70)&&!gFindBar.hidden){e.preventDefault();gFindBar.close();}}); //"KeyF":()=>{if(e.ctrlKey&&!e.altKey&&!e.shiftKey&&window.gFindBarInitialized&&!gFindBar.hidden){e.preventDefault();gFindBar.close?.();}}, //LS_Vit//"KeyF":{true_false_false=>{if(!window.gFindBarInitialized||gFindBar.hidden)return;e.preventDefault();gFindBar.close?.();}}, //LS_Vit//"KeyV":{"true_false_false":(e)=>{if(this.skip)return;this.ch.copyString(gURLBar.makeURIReadable(gBrowser.selectedBrowser.currentURI).displaySpec);showBrowserPageActionFeedback(PageActions.actionForID("copyURL"));}}, //addEventListener("keydown",e=>e.ctrlKey&&e.code=="KeyQ"&&!e.shiftKey&&!e.altKey&&e.preventDefault()+RunQT()); //============================================================ (this.keyboardshortcuts={ get skip(){return docShell.isCommandEnabled("cmd_insertText");}, get ch(){delete this.ch;return this.ch=Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);}, init(that){var keydown={ /*test*/"Backquote":{"false_false_false":(e)=>{this.skip||e.preventDefault();gBrowser.loadURI("javascript:(function(bookmarklets)%7Bfor(var%20i=0;i%3Cbookmarklets.length;i++)%7Bvar%20code=bookmarklets%5Bi%5D.url;if(code.indexOf(%22javascript:%22)!=-1)%7Bcode=code.replace(%22javascript:%22,%22%22);eval(code)%7Delse%7Bcode=code.replace(/%5Es+%7Cs+$/g,%22%22);if(code.length%3E0)%7Bwindow.open(code)%7D%7D%7D%7D)(%5B%7Btitle:%22%E7%A0%B4%E9%99%A4%E5%8F%B3%E9%94%AE%E8%8F%9C%E5%8D%95%E9%99%90%E5%88%B6%22,url:%22javascript:function%20applyWin(a)%7Bif(typeof%20a.__nnANTImm__===%5Cx22undefined%5Cx22)%7Ba.__nnANTImm__=%7B%7D;a.__nnANTImm__.evts=%5B%5Cx22mousedown%5Cx22,%5Cx22mousemove%5Cx22,%5Cx22copy%5Cx22,%5Cx22contextmenu%5Cx22%5D;a.__nnANTImm__.initANTI=function()%7Ba.__nnantiflag__=true;a.__nnANTImm__.evts.forEach(function(c,b,d)%7Ba.addEventListener(c,this.fnANTI,true)%7D,a.__nnANTImm__)%7D;a.__nnANTImm__.clearANTI=function()%7Bdelete%20a.__nnantiflag__;a.__nnANTImm__.evts.forEach(function(c,b,d)%7Ba.removeEventListener(c,this.fnANTI,true)%7D,a.__nnANTImm__);delete%20a.__nnANTImm__%7D;a.__nnANTImm__.fnANTI=function(b)%7Bb.stopPropagation();return%20true%7D;a.addEventListener(%5Cx22unload%5Cx22,function(b)%7Ba.removeEventListener(%5Cx22unload%5Cx22,arguments.callee,false);if(a.__nnantiflag__===true)%7Ba.__nnANTImm__.clearANTI()%7D%7D,false)%7Da.__nnantiflag__===true?a.__nnANTImm__.clearANTI():a.__nnANTImm__.initANTI()%7DapplyWin(top);var%20fs=top.document.querySelectorAll(%5Cx22frame,%20iframe%5Cx22);for(var%20i=0,len=fs.length;i%3Clen;i++)%7Bvar%20win=fs%5Bi%5D.contentWindow;try%7Bwin.document%7Dcatch(ex)%7Bcontinue%7DapplyWin(fs%5Bi%5D.contentWindow)%7D;void%200;%22%7D,%7Btitle:%22%E7%A0%B4%E9%99%A4%E9%80%89%E6%8B%A9%E5%A4%8D%E5%88%B6%E9%99%90%E5%88%B6%22,url:%22javascript:(function()%7Bvar%20doc=document;var%20bd=doc.body;bd.onselectstart=bd.oncopy=bd.onpaste=bd.onkeydown=bd.oncontextmenu=bd.onmousemove=bd.onselectstart=bd.ondragstart=doc.onselectstart=doc.oncopy=doc.onpaste=doc.onkeydown=doc.oncontextmenu=null;doc.onselectstart=doc.oncontextmenu=doc.onmousedown=doc.onkeydown=function%20()%7Breturn%20true;%7D;with(document.wrappedJSObject%7C%7Cdocument)%7Bonmouseup=null;onmousedown=null;oncontextmenu=null;%7Dvar%20arAllElements=document.getElementsByTagName(%5Cx27*%5Cx27);for(var%20i=arAllElements.length-1;i%3E=0;i--)%7Bvar%20elmOne=arAllElements;with(elmOne.wrappedJSObject%7C%7CelmOne)%7Bonmouseup=null;onmousedown=null;%7D%7Dvar%20head=document.getElementsByTagName(%5Cx27head%5Cx27)%5B0%5D;if(head)%7Bvar%20style=document.createElement(%5Cx27style%5Cx27);style.type=%5Cx27text/css%5Cx27;style.innerHTML=%5Cx22html,*%7B-moz-user-select:auto!important;%7D%5Cx22;head.appendChild(style);%7Dvoid(0);%7D)();%22%7D%5D)",{triggeringPrincipal:gBrowser.contentPrincipal});}},//Remove the right-click menu restriction "Digit1":{"false_false_false":(e)=>{this.skip||openPreferences();}}, "Digit2":{"false_false_false":(e)=>{this.skip||BrowserPageInfo();}}, "Digit3":{"false_false_false":(e)=>{this.skip||duplicateTabIn(gBrowser.selectedTab,'tab');}}, "Digit4":{"false_false_false":(e)=>{this.skip||gBrowser.loadURI("javascript:(function(){var%20night=function(w){(function(d){var%20css='html{opacity:0.7!important;background:black!important;}body{background:white!important;}';var%20s=d.getElementsByTagName('style');for(var%20i=0,si;si=s[i];i++){if(si.innerHTML==css){si.parentNode.removeChild(si);return}};var%20heads=d.getElementsByTagName('head');if(heads.length){var%20node=d.createElement('style');node.type='text/css';node.appendChild(d.createTextNode(css));heads[0].appendChild(node)}})(w.document);%20for(var%20i=0,f;f=w.frames[i];i++){try{arguments.callee(f)}catch(e){}}};night(window)})();",{triggeringPrincipal:gBrowser.contentPrincipal});}},//Night mode "Digit5":{"false_false_false":(e)=>{this.skip||gBrowser.loadURI("javascript:(function(){var EnRuT=[['щ','shh'],['Щ','Shh'],['Щ','SHH'],['х','hh'],['Х','Hh'],['Х','HH'],['ж','zh'],['Ж','Zh'],['Ж','ZH'],['ц','cz'],['Ц','Cz'],['Ц','CZ'],['ю','yu'],['Ю','Yu'],['Ю','YU'],['ё','yo'],['Ё','Yo'],['Ё','YO'],['я','ya'],['Я','Ya'],['Я','YA'],['ч','ch'],['Ч','Ch'],['Ч','CH'],['ш','sh'],['Ш','Sh'],['Ш','SH'],['э','e`'],['Э','E`'],['ы','y'],['Ы','Y'],['ъ','``'],['ь','`'],['р','r'],['т','t'],['у','u'],['и','i'],['о','o'],['п','p'],['а','a'],['с','s'],['д','d'],['ф','f'],['г','g'],['й','j'],['к','k'],['л','l'],['з','z'],['х','x'],['ц','c'],['в','v'],['б','b'],['н','n'],['м','m'],['Р','R'],['Т','T'],['У','U'],['И','I'],['О','O'],['П','P'],['А','A'],['С','S'],['Д','D'],['Ф','F'],['Г','G'],['Й','J'],['К','K'],['Л','L'],['З','Z'],['Х','X'],['Ц','C'],['В','V'],['Б','B'],['Н','N'],['М','M'],['е','e'],['Е','E']],A=document.activeElement;A.onkeyup=function ftr(){for(var s=A.value,i=0;i<EnRuT.length;i++){s=s.replace(RegExp(EnRuT[i][1],'g'),EnRuT[i][0])};A.value=s}})()",{triggeringPrincipal:gBrowser.contentPrincipal});}},//AutoTranslit- https://forum.ru-board.com/topic.cgi?forum=5&topic=46779&start=320#15 "F3":{"false_false_false":(e)=>{e.preventDefault();var s=prompt('Google_ site:.. ..','');if(s.length>0)gBrowser.addTrustedTab('https://www.google.com/search?q=site:'+encodeURIComponent(gBrowser.currentURI.host)+' '+encodeURIComponent(s));}}, "F2":{"false_false_false":(e)=>{gBrowser.loadURI("javascript:{d=document;b=d.body;o=d.createElement('scri'+'pt');o.setAttribute('src','https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit');o.setAttribute('type','text/javascript');b.appendChild(o);v=b.insertBefore(d.createElement('div'),b.firstChild);v.id='google_translate_element';v.style.display='none';p=d.createElement('scri'+'pt');p.text='function%20googleTranslateElementInit(){new%20google.translate.TranslateElement({pageLanguage:%22%22},%22google_translate_element%22);}';p.setAttribute('type','text/javascript');b.appendChild(p);}void%200",{triggeringPrincipal:gBrowser.contentPrincipal});}}, "KeyP":{"false_true_false" :(e)=>{OpenBrowserWindow({private:true});}}, "KeyS":{"true_true_false" :(e)=>{FileUtils.getFile('UChrm',['user_chrome_files','_Local','.Ev','Everything.exe']).launch();}}, "KeyU":{"true_true_false" :(e)=>{FileUtils.getFile('UChrm',['user_chrome_files','_Local','_ultrasurf.exe']).launch();}}, "KeyV":{"false_false_false":(e)=>{if(this.skip)return;this.ch.copyString(gURLBar.makeURIReadable(gBrowser.currentURI).displaySpec);showBrowserPageActionFeedback(PageActions.actionForID("copyURL"));}}, "KeyB":{"true_false_false" :(e)=>{e.preventDefault();gBrowser.toggleMuteAudioOnMultiSelectedTabs(gBrowser.selectedTab);}}, "KeyF":{"true_true_false" :(e)=>{FileUtils.File('D:\\.L\\_Soft\\-Port\\_Photo\\ShareX\\ShareX.exe').launch();}, "true_false_false"(e){if(!gFindBar.hidden){e.preventDefault();gFindBar.close();}}}, "KeyQ":{"true_false_false" :(e)=>{FileUtils.getFile('UChrm',['user_chrome_files','_Local','.QT','QTranslate.exe']).launch();},//Ctrl+Q "true_true_false"(e,nocache=false)//Ctrl+Alt+Q {var cancelQuit=Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(cancelQuit,"quit-application-requested","restart"); if(cancelQuit.data)return false; if(nocache)Services.appinfo.invalidateCachesOnRestart(); var restart=Services.startup; restart.quit(restart.eAttemptQuit|restart.eRestart);}, "true_true_true"(e){this["true_true_false"](e,true);}},//Ctrl+Alt+Shift+Q //"true_false_true"(e){if(AppConstants.platform=="linux")this["true_true_false"](e,true);}},//Ctrl+Shift+Q для linux //(this.keyboardshortcuts={ //init(that){var keydown={ handleEvent(e){if(AppConstants.platform !="macosx"){ (this.handleEvent=e=>{this[e.code]?.[`${e.ctrlKey}_${e.altKey}_${e.shiftKey}`]?.(e);})(e);return;} (this.handleEvent=e=>{this[e.code]?.[`${e.metaKey}_${e.altKey}_${e.shiftKey}`]?.(e);})(e);},}; // "KeyQ":{"true_false_false":(e)=>{}, // "000Digit2"(e){}, //this.handleEvent=e=>this[String(+e.ctrlKey) + +e.shiftKey + +e.altKey + e.code]?.(e);}, "000Digit2"(e){this.skip||BrowserPageInfo();},.. } document.addEventListener("keydown",keydown,true); this.destructor=()=>document.removeEventListener("keydown",keydown,true); that.unloadlisteners.push("keyboardshortcuts");}, }).init(this); /*(ucf.keyboardshortcuts={ ||Dumby|| init(){ windowRoot.addEventListener("keydown",this,true); ucf.unloadlisteners.push("keyboardshortcuts"); this.destructor=()=>windowRoot.removeEventListener("keydown",this,true); this.handleEvent=e=>this[String(+e.ctrlKey) + +e.shiftKey + +e.altKey + e.code]?.(e);}, "000Digit2"(e){this.skip||BrowserPageInfo();},.. }).init(); _//_// */ Заработал первый и второй код, ошибка была в пути к файлу. |
_zt > 15-05-2023 01:14:45 |
Dumby пишет
Я потом уже понял что не нужна. Поспешил. Почему то подумал, что он в принципе нужен и без него значок не выведется. Dumby пишет
Я так понял, что это вместо (subject, topic)... , так как если перед, то таймаут опять не работает. |
xrun1 > 15-05-2023 19:55:44 |
_zt |
_zt > 15-05-2023 23:20:20 |
xrun1 |
miirrr > 17-05-2023 08:50:41 |
Помогите пожалуйста запустить нижнюю панель начинающему, ткните мордой в инструкцию) |
kokoss > 17-05-2023 09:54:46 |
miirrr пишет
https://forum.mozilla-russia.org/viewtopic.php?pid=802991#p802991 |
unter_officer > 17-05-2023 13:21:28 |
miirrr пишет
Я вчера скинул вам архив со всеми внесёнными правками. Вы его установили или какой-то другой вариант UCF? P.S. Да, я вчера написал, что этот архив для Firefox версии 113. Просто у меня вчера не было возможности проверить на предыдущей версии. |
miirrr > 17-05-2023 14:56:36 |
kokoss, unter_officer огромное спасибо. Скачал сейчас 113, сразу запустилось все. Еще один вопрос, возможно ли на нижнюю или боковую ставить закладки и вкладки? |
_zt > 17-05-2023 20:38:44 |
miirrr |
miirrr > 18-05-2023 08:25:40 |
_zt |
_zt > 18-05-2023 16:46:26 |
miirrr |
xrun1 > 18-05-2023 18:38:32 |
miirrr пишет
Закладки и вкладки нельзя перетащить на доп.панели. Только кнопки. |
kokoss > 18-05-2023 18:50:42 |
xrun1 пишет
Закладки можно, только скопом. |
_zt > 18-05-2023 18:56:15 |
xrun1 пишет
Да ну!? Не знал. Видимо именно поэтому у меня закладки уже несколько лет живут на дополнительной панели. |
xrun1 > 18-05-2023 19:46:29 |
kokoss пишет
И как я этот скоп закладок могу выделить? _zt пишет
В обычной жизни ничего на доп.панели не добавляется, кроме кнопок. Проверял на чистом профиле на крайней портабельной. miirrr спросил, я ответил. Если у Вас есть личные хаки - в студию. |
_zt > 18-05-2023 20:12:53 |
xrun1 |
xrun1 > 18-05-2023 20:26:24 |
_zt пишет
Это кнопка. Вопрос был про отдельно взятую закладку, как на панели закладок: папки и закладки. На доп.панелях так сделать невозможно. 18-05-2023 20:29:41 |
kokoss > 18-05-2023 21:03:10 |
xrun1 пишет
Это все элементы панели закладок разом, а miirrr видимо нужно было переместить некоторые закладки, а это я не в курсе как сделать! |
_zt > 18-05-2023 23:33:03 |
kokoss пишет
Давайте не будем гадать. miirrr пишет
Какой вопрос, такой ответ и этот ответ был: _zt пишет
xrun1 пишет
Это не кнопка, это "Элементы панели закладок", т.е. все закладки панели закладок. |
kokoss > 18-05-2023 23:52:37 |
_zt пишет
Давайте |
b0ttle > 19-05-2023 19:49:43 |
del |
miirrr > 19-05-2023 22:27:57 |
Сделал я эти панели, и нижнюю и боковую в надежде, Ребята, вы помогали и советами и разными дополнениями, много за эти дни переделал. Уменьшил расстояние контекстных менюшее и увеличил шрифт. Еще убрать бы надпись в Адресной строке "Ищите с помощью... |
unter_officer > 19-05-2023 22:52:31 |
miirrr пишет
Попробуйте такой стиль (в userChrome.css): |
kokoss > 19-05-2023 23:04:34 |
miirrr пишет
С этим в профильную тему -> https://forum.mozilla-russia.org/viewto … 46#p805146 |
Dobrov > 20-05-2023 15:20:47 |
Обновил UserChromeFiles и Demo-ПРОФИЛЬ для Firefox 84+ Если оформление браузера «неправильное», скачайте aris-t2 стиль, соответствующий вашей версии Firefox. Дополнил диалог UCF-настроек, добавил опции: 1 Простой режим и подсказки кнопок |
Dobrov > 24-05-2023 01:28:38 |
Dumby - проблема с подсказками в твоём оригинальном скрипте перехвата кликов Выделить код Код:get "titlebar-button titlebar-close"() { return j( `Закрыть Firefox`, `◨ пр. клик ⇲ Свернуть`); }, …………… var root = document.getElementById("navigator-toolbox"); …………… var onMouseenter = e => { var trg = e.target, id = trg.id || trg.className; console.log('id= «'+ id + '» '+ Math.random()); var hint = tooltips[id] || tooltips[(trg = trg.parentNode).id]; клики добавлять не стал, они в моём расширеном скрипте ucf_hookClicks.js |
doud > 24-05-2023 14:32:48 |
Был такой cкрипт для скрытия в Библиотеке, из списка в левой части, строчек "Журнал", "Загрузки", "Метки", "Все закладки" |
Dobrov > 24-05-2023 19:06:37 |
Dumby скрипт сохранения картинки колёсиком на Firefox 113 выдаёт ошибку: Посмотрите, может исправите! |
Dumby > 25-05-2023 00:43:42 |
Dobrov пишет
У меня и в каком-нибудь Firefox 97 подсказка не меняется.
Это потому, что в internalSave() снова изменились аргументы. doud пишет
Ты совсем не понимаешь что скрипт делает. Теоретически, можно было бы создать папку, //.replace("RESULTS_AS_LEFT_PANE_QUERY", "RESULTS_AS_ROOTS_QUERY")); Но, безотносительно кода, насколько я вижу, само наличие такой папки — есть мина! |
Dobrov > 25-05-2023 02:24:49 |
Dumby пишет
На Линуксе и Маке подсказки меняются без проблем, может есть какой-то трюк и для Windows ? Dumby пишет
ClickPicSave cделал, как у тебя для saveURL(...args), картинку сохраняет. Dumby – проверь, может неправильно ? Выделить код Код:var args = [url, null, // document …………… win.document.nodePrincipal]; var {length} = win.internalSave, lfix = length > 15; lfix && args.splice(1, 0, null); |
_zt > 27-05-2023 22:22:51 |
Dumby |
Dumby > 28-05-2023 13:18:43 |
_zt пишет
Мне предлагается угадать, Угадатель из меня никакой. |
_zt > 28-05-2023 13:23:49 |
Dumby |
Dumby > 02-06-2023 15:24:08 |
egorsemenov06 Если бы иметь уверенность, что exe'шник будет Но ведь он может быть запущен в любой момент иным способом, скрытый текст Выделить код Код:(async url => { var path = ".......\\opera-proxy.windows-386.exe"; var icons = [ 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><rect fill="limegreen" x="0" y="0" width="16" height="16"/></svg>', 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><rect fill="red" x="0" y="0" width="16" height="16"/></svg>' ]; var labels = [ "Active", "Not Active" ]; var tooltips = [ "Active", "Not Active" ]; var type = "network.proxy.type"; try {var exp = ChromeUtils.importESModule(url + "sys.mjs");} catch {exp = ChromeUtils.import(url + "jsm");} exp.PageActions.addAction(new exp.PageActions.Action({ title: labels[1], iconURL: icons[1], pinnedToUrlbar: true, id: "ucf-opera-proxy", onPlacedInUrlbar(node) { var pref = Services.prefs.getIntPref(type) == 1, proc, active; var upd = () => { var state = pref && Boolean(proc); if (state == active) return; var ind = +!(active = state); this.setIconURL(icons[ind]); this.setTitle(labels[ind]); this.setTooltip(tooltips[ind]); } this["nsPref:changed"] = () => upd( pref = Services.prefs.getIntPref(type) == 1 ); this["process-finished"] = this["process-failed"] = () => upd(proc = null); this["quit-application-granted"] = t => { Services.obs.removeObserver(this, t); Services.prefs.removeObserver(type, this); proc?.kill(); } this.observe = (s, topic) => this[topic](topic); Services.prefs.addObserver(type, this); Services.obs.addObserver(this, "quit-application-granted"); var {id} = node; var style = `#${id} {display: flex !important;}\n` + `@media (max-width: 680px) {#${id} {visibility: collapse !important;}}`; (this.onPlacedInUrlbar = this._onPlacedInUrlbar = node => { var sheet = new node.ownerGlobal.CSSStyleSheet(); sheet.replaceSync(style); node.ownerDocument.adoptedStyleSheets.push(sheet); })(node); var run = () => { var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); (run = () => { proc = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); //proc.startHidden = true; try {proc.init(file); proc.runwAsync([], 0, this);} catch {proc = null;} upd(); })(); } this._onCommand = () => { if (active) Services.prefs.setIntPref(type, 0), proc.kill(); else pref || Services.prefs.setIntPref(type, 1), proc || run(); } } })); })("resource:///modules/PageActions."); |
_zt > 03-06-2023 15:26:57 |
egorsemenov06 пишет
С некоторой задежкой. |
Dumby > 04-06-2023 15:19:36 |
_zt пишет
скрытый текст Выделить код Код:/* this._onCommand = () => { */ var timeout = 1500; var tid, oldState, reload = (gb, tab, state) => { tid = null; active != state && gb.reloadTab(tab); } this._onCommand = e => { tid ? clearTimeout(tid) : oldState = active; var gb = e.view.gBrowser; tid = setTimeout(reload, timeout, gb, gb.selectedTab, oldState); |
Dumby > 04-06-2023 18:05:23 |
egorsemenov06 пишет
Всё правильно. Например, когда Active, если снаружи переключить только настройку,
Ну почему же, вполне возможно. |
_zt > 04-06-2023 20:42:31 |
Dumby |
Viatcheslav > 12-06-2023 09:14:37 |
Друзья, поделитесь, пожалуйста, настроенным комплектом UCF версии от 2021-9-23 |
_zt > 12-06-2023 09:29:35 |
Viatcheslav |
b0ttle > 17-06-2023 18:29:12 |
Как сюда добавить хоткей? Не хочется лишний раз дублировать код. Там что-то такое: ucf_hookClicks.js Выделить код Код:128(){ //Clean Cache var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart"); if (cancelQuit.data) return false; Services.appinfo.invalidateCachesOnRestart(); var restart = Services.startup; restart.quit(restart.eAttemptQuit|restart.eRestart); }, [upd:] Получилось, спасибо. |
Dobrov > 18-06-2023 02:04:50 |
b0ttle пишет
Если подразумевается ucf_hookClicks.js в шапке, то в нём подробные комментарии, добавляйте перехват клавиш по аналогии с двумя существующими: Выделить код Код:var keydown_win = e => { // нажатие клавиш if (e.keyCode == 83 && e.altKey) { console.log("Alt+S" + Math.random()); } if (e.keyCode == 88 && e.altKey){ console.log("Alt+X"); } } |
Viatcheslav > 21-06-2023 18:11:12 |
Содержание файла config.js (для отключения проверки цифровых подписей дополнений) для версии 102 и выше такое: config.js для Firefox версии 102 и выше Выделить код Код:// try {(jsval => { var dbg, gref, genv = func => { var sandbox = new Cu.Sandbox(g, {freshCompartment: true}); Cc["@mozilla.org/jsdebugger;1"].createInstance(Ci.IJSDebugger).addClass(sandbox); (dbg = new sandbox.Debugger()).addDebuggee(g); gref = dbg.makeGlobalObjectReference(g); return (genv = func => func && gref.makeDebuggeeValue(func).environment)(func); } var g = Cu.getGlobalForObject(jsval), o = g.Object, {freeze} = o, disleg; var AC = "AppConstants", uac = `resource://gre/modules/${AC}.`; var lexp = () => lockPref("extensions.experiments.enabled", true); if (o.isFrozen(o)) { // Fx 102.0b7+ lexp(); disleg = true; var env, def = g.ChromeUtils.defineModuleGetter; g.ChromeUtils.defineModuleGetter = (...args) => { try { genv(); dbg.addDebuggee(globalThis); var e = dbg.getNewestFrame().older.environment; var obj = e.parent.type == "object" && e.parent.object; if (obj && obj.class.startsWith("N")) // JSM, NSVO obj.unsafeDereference().Object = { freeze: ac => (ac.MOZ_REQUIRE_SIGNING = false) || freeze(ac) }; else env = e; // ESM, Lexy "var"(?) } catch(ex) {Cu.reportError(ex);} (g.ChromeUtils.defineModuleGetter = def)(...args); } ChromeUtils.import(uac + "jsm"); // (?) env && env.setVariable(AC, gref.makeDebuggeeValue(freeze(o.assign( new o(), env.getVariable(AC).unsafeDereference(), {MOZ_REQUIRE_SIGNING: false} )))); } else o.freeze = obj => { if (!Components.stack.caller.filename.startsWith(uac)) return freeze(obj); obj.MOZ_REQUIRE_SIGNING = false; if ((disleg = "MOZ_ALLOW_ADDON_SIDELOAD" in obj)) lexp(); else obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true, lockPref("extensions.legacy.enabled", true); return (o.freeze = freeze)(obj); } lockPref("xpinstall.signatures.required", false); lockPref("extensions.langpacks.signatures.required", false); var useDbg = true, xpii = "resource://gre/modules/addons/XPIInstall.jsm"; if (Ci.nsINativeFileWatcherService) { // Fx < 100 jsval = Cu.import(xpii, {}); var shouldVerify = jsval.shouldVerifySignedState; if (shouldVerify.length == 1) useDbg = false, jsval.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon); } if (useDbg) { jsval = g.ChromeUtils.import(xpii); var env = genv(jsval.XPIInstall.installTemporaryAddon); var ref = name => {try {return env.find(name).getVariable(name).unsafeDereference();} catch {}} jsval.XPIDatabase = (ref("lazy") || {}).XPIDatabase || ref("XPIDatabase"); var proto = ref("Package").prototype; var verify = proto.verifySignedState; proto.verifySignedState = function(id) { return id ? {cert: null, signedState: undefined} : verify.apply(this, arguments); } dbg.removeAllDebuggees(); } if (disleg) jsval.XPIDatabase.isDisabledLegacy = () => false; })( "permitCPOWsInScope" in Cu ? Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}) : Cu );} catch(ex) {Cu.reportError(ex);} А для работы комплекта UCF такое: config.js для UCF Выделить код Код:// (async () => { var sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal), { wantComponents: true, sandboxName: "UserChromeFiles", wantGlobalProperties: ["ChromeUtils"], }); Cu.evalInSandbox(` var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var user_chrome_files_sandbox = { init() { Services.obs.addObserver(this, "domwindowopened"); Services.obs.addObserver(this, "profile-after-change"); }, observe(aWindow, aTopic, aData) { Services.obs.removeObserver(this, "profile-after-change"); this.observe = (window, topic, data) => { if (!(window instanceof Ci.nsIDOMChromeWindow)) return; var docElementInserted = e => { var win = e.target.defaultView; if (win instanceof Ci.nsIDOMChromeWindow) user_chrome.initWindow(win); }; window.windowRoot.addEventListener("DOMDocElementInserted", docElementInserted, true); window.addEventListener("load", e => { window.addEventListener("unload", e => { window.windowRoot.removeEventListener("DOMDocElementInserted", docElementInserted, true); }, { once: true }); }, { once: true }); }; var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("user_chrome_files"); file.append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) { this.removeObs(); return; } try { Components.manager.QueryInterface(Ci.nsIComponentRegistrar) .autoRegister(file); Services.scriptloader.loadSubScript("chrome://user_chrome_files/content/user_chrome.js", globalThis, "UTF-8"); } catch(ex) { this.removeObs(); return; } if (aTopic === "domwindowopened") this.observe(aWindow, aTopic, aData); }, removeObs() { Services.obs.removeObserver(this, "domwindowopened"); }, }; user_chrome_files_sandbox.init(); `, sandbox); })(); // lockPref("xpinstall.signatures.required", false); // lockPref("extensions.experiments.enabled", true); // lockPref("extensions.langpacks.signatures.required", false); Можно ли совместить содержимое и использовать одновременно? Или... как правильно? Спасибо за помощь |
Farby > 21-06-2023 21:01:37 |
Viatcheslav пишет
а разве так можно???!!! скрытый текст Выделить код Код:// try {(jsval => { var dbg, gref, genv = func => { var sandbox = new Cu.Sandbox(g, {freshCompartment: true}); Cc["@mozilla.org/jsdebugger;1"].createInstance(Ci.IJSDebugger).addClass(sandbox); (dbg = new sandbox.Debugger()).addDebuggee(g); gref = dbg.makeGlobalObjectReference(g); return (genv = func => func && gref.makeDebuggeeValue(func).environment)(func); } var g = Cu.getGlobalForObject(jsval), o = g.Object, {freeze} = o, disleg; var AC = "AppConstants", uac = `resource://gre/modules/${AC}.`; var lexp = () => lockPref("extensions.experiments.enabled", true); if (o.isFrozen(o)) { // Fx 102.0b7+ lexp(); disleg = true; var env, def = g.ChromeUtils.defineModuleGetter; g.ChromeUtils.defineModuleGetter = (...args) => { try { genv(); dbg.addDebuggee(globalThis); var e = dbg.getNewestFrame().older.environment; var obj = e.parent.type == "object" && e.parent.object; if (obj && obj.class.startsWith("N")) // JSM, NSVO obj.unsafeDereference().Object = { freeze: ac => (ac.MOZ_REQUIRE_SIGNING = false) || freeze(ac) }; else env = e; // ESM, Lexy "var"(?) } catch(ex) {Cu.reportError(ex);} (g.ChromeUtils.defineModuleGetter = def)(...args); } ChromeUtils.import(uac + "jsm"); // (?) env && env.setVariable(AC, gref.makeDebuggeeValue(freeze(o.assign( new o(), env.getVariable(AC).unsafeDereference(), {MOZ_REQUIRE_SIGNING: false} )))); } else o.freeze = obj => { if (!Components.stack.caller.filename.startsWith(uac)) return freeze(obj); obj.MOZ_REQUIRE_SIGNING = false; if ((disleg = "MOZ_ALLOW_ADDON_SIDELOAD" in obj)) lexp(); else obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true, lockPref("extensions.legacy.enabled", true); return (o.freeze = freeze)(obj); } lockPref("xpinstall.signatures.required", false); lockPref("extensions.langpacks.signatures.required", false); var useDbg = true, xpii = "resource://gre/modules/addons/XPIInstall.jsm"; if (Ci.nsINativeFileWatcherService) { // Fx < 100 jsval = Cu.import(xpii, {}); var shouldVerify = jsval.shouldVerifySignedState; if (shouldVerify.length == 1) useDbg = false, jsval.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon); } if (useDbg) { jsval = g.ChromeUtils.import(xpii); var env = genv(jsval.XPIInstall.installTemporaryAddon); var ref = name => {try {return env.find(name).getVariable(name).unsafeDereference();} catch {}} jsval.XPIDatabase = (ref("lazy") || {}).XPIDatabase || ref("XPIDatabase"); var proto = ref("Package").prototype; var verify = proto.verifySignedState; proto.verifySignedState = function(id) { return id ? {cert: null, signedState: undefined} : verify.apply(this, arguments); } dbg.removeAllDebuggees(); } if (disleg) jsval.XPIDatabase.isDisabledLegacy = () => false; })( "permitCPOWsInScope" in Cu ? Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}) : Cu );} catch(ex) {Cu.reportError(ex);} // (async () => { var sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal), { wantComponents: true, sandboxName: "UserChromeFiles", wantGlobalProperties: ["ChromeUtils"], }); Cu.evalInSandbox(` var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var user_chrome_files_sandbox = { init() { Services.obs.addObserver(this, "domwindowopened"); Services.obs.addObserver(this, "profile-after-change"); }, observe(aWindow, aTopic, aData) { Services.obs.removeObserver(this, "profile-after-change"); this.observe = (window, topic, data) => { if (!(window instanceof Ci.nsIDOMChromeWindow)) return; var docElementInserted = e => { var win = e.target.defaultView; if (win instanceof Ci.nsIDOMChromeWindow) user_chrome.initWindow(win); }; window.windowRoot.addEventListener("DOMDocElementInserted", docElementInserted, true); window.addEventListener("load", e => { window.addEventListener("unload", e => { window.windowRoot.removeEventListener("DOMDocElementInserted", docElementInserted, true); }, { once: true }); }, { once: true }); }; var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("user_chrome_files"); file.append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) { this.removeObs(); return; } try { Components.manager.QueryInterface(Ci.nsIComponentRegistrar) .autoRegister(file); Services.scriptloader.loadSubScript("chrome://user_chrome_files/content/user_chrome.js", globalThis, "UTF-8"); } catch(ex) { this.removeObs(); return; } if (aTopic === "domwindowopened") this.observe(aWindow, aTopic, aData); }, removeObs() { Services.obs.removeObserver(this, "domwindowopened"); }, }; user_chrome_files_sandbox.init(); `, sandbox); })(); // lockPref("xpinstall.signatures.required", false); // lockPref("extensions.experiments.enabled", true); // lockPref("extensions.langpacks.signatures.required", false); |
b0ttle > 23-06-2023 00:25:51 |
Viatcheslav пишет
А для чего отключать проверку цифровых подписей дополнений? Для CB? Им еще пользуются? |
Viatcheslav > 23-06-2023 05:05:55 |
b0ttle пишет
Для возможности установки неподписанных расширений, а также не из АМО. |
_zt > 28-06-2023 18:33:00 |
b0ttle пишет
Гениальный вопрос. b0ttle пишет
А вы в соответствующую тему зайдите и там ляпните это. |
doud > 03-07-2023 10:46:13 |
_zt |
_zt > 03-07-2023 12:18:37 |
doud |
Dumby > 03-07-2023 16:26:39 |
doud пишет
Хмм, left mousedown и right click сойдёт? скрытый текст Выделить код Код:(async code => { await delayedStartupPromise; var btn = document.getElementById("unified-extensions-button"); btn.setAttribute("onmousedown", code); var toggle = gUnifiedExtensions.togglePanel.bind(gUnifiedExtensions, new MouseEvent("mousedown")); btn.oncontextmenu = () => !toggle(); var ttt = btn.tooltipText = [ "Left Mousedown: about:addons", "Ctrl + Left Mousedown: about:debugging#/runtime/this-firefox", "Contextmenu: Unified Extensions Panel" ].join("\n"); var args = ["aftercustomization", () => btn.tooltipText = ttt]; gNavToolbox.addEventListener(...args); addEventListener("unload", () => gNavToolbox.removeEventListener(...args), {once: true}); })(`if (!event.button) gBrowser.selectedTab = gBrowser.addTrustedTab( "about:" + (event.ctrlKey ? "debugging#/runtime/this-firefox" : "addons") );`); |
doud > 03-07-2023 16:40:40 |
Dumby |
vassemm > 06-07-2023 18:03:21 |
Добрый день! Прошу помощи. В 116-117 нет даже значка UCF. |
unter_officer > 06-07-2023 18:48:20 |
vassemm пишет
Попробовал запустить 116 Beta 1. Действительно не работает. Консоль ругается на файл config.js. |
Dumby > 06-07-2023 20:34:18 |
unter_officer пишет
Это Bug 1522052 - Remove nsIDOMChromeWindow Можно заменить все (два) « instanceof Ci.nsIDOMChromeWindow» на «.isChromeWindow» На Win7, я Firefox 117 уже только распаковкой смог поставить. |
Viatcheslav > 06-07-2023 20:57:51 |
Друзья, поделитесь, пожалуйста, рабочим в 114 |
vassemm > 06-07-2023 21:01:59 |
Dumby пишет
Благодарю. |
unter_officer > 06-07-2023 21:11:44 |
Dumby пишет
Большое спасибо! 06-07-2023 21:16:32 Viatcheslav пишет
Если ничего не путаю, то вот: https://forum.mozilla-russia.org/viewto … 52#p793152 |
Viatcheslav > 06-07-2023 23:55:05 |
unter_officer пишет
Спасибо большое, но... Всё время показывает дефолтную иконку. |
_zt > 07-07-2023 00:43:38 |
Viatcheslav скрытый текст Выделить код Код:// FavIcon in URL-bar - Иконка сайта в url-баре // https://forum.mozilla-russia.org/viewtopic.php?pid=789469#p789469 (this.faviconinurlbar = { init(that) { var identity = document.querySelector("#identity-icon"); if (!identity) return; var iconDefault = "chrome://user_chrome_files/content/custom_styles/png/globe-16.png"; // или свою иконку var style = "data:text/css;charset=utf-8," + encodeURIComponent(` #identity-faviconinurlbar { --v-faviconinurlbar-default: url("${iconDefault}"); list-style-image: var(--v-faviconinurlbar, none) !important; pointer-events: none !important; height: 16px !important; width: auto !important; margin-inline-start: 4px !important; -moz-context-properties: fill, fill-opacity; fill: currentColor; fill-opacity: var(--urlbar-icon-fill-opacity, 1); } #identity-faviconinurlbar:not([faviconinurlbar="true"]), #identity-faviconinurlbar[favbusy="true"] { --v-faviconinurlbar: var(--v-faviconinurlbar-default) !important; } #identity-faviconinurlbar[faviconchrome="true"], #urlbar[actiontype="extension"] #identity-faviconinurlbar, #identity-box:is(.extensionPage,.chromeUI,.localResource) #identity-faviconinurlbar, #urlbar:not(.searchButton) #identity-box[pageproxystate="invalid"] #identity-faviconinurlbar { display: none !important; } `); windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); var faviconinurlbar = document.createXULElement("image"); faviconinurlbar.id = "identity-faviconinurlbar"; identity.after(faviconinurlbar); gBrowser.tabContainer.addEventListener("TabAttrModified", this); gBrowser.addProgressListener(this); that.unloadlisteners.push("faviconinurlbar"); var {STATE_START, STATE_STOP, STATE_IS_NETWORK} = Ci.nsIWebProgressListener; var updatefavicon = image => { if (image) { faviconinurlbar.style.setProperty("--v-faviconinurlbar", `url("${image}")`); faviconinurlbar.setAttribute("faviconinurlbar", "true"); faviconinurlbar.setAttribute("faviconchrome", `${image.startsWith("chrome:")}`); } else { faviconinurlbar.setAttribute("faviconinurlbar", "false"); faviconinurlbar.style.setProperty("--v-faviconinurlbar", ""); } }; this.handleEvent = e => { var tab = e.target, changed; if (!tab.selected || !((changed = e.detail.changed).includes("image") || changed.includes("selected"))) return; updatefavicon(tab.image); }; this.onStateChange = (aWebProgress, aRequest, aStateFlags, aStatus) => { if (aStateFlags & STATE_IS_NETWORK && aWebProgress?.isTopLevel) { if (aStateFlags & STATE_START) faviconinurlbar.setAttribute("favbusy", "true"); else if (aStateFlags & STATE_STOP) { faviconinurlbar.setAttribute("favbusy", "false"); updatefavicon(gBrowser.selectedTab.image); } } }; }, destructor() { gBrowser.tabContainer.removeEventListener("TabAttrModified", this); gBrowser.removeProgressListener(this); } }).init(this); |
Viatcheslav > 07-07-2023 09:59:38 |
_zt пишет
Наверное... |
_zt > 07-07-2023 19:51:45 |
Viatcheslav Они разные, может и подключать по разному надо, у меня в CustomStylesScripts.jsm
Это аналог custom_script_win.js после секции ... Выделить код Код:load() { if (this.initialized) return; this.initialized = true; /* ************************************************ */ тут коды или импорт Импорт раньше у меня такой был ... скрытый текст Выделить код Код:// Для скриптов отдельными файлами (см. примеры) // С уточнением в каком "документе" работать // https://forum.mozilla-russia.org/viewtopic.php?pid=788301#p788301 (async () => { var loadscript = (relpath, obj) => { try { Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${relpath}`, obj, "UTF-8"); return true; } catch(e) { } return false; }, load_scripts_by_url = { browser: win => { //>>>>>>>>>>| Блок требуется для боковой панели и т.п. |>>>>>>>>>> var box = document.querySelector("#browser") || window; var listener = e => { var doc = e.target || ({}); load_scripts_by_url[doc.documentURI]?.(doc.defaultView); }; box.addEventListener("pageshow", listener); this.loadscriptswinandsidebar = { destructor() { box.removeEventListener("pageshow", listener); } }; this.unloadlisteners.push("loadscriptswinandsidebar"); /* <<<<<<<<<<<<<<<<<<<< */ //>>>>>>>>>>| Загрузка скриптов для browser.xhtml |>>>>>>>>>> // Здесь скрипты для основного окна loadscript("custom_js_win/ucf_Bookmarks_Star_Tooltip_Helper.uc.js", win); loadscript("custom_js_win/ucf_Context_Menu_Open_With.us.js", this) && this.unloadlisteners.push("contextmenuopenwith"); loadscript("custom_js_win/ucf_FavIcon_In_URL-bar.uc.js", this); loadscript("custom_js_win/ucf_Open_Hisory_Bookmark_In_NewTab.uc.js", win) && win.ucf_where_to_open_link.browser(); loadscript("custom_js_win/ucf_SidebarTabs.us.js", this) && this.unloadlisteners.push("sidebar_tabs"); // и т.д. //<<<<<<<<<<<<<<<<<<<< }, //>>>>>>>>>>| Загрузка скриптов для др. документов |>>>>>>>>>> "chrome://browser/content/places/bookmarksSidebar.xhtml": win => { // Здесь скрипты для боковой панели закладок loadscript("custom_js_win/s_AutoCloseBookMarkFolder_Fx37.uc.js", win); loadscript("custom_js_win/ucf_Open_Hisory_Bookmark_In_NewTab.uc.js", win) && win.ucf_where_to_open_link.bookmarksSidebar(); // и т.д. }, "chrome://browser/content/places/historySidebar.xhtml": win => { // Здесь скрипты для боковой панели истории loadscript("custom_js_win/s_AutoCloseHistoryFolder_Fx37.uc.js", win); loadscript("custom_js_win/ucf_Open_Hisory_Bookmark_In_NewTab.uc.js", win) && win.ucf_where_to_open_link.historySidebar(); // и т.д. }, //<<<<<<<<<<<<<<<<<<<< }; load_scripts_by_url.browser(window); })(); Понятия не имею бкдет ли оно сейчас работать. |
Viatcheslav > 07-07-2023 20:19:08 |
_zt пишет
Это для старой версии UCF |
unter_officer > 10-07-2023 13:38:30 |
Dumby скрытый текст Выделить код Код:// // Dumby: https://forum.mozilla-russia.org/viewtopic.php?pid=801497#p801497 // (async sep => { if (!sep) return; var key = "hasRemoveTransaction"; var g = Cu.import("resource://gre/modules/PlacesTransactions.jsm", {}); var raws = (g.lazy || g).TransactionsHistory?.proxifiedToRaw; if (raws) g = raws; if (!g[key]) { if (!raws) { Services.scriptloader.loadSubScript( `data:,this.${key}=TransactionsHistory.proxifiedToRaw;`, g ); raws = g[key]; } g[key] = entry => { for(var tr of entry) if (raws.get(tr) instanceof PlacesTransactions.Remove) return true; } } var menuitem = document.createXULElement("menuitem"); for(var args of Object.entries({ closemenu: "single", class: "menuitem-iconic", id: "placesCmd_undoRemove", label: "Восстановить удалённое", oncommand: "PlacesTransactions.undo().catch(Cu.reportError);", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAAEd0lEQVRIx53Ve2yW5RkG8N/7ft8Hxa/9CgjSSDnMA4xVTUMQWzadhzhnjSCC0y0jSjom+JdGp844ZhSjHLJsowaNZoCCHOWglXGoQbo2fBW3obDNUBfXKpsUVhxn6OHdH8+31GXGmL3/3M913ffzPNed93qeBxvmI8umCNjyPFEDSRJw40qKa9jyHSbdzY77Ar+9FTvZ+nHAb9T7P76YcwlOktlBdJia2SSthfRvaR/Mync5tp85Q2mbEHJ/X0bqRTpOBJyehog3C3j1HV9RQP91xG9T8z2SofyphMELWH4zW5s40s7kQ/T0cnYfXfPD1OgM0TlGzSN1DZkzxG1EdURjaa9HCfddEupfuSkIfHXJ5wVENA8Iw9QcRnbzXj31++g8w+WVZHMhXzaKhu2MGMtd36f5CTrn8WAJyf001KCYpA6dDBtLlOfoYuI6kgp6XuLsbhQRfw39ovDPx7/JgYS1b3NkCxcvoPgTevIULyFVTm4jyinp4uRJiirYt5BMLc15kvE0lnCsgZaE2wdx6LVCo9/ghQn4LhdFxEOonELv8ogVV9Iyjd9fx8T1FE2nq5XSQWQuJbsmrJH9JclMsldhFsW3EU0iuxsb6f9zTA3dHj1J1yPsKaPrIOtnkn6KDY2cvYF/vkfmINGuiPdnUD6Pd/7Mur/x0RCqXqTfj+m5glyO1B8ovR1pijeil6KvBw8V1QaB/QYWzNgSYu+TmMm5GVhKT47OBWR28kgnvxvKS/OjvuMGuTSr72FtBR/WctNe4l+H3GUt7DxB2TKe+CmnF5IZRzSZzFmS4wy9n2QGY2eR3Mx193DqAao+4vh04lZS2/EkQyqo7cWux4Kjwf4gKF3N5hEs+QsLlwVuVRPLP2FeTSh95hZSpSx6OOAkwWCWLSEqYWVz4JtLqd3GiuX0/oS6XKjd/BQbF6SRJynij4eJKpl7WSg8cCdzxjHjH3QuIsaorQx7NCx8QQdxCYM2kzxL423BbGN6SP+I6tmcO86hahqu4MA2To3mX+eTxbA2er6VJjcA/Yl2kOzlrutJxrDraaI1XH09j3fQVk7pcG5sCgIOttLVzejpmMPrnxJvYnIZXelwxGHTCOaX0PorsmUMOC/wpeNofg4fjg9EW3+k6CzcYJ99M7h6fSfxFFJrMZzFm0I+fzXxlTQ1EHf3eSlJyI3mlYGs/yEPx4F7/NkQ11zEymFhnDoY9RnwcHmIZ34Q1CcTkBD9FSM58gu8SmUHbmVuJbYRt2AiE/cwZT/tG3h+Gh29lH3A+VPZ+zMq1rHwcq6tY1U31ReQXPgFt3M+/9+xJRvM9f5S3NnX6btLqfqYt1p44xQrFnH0aX6zmBXIj+Hae0N95qG+ea/PJjrB7tV47csE7CzEJqKXyTcW8CquaibfwTOX0FjPLSfYk+G8XWyb+rlTUcndVUQjWXOK+FiBn/QfQen/FVBVVdhoc4FIkczqM5WBvPMWp4fQMpzFHeEN2NCFCcyNSH2b1AiSl3nhVnrnkjpNkqP9jrBvdzX8G2rIlxvMK3a7AAAAInpUWHRTb2Z0d2FyZQAAeNorLy/Xy8zLLk5OLEjVyy9KBwA22AZYEFPKXAAAAABJRU5ErkJggg==", })) menuitem.setAttribute(...args); var desc = Object.getOwnPropertyDescriptor(XULElement.prototype, "hidden"); var {set} = desc; desc.set = () => { var entry = PlacesTransactions.topUndoEntry; var vis = entry && g[key](entry); vis && menuitem.removeAttribute("disabled"); set.call(menuitem, !vis); } Object.defineProperty(menuitem, "hidden", desc); sep.after(menuitem); })(document.getElementById("placesContext_deleteSeparator")); В предыдущих версиях всё работает нормально. Возможно поправить? |
b0ttle > 10-07-2023 14:09:58 |
ucf_hookClicks.js некорректно работает в 115.0.1, где-то нет тултипов, отвалилась подсветка и вся система алертов при копирований адресной строки через identity-box, и еще что-то. Все остальное работает, пока не разобрался что еще отвалилось. |
Dumby > 11-07-2023 08:24:44 |
unter_officer пишет
Да, вижу. Слегка поменяли код. Можно попробовать вообще просто поставить на disabled заглушку скрытый текст Выделить код Код:/* var vis = entry && g[key](entry); vis && menuitem.removeAttribute("disabled"); set.call(menuitem, !vis); } */ set.call(menuitem, !entry || !g[key](entry)); } Object.defineProperty(menuitem, "disabled", {}); Bug 1780695 - «Remove Services.jsm» (Firefox 117+) |
unter_officer > 11-07-2023 14:12:13 |
Dumby пишет
Большое спасибо! |
b0ttle > 11-07-2023 15:32:36 |
Тут тултипы работают в hookClicks, но при запуске firefox почему-то пишет, что файл не запущен, хотя по виду все работает. Странно. |
Dobrov > 12-07-2023 02:31:44 |
b0ttle пишет
на FF114 всё работало. На 115 перехват кликов не работает, базовый hookClicks выдаёт много ошибок в консоли. Dumby - проверьте на Firefox 115 ваш базовый hookClicks, на его основе я делал все доработки для профиля в шапке. |
Dobrov > 12-07-2023 03:18:40 |
Dumby - просьба доработать скрипт, чтобы его запускать по перехвату кликов из любых кнопок: AppMenuTbbSaveHTMLChild.jsm Выделить код Код:/* для UCF CustomStylesScripts.jsm scriptsbackground: [ // В фоне [System Principal] { func: jsmImport("AppMenuTbbSaveHTMLChild.jsm"), }, */ var self, name = "AppMenuTbbSaveHTML", EXPORTED_SYMBOLS = [name + "Child"]; var {io, focus, obs} = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services; class AppMenuTbbSaveHTMLChild extends JSWindowActorChild { receiveMessage() { return htmlAndName(this.contentWindow); } } ChromeUtils.domProcessChild.childID || ({ init(topic) { ChromeUtils.registerWindowActor(name, { allFrames: true, child: {moduleURI: __URI__}, messageManagerGroups: ["browsers"] }); obs.addObserver(self = this, topic); obs.addObserver(function quit(s, t) { obs.removeObserver(quit, t); obs.removeObserver(self, topic); }, "quit-application-granted"); this.handleEvent = e => this[e.type](e); }, observe(win) { win.document.getElementById("appMenu-popup") .addEventListener("popupshowing", this); win.addEventListener("unload", this); }, popupshowing(e) { this.unload(e); var popup = e.target; var btn = popup.ownerDocument.createXULElement("toolbarbutton"); btn.id = "appMenu-ucf-save-html-button"; btn.setAttribute("label", "Страница | выбранное в единый HTML"); var before = "appMenu-save-file-button2", subviewbutton = "subviewbutton"; if ( parseInt(popup.ownerGlobal.Services.appinfo.version) < 89 ) { subviewbutton = "subviewbutton subviewbutton-iconic", before = "appMenu-print-button"; btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAAAAClZ7nPAAAAAXRSTlMAQObYZgAAACNJREFUCNdjYH/AgBX9/89Q/4/B/g+D/A8G/g8gEeYDDIwNAIB7EDCcKCcMAAAAAElFTkSuQmCC"); } btn.className = subviewbutton; btn.setAttribute("oncommand", "saveHTML();"); btn.saveHTML = this.saveHTML; popup.querySelector('toolbarbutton[id^="'+ before +'"]').before(btn); }, unload(e) { var win = e.target.ownerGlobal; win.removeEventListener("unload", this); win.document.getElementById("appMenu-popup").removeEventListener("popupshowing", this); }, async saveHTML() { var win = this.ownerGlobal; var br = win.gBrowser.selectedBrowser; var bc = focus.focusedContentBrowsingContext; if (bc?.top.embedderElement != br) bc = br.browsingContext; var actor = bc?.currentWindowGlobal?.getActor(name); actor && self.save(win, ...await actor.sendQuery("")); }, async save(win, fileContent, fileName) { var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker); fp.init(win, "", fp.modeSave); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); var res = await new Promise(fp.open); if (res == fp.returnOK || res == fp.returnReplace) this.write(fp.file.path, fileContent); }, write(path, html) { if (typeof IOUtils == "object") var write = IOUtils.writeUTF8 || IOUtils.writeAtomicUTF8; // Fx 85+ || 82-84 if (!write) { // Fx 79-81 var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); write = (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt)); } (this.write = write)(path, html); } }).init("browser-delayed-startup-finished"); var htmlAndName = async mainWin => { var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec; } catch {} }; var getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r; } catch(e) {} } }; var encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else { img = obj; }; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }; var toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild); var meta = doc.createElement('meta'); meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); var title = doc.getElementsByTagName('title')[0]; if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; var sheets = doc.styleSheets; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, ''); fileName += (function () { var d = new Date(), z = function(n){return '_' + (n < 10 ? '0' : '') + n}; return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds()); })(); if(!/\.html?$/.test(fileName))fileName += '.html'; return [doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->', fileName]; } Просьба такая - сделать единый скрипт, который работает в зависимости от переданных опций, то есть либо сохраняет в единый HTML с запросом "Куда?", либо сохраняет сразу без запроса в "Загрузки". |
Northtech > 12-07-2023 11:11:18 |
Не знаю в какую тему написать... В FX115 отвалилась кнопка восстановления вкладок после закрытия (не показывает список закрытых вкладок), вроде она относится к расширению add_toolbar_buttons@vitaliy.ru. Можно как-то ее починить? https://dropmefiles.com/XaeKh - расширение скрытый текст |
kokoss > 12-07-2023 11:33:30 |
Northtech Add, надеюсь оно, я просто эту кнопку не использую. |
Northtech > 12-07-2023 11:51:37 |
kokoss |
Dumby > 12-07-2023 12:51:54 |
egorsemenov06 пишет
Это как-то неудобно. Скрипт завязан на контекстное меню, Разве что через буфер обмена. Ну попробуй дописать после строки скрытый текст Выделить код Код:// var translate = async () => { var br = gBrowser.selectedBrowser; var fw = Services.focus.focusedWindow; if (fw == window) { if (document.activeElement != br) return; } else if (fw.browsingContext.top != br.browsingContext) return; var cb = navigator.clipboard; var was = await cb.readText(); if (was) await cb.writeText(""); docShell.doCommand("cmd_copy"); await new Promise(r => setTimeout(r, 100)); var txt = await cb.readText(); if (txt || was) cb.writeText(was); if (!txt && !br.currentURI.scheme.startsWith("http")) return; window.gContextMenu = {selectionInfo: { get fullText() { window.gContextMenu = null; return txt; } }}; ujs_google_translate("auto|ru"); } var ts = 0, destr = this.destructor, args = ["keyup", e => e.key == "Control" && ts - (ts = Cu.now()) > -300 && !e.shiftKey && !e.altKey && translate(ts = 0) ]; addEventListener(...args); this.destructor = () => destr(removeEventListener(...args)); Dobrov пишет
Нет у меня никакого hookClicks, не сочиняй.
Ну я убрал кусок кода if (typeof IOUtils != "object") {…}; В этом куске всё тот же косяк с непониманием работы var. Да, кстати, потерялся var перед str_cut = … и gClipboard конечно, который может перезаписать
Скрипт нельзя «вызвать», только загрузить. Вызвать можно функцию. Это надо что-то в SystemGlobal добавить, чтобы с других мест вызывать. скрытый текст Сначала в init() дописываем globalThis[Symbol.for(name)] = this.saveHTML; Затем, из saveHTML() убираем var win = this.ownerGlobal; и, в последней строке функции, наш аргумент пробрасываем Далее вписываем его и в save() Таким образом, внутри save() теперь можно его использовать Всё. Теперь можно вызывать снаружи, например, с консоли браузера: (() => { Northtech пишет
javascript:void(0); — нет уж, разрешите отказаться. Но наверняка дело в getClosedTabCount Если нужна обратная совместимость, то два |
Northtech > 12-07-2023 13:18:45 |
Dumby
Да я этого и не видел никогда, у меня ublock.
сработало, спасибо. |
6e73epo > 12-07-2023 14:06:35 |
В Firefox 117 не открывается старый about:config. Достаточно ли закомментировать строку с импортом Services.jsm? |
odd74RUS > 15-07-2023 11:25:05 |
После какого-то из недавних обновлений перестал работать скрипт (contextsearch.uc.js), вот он: https://forum.mozilla-russia.org/viewto … 83#p780283 , переключающий поисковые системы в контекстном меню выделенного текста. |
Dobrov > 15-07-2023 12:07:57 |
Dumby пишет
Спасибо за подсказки! Доработал скрипт AppMenuTbbSaveHTMLChild, проверь, может я накосячил где-то… SingleHTMLChild.jsm Выделить код Код:/* SingleHtml by Лекс, правка: Dumby, mod Dobrov для UCF CustomStylesScripts.jsm scriptsbackground: [ // В фоне [System Principal] { func: jsmImport("SingleHTMLChild.jsm"), }, вызов: Cu.getGlobalForObject(Cu)[Symbol.for("SingleHTML")](arg, window) если arg False, то диалог выбора пути сохранения */ var self, name = "SingleHTML", EXPORTED_SYMBOLS = [name + "Child"]; var {io, focus, obs, prefs, dirsvc} = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services; class SingleHTMLChild extends JSWindowActorChild { //класс = name + Child receiveMessage() { return htmlAndName(this.contentWindow);} } ChromeUtils.domProcessChild.childID || ({ init(topic) { ChromeUtils.registerWindowActor(name, { allFrames: true, child: {moduleURI: __URI__}, messageManagerGroups: ["browsers"] }); obs.addObserver(self = this, topic); obs.addObserver(function quit(s, t) { obs.removeObserver(quit, t); obs.removeObserver(self, topic); }, "quit-application-granted"); this.handleEvent = e => this[e.type](e); globalThis[Symbol.for(name)] = this.saveHTML; }, observe(win) { win.document.getElementById("appMenu-popup") .addEventListener("popupshowing", this); win.addEventListener("unload", this); }, popupshowing(e) { this.unload(e); var popup = e.target; var btn = popup.ownerDocument.createXULElement("toolbarbutton"); btn.id = "appMenu-ucf-save-html-button"; btn.setAttribute("label", "Страница | выбранное в единый HTML"); var before = "appMenu-save-file-button2", subviewbutton = "subviewbutton"; btn.className = subviewbutton; btn.setAttribute("oncommand", "saveHTML();"); btn.saveHTML = this.saveHTML; popup.querySelector('toolbarbutton[id^="'+ before +'"]').before(btn); }, unload(e) { var win = e.target.ownerGlobal; win.removeEventListener("unload", this); win.document.getElementById("appMenu-popup").removeEventListener("popupshowing", this); }, async saveHTML(arg, win = this.ownerGlobal) { var br = win.gBrowser.selectedBrowser; var bc = focus.focusedContentBrowsingContext; if (bc?.top.embedderElement != br) bc = br.browsingContext; var actor = bc?.currentWindowGlobal?.getActor(name); actor && self.save(win, ...await actor.sendQuery(""), arg); // htmlAndName }, async save(win, data, fname, host, arg, d = prefs.getStringPref("ucf.savedirs","_Web||_Pic|0")) { if (/.*\|/.test(arg)) d = arg; //Dir/Subdir|[пусто|0 title|1 host] if (!/.*\|/.test(d)) d += '|'; d = d.split('|').slice(0,2); //Загрузки[домен]имя fname = fname.replace(/\s+/g,' ').replace(/[\\\/?*\"'`]+/g,'').replace(/[|<>]+/g,'_').replace(/:/g,'։').slice(0,100).trim(); d[1] = (d[1] == "0") ? fname.slice(0,48).trim() : (d[1] == "1") ? host.replace(/\/.*/,'') : ""; try {var dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {var dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} d.forEach(dir.append); dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); fname += (function() {var d = new Date(), z = function(n){return '։' + (n < 10 ? '0' : '') + n}; return '_'+ d.getHours() + z(d.getMinutes()) + z(d.getSeconds());})(); dir.append(fname +'.html'); var path = dir.path; //назначить путь сохранения if (!arg) { // диалог выбора папки var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker); fp.init(win, "", fp.modeSave); fp.defaultString = path.split(/.*[\/|\\]/)[1]; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); var res = await new Promise(fp.open); if (res == fp.returnOK || res == fp.returnReplace) path = fp.file.path else return; } this.write(path, data); d = await win.Downloads.createDownload({source: "about:blank",target: win.FileUtils.File(path)}); (await win.Downloads.getList(win.Downloads.ALL)).add(d); await d.refresh(d.succeeded = true); //flash DWButton }, write(path, html) { if (typeof IOUtils == "object") var write = IOUtils.writeUTF8 || IOUtils.writeAtomicUTF8; // Fx 85+ || 82-84 if (!write) { // Fx 79-81 var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); write = (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt)); } (this.write = write)(path, html); } }).init("browser-delayed-startup-finished"); var htmlAndName = async mainWin => { var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec;} catch {} }, getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r;} catch(e) {} } }, encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else img = obj; if (img.complete) try { canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }, toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }, selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location, ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild), meta = doc.createElement('meta'), sheets = doc.styleSheets; meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); var title = doc.getElementsByTagName('title')[0]; if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet);} } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var onlyName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); return [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', onlyName, loc.hostname]; } |
Dobrov > 16-07-2023 05:43:08 |
Dumby - ещё нужна помощь! как в JSM-ке SingleHTMLChild получить адрес и имя текущей вкладки ? |
Dumby > 16-07-2023 09:54:01 |
odd74RUS пишет
Нет такой версии. А вот в 116, да, отвалится: Можно будет так поправить скрытый текст Выделить код Код:/* var pref = Services.prefs.getStringPref("browser.search.hiddenOneOffs"); var hiddenList = pref ? pref.split(",") : []; var engines = await Services.search.getVisibleEngines(); for (let engine of engines.filter(e => !hiddenList.includes(e.name))) { */ var engines = await Services.search.getVisibleEngines(); for(let engine of engines.filter(e => !e.hideOneOffButton)) { Или, если нужна какая-то обратная совместимость, например, так скрытый текст Выделить код Код:/* async rebuild(menu) { var de = Services.search.defaultEngine; de = de.wrappedJSObject || de; this.setAttrs(menu, de, `Искать в ${de.name} или в ...`); menu.ePopup.textContent = ""; var pref = Services.prefs.getStringPref("browser.search.hiddenOneOffs"); var hiddenList = pref ? pref.split(",") : []; var engines = await Services.search.getVisibleEngines(); for (let engine of engines.filter(e => !hiddenList.includes(e.name))) { */ getEngines() { var args = "hideOneOffButton" in Services.search.defaultEngine ? [e => !e.hideOneOffButton] : Object.defineProperty( [function(e) {return !this.includes(e.name);}], "1", { get: () => Services.prefs.getStringPref(this.hide)?.split(",") || [] } ); return (this.getEngines = async () => (await Services.search.getVisibleEngines()).filter(...args) )(); }, async rebuild(menu) { var de = Services.search.defaultEngine; de = de.wrappedJSObject || de; this.setAttrs(menu, de, `Искать в ${de.name} или в ...`); menu.ePopup.textContent = ""; for(let engine of await this.getEngines()) { И да, я понимаю, что разговоры про 116+ для Win7 не слишком актуальны, так что это просто так, на всякий случай. Dobrov пишет
Что-то я не понимаю твоего затруднения. Есть ссылка на окно — есть и его свойства, У тебя же самого, например, написано win.Downloads и win.FileUtils И gBrowser в модуле используется, смотри первую строку в saveHTML() |
Dobrov > 16-07-2023 15:18:46 |
Dumby пишет
Я тоже! Накосячил - разные функции с одним именем прописал в globalThis[Symbol.for(… Ещё не получилось добавить setTimeout(… в скрипты scriptsbackground: [ // В фоне [System Principal] |
b0ttle > 16-07-2023 17:35:43 |
Dobrov |
Dumby > 16-07-2023 17:56:06 |
Dobrov пишет
Не понял. Даже попробовал проверить: в scriptsbackground — { path: "test_timeout.js" }, |
kokoss > 16-07-2023 21:15:30 |
Dumby пишет
Работает, но почему то на mail.ru, bing.com, может ещё где не срабатывает, в чём может быть причина ? |
Dobrov > 17-07-2023 02:47:01 |
Dumby пишет
в JSM это не работает. Есть другой способ JSM подключать в CustomStylesScripts.jsm? Как добавить setTimeout в JSM? Выделить код Код:var jsmImport = name => `ChromeUtils.import("chrome://user_chrome_files/content/custom_scripts/${name}")`; …………… scriptsbackground: [ // В фоне [System Principal] { path: "test_timeout.jsm" }, // только здесь setTimeout работает { func: jsmImport("test_timeout.jsm"), }, // не пашет ✕✖✘ Dumby ещё вопрос: А возможно сделать доступными из начала скрипта несколько функций, прописанных в блоке (async (id) => {}) ? Блок-схема скрипта hookClicks.js (ChromeOnly) Выделить код Код:var hmap = new Map([["downloads-button", `колёсико ⬇︎ папка [Загрузки]`]]); // +++ код >>> data = { // клавиши и события мыши в начале скрипта для лучшего восприятия "#downloads-button": { 1() {save()}, // +++ код >>> }}; key_data = e => { // перехват клавиш в начале скрипта для лучшего восприятия log(e.keyCode); // ✕✖✘ недоступны функции из блока (async (id, func) => { }; // +++ код >>> (async (id, func) => { // +++ код основные функции >>> var dsym = Symbol(), tooltips = { [dsym]: GetDynamicShortcutTooltipText("downloads-button") + "\n" + hmap.get("downloads-button"), // +++ код >>> get "downloads-button"() { } var log = (msg) => { Services.console.logStringMessage(msg); }, keydown_win = e => { // перехват клавиш key_data(e); // не работает ✕✖✘ // +++ код >>> } window.addEventListener("keydown", keydown_win); // +++ код >>> })("hookClicks-and-tooltips"); |
Dobrov > 17-07-2023 10:24:06 |
Упростил скрипт перехвата кнопок/ролика мыши и нажатий клавиш ucf_hookClicks.js |
b0ttle > 17-07-2023 13:22:22 |
Dobrov |
Dobrov > 17-07-2023 13:40:21 |
b0ttle - userj(e) - внешний скрипт пользователя b0ttle пишет
нет, переноси код ручками - видно же, что синтаксис разный: |
b0ttle > 17-07-2023 14:02:07 |
Dobrov скрытый текст Выделить код Код:keyboard = { // нажатия клавиш Meta 8 Ctrl4 Shift2 Alt1 KeyS_1(e) { save()}, // S+Alt KeyS_3(e) { // S+Alt+Shift var single = document.getElementById(hmap.get("#").split('|')[10]); single ? single.click() : save(); // имитировать клик кнопки }, KeyS_5(e) { saveSelectionToTxt();}, // S+Alt+Ctrl KeyX_1(e) { userjs(e)}, // X+Alt внешний скрипт KeyQ_5(e) { // Q+Alt+Ctrl CleanCache - Перезапустить, удалив кэш var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart"); if (cancelQuit.data) return false; Services.appinfo.invalidateCachesOnRestart(); var restart = Services.startup; restart.quit(restart.eAttemptQuit | restart.eRestart);}, //============ get skip(){return docShell.isCommandEnabled("cmd_insertText");}, Backquote(){this.skip||PlacesCommandHook.showPlacesOrganizer("BookmarksMenu").click();}, Digit1(){this.skip||document.getElementById("unified-extensions-button").click();}, Digit2(){this.skip||BrowserOpenAddonsMgr();}, Digit3(){this.skip||openPreferences();}, Digit4(){this.skip||duplicateTabIn(gBrowser.selectedTab,'tab');}, Digit5(){if(this.skip)return;var s=prompt('Google_ site:.. ..','');if(s.length>0)gBrowser.addTrustedTab('https://www.google.com/search?q=site:'+encodeURIComponent(gBrowser.currentURI.host)+' '+encodeURIComponent(s));}, Digit6(){if(this.skip)return;var p=Services.dirsvc.get('GreD',Ci.nsIFile);p.initWithPath(p.path+"\\..\\..\\..\\_Photo\\ShareX\\ShareX.exe");p.launch();}, Digit7(){if(this.skip)return;gBrowser.fixupAndLoadURIString("javascript:(function(){var EnRuT=[['щ','shh'],['Щ','Shh'],['Щ','SHH'],['х','hh'],['Х','Hh'],['Х','HH'],['ж','zh'],['Ж','Zh'],['Ж','ZH'],['ц','cz'],['Ц','Cz'],['Ц','CZ'],['ю','yu'],['Ю','Yu'],['Ю','YU'],['ё','yo'],['Ё','Yo'],['Ё','YO'],['я','ya'],['Я','Ya'],['Я','YA'],['ч','ch'],['Ч','Ch'],['Ч','CH'],['ш','sh'],['Ш','Sh'],['Ш','SH'],['э','e`'],['Э','E`'],['ы','y'],['Ы','Y'],['ъ','``'],['ь','`'],['р','r'],['т','t'],['у','u'],['и','i'],['о','o'],['п','p'],['а','a'],['с','s'],['д','d'],['ф','f'],['г','g'],['й','j'],['к','k'],['л','l'],['з','z'],['х','x'],['ц','c'],['в','v'],['б','b'],['н','n'],['м','m'],['Р','R'],['Т','T'],['У','U'],['И','I'],['О','O'],['П','P'],['А','A'],['С','S'],['Д','D'],['Ф','F'],['Г','G'],['Й','J'],['К','K'],['Л','L'],['З','Z'],['Х','X'],['Ц','C'],['В','V'],['Б','B'],['Н','N'],['М','M'],['е','e'],['Е','E']],A=document.activeElement;A.onkeyup=function ftr(){for(var s=A.value,i=0;i<EnRuT.length;i++){s=s.replace(RegExp(EnRuT[i][1],'g'),EnRuT[i][0])};A.value=s}})()",{triggeringPrincipal:gBrowser.contentPrincipal}); },//AutoTranslit- https://forum.ru-board.com/topic.cgi?forum=5&topic=46779&start=320#15 F1(){FileUtils.getFile('SysD',['sndvol.exe']).launch();}, F2(e){e.preventDefault();gBrowser.fixupAndLoadURIString("javascript:{d=document;b=d.body;o=d.createElement('scri'+'pt');o.setAttribute('src','https://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit');o.setAttribute('type','text/javascript');b.appendChild(o);v=b.insertBefore(d.createElement('div'),b.firstChild);v.id='google_translate_element';v.style.display='none';p=d.createElement('scri'+'pt');p.text='function googleTranslateElementInit(){new google.translate.TranslateElement({pageLanguage:%22%22},%22google_translate_element%22);}';p.setAttribute('type','text/javascript');b.appendChild(p);}void 0",{triggeringPrincipal:gBrowser.contentPrincipal}); },//Enable translation(https://forum.mozilla-russia.org/viewtopic.php?pid=805422#p805422 ||805427#p805427) F3(e){e.preventDefault();gBrowser.fixupAndLoadURIString("javascript:(function(){var night=function(w){(function(d){var css='html{opacity:0.6!important;background:black!important;}body{background:white!important;}';var s=d.getElementsByTagName('style');for(var i=0,si;si=s[i];i++){if(si.innerHTML==css){si.parentNode.removeChild(si);return}};var heads=d.getElementsByTagName('head');if(heads.length){var node=d.createElement('style');node.type='text/css';node.appendChild(d.createTextNode(css));heads[0].appendChild(node)}})(w.document);for(var i=0,f;f=w.frames[i];i++){try{arguments.callee(f)}catch(e){}}};night(window)})();",{triggeringPrincipal:gBrowser.contentPrincipal}); },//Night mode(Focus mode) F4(){var vert=`javascript:{const o=["contextmenu","selectstart","select","mousedown","mouseup","cut","copy"],t=["-webkit","-moz","-ms","-khtml",""],e=window.jQuery;[document,document.body,document.documentElement].forEach(n=>{for(const t of o)n["on"+t]=null,e&&e(n).off(t);if(n.style)for(const o of t){const t=[o,"user-select"].join("-");n.style[t]="initial"}}) };void(0);`;gBrowser.loadURI(Services.io.newURI(vert),{triggeringPrincipal:Services.scriptSecurityManager.getSystemPrincipal()}); },//Re-enable selecting & copying text [maple3142] (Bookmarklet) KeyG_4(e){e.preventDefault();var bar=document.getElementById("ucf-additional-vertical-bar");setToolbarVisibility(bar,bar.collapsed);}, KeyW_1(){gBrowser.removeAllTabsBut(gBrowser.selectedTab);}, KeyV(){if(this.skip)return;gClipboard.write(gURLBar.value);glob.flash_bg_text('urlbar-input-container',0,'rgba(240,176,0,0.5)',300);},//300,"CopyURL: "+gURLBar.value.slice(0,80)) KeyV_1(){let url=readFromClipboard();try{switchToTabHavingURI(url,true);}catch(ex){ var reg=/[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?/; if(!reg.test(url)){url='https://www.google.com/search?q='+encodeURIComponent(url); }else{if(url.substring(4,0).toLowerCase()=="http"){url=encodeURIComponent(url); }else{url='http://'+encodeURIComponent(url);}}switchToTabHavingURI(url,true);}},//Open clipboard address KeyU_5(){FileUtils.getFile('UChrm',['user_chrome_files','_','u.exe']).launch();}, KeyA_5(){FileUtils.getFile('UChrm',['user_chrome_files','_','.Ev','Everything.exe']).launch();}, KeyQ_4(){FileUtils.getFile('UChrm',['user_chrome_files','_','.QT','QTranslate.exe']).launch();}, //============ } |
Dumby > 17-07-2023 23:07:53 |
kokoss пишет
Без понятия. Но интересно, если закомментировать Dobrov пишет
Ну так тоже импортируй модуль Timer.
Конечно недоступны, log определяется как var log = … внутри функции. Если нужно использовать log в key_data, но чтобы он задавался в (async (id, func) => { Ну, это в общем случае. Блок-схема не предполагает, что сам (весь) код b0ttle пишет
skip() тоже можно перенести, тогда не будет.
Какой ещё «клик event»? keydown event же. Вобщем как-то так скрытый текст Выделить код Код:....... = { // перехват клавиш Meta 8 Ctrl 4 Shift 2 Alt 1 get skip() {return docShell.isCommandEnabled("cmd_insertText");}, Backquote() {this.skip || PlacesCommandHook.showPlacesOrganizer("BookmarksMenu");}, Digit1() {this.skip || document.getElementById("unified-extensions-button").click();}, |
kokoss > 18-07-2023 00:39:31 |
Dumby пишет
Не срабатывает, ладно, всё равно я эти поисковики редко использую. |
b0ttle > 18-07-2023 02:50:11 |
Dumby |
Dobrov > 18-07-2023 04:35:22 |
b0ttle пишет
в поле быстрого ответа этого форума перехват нажатий клавиш работает. Dumby пишет
А как правильно завернуть код на блок-схеме или скрипте ucf_hookClicks.js, чтобы он не мусорил в окно? |
b0ttle > 18-07-2023 11:39:58 |
dobrov В общем, проблема в том, что `1234567, в полях ввода не пишутся, при рабочих Digit1,2,3,5,6,7. Функций работают, но текст нет. А при this.skip||, текст не работает и функций, в полях ввода, ничего не происходит. Отдельно функций работают. Как-то так. |
Dobrov > 18-07-2023 12:53:46 |
b0ttle пишет
Это пример, что функция keys.skip возвращает значение в переменную ret. (то есть, код работает) |
Dumby > 18-07-2023 13:40:31 |
Dobrov пишет
Ну, если ничего внутри не поменять, то пропадут.
Конечно не работает. А Cu.getGlobalForObject(Cu) возвращает SystemGlobal Иначе говоря, ты добавил GlobShare в одно место, Вобщем, заворачиваешь код, Ну это если такое присваивание будет исполнено сперва,
Сравнил тоже. Одну клавишу нажимать или три. b0ttle пишет
Такого быть не должно. |
Dobrov > 18-07-2023 15:36:36 |
Dumby пишет
Я ждал совета покруче! Но старый известный способ объявлять данные через window. наверное самый простой! |
Dumby > 18-07-2023 21:57:08 |
Dobrov пишет
Ищешь каких-то сложностей?
Ну как, смотри сам, А если собрать в один объект, то вероятность конфликта меньше, |
b0ttle > 18-07-2023 23:51:59 |
Dumby |
Dobrov > 19-07-2023 03:42:48 |
Dumby пишет
вопрос по старому коду перехвата клавиш: Для чего и что делает строка var num = RegExp.$1 ? Код для теста: перехват нажатий клавиш Выделить код Код:(async anim => { // горячие клавиши https://forum.mozilla-russia.org/viewtopic.php?pid=796907#p796907 // var re = /^(?:Digit|Numpad)(1|2|3|4)$/; var funcs = { 1: () => { true; }, 2: tab => gBrowser.removeAllTabsBut(tab), }; var args = ["keydown", e => { if (e.repeat || docShell.isCommandEnabled("cmd_insertText")) return; var m = (e.metaKey*8 + e.ctrlKey*4 + e.shiftKey*2 + e.altKey), n = m ? "_"+ m.toString() : ""; var num = RegExp.$1; // всегда 21 // if ( e.shiftKey || e.code.startsWith("N") && e.getModifierState("NumLock") && e.key != num ) // e.preventDefault(), funcs[num](gBrowser.selectedTab); e.preventDefault(); if (e.keyCode > 31) console.log('@ '+ e.key +' '+ e.code +' '+ e.keyCode +' '+ num +' '+ Math.random()); if (num in funcs) funcs[num](gBrowser.selectedTab); }, true]; addEventListener(...args); var id = Symbol(), ucf = ucf_custom_script_win; ucf.unloadlisteners.push(id); ucf[id] = {destructor: () => removeEventListener(...args)}; })({animate: true}); |
b0ttle > 19-07-2023 04:54:17 |
del |
Dumby > 19-07-2023 08:39:33 |
Dobrov пишет
В приведённом коде — не делает ничего осмысленного, А в оригинале — в num пишется цифра клавиши.
Ну вот, например, пункт контекстного меню вкладки «Закрыть вкладки слева» |
Dobrov > 19-07-2023 12:34:37 |
Переделал перехват нажатий клавиш в скрипте ucf_hookClicks.js, возможности: Выделить код Код:var klaBa = { // Пример блока обработки, нажатия клавиш Meta 8 Ctrl 4 Shift 2 Alt 1 Input 'I' Skip KeyA(e) { console.log('KeyA'); return 'KeyA'; // обычное нажатие клавиши }, keyA(e) { this.KeyA(e); // выполнить код обычного нажатия, не запускать preventDefault() return 'keyA Input'}, // нажатие в поле ввода KeyA_I() {0}, // в поле ввода (+ управляющие клавиши: KeyA_5I) KeyA_5() { console.log('нажатие A + Ctrl + Alt')} } |
b0ttle > 19-07-2023 19:49:45 |
Как сделать, чтобы F3 работал везде. С учетом preventDefault. То как сделал, он работает везде, за исключием одного момента, вне поля ввода, preventDefault не срабатывает. Может неправильно вписал? Просто как пример. Когда нужно, чтобы хоткей работал везде. Тут хоткей не работает в поле ввода, но вызывается стандартный хоткей "поиск". Вне поля ввода, ctrl+g начинает работать нормально. Выделить код Код:KeyG_4(){var bar=document.getElementById("ucf-additional-vertical-bar");setToolbarVisibility(bar,bar.collapsed);}, Тут добавил I, работает везде, но тогда вне поля ввода, он не перехватывает preventDefault. Выделить код Код:KeyG_4I(){var bar=document.getElementById("ucf-additional-vertical-bar");setToolbarVisibility(bar,bar.collapsed);}, |
Dobrov > 20-07-2023 04:21:53 |
b0ttle пишет
Вообще-то, я подробно всё расписал, может у тебя старая версия ? ucf_hookClicks.js часто обновляю. Пример блока обработки нажатий Выделить код Код:F3(){ console.log('F3 exec'); openPreferences(); }, F3_I(){this.F3()}, // F3 в поле ввода KeyG_4(){ // Ctrl+G var bar = document.getElementById("ucf-additional-vertical-bar"); setToolbarVisibility(bar,bar.collapsed); }, KeyG_4I(){this.KeyG_4()}, // Ctrl+G в поле ввода |
b0ttle > 20-07-2023 12:20:59 |
Dobrov Сейчас, когда KeyG_4I, он конфликтует из-за preventDefault, в полях ввода он перехватывает стандартные комбинаций пойска. Но вне поля ввода, он этого не делает. В этом и проблема. Это в случае со стандартными хоткеями. Есть тот же F3, где тоже стандартная комбинация пойск, на F2, там расширение у меня, его тоже надо перехватывать с preventDefault. Не знаю, как еще объяснить. В общем, из-за того что все из коробки, не очень удобно и что-то может конфкликтовать, и конфликтует. Как было до этого с preventDefault, в полях ввода, когда `1234567 отказывались вообще работать. Выделить код Код:keyG_4I(e){e.preventDefault();var bar=document.getElementById("ucf-additional-vertical-bar");setToolbarVisibility(bar,bar.collapsed);}, Так то что надо. Нигде ничего не конфликтует. Выделить код Код:KeyG_4(){var bar=document.getElementById("ucf-additional-vertical-bar");setToolbarVisibility(bar,bar.collapsed);}, KeyG_4I(){this.KeyG_4()}, |
Dobrov > 20-07-2023 13:02:45 |
Dumby - проверь плиз, код перехвата клавиш. b0ttle - Да, мой код глючит! (UPDATE пост обновил) В примере нажатия на странице и в поле ввода различаются (для поля ввода к имени нужно добавить "I"). Для Digit1_I (цифра 1 в поле ввода) выполняется preventDefault, но почему-то в поле ввода попадает символ. Выделить код Код:(async anim => { // Для докум. окна браузера [ChromeOnly] var keyboard = { // нажатия клавиш Meta 8 Ctrl 4 Shift 2 Alt 1 Input 'I' Skip первая буква строчная Digit1() { console.log("■ клавиша 1 "+ Math.random()); }, // Alt+X Digit1_I() { this.Digit1(); }, KeyX_1(e) { console.log("■ Alt+X "+ Math.random()); }, KeyX_1I(e) { this.KeyX_1(e)}, // Alt+X в поле ввода } var args = ["keydown", e => { if (e.repeat) return; //e.getModifierState("CapsLock")*16 var k, m = (e.metaKey*8 +e.ctrlKey*4 +e.shiftKey*2 +e.altKey +"I".slice(!docShell.isCommandEnabled("cmd_insertText"))).replace(/^0/,''); m = e.code + ("_"+ m).slice(0, 5*Boolean(m)); k = m[0].toLowerCase() + m.slice(1); if (k in keyboard) m = k, k = 0; // не держать ввод if (e.keyCode > 31) if (m in keyboard) { keyboard[m](gBrowser.selectedTab); !k && e.preventDefault(); } console.log("■ "+ m +' '+ Math.random()); }, true]; addEventListener(...args); var id = Symbol(), ucf = ucf_custom_script_win; ucf.unloadlisteners.push(id); ucf[id] = {destructor: () => removeEventListener(...args)}; })({animate: true}); |
Dumby > 21-07-2023 09:41:28 |
Dobrov пишет
Это каким же образом? Перед if-проверками в переменной k Первую if-проверку k не проходит, поскольку digit1_I в keyboard нет, Так и остаётся далее, где подходим к строке !k && e.preventDefault(); Выражение вида false && something Иными словами, e.preventDefault(), вопреки утверждению, не выполняется. скрытый текст Кстати, я тут возился с ucf_hookClicks.js типа как бы избежать этого slice-replace сумбура в keydown_win() Ну, просто так, на интерес. Вот вариант. Пропускаем объект klaBa через некий парсер (без валидации, конечно) Выделить код Код:((obj, re) => { for(var p in klaBa) { var func = klaBa[p]; if (typeof func == "string") func = klaBa[func]; var [key, mod] = p.split("_"); mod = mod || ""; var first = key[0]; var upper = first.toUpperCase(); var prevent = first == upper; var [, m, i] = mod.match(re); m = m || 0; // modifiers bitmap var arr = [func, prevent, i ? i == "I" ? 1 : 0 : -1]; // textfields flag var prop = prevent ? key : upper + key.slice(1); var o = obj[prop] || (obj[prop] = Object.create(null)); o[m] ? o[m].push(arr) : o[m] = [arr]; } klaBa = obj; })(Object.create(null), /(\d+)?(i)?/i); Тогда keydown_win() становится стройнее Выделить код Код:keydown_win = e => { // перехват клавиш, учитывая поля ввода if (e.repeat) return; var data = klaBa[e.code]?.[e.metaKey*8 + e.ctrlKey*4 + e.shiftKey*2 + e.altKey]; if (data) { var cmd = docShell.isCommandEnabled("cmd_insertText"); for(var [func, p, i] of data) if (i ^ cmd) p && e.preventDefault(), func(e, gBrowser.selectedTab); } }, И примечания к синтаксису свойств klaBa: Если начинается с маленькой буквы — не вызывать e.preventDefault(). При наличии модификаторов и/или «iI»-флага — отделять от кода клавиши символом «_». Проброс одинакового — вместо функции вписываем соответствующую строку ————— Но так получается, что в klaBa нельзя вписывать что-то постороннее, Ну и вообще, под парсер как концепцию, |
Dobrov > 21-07-2023 12:29:28 |
Dumby - спасибо за помощь, изучу твой код и исправлю свои ошибки! Не смог запустить сочетание клавиш Alt+X. По одной клавише пашет, а так нет: KeyX_1(e) { console.log("Alt+X");
Может, ещё надумаешь вариант покруче? Как я понял, теперь нельзя использовать что-то вроде
Ты проверял старый код, я вчера его улучшил, всё должно работать правильно Выделить код Код:keydown_win = e => { if (e.repeat) return; var k, m = (e.metaKey*8 +e.ctrlKey*4 +e.shiftKey*2 +e.altKey +"I".slice(!docShell.isCommandEnabled("cmd_insertText"))).replace(/^0/,''); m = e.code + ("_"+ m).slice(0, 5*Boolean(m)); k = m[0].toLowerCase() + m.slice(1); // m = Digit1 k = digit1 if (m in klaBa) // если прописаны одинаковые клавиши (Digit1 и digit1), приоритет имеют имена с Заглавной k = m, m = 0; // m = 0 – выполнять preventDefault if (k in klaBa) { // если Digit1 не найдено, запускаем digit1 и не выполняем preventDefault !m && e.preventDefault(); // пропуск, если имя с прописной буквы. Отрицание непустой строки !m = !Digit1 = false klaBa[k](e); // execute } }, |
Dumby > 23-07-2023 00:38:57 |
Dobrov пишет
Парсер это не объект, а отдельный фрагмент кода. А в keydown_win() ему не место, она же по каждому keydown исполняется, А сделать keydown_win() lazy-функцией не получится, она сразу регистрируется Разве что только переделать её в объект с методом handleEvent()
Наверно можно, но не знаю нужно ли. скрытый текст Выделить код Код:var keyMap = Object.create(null); (re => { var parse = (str, test) => { if (name.length < 2 || str.endsWith("_")) return null; var first = str[0]; var upper = first.toUpperCase(); var prevent = first == upper; upper = prevent ? str : upper + str.slice(1); if (test) return re.test(upper); var match = upper.match(re); if (match) { var [, kode, mod, i] = match; return [kode, str, prevent, i ? i == "I" ? 1 : 0 : -1, mod || 0]; } } for(var name in klaBa) { var arr = parse(name); if (!arr) continue; var desc = Object.getOwnPropertyDescriptor(klaBa, name); if ("value" in desc) { var val = klaBa[name]; if (typeof val == "string") { if (klaBa.hasOwnProperty(val) && parse(val, true)) arr[1] = val; else continue; // skip not alias strings } else if (typeof val != "function") continue; // skip not functions } else if (!desc.get) continue; // skip only setters var kode = arr.shift(), mod = arr.pop(); var o = keyMap[kode] || (keyMap[kode] = Object.create(null)); o[mod] ? o[mod].push(arr) : o[mod] = [arr]; } })(new RegExp(`^(${[ // https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_code_values "Key[A-Z]|F(?:1?\\d|2[0-4])|Digit\\d", "Numpad(?:\\d|Enter|Add|Comma|Subtract|Decimal|Divide|Multiply|Equal)", "(?:Bracket|Arrow|Control|Shift|Alt|OS)(?:Left|Right)|(?:Arrow|Page)(?:Up|Down)", "Space|Quote|Equal|Comma|Minus|Period|Slash|Semicolon|Backslash|CapsLock|ContextMenu", "Backquote|Help|Backspace|Tab|Enter|Escape|End|Home|Insert|Delete|PrintScreen|NumLock", "Again|Convert|Copy|Cut|Eject|Find|IntlBackslash|IntlRo|IntlYen|KanaMode|NonConvert", "Open|Paste|Pause|Power|Props|ScrollLock|Select|Sleep|Undo|WakeUp|Lang[1-2]", "Media(?:PlayPause|Select|Stop|TrackNext|TrackPrevious)|Volume(?:Up|Down|Mute)", "Browser(?:Back|Favorites|Forward|Home|Refresh|Search|Stop)|Launch(?:App1|App2|Mail)" ].join("|")})(?:_(\\d\\d?)?([iI])?)?$`)); Выделить код Код:keydown_win = e => { // перехват клавиш, учитывая поля ввода if (e.repeat) return; var data = keyMap[e.code]?.[e.metaKey*8 + e.ctrlKey*4 + e.shiftKey*2 + e.altKey]; if (data) { var cmd = docShell.isCommandEnabled("cmd_insertText"); for(var [name, p, i] of data) if (i ^ cmd) p && e.preventDefault(), klaBa[name](e, gBrowser.selectedTab); } },
Какой был предоставлен, такой и проверял. |
voqabuhe > 23-07-2023 11:15:37 |
Add Toolbar Buttons уже починяли? Если нет, Dumby, посмотри пожалуйста, из кнопки Восстановить закрытые вкладки пропали. |
xrun1 > 23-07-2023 12:48:36 |
voqabuhe
|
voqabuhe > 23-07-2023 15:04:03 |
xrun1 |
xrun1 > 23-07-2023 20:58:48 |
voqabuhe |
Dobrov > 24-07-2023 12:59:42 |
Dumby - придумал вариант списка нажатий клавиш проще прежнего. Код доделаю нескоро, может у тебя получится? Формат: получаем имя нажатой кнопки вместе с управляющими клавишами: Digit1_1 равно Alt+1 (учитывая LED-индикаторы, если в объекте вместо функции Digit1_1 есть строка "Digit1_1"). Пример объекта - Если вместо функции строка, то учитывем LED-индикаторы 1) Если в объекте есть функция Digit1_1 (без учёта LED), то все режимы разрешены, то есть выполняем её всегда. 2) Если нет функции Digit1_1 и строки-объекта "Digit1_1", то добавляем состояние LED-индикаторов (Digit1_17, если CapsLock включен) и ищем такую функцию или строку-объект. 3) Если вместо функции имеется строка-объект, то "Digit1_1" или "Digit1_17" содержит одну или несколько функций, имена которых равны сумме флагов. Разрешающий флаг как в предыдущих кодах, включает: preventDefault*4 + Input*2 + MainPage Преимущество в том, что одно и тоже сочетание клавиш (Alt+1) может работать по разному в зависимости от LED-индикаторов. Можно добавить фильтр по операционной системе, тогда сначала ищем это же имя + ваша OS: "Digit1_1_macosx", потом обычное имя Digit1_1. Выделить код Код:var keyData = { // имя объекта: Клавиша_Shift+Alt+Ctrl[LED] Digit1_1(e) { // 1+Alt если Имя = Функция, считаем, что все режимы разрешены console.log("Digit1 везде"); }, "Digit1_1": { // 1+Alt 7(e){ // preventDefault*4 + Input*2 + MainPage console.log("Digit1 везде, игнорируя LED-индикаторы"); }, 2(){}, // только в полях ввода, Skip preventDefault 5(){}, // кроме полей ввода }, "Digit1_1_macosx": { // массив для переопределения отдельных сочетаний клавиш для вашей OS 16(e){ // только если CapsLock включен keyData["Digit1_1"][0]("Digit1_1_macosx"); // повторяем код из общего объекта } }, } |
Dumby > 25-07-2023 08:13:52 |
Dobrov пишет
Что-то не вижу никакой строки вместо функции. И, при такой записи, "Digit1_1" затрёт Digit1_1 |
Dobrov > 25-07-2023 08:37:38 |
Dumby пишет
В объекте все варианты для примера, а так должен быть только один из них. Далее разбор в зависисмости от режима e.getModifierState("CapsLock") и прочих LED… То есть, эти две записи нельзя различить по типам, учитывая, что в объекте должна быть только одна из них? |
Dumby > 25-07-2023 12:23:29 |
Dobrov пишет
Не понял. А если имеется в виду, что различить такую же запись |
Dobrov > 25-07-2023 17:31:51 |
Dumby - я ранее расписал примерный алгоритм обработки нажатий. Различать по типу - если ключ это функция, то её запускаем, не проверяя режимы ввода. В примере это первый Digit1_1. А в строковом ключе (имя свойства объекта) будут имена функций тех режимов, на которых надо запускать код для этого сочетания клавиш. |
_zt > 27-07-2023 02:00:22 |
Dumby скрытый текст Выделить код Код:(async style => { var uri = Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(style)); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(uri, sss.USER_SHEET); })(` ... `); То ли лыжи не едут... |
Dumby > 27-07-2023 10:13:21 |
_zt Но да, на 115, вроде вполне достаточно будет просто только скрытый текст Выделить код Код:(async ids => { for(var id of ids) document.getElementById(id)?.setAttribute("removable", true); })(["unified-extensions-button", "alltabs-button"]); |
6e73epo > 27-07-2023 11:09:43 |
Dumby, подскажите, в чем разница между этими двумя записями? Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties).get('UChrm', Ci.nsIFile); |
Dumby > 27-07-2023 12:45:02 |
6e73epo пишет
Мне кажется, что хоть в сколько-нибудь актуальной версии лисицы, Но, если интересно копнуть вглубь веков относительно сахара, |
6e73epo > 27-07-2023 14:39:54 |
Dumby, благодарю, а чуть выше вы дали понять что в 115 записи для "unified-extensions-button" и "alltabs-button" могут быть эквивалентны, т.е. для config.js можно так скрытый текст Выделить код Код:// сделать кнопку All Tabs (alltabs-button) съемной (async topic => { var obs = doc => doc.getElementById("alltabs-button")?.setAttribute("removable", true); Services.obs.addObserver(obs, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(obs, topic); }, "quit-application-granted"); })("chrome-document-interactive"); // сделать кнопку unified-extensions-button съемной (async topic => { var obs = doc => doc.getElementById("unified-extensions-button")?.setAttribute("removable", true); Services.obs.addObserver(obs, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(obs, topic); }, "quit-application-granted"); })("chrome-document-interactive"); |
Dumby > 27-07-2023 16:27:46 |
6e73epo пишет
Да обычный мерж, только и всего. скрытый текст Выделить код Код:// установить для кнопок #alltabs-button и #unified-extensions-button // атрибут "removable" как "true" (async topic => { var obs = doc => { doc.getElementById("alltabs-button")?.setAttribute("removable", true); doc.getElementById("unified-extensions-button")?.setAttribute("removable", true); } Services.obs.addObserver(obs, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(obs, topic); }, "quit-application-granted"); })("chrome-document-interactive"); |
b0ttle > 27-07-2023 19:20:58 |
6e73epo |
Dobrov > 29-07-2023 08:32:11 |
Dumby прошу дополнить первый вариант парсинга горячих клавиш, чтобы работал в зависимости от текущей операционной системы. Логика такая: прописаны две одинаковых горячих клавиши, но у одной постфикс (или префикс, если это проще сделать в коде) с именем нужной ОС, для которой нужно выполнять код. Выделить код Код:var KlaBa = { keyX_1(e) { // обычное сочетание клавиш работает всегда console.log("Alt+X skip preventDefault"); }, Digit1_I_macosx(e, t) { // приоритет для вашей OS shell_RunwA("/usr/bin/open", ["-n","-b","com.apple.Stickies"]); }, Digit1_I_win(e, t) { // приоритет для вашей OS shell_RunwA("C:\\Windows\\system32\\StikyNot.exe",""); }, Digit1_I(e, t) { // приоритет низкий run Notes }, Digit1: "Digit1_I" //ссылка на функцию }; |
Dumby > 30-07-2023 08:06:54 |
Dobrov скрытый текст Выделить код Код:((obj, re) => { var del = new Set(); var platformRe = /_(?:win|linux|macosx)$/; var {platform} = AppConstants, num = -platform.length - 1; for(var p in klaBa) platformRe.test(p) && del.add( p.endsWith(platform) ? p.slice(0, num) : p ); for(p in klaBa) del.has(klaBa[p]) && del.add(p); for(var d of del) delete klaBa[d]; |
Dobrov > 30-07-2023 13:33:56 |
Dumby пишет
Спасибо! Но имена функций остаются в постфиксом ОС: Digit1_I_macosx(e, t)…… пробовал убрать, создав копию свойства объекта, но не работает: Выделить код Код:var klaBa = { keyX_1(e) { console.log("Alt+X skip preventDefault"); }, Digit1_I_macosx(e, t) { // приоритет для вашей OS shell_RunwA("/usr/bin/open", ["-n","-b","com.apple.Stickies"]); }, Digit1_I_win(e, t) { // приоритет для вашей OS shell_RunwA("C:\\Windows\\system32\\StikyNot.exe",""); }, Digit1_I(e, t) { // приоритет низкий 0; }, Digit1: "Digit1_I" //ссылка на функцию }; ((obj, re) => { var del = new Set(); var platformRe = /_(?:win|linux|macosx)$/; var {platform} = AppConstants, num = -platform.length - 1; for(var p in klaBa) platformRe.test(p) && del.add( p.endsWith(platform) ? p.slice(0, num) : p ); for(var p in klaBa) del.has(klaBa[p]) && del.add(p); for(var d of del) delete klaBa[d]; //есть Key_OS ? удалить имена-клоны for(var p in klaBa) if (platformRe.test(p)) { //убрать имя вашей ОС из свойства klaBa[p.replace(platformRe,'')] = klaBa[p]; delete klaBa[p]; } for(var p in klaBa) { var func = klaBa[p]; if (typeof func == "string") func = klaBa[func]; //ссылка на функцию var [key, mod] = p.split("_"); mod = mod || ""; var upper = key[0].toUpperCase(); var prevent = key[0] == upper; var [, m, i] = mod.match(re); m = m || 0; // modifiers bitmap var arr = [func, prevent, i ? i == "I" ? 1 : 0 : -1]; // textfields flag var prop = prevent ? key : upper + key.slice(1); //имя клавиши без модификаторов var o = obj[prop] || (obj[prop] = Object.create(null)); o[m] ? o[m].push(arr) : o[m] = [arr]; } klaBa = obj; })(Object.create(null), /(\d+)?([a-z]+)?/i); for(p in klaBa) console.log(klaBa[p]); |
Dumby > 31-07-2023 08:31:17 |
Dobrov пишет
Имена функций значения не имеют, их вызов идёт без участия имени.
Если отказаться от удаления ОС из свойств объекта, то будет работать неправильно.
Да вроде работает как написано, свойство Digit1_I_win успешно заменяется на Digit1_I |
Black_Monk > 02-08-2023 10:54:06 |
После установки 116-й версии в очередной раз исчезла нижняя панель. Специалисты, подскажите как опять её вернуть-то? Пробовал вот это, но не помогло. Может надо версию обновить? У меня в version.txt прописано: "версия, дата г-м-д: 2021-9-23". |
kokoss > 02-08-2023 11:33:03 |
Black_Monk пишет
проверяйте Выделить код Код:toolbarpaletteitem[place="palette"] > toolbaritem.ucf-additional-springs { background: white url("./svg/spring.svg") center no-repeat; border: none; outline: 1px solid currentColor; outline-offset: -1px; min-height: 37px; opacity: 0.3; } toolbarpaletteitem[place="toolbar"] > toolbaritem.ucf-additional-springs, toolbarpaletteitem[place="panel"] > toolbaritem.ucf-additional-springs, toolbarpaletteitem[place="menu-panel"] > toolbaritem.ucf-additional-springs { background: white url("./svg/spring.svg") center no-repeat; border: none; min-width: 34px; min-height: 14px; outline: 1px solid currentColor; outline-offset: -1px; margin-block: 2px !important; margin-inline: 1px !important; opacity: 0.3; } toolbarpaletteitem[place="palette"][id*="ucf-additional-top-spring"], toolbarpaletteitem[place="palette"][id*="ucf-additional-vertical-spring"], toolbarpaletteitem[place="palette"][id*="ucf-additional-bottom-spring"] { vertical-align: top; } toolbarpaletteitem[place] > toolbaritem.ucf-additional-springs { -moz-window-dragging: no-drag !important; } #ucf-restart-app { list-style-image: url("./svg/restart-app-16.svg") !important; fill: #f38725 !important; } #ucf-additional-vertical-toggle-button { list-style-image: url("./svg/vert-toolbar.svg") !important; } #ucf-additional-top-toggle-button { list-style-image: url("./svg/top-toolbar.svg") !important; } #ucf-additional-bottom-toggle-button { list-style-image: url("./svg/bottom-toolbar.svg") !important; } #ucf-view-history-sidebar-button { list-style-image: url("./svg/history-16.svg") !important; } #ucf-view-bookmarks-sidebar-button { list-style-image: url("./svg/bookmark-16.svg") !important; } #ucf-open-directories-button { list-style-image: url("./svg/user-home-16.svg") !important; } #browser-bottombox:not([lwthemefooter="true"]):-moz-lwtheme { background-color: transparent !important; } #ucf-additional-vertical-box { background: none !important; border: none !important; box-shadow: none !important; position: relative !important; z-index: 3 !important; margin: -1px 0 !important; } #ucf-additional-top-bar, #ucf-additional-vertical-bar, #ucf-additional-bottom-bar { -moz-appearance: none !important; appearance: none !important; padding: 0 !important; border-block: none !important; overflow: -moz-hidden-unscrollable; overflow: clip; } #ucf-additional-bottom-bar { border-top: 1px solid var(--chrome-content-separator-color, var(--toolbox-border-bottom-color, rgba(0,0,0,0.1))) !important; } #ucf-additional-bottom-bar #ucf-additional-bottom-closebutton { margin: 0 var(--toolbarbutton-outer-padding, 1px) !important; padding: var(--toolbarbutton-inner-padding, 4px) !important; } #ucf-additional-bottom-bar #ucf-additional-bottom-closebutton .toolbarbutton-icon { margin: 0 !important; padding: 0 !important; height: 16px !important; width: 16px !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar, #ucf-additional-bottom-bar { -moz-window-dragging: no-drag !important; background-clip: border-box !important; background-origin: border-box !important; background-color: var(--toolbar-bgcolor, -moz-Dialog) !important; background-image: var(--toolbar-bgimage, linear-gradient(rgba(255,255,255,.15), rgba(255,255,255,.15))) !important; color: var(--toolbar-color, -moz-DialogText) !important; border-inline: none !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar { padding: 1px 0 !important; margin: 0 !important; font-size: 1rem !important; min-width: 20px !important; width: auto !important; flex-grow: 1 !important; align-items: stretch !important; justify-content: start !important; flex-direction: column !important; } :root:-moz-lwtheme[style*="--lwt-additional-images"] #navigator-toolbox { background-attachment: fixed !important; } #ucf-additional-vertical-box:-moz-lwtheme > #ucf-additional-vertical-bar, #ucf-additional-bottom-bar:-moz-lwtheme { color: var(--toolbar-color, inherit) !important; background-repeat: no-repeat, var(--lwt-background-tiling, repeat-y) !important; background-size: auto auto !important; background-attachment: fixed !important; background-position: right top, var(--lwt-background-alignment, right top) !important; background-color: transparent !important; background-image: linear-gradient(var(--toolbar-bgcolor, rgba(255,255,255,.4)), var(--toolbar-bgcolor, rgba(255,255,255,.4))), var(--lwt-header-image, var(--lwt-additional-images, none)) !important; } :root[lwtheme-image="true"] #ucf-additional-vertical-box:-moz-lwtheme > #ucf-additional-vertical-bar, :root[lwtheme-image="true"] #ucf-additional-bottom-bar:-moz-lwtheme { background-repeat: no-repeat, repeat-y !important; } :root #browser-bottombox[lwthemefooter="true"] #ucf-additional-bottom-bar:-moz-lwtheme { background-repeat: initial !important; background-attachment: initial !important; background-position: initial !important; background-color: var(--toolbar-bgcolor, rgba(255,255,255,.4)) !important; background-image: none !important; } #ucf-additional-vertical-box[vertautohide="true"]:-moz-lwtheme > #ucf-additional-vertical-bar { background-color: var(--lwt-accent-color, white) !important; } #ucf-additional-vertical-box[vertautohide="true"]:-moz-lwtheme-brighttext > #ucf-additional-vertical-bar { background-color: var(--lwt-accent-color, black) !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar:not([collapsed="true"]) { border-inline-end: 1px solid var(--chrome-content-separator-color, var(--toolbox-border-bottom-color, rgba(0,0,0,0.1))) !important; } #ucf-additional-vertical-box[v_vertical_bar_start="false"] > #ucf-additional-vertical-bar:not([collapsed="true"]) { border-inline-end: none !important; border-inline-start: 1px solid var(--chrome-content-separator-color, var(--toolbox-border-bottom-color, rgba(0,0,0,0.1))) !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar[collapsed="true"] { padding: 0 !important; border: none !important; min-width: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbaritem.toolbaritem-combined-buttons { flex-direction: column !important; margin-inline: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbaritem.toolbaritem-combined-buttons > toolbarbutton.toolbarbutton-combined > .toolbarbutton-text { padding-inline: 1px !important; margin-inline: 0 !important; min-width: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbaritem.toolbaritem-combined-buttons separator { display: none !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbarspring { min-width: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbarseparator { -moz-appearance: none !important; appearance: none !important; padding: 0 !important; margin: 2px !important; margin-top: 4px !important; margin-bottom: 0 !important; border: none !important; border-top: 1px solid currentColor !important; width: auto !important; max-width: none !important; height: 5px !important; min-height: 5px !important; max-height: 5px !important; opacity: 0.3 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > toolbarspacer { height: 15px !important; } #ucf-additional-vertical-container { display: flex !important; } #ucf-additional-vertical-container[vertautohide="true"] { position: relative !important; min-width: 100px !important; width: 100px !important; max-width: 100px !important; overflow: visible !important; margin-inline-start: 0 !important; margin-inline-end: -100px !important; pointer-events: none !important; visibility: hidden !important; } #ucf-additional-vertical-container[vertautohide="true"][v_vertical_bar_start="false"] { margin-inline-start: -100px !important; margin-inline-end: 0 !important; } #ucf-additional-vertical-box[vertautohide="true"] { position: absolute !important; display: block !important; top: 0 !important; bottom: 0 !important; left: 0 !important; right: auto !important; font-size: 0px !important; } #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"], #ucf-additional-vertical-box[vertautohide="true"]:-moz-locale-dir(rtl) { left: auto !important; right: 0 !important; } #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"]:-moz-locale-dir(rtl) { left: 0 !important; right: auto !important; } #ucf-additional-vertical-box[vertautohide="true"] > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: calc(-1 * (100% - 5px)); right: auto; opacity: 0; animation-name: toolbar-hide !important; animation-timing-function: linear !important; animation-duration: 0.2s !important; animation-iteration-count: 1 !important; animation-delay: 0s !important; transition-property: opacity !important; transition-timing-function: step-start !important; transition-duration: 0s !important; transition-delay: 0.2s !important; pointer-events: auto !important; height: 100% !important; visibility: visible !important; position: relative !important; } #ucf-additional-vertical-box[vertautohide="true"]:-moz-locale-dir(rtl) > #ucf-additional-vertical-bar:not([collapsed="true"]), #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"] > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: auto; right: calc(-1 * (100% - 5px)); animation-name: toolbar-hide-rtl !important; } #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"]:-moz-locale-dir(rtl) > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: calc(-1 * (100% - 5px)); right: auto; animation-name: toolbar-hide !important; } #ucf-additional-vertical-container > #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_visible] > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: 0px; right: auto; opacity: 1; animation-name: toolbar-visible !important; transition-delay: 0s !important; } #ucf-additional-vertical-container > #ucf-additional-vertical-box[vertautohide="true"]:-moz-locale-dir(rtl)[v_vertical_bar_visible] > #ucf-additional-vertical-bar:not([collapsed="true"]), #ucf-additional-vertical-container > #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"][v_vertical_bar_visible] > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: auto; right: 0px; animation-name: toolbar-visible-rtl !important; } #ucf-additional-vertical-container > #ucf-additional-vertical-box[vertautohide="true"][v_vertical_bar_start="false"]:-moz-locale-dir(rtl)[v_vertical_bar_visible] > #ucf-additional-vertical-bar:not([collapsed="true"]) { left: 0px; right: auto; animation-name: toolbar-visible !important; } @keyframes toolbar-hide { from { left: 0px; } to { left: calc(-1 * (100% - 5px)); } } @keyframes toolbar-hide-rtl { from { right: 0px; } to { right: calc(-1 * (100% - 5px)); } } @keyframes toolbar-visible { from { left: calc(-1 * (100% - 5px)); } to { left: 0px; } } @keyframes toolbar-visible-rtl { from { right: calc(-1 * (100% - 5px)); } to { right: 0px; } } :root[inDOMFullscreen] #ucf-additional-vertical-box > #ucf-additional-vertical-bar:not([collapsed="true"]), :root[inFullscreen]:not([OSXLionFullscreen]) #ucf-additional-vertical-box > #ucf-additional-vertical-bar:not([collapsed="true"]):not([fullscreentoolbar="true"]), #ucf-additional-bottom-bar[collapsed="true"][customizable="true"][customizing="true"] { visibility: collapse !important; padding: 0 !important; border: none !important; min-width: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > #personal-bookmarks { width: 0 !important; flex-grow: 0 !important; margin: 0 !important; } #ucf-additional-vertical-box > #ucf-additional-vertical-bar > #search-container { width: 0 !important; max-height: 0 !important; overflow-y: visible !important; flex-grow: 0 !important; min-width: 80px !important; margin: 0 !important; } :root[chromehidden~="location"][chromehidden~="toolbar"] #ucf-additional-vertical-container { display: none !important; } @supports (fill: color-mix(in srgb, currentColor 20%, transparent)) { #ucf-restart-app { fill: color-mix(in srgb, currentColor 20%, #f38725) !important; } } |
Black_Monk > 02-08-2023 11:48:20 |
kokoss, у меня vertical_top_bottom_bar.css аналогичный, но нижней панели нет. |
kokoss > 02-08-2023 12:21:36 |
Black_Monk |
Black_Monk > 02-08-2023 12:49:32 |
kokoss пишет
Этот блок у меня в vertical_top_bottom_bar.js уже есть... |
Dumby > 02-08-2023 16:04:15 |
kokoss Если предположение верно, тогда мог просто накрыться сам UCF, Ну, и ещё, напомнить, что лучше заранее удалить |
Black_Monk > 02-08-2023 16:36:35 |
Dumby пишет
Да, так и есть... Dumby пишет
Да помогло, огромное спасибо. И vertical_top_bottom_bar.css не пришлось править... Dumby пишет
А это как сделать? Я честно говоря, даже не понял о чём вы... |
kokoss > 02-08-2023 16:48:45 |
Dumby Dumby пишет
У меня без этой правки не работал UCF, а у него только нижняя панель, поэтому даже не подумал про эту правку! |
kokoss > 02-08-2023 17:40:45 |
Black_Monk пишет
Видимо про это -> var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); |
unter_officer > 02-08-2023 18:32:30 |
kokoss пишет
А если так: ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); |
kokoss > 02-08-2023 18:42:36 |
unter_officer пишет
Откуда ж мне знать, у меня нет 117! |
Dumby > 02-08-2023 20:33:38 |
unter_officer пишет
Конечно удалять. По этому адресу теперь больше ничего нет. Если сомнение в том, а как же совместимость кода с лисицами древнее чем 104, Ещё возможен кейс, где импорт идёт через Cu.import() и не по назначению, а для получения NSVO |
unter_officer > 02-08-2023 22:08:16 |
Dumby пишет
Dumby, спасибо. Правда я пока не планирую переходить на Windows 10+, поэтому FF117+ мне не грозит. |
Black_Monk > 03-08-2023 07:18:40 |
Dumby, kokoss, спасибо за помощь... |
Dobrov > 03-08-2023 11:29:17 |
to_Alls свёл в один скрипт перехват нажатий клавиш от Dumby (немного изменил), может пригодиться! синтаксис: Имя(_mod)(_OS) справка в коде Выделить код Код:(async anim => { // Для докум. окна браузера [ChromeOnly] var klaBa = { /* блок перехвата нажатиий клавиш синтаксис: Имя[_mod][_OS](e,t){код} e = Event, t = gBrowser.selectedTab Откройте боковую панель и смотрите коды нажатий клавиш в консоли имя со строчной буквы: передавать нажатия окну, запрет preventDefault() mod содержит «I» — запуск только в полях ввода, «i» кроме полей ввода отделять «_» от кода клавиши при наличии модификаторов и/или «iI»-флага OS только для указанной системы: KeyA_1i_win(e,t){… //Alt+A для Windows Ссылка: "имя нужной функции": digit1() {код}, numpad1: "digit1" */ Digit1() { console.log("Digit1 Page+Input"); }, digit2() { console.log("digit2 skip preventDefault"); }, Digit3_I() { console.log("Digit3 Only Input"); }, Digit4_i() { console.log("Digit4 Skip Input"); }, Digit5: "Digit1", //ссылка на функцию Digit6_win(e, t) { console.log("Digit6_I Windows Only"); }, Digit6_linux(e, t) { console.log("Digit6_I Linux Only"); }, }; ((obj, re, reos, del) => { // парсинг блока клавиш ускоряет обработку нажатий var {platform} = AppConstants, num = -platform.length - 1; for(var p in klaBa) reos.test(p) && del.add( p.endsWith(platform) ? p.slice(0, num) : p); for(var p in klaBa) del.has(klaBa[p]) && del.add(p); for(var d of del) delete klaBa[d]; //есть Key_OS ? удалить имена-клоны for(var p in klaBa) if (reos.test(p)) { //убрать имя вашей ОС из свойства klaBa[p.replace(reos,'')] = klaBa[p]; delete klaBa[p];} for(var p in klaBa) { // парсинг функция(){…}, bool, num var func = klaBa[p]; if (typeof func == "string") func = klaBa[func]; //ссылка на функцию var [key, mod] = p.split("_"); mod = mod || ""; var upper = key[0].toUpperCase(); var prevent = key[0] == upper; // bool: True если имя с Заглавной. если false: Skip preventDefault var [, m, i] = mod.match(re); m = m || 0; // modifiers bitmap var arr = [func, prevent, i ? i == "I" ? 0 : 1 : -1]; // textfields flag var prop = prevent ? key : upper + key.slice(1); //имя клавиши без модификаторов var o = obj[prop] || (obj[prop] = Object.create(null)); o[m] ? o[m].push(arr) : o[m] = [arr]; } klaBa = obj; // нет Ii -1 везде, Имя_I = 0 в полях ввода, Имя_i 1 кроме полей ввода })(Object.create(null), /(\d+)?(i)?/i, /_(?:win|linux|macosx)$/, new Set()); var Debug = (id = "sidebar-box") => !document.getElementById(id).hidden, keydown_w = e => { // перехват клавиш if (e.repeat) return; // повтор: выход var mod = e.metaKey*8 + e.ctrlKey*4 + e.shiftKey*2 + e.altKey; if (e.keyCode > 31 && Debug()) console.log(`■ key ${mod ? e.code +"_"+ mod : e.code}`); //показ клавиш var data = klaBa[e.code]?.[mod]; if (!data) return; for(var [func, p, i] of data) if (i ^ docShell.isCommandEnabled("cmd_insertText")) p && e.preventDefault(), func(e, gBrowser.selectedTab); //запуск по сочетанию }; var args = ["keydown", e => { keydown_w(e)}, true]; window.addEventListener(...args); var id = Symbol(), ucf = ucf_custom_script_win; ucf.unloadlisteners.push(id); ucf[id] = {destructor: () => window.removeEventListener(...args)}; })({animate: true}); |
b0ttle > 03-08-2023 20:54:49 |
Dumby Что делать? Если уберут в 117, придется обходиться таким? Выделить код Код:var p=Services.dirsvc.get('UChrm',Ci.nsIFile);p.initWithPath(p.path+"...");p.launch(); |
Dumby > 03-08-2023 22:00:39 |
Dobrov пишет
Вот это мне не нравится. Даже если вернуть на место и повторить под Debug()-условием, то всё равно, Лучше бы что-нибудь другое для просмотра кода клавиш придумать. Набросок кода для добавления в предоставленный, перед последней строкой. скрытый текст Выделить код Код:// Ctrl+Shift+0 (klaBa.Digit0 = klaBa.Digit0 || (klaBa.Digit0 = Object.create(null)))[6] = [[e => { var df = MozXULElement.parseXULToFragment(` <panel onpopuphidden="destroy()" onpopupshown="pos()" oncommand="cmd(event)"> <hbox style="font-size: 20px; padding: .5em;"> <label style="min-width: 14em; border: 1px solid gray; display: flex; align-items: center; justify-content: center;"/> <button label="P" tooltiptext="Toggle skip preventDefailt()" style="min-width: 2em;"/> <button label="i" tooltiptext="Ignore textfields" style="min-width: 2em;"/> <button label="I" tooltiptext="Only textfields" style="min-width: 2em;"/> <box style="width: 1em;"/> <button label="W" tooltiptext="Windows" style="min-width: 2em;"/> <button label="L" tooltiptext="Linux" style="min-width: 2em;"/> <button label="M" tooltiptext="Mac" style="min-width: 2em;"/> <box style="width: 1em;"/> <button label="Copy"/> </hbox> </panel> `); var code, mods, os; var panel = df.firstChild, label = df.querySelector("label"); panel.remove(); var setLabel = () => label.value = [code, mods, os].filter(Boolean).join("_"); var kw = keydown_w; panel.destroy = () => panel.remove(keydown_w = kw); panel.pos = () => { var {width, height} = panel.getOuterScreenRect(); var aw = screen.availWidth - width; panel.moveTo(aw/2, screen.availHeight/3); panel.style.removeProperty("opacity"); } panel.cmd = e => { var lab = e.target.label; if (lab == "Copy") navigator.clipboard.writeText(label.value), panel.hidePopup(); else commands[lab](), setLabel(); } var re = /i/i, commands = { P() { var first = code[0]; var upper = first.toUpperCase(); first = first == upper ? first.toLowerCase() : upper; code = first + code.slice(1); }, i: (flag = "i") => re.test(mods) ? mods = mods.replace(re, mods.includes(flag) ? "" : flag) : mods += flag, I: () => commands.i("I"), W: (pl = "win") => os = os == pl ? "" : pl, L: () => commands.W("linux"), M: () => commands.W("macosx") }; var handleKeydown = e => { e.preventDefault(); e.stopImmediatePropagation(); if (e.repeat) return; os = ""; code = e.code || ""; mods = e.metaKey*8 + e.ctrlKey*4 + e.shiftKey*2 + e.altKey || ""; //if (!mods && code == "Escape") return panel.hidePopup(); setLabel(); } // end of lazy stuff (klaBa.Digit0[6][0][0] = () => { panel.style.setProperty("opacity", "0", "important"); mainPopupSet.append(panel); panel.openPopupAtScreen(); (keydown_w = handleKeydown)(e); })(); }, false, -1]]; b0ttle пишет
Нисколько не похоже. Эту плюшку просто выбросили в 116 |
OmTatSat > 03-08-2023 22:34:51 |
Здравствуйте, возможно ли на страницу about:addons вернуть поиск - фильтр установленных дополнений, как когда-то давно в Firefox по дефолту было? |
b0ttle > 03-08-2023 23:37:18 |
Dumby Выделить код Код:try{var closer={observe:(s,topic,data)=>{if(topic=="quit-application"){ //const clipboard=Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);clipboard.emptyClipboard(clipboard.kGlobalClipboard);//Clear clipboard FileUtils.getFile("UChrm",["user_chrome_files","_","sqlite[Fx].vbs"]).launch();//Run external script }}};Services.obs.addObserver(closer,"quit-application",false);}catch(ex){} По ссылке на баг, прочитал такое "IOUtils and PathUtils offers async alternatives", но дуб дубом в этом. Это что-то вроде замены FileUtils.getFile()? |
Northtech > 04-08-2023 00:13:02 |
В последних версиях пропали интервалы из add_toolbar_buttons@vitaliy.ru.xpi. Остался только растягивающийся интервал. Можно ли это как то поправить? скрытый текст special_widget.css: Выделить код Код:@-moz-document url("chrome://browser/content/browser.xhtml") { toolbarpaletteitem[place="palette"] > toolbarspring[id^="customizableui-special-spring"] { background: white url("./svg/spring.svg") center no-repeat !important; border: none !important; outline: 1px solid currentColor !important; outline-offset: -1px !important; min-height: 37px !important; opacity: 0.3 !important; } toolbarpaletteitem[place="toolbar"] > toolbarspring[id^="customizableui-special-spring"] { background: white url("./svg/spring.svg") center no-repeat !important; border: none !important; min-width: 34px !important; min-height: 14px !important; outline: 1px solid currentColor !important; outline-offset: -1px !important; margin-block: 2px !important; margin-inline: 1px !important; opacity: 0.3 !important; } toolbarpaletteitem[place="palette"] > toolbarspacer[id^="customizableui-special-spacer"] { background: white !important; border: none !important; outline: 1px solid currentColor !important; outline-offset: -1px !important; min-height: 37px !important; width: 15px !important; max-width: 15px !important; opacity: 0.3 !important; } toolbarpaletteitem[place="toolbar"] > toolbarspacer[id^="customizableui-special-spacer"] { background: white !important; border: none !important; outline: 1px solid currentColor !important; outline-offset: -1px !important; min-height: 14px !important; width: 15px !important; margin-block: 2px !important; margin-inline: 1px !important; opacity: 0.3 !important; } toolbarseparator[id^="customizableui-special-separator"] { -moz-appearance: none !important; appearance: none !important; padding: 0 !important; margin: 2px !important; margin-inline-start: 4px !important; margin-inline-end: 0 !important; border: none !important; border-inline-start: 1px solid currentColor !important; min-width: 5px !important; width: 5px !important; max-width: 5px !important; opacity: 0.3 !important; } toolbar[orient="vertical"] toolbarseparator[id^="customizableui-special-separator"] { margin-inline-start: 2px !important; margin-inline-end: 2px !important; margin-top: 4px !important; margin-bottom: 0 !important; border-top: 1px solid currentColor !important; border-inline-start: none !important; width: auto !important; max-width: none !important; height: 5px !important; min-height: 5px !important; max-height: 5px !important; } toolbarpaletteitem[place="palette"] > toolbarseparator[id^="customizableui-special-separator"] { margin: 0 !important; min-height: 37px !important; } toolbarpaletteitem[place] > toolbarspring[id^="customizableui-special-spring"], toolbarpaletteitem[place] > toolbarspacer[id^="customizableui-special-spacer"], toolbarpaletteitem[place] > toolbarseparator[id^="customizableui-special-separator"] { -moz-window-dragging: no-drag !important; } toolbar:not(#nav-bar) toolbarpaletteitem[place="toolbar"][id^="wrapper-customizableui-special-spring"], toolbar:not(#nav-bar) toolbarspring { max-width: none !important; } toolbarpaletteitem[place="palette"][id^="wrapper-customizableui-special-spacer"], toolbarpaletteitem[place="palette"][id^="wrapper-customizableui-special-separator"] { -moz-box-align: center !important; box-align: center !important; align-items: center !important; text-align: center !important; } } |
b0ttle > 04-08-2023 01:36:50 |
Northtech special_widget.css Выделить код Код:@-moz-document url("chrome://browser/content/browser.xhtml") { toolbarpaletteitem[place="palette"] > toolbarspring[id^="customizableui-special-spring"] { background: white url("../vertical_top_bottom_bar/svg/spring.svg") center no-repeat !important; border: none !important; outline: 1px solid currentColor !important; outline-offset: -1px !important; min-height: 37px !important; opacity: 0.3 !important; } toolbarpaletteitem[place="toolbar"] > toolbarspring[id^="customizableui-special-spring"] { background: white url("./svg/spring.svg") center no-repeat !important; border: none !important; min-width: 34px !important; min-height: 14px !important; outline: 1px solid currentColor !important; outline-offset: -1px !important; margin-block: 2px !important; margin-inline: 1px !important; opacity: 0.3 !important; } toolbarpaletteitem[place="palette"] > toolbarspacer[id^="customizableui-special-spacer"] { background: white !important; border: none !important; outline: 1px solid currentColor !important; outline-offset: -1px !important; min-height: 37px !important; width: 15px !important; max-width: 15px !important; opacity: 0.3 !important; } toolbarpaletteitem[place="toolbar"] > toolbarspacer[id^="customizableui-special-spacer"] { background: white !important; border: none !important; outline: 1px solid currentColor !important; outline-offset: -1px !important; min-height: 14px !important; width: 15px !important; margin-block: 2px !important; margin-inline: 1px !important; opacity: 0.3 !important; } toolbarseparator[id^="customizableui-special-separator"] { -moz-appearance: none !important; appearance: none !important; padding: 0 !important; margin: 2px !important; margin-inline-start: 4px !important; margin-inline-end: 0 !important; border: none !important; border-inline-start: 1px solid currentColor !important; min-width: 5px !important; width: 5px !important; max-width: 5px !important; opacity: 0.3 !important; } toolbar[orient="vertical"] toolbarseparator[id^="customizableui-special-separator"] { margin-inline-start: 2px !important; margin-inline-end: 2px !important; margin-top: 4px !important; margin-bottom: 0 !important; border-top: 1px solid currentColor !important; border-inline-start: none !important; width: auto !important; max-width: none !important; height: 5px !important; min-height: 5px !important; max-height: 5px !important; } toolbarpaletteitem[place="palette"] > toolbarseparator[id^="customizableui-special-separator"] { margin: 0 !important; min-height: 37px !important; } toolbarpaletteitem[place] > toolbarspring[id^="customizableui-special-spring"], toolbarpaletteitem[place] > toolbarspacer[id^="customizableui-special-spacer"], toolbarpaletteitem[place] > toolbarseparator[id^="customizableui-special-separator"] { -moz-window-dragging: no-drag !important; } toolbar:not(#nav-bar) toolbarpaletteitem[place="toolbar"][id^="wrapper-customizableui-special-spring"], toolbar:not(#nav-bar) toolbarspring { max-width: none !important; } toolbarpaletteitem[place="palette"][id^="wrapper-customizableui-special-spacer"], toolbarpaletteitem[place="palette"][id^="wrapper-customizableui-special-separator"] { align-items: center !important; } } Это стиль, еще есть скрипт который добавляет сами интервалы. Если без стиля, они переносятся на панели, просто без обертки в виде стиля будут невидимы. Собственно, у меня все интервалы есть на 116, через ucf. |
Dobrov > 04-08-2023 04:37:37 |
Dumby пишет
Это всё конечно хорошо, но многовато дублирующего кода - в однократном парсинге и коде просмотра клавиш одинаковая обработка модификаторов и постфиксов на ОС. А если использовать предпросмотр нажатий, то код панельки пригодится вынести отдельно - в ней и нажатия мыши удобно просматривать и вывод отладки или сообщения об ошибках… Ещё вот вариант простого синтаксиса клавиш, сложнее в восприятии, но проще для кода парсинга: Переделал обработчик нажатий клавиш, проверь, так лучше? Выделить код Код:var keydown_win = e => { // перехват клавиш, учитывая поля ввода if (e.repeat || !prefs.getBoolPref('javascript.enabled',1)) return; // повтор|скрипты OFF: выход var data = klaBa[e.code]?.[e.metaKey*8 + e.ctrlKey*4 + e.shiftKey*2 + e.altKey]; if (data) for(var [func, p, i] of data) if (i ^ docShell.isCommandEnabled("cmd_insertText")) p && e.preventDefault(), func(e, gBrowser.selectedTab); //запуск по сочетанию if (!Debug()) return; // отладки нет var mod = e.metaKey*8 + e.ctrlKey*4 + e.shiftKey*2 + e.altKey; console.log(`■ key ${mod ? e.code +"_"+ mod : e.code}`); //показ клавиш } |
Viatcheslav > 04-08-2023 06:22:17 |
Поделитесь, пожалуйста, рабочим вариантом |
xrun1 > 04-08-2023 10:29:18 |
Northtech пишет
У меня всегда было их два, "Растягивающийся пробел" первый и последний в списке. Остальные тоже на месте. https://imgsh.net/a/rqWJYGc.png скрытый текст Выделить код Код:box-align: center !important; align-items: center !important; text-align: center !important; Вот мой add_toolbar_buttons@vitaliy.ru.xpi |
kokoss > 04-08-2023 11:12:29 |
Viatcheslav |
Viatcheslav > 04-08-2023 11:33:33 |
kokoss пишет
Спасибо, но мне не для панели поиска Findbar (поиск на странице), |
kokoss > 04-08-2023 11:41:23 |
Viatcheslav |
xrun1 > 04-08-2023 11:43:21 |
kokoss |
Viatcheslav > 04-08-2023 11:57:32 |
xrun1 пишет
Спасибо, но там много лишнего... |
kokoss > 04-08-2023 11:59:50 |
Viatcheslav пишет
Достаточно этого: скрытый текст Выделить код Код:// Очистить панель адреса или поиска прокруткой колёсиком мыши на панели // https://forum.mozilla-russia.org/viewtopic.php?pid=788229#p788229 (this.clearsearchurlbar = { init(that) { for (let el of (this.urlsearcbar = document.querySelectorAll("#urlbar,#searchbar"))) el.addEventListener("wheel", this); that.unloadlisteners.push("clearsearchurlbar"); }, handleEvent(e) { e.target.value = ""; }, destructor() { for (let el of this.urlsearcbar) el.removeEventListener("wheel", this); }, }).init(this); |
Viatcheslav > 04-08-2023 19:51:27 |
kokoss пишет
Не знаю, в чём дело, но не работает 04-08-2023 19:58:52 kokoss пишет
Слава Богу, хоть это сработало |
kokoss > 04-08-2023 20:09:22 |
Viatcheslav пишет
У меня при добавлении в custom_script_win.js тоже не работает в строке поиска, только в адресной строке, поэтому предложил ATB. |
Dumby > 05-08-2023 06:25:55 |
b0ttle пишет
Здесь, наверно, упор скорее на «async», Вобщем, как-то так скрытый текст Выделить код Код:(async parts => Services.obs.addObserver(function quit(s, topic, data) { Services.obs.removeObserver(quit, topic); //if (data == "restart") return; var file = Services.dirsvc.get("UChrm", Ci.nsIFile); parts.forEach(file.append); file.launch(); }, "quit-application"))(["user_chrome_files", "_", "sqlite[Fx].vbs"]); Dobrov пишет
Да, так чуть лучше.
Четыре сущности разделённые запятой. Функция и три примитива. kokoss пишет
Если под «при добавлении» имеется в виду добавление в конец, Код предназначен быть добавленным после строки Об этом как-бы намекает констукция вида (this.something = {…}).init(this); |
OmTatSat > 05-08-2023 07:46:48 |
Есть скрипт который нормально работает на странице about:addons с консоли |
Dumby > 05-08-2023 10:27:09 |
OmTatSat пишет
Допустим, создаём в папке custom_scripts Тогда, в CustomStylesScriptsChild.jsm Теперь, убеждаемся, что в настройках UCF проставлена галка Всё. Рестарт с очисткой кэша, и должно работать. Если не работает, то на Firefox, древнее чем 115,
Это предложение угадать его содержимое? |
Dobrov > 05-08-2023 12:26:31 |
Dumby пишет
Для временного отключения кода перехвата клавиш - для отладки или если в системе такие же есть. |
kokoss > 05-08-2023 12:35:24 |
Dumby пишет
Туда и добавлял, сейчас проверил -> работает, дааааа |
b0ttle > 05-08-2023 13:21:10 |
Dumby пишет
Классно, отрабатывает лучше чем было. |
Dumby > 05-08-2023 15:18:56 |
Dobrov пишет
Почему тогда именно эта настройка,
Это какая-то разновидность дискриминации? |
OmTatSat > 05-08-2023 16:26:16 |
Dumby пишет
Спасибо огромное!) Голову сломал, никак не получалось) |
Dobrov > 05-08-2023 17:09:44 |
Dumby пишет
3 уже добавлял, но в итоге в UCF только одну оставил. К javascript.enabled привязал просто как пример, кому надо, уберут!
Да, на макос с Meta+Shift+Буква много системных сочетаний, поэтому и просил постфикс операционки добавить в перехват нажатий клавиш. |
b0ttle > 05-08-2023 19:21:06 |
OmTatSat |
Dumby > 05-08-2023 19:23:53 |
OmTatSat пишет
Не понял. Что значит «пришлось» ? UCF либо развёрнут, либо нет. Остальное, иные uc-экосистемы, или CB, могут и должны Dobrov пишет
Другое дело. |
OmTatSat > 05-08-2023 21:33:49 |
b0ttle пишет
кстати оказалось, они оба вместе живут себе)) просто конфиг config.js который в папке Firefox я сначала заменил на UCF а потом решил попробовать объединить, и волшебным образом завелось) скрытый текст Выделить код Код:// UserChromeFiles Vitaliy V. http://forum.mozilla-russia.org/viewtopic.php?id=76642 lockPref('xpinstall.signatures.required', false); lockPref('extensions.install_origins.enabled', false); try { let cmanifest = Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties).get('UChrm', Ci.nsIFile); cmanifest.append('utils'); cmanifest.append('chrome.manifest'); Components.manager.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(cmanifest); Cu.import('chrome://userchromejs/content/BootstrapLoader.jsm'); } catch (ex) {}; try { Cu.import('chrome://userchromejs/content/userChrome.jsm'); } catch (ex) {}; (async () => { Cu.evalInSandbox(` var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"), user_chrome_files_sandbox = { init() { Services.obs.addObserver(this, "domwindowopened"); Services.obs.addObserver(this, "profile-after-change"); }, observe(aWindow, aTopic, aData) { Services.obs.removeObserver(this, "profile-after-change"); this.observe = (window, topic, data) => { if (!(window instanceof Ci.nsIDOMChromeWindow)) return; var docElementInserted = e => { var win = e.target.defaultView; if (win instanceof Ci.nsIDOMChromeWindow) user_chrome.initWindow(win); }; window.windowRoot.addEventListener("DOMDocElementInserted", docElementInserted, true); window.addEventListener("load", e => { window.addEventListener("unload", e => { window.windowRoot.removeEventListener("DOMDocElementInserted", docElementInserted, true); }, { once: true }); }, { once: true }); }; var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("user_chrome_files"); file.append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) { this.removeObs(); return; } try { Components.manager.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(file); Services.scriptloader.loadSubScript("chrome://user_chrome_files/content/user_chrome.js", globalThis, "UTF-8"); } catch(ex) { this.removeObs(); return; } if (aTopic === "domwindowopened") this.observe(aWindow, aTopic, aData); }, removeObs() { Services.obs.removeObserver(this, "domwindowopened"); }, }; user_chrome_files_sandbox.init();`, Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal), { wantComponents: true, sandboxName: "UserChromeFiles", wantGlobalProperties: ["ChromeUtils"],})); })(); 05-08-2023 21:43:17 Dumby пишет
Я скриптами разбираюсь на аматорском уровне, может и не правильно термин применил) 05-08-2023 22:00:24 Выделить код Код:// Создание элементов const input = document.createElement('input'); input.id = 'search'; input.type = 'text'; const button = document.createElement('button'); button.id = 'filter'; button.innerText = 'Найти'; const search = document.querySelector('.main-search > search-addons:nth-child(2)'); // Прикрепление к нужному элементу search.appendChild(input); search.appendChild(button); // Обработчики событий button.addEventListener('click', () => { const searchTerm = input.value; filterElements(""); filterElements(searchTerm); }); input.style.position = 'relative'; input.style.zIndex = '999'; input.style.left = '300px'; input.style.top = '-37px'; input.style.maxheight = '13px'; input.style.height = '15px'; button.style.position = 'relative'; button.style.zIndex = '999'; button.style.left = '300px'; button.style.top = '-35px'; button.style.height = '20px'; function filterElements(searchTerm) { const names = document.querySelectorAll('h3.addon-name a.addon-name-link'); const descs = document.querySelectorAll('.addon-description'); descs.forEach((desc, i) => { console.log('Проверяем элемент', desc); const textElem = desc.firstChild; if (!textElem) { const text = "emp"; foundDesc = false; } else { text = textElem.textContent; foundDesc = text.includes(searchTerm); ;console.log('описание:', text , 'foundDesc' , foundDesc); } const name = names[i]; if (!name ) { return } const nametext = name.textContent; let foundName = name.textContent.toLowerCase().includes(searchTerm); ; console.log('название:', nametext , 'foundName' , foundName , 'описание:', text , 'foundDesc' , foundDesc); if (!foundName && !foundDesc) { name.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.style.display = 'none'; console.log('Скрываем название:', nametext , 'foundName' , foundName , 'описание:', text , 'foundDesc' , foundDesc); } else { name.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.style.display = 'unset'; console.log('Показываем название:', nametext , 'foundName' , foundName , 'описание:', text , 'foundDesc' , foundDesc); } }); } |
b0ttle > 05-08-2023 23:29:53 |
OmTatSat |
OmTatSat > 06-08-2023 08:30:49 |
b0ttle пишет
Хз) смотря что вы считаете странностью |
antialt > 07-08-2023 09:11:04 |
Подскажите, как вернуть к жизни Add Toolbar Buttons в FF 117 ? |
fuchsfan > 07-08-2023 17:00:08 |
@Dumby |
stvol > 07-08-2023 17:53:00 |
Dumby пишет
А где это надо менять? |
kokoss > 07-08-2023 18:04:46 |
stvol пишет
|
Dumby > 07-08-2023 19:56:28 |
fuchsfan пишет
Что значит «исправить»? Вобщем, меняем первую и последнюю (не пустую) строку на такие И, вместо методов init() и destructor() один только init(), такой: скрытый текст Выделить код Код:// init(type) { window.addEventListener(type, this); window.addEventListener("unload", () => window.removeEventListener(type, this) , {once: true}); }, И про special_widget.css не забываем. |
antialt > 07-08-2023 20:38:29 |
antialt пишет
Спасибо за ответ Dumby в личке
фикс для ff 117+ |
fuchsfan > 08-08-2023 09:59:51 |
Dumby пишет
В навбаре все нормально, а в вертикальном аддонбаре https://github.com/Aris-t2/CustomJSforF … ical.uc.js линии-разделители видны, а промежутки не видны. |
Dumby > 08-08-2023 11:58:33 |
fuchsfan Чтобы «промежутки» было видно на этом вертикальном аддонбаре, toolbar#addonbar_v > toolbarspacer { |
fuchsfan > 08-08-2023 15:19:30 |
Dumby пишет
Пристроил, наконец-то все пошло, благодарю. 08-08-2023 15:43:30 |
kokoss > 08-08-2023 16:44:38 |
fuchsfan пишет
|
fuchsfan > 08-08-2023 18:42:35 |
kokoss пишет
Сработало, все как надо, благодарю за помощь. Вопрос закрыт. |
Dobrov > 09-08-2023 16:00:14 |
Обновил ucf_hookClicks.js - изменений много, вот некоторые: 1) проще редактировать свои сочетания клавиш, добавлены клики мыши на вкладках: Закрыть все слева/справа. |
fuchsfan > 24-08-2023 17:22:34 |
Verevkin пишет
У меня он такой скрытый текст Выделить код Код://config.js для user_chrome_files (UCF) (async () => { var sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal), { wantComponents: true, sandboxName: "UserChromeFiles", wantGlobalProperties: ["ChromeUtils"], }); Cu.evalInSandbox(` var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var user_chrome_files_sandbox = { init() { Services.obs.addObserver(this, "domwindowopened"); Services.obs.addObserver(this, "profile-after-change"); }, observe(aWindow, aTopic, aData) { Services.obs.removeObserver(this, "profile-after-change"); this.observe = (window, topic, data) => { if (!(window instanceof Ci.nsIDOMChromeWindow)) return; var docElementInserted = e => { var win = e.target.defaultView; if (win instanceof Ci.nsIDOMChromeWindow) user_chrome.initWindow(win); }; window.windowRoot.addEventListener("DOMDocElementInserted", docElementInserted, true); window.addEventListener("load", e => { window.addEventListener("unload", e => { window.windowRoot.removeEventListener("DOMDocElementInserted", docElementInserted, true); }, { once: true }); }, { once: true }); }; var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("user_chrome_files"); file.append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) { this.removeObs(); return; } try { Components.manager.QueryInterface(Ci.nsIComponentRegistrar) .autoRegister(file); Services.scriptloader.loadSubScript("chrome://user_chrome_files/content/user_chrome.js", globalThis, "UTF-8"); } catch(ex) { this.removeObs(); return; } if (aTopic === "domwindowopened") this.observe(aWindow, aTopic, aData); }, removeObs() { Services.obs.removeObserver(this, "domwindowopened"); }, }; user_chrome_files_sandbox.init(); `, sandbox); })(); |
xrun1 > 24-08-2023 17:57:27 |
fuchsfan |
fuchsfan > 24-08-2023 18:52:39 |
xrun1 пишет
То был файл из v115. А вот этот из v116, с ним у меня работает ucf с панелью, а какой он свжести фиг его знает. скрытый текст Выделить код Код:// config.js для user_chrome_files (UCF) (код уже исправлен для работы в v117 - ниже закомментирована строка #9 импорта модуля Services.jsm, ее можно всю удалить) (async () => { var sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal), { wantComponents: true, sandboxName: "UserChromeFiles", wantGlobalProperties: ["ChromeUtils"], }); Cu.evalInSandbox(` // var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var user_chrome_files_sandbox = { init() { Services.obs.addObserver(this, "domwindowopened"); Services.obs.addObserver(this, "profile-after-change"); }, observe(aWindow, aTopic, aData) { Services.obs.removeObserver(this, "profile-after-change"); this.observe = (window, topic, data) => { if (!(window .isChromeWindow)) return; var docElementInserted = e => { var win = e.target.defaultView; if (win .isChromeWindow) user_chrome.initWindow(win); }; window.windowRoot.addEventListener("DOMDocElementInserted", docElementInserted, true); window.addEventListener("load", e => { window.addEventListener("unload", e => { window.windowRoot.removeEventListener("DOMDocElementInserted", docElementInserted, true); }, { once: true }); }, { once: true }); }; var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("user_chrome_files"); file.append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) { this.removeObs(); return; } try { Components.manager.QueryInterface(Ci.nsIComponentRegistrar) .autoRegister(file); Services.scriptloader.loadSubScript("chrome://user_chrome_files/content/user_chrome.js", globalThis, "UTF-8"); } catch(ex) { this.removeObs(); return; } if (aTopic === "domwindowopened") this.observe(aWindow, aTopic, aData); }, removeObs() { Services.obs.removeObserver(this, "domwindowopened"); }, }; user_chrome_files_sandbox.init(); `, sandbox); })(); |
kokoss > 24-08-2023 19:43:05 |
fuchsfan пишет
Версию можно узнать в user_chrome_files/текстовый файл -> version |
xrun1 > 25-08-2023 10:37:37 |
fuchsfan |
Verevkin > 25-08-2023 12:20:50 |
Спасибо, мужики. Буду пробовать, о результатах сообщу. |
Verevkin > 25-08-2023 18:37:27 |
fuchsfan пишет
Спасибо, вроде работает. |
kokoss > 25-08-2023 19:24:32 |
Verevkin пишет
Зачем перемещать дополнительную панель вниз, если можно использовать нижнюю панель! |
Verevkin > 25-08-2023 19:47:15 |
kokoss пишет
А как её создать? |
Verevkin > 25-08-2023 21:40:04 |
kokoss пишет
Обнаружил кнопку вызова окна настройки, но рано обрадовался: чекбоксы включаются, но перезапуск не срабатывает. Как вручную подправить конфиг, чтобы тупо появилась нижняя панель? Кроме неё мне ничего не надо. |
kokoss > 25-08-2023 22:44:34 |
Verevkin пишет
Её не надо создавать, её необходимо включить в настройках UCF + перезапустить браузер...
Может потому что используйте актуальный код в старом комплекте UCF |
vassemm > 26-08-2023 01:17:20 |
Господа! Прошу помощи в возвращении к жизни UCF в 117 версии. В 116 все работает норм.(после изменений которые были вот в этом посте https://forum.mozilla-russia.org/viewto … 69#p805869) Но беда опять пришла. Пробовал комментировать ================================================== |
fuchsfan > 26-08-2023 09:09:14 |
vassemm пишет
В настройках UCF внизу "Включить стили:", кажется, все птички должны стоять. Пробуйте закрыть браузер и руками удалить все из папки startupCache. 26-08-2023 09:11:57 26-08-2023 09:17:07 Verevkin пишет
Просто к сведению, у Aris-t2 есть горизонтальные панели, верхняя и нижняя, нижняя это https://github.com/Aris-t2/CustomJSforF … nbar.uc.js Подключается легко, работает. |
Dumby > 26-08-2023 09:34:10 |
скрытый текст Выделить код Код:data:image/png;base64,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/W1QsGOW86RUrmPrwltvH93pe8JVTQk0VsXz5z/ba62efJLZeOqpdvrq4ouzdg5UNtBYOlga65577rE+3H777dBYNKlorPu+//2bb7rp3/79N6M/OnrI4EHDhg4ebomswYOKRfLG7t1nfvyMhx5++LavfMXf39dYturoaOxZP26J/zLxQM2wmsN/37j/wdcl3gdb3ng6zDfiWLet2K8oJmKVtTOkdcKl6xjkHHONWP9671umXpgeLsVQY02aNKlQKOzbt+/dd9/92Mc+9tZbb+3YsWP48OEXXHBBwfmBeldXV0hjOcqEFj8CjfXRZ257gDgSx1Y4r09hFJW7j62HhBrLOval8x11xFj29rCNOd9xR5Us3/PiBbf7Aspy4fyXJJ7sXlUqJrAQqpoSaKzKZt06cv315I9/ZDZed529AOuDH8zaOVDxmI4Pb7399on977XiX/va13yNNX369E9S81TJYl3RoLE8jbXxhU2nnnqKpa6GDxtiYYXG0lh7/3vviJNOeuTRR+fMnu3vH6zHCuefbJo6e6oX8ZrD0yjElyo6GiswIp+VZEoPZ9GcfFWV3GA4nUb45Ba3KagjvaW0YySWxrrsssus8G7ZssWSWVbnfuWVV/bv319VVTVy5EgvWCGNtXtV6xvnX/BiJyV9uByVl0+idc/rU24f3Rns46gYwhxlp5hGlbQXba2UjfIK4mQZkWTR7C+clNStlKusJ4GUKh0lqJoSaKxK5ehRcvfdxBrZqZWIZNgwe8H7rbdm7RzoI2B80OGrX/3qokWLrA933HEH1rzTpKKxfvL445/59Kffeff9IYMHjzjpw5bAGjx4sCUCDh48eOjQoffee+/Xv/nNF//6r/39qblCh3AWR5TXcURWJ5lSygb5qokWW/xcoZ7GovNJlk6jFR6XlOIMdjZ2TClltjjN5+58x7YqzklZuSZ5rMsvv9wK74EDB1566SXiKP2hQ4deeOGF7mcS1lhTXn/ojcktn/wPRuuEVY5QY6m3+EeF81s+SWksNtPmHSWsmhKMoRXJ739vP7393/+d2XjeeaSjg4wbl7VzoO+A8UGH5cuXX3HFFdaHH/7whzfffPOECROy9simz2os60q/97//+4LzL3ht164RI0764IknDho06OjRo5bAsq79z2/cOOKkk86nHgPIa6zwxJtQczgSipTSPa4cYiYNfTvh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 |
kokoss > 26-08-2023 10:30:47 |
UCF для FF 115-116 с правками от Dumby |
Verevkin > 26-08-2023 11:51:26 |
kokoss пишет
Ну, я ж не шарю во всём этом добре. Дайте просто набор файлов для 117+, готовых к употреблению, пожалуйста. |
kokoss > 26-08-2023 12:22:22 |
Verevkin пишет
На предыдущей странице скачайте комплект UCF для 116 и сделайте правки для 117 из этого поста, затем очистите папку startupCache |
JKT > 26-08-2023 12:28:18 |
Всем здравствовать. Граждане, подскажите плиз рабочий вариант кода для установки не подписанных расширений для FF 102.9 esr |
kokoss > 26-08-2023 12:53:47 |
egorsemenov06 пишет
У вас же вроде 116, а эта правка для 117+ |
Verevkin > 26-08-2023 12:53:58 |
kokoss пишет
Скачал, извлёк из rar-архива. kokoss пишет
В посту картинка в base64 - скриншот поиска текста "Services.jsm" в файлах. Я нашёл 4 файла с таким вхождением. Что дальше? Как и где править? 26-08-2023 12:57:13 kokoss пишет
У меня 5 компов, на 2 из них Linux. Именно на них FF обновился до 117 2 дня назад и вылезла текущая проблема. |
kokoss > 26-08-2023 13:00:49 |
Verevkin пишет
Просто удалите эти строки -> var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); в этих 4 файлах, и после не забудьте очистить папку startupCache |
Verevkin > 26-08-2023 13:33:22 |
kokoss пишет
Спасибо, получилось. |
Dumby > 26-08-2023 14:44:52 |
egorsemenov06 пишет
Оно там под условием if(!("Services" in window)) Иначе это условие перейдёт на код, JKT пишет
Да нынешний вроде должен работать.
Неподписанное расширение — это "масляное масло". Расширения сто лет как не подписывают,
Для ESR 102 код не требуется, достаточно настроек |
vassemm > 26-08-2023 15:17:12 |
Уф. Странно ночью несколько раз делал тоже самое плюс очистка кэша. И ничего не работало. Тем не менее всем спасибо! |
kokoss > 28-08-2023 00:08:26 |
Verevkin пишет
скрытый текст Выделить код Код:#ucf-additional-bottom-bar { --toolbarbutton-outer-padding: 1px; --toolbarbutton-inner-padding: 2px; --toolbar-bgcolor: red; } |
xrun1 > 28-08-2023 14:40:10 |
Verevkin скрытый текст Выделить код Код:/* Сжать доп.панели https://forum.mozilla-russia.org/viewtopic.php?pid=775867#p775867 */ #ucf-additional-top-bar, #ucf-additional-bottom-bar { --toolbarbutton-outer-padding: 2px !important; /* было 0px */ --toolbarbutton-inner-padding: 2px !important; min-height: 18px !important; } :is(#ucf-additional-top-bar,#ucf-additional-bottom-bar) .toolbarbutton-badge { margin-inline-end: calc(-1 * (var(--toolbarbutton-outer-padding) + var(--toolbarbutton-inner-padding))) !important; } #ucf-additional-bottom-closebutton { padding: 0 !important; } #ucf-additional-vertical-bar { --toolbarbutton-outer-padding: 0px !important; /* это и есть ширина боковой панели; комбинируется с пар. ниже */ --toolbarbutton-inner-padding: 3px !important; / расстояние по вертикали между кнопками; комбинируется с предыдущим, лучше 3 или 5 */ min-width: 18px !important; } #ucf-additional-vertical-bar .toolbarbutton-badge { margin-inline-end: calc(-1 * (var(--toolbarbutton-outer-padding) + var(--toolbarbutton-inner-padding))) !important; } |
fuchsfan > 28-08-2023 17:07:00 |
Verevkin пишет
Нашлось такое решение. В стиле: "user_chrome_files\vertical_top_bottom_bar\vertical_top_bottom_bar.css" меняем строку на строку. |
m_nikolay > 29-08-2023 16:13:35 |
Кто-нибудь пользуется скроллбаром Aris-t2? |
xrun1 > 29-08-2023 17:31:18 |
m_nikolay скрытый текст Выделить код Код:/* изменения с 113-й; перестал работать скрипт custom_scrollbars.uc.js Здесь стиль https://forum.mozilla-russia.org/viewtopic.php?pid=804939#p804939 */ @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); @namespace html url("http://www.w3.org/1999/xhtml"); /* Ширина и наличие кнопок перемотки регулируется через about:config : * По умолчанию - 0, MacOs - 1 (без кнопок), GTK - 2 (без кнопок), * Android - 3 (без кнопок), Windows 10 - 4, Windows 11 - 5 ***//* user_pref("widget.non-native-theme.scrollbar.style", 2); себе поставил 3 // Наложенный скролбар + скрытие, через ~3сек неактивности (с метками поиска) user_pref("ui.useOverlayScrollbars", 1); /* себе параметр не создавал */ scrollbar, scrollcorner, html|select { --v-scrollbar-background-color: #E48080 !important; /* rgba(100,100,100,.4) */ --v-scrollbar-background-color-hover: #FF0000 !important; /* rgba(100,100,100,.5) */ --v-scrollbar-background-color-active: #0000BB !important; /* rgba(100,100,100,.6) */ --v-scrollbar-border-radius: 5px !important; --v-scrollbar-min-size: 7px !important; /* влияет только на размер кнопок */ --v-scrollbar-dn-image: url(".././svg/arrow-dn.svg"); --v-scrollbar-up-image: url(".././svg/arrow-up.svg"); --v-scrollbar-rit-image: url(".././svg/arrow-rit.svg"); --v-scrollbar-lft-image: url(".././svg/arrow-lft.svg"); --v-scrollbar-image-size: 5px !important; /* значок кнопок перемотки, 0 что б скрыть */ } /* ************************************************ */ /* Скроллбар, dropmarker */ scrollbar { /* -moz-appearance: none !important; appearance: none !important; /**/ background: none !important; border: none !important; padding: 0 !important; margin: 0 !important; } scrollbar[root="true"] { position: relative !important; z-index: 2147483647 !important; } scrollbar[root="true"][orient="vertical"] { margin-left: calc(-1 * var(--v-scrollbar-min-size)) !important; } scrollbar[root="true"][orient="horizontal"] { margin-top: calc(-1 * var(--v-scrollbar-min-size)) !important; } scrollcorner { -moz-appearance: none !important; appearance: none !important; width: var(--v-scrollbar-min-size) !important; height: var(--v-scrollbar-min-size) !important; background: none !important; border: none !important; } scrollbar > slider { -moz-appearance: none !important; appearance: none !important; background: #44944A !important; /* Арлекин; было none */ border: none !important; } scrollbar > slider > thumb, scrollbar > scrollbarbutton, html|*:not(html|select) > scrollbar > slider > thumb, html|select > html|button { -moz-appearance: none !important; appearance: none !important; border: none !important; border-radius: var(--v-scrollbar-border-radius) !important; background-color: var(--v-scrollbar-background-color) !important; background-image: none !important; background-repeat: no-repeat !important; background-position: center !important; background-size: var(--v-scrollbar-image-size) !important; } scrollbar[orient="vertical"], scrollbar[orient="vertical"] > slider, scrollbar[orient="vertical"] > slider > thumb { min-width: var(--v-scrollbar-min-size) !important; max-width: var(--v-scrollbar-min-size) !important; } scrollbar[orient="horizontal"], scrollbar[orient="horizontal"] > slider, scrollbar[orient="horizontal"] > slider > thumb { min-height: var(--v-scrollbar-min-size) !important; max-height: var(--v-scrollbar-min-size) !important; } scrollbar > scrollbarbutton { min-width: var(--v-scrollbar-min-size) !important; min-height: var(--v-scrollbar-min-size) !important; } scrollbar > slider > thumb:hover, scrollbar > scrollbarbutton:not([disabled="true"]):hover { background-color: var(--v-scrollbar-background-color-hover) !important; } scrollbar > slider > thumb:active, scrollbar > scrollbarbutton:not([disabled="true"]):active, html|select > html|button:active { background-color: var(--v-scrollbar-background-color-active) !important; } html|select > html|button { background-image: var(--v-scrollbar-dn-image) !important; } scrollbar > scrollbarbutton[type="increment"], html|select > html|button[orientation="right"] { background-image: var(--v-scrollbar-rit-image) !important; } scrollbar[orient="vertical"] > scrollbarbutton[type="increment"] { background-image: var(--v-scrollbar-dn-image) !important; } scrollbar > scrollbarbutton[type="decrement"], html|select > html|button[orientation="left"] { background-image: var(--v-scrollbar-lft-image) !important; } scrollbar[orient="vertical"] > scrollbarbutton[type="decrement"] { background-image: var(--v-scrollbar-up-image) !important; } scrollbar > scrollbarbutton[disabled="true"] { opacity: 0.5 !important; } P.S. Размеры у Aris-t2, наверное, тоже регулируются параметром widget.non-native-theme.scrollbar.style И у меня Win 10. Как на других OS не помню. |
m_nikolay > 29-08-2023 18:13:06 |
xrun1 |
m_nikolay > 29-08-2023 18:55:37 |
xrun1 пишет
Вот это нужная подсказка, спасибо. |
stvol > 29-08-2023 19:07:35 |
kokoss пишет
Всё сделал по рекомендациям, но не могу найти папку startupCache. kokoss пишет
И ещё: где кроме как в config.js искать эту строку? |
kokoss > 29-08-2023 19:31:29 |
stvol пишет
В профиле
|
stvol > 29-08-2023 19:45:24 |
Dumby 29-08-2023 19:50:11 kokoss пишет
Нет такой. Всё ПОЛУЧИЛОСЬ!! |
xrun1 > 29-08-2023 20:02:09 |
m_nikolay пишет
\chrome\user_chrome_files\custom_scripts\CustomStylesScripts.jsm |
kokoss > 29-08-2023 20:55:32 |
stvol пишет
Нет не во всех, а только в четырёх; помимо файла config.js, в -> options/prefs.js, в CustomStylesScripts.jsm и CustomStylesScriptsChild.jsm |
Dumby > 29-08-2023 21:09:48 |
egorsemenov06 пишет
Да, это Bug 713713 - Clean up OpenBrowserWindow скрытый текст Выделить код Код:(async (bwt, lazy) => { var TelemetryStopwatch = lazy = Object.create(null); lazy.start = lazy.finish = () => {}; ChromeUtils.defineLazyGetter(lazy, "BrowserHandler", () => Cc["@mozilla.org/browser/clh;1"].getService(Ci.nsIBrowserHandler) ); ChromeUtils.defineESModuleGetters(lazy, { HomePage: "resource:///modules/HomePage.sys.mjs", PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs" }); var bwt = ChromeUtils.importESModule(bwt).BrowserWindowTracker; Object.assign(bwt, eval(`({${bwt.openWindow}})`.replace(/\n +if \(!args &.+?}/s, ""))); })("resource:///modules/BrowserWindowTracker.sys.mjs"); |
Dumby > 30-08-2023 12:06:30 |
Упс, не туда. |
xrun1 > 30-08-2023 12:36:48 |
В 117 отвалился старый about:config Dumby, что с этим делать? |
m_nikolay > 30-08-2023 12:45:17 |
xrun1 |
Black_Monk > 30-08-2023 12:47:35 |
xrun1 пишет
Тоже с этим столкнулся. Само расширение есть, а кнопок нет... |
Farby > 30-08-2023 12:52:33 |
xrun1 пишет
можно так Выделить код Код:var Services = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services; ладно вот add_toolbar_buttons-112.2023.08.23.xpi, надеюсь ничего не упустил... |
xrun1 > 30-08-2023 12:55:29 |
Farby |
Black_Monk > 30-08-2023 13:05:55 |
Farby пишет
Ну вот и кнопки вернулись. Сенькаю! p.s. Вот только кнопка about:config при нажатии ЛКМ не срабатывает (все остальные кнопки мыши срабатывают). |
Dumby > 30-08-2023 13:33:23 |
Black_Monk пишет
Можно заменить в parent.js br.loadURI(url |
Farby > 30-08-2023 14:09:19 |
Dumby пишет
Спасибо, забрал. Почему-то в консоли ошибок не было или я опять ступил... |
xrun1 > 30-08-2023 15:39:53 |
С ATB разобрались. А что с этим делать? |
kokoss > 30-08-2023 16:19:49 |
xrun1 пишет
Может так -> const Services = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services; |
xrun1 > 30-08-2023 16:53:29 |
kokoss |
Dumby > 30-08-2023 21:05:43 |
xrun1 пишет
Я тут пробовал сконвертировать jsm в mjs, Там без файла favicon (наверняка уже свой стоит), Регистрация about:cfg — соответственно Текстовая ссылка на страницу загрузки скрытый текст Выделить код Код:data:text/html;charset=utf-8,<!DOCTYPE html>%0A<html>%0A%09<head>%0A%09%09<title>aboutconfig-mjs</title>%0A%09%09<meta http-equiv="Content-Type" content="text/html; charset=utf-8">%0A%09</head>%0A%09<body> %0A%09%09<center style="font-family: Verdana; margin-top: 25vh;"><h1><a%0A%09%09%09download="aboutconfig-mjs.zip"%0A%09%09%09href="data:application/x-zip-compressed;base64,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"%0A%09%09>aboutconfig-mjs.zip</a></h1></center>%0A%09</body>%0A</html> |
xrun1 > 31-08-2023 10:19:59 |
Dumby пишет
Нет, зачем менять. Зелёная шестерёнка устраивает. Спасибо, всё завелось и работает. |
sachka > 31-08-2023 14:10:06 |
огромная просьба вернуть к жизни расширение на фф 117.0 https://www.upload.ee/files/15636250/lo … 8.xpi.html |
Farby > 31-08-2023 15:55:33 |
sachka |
sachka > 31-08-2023 17:34:26 |
Farby |
Dobrov > 31-08-2023 23:34:32 |
Dumby пишет
А как jsm в mjs переделывать? Например скрипт сохранения страницы SingleSaveHTML.jsm ? |
Dumby > 01-09-2023 09:47:40 |
Dobrov пишет
Ооо, следуй за ними.
скрытый текст Выделить код Код:export class SingleHTMLChild extends JSWindowActorChild { //класс = name + Child receiveMessage() { return htmlAndName(this.contentWindow);} } ChromeUtils.domProcessChild.childID || ({ init(topic) { ChromeUtils.registerWindowActor(name, { allFrames: true, child: {esModuleURI: Components.stack.filename},
Ну, ES типа вебский модуль, только без top-level await'а.
Конечно нет. Даже рядом не стояло. |
xrun1 > 01-09-2023 10:25:51 |
Раз уж тут jsm-ками озадачились, добавлю, что не работает (последний спойлер AppMenuTbbSaveHTMLChild.jsm). |
Farby > 01-09-2023 11:22:30 |
xrun1 скрытый текст Выделить код Код:// в custom_script.js (async url => ChromeUtils.importESModule(url))( "chrome://user_chrome_files/content/custom_scripts/Actors/AppMenuTbbSaveHTMLChild.mjs"); var self, name = "AppMenuTbbSaveHTML"; //, EXPORTED_SYMBOLS = [name + "Child"]; var {io, focus, obs} = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services; export class AppMenuTbbSaveHTMLChild extends JSWindowActorChild { receiveMessage() { return htmlAndName(this.contentWindow); } } ChromeUtils.domProcessChild.childID || ({ init(topic) { ChromeUtils.registerWindowActor(name, { allFrames: true, child: {esModuleURI: Components.stack.filename}, messageManagerGroups: ["browsers"] }); obs.addObserver(self = this, topic); obs.addObserver(function quit(s, t) { obs.removeObserver(quit, t); obs.removeObserver(self, topic); }, "quit-application-granted"); this.handleEvent = e => this[e.type](e); }, observe(win) { win.document.getElementById("appMenu-popup") .addEventListener("popupshowing", this); win.addEventListener("unload", this); }, popupshowing(e) { this.unload(e); var popup = e.target; var btn = popup.ownerDocument.createXULElement("toolbarbutton"); btn.id = "appMenu-ucf-save-html-button"; btn.className = "subviewbutton subviewbutton-iconic"; btn.setAttribute("label", "Страница | выбранное в единый HTML"); // btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAAAAClZ7nPAAAAAXRSTlMAQObYZgAAACNJREFUCNdjYH/AgBX9/89Q/4/B/g+D/A8G/g8gEeYDDIwNAIB7EDCcKCcMAAAAAElFTkSuQmCC"); btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzElEQVQ4jV2STW8bZRDHf/Psrr11nZhgVKcKaSmUiArRKBRVIMgH4BKJ7xAp5MSFiA+Rc28ckBAoipC4koJQLyAaVFChIlQllDRWmjRev8Qvu14/+wwHx6ZlpNFcZn7zn79GVJW1tbXc6urqijHGqKoAPF3TgcVaq8owXJbphx99fOOnWzcHoqqsr68/t7y83BARVBXnHHraXo3a3HoUU8gFAHRTS2Bg/7C2Zx7vXPIBwjA0p3BU9Zns9i3vvVrhr6MWzlpee+EsRqAbHc3+/Pee7wPkcrkx4P+g0IMvb/5Iv5/iXEaWZQS+By578MaVy9YH8H3fE5FnANZajqMmgcAnH7yN73mICMYMd21sbLy7srKiPkA+n3/qBLhzv8p+EuOfTUjShPbODvOVWa5fnRsvKBaLAcAIMFbw+bc/EBVn8At7SPcQ60LSiVm++P0fGu0e7y++yalvHoABCILAiAj7hzU+vfcVT6zPVGmR3x4/xJoLSH6BVu4cN777nnQwQETI5XL/AYwxRkS4ff8BEk6Q2pBfq3dxUuHMmWt0kgFGStTDY/7YrTLybQwYPU2cpgzsCd1OgmSzWHeOR7VjWicxaT9lxn+HfjoYmWnGHgAiIsydf5HKnUXiThehQDG4Tr3e5KR7hN8XilnGKxfOoyrDgZECwIgIb125xIxxTGVdgjRG4pR2+zbG/sIkD7l2cYJyaYLMOZxzjBV4nueLCI1GnaWFab65t4OXt4gUuFqYJ8gGuPYBCxdLHNciys9PkaapjAHGGM8YQ7lcZv71OaYmC/xZPaJHTN4cUgpDXrr8MtOVaUqTRXzfY3t7u7O0tDR82a2trfkkSTSOY+31etrpdLTZbGoURRpFkdbrTY3qTW00mhrHse7u7t4tl8uhqg4VxHHcPDg4+ExVHeBU1YmIU1WnisucZtamLszn01ar9WRzc/PrWq2WAPwLJ7l2ULfXOAMAAAAASUVORK5CYII="); btn.setAttribute("oncommand", "saveHTML();"); btn.saveHTML = this.saveHTML; popup.querySelector('toolbarbutton[id^="appMenu-print-button"]').before(btn); }, unload(e) { var win = e.target.ownerGlobal; win.removeEventListener("unload", this); win.document.getElementById("appMenu-popup").removeEventListener("popupshowing", this); }, async saveHTML() { var win = this.ownerGlobal; var br = win.gBrowser.selectedBrowser; var bc = focus.focusedContentBrowsingContext; if (bc?.top.embedderElement != br) bc = br.browsingContext; var actor = bc?.currentWindowGlobal?.getActor(name); actor && self.save(win, ...await actor.sendQuery("")); }, async save(win, fileContent, fileName) { var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker); fp.init(win, "", fp.modeSave); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); var res = await new Promise(fp.open); if (res == fp.returnOK || res == fp.returnReplace) this.write(fp.file.path, fileContent); }, write(path, html) { if (typeof IOUtils == "object") var write = IOUtils.writeUTF8 || IOUtils.writeAtomicUTF8; // Fx 85+ || 82-84 if (!write) { // Fx 79-81 var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); write = (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt)); } (this.write = write)(path, html); } }).init("browser-delayed-startup-finished"); var htmlAndName = async mainWin => { var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec; } catch {} }; var getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r; } catch(e) {} } }; var encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else { img = obj; }; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }; var toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild); var meta = doc.createElement('meta'); meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); var title = doc.getElementsByTagName('title')[0]; if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; var sheets = doc.styleSheets; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, ''); fileName += (function () { var d = new Date(), z = function(n){return '_' + (n < 10 ? '0' : '') + n}; return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds()); })(); if(!/\.html?$/.test(fileName))fileName += '.html'; return [doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->', fileName]; } |
qwerty1956 > 01-09-2023 12:16:29 |
Dumby |
kokoss > 01-09-2023 12:45:17 |
qwerty1956 пишет
Откройте настройки ATB, включайте -> Открывать в новой вкладке кнопки и ссылки, и жмёте на "Сохранить настройки". |
xrun1 > 01-09-2023 13:47:17 |
Farby скрытый текст |
Farby > 01-09-2023 13:58:44 |
xrun1 пишет
у меня так скрытый текст импорт правильный? custom_script.js Выделить код Код:// в custom_script.js (async url => ChromeUtils.importESModule(url))( "chrome://user_chrome_files/content/custom_scripts/Actors/AppMenuTbbSaveHTMLChild.mjs"); 01-09-2023 14:05:44 Dumby пишет
|
xrun1 > 01-09-2023 14:53:59 |
Farby |
Dobrov > 01-09-2023 15:31:23 |
Farby пишет
custom_script.js лишний этап, можно грузить напрямую с авто-определением JSM<>MJS в CustomStylesScripts.jsm Выделить код Код:jsmImport = (s, e = /\.jsm$/i.test(s) ? "" : "ESModule") => `ChromeUtils.import${e}("chrome://user_chrome_files/content/custom_scripts/${s}")`; ……… scriptsbackground: [ // В фоне [System Principal] { func: jsmImport("SingleHTML.mjs"), }, |
xrun1 > 01-09-2023 15:48:52 |
Ещё не работает "Экспорт папки в HTML". |
qwerty1956 > 01-09-2023 16:09:40 |
kokoss пишет
Блин, забыл про настройки. Спасибо |
Farby > 01-09-2023 17:01:06 |
xrun1 Экспорт папки в HTML Выделить код Код:. // fp.init(win, win.PlacesUIUtils.getString("EnterExport"), fp.modeSave); fp.init(win, win.PlacesUIUtils.promptLocalization.formatValueSync("places-bookmarks-export"), fp.modeSave); |
fuchsfan > 01-09-2023 18:48:27 |
Farby пишет
Появилась такая фича, как будто в код встроен счетчик количества запусков "Управления закладками", один раз открыл - один пункт, три раза открыл - три пункта. |
LGS > 01-09-2023 19:04:22 |
fuchsfan fuchsfan пишет
Это не фича. Здесь, третий абзац объясняется почему. |
fuchsfan > 01-09-2023 19:26:24 |
LGS пишет
В боковой панели не двоит, двоит только в "управлении закладками". Пробую не в UCF, а c загрузчиком Aris-t2. |
LGS > 01-09-2023 19:51:28 |
fuchsfan пишет
Возможно, из-за этого и размножается. Если есть желание, проверьте в UCF и custom_script.js. У меня в "Управлении закладками" все нормально. |
fuchsfan > 01-09-2023 20:02:23 |
LGS пишет
При активации в CustomStylesScripts.jsm не двоит, при добавлении кода в custom_script.js двоит. При активации в Aris-t2 двоит. |
Farby > 01-09-2023 23:49:54 |
fuchsfan пишет
Скажете пожалуйста, а до моего предложения у Вас хоть раз встречалась "Экспорт папки в HTML"? |
fuchsfan > 02-09-2023 07:42:26 |
Farby пишет
До вашего предложения я этот скрипт не использовал. |
LGS > 02-09-2023 10:55:08 |
А починить можно такую jsm-ку, первый спойлер..? Или сконвертировать в mjs..? ЛКМ для userChrome.css работает, правая для userContent.css - нет. |
Farby > 02-09-2023 19:41:34 |
LGS пишет
MJS`ка Reload user{Chrome, Content}.css Выделить код Код:// в custom_script.js (async url => ChromeUtils.importESModule(url))( "chrome://user_chrome_files/content/custom_scripts/Actors/userContentReloader.mjs"); var name = "UCF_userContentReloader"; /*, EXPORTED_SYMBOLS = [name + "Child"]; */ export {UCF_userContentReloaderChild}; if (typeof Services != "object") /* eslint-disable-next-line no-var */ var Services = globalThis.Services; var find = function(sheet) { return sheet.href == this; } var getSheet = (doc, href) => InspectorUtils.getAllStyleSheets(doc).find(find, href); if (!ChromeUtils.domProcessChild.childID) { var noop = () => {}; ChromeUtils.importESModule("resource:///modules/CustomizableUI.sys.mjs").CustomizableUI.createWidget({ label: "Reload user{Chrome, Content}.css", tooltiptext: "L: Reload userChrome.css\nR: Reload userContent.css", id: "ucf-userContentReloader", localized: false, onCreated(btn) { btn._handleClick = this.click; btn.oncontextmenu = oncontextmenu; btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIpwAACKcBMsYCAwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMwSURBVEiJ5dbNb5RVFMfxz3mmrYgYE0IN4IaKb4n4UqOwMCYu2JCoQVDiwoUrQ4j0xao7ExITQxRoodEFK1cmRkSE8AeYYKpEFF0YY4SiUSMRQW0sLe0818U8nekwHe3U7vhtnnNOzj3f89znPvderjVFK8npaSWrPSjpElahQzhvyrF4y++t1GqbF7DHOvQLj6Ozrt2EDutYRHAasMK0vXgWWZO0SX/7DlJf6Skp3UWcFeVRV4zG235tCZx6rDPtKLqqAN4XPhROm3DJEiG3LA6aKkZ14jUSKaOd1Gsco6Qz8vRiDDvTFJz63S13AjdVAg7JvBxDzs2RfrE2MP9ijolZijvJXo/h8pmmb5z6LZf7qICWJQNxwP5mM1OnzNdy03V1U0oi2x77y+/Wp16t3CDWgvDKvKGIQZepfO+iWBIpKG9s7HGW0k7dKgsJjsSQffOF1or4srAuS04U9jOp14amYGGgiF2Re6llaEWnMSbPNyl5DtNFQzvnBKdd2oRNhXt4ZvW1rCwfkbInY9jHMeiscBiEJ9Lz2mfSaovgovXC8sI7siAoYsgnMy8JkmPYhhtdbwOV6a9NdVhT69qphYIblPl0FuO2WrimVVVrcu7dZkFqd75q525uBCelqj0tXzRwvSYbwWZ1doOVi4Yad0vVDj81gjPfV+2y9YsGLnlgFrj6p9TA405irPAemwmn/raNqc/D/wO9uXj+bMhXDeDihDledLYt9VmTektb5flxebYgcOpx+yzw0aic3vXgSqY9hdUuOUx6T+WWcX/LUELYh3ZMyqq1G8FxwCl8ULjdVFd6d6tgPQbMfLIwHIPONgVXWs1OFm3Mjt6Rdlg2X2bq0yfsLtzP/OHVq3PqzuPUm/Vj9xz9ZDrcg5F/Bb6gS8mbkq1F6EdlW+IdE03Baae1pEeJb1SuO0vrMvPsPvKRArDaChf8qWRal/BQccBsxnXFiBFTtjS7czW93qYdVurQJZW6SLeK+DaGyofSLh0uGUNHk6F/SfZI3ojh2k41b3DThnrdS+1/nAnjcxzR5mDsdeG/6szrXl2nJX4w4RFJJ3LhF7lzMey3lmtdU/oHaoj4Y/PDRWgAAAAASUVORK5CYII="); }, get click() { var {file, spec} = getURI("hrome"); var chromeSheet = getSheet(Services.wm.getMostRecentWindow(null).document, spec); delete this.click; return this.click = !chromeSheet ? noop : function() { var win = this.ownerGlobal; if (win.event?.detail < 2 && file.exists()) reload(chromeSheet), win.setTimeout(restyle, 50); } } }); var getURI = sub => { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append(`userC${sub}.css`); return Services.io.newFileURI(file).QueryInterface(Ci.nsIFileURL); } var oncontextmenu = e => e.ctrlKey || e.shiftKey || e.detail != 1 || contextmenu(e); var contextmenu = e => { var {file, spec} = getURI("ontent"); var wb = Services.appShell.createWindowlessBrowser(); var contentSheet = getSheet(wb.document, spec); wb.close(); if (!contentSheet) return oncontextmenu = contextmenu = noop; ChromeUtils.registerProcessActor(name, {child: {esModuleURI: Components.stack.filename}}); (contextmenu = async e => { if (!file.exists()) return; e.preventDefault(); var data = await reload(contentSheet, Object.create(null)); if (data) for(var p in data) { for(var dp of ChromeUtils.getAllDOMProcesses()) dp.remoteType && await dp.getActor(name).sendQuery(spec, data); restyle(); return; } })(e); } var restyle = () => { var subst = "u_css_reloader_restyle_substitution"; var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); rph.setSubstitution(subst, Services.io.newURI("data:text/css,:root{}")); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var args = [Services.io.newURI(`resource://${subst}/`), sss.USER_SHEET]; (restyle = () => { sss.loadAndRegisterSheet(...args); sss.unregisterSheet(...args); })(); } var reload = async (sheet, obj) => { try {var style = await (await fetch(sheet.href)).text();} catch {return obj;} InspectorUtils.parseStyleSheet(sheet, style); if (obj) obj[sheet.href] = style; for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); rule.type == rule.IMPORT_RULE && rule.styleSheet.href.startsWith("file:///") && await reload(rule.styleSheet, obj); } return obj; } } else var UCF_userContentReloaderChild = class extends JSProcessActorChild { receiveMessage(msg) { var {sheet} = this; if (!sheet) { var en = Services.ww.getWindowEnumerator(null); if (en.hasMoreElements()) sheet = this.sheet = getSheet(en.getNext().document, msg.name); } sheet && this.parse(sheet, msg.data); } parse(sheet, data) { var style = data[sheet.href]; if (!style) return; InspectorUtils.parseStyleSheet(sheet, style); for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); rule.type == rule.IMPORT_RULE && rule.styleSheet.href.startsWith("file:///") && this.parse(rule.styleSheet, data); } } } |
LGS > 02-09-2023 20:41:05 |
Farby, благодарю, заработало. Вспомнил, что не на все правки в userContent.css "на лету" ПКМ реагирует, все равно приходится перезагружать. А я как раз на таком стиле и проверял. Догадался на других проверить - срабатывает. |
xrun1 > 04-09-2023 11:59:27 |
Farby пишет
Спасибо, работает. |
LGS > 09-09-2023 11:12:14 |
Dumby, вы не могли бы написать скрипт, который убирает фокус из строки поиска на страницах about:config и about:cfg..? |
Dumby > 09-09-2023 15:45:21 |
LGS пишет
Хмм, убирает когда? скрытый текст Выделить код Код:location.pathname == "config" ? document.getElementById("about-config-search").blur() : textbox.addEventListener("focus", e => e.target.blur(), {once: true}); И прописать в CustomStylesScriptsChild.jsm, в массив DOMContentLoaded { path: "blur.js", urlregxp: /^about:c(?:f|onfi)g(?:\?.+)?$/ }, Ну, и убедиться, что в настройках UCF стоит галка |
LGS > 09-09-2023 17:55:51 |
Dumby пишет
Ценное замечание, так бы я долго проверял почему не работает. Но теперь фоновая картинка бесит: custom_styles\png\background.png. Как ее культурно отключить, кроме переименования/удаления..? Кажется разобрался, все просто. Надо в CustomStylesScriptsChild.jsm закомментировать строку { path: "common.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, |
Dobrov > 12-09-2023 15:17:59 |
на Firefox 117 диалог настроек UCF не запоминает ничего - можно установить флажки, закрыть настройки UCF. Вот архив изменённого UCF – у кого работает UCF на FF 117, подскажите, где ошибка в правленных файлах??? |
Farby > 12-09-2023 15:53:49 |
Dobrov пишет
у меня его нет, но можно начать с chrome\user_chrome_files\options\prefs.js |
Dobrov > 12-09-2023 17:04:32 |
Farby - спасибо! убрал забытый var {Services}… в user_chrome_files/options/prefs.js, всё заработало. to_Alls сделал версию UCF, совместимую с Firefox 78-116, папки Firefox, chrome/user_chrome_files не знаю, как исправить для Firefox 117 — в нём не подключаются стили и скрипты… |
b0ttle > 19-09-2023 14:27:55 |
Оказывается все итак работает. По сообщению выше, думал есть какие-то проблемы в 117. |
rubel > 21-09-2023 17:52:50 |
Dumby |
fuchsfan > 21-09-2023 18:58:29 |
rubel скрытый текст Выделить код Код:// Скрипт создает подмножество кнопок для запуска приложений, открытия папок и файлов // Кнопка 1 (Открыть F:\\Firefox Backup) try { CustomizableUI.createWidget({ id: "add-openfolder1-app", label: "Открыть папку 1", tooltiptext: "Открыть F:\\Firefox Backup", defaultArea: CustomizableUI.AREA_NAVBAR, onCreated: btn => btn.image = "file:///D:/Portable Files/Firefox Portable/Profiles/Chrome/icons/folder1.png", onCommand: function(event) { var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath("F:\\Firefox Backup"); if (file.exists()) file.launch(); } }); } catch(e) {} // Кнопка 2 (повторяем код с другим путем) // Следующая кнопка... |
rubel > 21-09-2023 19:23:52 |
fuchsfan |
kokoss > 22-09-2023 00:08:10 |
rubel пишет
Да вроде работает, какая версия UCF ? |
rubel > 22-09-2023 03:48:55 |
kokoss |
fuchsfan > 22-09-2023 07:11:13 |
rubel пишет
Никаких особенностей, в userChrome.js, если Aris-t2, или в CustomStylesScripts.jsm, если UCF. |
rubel > 22-09-2023 08:03:51 |
fuchsfan Выделить код Код:scriptsbackground: [ // В фоне [System Principal] { path: "WinFolders.js", }, { path: "custom_script.js", }, ], Удалил startupCache, перезапускаю и никаких кнопок нигде не появляется, где моя ошибка ? |
fuchsfan > 22-09-2023 08:39:24 |
rubel пишет
Практически все сторонние скрипты прописаны в первой сверху секции load Выделить код Код:load: [ // По событию "load" { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar { path: "favicon_in_urlbar.js", ucfobj: true, }, { path: "ucf-mem-indicator_simple.uc.js", ucfobj: false, }, |
rubel > 22-09-2023 09:05:44 |
fuchsfan Выделить код Код:load: [ // По событию "load" // { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets { path: "WinFolders.js", ucfobj: true, }, { path: "favicon_in_urlbar.js", ucfobj: true, }, // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar ], Все равно кнопки нет, а вот иконка сайта в адресной строке появилась. |
fuchsfan > 22-09-2023 09:21:18 |
В настройках панели инструментов смотрели? В гл. окне браузера мышкой медленно поводите там, где могла бы быть кнопка, может, кнопка есть, но без иконки, под мышкой это проявится. Я отошел от ucf, но смогу проверить ваш WinFolders.js на другом компе, если выложите код. |
kokoss > 22-09-2023 09:30:41 |
rubel пишет
Я добавляю в файл -> custom_script.js rubel пишет
Я спрашивал про версию UCF, а не про сделанные правки, кстати про правку для 116 я в курсе, а что за правка для 115 ? |
rubel > 22-09-2023 09:52:10 |
fuchsfan Выделить код Код:// Скрипт создает подмножество кнопок для запуска приложений, открытия папок и файлов // Кнопка 1 (Открыть F:\\Firefox Backup) try { CustomizableUI.createWidget({ id: "add-openfolder1-app", label: "Открыть папку 1", tooltiptext: "Открыть D:\\1", defaultArea: CustomizableUI.AREA_NAVBAR, onCreated: btn => btn.image = "file:///D:/Portable Files/Firefox Portable/Profiles/Chrome/icons/folder1.png", onCommand: function(event) { var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath("D:\\1"); if (file.exists()) file.launch(); } }); } catch(e) {} // Кнопка 2 (повторяем код с другим путем) try { CustomizableUI.createWidget({ id: "add-openfolder1-app", label: "Открыть папку 2", tooltiptext: "Открыть D:\\Downloads", defaultArea: CustomizableUI.AREA_NAVBAR, onCreated: btn => btn.image = "file:///D:/Portable Files/Firefox Portable/Profiles/Chrome/icons/folder1.png", onCommand: function(event) { var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath("D:\\Downloads"); if (file.exists()) file.launch(); } }); } catch(e) {} // Следующая кнопка... Что не правильно ? |
fuchsfan > 22-09-2023 09:56:26 |
rubel 22-09-2023 09:56:48 22-09-2023 10:01:00 Выделить код Код:onCreated: btn => btn.image = "file:///D:/Portable Files/Firefox Portable/Profiles/Chrome/icons/folder1.png", Измените путь на свой, в папке Chrome создайте папку icons, в нее положите иконку 16х16, 24х24 пикселя png, jpg с любым именем, в коде исправьте имя на свое. И иконка появится. 22-09-2023 10:03:41 22-09-2023 10:11:12 rubel пишет
В этой строке измените всплывающую подсказку на свою |
rubel > 22-09-2023 10:23:01 |
fuchsfan 22-09-2023 10:40:40 |
fuchsfan > 22-09-2023 11:35:18 |
rubel пишет
Так можете заменить на любую свою взрачную, тем более. что эта ассоциируется с "сохранить" (стрелка вовнутрь), а не с "открыть" (стрелка наружу). |
rubel > 22-09-2023 13:21:23 |
fuchsfan |
6e73epo > 26-09-2023 00:05:15 |
fuchsfan, а чтобы кнопка открывала папку chrome в профиле, какой путь указать? Без всяких проверок на существование папки |
rubel > 26-09-2023 03:52:26 |
Dumby скрытый текст ucf-mem-indicator.js Выделить код Код:(async id => ({ delay: 2e3, val: "", init(topic, mm) { Services.obs.addObserver(mm = this, topic); Services.obs.addObserver(function quit(s, t) { this.timer?.cancel(); Services.obs.removeObserver(mm, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); }, observe(win) { var df = win.MozXULElement.parseXULToFragment( `<hbox id="${id}" tooltiptext="${ "ЛКМ: Минимизировать потребление памяти
ПКМ: about:performance
Ctrl+ПКМ: about:debugging#/runtime/this-firefox" }" onclick="event.button || ${ "memoryMinimizationButton.doMinimize(event)" }"><label id="${id += "-label"}"/></hbox>` ); this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); (this.observe = async win => { this.timer.cancel(); await new Promise(ChromeUtils.idleDispatch); var clone = win.document.importNode(df, true); clone.firstChild.oncontextmenu = this.about; win.document.getElementById("star-button-box").after(clone); this.notify(); })(win); }, about(e) { var gb = e.view.gBrowser; gb.selectedTab = gb.addTrustedTab(`about:${ e.ctrlKey ? "debugging#/runtime/this-firefox" : "performance" }`); }, async notify() { var info = await ChromeUtils.requestProcInfo(); var bytes = info.memory; for(var child of info.children) bytes += child.memory; this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT); var prev = this.val; if ((this.val = this.mgb(bytes)) != prev) for(var win of CustomizableUI.windows) { var lab = win.document.getElementById(id); if (lab) lab.value = this.val; } }, mgb: bytes => bytes < 1073741824 ? Math.round(bytes / 1048576) + "MB" : (bytes / 1073741824).toFixed(2) + "GB" }).init("browser-delayed-startup-finished"))("ucf-mem-indicator"); |
Dobrov > 26-09-2023 04:41:59 |
rubel пишет
Насколько я понимаю, метод Aris-t2 не позволяет подключать скрипты «В фоне [System Principal]», поэтому UCF удобней и полезней… |
fuchsfan > 26-09-2023 06:59:52 |
6e73epo пишет
Указать реальный путь к папке Chrome. 6e73epo пишет
Если браузер перемещен в другую директорию, чтобы скрипт сам определял путь к папке Chrome, такого не знаю, но есть кнопка для папки Profiles, а там останется один клик. И есть скрипт сложнее и побольше, который путь ко всем папкам Firefox и файлам userChrome.css, user.js определяет сам. |
6e73epo > 26-09-2023 07:58:50 |
fuchsfan, с пробелами не тестировал, у меня путь без пробелов. Завелось так |
fuchsfan > 26-09-2023 08:32:58 |
rubel пишет
Зато есть тема под названием userChrome.js https://forum.mozilla-russia.org/viewtopic.php?id=77354 и вашему посту как раз в ней место, а не в теме по ucf. |
rubel > 26-09-2023 10:50:12 |
Dobrov пишет
Да и методом UCF тоже ничего сложного, когда его освоишь. |
Dobrov > 26-09-2023 16:22:59 |
rubel пишет
ответ Всем… По этой инструкции. или читаем Шапку. |
b0ttle > 27-09-2023 00:13:04 |
Может кому пригодится, спасибо dobrov. Кстати, тут есть и хоткей, и кнопки-папки, да много чего. Удобная штука, советую) По желанию, можно подвести под личные потребности. Не пропускает в тексте, скорее всего из-за каких-то символов... пришлось так. Вставить в адресную строку. Выделить код Код:data:text/plain;charset=UTF-8;base64,KGFzeW5jKEZmLHRFeHApPT57IC8vIGhvb2sgTW91c2VLZXlzIMKpIER1bWJ5LCBtb2QgMi4wIERvYnJvdiDQutC90L7Qv9C60Lgg0LrQvtC80LDQvdC00Ysg0YHQutC40L3igKYKVGFnPXsKCiJkb3dubG9hZHMtYnV0dG9uIjoneycrIC8v0L3Rg9C20LXQvSBTaW5nbGVIVE1MLmpzbSwg0LfQsNCy0LjRgdC40LzRi9C5IHVjZl9RdWlja1RvZ2dsZQpg4peJ77yaICAgIOKsh++4jmZvbGRlciBbRG93bmxvYWRzXQril6jvvJogICAgICAgICAgIOKenFNhdmUgUGFnZQril4nvvJogICAgICAgICAgIG9uIFBob3RvIOKenFNhdmXvuLBgKyAvL9C00LXQudGB0YLQstC40Y8g0LrQu9Cw0LLQuNGIfNC80YvRiNC4LCDQv9C+0LTRgdC60LDQt9C60LgKYOKXpy1sb25n77yaIOKsh++4jmZvbGRlciBbRG93bmxvYWRzXVxuCuKXqO+8miAgICAgICAgICAgICAgIChBbHQrUykg4p6cU2F2ZQogICAgICAgICAgICAgICB0byBTaW5nbGVIVE1MIGFsbCAvaGlnaGxpZ2h0ZWQK4peJ77yaICAgICAgICAgICAgICAgJHtGZi5DdHIoIlN1cGVyIiwiQ3RybCtTaGlmdCIpfStTIOKenGFzIFRleHRcbgril6ctZG91Ymxl77yaIG9uIFBob3RvOiBmaW5kIFNpbWlsYXIK4penK1NoaWZ077yaICAgIEdyYXBoaWNzIG9uL29mZgril6crQWx077yaICAgICAgIFNlbGVjdGlvbiBkaWFsb2cgb24vb2ZmfWAsCgoiUGFuZWxVSS1tZW51LWJ1dHRvbiI6IC8v0YLQtdC60YHRgiDQn9GA0L7RgdGC0L7QuSDRgNC10LbQuNC877iw0K3QutGB0L/QtdGA0YIKYOKXp++8miAgICAgICAgICAgICAgICBtZW51IEZpcmVmb3ggJHtGZi52ZXJ9e1xu77iwCuKXpytTaGlmdO+8miAgICAg4p6/aGVscFxufQril6ctbG9uZ++8miAgICAgICDinJUgQ2xvc2UgYnJvd3NlclxuYCArYOKXpytBbHTvvJril4nvvJog4p2QTWF4aW1pemXilIJSZXN0b3JlCgril6jvvJogICAgICAgICAgICAgICAg4oeyTWluaW1pemUge++4sGAgLyrRjdC60YHQv9C10YDRgiovKyBgCuKXqCtBbHTvvJogICAgICAgICBhYm91dDpzdXBwb3J0fQrDmC1zY3JvbGzvvJog4oaRICDipL4gUmV0dXJuIHRhYmAsCgoiem9vbXBhZ2Utd2VfZHctZGV2LWJyb3dzZXItYWN0aW9uIjoKYFxuXG7il4krQWx077yaICAgIGNsb3NlIHRhYnMgb24gdGhlIHJpZ2h0CuKXiStTaGlmdO+8miBjbG9zZSBsZWZ0YCwKCiJ0YWJzLW5ld3RhYi1idXR0b24iOgpg4peo77yaICAgICDQstC10YDQvdGD0YLRjCDQstC60LvQsNC00LrRgwril6crQWx077yaINC+0YHRgtCw0LLQuNGC0YwgMSDRgtC10LrRg9GJ0YPRjmAsCgoiaWRlbnRpdHktYm94IjogLy9kZWJ1ZyDimJEg0LrQvtC80LDQvdC00Yt80LTQtdC50YHRgtCy0LjRjyDQsiDQutC+0L3RgdC+0LvRjApg4peo77yaICAgICAgICAgICAgICAgIENvcHkgYWRkcmVzcyB0byBjbGlwYm9hcmQK4penK0FsdO+8muKXie+8miBQcm94eSBzZXR0aW5ncwp777iwXG7il6crU2hpZnTvvJogICAgIG1lZGlhVGFifQrDmC1zY3JvbGzvvJogICAgIEJyaWdodG5lc3M6IGAsCgoiZmF2ZGlycy1idXR0b24iOiAvL9Cx0L7QutC+0LLQsNGPINC/0LDQvdC10LvRjCDQvtGC0LrRgNGL0YLQsDogZGVidWcg0JLQutC7CmDil6fvvJogICAgICAgICAgICAg4piFQm9va21hcmtzCuKXqO+8miAgICAgICAgICAgICDin7NIaXN0b3J5CuKXpytBbHTvvJogICAgICBGRgril6grQWx077yaICAgICAgSG9tZSBmb2xkZXJcbgril4nvvJogICAgICAgICAgICAg4qyH77iORG93bmxvYWRzCuKXiStBbHTvvJogICAgICBVc2VyQ2hyb21lRmlsZXNcbgrDmC1zY3JvbGzvvJogICDihpEgdXNlcl9jaHJvbWVfZmlsZXMKICAgICAgICAgICAgICAgICAgICDipL4gY3VzdG9tX3NjcmlwdHMK4penK1NoaWZ077yaICAgJUgudHh0CuKXqCtTaGlmdO+8miAgIHVjZl9ob29rQ2xpY2tzLmpzXG5cbgpNYWduaWZ5JkVtb2ppVzEwKFdpbisuKXxjaGFybWFwLG9zayxzbmR2b2xcbkFsdCtEICBBbHQr4oaQ4oaSL8OYXG5DdHJsK0IvSCAgICAgICAgICAgICAgLUJvb2ttYXJrcy9IICAoQWx0K0IvUylcbkN0cmwrRSAgICAgICAgICAgICAgICAgICAtU2VhcmNoXG5DdHJsK1NoaWZ0K1EvVyAtQ2xvc2VGRlxuQ3RybCtVICAgICAgICAgICAgICAgICAgLVBhZ2VTb3VyY2VcbkN0cmwrTyAgICAgICAgICAgICAgICAgIC1PcGVuIGEgZmlsZVxuQ3RybCtTaGlmdCtTICAgICAgICAtU2NyZWVuc2hvdFxuQ3RybCtBbHQrU2hpZnQrSSAtQnJvd3NlclRvb2xib3hcblxuQ3RybCtTaGlmdCtPL0ggQ3RybCtCL0ggQWx0K0IvU1xuQ3RybCtTaGlmdCtK4pWRQ3RybCtTaGlmdCtEZWzilZFDdHJsK1NoaWZ0K0RcbkN0cmwrU2hpZnQrQuKVkUN0cmwrSuKVkVNoaWZ0K8OY4pWRQ3RybCtTaGlmdCtFIEYxMmAsCgoiVG9nZ2xlQnV0dG9uIjoKYOKXpy1sb25n77yaICAg0LIg0YHRgtGA0L7QutC1INC80LXQvdGOLWFib3V0OmNvbmZpZwril6grQWx077yaICAgICDQv9C+0YHQuy4g0LfQsNC60LvQsNC00LrQsCDQvNC10L3Rjgril6fvvJogICAgICAgICAgICAtwqvQltGD0YDQvdCw0LvCu1xuCuKXqO+8miAgICAgICAgICAgINCc0LXQvdGOINCx0YvRgdGC0YDRi9GFINC90LDRgdGC0YDQvtC10LoK4peJ77yaICAgICAgICAgICAgLeKKntCd0L7QstCw0Y8g0LLQutC70LDQtNC60LAgKCR7RmYuQ3RyKCl9VClcbgril6crQWx077yaICAgICAt0JHQuNCx0LvQuNC+0YLQtdC60LAsINCW0YPRgNC90LDQuyB777iwCuKXpy1sb25n77yaICAg0J/QuNC/0LXRgtC60LAg0YbQstC10YLQsCwg0LvQuNC90LfQsFxuCuKXpytTaGlmdO+8miAg0LzQsNGB0YjRgtCw0LEg0KLQtdC60YHRgiAvINCS0YHRkX0Kw5gtc2Nyb2xs77yaICDQvNCw0YHRiNGC0LDQsSDQodGC0YDQsNC90LjRhtGLIMKxYCwKCiJSZWFkZXJWaWV3IjoKYNCa0LvQuNC6INC80YvRiNC4CdCn0YLQtdC90LjQtSDQsiBSZWFkZXJWaWV3CtCa0L7Qu9GR0YHQuNC60L4J0J/RgNC+0YHRgtC+0Lkg0YDQtdC20LjQvCDRh9GC0LXQvdC40Y9cbmAsCiJyZWFkZXItbW9kZS1idXR0b24iOgpg4peo77yaICAgICAgICAgINCQ0LTQsNC/0YLQuNCy0L3Ri9C5INC00LjQt9Cw0LnQvQril6grQWx077yaICDQktGL0LHQvtGAINGH0LDRgdGC0Lgg0YHRgtGA0LDQvdC40YbRiyBcbgrDmC1zY3LvvJogICDQr9GA0LrQvtGB0YLRjCDRgdGC0YDQsNC90LjRhjogYCwKCiJwcmludC1idXR0b24iOgpg0KDQsNGB0L/QtdGH0LDRgtCw0YLRjCDRgdGC0YDQsNC90LjRhtGDICgke0ZmLkN0cigpfVApXG4K4peo77yaICAgICAgICAgICAg0LHRi9GB0YLRgNCw0Y8g0J/QtdGH0LDRgtGMCuKXie+8miAgICAgICAgICAgINGA0LXQttC40Lwg0LrQvdC+0L/QvtC6CuKXpy1sb25n77yaICDinr/QutGA0LDRgtC60LDRjyDRgdC/0YDQsNCy0LrQsGAsCgoicmVsb2FkLWJ1dHRvbiI6CmDil6fvvJogICAgICAgICAgICDin7Mgbm8gY2FjaGUK4penLWxvbmfvvJogIOKtriBhbGwgdGFic2AsCgoidHJhY2tpbmctcHJvdGVjdGlvbi1pY29uLWNvbnRhaW5lciI6CmDil6fvvJogIFNpdGUgc2VjdXJpdHkgZGV0YWlscwril6jvvJogIExvZ2lucyBhbmQgUGFzc3dvcmRzCuKXie+8miAgYWJvdXQ6cHJvY2Vzc2VzCnvvuLBcbuKXpy1sb25n77yaICDih4YgV2ViLWZvbnRzCuKXpytTaGlmdO+8miAgYWJvdXQ6c2VydmljZXdvcmtlcnN9YCwKCiJ3aGVlbC1zdG9wIjoKYOKXie+8miAgICAgICAgICAgIOKclSBhbGwgcmVsb2Fkcwp777iw4peoLWxvbmfvvJogICBBbnRpemFwcmV0IOKHhiBObyBwcm94eX1cbmAsCgoidGl0bGViYXItYnV0dG9uLnRpdGxlYmFyLWNsb3NlIjogLy/QutGA0L7QvNC1IFdpbmRvd3MKYNCX0LDQutGA0YvRgtGMIEZpcmVmb3ggJHtGZi52ZXJ9XG4K4peJ77yaINCy0LXRgNC90YPRgtGMINCy0LrQu9Cw0LTQutGDCuKXpy1sb25n77yaIOKev9C60YDQsNGC0LrQsNGPINGB0L/RgNCw0LLQutCwCuKXqO+8miDih7LQodCy0LXRgNC90YPRgtGMYCwKCiJBdHRyaWJ1dGVzLUluc3BlY3RvciI6IC8vYXR0cnNJbnNwZWN0b3IuanMgfOKXqO+8miAgICAgICAgICAgINCd0LDRgdGC0YDQvtC50LrQuCBVc2VyQ2hyb21lRmlsZXN8QWx0ICsgeCAgICAgICDQt9Cw0L/Rg9GB0YLQuNGC0Ywg0YHQutGA0LjQv9GCIFVzZXIuanMKYOKXp++8miAgICAgICAgICAgIEF0dHJpYnV0ZXMtSW5zcGVjdG9yCuKXpy1sb25n77yaICDRgdC80LXQvdCwINGA0LXQttC40LzQsCDQutC90L7Qv9C+0LoK4penK0FsdO+8miAgICDQmNC90YHRgtGA0YPQvNC10L3RgtGLINCx0YDQsNGD0LfQtdGA0LAK4penK1NoaWZ077yaINCd0LDRgdGC0YDQvtC50LrQuCDQv9GA0L7RhNCw0LnQu9C10YDQsGAsCgoiQCI6IC8v0YLQtdC60YHRgtGLCmDQntGH0LjRgdGC0LjRgtGMINC/0LDQvdC10LvRjCDQutC+0LvRkdGB0LjQutC+0Lwg0LzRi9GI0Lh80JfQsNC/0YDQtdGJ0ZHQvdC90YvQtSDRgdCw0LnRgtGLINGH0LXRgNC10Lcg0JDQvdGC0LjQl9Cw0L/RgNC10YJ84piAIEJyaWdodG5lc3M6IHzwn5K+INC60Y3RiCwg0LTQsNC90L3Ri9C1INGB0LDQudGC0L7Qsiwg0LrRg9C60Lgg0LfQsNC90LjQvNCw0Y7RgiB80JfQsNGF0LLQsNGCINGG0LLQtdGC0LAg0LIg0JHRg9GE0LXRgCDQvtCx0LzQtdC90LAgKNC60YPRgNGB0L7RgCDQtNCy0LjQs9Cw0LXRgiDQvdCwIDEg0YLQvtGH0LrRgyl84pqh77iPINCX0LDQv9GA0LXRidC10L3QviDRgdC+0YXRgNCw0L3Rj9GC0Ywg0LvQvtCz0LjQvdGLINC4INC/0LDRgNC+0LvQuHzil6cg0LTQtdGA0LbQsNGC0Yw6IGFib3V0OmNvbmZpZywg4peoINC/0YAuINC60LvQuNC6INCh0LHRgNC+0YEsIOKfsyDQntCx0L3QvtCy0LjRgtGMLCDihq8g0J/QtdGA0LXQt9Cw0L/Rg9GB0Lp80JTQvtC70LPQuNC5INC60LvQuNC6INCyINGB0YLRgNC+0LrQtSDQvNC10L3Rjjog0J/RgNCw0LLQuNGC0Ywg0L7Qv9GG0LjRjiDilIIg0JrQvtC70ZHRgdC40LrQvjog0KHQtdGA0LLQuNGB0Yt80J7RiNC40LHQutCwINGB0LrRgNC40L/RgtCwIHzihq8g0J3QtSDQt9Cw0L/QvtC80LjQvdCw0YLRjCDQuNGB0YLQvtGA0LjRjiDQv9C+0YHQtdGJ0LXQvdC40Ll84oavINCj0LTQsNC70Y/RgtGMINC40YHRgtC+0YDQuNGOINC/0L7RgdC10YnQtdC90LjQuSwg0LfQsNC60YDRi9Cy0LDRjyDQsdGA0LDRg9C30LXRgHzQv9C10YDQuNC+0LQg0YHQvtGF0YDQsNC90LXQvdC40Y8g0YHQtdGB0YHQuNC5INC80LXQvdGP0LXRgtGB0Y8g0LIg0LzQtdC90Y4g0LrQvdC+0L/QutC4IMKr0JbRg9GA0L3QsNC7wrt8U2luZ2xlRmlsZSAoQWx0K0N0cmwrUylcbtCh0L7RhdGA0LDQvdC40YLRjCDRgdGC0YDQsNC90LjRhtGDINCyINC10LTQuNC90YvQuSBIdG1sfFZpZGVvIERvd25sb2FkSGVscGVyXG7QodC60LDRh9C40LLQsNC90LjQtSDQv9GA0L7QuNCz0YDRi9Cy0LDQtdC80L7Qs9C+INCy0LjQtNC10L58XG5cbuKXqO+8miDQndCw0YHRgtGA0L7QudC60LggVXNlckNocm9tZUZpbGVzXG7il4nvvJog0J/QtdGA0LXQt9Cw0L/Rg9GB0YLQuNGC0YwsINGD0LTQsNC70LjQsiDQutGN0YhcbkFsdCArIHgJ0LfQsNC/0YPRgdGC0LjRgtGMINGB0LrRgNC40L/RgiBVc2VyLmpzYH07IHZhciBUID0gVGFnWyJAIl0uc3BsaXQoJ3wnKSwgQiA9IFsuLi5PYmplY3Qua2V5cyhUYWcpLCJ2aWV3SGlzdG9yeVNpZGViYXIiXTsKCihhc3luYyAoaWQpID0+IEN1c3RvbWl6YWJsZVVJLmNyZWF0ZVdpZGdldCh7bGFiZWw6YNCf0LDQvdC10LvQuCwg0J/QsNC/0LrQuGAsaWQ6IGlkLHRvb2x0aXB0ZXh0OiBUYWdbaWRdLApvbkNyZWF0ZWQoYnRuKXtidG4uc3R5bGUuc2V0UHJvcGVydHkoImxpc3Qtc3R5bGUtaW1hZ2UiLCJ1cmwoY2hyb21lOi8vZGV2dG9vbHMvc2tpbi9pbWFnZXMvZm9sZGVyLnN2ZykiKTt9fSkKKShCWzVdKTsgLy8g0LrQvdC+0L/QutC4LdC/0L7QtNGB0LrQsNC30LrQuC3QutC70LjQutC4CgprbGFCYSA9IHsgLy/Qv9C10YDQtdGF0LLQsNGCLdC60LvQsNCy0LjRiCBLZXlBW19tb2RdW19PU10oZSx0KXvQutC+0LR9INC4IEtleUI6ICJLZXlBIgoJS2V5WF8xKGUsdCkge3VzZXJqcyhlKX0sICAgICAgLy8gQWx0K1gg0LfQsNC/0YPRgdC6INCy0L3QtdGI0L3QtdCz0L4gSlMt0LrQvtC00LAKCUtleVNfNigpICAgIHtzYXZlU2VsVG9UeHQoKX0sIC8qIEN0cmwrU2hpZnQrUyAqLyBLZXlTXzE1OiAiS2V5U182IiwKCUtleVNfMShlLHQpIHtzYXZlKCl9LCAgICAgICAgIC8vQWx0K1MgfCBlOiBFdmVudCwgdDogZ0Jyb3dzZXIuc2VsZWN0ZWRUYWIKLyoKCW1vZCA9IGUubWV0YUtleSo4ICsgZS5jdHJsS2V5KjQgKyBlLnNoaWZ0S2V5KjIgKyBlLmFsdEtleQoJbW9kICsgSSDQsiDQutC+0L3RhtC1OiDRgtC+0LvRjNC60L4g0LIg0L/QvtC70Y/RhSDQstCy0L7QtNCwLCDCq2nCuyDQutGA0L7QvNC1INC/0L7Qu9C10Lkg0LLQstC+0LTQsAoJMdGPINCx0YPQutCy0LAg0YHRgtGA0L7Rh9C90LDRjzog0L/QtdGA0LXQtNCw0LLQsNGC0Ywg0L3QsNC20LDRgtC40Y8sINC30LDQv9GA0LXRgiBwcmV2ZW50RGVmYXVsdAoJ0L7RgtC00LXQu9GP0YLRjCDCq1/CuyDQvtGCINC60L7QtNCwLCDQtdGB0LvQuCDQtdGB0YLRjCDQvNC+0LTQuNGE0LjQutCw0YLQvtGA0Ysg0Lgv0LjQu9C4IMKraUnCuy3RhNC70LDQswoJ0YLQvtC70YzQutC+INCyINGD0LrQsNC30LDQvdC90L7QuSBPUzogS2V5QV8xaV93aW4oZSx0KXvigKYgQWx0K0Eg0LTQu9GPINCy0LjQvdC00YsgKi8KCS8vPT09PT09PT09PT09CiBCYWNrcXVvdGVfaSgpe1BsYWNlc0NvbW1hbmRIb29rLnNob3dQbGFjZXNPcmdhbml6ZXIoIkJvb2ttYXJrc01lbnUiKS5jbGljaygpO30sCglEaWdpdDFfaSgpe2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ1bmlmaWVkLWV4dGVuc2lvbnMtYnV0dG9uIikuY2xpY2soKTt9LAoJRGlnaXQyX2koKXtCcm93c2VyT3BlbkFkZG9uc01ncigpO30sCglEaWdpdDNfaSgpe29wZW5QcmVmZXJlbmNlcygpO30sCglEaWdpdDRfaSgpe2R1cGxpY2F0ZVRhYkluKGdCcm93c2VyLnNlbGVjdGVkVGFiLCd0YWInKTt9LAoJRGlnaXQ1X2koKXt2YXIgcz1wcm9tcHQoJ0dvb2dsZV8gc2l0ZTouLiAuLicsJycpO2lmKHMubGVuZ3RoPjApZ0Jyb3dzZXIuYWRkVHJ1c3RlZFRhYignaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS9zZWFyY2g/cT1zaXRlOicrZW5jb2RlVVJJQ29tcG9uZW50KGdCcm93c2VyLmN1cnJlbnRVUkkuaG9zdCkrJyAnK2VuY29kZVVSSUNvbXBvbmVudChzKSk7fSwKCURpZ2l0Nl9pKCl7dmFyIHA9U2VydmljZXMuZGlyc3ZjLmdldCgnR3JlRCcsQ2kubnNJRmlsZSk7cC5pbml0V2l0aFBhdGgocC5wYXRoKyJcXC4uXFwuLlxcLi5cXF9QaG90b1xcU2hhcmVYXFxTaGFyZVguZXhlIik7cC5sYXVuY2goKTt9LAovKglEaWdpdDdfaSgpe2dCcm93c2VyLmZpeHVwQW5kTG9hZFVSSVN0cmluZygiamF2YXNjcmlwdDooZnVuY3Rpb24oKXt2YXIgRW5SdVQ9W1sn0YknLCdzaGgnXSxbJ9CpJywnU2hoJ10sWyfQqScsJ1NISCddLFsn0YUnLCdoaCddLFsn0KUnLCdIaCddLFsn0KUnLCdISCddLFsn0LYnLCd6aCddLFsn0JYnLCdaaCddLFsn0JYnLCdaSCddLFsn0YYnLCdjeiddLFsn0KYnLCdDeiddLFsn0KYnLCdDWiddLFsn0Y4nLCd5dSddLFsn0K4nLCdZdSddLFsn0K4nLCdZVSddLFsn0ZEnLCd5byddLFsn0IEnLCdZbyddLFsn0IEnLCdZTyddLFsn0Y8nLCd5YSddLFsn0K8nLCdZYSddLFsn0K8nLCdZQSddLFsn0YcnLCdjaCddLFsn0KcnLCdDaCddLFsn0KcnLCdDSCddLFsn0YgnLCdzaCddLFsn0KgnLCdTaCddLFsn0KgnLCdTSCddLFsn0Y0nLCdlYCddLFsn0K0nLCdFYCddLFsn0YsnLCd5J10sWyfQqycsJ1knXSxbJ9GKJywnYGAnXSxbJ9GMJywnYCddLFsn0YAnLCdyJ10sWyfRgicsJ3QnXSxbJ9GDJywndSddLFsn0LgnLCdpJ10sWyfQvicsJ28nXSxbJ9C/JywncCddLFsn0LAnLCdhJ10sWyfRgScsJ3MnXSxbJ9C0JywnZCddLFsn0YQnLCdmJ10sWyfQsycsJ2cnXSxbJ9C5JywnaiddLFsn0LonLCdrJ10sWyfQuycsJ2wnXSxbJ9C3JywneiddLFsn0YUnLCd4J10sWyfRhicsJ2MnXSxbJ9CyJywndiddLFsn0LEnLCdiJ10sWyfQvScsJ24nXSxbJ9C8JywnbSddLFsn0KAnLCdSJ10sWyfQoicsJ1QnXSxbJ9CjJywnVSddLFsn0JgnLCdJJ10sWyfQnicsJ08nXSxbJ9CfJywnUCddLFsn0JAnLCdBJ10sWyfQoScsJ1MnXSxbJ9CUJywnRCddLFsn0KQnLCdGJ10sWyfQkycsJ0cnXSxbJ9CZJywnSiddLFsn0JonLCdLJ10sWyfQmycsJ0wnXSxbJ9CXJywnWiddLFsn0KUnLCdYJ10sWyfQpicsJ0MnXSxbJ9CSJywnViddLFsn0JEnLCdCJ10sWyfQnScsJ04nXSxbJ9CcJywnTSddLFsn0LUnLCdlJ10sWyfQlScsJ0UnXV0sQT1kb2N1bWVudC5hY3RpdmVFbGVtZW50O0Eub25rZXl1cD1mdW5jdGlvbiBmdHIoKXtmb3IodmFyIHM9QS52YWx1ZSxpPTA7aTxFblJ1VC5sZW5ndGg7aSsrKXtzPXMucmVwbGFjZShSZWdFeHAoRW5SdVRbaV1bMV0sJ2cnKSxFblJ1VFtpXVswXSl9O0EudmFsdWU9c319KSgpIix7dHJpZ2dlcmluZ1ByaW5jaXBhbDpnQnJvd3Nlci5jb250ZW50UHJpbmNpcGFsfSk7CgkJCSB9LC8vQXV0b1RyYW5zbGl0LSBodHRwczovL2ZvcnVtLnJ1LWJvYXJkLmNvbS90b3BpYy5jZ2k/Zm9ydW09NSZ0b3BpYz00Njc3OSZzdGFydD0zMjAjMTUgKi8KLyoJRGlnaXQ4X2koKXt2YXIgcD1TZXJ2aWNlcy5kaXJzdmMuZ2V0KCdIb21lJyxDaS5uc0lGaWxlKTtwLmluaXRXaXRoUGF0aChwLnBhdGgrIlxcLi5cXC4uXFwuLlxcX1Bob3RvXFxTaGFyZVhcXFNoYXJlWC5leGUiKTsKCQkJIGxldCBhcmd1bWVudHM9WyItbm8tcmVtb3RlIiwiLVAiLCJYWFgiLCAiLWZvcmVncm91bmQiXTsgLy/QktGL0LHQvtGAINC/0YDQvtGE0LjQu9GPLiDQktC80LXRgdGC0L4gVGVzdC1Vc2VyINCy0LXQtNC40YLQtSDQuNC80Y8g0L/RgNC+0YTQuNC70Y8g0YLQsNC6LCDQutCw0Log0L7QvdC+INC+0YLQvtCx0YDQsNC20LDQtdGC0YHRjyDQsiBhYm91dDpwcm9maWxlcwoJCQkgbGV0IHByb2Nlc3M9Q2NbIkBtb3ppbGxhLm9yZy9wcm9jZXNzL3V0aWw7MSJdLmNyZWF0ZUluc3RhbmNlKENpLm5zSVByb2Nlc3MpOwoJCQkgcHJvY2Vzcy5pbml0KHApO3Byb2Nlc3MucnVuKGZhbHNlLCBhcmd1bWVudHMsIGFyZ3VtZW50cy5sZW5ndGgpOyAvL9Cf0YDQvtGE0LjQu9GMINC/0L7QtNGC0LLQtdGA0LbQtNC10L0KCQkJIH0sLy8gaHR0cHM6Ly9mb3J1bS5ydS1ib2FyZC5jb20vdG9waWMuY2dpP2ZvcnVtPTUmdG9waWM9NTEyMDIjNCAqLwogICAJCUYxKCl7dmFyIHA9U2VydmljZXMuZGlyc3ZjLmdldCgnU3lzRCcsQ2kubnNJRmlsZSk7cC5pbml0V2l0aFBhdGgocC5wYXRoKyJcXHNuZHZvbC5leGUiKTtwLmxhdW5jaCgpO30sCgkJRjIoKXtnQnJvd3Nlci5maXh1cEFuZExvYWRVUklTdHJpbmcoImphdmFzY3JpcHQ6e2Q9ZG9jdW1lbnQ7Yj1kLmJvZHk7bz1kLmNyZWF0ZUVsZW1lbnQoJ3NjcmknKydwdCcpO28uc2V0QXR0cmlidXRlKCdzcmMnLCdodHRwczovL3RyYW5zbGF0ZS5nb29nbGUuY29tL3RyYW5zbGF0ZV9hL2VsZW1lbnQuanM/Y2I9Z29vZ2xlVHJhbnNsYXRlRWxlbWVudEluaXQnKTtvLnNldEF0dHJpYnV0ZSgndHlwZScsJ3RleHQvamF2YXNjcmlwdCcpO2IuYXBwZW5kQ2hpbGQobyk7dj1iLmluc2VydEJlZm9yZShkLmNyZWF0ZUVsZW1lbnQoJ2RpdicpLGIuZmlyc3RDaGlsZCk7di5pZD0nZ29vZ2xlX3RyYW5zbGF0ZV9lbGVtZW50Jzt2LnN0eWxlLmRpc3BsYXk9J25vbmUnO3A9ZC5jcmVhdGVFbGVtZW50KCdzY3JpJysncHQnKTtwLnRleHQ9J2Z1bmN0aW9uIGdvb2dsZVRyYW5zbGF0ZUVsZW1lbnRJbml0KCl7bmV3IGdvb2dsZS50cmFuc2xhdGUuVHJhbnNsYXRlRWxlbWVudCh7cGFnZUxhbmd1YWdlOiUyMiUyMn0sJTIyZ29vZ2xlX3RyYW5zbGF0ZV9lbGVtZW50JTIyKTt9JztwLnNldEF0dHJpYnV0ZSgndHlwZScsJ3RleHQvamF2YXNjcmlwdCcpO2IuYXBwZW5kQ2hpbGQocCk7fXZvaWQgMCIse3RyaWdnZXJpbmdQcmluY2lwYWw6Z0Jyb3dzZXIuY29udGVudFByaW5jaXBhbH0pOwoJCQkgfSwvL0VuYWJsZSB0cmFuc2xhdGlvbihodHRwczovL2ZvcnVtLm1vemlsbGEtcnVzc2lhLm9yZy92aWV3dG9waWMucGhwP3BpZD04MDU0MjIjcDgwNTQyMiB8fDgwNTQyNyNwODA1NDI3KQoJCUYzKCl7Z0Jyb3dzZXIuZml4dXBBbmRMb2FkVVJJU3RyaW5nKCJqYXZhc2NyaXB0OihmdW5jdGlvbigpe3ZhciBuaWdodD1mdW5jdGlvbih3KXsoZnVuY3Rpb24oZCl7dmFyIGNzcz0naHRtbHtvcGFjaXR5OjAuNiFpbXBvcnRhbnQ7YmFja2dyb3VuZDpibGFjayFpbXBvcnRhbnQ7fWJvZHl7YmFja2dyb3VuZDp3aGl0ZSFpbXBvcnRhbnQ7fSc7dmFyIHM9ZC5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc3R5bGUnKTtmb3IodmFyIGk9MCxzaTtzaT1zW2ldO2krKyl7aWYoc2kuaW5uZXJIVE1MPT1jc3Mpe3NpLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoc2kpO3JldHVybn19O3ZhciBoZWFkcz1kLmdldEVsZW1lbnRzQnlUYWdOYW1lKCdoZWFkJyk7aWYoaGVhZHMubGVuZ3RoKXt2YXIgbm9kZT1kLmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyk7bm9kZS50eXBlPSd0ZXh0L2Nzcyc7bm9kZS5hcHBlbmRDaGlsZChkLmNyZWF0ZVRleHROb2RlKGNzcykpO2hlYWRzWzBdLmFwcGVuZENoaWxkKG5vZGUpfX0pKHcuZG9jdW1lbnQpO2Zvcih2YXIgaT0wLGY7Zj13LmZyYW1lc1tpXTtpKyspe3RyeXthcmd1bWVudHMuY2FsbGVlKGYpfWNhdGNoKGUpe319fTtuaWdodCh3aW5kb3cpfSkoKTsiLHt0cmlnZ2VyaW5nUHJpbmNpcGFsOmdCcm93c2VyLmNvbnRlbnRQcmluY2lwYWx9KTsKCQkJIH0sLy9OaWdodCBtb2RlKEZvY3VzIG1vZGUpCgkJRjQoKXt2YXIgdmVydD1gamF2YXNjcmlwdDp7Y29uc3Qgbz1bImNvbnRleHRtZW51Iiwic2VsZWN0c3RhcnQiLCJzZWxlY3QiLCJtb3VzZWRvd24iLCJtb3VzZXVwIiwiY3V0IiwiY29weSJdLHQ9WyItd2Via2l0IiwiLW1veiIsIi1tcyIsIi1raHRtbCIsIiJdLGU9d2luZG93LmpRdWVyeTtbZG9jdW1lbnQsZG9jdW1lbnQuYm9keSxkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRdLmZvckVhY2gobj0+e2Zvcihjb25zdCB0IG9mIG8pblsib24iK3RdPW51bGwsZSYmZShuKS5vZmYodCk7aWYobi5zdHlsZSlmb3IoY29uc3QgbyBvZiB0KXtjb25zdCB0PVtvLCJ1c2VyLXNlbGVjdCJdLmpvaW4oIi0iKTtuLnN0eWxlW3RdPSJpbml0aWFsIn19KQoJCQkgfTt2b2lkKDApO2A7Z0Jyb3dzZXIubG9hZFVSSShTZXJ2aWNlcy5pby5uZXdVUkkodmVydCkse3RyaWdnZXJpbmdQcmluY2lwYWw6U2VydmljZXMuc2NyaXB0U2VjdXJpdHlNYW5hZ2VyLmdldFN5c3RlbVByaW5jaXBhbCgpfSk7CgkJCSB9LC8vUmUtZW5hYmxlIHNlbGVjdGluZyAmIGNvcHlpbmcgdGV4dCBbbWFwbGUzMTQyXSAoQm9va21hcmtsZXQpCglLZXlHXzQoKXt2YXIgYmFyPWRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ1Y2YtYWRkaXRpb25hbC12ZXJ0aWNhbC1iYXIiKTtzZXRUb29sYmFyVmlzaWJpbGl0eShiYXIsYmFyLmNvbGxhcHNlZCk7fSwKCUtleVdfMSgpe2dCcm93c2VyLnJlbW92ZUFsbFRhYnNCdXQoZ0Jyb3dzZXIuc2VsZWN0ZWRUYWIpO30sCglLZXlWX2koKXtnQ2xpcGJvYXJkLndyaXRlKGdVUkxCYXIudmFsdWUpO2dsb2IuZmxhc2goMCwwLCdyZ2JhKDI0MCwxNzYsMCwwLjUpJywzMDApO30sLy8zMDAsIkNvcHlVUkw6ICIrZ1VSTEJhci52YWx1ZS5zbGljZSgwLDgwKSkKCUtleVZfMSgpe2xldCB1cmw9cmVhZEZyb21DbGlwYm9hcmQoKTt0cnl7c3dpdGNoVG9UYWJIYXZpbmdVUkkodXJsLHRydWUpO31jYXRjaChleCl7CgkJCSB2YXIgcmVnPS9bYS16QS1aMC05XVstYS16QS1aMC05XXswLDYyfShcLlthLXpBLVowLTldWy1hLXpBLVowLTldezAsNjJ9KStcLj8vOwoJCQkgaWYoIXJlZy50ZXN0KHVybCkpe3VybD0naHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS9zZWFyY2g/cT0nK2VuY29kZVVSSUNvbXBvbmVudCh1cmwpOwoJCQkgfWVsc2V7aWYodXJsLnN1YnN0cmluZyg0LDApLnRvTG93ZXJDYXNlKCk9PSJodHRwIil7dXJsPWVuY29kZVVSSUNvbXBvbmVudCh1cmwpOwoJCQkgfWVsc2V7dXJsPSdodHRwOi8vJytlbmNvZGVVUklDb21wb25lbnQodXJsKTt9fXN3aXRjaFRvVGFiSGF2aW5nVVJJKHVybCx0cnVlKTt9fSwvL09wZW4gY2xpcGJvYXJkIGFkZHJlc3MKCUtleVFfNSgpe01vdXNlW0JbMTRdXVsxMjhdKCk7fSwKCUtleVVfNSgpe3ZhciBwPVNlcnZpY2VzLmRpcnN2Yy5nZXQoJ1VDaHJtJyxDaS5uc0lGaWxlKTtwLmluaXRXaXRoUGF0aChwLnBhdGgrIlxcdXNlcl9jaHJvbWVfZmlsZXNcXF9cXHUuZXhlIik7cC5sYXVuY2goKTt9LAoJS2V5QV81KCl7dmFyIHA9U2VydmljZXMuZGlyc3ZjLmdldCgnVUNocm0nLENpLm5zSUZpbGUpO3AuaW5pdFdpdGhQYXRoKHAucGF0aCsiXFx1c2VyX2Nocm9tZV9maWxlc1xcX1xcLkV2XFxFdmVyeXRoaW5nLmV4ZSIpO3AubGF1bmNoKCk7fSwKCUtleVFfNCgpe3ZhciBwPVNlcnZpY2VzLmRpcnN2Yy5nZXQoJ1VDaHJtJyxDaS5uc0lGaWxlKTtwLmluaXRXaXRoUGF0aChwLnBhdGgrIlxcdXNlcl9jaHJvbWVfZmlsZXNcXF9cXC5RVFxcUVRyYW5zbGF0ZS5leGUiKTtwLmxhdW5jaCgpO30sCgkvLz09PT09PT09PT09PQp9LApNb3VzZT17IC8vTWV0YSo2NCBDdHJsKjMyINCo0LjRhNGCKjE2IEFsdCo4IChXaCA/IDIgOiBCdXQqMTI4KSBsb25nKjEKCSJ1cmxiYXItaW5wdXQiOnsgLy9DYXBzTG9jayBPbjogc2tpcCBhY3Rpb24gbW91c2V8a2V5Ym9hcmQKCQkyKHRyZyxmb3J3YXJkKXt0cmcudmFsdWU9IiJ9fSwgLy/QvtGH0LjRgdGC0LjRgtGMCgkidGFiYnJvd3Nlci10YWJzIjp7IC8vPD4g0LLQutC70LDQtNC60Lgg0LrQvtC70ZHRgdC40LrQvtC8CgkJMih0cmcsZm9yd2FyZCl7Z0Jyb3dzZXIudGFiQ29udGFpbmVyLmFkdmFuY2VTZWxlY3RlZFRhYihmb3J3YXJkID8gLTEgOiAxLHRydWUpO30sCgkJOCgpe30sMTYoKXt9LDY0KCl7fSwgLy/QstGL0LHQvtGACgkJMTI4KGJ0bil7Z0Jyb3dzZXIucmVtb3ZlVGFiKFRhYkFjdChidG4pKX0sIC8v0JwgICAgICAgLSDQstC60LvQsNC00LrQsCDQv9C+0LQg0LzRi9GI0YzRjgoJCTEzNihidG4pe1RhYnNEZWwoMSxUYWJBY3QoYnRuKSl9LCAgICAgICAgICAvL9CcK0FsdCAgIC0g0LfQsNC60YDRi9GC0Ywg0LLQutC70LDQtNC60Lgg0YHQv9GA0LDQstCwCgkJMTQ0KGJ0bil7VGFic0RlbCgwLFRhYkFjdChidG4pKX19LCAgICAgICAgIC8v0JwrU2hpZnQgLSDigKYg0YHQu9C10LLQsAoJInN0b3AtYnV0dG9uIjp7CgkJMTI4KCl7Zm9yKHZhciBpPTA7aTxnQnJvd3Nlci50YWJzLmxlbmd0aDtpKyspIGdCcm93c2VyLmdldEJyb3dzZXJBdEluZGV4KGkpLnN0b3AoKX0sIC8vTQoJCTI1Nygpe3N3aXRjaFByb3h5KCl9fSwgICAgICAgICAgICAvL1ItbG9uZwoJInN0YXItYnV0dG9uLWJveCI6ewoJCTEoKXt0cmFuc2xhdGUoKX0sICAgICAgICAgICAgICAgICAvL0xvbmcKCQk4KCl7d2luZG93LlBsYWNlc0NvbW1hbmRIb29rLnNob3dQbGFjZXNPcmdhbml6ZXIoIkJvb2ttYXJrc1Rvb2xiYXIiKX0sIC8vTCtBbHQgLSDQsdC40LHQu9C40L7RgtC10LrQsAoJCTEyOCgpe3N3aXRjaFRhYihGYXZJdGVtKCkpfSwgICAgICAvL00KCQkxMjkoKXtzd2l0Y2hUYWIoRmF2SXRlbShmYWxzZSkpfSwgLy9NLWxvbmcKCQkyNTYoKXt0b0ZhdigpfX0sICAgICAgICAgICAgICAgICAgLy9SCgkiYXBwTWVudS1wcmludC1idXR0b24yIjp7IC8v0JzQtdC90Y46INCf0LXRh9Cw0YLRjOKApgoJCTEoKXtIZWxwKCl9LAoJCTEyOChidG4pe0V4cGVydCgpfSwKCQkyNTYoKXtNb3VzZVtCWzldXVsyNTZdKCl9fSwKCSJwYWdlQWN0aW9uLXVybGJhci1fMjQ5NWQyNTgtNDFlNy00Y2Q1LWJjN2QtYWMxNTk4MWYwNjRlXyI6eyAvL1JlYWRlclZpZXcKCQkyKHRyZyxmb3J3YXJkKXticmlnaHQodHJnLGZvcndhcmQsNSl9LCAvL9GP0YDQutC+0YHRgtGMINC/0L4gd2hlZWwgwrEKCQkxMjgoYnRuKXtidG4ub3duZXJEb2N1bWVudC5nZXRFbGVtZW50QnlJZCgia2V5X3RvZ2dsZVJlYWRlck1vZGUiKS5kb0NvbW1hbmQoKX0sIC8v0YjRgtCw0YLQvdGL0Lkg0KDQtdC20LjQvCDRh9GC0LXQvdC40Y8KCQkyNTYoYnRuKXtNb3VzZVtCWzhdXVsyNTZdKGJ0bil9fSwKCSJ1bmlmaWVkLWV4dGVuc2lvbnMtYnV0dG9uIjp7bW91c2Vkb3duVGFyZ2V0OnRydWUsIAoJCTEoKXtFeHBlcnQoKX0sCgkJMTI4KCl7TW91c2VbQlsxNF1dWzEyOF0oKX0sCgkJMjU2KCl7b3BlbkRpYWwoKX19LAoJW0JbMF1dOnttb3VzZWRvd25UYXJnZXQ6dHJ1ZSwgLy/QvdC1INC/0LXRgNC10LTQsNCy0LDRgtGMINC90LDQttCw0YLQuNGPINC00LDQu9GM0YjQtQoJCTEoKXtEb3dubG9hZHMuZ2V0U3lzdGVtRG93bmxvYWRzRGlyZWN0b3J5KCkudGhlbihwYXRoID0+IEZpbGVVdGlscy5GaWxlKHBhdGgpLmxhdW5jaCgpLEN1LnJlcG9ydEVycm9yKX0sIC8vTG9uZwoJCTgoKXt2YXIgcD0iYnJvd3Nlci5kb3dubG9hZC5pbXByb3ZlbWVudHNfdG9fZG93bmxvYWRfcGFuZWwiLG49Z2xvYi5wcmVmKHApOwoJCQlnbG9iLnByZWYocCwgIW4pOwoJCQlnbG9iLnRvU3RhdHVzKGDQn9C+0LTRgtCy0LXRgNC20LTQtdC90LjQtSDQt9Cw0LPRgNGD0LfQutC4ICR7biA/ICLiiJog0YDQsNC30YDQtdGIIiA6ICLinJgg0LfQsNC/0YDQtdGJIn3QtdC90L5gLDNlMyk7fSwgLy9MK0FsdAoJCTE2KCl7dmFyIG49Z2xvYi5wcmVmKEZmLmkpID09IDI7Z2xvYi5wcmVmKEZmLmksIG4gPyAxIDogMik7CgkJCWdsb2IubW9kZV9za2luKCk7IEJyb3dzZXJSZWxvYWQoKTsKCQkJZ2xvYi50b1N0YXR1cyhg0JfQsNCz0YDRg9C30LrQsCDQuNC30L7QsdGA0LDQttC10L3QuNC5ICR7biA/ICLiiJog0YDQsNC30YDQtdGIIiA6ICLinJgg0LfQsNC/0YDQtdGJIn3QtdC90L5gLDNlMyk7fSwgICAvL0wrU2hpZnQKCQkxMjgoKXtGZi5FeHAoKSAvL9GA0LXQttC40Lwg0J/RgNC+0YHRgtC+0Lkv0K3QutGB0L/QtdGA0YI6INGA0LDQt9C90YvQtSDQtNC10LnRgdGC0LLQuNGPCgkJCT8gc2F2ZVNlbFRvVHh0KCkgOiAvL9GB0L7RhdGA0LDQvdC40YLRjHzQstGL0LTQtdC70LXQvS4g0LrQsNC6IC50eHQKCQkJRG93bmxvYWRzLmdldFN5c3RlbURvd25sb2Fkc0RpcmVjdG9yeSgpLnRoZW4ocGF0aCA9PiBGaWxlVXRpbHMuRmlsZShwYXRoKS5sYXVuY2goKSxDdS5yZXBvcnRFcnJvcil9LAoJCTI1Nigpe3NhdmUoKX19LCAvL3dlYgoJW0JbMV1dOnttb3VzZWRvd25UYXJnZXQ6dHJ1ZSwKCQkxKGJ0bil7Z29RdWl0QXBwbGljYXRpb24oYnRuKX0sIC8vTG9uZwoJCTIodHJnLGZvcndhcmQpe2ZvcndhcmQgPyB0cmcub3duZXJHbG9iYWwudW5kb0Nsb3NlVGFiKCkgOiB0cmcub3duZXJHbG9iYWwuQnJvd3NlckNsb3NlVGFiT3JXaW5kb3coKX0sIC8v0LrRgNGD0YLQuNGC0YwgK9CX0LDQutGA0YvRgtGMINCy0LrQu9Cw0LTQutGDIC3QktC+0YHRgdGC0LDQvdC+0LLQuNGC0YwKCQk4KCl7d2luZG93U3RhdGUgIT0gU1RBVEVfTUFYSU1JWkVEID8gbWF4aW1pemUoKSA6IHJlc3RvcmUoKX0sICAgLy9MK0FsdAoJCTE2KCl7SGVscCgpfSwgICAgICAgICAgICAgICAgICAgLy9MK1NoaWZ0CgkJMTI4KCl7d2luZG93U3RhdGUgIT0gU1RBVEVfTUFYSU1JWkVEID8gbWF4aW1pemUoKSA6IHJlc3RvcmUoKX0sIC8vTQoJCTEyOSgpe0Jyb3dzZXJGdWxsU2NyZWVuKCl9LCAgICAgLy9NLWxvbmcKCQkxMzYoKXt0aGlzWzEyOV0oKX0sICAgICAgICAgICAgIC8vTStBbHQKCQkyNTYoKXttaW5pbWl6ZSgpfSwgICAgICAgICAgICAgIC8vUgoJCTI2NCgpe3N3aXRjaFRhYignYWJvdXQ6c3VwcG9ydCcpfSwgLy9SK0FsdAoJCTI3MihidG4pe2J0bi5vd25lckdsb2JhbC5QbGFjZXNDb21tYW5kSG9vay5zaG93UGxhY2VzT3JnYW5pemVyKCJIaXN0b3J5Iil9fSwgLy9SK1NoaWZ0CglbQlsyXV06ezIodHJnLGZvcndhcmQpe3pvb20oZm9yd2FyZCl9fSwgLy93aGVlbAoJW0JbM11dOnsKCQk4KCl7Z0Jyb3dzZXIucmVtb3ZlQWxsVGFic0J1dChnQnJvd3Nlci5zZWxlY3RlZFRhYil9LAoJCTI1NihidG4pe2J0bi5vd25lckdsb2JhbC51bmRvQ2xvc2VUYWIoKX19LAoJW0JbNF1dOnsgLy/Qt9Cw0LzQvtC6CgkJMih0cmcsZm9yd2FyZCl7YnJpZ2h0KHRyZyxmb3J3YXJkLDUpfSwgLy/Rj9GA0LrQvtGB0YLRjAoJCTgoKXtvcGVuUHJveHlXaW4oKX0sIC8vTCtBbHQKCQkxMCh0cmcsZm9yd2FyZCl7YnJpZ2h0KHRyZyxmb3J3YXJkKX0sCgkJMTYoYnRuKXtCcm93c2VyUGFnZUluZm8oYnRuLCJtZWRpYVRhYiIpfSwgLy9MK1NoaWZ0IC0gZmVlZFRhYiBwZXJtVGFiIHNlY3VyaXR5VGFiCgkJMTI4KCl7dGhpc1s4XSgpfSwKCQkyNTYoKXtnQ2xpcGJvYXJkLndyaXRlKGdVUkxCYXIudmFsdWUpO2dsb2IuZmxhc2goMCwwLCdyZ2JhKDI0MCwxNzYsMCwwLjUpJywzMDAsItCyINCx0YPRhNC10YDQtTogIitnVVJMQmFyLnZhbHVlLnNsaWNlKDAsODApKTt9fSwKCVtCWzVdXTp7IC8vQ3VzdG9taXphYmxlVUkg0LIg0YHQutGA0LjQv9GC0LUKCQkwKGJ0bil7YnRuLm93bmVyR2xvYmFsLlNpZGViYXJVSS50b2dnbGUoInZpZXdCb29rbWFya3NTaWRlYmFyIil9LCAvL0wKCQkyKHRyZyxmb3J3YXJkKXtmb3J3YXJkID8gZ2xvYi5kaXJzdmNnZXQoIlVDaHJtIiwidXNlcl9jaHJvbWVfZmlsZXMiKSA6IGdsb2IuZGlyc3ZjZ2V0KCJVQ2hybSIsInVzZXJfY2hyb21lX2ZpbGVzIiwiY3VzdG9tX3NjcmlwdHMiKX0sCgkJOCgpe2dsb2IuZGlyc3ZjZ2V0KCJIb21lIil9LCAgICAgICAgICAgICAgICAgICAgICAgICAgLy9MK0FsdAoJCTE2KCl7Z2xvYi5kaXJzdmNnZXQoIlVDaHJtIiwidXNlcl9jaHJvbWVfZmlsZXMiLCJjdXN0b21fc2NyaXB0cyIsIkNCIiwiJUgudHh0Iil9LCAvL0wrU2hpZnQKCQkxMjgoYnRuKXtidG4ub3duZXJHbG9iYWwuUGxhY2VzQ29tbWFuZEhvb2suc2hvd1BsYWNlc09yZ2FuaXplcigiRG93bmxvYWRzIil9LCAvL00gLSDQkdC40LHQu9C40L7RgtC10LrQsCDQl9Cw0LPRgNGD0LfQutC4CgkJMTM2KCl7Z2xvYi5kaXJzdmNnZXQoIlVDaHJtIiwidXNlcl9jaHJvbWVfZmlsZXMiKX0sICAgLy9NK0FsdAoJCTI1NihidG4pe2J0bi5vd25lckdsb2JhbC5TaWRlYmFyVUkudG9nZ2xlKEIuYXQoLTEpKX0sIC8vUgoJCTI2NCgpe2dsb2IuZGlyc3ZjZ2V0KCJHcmVEIil9LCAgICAgICAgICAgICAgICAgICAgICAgIC8vUitBbHQKCQkyNzIoKXtnbG9iLmRpcnN2Y2dldCgiVUNocm0iLCJ1c2VyX2Nocm9tZV9maWxlcyIsImN1c3RvbV9zY3JpcHRzIiwiZG9icm92IiwidWNmX2hvb2tDbGlja3MuanMiKX19LCAvL0wrU2hpZnQKCVtCWzZdXTp7bW91c2Vkb3duVGFyZ2V0OnRydWUsCgkJMChidG4pe2lmIChidG4uaWQgPT0gQls2XSkgewoJCQkJICAgdmFyIGJhciA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJ1Y2YtYWRkaXRpb25hbC12ZXJ0aWNhbC1iYXIiKTsKCQkJCSAgIGlmIChiYXIpIHdpbmRvdy5zZXRUb29sYmFyVmlzaWJpbGl0eShiYXIsZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInNpZGViYXItYm94IikuaGlkZGVuKTsKCQkJCSAgIHdpbmRvdy5TaWRlYmFyVUkudG9nZ2xlKEIuYXQoLTEpKTsKCQkJICAgfSBlbHNlIGdsb2IubW9kZV9za2luKCk7fSwgLy9MIC0g0LzQtdC90Y4g0LrQvdC+0L/QutC4CgkJMShidG4peyAvL0xvbmcKCQkJaWYgKGJ0bi5pZCA9PSBCWzZdKXsgLy/Qu9C40L3Qt9CwCgkJCQlnbG9iLmZsYXNoKDAsMCwncmdiYSgxMDAsMCwyMjUsMC4xKScsNTAwLCBUWzRdKTsKCQkJCXZhciB1cmwgPSBgcmVzb3VyY2U6Ly9kZXZ0b29scy9zaGFyZWQvJHtwYXJzZUludChGZi52ZXIpID4gOTUgPyAibG9hZGVyLyIgOiAiIn1Mb2FkZXIuYDsKCQkJCXRyeSB7dmFyIGV4cCA9IENocm9tZVV0aWxzLmltcG9ydEVTTW9kdWxlKHVybCArICJzeXMubWpzIik7fSBjYXRjaCB7ZXhwID0gQ2hyb21lVXRpbHMuaW1wb3J0KHVybCArICJqc20iKTt9CgkJCQl2YXIgb2JqID0gZXhwLnJlcXVpcmUoImRldnRvb2xzL2NsaWVudC9tZW51cyIpLm1lbnVpdGVtcy5maW5kKG1lbnVpdGVtID0+IG1lbnVpdGVtLmlkID09ICJtZW51X2V5ZWRyb3BwZXIiKTsKCQkJCSh0ZXN0ID0gb2JqLm9uY29tbWFuZC5iaW5kKG51bGwsIHt0YXJnZXQ6YnRufSkpKCk7CgkJCX0gZWxzZSAvL9C60LvQuNC6INCyINC80LXQvdGOINCx0YvRgdGC0YDRi9GFINC90LDRgdGC0YDQvtC10LoKCQkJCWdsb2IuYWJvdXRfY29uZmlnKGJ0bi5wcmVmLnByZWYpLCAvL2dvINC/0LDRgNCw0LzQtdGC0YAgYWJvdXQ6Y29uZmlnCgkJCQlidG4ucGFyZW50Tm9kZS5wYXJlbnROb2RlLnNlY29uZGFyeVBvcHVwLmhpZGVQb3B1cCgpO30sCgkJMih0cmcsZm9yd2FyZCl7em9vbShmb3J3YXJkKX0sIC8vd2hlZWwKCQk4KCl7c3dpdGNoVGFiKCdjaHJvbWU6Ly9icm93c2VyL2NvbnRlbnQvcGxhY2VzL3BsYWNlcy54aHRtbCcpfSwgLy9MK0FsdAoJCTE2KGJ0bil7aWYgKGJ0bi5pZCA9PSBCWzZdKSB6b29tKDAsMSl9LCAgICAgICAgICAgICAgICAgICAgICAgICAvL0wrU2hpZnQKCQkxMjgoYnRuKXsgLy9NCgkJCWlmIChidG4uaWQgPT0gQls2XSkKCQkJCXN3aXRjaFRhYigiYWJvdXQ6bmV3dGFiIiwgdHJ1ZSkKCQkJZWxzZSAvL9C80LXQvdGOINCx0YvRgdGC0YDRi9GFINC90LDRgdGC0YDQvtC10LoKCQkJCXN3aXRjaFRhYigpLAoJCQkJYnRuLnBhcmVudE5vZGUucGFyZW50Tm9kZS5zZWNvbmRhcnlQb3B1cC5oaWRlUG9wdXAoKTt9LAoJCTEyOShidG4pe3VzZXJqcyhidG4sIiIpfSwgICAgICAgICAgICAgICAvL00tbG9uZyAtINC60L7QvdGB0L7Qu9GMCgkJMTM2KCl7dmFyIG49ImJyb3dzZXIuZGlzcGxheS51c2VfZG9jdW1lbnRfZm9udHMiLGY9Z2xvYi5wcmVmKG4pID8gMCA6IDE7CgkJCSAgZ2xvYi5wcmVmKG4sZik7em9vbSgwLDAsMCwoZj4wKSA/ICIgKyBXZWIt0YjRgNC40YTRgtGLIiA6ICIiKTtCcm93c2VyUmVsb2FkKCk7fSwgLy9NK0FsdAoJCTI1Nigpe30sICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1IgLSBsb2NrCgkJMjY0KCl7c3dpdGNoVGFiKEZhdkl0ZW0oZmFsc2UpKX19LCAgICAgICAvL1IrQWx0CgkgIC8vMjcyKGJ0bil7aWYgKGJ0bi5pZD1CWzZdKSBvcGVuRGlhbCgpfX0sIC8vTCtTaGlmdCAtIFVDRiBQcmVmcwoJW0JbOF1dOnsgLy/inr8KCQkyKHRyZyxmb3J3YXJkKXticmlnaHQodHJnLGZvcndhcmQsNSl9LCAgLy/Rj9GA0LrQvtGB0YLRjAoJCTI1NihidG4pe2J0bi5vd25lckRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJrZXlfcmVzcG9uc2l2ZURlc2lnbk1vZGUiKS5kb0NvbW1hbmQoKTsKCQkJCSBpZihnQnJvd3Nlci5zZWxlY3RlZEJyb3dzZXIuYnJvd3NpbmdDb250ZXh0LmluUkRNUGFuZSlCcm93c2VyUmVsb2FkKCk7fX0sIC8vUiAtIE1vYmlsZSBWaWV3ICjQv9GD0L3QutGCINC80LXQvdGOINGBIEhvdEtleSkKCVtCWzldXTp7CgkJMSgpe0hlbHAoKX0sCgkJMTI4KCl7RXhwZXJ0KCl9LAoJCTI1Nigpe2RvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJtZW51X3ByaW50IikuZG9Db21tYW5kKCl9fSwKCVtCWzEwXV06ewoJCTEoKXt3aXRoIChnQnJvd3Nlcikgc2VsZWN0QWxsVGFicygpLHJlbG9hZE11bHRpU2VsZWN0ZWRUYWJzKCksY2xlYXJNdWx0aVNlbGVjdGVkVGFicygpO30sCgkJMTI4KCl7Zm9yICh2YXIgaT0wO2k8Z0Jyb3dzZXIudGFicy5sZW5ndGg7aSsrKSBnQnJvd3Nlci5nZXRCcm93c2VyQXRJbmRleChpKS5zdG9wKCl9LAoJCTI1Nigpe0Jyb3dzZXJSZWxvYWRTa2lwQ2FjaGUoKX0sCgkJMjU3KCl7c3dpdGNoUHJveHkoKX19LAoJW0JbMTFdXTp7CgkJMSgpe01vdXNlW0JbNl1dWzEzNl0oKX0sIC8vTG9uZyAtZm9udHMKCQkyKHRyZyxmb3J3YXJkKXticmlnaHQodHJnLGZvcndhcmQpfSwKCQkxNigpe3N3aXRjaFRhYigpfSwKCQkxMjgoKXtzd2l0Y2hUYWIoJ2Fib3V0OnBlcmZvcm1hbmNlJyl9LAoJCTI1NihidG4pe3ZhciBsb2dpbnM9YnRuLm93bmVyRG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoInVjZi1sb2dpbnMtc2l0ZWRhdGEiKTtsb2dpbnMgPyBsb2dpbnMuY2xpY2soKSA6IHN3aXRjaFRhYignYWJvdXQ6bG9naW5zJyk7fX0sCglbQlsxM11dOnsKCQkxKCl7SGVscCgpfSwKCQkxMjgoYnRuKXtidG4ub3duZXJHbG9iYWwudW5kb0Nsb3NlVGFiKCl9LAoJCTI1Nigpe21pbmltaXplKCl9fSwKCVtCWzE0XV06eyAvL0F0dHJWaWV3CgkJMSgpe0V4cGVydCgpfSwKCQk4KCl7dmFyIGNocj0iZGV2dG9vbHMuY2hyb21lLmVuYWJsZWQiLHJlbT0iZGV2dG9vbHMuZGVidWdnZXIucmVtb3RlLWVuYWJsZWQiOwoJCQlpZiAoIWdsb2IucHJlZihjaHIpIHx8ICFnbG9iLnByZWYocmVtKSkge2dsb2IucHJlZihjaHIsdHJ1ZSk7IGdsb2IucHJlZihyZW0sdHJ1ZSk7fQoJCQl2YXIge0Jyb3dzZXJUb29sYm94TGF1bmNoZXJ9PUNocm9tZVV0aWxzLmltcG9ydCgicmVzb3VyY2U6Ly9kZXZ0b29scy9jbGllbnQvZnJhbWV3b3JrL2Jyb3dzZXItdG9vbGJveC9MYXVuY2hlci5qc20iKTsKCQkJQnJvd3NlclRvb2xib3hMYXVuY2hlci5pbml0KCk7fSwgLy/Rg9C0LtC+0YLQu9Cw0LTQutCwCgkJMTYoKXtzd2l0Y2hUYWIoJ2Fib3V0OnByb2ZpbGluZycpfSwKCQkxMjgoKXsgLy9NLCBRK0FsdCtDdHJsIENsZWFuQ2FjaGUgLSDQn9C10YDQtdC30LDQv9GD0YHRgtC40YLRjCwg0YPQtNCw0LvQuNCyINC60Y3RiAoJCQl2YXIgY2FuY2VsUXVpdCA9IENjWyJAbW96aWxsYS5vcmcvc3VwcG9ydHMtUFJCb29sOzEiXS5jcmVhdGVJbnN0YW5jZShDaS5uc0lTdXBwb3J0c1BSQm9vbCk7CgkJCVNlcnZpY2VzLm9icy5ub3RpZnlPYnNlcnZlcnMoY2FuY2VsUXVpdCwicXVpdC1hcHBsaWNhdGlvbi1yZXF1ZXN0ZWQiLCJyZXN0YXJ0Iik7CgkJCWlmIChjYW5jZWxRdWl0LmRhdGEpIHJldHVybiBmYWxzZTsKCQkJU2VydmljZXMuYXBwaW5mby5pbnZhbGlkYXRlQ2FjaGVzT25SZXN0YXJ0KCk7CgkJCXZhciByZXN0YXJ0ID0gU2VydmljZXMuc3RhcnR1cDsKCQkJcmVzdGFydC5xdWl0KHJlc3RhcnQuZUF0dGVtcHRRdWl0IHwgcmVzdGFydC5lUmVzdGFydCk7fSwKCQkyNTYoKXtvcGVuRGlhbCgpfSAvL1VDRnByZWZzCgl9fTsgdmFyIE0gPSBPYmplY3Qua2V5cyhNb3VzZSk7CgooYXN5bmMgKGlkKSA9PiBDdXN0b21pemFibGVVSS5jcmVhdGVXaWRnZXQoe2xhYmVsOmlkLnJlcGxhY2UoJy0nLCcgJyksIGlkOmlkLAoJb25DcmVhdGVkKGJ0bikgewoJCWJ0bi5zZXRBdHRyaWJ1dGUoImltYWdlIiwiZGF0YTppbWFnZS93ZWJwO2Jhc2U2NCxVa2xHUmp3QUFBQlhSVUpRVmxBNFRDOEFBQUF2RDhBREFBb0diU001T3Y2azc3NFhDUEZQLzAvMDMvOEpHUHh6cm9JenVPVzA2SWg2MEdlbm4xUy9nSGUrQmdBPSIpOwoJCWJ0bi5vbm1vdXNlZW50ZXIgPSBidG4ub25tb3VzZWxlYXZlID0gdGhpcy5vbm1vdXNlOwoJCWJ0bi5zZXRBdHRyaWJ1dGUoIm9uY29tbWFuZCIsImhhbmRsZUNvbW1hbmQodGhpcykiKTsgYnRuLmhhbmRsZUNvbW1hbmQgPSB0aGlzLmhhbmRsZUNvbW1hbmQ7Cgl9LAoJb25tb3VzZTogZSA9PiBlLnRhcmdldC5mb2N1c2VkV2luZG93ID0gZS50eXBlLmVuZHNXaXRoKCJyIikgJiYgU2VydmljZXMud20uZ2V0TW9zdFJlY2VudFdpbmRvdyhudWxsKSwKCWdldCBoYW5kbGVDb21tYW5kKCkge2RlbGV0ZSB0aGlzLmhhbmRsZUNvbW1hbmQ7CgkJcmV0dXJuIHRoaXMuaGFuZGxlQ29tbWFuZCA9IGJ0biA9PiB7KGJ0bi5oYW5kbGVDb21tYW5kID0gbmV3IGJ0bi5vd25lckdsb2JhbC5GdW5jdGlvbih0aGlzLmNvZGUpLmJpbmQoYnRuKSkoKTt9Cgl9LAoJZ2V0IGNvZGUoKSB7ZGVsZXRlIHRoaXMuY29kZTsgdmFyIHMgPSBGZi5jICsiY3VzdG9tX3NjcmlwdHMvIisgQlsxNF0gKyIuanMiOwoJCXRyeSB7aWQgPSAndGhpcy5mb2N1c2VkV2luZG93ICYmIHRoaXMuZm9jdXNlZFdpbmRvdy5mb2N1cygpO1xuJysKCQkJQ3UucmVhZFVURjhVUkkoU2VydmljZXMuaW8ubmV3VVJJKHMpKX0gY2F0Y2gge2lkID0gYGdsb2IudG9TdGF0dXMoIiR7VFs4XX0ke3N9Iiw3ZTMpYH0KCQlyZXR1cm4gdGhpcy5jb2RlID0gaWQ7fQp9KSkoQlsxNF0pOwoKdmFyIHtwcmVmc30gPSBTZXJ2aWNlcyxPdmVyID0geyAvL21vZGlmeSBUb29sdGlwcyDQv9C+0LQg0LzRi9GI0YzRjgpnZXQgW0JbMV1dKCkgeyAvLyBkZWxldGUgdGhpc1vigKZdOwoJZ2xvYi5tb2RlX3NraW4oKTsgaWYgKGdsb2IucHJlZigic2lnbm9uLnJlbWVtYmVyU2lnbm9ucyIpKQoJCVNlcnZpY2VzLmNhY2hlMi5hc3luY0dldERpc2tDb25zdW1wdGlvbih7b25OZXR3b3JrQ2FjaGVEaXNrQ29uc3VtcHRpb24oYnl0ZXMpIHsKCQkJZ2xvYi50b1N0YXR1cyhUWzNdICsgZ2xvYi5mb3JtYXRCeXRlcyhieXRlcyksM2UzKSAvLyDQstGL0LLQvtC0INC+0LHRitGR0LzQsCDQutGN0YjQsAoJCX0sIFF1ZXJ5SW50ZXJmYWNlOiBDaHJvbWVVdGlscy5nZW5lcmF0ZVFJKFsibnNJU3VwcG9ydHNXZWFrUmVmZXJlbmNlIiwibnNJQ2FjaGVTdG9yYWdlQ29uc3VtcHRpb25PYnNlcnZlciJdKX0pCgllbHNlIGdsb2IudG9TdGF0dXMoVFs1XSwyZTMpOyAvL9C90LUg0YXRgNCw0L3QuNGC0Ywg0L/QsNGA0L7Qu9C4CglyZXR1cm4gdEV4cChCWzFdKTsKfSwKZ2V0IFtCWzNdXSgpIHsKCXJldHVybiBHZXREeW5hbWljU2hvcnRjdXRUb29sdGlwVGV4dChCWzNdKSArIFRhZ1tCWzNdXTsKfSwKZ2V0IFtCWzBdXSgpIHt2YXIgZHcgPSBnbG9iLmRpcnN2Y2dldCgiIik7CglpZiAoZHcpIGdsb2IubW9kZV9za2luKGAke2dsb2IucHJlZihGZi5pKSA+IDEgPyAiXHV7MjZBMX0g0JPRgNCw0YTQuNC60LAg0L7RgtC60LvRjtGH0LXQvdCwLCIgOiAi8J+SviDQv9Cw0L/QutCwIn0gW9CX0LDQs9GA0YPQt9C60LhdIGArIGdsb2IuY3JvcChkdywgOTYsJycpKTsKCXJldHVybiBHZXREeW5hbWljU2hvcnRjdXRUb29sdGlwVGV4dChCWzBdKSArIlxuIisgdEV4cChCWzBdKTsKfSwKZ2V0ICJ0YWJicm93c2VyLXRhYiIoKSB7dmFyIHRyZyA9IHdpbmRvdy5ldmVudD8udGFyZ2V0OwoJdHJnLnRvb2x0aXBUZXh0ID0gdHJnLmxhYmVsICsgVGFnW0JbMl1dOwp9LApnZXQgW0JbMTBdXSgpIHtnbG9iLm1vZGVfc2tpbignJyk7CglyZXR1cm4gR2V0RHluYW1pY1Nob3J0Y3V0VG9vbHRpcFRleHQoQlsxMF0pICsiXG5cbiIrIFRhZ1tCWzEwXV0gKyJcbiIrIHRFeHAoQlsxMl0pOwp9LApnZXQgW01bMl1dKCkge3JldHVybiBHZXREeW5hbWljU2hvcnRjdXRUb29sdGlwVGV4dChbTVsyXV0pICsiXG4iKyB0RXhwKEJbMTJdKTsKfSwKZ2V0IFtNWzBdXSgpIHtnbG9iLnRvU3RhdHVzKFRbMF0sMjUwMCk7Cn0sCltCWzldXTogVGFnW0JbOV1dLApbTVs0XV06IFRhZ1tCWzldXSwKInRpdGxlYmFyLWJ1dHRvbiB0aXRsZWJhci1jbG9zZSI6IFRhZ1tCWzEzXV0sCmdldCBbTVszXV0oKSB7Cgl2YXIgdHh0ID0gYCR7Z2xvYi5wcmVmKCJkb20uZGlzYWJsZV9vcGVuX2R1cmluZ19sb2FkIikgPyAi0JfQsNC/0YDQtdGCIiA6ICLihq8g0KDQsNC30YDQtdGIIn3QuNGC0Ywg0LLRgdC/0LvRi9Cy0LDRjtGJ0LjQtSDQvtC60L3QsGA7CglpZiAoIWdsb2IucHJlZigicGxhY2VzLmhpc3RvcnkuZW5hYmxlZCIpKSB0eHQgPSBUWzldOwoJaWYgKGdsb2IucHJlZigicHJpdmFjeS5zYW5pdGl6ZS5zYW5pdGl6ZU9uU2h1dGRvd24iKSkgdHh0ID0gVFsxMF07CglnbG9iLnRvU3RhdHVzKHR4dCwzZTMpOwp9LApnZXQgW0JbMl1dKCkgeyAvL2N1c3RvbSBoaW50CglyZXR1cm4gdG9vbHRpcF94KHdpbmRvdy5ldmVudC50YXJnZXQsIuKpiSDQoNC+0LvQuNC6IMKxCdCY0LfQvNC10L3QuNGC0Ywg0LzQsNGB0YjRgtCw0LEiKTsKfSwKZ2V0IFtCWzE0XV0oKSB7cmV0dXJuIFRhZ1tCWzE0XV0gKyBUWzE0XTt9LApnZXQgImlkZW50aXR5LWljb24tYm94IigpIHsKCXJldHVybiB0b29sdGlwX3god2luZG93LmV2ZW50LnRhcmdldCwgdEV4cChCWzRdKSArIGJyX3ZhbCgpKTsKfSwKZ2V0IFtCWzRdXSgpIHtnbG9iLnRvU3RhdHVzKHRoaXMuYnJfZXhwKCksMjUwMCk7IC8v0YDQtdC20LjQvCDQutC90L7Qv9C+0LoKCXJldHVybiB0b29sdGlwX3god2luZG93LmV2ZW50LnRhcmdldCwgdEV4cChCWzRdKSArIGJyX3ZhbCgpKTsKfSwKZ2V0IFtCWzExXV0oKSB7Z2xvYi50b1N0YXR1cyh0aGlzLmJyX2V4cCgpLDI1MDApOwoJdmFyIHRyZyA9IHdpbmRvdy5ldmVudD8udGFyZ2V0OyAvL2N1c3RvbSBoaW50IDIKCXJldHVybiB0cmcuaWQuZW5kc1dpdGgoInIiKSAmJiB0cmcudGV4dENvbnRlbnQgKydcbicrIHRFeHAoQlsxMV0pOwp9LApnZXQgW0JbNl1dKCkgeyAvL0Zhdk1lbnUKCXZhciB0cmcgPSB3aW5kb3cuZXZlbnQ/LnRhcmdldDsKCWlmICh0cmcuaWQgPT0gQls2XSkgewoJCXRyeSB7dHJnLm1zdGF0ZSA9IHRyZy5zZWNvbmRhcnlQb3B1cC5zdGF0ZTt9IGNhdGNoe30gLy/QtNC70Y8gdWNmX1F1aWNrVG9nZ2xlLmpzCgkJem9vbSgwLDAsMCxgLCAke2dsb2IucHJlZigiYnJvd3Nlci50YWJzLmxvYWRJbkJhY2tncm91bmQiKSA/ICLQndC1INCy0YvQsdC40YDQsNGC0YwiIDogItCf0LXRgNC10LrQu9GO0YfQsNGC0YzRgdGPINCyIn0g0L3QvtCy0YvQtSDQstC60LvQsNC00LrQuGApOwoJfSBlbHNlIHsKCQl0cmcubXN0YXRlID0gdHJnLnN0YXRlOwoJCWdsb2IudG9TdGF0dXMoVFs2XSw5ZTMpOwoJfQoJaWYgKHRyZy5tc3RhdGUgIT0gIm9wZW4iKQoJCXJldHVybiB0RXhwKEJbNl0pCgllbHNlIHRyZy50b29sdGlwVGV4dCA9ICIiOwp9LApnZXQgW0JbOF1dKCkgeyAvL2dldCDQvNC+0LbQtdGCINCy0YvQv9C+0LvQvdGP0YLRjCDQutC+0LQKCXJldHVybiBHZXREeW5hbWljU2hvcnRjdXRUb29sdGlwVGV4dChCWzhdKSArIlxuIisgVGFnW0JbOF1dICsgYnJfdmFsKCk7Cn0sCmdldCBbTVs1XV0oKSB7CglyZXR1cm4gVGFnW0JbN11dICsgVGFnW0JbOF1dICsgYnJfdmFsKCk7Cn0sCmdldCAidWNmX1Nlc3Npb25NYW5hZ2VyIigpIHtnbG9iLnRvU3RhdHVzKFRbMTFdKTt9LApnZXQgInVuaWZpZWQtZXh0ZW5zaW9ucy1idXR0b24iKCl7cmV0dXJuICLQoNCw0YHRiNC40YDQtdC90LjRjyIrIFRbMTRdfSwKIl81MzE5MDZkMy1lMjJmLTRhNmMtYTEwMi04MDU3Yjg4YTFhNjNfLWJyb3dzZXItYWN0aW9uIjogVFsxMl0sIC8vU2luZ2xlRmlsZQoiXzUzMTkwNmQzLWUyMmYtNGE2Yy1hMTAyLTgwNTdiODhhMWE2M18tQkFQIjogVFsxMl0sCiJfYjlkYjE2YTQtNmVkYy00N2VjLWExZjQtYjg2MjkyZWQyMTFkXy1icm93c2VyLWFjdGlvbiI6IFRbMTNdLCAvL1ZESAoiX2I5ZGIxNmE0LTZlZGMtNDdlYy1hMWY0LWI4NjI5MmVkMjExZF8tQkFQIjogVFsxNF0sCmJyX2V4cCh0ID0gVFsyXSArIGJyX3ZhbCgpKXsKCXJldHVybiB0ICtgICR7RmYuRXhwKCkgPyAi0K3QutGB0L/QtdGA0YLQvdGL0LkiIDogItCf0YDQvtGB0YLQvtC5In0g0YDQtdC20LjQvCDQutC90L7Qv9C+0LpgfQp9OwoKd2luZG93Lmdsb2IgPSB7IC8vYWxsIFtDaHJvbWVPbmx5XS1zY3JpcHRzCglwcmVmKGtleSxzZXQsIHB0ID0ge2I6IkJvb2wiLG46IkludCIsczoiU3RyaW5nIn0pIHsgLy/QuNC70Lgga2V5ID0gW2tleSxkZWZhdWx0XQoJCWlmICh0eXBlb2Yga2V5ICE9ICJvYmplY3QiKSBrZXkgPSBba2V5XTsKCQl2YXIgdCA9IFNlcnZpY2VzLnByZWZzLmdldFByZWZUeXBlKGtleVswXSk7CgkJdCA9IHB0W3QgPT0gMTI4ID8gImIiIDogdCA9PSA2NCA/ICJuIiA6IHQgPT0gMzIgPyAicyIgOiAiIl07CgkJaWYgKCF0KSB0ID0gcHRbc2V0ICE9IHVuZGVmaW5lZCA/ICh0eXBlb2Ygc2V0KVswXSA6ICh0eXBlb2Yga2V5WzFdKVswXV07CgkJaWYgKCF0KSByZXR1cm47IGlmIChzZXQgIT0gdW5kZWZpbmVkKQoJCQlTZXJ2aWNlcy5wcmVmc1tgc2V0JHt0fVByZWZgXShrZXlbMF0sc2V0KQoJCWVsc2Ugc2V0ID0gU2VydmljZXMucHJlZnNbYGdldCR7dH1QcmVmYF0oLi4ua2V5KTsgcmV0dXJuIHNldDsKCX0sCgl1YShyZWFsID0gZmFsc2UsdWFfbXkgPSAiZ2VuZXJhbC51c2VyYWdlbnQub3ZlcnJpZGUiKSB7IC8v0YLQtdC60YPRidC40Lkg0LjQu9C4INCy0YjQuNGC0YvQuSDQrtC30LXRgNCQ0LPQtdC90YIKCQl0dHQgPSB0aGlzLnByZWYodWFfbXkpOyBTZXJ2aWNlcy5wcmVmcy5jbGVhclVzZXJQcmVmKHVhX215KTsKCQl1YSA9IENjWyJAbW96aWxsYS5vcmcvbmV0d29yay9wcm90b2NvbDsxP25hbWU9aHR0cCJdLmdldFNlcnZpY2UoQ2kubnNJSHR0cFByb3RvY29sSGFuZGxlcikudXNlckFnZW50OyAvLyDQutC+0YHRgtGL0LvRjAoJCXR0dCAmJiB0aGlzLnByZWYodWFfbXksdHR0KTsgaWYgKCF0dHQpIHR0dCA9IHVhOyBpZiAocmVhbCkgdHR0ID0gdWE7IHJldHVybiB0dHQ7Cgl9LAoJZGlyc3ZjZ2V0KCkgeyAvL9C60L7QvdGB0YLQsNC90YLQsCDQv9GD0YLQuCArIHN1YmRpcnMsINC10YHQu9C4INC/0L7RgdC7LiDQvtC/0YbQuNGPID0gIiIg0LLQtdGA0L3Rg9GC0Ywg0L/Rg9GC0YwsINC40L3QsNGH0LUg0L7RgtC60YDRi9GC0YwKCQl2YXIgZiwgZCA9IFsuLi5hcmd1bWVudHNdLCByID0gKGQuYXQoLTEpID09ICIiKTsgKHIpICYmIGQucG9wKCk7CgkJdHJ5IHtmID0gU2VydmljZXMuZGlyc3ZjLmdldChkWzBdIHx8ICJEZmx0RHdubGQiLENpLm5zSUZpbGUpO30gY2F0Y2gge2YgPSBTZXJ2aWNlcy5wcmVmcy5nZXRDb21wbGV4VmFsdWUoImJyb3dzZXIuZG93bmxvYWQuZGlyIixDaS5uc0lGaWxlKX0KCQlkLnNsaWNlKDEsIGQubGVuZ3RoKS5mb3JFYWNoKChjKT0+Zi5hcHBlbmQoYykpOwoJCWlmIChyKSByZXR1cm4gZi5wYXRoOyBmLmV4aXN0cygpICYmIGYubGF1bmNoKCk7Cgl9LAoJY3JvcChzLGN1dCA9IDMzLGNoID0gJ+KAplxuJykgeyAvL9GB0L7QutGA0LDRgtC40YLRjC/RgNCw0LfQsdC40YLRjCDRgdGC0YDQvtC60YMKCQlyZXR1cm4gcy5zdWJzdHJpbmcoMCxjdXQpICtgJHtzLmxlbmd0aCA+IGN1dCAtIDEgPyBgJHtjaH3igKYke3Muc3Vic3RyaW5nKHMubGVuZ3RoIC0gY3V0ICsgY2gubGVuZ3RoLHMubGVuZ3RoKX1gOiAnJ31gOwoJfSwKCWZvcm1hdEJ5dGVzKGIsZCA9IDEpIHsgLy/QvtCx0YrRkdC8INCx0LDQudGC4oCm0KLQsQoJCWxldCBpID0gTWF0aC5sb2cyKGIpLzEwfDA7IHJldHVybiBwYXJzZUZsb2F0KChiLzEwMjQqKihpPWk8PTA/MDppKSkudG9GaXhlZChkKSkrYCR7aT4wPydLTUdUJ1tpLTFdOicnfWJgOwoJfSwKCWFib3V0X2NvbmZpZyhmaWx0ZXIpIHsgLy/QvdCwINC+0L/RhtC40Y4KCQl2YXIgc2V0RmlsdGVyID0gKGUsaW5wdXQgPSAoZT8udGFyZ2V0IHx8IHdpbmRvdy5jb250ZW50LmRvY3VtZW50KS5nZXRFbGVtZW50QnlJZCgiYWJvdXQtY29uZmlnLXNlYXJjaCIpKSA9PiB7CgkJCWlmIChlIHx8IGlucHV0LnZhbHVlICE9IGZpbHRlcikgaW5wdXQuc2V0VXNlcklucHV0KGZpbHRlcik7fSwKCQlmb3VuZCA9IHdpbmRvdy5zd2l0Y2hUb1RhYkhhdmluZ1VSSSgiYWJvdXQ6Y29uZmlnIix0cnVlLCB7cmVsYXRlZFRvQ3VycmVudDogdHJ1ZSwKCQkJdHJpZ2dlcmluZ1ByaW5jaXBhbDogU2VydmljZXMuc2NyaXB0U2VjdXJpdHlNYW5hZ2VyLmdldFN5c3RlbVByaW5jaXBhbCgpfSk7CgkJaWYgKGZvdW5kKSBzZXRGaWx0ZXIobnVsbCx3aW5kb3cpOwoJCWVsc2UgZ0Jyb3dzZXIuc2VsZWN0ZWRCcm93c2VyLmFkZEV2ZW50TGlzdGVuZXIoInBhZ2VzaG93IixzZXRGaWx0ZXIsIHtvbmNlOiB0cnVlfSk7Cgl9LAoJdG9TdGF0dXModHh0LHRpbWUgPSA1ZTMsU3RhdHVzUGFuZWwgPSB3aW5kb3cuU3RhdHVzUGFuZWwpIHsKCQlpZiAoU3RhdHVzUGFuZWwudXBkYXRlLnRpZCkKCQkJY2xlYXJUaW1lb3V0KFN0YXR1c1BhbmVsLnVwZGF0ZS50aWQpCgkJZWxzZSB7CgkJCXZhciB7dXBkYXRlfSA9IFN0YXR1c1BhbmVsOwoJCQlTdGF0dXNQYW5lbC51cGRhdGUgPSAoKSA9PiB7fTsKCQkJU3RhdHVzUGFuZWwudXBkYXRlLnJldCA9ICgpID0+IHsKCQkJCVN0YXR1c1BhbmVsLnVwZGF0ZSA9IHVwZGF0ZSxTdGF0dXNQYW5lbC51cGRhdGUoKTsKCQl9fQoJCVN0YXR1c1BhbmVsLnVwZGF0ZS50aWQgPSBzZXRUaW1lb3V0KFN0YXR1c1BhbmVsLnVwZGF0ZS5yZXQsdGltZSk7CgkJU3RhdHVzUGFuZWwuX2xhYmVsID0gdHh0OwoJfSwKCWZsYXNoKGlkLHN0eWxlLGNvbG9yLG1zLHRleHQsdGltZSA9IDVlMykgeyAvL9GB0YLQsNGC0YPRgSwg0LzQuNCz0LDQvdC40LUKCQlpZCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKGlkIHx8ICd1cmxiYXItaW5wdXQtY29udGFpbmVyJyk7IGlmICghaWQpIHJldHVybjsKCQlpZiAoc3R5bGUpIGlkLnN0eWxlLmZpbHRlciA9IHN0eWxlOyBpZiAoY29sb3IpIGlkLnN0eWxlLmJhY2tncm91bmQgPSBjb2xvcjsKCQlpZiAobXMpIHNldFRpbWVvdXQoKCkgPT4gewoJCQlpZC5zdHlsZS5yZW1vdmVQcm9wZXJ0eSgnZmlsdGVyJyksaWQuc3R5bGUucmVtb3ZlUHJvcGVydHkoJ2JhY2tncm91bmQtY29sb3InKTt9LG1zKTsKCQlpZiAodGV4dCkgZ2xvYi50b1N0YXR1cyh0ZXh0LHRpbWUpOwoJfSwKCW1vZGVfc2tpbih0ZXh0LHAgPSB0aGlzLnByZWYoJ25ldHdvcmsucHJveHkudHlwZScpLHQscyA9ICd1bnNldCcsbyA9ICcnLHopIHt3aXRoKGdsb2IpewoJCWlmIChwcmVmKCJkb20uc2VjdXJpdHkuaHR0cHNfb25seV9tb2RlIikpCgkJCWZsYXNoKEJbMTBdLCJkcm9wLXNoYWRvdygwcHggMC41cHggMHB4ICNGOEYpIiksbyA9ICcsINGC0L7Qu9GM0LrQviBIVFRQUycKCQllbHNlIGZsYXNoKEJbMTBdLCJub25lIik7CgkJaWYgKHVhKCkgJiYgKHVhKCkgIT0gdWEodHJ1ZSkpKSBvID0gbyArJywg0YfRg9C20L7QuSDQrtC30LXRgNCQ0LPQtdC90YInOwoJCXogPSBwcmVmKCJuZXR3b3JrLnByb3h5Lm5vX3Byb3hpZXNfb24iKSA9PSAiIiA/ICIiIDogIiwg0JXRgdGC0Ywg0YHQsNC50YLRiy3QuNGB0LrQu9GO0YfQtdC90LjRjyI7CgkJaWYgKHAgPT0gMSkgdCA9IFsnc2VwaWEoMTAwJSkgc2F0dXJhdGUoMTUwJSkgYnJpZ2h0bmVzcygwLjkpJywgJ9Cg0YPRh9C90LDRjyDQvdCw0YHRgtGA0L7QudC60LAg0L/RgNC+0LrRgdC4Jysgel07CgkJZWxzZSBpZiAocCA9PSAyKSB0ID0gWydodWUtcm90YXRlKDEyMGRlZykgc2F0dXJhdGUoNzAlKScsVFsxXSArIHpdLHMgPSAnaHVlLXJvdGF0ZSgyNzBkZWcpIGJyaWdodG5lc3MoOTUlKSc7CgkJZWxzZSBpZiAocCA9PSA0KSB0ID0gWydodWUtcm90YXRlKDI1MGRlZykgYnJpZ2h0bmVzcygwLjk1KSBzYXR1cmF0ZSgxNTAlKScsJ9Ch0LXRgtGMIC0g0LDQstGC0L7QvdCw0YHRgtGA0L7QudC60LAg0L/RgNC+0LrRgdC4Jysgel07CgkJZWxzZSBpZiAocCA9PSAwKSB0ID0gWydzYXR1cmF0ZSgwJSkgYnJpZ2h0bmVzcygwLjk1KScsJ9Cd0LDRgdGC0YDQvtC50LrQuCDRgdC10YLQuCAtINGB0LjRgdGC0LXQvNC90YvQtScrIHpdCgkJZWxzZSB0ID0gW3MsJ9Ch0LXRgtGMINGA0LDQsdC+0YLQsNC10YIg0LHQtdC3INC/0YDQvtC60YHQuCddOyAvLyDRgdC10YDRi9C5INGE0L7QvSDQutC90L7Qv9C60LgKCQlmbGFzaChCWzBdLHByZWYoRmYuaSkgPiAxID8gImh1ZS1yb3RhdGUoMTgwZGVnKSBkcm9wLXNoYWRvdygwcHggMC41cHggMHB4ICNGNjgpIiA6ICJub25lIik7CgkJZmxhc2goQls2XSxzKTsgZmxhc2goQlsxXSx0WzBdKTsKCQl6ID0gdHlwZW9mKHRleHQpOyBpZiAoeiA9PSAnc3RyaW5nJykKCQkJdG9TdGF0dXModGV4dCA/IHRleHQgOiAiXHV7MjZBMX0iKyB0WzFdICsgbyw1ZTMpOyAvLyDRgdC40LzQstC+0Lsg0JLQvdC40LzQsNC90LjQtQoJfX0KfTsKKChvYmosZGVsLHJlLHJlb3MpID0+IHsgLy8g0L/QsNGA0YHQuNC90LMg0LHQu9C+0LrQsCDQutC70LDQstC40Ygg0YPRgdC60L7RgNGP0LXRgiDQvtCx0YDQsNCx0L7RgtC60YMg0L3QsNC20LDRgtC40LkKCXZhciBudW0gPSAtRmYub3MubGVuZ3RoIC0gMTsKCWZvcih2YXIgcCBpbiBrbGFCYSkgcmVvcy50ZXN0KHApICYmIGRlbC5hZGQoIHAuZW5kc1dpdGgocGxhdGZvcm0pID8gcC5zbGljZSgwLG51bSkgOiBwKTsKCWZvcih2YXIgcCBpbiBrbGFCYSkgZGVsLmhhcyhrbGFCYVtwXSkgJiYgZGVsLmFkZChwKTsKCWZvcih2YXIgZCBvZiBkZWwpIGRlbGV0ZSBrbGFCYVtkXTsgLy/QtdGB0YLRjCBLZXlfT1MgPyDRg9C00LDQu9C40YLRjCDQuNC80LXQvdCwLdC60LvQvtC90YsKCWZvcih2YXIgcCBpbiBrbGFCYSkgaWYgKHJlb3MudGVzdChwKSkKCQkJa2xhQmFbcC5yZXBsYWNlKHJlb3MsJycpXSA9IGtsYUJhW3BdLCBkZWxldGUga2xhQmFbcF07IC8v0YPQsdGA0LDRgtGMINC40LzRjyDQstCw0YjQtdC5INCe0KEg0LjQtyDRgdCy0L7QudGB0YLQstCwCglmb3IodmFyIHAgaW4ga2xhQmEpIHt2YXIgZnVuYyA9IGtsYUJhW3BdOyAvLygpe+KApn0sIGJvb2wsbnVtCgkJaWYgKHR5cGVvZiBmdW5jID09ICJzdHJpbmciKSBmdW5jID0ga2xhQmFbZnVuY107IC8v0YHRgdGL0LvQutCwINC90LAg0YTRg9C90LrRhtC40Y4KCQl2YXIgW2tleSxtb2RdID0gcC5zcGxpdCgiXyIpOyBtb2QgPSBtb2QgfHwgIiI7CgkJdmFyIHVwcGVyID0ga2V5WzBdLnRvVXBwZXJDYXNlKCk7IHZhciBwcmV2ZW50ID0ga2V5WzBdID09IHVwcGVyOwoJCXZhciBbLCBtLGldID0gbW9kLm1hdGNoKHJlKTsgbSA9IG0gfHwgMDsgLy9tb2RpZmllcnMgYml0bWFwCgkJdmFyIGFyciA9IFtmdW5jLHByZXZlbnQsIGkgPyBpID09ICJJIiA/IDAgOiAxIDogLTFdOyAvL3RleHRmaWVsZHMgZmxhZyDQmNC80Y9faSAxINC60YDQvtC80LUg0L/QvtC70LXQuSDQstCy0L7QtNCwCgkJdmFyIHByb3AgPSBwcmV2ZW50ID8ga2V5IDogdXBwZXIgKyBrZXkuc2xpY2UoMSk7IC8v0LjQvNGPINCx0LXQtyBtb2QKCQl2YXIgbyA9IG9ialtwcm9wXSB8fCAob2JqW3Byb3BdID0gT2JqZWN0LmNyZWF0ZShudWxsKSk7CgkJb1ttXSA/IG9bbV0ucHVzaChhcnIpIDogb1ttXSA9IFthcnJdOyAvL9C40LzRjyDRgdC+INGB0YLRgNC+0YfQvdC+0Lk6IFNraXAgcHJldmVudERlZmF1bHQKCX07IGtsYUJhID0gb2JqOyB9KShPYmplY3QuY3JlYXRlKG51bGwpLG5ldyBTZXQoKSwvKFxkKyk/KGkpPy9pLC9fKD86d2lufGxpbnV4fG1hY29zeCkkLyk7CmRhdGEgPSB7fTsgTS5mb3JFYWNoKChrKSA9PntkYXRhWyIjIisga10gPSBkYXRhWyIuIisga10gPSBNb3VzZVtrXX0pOwoKdmFyIERlYnVnID0gKGUsaWQgPSAic2lkZWJhci1ib3giKSA9PiB7CglpZiAoU2VydmljZXMucHJlZnMuZ2V0Qm9vbFByZWYoRmYucCArJ2RlYnVnJyxmYWxzZSkpIHJldHVybiB0cnVlOwoJcmV0dXJuICFkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZCkuaGlkZGVuOwp9LAprZXlkb3duX3dpbiA9IGUgPT4geyAvL9C/0LXRgNC10YXQstCw0YIg0LrQu9Cw0LLQuNGILCDRg9GH0LjRgtGL0LLQsNGPINC/0L7Qu9GPINCy0LLQvtC00LAKCWlmIChlLnJlcGVhdCkgcmV0dXJuOyAvLyDQstGL0LrQu9GO0YfQuNGC0YwgZS5nZXRNb2RpZmllclN0YXRlKCJDYXBzTG9jayIpCgl2YXIgZGF0YSA9IGtsYUJhW2UuY29kZV0/LltlLm1ldGFLZXkqOCArIGUuY3RybEtleSo0ICsgZS5zaGlmdEtleSoyICsgZS5hbHRLZXldOwoJaWYgKGRhdGEpIC8v0LXRgdGC0YwgSG90S2V5CgkJZm9yKHZhciBbZnVuYyxwLGldIG9mIGRhdGEpCgkJCWlmIChpIF4gZG9jU2hlbGwuaXNDb21tYW5kRW5hYmxlZCgiY21kX2luc2VydFRleHQiKSkKCQkJCXAgJiYgZS5wcmV2ZW50RGVmYXVsdCgpLCBmdW5jKGUsIGdCcm93c2VyLnNlbGVjdGVkVGFiKTsgLy/Qt9Cw0L/Rg9GB0Log0L/QviDRgdC+0YfQtdGC0LDQvdC40Y4KCWlmICghRGVidWcoKSkgcmV0dXJuOyAvL9C/0L7QutCw0Lcg0LrQu9Cw0LLQuNGICgljb25zb2xlLmxvZygn4pagIGtleSAnKyBlLmNvZGUgKyAoJ18nKyAoZS5tZXRhS2V5KjggKyBlLmN0cmxLZXkqNCArIGUuc2hpZnRLZXkqMiArIGUuYWx0S2V5KSkucmVwbGFjZSgnXzAnLCcnKSk7Cn07Cmxpc3RlbmVyID0geyAvL9C00LXQudGB0YLQstC40Y8g0LzRi9GI0LgsINC/0LXRgNC10YXQstCw0YIg0YHRg9GJ0LXRgdGC0LLRg9GO0YnQuNGFCgloYW5kbGVFdmVudChlKSB7CgkJaWYgKHRoaXMuc2tpcCB8fCBlLmRldGFpbCA+IDEpIHJldHVybjsKCQl2YXIgdHJnID0gZS50YXJnZXQsIGlkID0gdHJnLmlkIHx8IHRyZy5jbGFzc05hbWUgfHwgdHJnLnRhZ05hbWU7CgkJaWYgKGUudHlwZSA9PSAibW91c2VlbnRlciIpIHsKCQkJdmFyIGhpbnQgPSBPdmVyW2lkXSB8fCBPdmVyWyh0cmcgPSB0cmcucGFyZW50Tm9kZSkuaWRdOwoJCQlpZiAoaGludCkgdHJnLnRvb2x0aXBUZXh0ID0gaGludDsgcmV0dXJuOyAvL9C+0LHQvdC+0LLQuNGC0Ywg0L/QvtC00YHQutCw0LfQutGDCgkJfQoJCXZhciBzZWxzID0gdGhpcy5zZWxlY3RvcnMuZmlsdGVyKHRoaXMuZmlsdGVyLCB0cmcpOyAvLyNpZAoJCXZhciB7bGVuZ3RofSA9IHNlbHM7IGlmICghbGVuZ3RoKSByZXR1cm47CgkJdmFyIHdoZWVsID0gZS50eXBlLnN0YXJ0c1dpdGgoInciKTsKCQl2YXIgbnVtID0gZS5tZXRhS2V5KjY0ICsgZS5jdHJsS2V5KjMyICsgZS5zaGlmdEtleSoxNiArIGUuYWx0S2V5KjggKyAod2hlZWwgPyAyIDogZS5idXR0b24qMTI4KTsgLy9kYmwqNAoJCXZhciBvYmogPSBkYXRhWwoJCQlsZW5ndGggPiAxICYmIHNlbHMuZmluZCh0aGlzLmZpbmQsbnVtKSB8fCBzZWxzWzBdCgkJXTsKCQlEZWJ1ZygpICYmIGNvbnNvbGUubG9nKCfilqAgYnV0IMKrJysgaWQgKyfCuyBrZXkgJysgbnVtKTsgLy93aGVlbCDQtNCy0LDQttC00YsKCQlpZiAod2hlZWwpIHJldHVybiBvYmpbbnVtXT8uKHRyZywgZS5kZWx0YVkgPCAwKTsKLy8gbW91c2Vkb3duCgkJaWYgKGUudHlwZS5zdGFydHNXaXRoKCJtIikpIHsKCQkJb2JqLm1vdXNlZG93blRhcmdldCAmJiB0aGlzLnN0b3AoZSk7CgkJCXRoaXMubG9uZ1ByZXNzID0gZmFsc2U7IC8vKyDQt9Cw0LTQtdGA0LbQutCwINC/0YDQuCDQvtCx0YvRh9C90L7QvCDQutC70LjQutC1CgkJCWlmICgrK251bSBpbiBvYmopCgkJCQl0aGlzLm1vdXNlZG93blRJRCA9IHNldFRpbWVvdXQodGhpcy5vbkxvbmdQcmVzcyw2NDAsIHRyZyxvYmosbnVtKTsKCQkJaWYgKGUuYnV0dG9uID09IDIpCgkJCQl0aGlzLmN0eCA9IHRyZy5nZXRBdHRyaWJ1dGUoImNvbnRleHQiKSwgdHJnLnNldEF0dHJpYnV0ZSgiY29udGV4dCIsIiIpOwoJCQlyZXR1cm47CgkJfQoJCW9iai5tb3VzZWRvd25UYXJnZXQgfHwgdGhpcy5zdG9wKGUpOwkvL2NsaWNrCgkJaWYgKHRoaXMubG9uZ1ByZXNzKSByZXR1cm4gdGhpcy5sb25nUHJlc3MgPSBmYWxzZTsKCQl0aGlzLm1vdXNlZG93blRJRCAmJj0gY2xlYXJUaW1lb3V0KHRoaXMubW91c2Vkb3duVElEKTsKCQlpZiAoIW9ialtudW1dKSB7CgkJCWlmIChlLmJ1dHRvbiA9PSAxKSByZXR1cm47CgkJCWlmIChlLmJ1dHRvbikgewoJCQkJbnVtID0gImNvbnRleHQiOwoJCQkJZm9yKHZhciBwIGluIHRoaXMuYSkgdGhpcy5hW3BdID0gZVtwXTsKCQkJfSBlbHNlCgkJCQludW0gPSAiZGlzcGF0Y2giLCB0aGlzLm1kdCA9IG9iai5tb3VzZWRvd25UYXJnZXQ7CgkJCW9iaiA9IHRoaXM7CgkJfQoJCW9ialtudW1dKHRyZyk7IC8vcnVuCgl9LAoJZmluZChzZWwpIHsgLy/Rg9GB0LvQvtCy0LjRjyDQt9Cw0L/Rg9GB0LrQsCA/CgkJcmV0dXJuIGRhdGFbc2VsXVt0aGlzXSB8fCBkYXRhW3NlbF1bdGhpcyArIDFdOwoJfSwKCWZpbHRlcihzZWwpIHtyZXR1cm4gdGhpcy5jbG9zZXN0KHNlbCk7Cgl9LAoJZ2V0IHNlbGVjdG9ycygpIHsKCQl0aGlzLm9uTG9uZ1ByZXNzID0gKHRyZyxvYmosbnVtKSA9PiB7CgkJCXRoaXMubW91c2Vkb3duVElEID0gbnVsbDsKCQkJdGhpcy5sb25nUHJlc3MgPSB0cnVlOwoJCQlvYmpbbnVtXSh0cmcpOwoJCX0KCQlkZWxldGUgdGhpcy5zZWxlY3RvcnM7CgkJcmV0dXJuIHRoaXMuc2VsZWN0b3JzID0gT2JqZWN0LmtleXMoZGF0YSk7Cgl9LAoJZ2V0IG1kRXZlbnQoKSB7CgkJZGVsZXRlIHRoaXMubWRFdmVudDsKCQlyZXR1cm4gdGhpcy5tZEV2ZW50ID0gbmV3IE1vdXNlRXZlbnQoIm1vdXNlZG93biIsIHtidWJibGVzOiB0cnVlfSk7Cgl9LAoJY29udGV4dCh0cmcpIHsKCQl0aGlzLmN0eCA/IHRyZy5zZXRBdHRyaWJ1dGUoImNvbnRleHQiLHRoaXMuY3R4KSA6IHRyZy5yZW1vdmVBdHRyaWJ1dGUoImNvbnRleHQiKTsKCQl0cmcuZGlzcGF0Y2hFdmVudChuZXcgTW91c2VFdmVudCgiY29udGV4dG1lbnUiLHRoaXMuYSkpOwoJfSwKCWRpc3BhdGNoKHRyZykgewoJCXRoaXMuc2tpcCA9IHRydWU7CgkJdGhpcy5tZHQgPyB0cmcuZGlzcGF0Y2hFdmVudCh0aGlzLm1kRXZlbnQpIDogdHJnLmNsaWNrKCk7CgkJdGhpcy5za2lwID0gZmFsc2U7Cgl9LAoJc3RvcDogZSA9PiB7CgkJZS5wcmV2ZW50RGVmYXVsdCgpOyBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpOwoJfSwKCWE6IHtfX3Byb3RvX186IG51bGwsYnViYmxlczogdHJ1ZSxzY3JlZW5YOiAwLHNjcmVlblk6IDB9Cn0sCmlkID0gInVjZl9ob29rRXhwZXJ0IixldmVudHMgPSBbImNsaWNrIiwibW91c2Vkb3duIiwid2hlZWwiLCJtb3VzZWVudGVyIl0sCmVscyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoIiNuYXZpZ2F0b3ItdG9vbGJveCwjdWNmLWFkZGl0aW9uYWwtdmVydGljYWwtYmFyLCNhcHBNZW51LXBvcHVwLCN3aWRnZXQtb3ZlcmZsb3ctbWFpblZpZXciKTsKZm9yKHZhciBlbCBvZiBlbHMpIGZvcih2YXIgdHlwZSBvZiBldmVudHMpCgkJZWwuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLGxpc3RlbmVyLHRydWUpOwp3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigia2V5ZG93biIsa2V5ZG93bl93aW4sdHJ1ZSk7CnVjZl9jdXN0b21fc2NyaXB0X3dpbi51bmxvYWRsaXN0ZW5lcnMucHVzaChpZCk7CnVjZl9jdXN0b21fc2NyaXB0X3dpbltpZF0gPSB7ZGVzdHJ1Y3RvcigpIHsKCXdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCJrZXlkb3duIixrZXlkb3duX3dpbik7Cglmb3IodmFyIGVsIG9mIGVscykgZm9yKHZhciB0eXBlIG9mIGV2ZW50cykKCQllbC5yZW1vdmVFdmVudExpc3RlbmVyKHR5cGUsbGlzdGVuZXIsdHJ1ZSk7Cn19Owp2YXIgYWRkRGVzdHJ1Y3RvciA9IG5leHREZXN0cnVjdG9yID0+IHsgLy/QtNC70Y8gc2F2ZVNlbFRvVHh0Cgl2YXIge2Rlc3RydWN0b3J9ID0gdWNmX2N1c3RvbV9zY3JpcHRfd2luW2lkXTsKCXVjZl9jdXN0b21fc2NyaXB0X3dpbltpZF0uZGVzdHJ1Y3RvciA9ICgpID0+IHsKCQl0cnkge2Rlc3RydWN0b3IoKTt9IGNhdGNoKGV4KSB7Q3UucmVwb3J0RXJyb3IoZXgpO30KCQluZXh0RGVzdHJ1Y3RvcigpOwp9fTsKd2l0aCAoZG9jdW1lbnQpIGdldEVsZW1lbnRCeUlkKEJbMTFdKS5yZW1vdmVBdHRyaWJ1dGUoInRvb2x0aXAiKSwKCWdldEVsZW1lbnRCeUlkKCJuYXYtYmFyIikudG9vbHRpcCA9IGlkOyAvL9GE0LvQsNCzINGD0YHQv9C10YjQvdC+0Lkg0LfQsNCz0YDRg9C30LrQuAoKZ2xvYi5tb2RlX3NraW4oKTsgLy/Qv9C+0LTRgdCy0LXRgtC60LAg0LrQvdC+0L/QvtC6INC4INC/0L7QtNGB0LrQsNC30LrQuCDQvtGC0L7QsdGA0LDQttCw0Y7RgiDQvdCw0YHRgtGA0L7QudC60Lgg0LHRgNCw0YPQt9C10YDQsApnbG9iLnByZWYoJ3VpLnByZWZlcnNSZWR1Y2VkTW90aW9uJywwKTsJLy9Eb3dubG9hZEJ1dHRvbiBhbmltYXRpb24gRklYCnZhciB0YWJyID0gRmYucCArIm9wYWNpdHkiLHVybCA9IGByZXNvdXJjZTovLyR7dGFicn0vYCwgLy9icmlnaHQgdGFicwpnZXRJbnRQcmVmID0gKHApID0+IFNlcnZpY2VzLnByZWZzLmdldEludFByZWYocCwxMDApLApzc3MgPSBDY1siQG1vemlsbGEub3JnL2NvbnRlbnQvc3R5bGUtc2hlZXQtc2VydmljZTsxIl0uZ2V0U2VydmljZShDaS5uc0lTdHlsZVNoZWV0U2VydmljZSksCmNzcyA9IGBALW1vei1kb2N1bWVudCB1cmwoY2hyb21lOi8vYnJvd3Nlci9jb250ZW50L2Jyb3dzZXIueGh0bWwpIHsKCTppcygke2lkfSlbcnN0XSB7ZmlsdGVyOiBncmF5c2NhbGUoMSUpICFpbXBvcnRhbnR9Cgk6cm9vdDpub3QoW2Nocm9tZWhpZGRlbio9dG9vbGJhcl0pICN0YWJicm93c2VyLXRhYmJveCB7YmFja2dyb3VuZC1jb2xvcjogYmxhY2sgIWltcG9ydGFudH0KCTpyb290Om5vdChbY2hyb21laGlkZGVuKj10b29sYmFyXSkgI3RhYmJyb3dzZXItdGFicGFuZWxzIHtvcGFjaXR5OiR7Z2V0SW50UHJlZih0YWJyKS8xMDB9ICFpbXBvcnRhbnR9fWA7ClNlcnZpY2VzLmlvLmdldFByb3RvY29sSGFuZGxlcigicmVzb3VyY2UiKS5RdWVyeUludGVyZmFjZShDaS5uc0lSZXNQcm90b2NvbEhhbmRsZXIpCgkuc2V0U3Vic3RpdHV0aW9uKHRhYnIsU2VydmljZXMuaW8ubmV3VVJJKCJkYXRhOnRleHQvY3NzLCIrIGVuY29kZVVSSUNvbXBvbmVudChjc3MpKSk7CnNzcy5sb2FkQW5kUmVnaXN0ZXJTaGVldChTZXJ2aWNlcy5pby5uZXdVUkkodXJsKSxzc3MuVVNFUl9TSEVFVCk7CnZhciBzdCA9IEluc3BlY3RvclV0aWxzLmdldEFsbFN0eWxlU2hlZXRzKGRvY3VtZW50KS5maW5kKHMgPT4gcy5ocmVmID09IHVybCkuY3NzUnVsZXNbMF0uY3NzUnVsZXNbMl0uc3R5bGU7CnZhciBvYnNlcnZlciA9ICgpID0+IHN0LnNldFByb3BlcnR5KCJvcGFjaXR5IiwgZ2V0SW50UHJlZih0YWJyKS8xMDAsImltcG9ydGFudCIpOwpwcmVmcy5hZGRPYnNlcnZlcih0YWJyLG9ic2VydmVyKTsKdGhpcy5yZW1vdmVQcmVmT2JzID0gKCkgPT4gcHJlZnMucmVtb3ZlT2JzZXJ2ZXIodGFicixvYnNlcnZlcik7IC8vZW5kIGJyaWdodAoKdmFyIGNzc19VU0VSID0gKGNzcykgPT4geyAvL9C70L7QutCw0LvRjNC90YvQtSDRhNGD0L3QutGG0LjQuAoJdmFyIHN0eWxlID0gRmlsZUV4aXN0cyhjc3MpID8gU2VydmljZXMuaW8ubmV3VVJJKGNzcykgOiBtYWtlVVJJKCdkYXRhOnRleHQvY3NzO2NoYXJzZXQ9dXRmLTgsJysgZW5jb2RlVVJJQ29tcG9uZW50KGNzcykpOwoJdmFyIGFyZ3MgPSBbc3R5bGUsc3NzLlVTRVJfU0hFRVRdOyAvLyDRgdGC0LjQu9GMOiDRhNCw0LnQuyDQuNC70LggQ1NTCgkodGhpcy5jc3MgPSAhdGhpcy5jc3MpID8gc3NzLmxvYWRBbmRSZWdpc3RlclNoZWV0KC4uLmFyZ3MpIDogc3NzLnVucmVnaXN0ZXJTaGVldCguLi5hcmdzKTsKfSwKZ0NsaXBib2FyZCA9IHt3cml0ZShzdHIsY2ggPSBDY1siQG1vemlsbGEub3JnL3dpZGdldC9jbGlwYm9hcmRoZWxwZXI7MSJdLmdldFNlcnZpY2UoQ2kubnNJQ2xpcGJvYXJkSGVscGVyKSkgewoJCSh0aGlzLndyaXRlID0gc3RyID0+IGNoLmNvcHlTdHJpbmdUb0NsaXBib2FyZChzdHIsU2VydmljZXMuY2xpcGJvYXJkLmtHbG9iYWxDbGlwYm9hcmQpKShzdHIpO30KfSwKVGFiQWN0ID0gKGUpID0+IHtyZXR1cm4gZS5jbG9zZXN0KCIudGFiYnJvd3Nlci10YWIiKTsKfSwKc3dpdGNoVGFiID0gKHVybCA9ICdhYm91dDpzZXJ2aWNld29ya2VycycsZ28gPSBmYWxzZSkgPT4geyAvL9C+0YLQutGA0YvRgtGMINCy0LrQu9Cw0LTQutGDIHwg0LfQsNC60YDRi9GC0YwsINC10YHQu9C4INC+0YLQutGA0YvRgtCwIHwg0LLRi9Cx0YDQsNGC0YwKCWZvcih2YXIgdGFiIG9mIGdCcm93c2VyLnZpc2libGVUYWJzKQoJCWlmICh0YWIubGlua2VkQnJvd3Nlci5jdXJyZW50VVJJLnNwZWMgPT0gdXJsKQoJCQl7Z28gPyBnQnJvd3Nlci5zZWxlY3RlZFRhYiA9IHRhYiA6IGdCcm93c2VyLnJlbW92ZVRhYih0YWIpOyByZXR1cm47fQoJZ0Jyb3dzZXIuYWRkVHJ1c3RlZFRhYih1cmwpOyBnQnJvd3Nlci5zZWxlY3RlZFRhYiA9IGdCcm93c2VyLnZpc2libGVUYWJzW2dCcm93c2VyLnZpc2libGVUYWJzLmxlbmd0aCAtMV07Cn0sClRhYnNEZWwgPSAocmlnaHQgPSAwLGN1cnIgPSBnQnJvd3Nlci5zZWxlY3RlZFRhYikgPT4geyAvLyDQt9Cw0LrRgNGL0YLRjCDQstC60LvQsNC00LrQuCDRgdC70LXQstCwL9GB0L/RgNCw0LLQsCDQvtGCINCw0LrRgtC40LLQvdC+0LkKCXZhciB0YWJzID0gZ0Jyb3dzZXIudmlzaWJsZVRhYnMuZmlsdGVyKHRhYiA9PiAhdGFiLnBpbm5lZCksIGkgPSB0YWJzLmluZGV4T2YoY3Vycik7Cgl2YXIgYSA9IChpICE9IC0xKSwgYiA9IChhID8gaSArIHJpZ2h0IDogIXJpZ2h0ICogdGFicy5sZW5ndGgpOwoJYXJncyA9IHJpZ2h0ID8gW2IsIHRhYnMubGVuZ3RoXSA6IFswLGJdOwoJdGFicy5zbGljZSguLi5hcmdzKS5mb3JFYWNoKChpKSA9PiB7Z0Jyb3dzZXIucmVtb3ZlVGFiKGkpfSk7Cn0sCnN3aXRjaFByb3h5ID0gKHBhYyA9ICdodHRwczovL2FudGl6YXByZXQucHJvc3RvdnBuLm9yZy9wcm94eS5wYWMnKSA9PiB7Cgl2YXIgcG4gPSAnbmV0d29yay5wcm94eS50eXBlJyxwID0gJ25ldHdvcmsucHJveHkuYXV0b2NvbmZpZ191cmwnOwoJaWYgKGdsb2IucHJlZihwbikgIT0gMikgLy8g0LLRi9C60LvRjtGH0LjRgtGMCgkJZ2xvYi5wcmVmKHBuLDIpLCBnbG9iLnByZWYocCxwYWMpCgllbHNlCgkJZ2xvYi5wcmVmKHBuLDUpLCBnbG9iLnByZWYocCwibG9jYWxob3N0Iik7CglnbG9iLm1vZGVfc2tpbigpOyAvL9GA0LDQt9C90YvQuSDRhNC+0L0g0LfQsNC80LrQsCDQtNC70Y8g0J/RgNC+0LrRgdC4CglCcm93c2VyUmVsb2FkKCk7Cn0sClRpdGxlID0gKG1heCx0aXRsZSkgPT4geyAvL9C30LDQs9C+0LvQvtCy0L7Qui4g0LHQtdC3INC+0LHRgNC10LfQutC4OiBtYXgg0L3QtSDRg9C60LDQt9Cw0L0sINC00L7QvNC10L06IG1heCA8MCwgKyDQtNCw0YLQsDogbWF4PTAKCWlmICghdGl0bGUpIHZhciB0aXRsZSA9IGRvY3VtZW50LnRpdGxlIHx8IGdCcm93c2VyLnNlbGVjdGVkVGFiLmxhYmVsOwoJaWYgKG1heCA9PSB1bmRlZmluZWQpIHJldHVybiB0aXRsZTsgLy/QvtCz0YDQsNC90LjRh9C40YLRjCDQtNC70LjQvdGDLCDRg9Cx0YDQsNGC0Ywg0YHQu9GD0LbQtdCx0L3Ri9C1INGB0LjQvNCy0L7Qu9GLCgl0aXRsZSA9IHRpdGxlLnJlcGxhY2UoL1tcXFwvPypcIidgXSsvZywnJykucmVwbGFjZSgvXHMrL2csJyAnKS5yZXBsYWNlKC9bfDw+XSsvZywnXycpLnJlcGxhY2UoLzovZywn1oknKS50cmltKCk7CglpZiAoIG1heCA+IDAgKSByZXR1cm4gdGl0bGUuc2xpY2UoMCxtYXgpOwoJaWYgKCBtYXggPT0gMCkgcmV0dXJuIHRpdGxlLnNsaWNlKDAsMTAwKSArIl8iKyBuZXcgRGF0ZSgpLnRvTG9jYWxlRGF0ZVN0cmluZygncnUnLCB7ZGF5OidudW1lcmljJyxtb250aDonbnVtZXJpYycseWVhcjonMi1kaWdpdCd9KSArJy0nKyBuZXcgRGF0ZSgpLnRvTG9jYWxlVGltZVN0cmluZygnZW4tR0InKS5yZXBsYWNlKC86L2csItaJIik7IC8v0LTQsNGC0LAt0YfQsNGB0YsKCXZhciBob3N0ID0gZGVjb2RlVVJJQ29tcG9uZW50KGdVUkxCYXIudmFsdWUpOyAvL21heCA8IDAKCWlmICghL15maWxlOlwvXC8vLnRlc3QoaG9zdCkpIGhvc3QgPSBob3N0LnJlcGxhY2UoL14uKnVybD18aHR0cHM/OlwvXC98d3d3XC58XC8uKi9nLCcnKS5yZXBsYWNlKC9ecnVcLnxebVwufGZvcnVtXC4vLCcnKS5yZXBsYWNlKC9eY2x1YlwuZG5zLywnZG5zJyk7CglyZXR1cm4gaG9zdDsKfSwKc2F2ZSA9ICgpID0+IHsgLy/RhNGD0L3QutGG0LjRjyDQuNC3IFNpbmdsZUhUTUwuanNtCgl2YXIgYXJncyA9IFtnbG9iLmNyb3AoIuKImiDRgdGC0YDQsNC90LjRhtCwINC30LDQv9C40YHQsNC90LA6ICIrIFRpdGxlKDApLDQ4LCcnKSw3ZTNdOwoJdHJ5IHtDdS5nZXRHbG9iYWxGb3JPYmplY3QoQ3UpW1N5bWJvbC5mb3IoIlNpbmdsZUhUTUwiKV0odHJ1ZSx3aW5kb3cpOwoJCWdCcm93c2VyLnNlbGVjdGVkVGFiLnRleHRMYWJlbC5zdHlsZS50ZXh0RGVjb3JhdGlvbiA9ICJvdmVybGluZSI7IC8vIF7Qv9C+0LTRh9GR0YDQutC40LLQsNC90LjQtQoJfSBjYXRjaCB7YXJncyA9IFsn4pi5INCe0YjQuNCx0LrQsCDRhNGD0L3QutGG0LjQuCBTaW5nbGVIVE1MJywxZTRdfQoJZ2xvYi50b1N0YXR1cyguLi5hcmdzKTsKfSwKc2F2ZVNlbFRvVHh0ID0gYXN5bmMgKCkgPT4geyAvL9CyIC50eHQg0JLRgdGRINC40LvQuCDQktGL0LHRgNCw0L3QvdC+0LUKCXZhciB7bGVuZ3RofSA9IHNhdmVVUkwsIHNwbGljZSA9IGxlbmd0aCA+IDksIGwxMSA9IGxlbmd0aCA9PSAxMSwgbXNnTmFtZSA9IGlkICsgIjpTYXZlOkdldFNlbGVjdGlvbiI7IC8vRklYIEZGMTAzKwoJdmFyIHJlY2VpdmVyID0gbXNnID0+IHt2YXIgdHh0ID0gImRhdGE6dGV4dC9wbGFpbiwiKyBlbmNvZGVVUklDb21wb25lbnQoZ0Jyb3dzZXIuY3VycmVudFVSSS5zcGVjICsiXG5cbiIrIG1zZy5kYXRhKTsKCQl2YXIgYXJncyA9IFt0eHQsVGl0bGUoMCkgKycudHh0JyxudWxsLGZhbHNlLHRydWUsbnVsbCx3aW5kb3cuZG9jdW1lbnRdOwoJCXNwbGljZSAmJiBhcmdzLnNwbGljZSg1LDAsbnVsbCkgJiYgbDExICYmIGFyZ3Muc3BsaWNlKDEsMCxudWxsKTsKCQlzYXZlVVJMKC4uLmFyZ3MpOwoJCWdsb2IudG9TdGF0dXMoZ2xvYi5jcm9wKCLiiJog0YLQtdC60YHRgiDRgdC+0YXRgNCw0L3RkdC9OiAiKyBUaXRsZSgwKSw5NiwnJykpOwoJfQoJbWVzc2FnZU1hbmFnZXIuYWRkTWVzc2FnZUxpc3RlbmVyKG1zZ05hbWUscmVjZWl2ZXIpOwoJYWRkRGVzdHJ1Y3RvcigoKSA9PiBtZXNzYWdlTWFuYWdlci5yZW1vdmVNZXNzYWdlTGlzdGVuZXIobXNnTmFtZSxyZWNlaXZlcikpOwoJdmFyIHNmdW5jID0gZm0gPT4gewoJCXZhciByZXMsZmVkLHdpbiA9IHt9LGZlID0gZm0uZ2V0Rm9jdXNlZEVsZW1lbnRGb3JXaW5kb3coY29udGVudCx0cnVlLHdpbik7CgkJdmFyIHNlbCA9ICh3aW4gPSB3aW4udmFsdWUpLmdldFNlbGVjdGlvbigpOwoJCWlmIChzZWwuaXNDb2xsYXBzZWQpIHsKCQkJdmFyIGVkID0gZmUgJiYgZmUuZWRpdG9yOwoJCQlpZiAoZWQgJiYgZWQgaW5zdGFuY2VvZiBDaS5uc0lFZGl0b3IpCgkJCQlzZWwgPSBlZC5zZWxlY3Rpb24sIGZlZCA9IGZlOwoJCX0KCQlpZiAoc2VsLmlzQ29sbGFwc2VkKQoJCQlmZWQgJiYgZmVkLmJsdXIoKSxkb2NTaGVsbC5kb0NvbW1hbmQoImNtZF9zZWxlY3RBbGwiKSwKCQkJcmVzID0gd2luLmdldFNlbGVjdGlvbigpLnRvU3RyaW5nKCksZG9jU2hlbGwuZG9Db21tYW5kKCJjbWRfc2VsZWN0Tm9uZSIpLAoJCQlmZWQgJiYgZmVkLmZvY3VzKCk7CgkJcmVzID0gcmVzIHx8IHNlbC50b1N0cmluZygpOwoJCS9cUy8udGVzdChyZXMpICYmIHNlbmRBc3luY01lc3NhZ2UoInNhdmVTZWxUb1R4dCIscmVzKTsKCX0KCXZhciB1cmwgPSAiZGF0YTo7Y2hhcnNldD11dGYtOCwiKyBlbmNvZGVVUklDb21wb25lbnQoYCgke3NmdW5jfSlgLnJlcGxhY2UoInNhdmVTZWxUb1R4dCIsbXNnTmFtZSkpICsnKENjWyJAbW96aWxsYS5vcmcvZm9jdXMtbWFuYWdlcjsxIl0uZ2V0U2VydmljZShDaS5uc0lGb2N1c01hbmFnZXIpKTsnOwoJKHNhdmVTZWxUb1R4dCA9ICgpID0+IGdCcm93c2VyLnNlbGVjdGVkQnJvd3Nlci5tZXNzYWdlTWFuYWdlci5sb2FkRnJhbWVTY3JpcHQodXJsLGZhbHNlKSkoKTsKfSwKb3BlbkRpYWwgPSAoYXJncyA9IFtGZi5jICsib3B0aW9ucy9wcmVmc193aW4ueGh0bWwiLCJ1c2VyX2Nocm9tZV9wcmVmczp3aW5kb3ciLCJjZW50ZXJzY3JlZW4scmVzaXphYmxlLGRpYWxvZz1ubyJdKSA9PiB3aW5kb3cub3BlbkRpYWxvZyguLi5hcmdzKSwgLy/QuNC70LggYWJvdXQ6dXNlci1jaHJvbWUtZmlsZXMKdG9vbHRpcF94ID0gKHRyZyx0ZXh0ID0gIiIsIHR0dCA9ICIiKSA9PiB7CglpZiAoIXRyZy5pZC5lbmRzV2l0aCgieCIpKSB7IC8vYm94CgkJdHR0ID0gKHRyZy5oYXNBdHRyaWJ1dGUoInRvb2x0aXB0ZXh0IikpID8gdHJnLnR0dCA9IHRyZy50b29sdGlwVGV4dCA6IHRyZy50dHQ7CgkJaWYgKHR0dCAmJiB0dHQuaW5kZXhPZih0ZXh0KSA9PSAtMSkgdHR0ICs9ICJcblxuIjsKCQl0cmcucmVtb3ZlQXR0cmlidXRlKCJ0b29sdGlwdGV4dCIpOwoJfQoJcmV0dXJuICh0dHQuaW5kZXhPZih0ZXh0KSA9PSAtMSkgPyB0dHQgKyB0ZXh0IDogdHR0Owp9LApicmlnaHQgPSAodHJnLGZvcndhcmQsc3RlcCA9IDEsdmFsKSA9PiB7IC8vd2hlZWwKCWlmICghdmFsKSB2YXIgdmFsID0gZ2V0SW50UHJlZih0YWJyKSArIChmb3J3YXJkID8gc3RlcCA6IC1zdGVwKTsKCXZhbCA9IHZhbCA+IDEwMCA/IDEwMCA6IHZhbCA8IDE1ID8gMTUgOiB2YWw7CglnbG9iLnByZWYodGFicix2YWwpOyB0cmcudG9nZ2xlQXR0cmlidXRlKCJyc3QiKTsgZ2xvYi50b1N0YXR1cyhUWzJdICsgdmFsICsiJSIsMWUzKTsKfSwKYnJfdmFsID0gKCkgPT4gZ2xvYi5wcmVmKFt0YWJyLDEwMF0pICsiJSIsCnpvb20gPSAoZm9yd2FyZCx0b2dnbGUgPSBmYWxzZSwgY2hhbmdlID0gdHJ1ZSx0ZXh0ID0gJycpID0+IHsKCXRvZ2dsZSA/IFpvb21NYW5hZ2VyLnRvZ2dsZVpvb20oKSA6IGNoYW5nZSA/IGZvcndhcmQgPyBGdWxsWm9vbS5lbmxhcmdlKCkgOiBGdWxsWm9vbS5yZWR1Y2UoKSA6IDA7CglnbG9iLnRvU3RhdHVzKCLCsSDQnNCw0YHRiNGC0LDQsSAiKyBNYXRoLnJvdW5kKFpvb21NYW5hZ2VyLnpvb20qMTAwKSArYCUke2dsb2IucHJlZigiYnJvd3Nlci56b29tLmZ1bGwiKSA/ICIiIDogIiAo0YLQvtC70YzQutC+INGC0LXQutGB0YIpIn1gICsgdGV4dCwzZTMpOwp9LApFeHBlcnQgPSAobSA9IEJvb2xlYW4oRmYuRXhwKCkpLHAgPSBGZi5wICsnZXhwZXJ0JykgPT4gewoJZ2xvYi5wcmVmKHAsIW0pOyBnbG9iLnRvU3RhdHVzKE92ZXIuYnJfZXhwKCIiKSwzZTMpOwp9LApIZWxwID0gKGhlbHAgPSBGZi5jICsiaGVscC5odG1sIikgPT4geyAvL9C/0L7QvNC+0YnRjAoJKEZpbGVFeGlzdHMoaGVscCkpID8gc3dpdGNoVGFiKGhlbHApIDogc3dpdGNoVGFiKCd2aWN0b3ItZG9icm92Lm5hcm9kLnJ1L2hlbHAtRkYuaHRtbCcpOwp9LApGaWxlRXhpc3RzID0gKGZpbGUpID0+IHt0cnkgeyAvL9GE0LDQudC7fNC/0LDQv9C60LAg0YHRg9GJ0LXRgdGC0LLRg9C10YI/CglpZiAoIWZpbGUuc3RhcnRzV2l0aCgiY2hyb21lOi8vIikpCgkJcmV0dXJuIEZpbGVVdGlscy5GaWxlKFN0cmluZy5yYXdgJHtmaWxlfWApLmV4aXN0cygpCgllbHNlIHJldHVybiBDY1siQG1vemlsbGEub3JnL2Nocm9tZS9jaHJvbWUtcmVnaXN0cnk7MSJdLmdldFNlcnZpY2UoQ2kubnNJWFVMQ2hyb21lUmVnaXN0cnkpLmNvbnZlcnRDaHJvbWVVUkwoU2VydmljZXMuaW8ubmV3VVJJKGZpbGUpKS5RdWVyeUludGVyZmFjZShDaS5uc0lGaWxlVVJMKS5maWxlLmV4aXN0cygpOwoJfSBjYXRjaCB7fTsgcmV0dXJuIGZhbHNlOwp9LAp1c2VyanMgPSAoZSxteWpzID0gRmYuYyArImN1c3RvbV9zY3JpcHRzL1VzZXIuanMiKSA9PiB7CglEZWJ1ZygpICYmIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJrZXlfYnJvd3NlckNvbnNvbGUiKS5kb0NvbW1hbmQoKTsgLy/RhNC+0LrRg9GBINC90LAg0LrQvtC90YHQvtC70YwKCUZpbGVFeGlzdHMobXlqcykgPyBldmFsKEN1LnJlYWRVVEY4VVJJKFNlcnZpY2VzLmlvLm5ld1VSSShteWpzKSkpIDogdCA9IG15anMgKyIg4oCUINGB0LrRgNC40L/RgiDQvdC1INC90LDQudC00LXQvSI7Cgljb25zb2xlLmxvZygi4pyFXHQiKyBNYXRoLnJhbmRvbSgpLCIiKTsgLy/QstCw0Ygg0YHQutGA0LjQv9GCCn0sCnRyYW5zbGF0ZSA9IChick1NID0gZ0Jyb3dzZXIuc2VsZWN0ZWRCcm93c2VyLm1lc3NhZ2VNYW5hZ2VyKSA9PiB7IC8vINC/0LXRgNC10LLQvtC0INGB0LDQudGCIHwg0LLRi9C00LXQuy4g0YLQtdC60YHRggoJYnJNTS5hZGRNZXNzYWdlTGlzdGVuZXIoJ2dldFNlbGVjdCcsbGlzdGVuZXIgPSAobXNnKSA9PnsKCQlpZiAobXNnLmRhdGEpIC8vINCf0LXRgNC10LLQvtC0INCy0YvQtNC10LvQtdC90L3QvtCz0L4KCQkJc3dpdGNoVGFiKCJodHRwczovL3RyYW5zbGF0ZS5nb29nbGUuY29tLyN2aWV3PWhvbWUmb3A9dHJhbnNsYXRlJnNsPWF1dG8mdGw9cnUmdGV4dD0iKyBtc2cuZGF0YSx0cnVlKQoJCWVsc2UgLy8g0JPRg9Cz0Lsg0LjQu9C4INCf0LXRgNC10LLQvtC0INGB0LDQudGC0LAg0LIg0K/QvdC00LXQutGBCgkJCXN3aXRjaFRhYigiaHR0cHM6Ly90cmFuc2xhdGUueWFuZGV4LmNvbS90cmFuc2xhdGU/dXJsPSIrIGdVUkxCYXIudmFsdWUgKyImZGlyPSZ1aT1ydSZsYW5nPWF1dG8tcnUiLHRydWUpOwoJYnJNTS5yZW1vdmVNZXNzYWdlTGlzdGVuZXIoJ2dldFNlbGVjdCcsbGlzdGVuZXIsdHJ1ZSk7Cgl9KTsKCWJyTU0ubG9hZEZyYW1lU2NyaXB0KCdkYXRhOixzZW5kQXN5bmNNZXNzYWdlKCJnZXRTZWxlY3QiLGNvbnRlbnQuZG9jdW1lbnQuZ2V0U2VsZWN0aW9uKCkudG9TdHJpbmcoKSknLGZhbHNlKTsKfSwKb3BlblByb3h5V2luID0gKF93aW4gPSBTZXJ2aWNlcy53bS5nZXRNb3N0UmVjZW50V2luZG93KCJhVGFCOlByb3h5V2luIikpID0+IHsKCWlmIChfd2luKSBfd2luLmZvY3VzKCkKCWVsc2UgewoJCV93aW4gPSBvcGVuRGlhbChbImNocm9tZTovL2Jyb3dzZXIvY29udGVudC9wcmVmZXJlbmNlcy9kaWFsb2dzL2Nvbm5lY3Rpb24ueGh0bWwiLCJfYmxhbmsiLCJjaHJvbWUsZGlhbG9nPW5vLGNlbnRlcnNjcmVlbixyZXNpemFibGUiXSk7CgkJX3dpbi5hZGRFdmVudExpc3RlbmVyKCJET01Db250ZW50TG9hZGVkIiwoKSA9PiB7CgkJCV93aW4uZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNldEF0dHJpYnV0ZSgid2luZG93dHlwZSIsImFUYUI6UHJveHlXaW4iKTsKCQl9LHtvbmNlOiB0cnVlfSk7CgkJX3dpbi5vcGVuZXIgPSB3aW5kb3c7IF93aW4ub3BlbmVyLmdTdWJEaWFsb2cgPSB7X2RpYWxvZ3M6IFtdfTt9Cn0sCkZhdkl0ZW0gPSAoZmlyc3QgPSB0cnVlLGRlZl91cmwgPSAndWEucnUnKSA9PiB7IC8v0L/QtdGA0LLRi9C5fNC/0L7RgdC7LiB1cmwg0JzQtdC90Y4g0LfQsNC60LvQsNC00L7QugoJdmFyIHF1ZXJ5ID0ge30sIG9wdGlvbnMgPSB7fSwgZm9sZGVyID0gUGxhY2VzVXRpbHMuaGlzdG9yeS5leGVjdXRlUXVlcnkocXVlcnkudmFsdWUsIG9wdGlvbnMudmFsdWUpLnJvb3Q7CglQbGFjZXNVdGlscy5oaXN0b3J5LnF1ZXJ5U3RyaW5nVG9RdWVyeShgcGxhY2U6cGFyZW50PSR7UGxhY2VzVXRpbHMuYm9va21hcmtzLm1lbnVHdWlkfSZleGNsdWRlUXVlcmllcz0xYCxxdWVyeSxvcHRpb25zKTsKCWZvbGRlci5jb250YWluZXJPcGVuID0gdHJ1ZTsKCXZhciBtYXggPSBmb2xkZXIuY2hpbGRDb3VudCAtIDEsIHR5cGUgPSBDaS5uc0lOYXZIaXN0b3J5UmVzdWx0Tm9kZS5SRVNVTFRfVFlQRV9VUkksIHVybDsKCWlmIChmaXJzdCkgZm9yKHZhciBpbmQgPSAwOyBpbmQgPD0gbWF4OyBpbmQrKykgeyAvLyBmaXJzdAoJCXZhciBub2RlID0gZm9sZGVyLmdldENoaWxkKGluZCk7CgkJaWYgKG5vZGUudHlwZSA9PSB0eXBlKSB7dXJsID0gbm9kZS51cmk7IGJyZWFrO30KCX0gZWxzZQkJZm9yKHZhciBpbmQgPSBtYXg7IDAgPD0gaW5kOyBpbmQtLSkgeyAvLyBsYXN0CgkJdmFyIG5vZGUgPSBmb2xkZXIuZ2V0Q2hpbGQoaW5kKTsKCQlpZiAobm9kZS50eXBlID09IHR5cGUpIHt1cmwgPSBub2RlLnVyaTsgYnJlYWs7fQoJfQoJaWYgKCF1cmwpIHVybCA9IGRlZl91cmw7IHJldHVybiB1cmw7Cn0sCnRvRmF2ID0gKCkgPT4ge3dpdGggKFBsYWNlc1V0aWxzLmJvb2ttYXJrcyl7IC8v0LHQtdC3INC00LjQsNC70L7Qs9CwCgl2YXIgdXJsID0gZ0Jyb3dzZXIuc2VsZWN0ZWRCcm93c2VyLmN1cnJlbnRVUkkuc3BlYzsKCXNlYXJjaCh7dXJsfSkudGhlbihhc3luYyBhcnJheSA9PiB7CgkJaWYgKGFycmF5Lmxlbmd0aCkKCQkJdHJ5IHthd2FpdCByZW1vdmUoYXJyYXkpO30gY2F0Y2gge30KCQllbHNlCgkJCXRyeSB7YXdhaXQgaW5zZXJ0KHsKCQkJCXVybDogU2VydmljZXMuaW8ubmV3VVJJKHVybCksCgkJCQl0aXRsZTogKGdCcm93c2VyLmNvbnRlbnRUaXRsZSB8fCBnQnJvd3Nlci5zZWxlY3RlZFRhYi5sYWJlbCB8fCB1cmwpLAoJCQkJcGFyZW50R3VpZDogWygpID0+IHRvb2xiYXJHdWlkLCAoKSA9PiBtZW51R3VpZCwgKCkgPT4gdW5maWxlZEd1aWRdW1NlcnZpY2VzLnByZWZzLmdldEludFByZWYoImJvb2ttYXJrc3BhcmVudGd1aWQiLDApXSgpLAoJCQkJaW5kZXg6IERFRkFVTFRfSU5ERVgKCQkJfSk7fSBjYXRjaCB7fQoJfSk7Cn19CmlmIChGZi5vcyA9PSAibWFjb3N4IikKCU9iamVjdC5rZXlzKFRhZykuZm9yRWFjaCgoayk9PnsgLy9pINGB0YfRkdGC0YfQuNC6LCDQt9Cw0LzQtdC90LAg0LHRg9C60LIKCQlbJ+KXiScsJ8OYJ10uZm9yRWFjaCgoYyxpKT0+e1RhZ1trXSA9IFRhZ1trXS5yZXBsYWNlKG5ldyBSZWdFeHAoYywnZycpLAoJCVsn4qa/Jywn4peOJ11baV0pfSl9KQplbHNlIGlmIChnbG9iLnByZWYoW0ZmLnAgKyd3aW5idXR0b25zJyxmYWxzZV0pKQoJCWNzc19VU0VSKCcudGl0bGViYXItYnV0dG9uYm94IHtkaXNwbGF5OiBub25lICFpbXBvcnRhbnR9JykKCWVsc2UgY3NzX1VTRVIoRmYuYyArImN1c3RvbV9zdHlsZXMvd2luX2J1dHRvbnMtdml0di5jc3MiKTsKCn0pKCAvL2luaXQt0LrQvtC0CkZmID0ge3A6J2V4dGVuc2lvbnMudXNlcl9jaHJvbWVfZmlsZXMuJywgYzonY2hyb21lOi8vdXNlcl9jaHJvbWVfZmlsZXMvY29udGVudC8nLCBpOidwZXJtaXNzaW9ucy5kZWZhdWx0LmltYWdlJywKCW9zOiBBcHBDb25zdGFudHMucGxhdGZvcm0sIHZlcjogU2VydmljZXMuYXBwaW5mby52ZXJzaW9uLnJlcGxhY2UoLy0uKi8sJycpLAoJQ3RyKG0gPSAi4oyYIiwgdyA9ICJDdHJsKyIpe3JldHVybiB0aGlzLm9zID09ICJtYWNvc3giID8gbSA6IHd9LAoJRXhwKCl7cmV0dXJuIE51bWJlcihTZXJ2aWNlcy5wcmVmcy5nZXRCb29sUHJlZih0aGlzLnAgKydleHBlcnQnLGZhbHNlKSl9Cn0sCihuYW1lLG0gPSBGZi5FeHAoKSwgdCx6KSA9PiB7IC8v4oCmIHvQntCx0YnQuNC577iw0K3QutGB0L/QtdGA0YIgKG0gPSAxKVvvuLDigKZdfQoJdCA9IFRhZ1tuYW1lXTsgeiA9IHQubWF0Y2goLyhceykoW1xzXFNdKj8pKFx9KS9nbSk7CglpZiAoeikgei5mb3JFYWNoKChrLGgpID0+eyAvL9GC0LXQutGB0YIg0LfQsNCy0LjRgdC40YIg0L7RgiDRgNC10LbQuNC80LAKCQloID0gay5zcGxpdCgn77iwJyk7IGlmIChoICYmIGgubGVuZ3RoID4gbSkKCQkJdCA9IHQucmVwbGFjZShrLGhbbV0ucmVwbGFjZSgvXHt8XH0vZywnJykpO30pCglyZXR1cm4gdDt9IC8v0YDQsNC30LTQtdC70LjRgtC10LvRjCDQuCDQvdGD0LbQvdCw0Y8g0YfQsNGB0YLRjCDihpEKKTs= |
Dobrov > 27-09-2023 13:46:49 |
для совместимости с Firefox 78-117 изменил UCF так (может, что-то можно сделать лучше…) Выделить код Код:// фрагмент config.js для Firefox 78-117: this.observe = (window, topic, data, icw) => { try {icw = (window instanceof Ci.nsIDOMChromeWindow);} catch {icw = (window .isChromeWindow)} //Ff116+ if (!icw) return; var docElementInserted = e => { var win = e.target.defaultView; if (icw) user_chrome.initWindow(win); // Services в jsm-скриптах для Firefox 78-117 подключается так: if (typeof Services != "object") try{var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm")} catch{var {Services} = globalThis} // Services в js-скриптах для Firefox 78-117: if (typeof Services != "object") var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); |
Farby > 27-09-2023 15:35:47 |
Dobrov скрытый текст icw должна быть определена заранее Выделить код Код:var Services = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services; |
Dobrov > 27-09-2023 17:13:54 |
Farby - значит, эти две строки создают одинаковый объект Services? var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); |
Farby > 27-09-2023 17:47:21 |
Dobrov пишет
Да. Кажется такая конструкция должна работать... для config.js Выделить код Код:if ((window.isChromeWindow) ? false : (window instanceof Ci.nsIDOMChromeWindow) ? false : true) return; 27-09-2023 18:02:12 |
rubel > 28-09-2023 05:03:04 |
Dumby скрытый текст Выделить код Код:try {(() => { var id = "ucf-undo-tab", label = "Восстановить", tooltiptext = "ЛКМ: Восстановить вкладку\nПКМ: Восстановить окно", tooltiptextbtnmenu = "ЛКМ: Открыть меню\nПКМ: Показать весь журнал", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 16,12 C 16,12 3,27 3,26.81 L 24.2,48 H 45 C 46.7,48 48,46.7 48,45 V 17.3 L 40,9.3 Z'/><path style='fill:white;' d='M 27.68,3.93 C 26.7,3.93 25.66,3.992 24.58,4.138 19.23,5.17 13.74,8.472 10.22,12.78 3.018,5.815 7.525,10.29 3.021,5.815 L 3,26.81 H 24.18 L 17.03,19.7 C 20.44,14.7 30.87,6.752 38.32,19.08 40.69,25.69 40.58,36.52 35.69,44 40.97,38.26 45.35,30.55 44.98,21.33 44.59,14.08 39.37,3.992 27.68,3.93' /></g></svg>", imgmenu = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><circle cy='24' cx='24' style='fill:rgb(0, 120, 173);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,41.8 22.3,31.1 36.7,17.9 44,25.2 C 43.5,30.6 41,37.7 33,41.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,19 H 13 L 24,30 35,19' /></g></svg>"; CustomizableUI.createWidget({ id: id, type: "custom", label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(document) { var win = document.defaultView, toolbaritem = document.createXULElement("toolbaritem"); toolbaritem.id = id; toolbaritem.className = "chromeclass-toolbar-additional"; toolbaritem.setAttribute("label", label); toolbaritem.setAttribute("type", "custom"); var toolbarbutton_0 = document.createXULElement("toolbarbutton"); toolbarbutton_0.id = `${id}-button`; toolbarbutton_0.className = "toolbarbutton-1"; toolbarbutton_0.setAttribute("label", label); toolbarbutton_0.setAttribute("tooltiptext", tooltiptext); toolbarbutton_0.setAttribute("context", "false"); toolbarbutton_0.addEventListener("click", function(event) { if (event.button == 0) win.undoCloseTab(); else if (event.button == 2) { event.preventDefault(); event.stopPropagation(); win.undoCloseWindow(); } }); toolbaritem.append(toolbarbutton_0); var toolbarbutton_1 = document.createXULElement("toolbarbutton"); toolbarbutton_1.id = `${id}-button-menu`; toolbarbutton_1.className = "toolbarbutton-1"; toolbarbutton_1.setAttribute("type", "menu"); toolbarbutton_1.setAttribute("label", ""); toolbarbutton_1.setAttribute("tooltiptext", tooltiptextbtnmenu); toolbarbutton_1.setAttribute("context", "false"); toolbarbutton_1.addEventListener("click", function(event) { if (event.button == 2) { event.preventDefault(); event.stopPropagation(); win.PlacesCommandHook.showPlacesOrganizer("History"); } }); var menupopup_0 = document.createXULElement("menupopup"); menupopup_0.id = `${id}-popup`; menupopup_0.setAttribute("tooltip", "bhTooltip"); menupopup_0.setAttribute("popupsinherittooltip", true); menupopup_0.addEventListener("click", function(event) { event.stopPropagation(); }); menupopup_0.addEventListener("command", function(event) { event.stopPropagation(); }); var menu_0 = document.createXULElement("menu"); menu_0.setAttribute("disabled", true); menu_0.setAttribute("label", "Недавно закрытые вкладки"); var menupopup_1 = document.createXULElement("menupopup"); menupopup_1.addEventListener("popupshowing", function(event) { while (menupopup_1.hasChildNodes()) menupopup_1.firstChild.remove(); if (win == Services.appShell.hiddenDOMWindow || win.SessionStore.getClosedTabCount(win) == 0) { menu_0.setAttribute("disabled", true); return; } var tabsFragment = win.RecentlyClosedTabsAndWindowsMenuUtils.getTabsFragment(win, "menuitem"); menupopup_1.append(tabsFragment); menu_0.removeAttribute("disabled"); }); menu_0.append(menupopup_1); menupopup_0.append(menu_0); var menu_1 = document.createXULElement("menu"); menu_1.setAttribute("disabled", true); menu_1.setAttribute("label", "Недавно закрытые окна"); var menupopup_2 = document.createXULElement("menupopup"); menupopup_2.addEventListener("popupshowing", function(event) { while (menupopup_2.hasChildNodes()) menupopup_2.firstChild.remove(); if (win.SessionStore.getClosedWindowCount() == 0) { menu_1.setAttribute("disabled", true); return; } var windowsFragment = win.RecentlyClosedTabsAndWindowsMenuUtils.getWindowsFragment(win, "menuitem"); menupopup_2.append(windowsFragment); menu_1.removeAttribute("disabled"); }); menu_1.append(menupopup_2); menupopup_0.append(menu_1); menupopup_0.addEventListener("popupshowing", function(event) { if (win == Services.appShell.hiddenDOMWindow || win.SessionStore.getClosedTabCount(win) == 0) menu_0.setAttribute("disabled", true); else menu_0.removeAttribute("disabled"); if (win.SessionStore.getClosedWindowCount() == 0) menu_1.setAttribute("disabled", true); else menu_1.removeAttribute("disabled"); }); var menuitem_0 = document.createXULElement("menuitem"); menuitem_0.id = `${id}-all-history`; menuitem_0.setAttribute("label", "Показать весь журнал"); menuitem_0.addEventListener("command", function(event) { event.stopPropagation(); win.PlacesCommandHook.showPlacesOrganizer("History"); }); menupopup_0.append(menuitem_0); var menuitem_1 = document.createXULElement("menuitem"); menuitem_1.setAttribute("label", "Удалить недавнюю историю…"); menuitem_1.addEventListener("command", function(event) { event.stopPropagation(); win.Sanitizer.showUI(win); }); menupopup_0.append(menuitem_1); toolbarbutton_1.append(menupopup_0); toolbaritem.append(toolbarbutton_1); var btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(` #${id}-button { list-style-image: url("${img}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; margin-inline-end: 0 !important; } #${id}-button-menu { list-style-image: url("${imgmenu}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; margin-inline-start: 0px !important; } toolbarpaletteitem[place="palette"] #${id}-button-menu, #${id}-button-menu dropmarker { display: none !important; } toolbarpaletteitem[place="palette"] #${id} { -moz-box-orient: vertical !important; } #${id}-button-menu > .toolbarbutton-icon { min-width: 0 !important; max-width: none !important; width: auto !important; padding-left: 0 !important; padding-right: 0 !important; } `); try { win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} return toolbaritem; } }); })();} catch(e) {} |
kokoss > 28-09-2023 09:16:43 |
rubel |
rubel > 28-09-2023 09:42:03 |
kokoss |
Dobrov > 28-09-2023 15:32:00 |
rubel пишет
У тебя старая версия. В новом коде строки Закрытых вкладок сразу в выпадающее меню кнопки добавляются. Восстановить Закрытые вкладки/окна - модификация без dropmarker Выделить код Код:try {(() => { var id = "ucf-undo-tab", label = "Закрытые вкладки/окна", tooltiptextbtnmenu = "ЛКМ: Открыть меню\nПКМ: Восстановить вкладку\nСКМ: Показать весь журнал"; CustomizableUI.createWidget({ id: id, label: label, type: "custom", localized: false, onBuild(doc) { var win = doc.defaultView, trim = doc.createXULElement("toolbaritem"); trim.id = id; trim.className = "toolbaritem-combined-buttons ucf-toolbaritem-combined-buttons chromeclass-toolbar-additional"; trim.setAttribute("label", label); trim.setAttribute("type", "custom"); trim.style.setProperty("margin-inline","0"); var trbn_1 = doc.createXULElement("toolbarbutton"); trbn_1.id = `${id}-button-menu`; trbn_1.className = "toolbarbutton-1 ucf-toolbarbutton-combined-buttons-toolbarbutton"; trbn_1.setAttribute("type", "menu"); trbn_1.setAttribute("label", ""); trbn_1.setAttribute("image", "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 16,12 C 16,12 3,27 3,26.81 L 24.2,48 H 45 C 46.7,48 48,46.7 48,45 V 17.3 L 40,9.3 Z'/><path style='fill:white;' d='M 27.68,3.93 C 26.7,3.93 25.66,3.992 24.58,4.138 19.23,5.17 13.74,8.472 10.22,12.78 3.018,5.815 7.525,10.29 3.021,5.815 L 3,26.81 H 24.18 L 17.03,19.7 C 20.44,14.7 30.87,6.752 38.32,19.08 40.69,25.69 40.58,36.52 35.69,44 40.97,38.26 45.35,30.55 44.98,21.33 44.59,14.08 39.37,3.992 27.68,3.93' /></g></svg>"); trbn_1.setAttribute("tooltiptext", tooltiptextbtnmenu); trbn_1.setAttribute("context", ""); trbn_1.addEventListener("click", e => { if (e.button == 1) win.PlacesCommandHook.showPlacesOrganizer("History"); else if (e.button == 2) { e.preventDefault(); e.stopPropagation(); win.undoCloseTab(); } }); var mupp_0 = doc.createXULElement("menupopup"); mupp_0.id = `${id}-popup`; mupp_0.setAttribute("tooltip", "bhTooltip"); mupp_0.setAttribute("popupsinherittooltip", true); mupp_0.addEventListener("click", e => { e.stopPropagation(); }); mupp_0.addEventListener("command", e => { e.stopPropagation(); }); var muim_0 = doc.createXULElement("menuitem"); muim_0.id = `${id}-all-history`; muim_0.className = "ucf-menuitem"; muim_0.setAttribute("label", "Показать весь журнал"); muim_0.addEventListener("command", e => { e.stopPropagation(); win.PlacesCommandHook.showPlacesOrganizer("History"); }); mupp_0.append(muim_0); var muim_1 = doc.createXULElement("menuitem"); muim_1.id = `${id}-sanitize`; muim_1.className = "ucf-menuitem"; muim_1.setAttribute("label", "Удалить недавнюю историю…"); muim_1.addEventListener("command", e => { e.stopPropagation(); win.Sanitizer.showUI(win); }); mupp_0.append(muim_1); var muim_2 = doc.createXULElement("menuitem"); muim_2.id = `${id}-session`; muim_2.className = "ucf-menuitem"; muim_2.setAttribute("hidden", "true"); muim_2.setAttribute("label", "Восстановить последнюю сессию"); muim_2.addEventListener("command", e => { e.stopPropagation(); win.SessionStore.restoreLastSession(); }); mupp_0.append(muim_2); var menu_0 = doc.createXULElement("menu"); menu_0.id = `${id}-menu-closed-win`; menu_0.setAttribute("hidden", "true"); menu_0.setAttribute("label", "Недавно закрытые окна"); var mupp_1 = doc.createXULElement("menupopup"); var muim_3 = doc.createXULElement("menuitem"); muim_3.id = `${id}-item-closed-win`; muim_3.className = "ucf-menuitem"; muim_3.setAttribute("hidden", "true"); muim_3.setAttribute("label", "Забыть закрытые окна"); muim_3.addEventListener("command", e => { e.stopPropagation(); var sessionStore = win.SessionStore; var count = sessionStore.getClosedWindowCount(); while(count--) sessionStore.forgetClosedWindow(0); }); mupp_1.append(muim_3); var musr_0 = doc.createXULElement("menuseparator"); musr_0.id = `${id}-sep-closed-win`; musr_0.className = "ucf-menuseparator"; musr_0.setAttribute("hidden", "true"); mupp_1.append(musr_0); mupp_1.addEventListener("popupshowing", e => { e.stopPropagation(); for (let item of mupp_1.querySelectorAll(":scope > :is(menuitem:not(.ucf-menuitem), menuseparator:not(.ucf-menuseparator))")) item.remove(); if (win.SessionStore.getClosedWindowCount() == 0) { muim_3.setAttribute("hidden", "true"); musr_0.setAttribute("hidden", "true"); return; } if ("RecentlyClosedTabsAndWindowsMenuUtils" in win) { muim_3.removeAttribute("hidden"); musr_0.removeAttribute("hidden"); var windowsFragment = win.RecentlyClosedTabsAndWindowsMenuUtils.getWindowsFragment(win, "menuitem"); mupp_1.append(windowsFragment); menu_0.removeAttribute("hidden"); } }); menu_0.append(mupp_1); mupp_0.append(menu_0); var musr_1 = doc.createXULElement("menuseparator"); musr_1.className = "ucf-menuseparator"; musr_1.setAttribute("hidden", "true"); mupp_0.append(musr_1); var muim_4 = doc.createXULElement("menuitem"); muim_4.id = `${id}-item-closed-tabs`; muim_4.className = "ucf-menuitem"; muim_4.setAttribute("hidden", "true"); muim_4.setAttribute("label", "Забыть закрытые вкладки"); muim_4.addEventListener("command", e => { e.stopPropagation(); var sessionStore = win.SessionStore, count; try{count = sessionStore.getClosedTabCountForWindow(win);} catch(e){count = sessionStore.getClosedTabCount(win)} while(count--) sessionStore.forgetClosedTab(win, 0); }); mupp_0.append(muim_4); var musr_2 = doc.createXULElement("menuseparator"); musr_2.id = `${id}-sep-closed-tabs`; musr_2.className = "ucf-menuseparator"; musr_2.setAttribute("hidden", "true"); mupp_0.append(musr_2); mupp_0.addEventListener("popupshowing", e => { var sessionStore = win.SessionStore; if (sessionStore.getClosedWindowCount() == 0) menu_0.setAttribute("hidden", "true"); else menu_0.removeAttribute("hidden"); if (!sessionStore.canRestoreLastSession) muim_2.setAttribute("hidden", "true"); else muim_2.removeAttribute("hidden"); for (let item of mupp_0.querySelectorAll(":scope > :is(menuitem:not(.ucf-menuitem), menuseparator:not(.ucf-menuseparator))")) item.remove(); try{var sSgCTC = sessionStore.getClosedTabCountForWindow(win);} catch(e){var sSgCTC = sessionStore.getClosedTabCount(win)} if (win == Services.appShell.hiddenDOMWindow || sSgCTC == 0) { musr_1.setAttribute("hidden", "true"); muim_4.setAttribute("hidden", "true"); musr_2.setAttribute("hidden", "true"); return; } if ("RecentlyClosedTabsAndWindowsMenuUtils" in win) { musr_1.removeAttribute("hidden"); muim_4.removeAttribute("hidden"); musr_2.removeAttribute("hidden"); var tabsFragment = win.RecentlyClosedTabsAndWindowsMenuUtils.getTabsFragment(win, "menuitem"); mupp_0.append(tabsFragment); } }); trbn_1.append(mupp_0); trim.append(trbn_1); return trim; } }); })()} catch(e){} Напомню, что в Шапке есть Ссылка на обновляемые скрипты |
rubel > 28-09-2023 17:06:55 |
Dobrov
Ваша кнопка вообще не работает, не появляется на панели и в настройках панели инструментов тоже её нет. |
Dumby > 28-09-2023 21:02:05 |
rubel пишет
Это потому, что четвёртая строка заканчивается запятой. |
Dobrov > 29-09-2023 01:33:18 |
Dumby Ошибку исправил! кнопка создаётся через onBuild(doc) { …… Восстановить Закрытые вкладки/окна (вариант без dropmarker) Возможно, это упростит код и сократит объём: не нужны будут return trbn_1 и trim = doc.createXULElement("toolbaritem")… |
Northtech > 29-09-2023 07:34:16 |
Подскажите пожалуйста, что поправить в UCF (см. ссылку) для fx 118, чтобы вернуть интервалы (special_widget), остался только растягивающийся интервал, а пробел и разделитель пропали. |
rubel > 29-09-2023 07:40:43 |
В 115 сломалась иконка кнопки "Загрузки" и "Переключить прокси" . скрытый текст Выделить код Код:try { (() => { var id = "ucf-toggle-proxy", label = "Переключить прокси", tooltiptext = "Переключить прокси", tooltiptextbtnmenu = "ЛКМ: Открыть меню\nПКМ: Открыть настройки прокси", toggleproxy = 1, // 0, 1, 2, 4 , 5 Первый режим toggleproxy2 = 2, // 0, 1, 2, 4 , 5 Второй режим doreload = true, // Перезагрузить страницу img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 240'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(146, 69, 101);'/><path style='opacity:0.25;fill:black;' d='M 16.8,17.6 23.1,23.9 8,26 6.4,32.2 11.4,37.2 3.7,44.8 6.9,48 45,48 C 46.7,48 48,46.7 48,45 V 20 L 31.4,3.4'/><path style='fill:white;' d='M 17.4,3 C 16.7,3 16.2,3.82 16.2,4.91 V 15.9 C 16.2,17 16.7,17.8 17.4,17.8 H 30.6 C 31.3,17.8 31.8,17 31.8,15.9 V 4.91 C 31.8,3.82 31.3,3 30.6,3 H 17.4 M 22.4,20.5 V 23.7 H 6.41 V 32.2 H 9.35 V 28.2 H 22.4 V 32.4 H 25.5 V 28.2 H 38.5 V 32.4 H 41.5 V 23.7 H 25.5 V 20.5 H 22.4 M 4.23,35.1 C 3.55,35.1 3,35.9 3,37.1 V 43 C 3,44.1 3.55,45 4.23,45 H 12.1 C 12.8,45 13.3,44.1 13.3,43 V 37.1 C 13.3,35.9 12.8,35.1 12.1,35.1 H 4.23 M 19.9,35.1 C 19.2,35.1 18.7,35.9 18.7,37.1 V 43 C 18.7,44.1 19.2,45 19.9,45 H 27.8 C 28.5,45 29,44.1 29,43 V 37.1 C 29,35.9 28.5,35.1 27.8,35.1 H 19.9 M 35.9,35.1 C 35.2,35.1 34.7,35.9 34.7,37.1 V 43 C 34.7,44.1 35.2,45 35.9,45 H 43.7 C 44.4,45 45,44.1 45,43 V 37.1 C 45,35.9 44.4,35.1 43.7,35.1 H 35.9' /><rect x='0' y='48' width='48' height='48' rx='3' ry='3' style='fill:rgb(209, 8, 3);'/><path style='opacity:0.25;fill:black;' d='M 16.8,65.6 23.1,71.9 8,74 6.4,80.2 11.4,85.2 3.7,92.8 6.9,96 45,96 C 46.7,96 48,94.7 48,93 V 68 L 31.4,51.4'/><path style='fill:white;' d='M 17.4,51 C 16.7,51 16.2,51.8 16.2,52.9 V 63.9 C 16.2,65 16.7,65.8 17.4,65.8 H 30.6 C 31.3,65.8 31.8,65 31.8,63.9 V 52.9 C 31.8,51.8 31.3,51 30.6,51 H 17.4 M 22.4,68.5 V 71.7 H 6.41 V 80.2 H 9.35 V 76.2 H 22.4 V 80.4 H 25.5 V 76.2 H 38.5 V 80.4 H 41.5 V 71.7 H 25.5 V 68.5 H 22.4 M 4.23,83.1 C 3.55,83.1 3,83.9 3,85.1 V 91 C 3,92.1 3.55,93 4.23,93 H 12.1 C 12.8,93 13.3,92.1 13.3,91 V 85.1 C 13.3,83.9 12.8,83.1 12.1,83.1 H 4.23 M 19.9,83.1 C 19.2,83.1 18.8,83.9 18.8,85.1 V 91 C 18.8,92.1 19.2,93 19.9,93 H 27.8 C 28.5,93 29,92.1 29,91 V 85.1 C 29,83.9 28.5,83.1 27.8,83.1 H 19.9 M 35.9,83.1 C 35.2,83.1 34.7,83.9 34.7,85.1 V 91 C 34.7,92.1 35.2,93 35.9,93 H 43.7 C 44.4,93 45,92.1 45,91 V 85.1 C 45,83.9 44.4,83.1 43.7,83.1 H 35.9' /><rect x='0' y='96' width='48' height='48' rx='3' ry='3' style='fill:rgb(243, 135, 37);'/><path style='opacity:0.25;fill:black;' d='M 16.8,114 23.1,120 8,122 6.4,128 11.4,133 3.7,141 6.9,144 H 45 C 46.7,144 48,142.7 48,141 V 116 L 31.4,99.4'/><path style='fill:white;' d='M 17.4,99 C 16.7,99 16.2,99.8 16.2,101 V 112 C 16.2,113 16.7,114 17.4,114 H 30.6 C 31.3,114 31.8,113 31.8,112 V 101 C 31.8,99.8 31.3,99 30.6,99 H 17.4 M 22.4,117 V 120 H 6.41 V 128 H 9.35 V 124 H 22.4 V 128 H 25.5 V 124 H 38.5 V 128 H 41.5 V 120 H 25.5 V 117 H 22.4 M 4.23,131 C 3.55,131 3,132 3,133 V 139 C 3,140 3.55,141 4.23,141 H 12.1 C 12.8,141 13.3,140 13.3,139 V 133 C 13.3,132 12.8,131 12.1,131 H 4.23 M 19.9,131 C 19.2,131 18.8,132 18.8,133 V 139 C 18.8,140 19.2,141 19.9,141 H 27.8 C 28.5,141 29,140 29,139 V 133 C 29,132 28.5,131 27.8,131 H 19.9 M 35.9,131 C 35.2,131 34.7,132 34.7,133 V 139 C 34.7,140 35.2,141 35.9,141 H 43.7 C 44.4,141 45,140 45,139 V 133 C 45,132 44.4,131 43.7,131 H 35.9' /><rect x='0' y='144' width='48' height='48' rx='3' ry='3' style='fill:rgb(21, 161, 99);'/><path style='opacity:0.25;fill:black;' d='M 16.8,162 23.1,168 8,170 6.4,176 11.4,181 3.7,189 6.9,192 H 45 C 46.7,192 48,190.7 48,189 V 164 L 31.4,147'/><path style='fill:white;' d='M 17.4,147 C 16.7,147 16.2,148 16.2,149 V 160 C 16.2,161 16.7,162 17.4,162 H 30.6 C 31.3,162 31.8,161 31.8,160 V 149 C 31.8,148 31.3,147 30.6,147 H 17.4 M 22.4,165 V 168 H 6.41 V 176 H 9.35 V 172 H 22.4 V 176 H 25.5 V 172 H 38.5 V 176 H 41.5 V 168 H 25.5 V 165 H 22.4 M 4.23,179 C 3.55,179 3,180 3,181 V 187 C 3,188 3.55,189 4.23,189 H 12.1 C 12.8,189 13.3,188 13.3,187 V 181 C 13.3,180 12.8,179 12.1,179 H 4.23 M 19.9,179 C 19.2,179 18.8,180 18.8,181 V 187 C 18.8,188 19.2,189 19.9,189 H 27.8 C 28.5,189 29,188 29,187 V 181 C 29,180 28.5,179 27.8,179 H 19.9 M 35.9,179 C 35.2,179 34.7,180 34.7,181 V 187 C 34.7,188 35.2,189 35.9,189 H 43.7 C 44.4,189 45,188 45,187 V 181 C 45,180 44.4,179 43.7,179 H 35.9' /><rect x='0' y='192' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 16.8,210 23.1,216 8,218 6.4,224 11.4,229 3.7,237 6.9,240 H 45 C 46.7,240 48,238.7 48,237 L 48,212 31.4,195'/><path style='fill:white;' d='M 17.4,195 C 16.7,195 16.2,196 16.2,197 V 208 C 16.2,209 16.7,210 17.4,210 H 30.6 C 31.3,210 31.8,209 31.8,208 V 197 C 31.8,196 31.3,195 30.6,195 H 17.4 M 22.4,213 V 216 H 6.41 V 224 H 9.4 V 220 H 22.4 V 224 H 25.5 V 220 H 38.5 V 224 H 41.5 V 216 H 25.5 V 213 H 22.4 M 4.23,227 C 3.55,227 3,228 3,229 V 235 C 3,236 3.55,237 4.23,237 H 12.1 C 12.8,237 13.3,236 13.3,235 V 229 C 13.3,228 12.8,227 12.1,227 H 4.23 M 19.9,227 C 19.2,227 18.7,228 18.7,229 V 235 C 18.7,236 19.2,237 19.9,237 H 27.8 C 28.5,237 29,236 29,235 V 229 C 29,228 28.5,227 27.8,227 H 19.9 M 35.9,227 C 35.2,227 34.7,228 34.7,229 V 235 C 34.7,236 35.2,237 35.9,237 H 43.7 C 44.4,237 45,236 45,235 V 229 C 45,228 44.4,227 43.7,227 H 35.9' /></g></svg>", imgmenu = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 240'><g><circle cy='24' cx='24' style='fill:rgb(146, 69, 101);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,41.8 22.3,31.1 36.7,17.9 44,25.2 C 43.5,30.6 41,37.7 33,41.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,19 H 13 L 24,30 35,19' /><circle cy='72' cx='24' style='fill:rgb(209, 8, 3);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,89.8 22.3,79.1 36.7,65.9 44,73.2 C 43.5,78.6 41,85.7 33,89.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,67 H 13 L 24,78 35,67' /><circle cy='120' cx='24' style='fill:rgb(243, 135, 37);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.8,138 22,127 36.7,114 44,121 C 43.5,127 40.9,134 32.8,138 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 34.9,115 H 13.1 L 24,126 34.9,115' /><circle cy='168' cx='24' style='fill:rgb(21, 161, 99);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.9,186 22,175 36.7,162 44,169 C 43.5,175 40.9,182 32.9,186 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,163 H 13 L 24,174 35,163' /><circle cy='216' cx='24' style='fill:rgb(0, 120, 173);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.8,234 22,223 36.7,210 44,217 C 43.5,223 40.9,230 32.8,234 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,211 H 13 L 24,222 35,211' /></g></svg>"; var id2 = "ucf-open-downloads", label2 = "Загрузки", tooltiptext2 = "ЛКМ: Показать загрузки\nСКМ: Открыть папку загрузок\nПКМ: Открыть последнюю папку загрузок", img2 = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 23.4,33 30,39.6 H 18 L 8.7,30 3.9,44.1 7.8,48 H 45 C 46.7,48 48,46.7 48,45 V 22.5 L 28.8,3.3 Z'/><path style='fill:white;' d='M 20.27,3 C 19,3 19.25,3.798 19.25,3.798 V 17.94 20.23 H 13.75 C 12.13,20.23 13.61,21.58 13.61,21.58 L 23.36,32.85 V 32.85 C 23.36,32.85 24.17,33.75 25.01,32.95 26.16,31.84 34.47,21.3 34.47,21.3 34.47,21.3 35.93,19.89 33.98,19.89 H 28.91 V 17.83 3.672 C 28.91,3.672 28.93,3 28.03,3 Z M 3,29.93 V 42.22 C 3,43.75 4.303,45 5.918,45 H 42.08 C 43.71,45 45,43.75 45,42.22 V 29.93 H 39.16 V 39.43 H 8.837 V 29.93 Z' /></g></svg>"; var tbarbtns = { get network_proxy_type() { delete this.network_proxy_type; try { return this.network_proxy_type = Services.prefs.getIntPref("network.proxy.type"); } catch(e) { } return this.network_proxy_type = null; }, get btnstyle() { delete this.btnstyle; return this.btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(` #${id}-button { list-style-image: url("${img}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; margin-inline-end: 0 !important; } #${id}-button-menu { list-style-image: url("${imgmenu}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; margin-inline-start: 0px !important; } #${id}[activated="1"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(16px, 16px, 32px, 0px) !important; } #${id}[activated="2"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(32px, 16px, 48px, 0px) !important; } #${id}[activated="4"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(48px, 16px, 64px, 0px) !important; } #${id}[activated="5"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(64px, 16px, 80px, 0px) !important; } toolbarpaletteitem[place="palette"] #${id}-button-menu, #${id}-button-menu dropmarker { display: none !important; } toolbarpaletteitem[place="palette"] #${id} { -moz-box-orient: vertical !important; } #${id}-button-menu > .toolbarbutton-icon { min-width: 0 !important; max-width: none !important; width: auto !important; padding-left: 0 !important; padding-right: 0 !important; } `); }, toggleTheProxy: function() { Services.prefs.setIntPref("network.proxy.type", (Services.prefs.getIntPref("network.proxy.type") == toggleproxy2) ? toggleproxy : toggleproxy2); }, setProxyMenuItem: function(event) { var proxyState = Services.prefs.getIntPref("network.proxy.type"), popup = event.currentTarget; for (var menuitem in popup.childNodes) { var childNode = popup.childNodes[menuitem]; if (+childNode.getAttribute("value") == proxyState) { childNode.setAttribute("checked", "true"); break; } } }, setProxyValue: function(event) { Services.prefs.setIntPref("network.proxy.type", +event.target.getAttribute("value")); }, checkBrowserReload: function(win) { if (doreload) win.BrowserReloadSkipCache(); }, openProxyWin: function(win) { var _win = Services.wm.getMostRecentWindow("aTaB:ProxyWin"); if (_win) _win.focus(); else { _win = win.openDialog("chrome://browser/content/preferences/dialogs/connection.xhtml", "_blank", "chrome,dialog=no,centerscreen,resizable"); var DOMLoad = () => { _win.document.documentElement.setAttribute("type", "prefwindow"); _win.document.documentElement.setAttribute("windowtype", "aTaB:ProxyWin"); }; _win.addEventListener("DOMContentLoaded", DOMLoad, { once: true }); _win.opener = win; _win.opener.gSubDialog = { _dialogs: [] }; } }, }; CustomizableUI.createWidget({ id: id, type: "custom", label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(document) { var win = document.defaultView, toolbaritem = document.createXULElement("toolbaritem"); toolbaritem.id = id; toolbaritem.className = "chromeclass-toolbar-additional"; toolbaritem.setAttribute("label", label); toolbaritem.setAttribute("type", "custom"); var toolbarbutton_0 = document.createXULElement("toolbarbutton"); toolbarbutton_0.id = `${id}-button`; toolbarbutton_0.className = "toolbarbutton-1"; toolbarbutton_0.setAttribute("label", label); toolbarbutton_0.setAttribute("tooltiptext", tooltiptext); toolbarbutton_0.setAttribute("context", "false"); toolbaritem.append(toolbarbutton_0); var toolbarbutton_1 = document.createXULElement("toolbarbutton"); toolbarbutton_1.id = `${id}-button-menu`; toolbarbutton_1.className = "toolbarbutton-1"; toolbarbutton_1.setAttribute("type", "menu"); toolbarbutton_1.setAttribute("label", ""); toolbarbutton_1.setAttribute("tooltiptext", tooltiptextbtnmenu); toolbarbutton_1.setAttribute("context", "false"); toolbarbutton_1.addEventListener("click", function(event) { if (event.button == 2) { event.preventDefault(); event.stopPropagation(); tbarbtns.openProxyWin(win); } }); var menupopup_0 = document.createXULElement("menupopup"); menupopup_0.id = `${id}-popup`; menupopup_0.addEventListener("click", function(event) { event.stopPropagation(); }); var proxy = tbarbtns.network_proxy_type; if (proxy !== null) { toolbaritem.setAttribute("activated", tbarbtns.network_proxy_type); toolbarbutton_0.addEventListener("command", function(event) { tbarbtns.toggleTheProxy(); tbarbtns.checkBrowserReload(win); }); menupopup_0.addEventListener("command", function(event) { event.stopPropagation(); tbarbtns.setProxyValue(event); tbarbtns.checkBrowserReload(win); }); menupopup_0.addEventListener("popupshowing", function(event) { tbarbtns.setProxyMenuItem(event); }); } var menuitem_0 = document.createXULElement("menuitem"); menuitem_0.setAttribute("label", "Прямое подключение, без прокси"); menuitem_0.setAttribute("type", "radio"); menuitem_0.setAttribute("value", "0"); menupopup_0.append(menuitem_0); var menuitem_1 = document.createXULElement("menuitem"); menuitem_1.setAttribute("label", "Ручная настройка прокси"); menuitem_1.setAttribute("type", "radio"); menuitem_1.setAttribute("value", "1"); menupopup_0.append(menuitem_1); var menuitem_2 = document.createXULElement("menuitem"); menuitem_2.setAttribute("label", "Автоматическая настройка прокси"); menuitem_2.setAttribute("type", "radio"); menuitem_2.setAttribute("value", "2"); menupopup_0.append(menuitem_2); var menuitem_3 = document.createXULElement("menuitem"); menuitem_3.setAttribute("label", "Автоопределение настроек прокси"); menuitem_3.setAttribute("type", "radio"); menuitem_3.setAttribute("value", "4"); menupopup_0.append(menuitem_3); var menuitem_4 = document.createXULElement("menuitem"); menuitem_4.setAttribute("label", "Использовать системные настройки прокси"); menuitem_4.setAttribute("type", "radio"); menuitem_4.setAttribute("value", "5"); menupopup_0.append(menuitem_4); var menuseparator_0 = document.createXULElement("menuseparator"); menupopup_0.append(menuseparator_0); var menuitem_5 = document.createXULElement("menuitem"); menuitem_5.setAttribute("label", "Открыть настройки прокси"); menuitem_5.addEventListener("command", function(event) { event.stopPropagation(); tbarbtns.openProxyWin(win); }); menupopup_0.append(menuitem_5); toolbarbutton_1.append(menupopup_0); toolbaritem.append(toolbarbutton_1); try { win.windowUtils.loadSheetUsingURIString(tbarbtns.btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} return toolbaritem; } }); Services.prefs.addObserver("network.proxy.type", { observe: function(aSubject, aTopic, aData) { if (aData == "network.proxy.type") { let network_proxy_type = tbarbtns.network_proxy_type = Services.prefs.getIntPref(aData), getW = CustomizableUI.getWidget(id); if (getW.instances.length) for(let {node} of getW.instances) try { node.setAttribute("activated", network_proxy_type); } catch(e) {} else for (let win of CustomizableUI.windows) try { getW.forWindow(win).node.setAttribute("activated", network_proxy_type); } catch(e) {} } } }); CustomizableUI.createWidget({ id: id2, type: "custom", label: label2, tooltiptext: tooltiptext2, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(document) { var win = document.defaultView, toolbarbutton = document.createXULElement("toolbarbutton"); toolbarbutton.id = id2; toolbarbutton.className = "toolbarbutton-1 chromeclass-toolbar-additional"; toolbarbutton.setAttribute("label", label2); toolbarbutton.setAttribute("context", "false"); toolbarbutton.setAttribute("tooltiptext", tooltiptext2); toolbarbutton.addEventListener("click", function(event) { if (event.button == 0) win.DownloadsPanel.showDownloadsHistory(); else if (event.button == 1) { try { Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile).launch(); } catch(e) { Services.dirsvc.get("DfltDwnld", Ci.nsIFile).launch(); } } else if (event.button == 2) { event.preventDefault(); event.stopPropagation(); try { Services.prefs.getComplexValue("browser.download.lastDir", Ci.nsIFile).launch(); } catch(e) { Services.dirsvc.get("DfltDwnld", Ci.nsIFile).launch(); } } }); toolbarbutton.style.setProperty("list-style-image", `url("${img2}")`, "important"); return toolbarbutton; } }); })(); } catch(e) {} Как бы это поправить, уважаемые гуру. |
xrun1 > 29-09-2023 08:39:11 |
Northtech пишет
Это вопрос к автору мода Dobrov. В родном всё работает. |
Dobrov > 29-09-2023 09:58:59 |
Northtech пишет
Если что-то не пашет, просто проверьте по ссылке в шапке, может это уже исправлено! |
kokoss > 29-09-2023 21:25:07 |
rubel |
rubel > 30-09-2023 04:27:54 |
kokoss |
fuchsfan > 30-09-2023 06:44:24 |
Northtech пишет
Встречалось такое на этом форуме
Еще существует отдельный скрипт, не из состава ucf, создает как раз два пропавших элемента https://forum.ru-board.com/topic.cgi?fo … tart=80#14 , по сути это скрипт от Dumby, в который Farby встроил css-код. Активировать его можно как в ucf, так и без. |
Dumby > 30-09-2023 07:50:41 |
Dobrov пишет
скрытый текст Выделить код Код:/* id: id, label: label, type: "custom", localized: false, onBuild(doc) { var win = doc.defaultView, trim = doc.createXULElement("toolbaritem"); trim.id = id; trim.className = "toolbaritem-combined-buttons ucf-toolbaritem-combined-buttons chromeclass-toolbar-additional"; trim.setAttribute("label", label); trim.setAttribute("type", "custom"); trim.style.setProperty("margin-inline","0"); var trbn_1 = doc.createXULElement("toolbarbutton"); trbn_1.id = `${id}-button-menu`; trbn_1.className = "toolbarbutton-1 ucf-toolbarbutton-combined-buttons-toolbarbutton"; trbn_1.setAttribute("type", "menu"); trbn_1.setAttribute("label", ""); */ id, label, localized: false, onCreated(trbn_1) { var win = trbn_1.ownerGlobal, doc = win.document; trbn_1.setAttribute("type", "menu"); ....... /* trim.append(trbn_1); return trim; */ rubel пишет
скрытый текст Выделить код Код:/* img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 240'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(146, 69, 101);'/><path style='opacity:0.25;fill:black;' d='M 16.8,17.6 23.1,23.9 8,26 6.4,32.2 11.4,37.2 3.7,44.8 6.9,48 45,48 C 46.7,48 48,46.7 48,45 V 20 L 31.4,3.4'/><path style='fill:white;' d='M 17.4,3 C 16.7,3 16.2,3.82 16.2,4.91 V 15.9 C 16.2,17 16.7,17.8 17.4,17.8 H 30.6 C 31.3,17.8 31.8,17 31.8,15.9 V 4.91 C 31.8,3.82 31.3,3 30.6,3 H 17.4 M 22.4,20.5 V 23.7 H 6.41 V 32.2 H 9.35 V 28.2 H 22.4 V 32.4 H 25.5 V 28.2 H 38.5 V 32.4 H 41.5 V 23.7 H 25.5 V 20.5 H 22.4 M 4.23,35.1 C 3.55,35.1 3,35.9 3,37.1 V 43 C 3,44.1 3.55,45 4.23,45 H 12.1 C 12.8,45 13.3,44.1 13.3,43 V 37.1 C 13.3,35.9 12.8,35.1 12.1,35.1 H 4.23 M 19.9,35.1 C 19.2,35.1 18.7,35.9 18.7,37.1 V 43 C 18.7,44.1 19.2,45 19.9,45 H 27.8 C 28.5,45 29,44.1 29,43 V 37.1 C 29,35.9 28.5,35.1 27.8,35.1 H 19.9 M 35.9,35.1 C 35.2,35.1 34.7,35.9 34.7,37.1 V 43 C 34.7,44.1 35.2,45 35.9,45 H 43.7 C 44.4,45 45,44.1 45,43 V 37.1 C 45,35.9 44.4,35.1 43.7,35.1 H 35.9' /><rect x='0' y='48' width='48' height='48' rx='3' ry='3' style='fill:rgb(209, 8, 3);'/><path style='opacity:0.25;fill:black;' d='M 16.8,65.6 23.1,71.9 8,74 6.4,80.2 11.4,85.2 3.7,92.8 6.9,96 45,96 C 46.7,96 48,94.7 48,93 V 68 L 31.4,51.4'/><path style='fill:white;' d='M 17.4,51 C 16.7,51 16.2,51.8 16.2,52.9 V 63.9 C 16.2,65 16.7,65.8 17.4,65.8 H 30.6 C 31.3,65.8 31.8,65 31.8,63.9 V 52.9 C 31.8,51.8 31.3,51 30.6,51 H 17.4 M 22.4,68.5 V 71.7 H 6.41 V 80.2 H 9.35 V 76.2 H 22.4 V 80.4 H 25.5 V 76.2 H 38.5 V 80.4 H 41.5 V 71.7 H 25.5 V 68.5 H 22.4 M 4.23,83.1 C 3.55,83.1 3,83.9 3,85.1 V 91 C 3,92.1 3.55,93 4.23,93 H 12.1 C 12.8,93 13.3,92.1 13.3,91 V 85.1 C 13.3,83.9 12.8,83.1 12.1,83.1 H 4.23 M 19.9,83.1 C 19.2,83.1 18.8,83.9 18.8,85.1 V 91 C 18.8,92.1 19.2,93 19.9,93 H 27.8 C 28.5,93 29,92.1 29,91 V 85.1 C 29,83.9 28.5,83.1 27.8,83.1 H 19.9 M 35.9,83.1 C 35.2,83.1 34.7,83.9 34.7,85.1 V 91 C 34.7,92.1 35.2,93 35.9,93 H 43.7 C 44.4,93 45,92.1 45,91 V 85.1 C 45,83.9 44.4,83.1 43.7,83.1 H 35.9' /><rect x='0' y='96' width='48' height='48' rx='3' ry='3' style='fill:rgb(243, 135, 37);'/><path style='opacity:0.25;fill:black;' d='M 16.8,114 23.1,120 8,122 6.4,128 11.4,133 3.7,141 6.9,144 H 45 C 46.7,144 48,142.7 48,141 V 116 L 31.4,99.4'/><path style='fill:white;' d='M 17.4,99 C 16.7,99 16.2,99.8 16.2,101 V 112 C 16.2,113 16.7,114 17.4,114 H 30.6 C 31.3,114 31.8,113 31.8,112 V 101 C 31.8,99.8 31.3,99 30.6,99 H 17.4 M 22.4,117 V 120 H 6.41 V 128 H 9.35 V 124 H 22.4 V 128 H 25.5 V 124 H 38.5 V 128 H 41.5 V 120 H 25.5 V 117 H 22.4 M 4.23,131 C 3.55,131 3,132 3,133 V 139 C 3,140 3.55,141 4.23,141 H 12.1 C 12.8,141 13.3,140 13.3,139 V 133 C 13.3,132 12.8,131 12.1,131 H 4.23 M 19.9,131 C 19.2,131 18.8,132 18.8,133 V 139 C 18.8,140 19.2,141 19.9,141 H 27.8 C 28.5,141 29,140 29,139 V 133 C 29,132 28.5,131 27.8,131 H 19.9 M 35.9,131 C 35.2,131 34.7,132 34.7,133 V 139 C 34.7,140 35.2,141 35.9,141 H 43.7 C 44.4,141 45,140 45,139 V 133 C 45,132 44.4,131 43.7,131 H 35.9' /><rect x='0' y='144' width='48' height='48' rx='3' ry='3' style='fill:rgb(21, 161, 99);'/><path style='opacity:0.25;fill:black;' d='M 16.8,162 23.1,168 8,170 6.4,176 11.4,181 3.7,189 6.9,192 H 45 C 46.7,192 48,190.7 48,189 V 164 L 31.4,147'/><path style='fill:white;' d='M 17.4,147 C 16.7,147 16.2,148 16.2,149 V 160 C 16.2,161 16.7,162 17.4,162 H 30.6 C 31.3,162 31.8,161 31.8,160 V 149 C 31.8,148 31.3,147 30.6,147 H 17.4 M 22.4,165 V 168 H 6.41 V 176 H 9.35 V 172 H 22.4 V 176 H 25.5 V 172 H 38.5 V 176 H 41.5 V 168 H 25.5 V 165 H 22.4 M 4.23,179 C 3.55,179 3,180 3,181 V 187 C 3,188 3.55,189 4.23,189 H 12.1 C 12.8,189 13.3,188 13.3,187 V 181 C 13.3,180 12.8,179 12.1,179 H 4.23 M 19.9,179 C 19.2,179 18.8,180 18.8,181 V 187 C 18.8,188 19.2,189 19.9,189 H 27.8 C 28.5,189 29,188 29,187 V 181 C 29,180 28.5,179 27.8,179 H 19.9 M 35.9,179 C 35.2,179 34.7,180 34.7,181 V 187 C 34.7,188 35.2,189 35.9,189 H 43.7 C 44.4,189 45,188 45,187 V 181 C 45,180 44.4,179 43.7,179 H 35.9' /><rect x='0' y='192' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 16.8,210 23.1,216 8,218 6.4,224 11.4,229 3.7,237 6.9,240 H 45 C 46.7,240 48,238.7 48,237 L 48,212 31.4,195'/><path style='fill:white;' d='M 17.4,195 C 16.7,195 16.2,196 16.2,197 V 208 C 16.2,209 16.7,210 17.4,210 H 30.6 C 31.3,210 31.8,209 31.8,208 V 197 C 31.8,196 31.3,195 30.6,195 H 17.4 M 22.4,213 V 216 H 6.41 V 224 H 9.4 V 220 H 22.4 V 224 H 25.5 V 220 H 38.5 V 224 H 41.5 V 216 H 25.5 V 213 H 22.4 M 4.23,227 C 3.55,227 3,228 3,229 V 235 C 3,236 3.55,237 4.23,237 H 12.1 C 12.8,237 13.3,236 13.3,235 V 229 C 13.3,228 12.8,227 12.1,227 H 4.23 M 19.9,227 C 19.2,227 18.7,228 18.7,229 V 235 C 18.7,236 19.2,237 19.9,237 H 27.8 C 28.5,237 29,236 29,235 V 229 C 29,228 28.5,227 27.8,227 H 19.9 M 35.9,227 C 35.2,227 34.7,228 34.7,229 V 235 C 34.7,236 35.2,237 35.9,237 H 43.7 C 44.4,237 45,236 45,235 V 229 C 45,228 44.4,227 43.7,227 H 35.9' /></g></svg>", imgmenu = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 240'><g><circle cy='24' cx='24' style='fill:rgb(146, 69, 101);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,41.8 22.3,31.1 36.7,17.9 44,25.2 C 43.5,30.6 41,37.7 33,41.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,19 H 13 L 24,30 35,19' /><circle cy='72' cx='24' style='fill:rgb(209, 8, 3);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,89.8 22.3,79.1 36.7,65.9 44,73.2 C 43.5,78.6 41,85.7 33,89.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,67 H 13 L 24,78 35,67' /><circle cy='120' cx='24' style='fill:rgb(243, 135, 37);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.8,138 22,127 36.7,114 44,121 C 43.5,127 40.9,134 32.8,138 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 34.9,115 H 13.1 L 24,126 34.9,115' /><circle cy='168' cx='24' style='fill:rgb(21, 161, 99);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.9,186 22,175 36.7,162 44,169 C 43.5,175 40.9,182 32.9,186 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,163 H 13 L 24,174 35,163' /><circle cy='216' cx='24' style='fill:rgb(0, 120, 173);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.8,234 22,223 36.7,210 44,217 C 43.5,223 40.9,230 32.8,234 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,211 H 13 L 24,222 35,211' /></g></svg>"; */ img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 48'><view id='1' viewBox='0 48 48 48'/><view id='2' viewBox='0 96 48 48'/><view id='4' viewBox='0 144 48 48'/><view id='5' viewBox='0 192 48 48'/><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(146, 69, 101);'/><path style='opacity:0.25;fill:black;' d='M 16.8,17.6 23.1,23.9 8,26 6.4,32.2 11.4,37.2 3.7,44.8 6.9,48 45,48 C 46.7,48 48,46.7 48,45 V 20 L 31.4,3.4'/><path style='fill:white;' d='M 17.4,3 C 16.7,3 16.2,3.82 16.2,4.91 V 15.9 C 16.2,17 16.7,17.8 17.4,17.8 H 30.6 C 31.3,17.8 31.8,17 31.8,15.9 V 4.91 C 31.8,3.82 31.3,3 30.6,3 H 17.4 M 22.4,20.5 V 23.7 H 6.41 V 32.2 H 9.35 V 28.2 H 22.4 V 32.4 H 25.5 V 28.2 H 38.5 V 32.4 H 41.5 V 23.7 H 25.5 V 20.5 H 22.4 M 4.23,35.1 C 3.55,35.1 3,35.9 3,37.1 V 43 C 3,44.1 3.55,45 4.23,45 H 12.1 C 12.8,45 13.3,44.1 13.3,43 V 37.1 C 13.3,35.9 12.8,35.1 12.1,35.1 H 4.23 M 19.9,35.1 C 19.2,35.1 18.7,35.9 18.7,37.1 V 43 C 18.7,44.1 19.2,45 19.9,45 H 27.8 C 28.5,45 29,44.1 29,43 V 37.1 C 29,35.9 28.5,35.1 27.8,35.1 H 19.9 M 35.9,35.1 C 35.2,35.1 34.7,35.9 34.7,37.1 V 43 C 34.7,44.1 35.2,45 35.9,45 H 43.7 C 44.4,45 45,44.1 45,43 V 37.1 C 45,35.9 44.4,35.1 43.7,35.1 H 35.9' /><rect x='0' y='48' width='48' height='48' rx='3' ry='3' style='fill:rgb(209, 8, 3);'/><path style='opacity:0.25;fill:black;' d='M 16.8,65.6 23.1,71.9 8,74 6.4,80.2 11.4,85.2 3.7,92.8 6.9,96 45,96 C 46.7,96 48,94.7 48,93 V 68 L 31.4,51.4'/><path style='fill:white;' d='M 17.4,51 C 16.7,51 16.2,51.8 16.2,52.9 V 63.9 C 16.2,65 16.7,65.8 17.4,65.8 H 30.6 C 31.3,65.8 31.8,65 31.8,63.9 V 52.9 C 31.8,51.8 31.3,51 30.6,51 H 17.4 M 22.4,68.5 V 71.7 H 6.41 V 80.2 H 9.35 V 76.2 H 22.4 V 80.4 H 25.5 V 76.2 H 38.5 V 80.4 H 41.5 V 71.7 H 25.5 V 68.5 H 22.4 M 4.23,83.1 C 3.55,83.1 3,83.9 3,85.1 V 91 C 3,92.1 3.55,93 4.23,93 H 12.1 C 12.8,93 13.3,92.1 13.3,91 V 85.1 C 13.3,83.9 12.8,83.1 12.1,83.1 H 4.23 M 19.9,83.1 C 19.2,83.1 18.8,83.9 18.8,85.1 V 91 C 18.8,92.1 19.2,93 19.9,93 H 27.8 C 28.5,93 29,92.1 29,91 V 85.1 C 29,83.9 28.5,83.1 27.8,83.1 H 19.9 M 35.9,83.1 C 35.2,83.1 34.7,83.9 34.7,85.1 V 91 C 34.7,92.1 35.2,93 35.9,93 H 43.7 C 44.4,93 45,92.1 45,91 V 85.1 C 45,83.9 44.4,83.1 43.7,83.1 H 35.9' /><rect x='0' y='96' width='48' height='48' rx='3' ry='3' style='fill:rgb(243, 135, 37);'/><path style='opacity:0.25;fill:black;' d='M 16.8,114 23.1,120 8,122 6.4,128 11.4,133 3.7,141 6.9,144 H 45 C 46.7,144 48,142.7 48,141 V 116 L 31.4,99.4'/><path style='fill:white;' d='M 17.4,99 C 16.7,99 16.2,99.8 16.2,101 V 112 C 16.2,113 16.7,114 17.4,114 H 30.6 C 31.3,114 31.8,113 31.8,112 V 101 C 31.8,99.8 31.3,99 30.6,99 H 17.4 M 22.4,117 V 120 H 6.41 V 128 H 9.35 V 124 H 22.4 V 128 H 25.5 V 124 H 38.5 V 128 H 41.5 V 120 H 25.5 V 117 H 22.4 M 4.23,131 C 3.55,131 3,132 3,133 V 139 C 3,140 3.55,141 4.23,141 H 12.1 C 12.8,141 13.3,140 13.3,139 V 133 C 13.3,132 12.8,131 12.1,131 H 4.23 M 19.9,131 C 19.2,131 18.8,132 18.8,133 V 139 C 18.8,140 19.2,141 19.9,141 H 27.8 C 28.5,141 29,140 29,139 V 133 C 29,132 28.5,131 27.8,131 H 19.9 M 35.9,131 C 35.2,131 34.7,132 34.7,133 V 139 C 34.7,140 35.2,141 35.9,141 H 43.7 C 44.4,141 45,140 45,139 V 133 C 45,132 44.4,131 43.7,131 H 35.9' /><rect x='0' y='144' width='48' height='48' rx='3' ry='3' style='fill:rgb(21, 161, 99);'/><path style='opacity:0.25;fill:black;' d='M 16.8,162 23.1,168 8,170 6.4,176 11.4,181 3.7,189 6.9,192 H 45 C 46.7,192 48,190.7 48,189 V 164 L 31.4,147'/><path style='fill:white;' d='M 17.4,147 C 16.7,147 16.2,148 16.2,149 V 160 C 16.2,161 16.7,162 17.4,162 H 30.6 C 31.3,162 31.8,161 31.8,160 V 149 C 31.8,148 31.3,147 30.6,147 H 17.4 M 22.4,165 V 168 H 6.41 V 176 H 9.35 V 172 H 22.4 V 176 H 25.5 V 172 H 38.5 V 176 H 41.5 V 168 H 25.5 V 165 H 22.4 M 4.23,179 C 3.55,179 3,180 3,181 V 187 C 3,188 3.55,189 4.23,189 H 12.1 C 12.8,189 13.3,188 13.3,187 V 181 C 13.3,180 12.8,179 12.1,179 H 4.23 M 19.9,179 C 19.2,179 18.8,180 18.8,181 V 187 C 18.8,188 19.2,189 19.9,189 H 27.8 C 28.5,189 29,188 29,187 V 181 C 29,180 28.5,179 27.8,179 H 19.9 M 35.9,179 C 35.2,179 34.7,180 34.7,181 V 187 C 34.7,188 35.2,189 35.9,189 H 43.7 C 44.4,189 45,188 45,187 V 181 C 45,180 44.4,179 43.7,179 H 35.9' /><rect x='0' y='192' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 16.8,210 23.1,216 8,218 6.4,224 11.4,229 3.7,237 6.9,240 H 45 C 46.7,240 48,238.7 48,237 L 48,212 31.4,195'/><path style='fill:white;' d='M 17.4,195 C 16.7,195 16.2,196 16.2,197 V 208 C 16.2,209 16.7,210 17.4,210 H 30.6 C 31.3,210 31.8,209 31.8,208 V 197 C 31.8,196 31.3,195 30.6,195 H 17.4 M 22.4,213 V 216 H 6.41 V 224 H 9.4 V 220 H 22.4 V 224 H 25.5 V 220 H 38.5 V 224 H 41.5 V 216 H 25.5 V 213 H 22.4 M 4.23,227 C 3.55,227 3,228 3,229 V 235 C 3,236 3.55,237 4.23,237 H 12.1 C 12.8,237 13.3,236 13.3,235 V 229 C 13.3,228 12.8,227 12.1,227 H 4.23 M 19.9,227 C 19.2,227 18.7,228 18.7,229 V 235 C 18.7,236 19.2,237 19.9,237 H 27.8 C 28.5,237 29,236 29,235 V 229 C 29,228 28.5,227 27.8,227 H 19.9 M 35.9,227 C 35.2,227 34.7,228 34.7,229 V 235 C 34.7,236 35.2,237 35.9,237 H 43.7 C 44.4,237 45,236 45,235 V 229 C 45,228 44.4,227 43.7,227 H 35.9' /></g></svg>", imgmenu = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 48'><view id='1' viewBox='0 48 48 48'/><view id='2' viewBox='0 96 48 48'/><view id='4' viewBox='0 144 48 48'/><view id='5' viewBox='0 192 48 48'/><g><circle cy='24' cx='24' style='fill:rgb(146, 69, 101);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,41.8 22.3,31.1 36.7,17.9 44,25.2 C 43.5,30.6 41,37.7 33,41.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,19 H 13 L 24,30 35,19' /><circle cy='72' cx='24' style='fill:rgb(209, 8, 3);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,89.8 22.3,79.1 36.7,65.9 44,73.2 C 43.5,78.6 41,85.7 33,89.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,67 H 13 L 24,78 35,67' /><circle cy='120' cx='24' style='fill:rgb(243, 135, 37);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.8,138 22,127 36.7,114 44,121 C 43.5,127 40.9,134 32.8,138 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 34.9,115 H 13.1 L 24,126 34.9,115' /><circle cy='168' cx='24' style='fill:rgb(21, 161, 99);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.9,186 22,175 36.7,162 44,169 C 43.5,175 40.9,182 32.9,186 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,163 H 13 L 24,174 35,163' /><circle cy='216' cx='24' style='fill:rgb(0, 120, 173);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.8,234 22,223 36.7,210 44,217 C 43.5,223 40.9,230 32.8,234 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,211 H 13 L 24,222 35,211' /></g></svg>"; ....... /* #${id}-button { list-style-image: url("${img}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; margin-inline-end: 0 !important; } #${id}-button-menu { list-style-image: url("${imgmenu}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; margin-inline-start: 0px !important; } #${id}[activated="1"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(16px, 16px, 32px, 0px) !important; } #${id}[activated="2"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(32px, 16px, 48px, 0px) !important; } #${id}[activated="4"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(48px, 16px, 64px, 0px) !important; } #${id}[activated="5"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(64px, 16px, 80px, 0px) !important; } */ #${id}-button { list-style-image: url("${img}") !important; margin-inline-end: 0 !important; } #${id}[activated="1"] > #${id}-button { list-style-image: url("${img}#1") !important; } #${id}[activated="2"] > #${id}-button { list-style-image: url("${img}#2") !important; } #${id}[activated="4"] > #${id}-button { list-style-image: url("${img}#4") !important; } #${id}[activated="5"] > #${id}-button { list-style-image: url("${img}#5") !important; } #${id}-button-menu { list-style-image: url("${imgmenu}") !important; margin-inline-start: 0px !important; } #${id}[activated="1"] > #${id}-button-menu { list-style-image: url("${imgmenu}#1") !important; } #${id}[activated="2"] > #${id}-button-menu { list-style-image: url("${imgmenu}#2") !important; } #${id}[activated="4"] > #${id}-button-menu { list-style-image: url("${imgmenu}#4") !important; } #${id}[activated="5"] > #${id}-button-menu { list-style-image: url("${imgmenu}#5") !important; } ....... /* width: auto !important; */ |
rubel > 30-09-2023 16:50:04 |
Dumby |
Dumby > 30-09-2023 17:47:30 |
rubel пишет
Значит с img и imgmenu понятно. С кодом стилей — то же самое. Строка width: auto !important; (там в конце) — это третья часть. |
b0ttle > 30-09-2023 18:24:55 |
Dumby Выделить код Код:data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 48'><view id='1' viewBox='0 48 48 48'/><view id='2' viewBox='0 96 48 48'/><view id='4' viewBox='0 144 48 48'/><view id='5' viewBox='0 192 48 48'/><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(146, 69, 101);'/><path style='opacity:0.25;fill:black;' d='M 16.8,17.6 23.1,23.9 8,26 6.4,32.2 11.4,37.2 3.7,44.8 6.9,48 45,48 C 46.7,48 48,46.7 48,45 V 20 L 31.4,3.4'/><path style='fill:white;' d='M 17.4,3 C 16.7,3 16.2,3.82 16.2,4.91 V 15.9 C 16.2,17 16.7,17.8 17.4,17.8 H 30.6 C 31.3,17.8 31.8,17 31.8,15.9 V 4.91 C 31.8,3.82 31.3,3 30.6,3 H 17.4 M 22.4,20.5 V 23.7 H 6.41 V 32.2 H 9.35 V 28.2 H 22.4 V 32.4 H 25.5 V 28.2 H 38.5 V 32.4 H 41.5 V 23.7 H 25.5 V 20.5 H 22.4 M 4.23,35.1 C 3.55,35.1 3,35.9 3,37.1 V 43 C 3,44.1 3.55,45 4.23,45 H 12.1 C 12.8,45 13.3,44.1 13.3,43 V 37.1 C 13.3,35.9 12.8,35.1 12.1,35.1 H 4.23 M 19.9,35.1 C 19.2,35.1 18.7,35.9 18.7,37.1 V 43 C 18.7,44.1 19.2,45 19.9,45 H 27.8 C 28.5,45 29,44.1 29,43 V 37.1 C 29,35.9 28.5,35.1 27.8,35.1 H 19.9 M 35.9,35.1 C 35.2,35.1 34.7,35.9 34.7,37.1 V 43 C 34.7,44.1 35.2,45 35.9,45 H 43.7 C 44.4,45 45,44.1 45,43 V 37.1 C 45,35.9 44.4,35.1 43.7,35.1 H 35.9' /><rect x='0' y='48' width='48' height='48' rx='3' ry='3' style='fill:rgb(209, 8, 3);'/><path style='opacity:0.25;fill:black;' d='M 16.8,65.6 23.1,71.9 8,74 6.4,80.2 11.4,85.2 3.7,92.8 6.9,96 45,96 C 46.7,96 48,94.7 48,93 V 68 L 31.4,51.4'/><path style='fill:white;' d='M 17.4,51 C 16.7,51 16.2,51.8 16.2,52.9 V 63.9 C 16.2,65 16.7,65.8 17.4,65.8 H 30.6 C 31.3,65.8 31.8,65 31.8,63.9 V 52.9 C 31.8,51.8 31.3,51 30.6,51 H 17.4 M 22.4,68.5 V 71.7 H 6.41 V 80.2 H 9.35 V 76.2 H 22.4 V 80.4 H 25.5 V 76.2 H 38.5 V 80.4 H 41.5 V 71.7 H 25.5 V 68.5 H 22.4 M 4.23,83.1 C 3.55,83.1 3,83.9 3,85.1 V 91 C 3,92.1 3.55,93 4.23,93 H 12.1 C 12.8,93 13.3,92.1 13.3,91 V 85.1 C 13.3,83.9 12.8,83.1 12.1,83.1 H 4.23 M 19.9,83.1 C 19.2,83.1 18.8,83.9 18.8,85.1 V 91 C 18.8,92.1 19.2,93 19.9,93 H 27.8 C 28.5,93 29,92.1 29,91 V 85.1 C 29,83.9 28.5,83.1 27.8,83.1 H 19.9 M 35.9,83.1 C 35.2,83.1 34.7,83.9 34.7,85.1 V 91 C 34.7,92.1 35.2,93 35.9,93 H 43.7 C 44.4,93 45,92.1 45,91 V 85.1 C 45,83.9 44.4,83.1 43.7,83.1 H 35.9' /><rect x='0' y='96' width='48' height='48' rx='3' ry='3' style='fill:rgb(243, 135, 37);'/><path style='opacity:0.25;fill:black;' d='M 16.8,114 23.1,120 8,122 6.4,128 11.4,133 3.7,141 6.9,144 H 45 C 46.7,144 48,142.7 48,141 V 116 L 31.4,99.4'/><path style='fill:white;' d='M 17.4,99 C 16.7,99 16.2,99.8 16.2,101 V 112 C 16.2,113 16.7,114 17.4,114 H 30.6 C 31.3,114 31.8,113 31.8,112 V 101 C 31.8,99.8 31.3,99 30.6,99 H 17.4 M 22.4,117 V 120 H 6.41 V 128 H 9.35 V 124 H 22.4 V 128 H 25.5 V 124 H 38.5 V 128 H 41.5 V 120 H 25.5 V 117 H 22.4 M 4.23,131 C 3.55,131 3,132 3,133 V 139 C 3,140 3.55,141 4.23,141 H 12.1 C 12.8,141 13.3,140 13.3,139 V 133 C 13.3,132 12.8,131 12.1,131 H 4.23 M 19.9,131 C 19.2,131 18.8,132 18.8,133 V 139 C 18.8,140 19.2,141 19.9,141 H 27.8 C 28.5,141 29,140 29,139 V 133 C 29,132 28.5,131 27.8,131 H 19.9 M 35.9,131 C 35.2,131 34.7,132 34.7,133 V 139 C 34.7,140 35.2,141 35.9,141 H 43.7 C 44.4,141 45,140 45,139 V 133 C 45,132 44.4,131 43.7,131 H 35.9' /><rect x='0' y='144' width='48' height='48' rx='3' ry='3' style='fill:rgb(21, 161, 99);'/><path style='opacity:0.25;fill:black;' d='M 16.8,162 23.1,168 8,170 6.4,176 11.4,181 3.7,189 6.9,192 H 45 C 46.7,192 48,190.7 48,189 V 164 L 31.4,147'/><path style='fill:white;' d='M 17.4,147 C 16.7,147 16.2,148 16.2,149 V 160 C 16.2,161 16.7,162 17.4,162 H 30.6 C 31.3,162 31.8,161 31.8,160 V 149 C 31.8,148 31.3,147 30.6,147 H 17.4 M 22.4,165 V 168 H 6.41 V 176 H 9.35 V 172 H 22.4 V 176 H 25.5 V 172 H 38.5 V 176 H 41.5 V 168 H 25.5 V 165 H 22.4 M 4.23,179 C 3.55,179 3,180 3,181 V 187 C 3,188 3.55,189 4.23,189 H 12.1 C 12.8,189 13.3,188 13.3,187 V 181 C 13.3,180 12.8,179 12.1,179 H 4.23 M 19.9,179 C 19.2,179 18.8,180 18.8,181 V 187 C 18.8,188 19.2,189 19.9,189 H 27.8 C 28.5,189 29,188 29,187 V 181 C 29,180 28.5,179 27.8,179 H 19.9 M 35.9,179 C 35.2,179 34.7,180 34.7,181 V 187 C 34.7,188 35.2,189 35.9,189 H 43.7 C 44.4,189 45,188 45,187 V 181 C 45,180 44.4,179 43.7,179 H 35.9' /><rect x='0' y='192' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 16.8,210 23.1,216 8,218 6.4,224 11.4,229 3.7,237 6.9,240 H 45 C 46.7,240 48,238.7 48,237 L 48,212 31.4,195'/><path style='fill:white;' d='M 17.4,195 C 16.7,195 16.2,196 16.2,197 V 208 C 16.2,209 16.7,210 17.4,210 H 30.6 C 31.3,210 31.8,209 31.8,208 V 197 C 31.8,196 31.3,195 30.6,195 H 17.4 M 22.4,213 V 216 H 6.41 V 224 H 9.4 V 220 H 22.4 V 224 H 25.5 V 220 H 38.5 V 224 H 41.5 V 216 H 25.5 V 213 H 22.4 M 4.23,227 C 3.55,227 3,228 3,229 V 235 C 3,236 3.55,237 4.23,237 H 12.1 C 12.8,237 13.3,236 13.3,235 V 229 C 13.3,228 12.8,227 12.1,227 H 4.23 M 19.9,227 C 19.2,227 18.7,228 18.7,229 V 235 C 18.7,236 19.2,237 19.9,237 H 27.8 C 28.5,237 29,236 29,235 V 229 C 29,228 28.5,227 27.8,227 H 19.9 M 35.9,227 C 35.2,227 34.7,228 34.7,229 V 235 C 34.7,236 35.2,237 35.9,237 H 43.7 C 44.4,237 45,236 45,235 V 229 C 45,228 44.4,227 43.7,227 H 35.9' /></g></svg> Можно еще поменять полный путь, чтобы он брал путь с папки chrome? Полный путь не совсем удобно. А так, кнопка рабочая. Можно и по другому запускать прокси. Просто так одним кликом) И на видном месте. Как бы не обязательно. Upd: Класс. Спасибо. |
rubel > 30-09-2023 18:40:47 |
Dumby |
Dumby > 30-09-2023 21:09:03 |
b0ttle пишет
Не нужно тут такое же делать, Если просто эта svg'шка нравится, тогда берём первый кусок, скрытый текст Выделить код Код:data:image/svg+xml,<svg style='fill: red;' xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3'/><path style='opacity:0.25;fill:black;' d='M 16.8,17.6 23.1,23.9 8,26 6.4,32.2 11.4,37.2 3.7,44.8 6.9,48 45,48 C 46.7,48 48,46.7 48,45 V 20 L 31.4,3.4'/><path style='fill:white;' d='M 17.4,3 C 16.7,3 16.2,3.82 16.2,4.91 V 15.9 C 16.2,17 16.7,17.8 17.4,17.8 H 30.6 C 31.3,17.8 31.8,17 31.8,15.9 V 4.91 C 31.8,3.82 31.3,3 30.6,3 H 17.4 M 22.4,20.5 V 23.7 H 6.41 V 32.2 H 9.35 V 28.2 H 22.4 V 32.4 H 25.5 V 28.2 H 38.5 V 32.4 H 41.5 V 23.7 H 25.5 V 20.5 H 22.4 M 4.23,35.1 C 3.55,35.1 3,35.9 3,37.1 V 43 C 3,44.1 3.55,45 4.23,45 H 12.1 C 12.8,45 13.3,44.1 13.3,43 V 37.1 C 13.3,35.9 12.8,35.1 12.1,35.1 H 4.23 M 19.9,35.1 C 19.2,35.1 18.7,35.9 18.7,37.1 V 43 C 18.7,44.1 19.2,45 19.9,45 H 27.8 C 28.5,45 29,44.1 29,43 V 37.1 C 29,35.9 28.5,35.1 27.8,35.1 H 19.9 M 35.9,35.1 C 35.2,35.1 34.7,35.9 34.7,37.1 V 43 C 34.7,44.1 35.2,45 35.9,45 H 43.7 C 44.4,45 45,44.1 45,43 V 37.1 C 45,35.9 44.4,35.1 43.7,35.1 H 35.9' /></g></svg>
Ну сколько можно одно и то же, неужели не откладывается. скрытый текст Выделить код Код:/* var path = ".......\\opera-proxy.windows-386.exe"; */ var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("opera-proxy.windows-386.exe"); var {path} = file; rubel Вот ещё вариант правки скрытый текст Выделить код Код:/* doreload = true, // Перезагрузить страницу img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 240'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(146, 69, 101);'/><path style='opacity:0.25;fill:black;' d='M 16.8,17.6 23.1,23.9 8,26 6.4,32.2 11.4,37.2 3.7,44.8 6.9,48 45,48 C 46.7,48 48,46.7 48,45 V 20 L 31.4,3.4'/><path style='fill:white;' d='M 17.4,3 C 16.7,3 16.2,3.82 16.2,4.91 V 15.9 C 16.2,17 16.7,17.8 17.4,17.8 H 30.6 C 31.3,17.8 31.8,17 31.8,15.9 V 4.91 C 31.8,3.82 31.3,3 30.6,3 H 17.4 M 22.4,20.5 V 23.7 H 6.41 V 32.2 H 9.35 V 28.2 H 22.4 V 32.4 H 25.5 V 28.2 H 38.5 V 32.4 H 41.5 V 23.7 H 25.5 V 20.5 H 22.4 M 4.23,35.1 C 3.55,35.1 3,35.9 3,37.1 V 43 C 3,44.1 3.55,45 4.23,45 H 12.1 C 12.8,45 13.3,44.1 13.3,43 V 37.1 C 13.3,35.9 12.8,35.1 12.1,35.1 H 4.23 M 19.9,35.1 C 19.2,35.1 18.7,35.9 18.7,37.1 V 43 C 18.7,44.1 19.2,45 19.9,45 H 27.8 C 28.5,45 29,44.1 29,43 V 37.1 C 29,35.9 28.5,35.1 27.8,35.1 H 19.9 M 35.9,35.1 C 35.2,35.1 34.7,35.9 34.7,37.1 V 43 C 34.7,44.1 35.2,45 35.9,45 H 43.7 C 44.4,45 45,44.1 45,43 V 37.1 C 45,35.9 44.4,35.1 43.7,35.1 H 35.9' /><rect x='0' y='48' width='48' height='48' rx='3' ry='3' style='fill:rgb(209, 8, 3);'/><path style='opacity:0.25;fill:black;' d='M 16.8,65.6 23.1,71.9 8,74 6.4,80.2 11.4,85.2 3.7,92.8 6.9,96 45,96 C 46.7,96 48,94.7 48,93 V 68 L 31.4,51.4'/><path style='fill:white;' d='M 17.4,51 C 16.7,51 16.2,51.8 16.2,52.9 V 63.9 C 16.2,65 16.7,65.8 17.4,65.8 H 30.6 C 31.3,65.8 31.8,65 31.8,63.9 V 52.9 C 31.8,51.8 31.3,51 30.6,51 H 17.4 M 22.4,68.5 V 71.7 H 6.41 V 80.2 H 9.35 V 76.2 H 22.4 V 80.4 H 25.5 V 76.2 H 38.5 V 80.4 H 41.5 V 71.7 H 25.5 V 68.5 H 22.4 M 4.23,83.1 C 3.55,83.1 3,83.9 3,85.1 V 91 C 3,92.1 3.55,93 4.23,93 H 12.1 C 12.8,93 13.3,92.1 13.3,91 V 85.1 C 13.3,83.9 12.8,83.1 12.1,83.1 H 4.23 M 19.9,83.1 C 19.2,83.1 18.8,83.9 18.8,85.1 V 91 C 18.8,92.1 19.2,93 19.9,93 H 27.8 C 28.5,93 29,92.1 29,91 V 85.1 C 29,83.9 28.5,83.1 27.8,83.1 H 19.9 M 35.9,83.1 C 35.2,83.1 34.7,83.9 34.7,85.1 V 91 C 34.7,92.1 35.2,93 35.9,93 H 43.7 C 44.4,93 45,92.1 45,91 V 85.1 C 45,83.9 44.4,83.1 43.7,83.1 H 35.9' /><rect x='0' y='96' width='48' height='48' rx='3' ry='3' style='fill:rgb(243, 135, 37);'/><path style='opacity:0.25;fill:black;' d='M 16.8,114 23.1,120 8,122 6.4,128 11.4,133 3.7,141 6.9,144 H 45 C 46.7,144 48,142.7 48,141 V 116 L 31.4,99.4'/><path style='fill:white;' d='M 17.4,99 C 16.7,99 16.2,99.8 16.2,101 V 112 C 16.2,113 16.7,114 17.4,114 H 30.6 C 31.3,114 31.8,113 31.8,112 V 101 C 31.8,99.8 31.3,99 30.6,99 H 17.4 M 22.4,117 V 120 H 6.41 V 128 H 9.35 V 124 H 22.4 V 128 H 25.5 V 124 H 38.5 V 128 H 41.5 V 120 H 25.5 V 117 H 22.4 M 4.23,131 C 3.55,131 3,132 3,133 V 139 C 3,140 3.55,141 4.23,141 H 12.1 C 12.8,141 13.3,140 13.3,139 V 133 C 13.3,132 12.8,131 12.1,131 H 4.23 M 19.9,131 C 19.2,131 18.8,132 18.8,133 V 139 C 18.8,140 19.2,141 19.9,141 H 27.8 C 28.5,141 29,140 29,139 V 133 C 29,132 28.5,131 27.8,131 H 19.9 M 35.9,131 C 35.2,131 34.7,132 34.7,133 V 139 C 34.7,140 35.2,141 35.9,141 H 43.7 C 44.4,141 45,140 45,139 V 133 C 45,132 44.4,131 43.7,131 H 35.9' /><rect x='0' y='144' width='48' height='48' rx='3' ry='3' style='fill:rgb(21, 161, 99);'/><path style='opacity:0.25;fill:black;' d='M 16.8,162 23.1,168 8,170 6.4,176 11.4,181 3.7,189 6.9,192 H 45 C 46.7,192 48,190.7 48,189 V 164 L 31.4,147'/><path style='fill:white;' d='M 17.4,147 C 16.7,147 16.2,148 16.2,149 V 160 C 16.2,161 16.7,162 17.4,162 H 30.6 C 31.3,162 31.8,161 31.8,160 V 149 C 31.8,148 31.3,147 30.6,147 H 17.4 M 22.4,165 V 168 H 6.41 V 176 H 9.35 V 172 H 22.4 V 176 H 25.5 V 172 H 38.5 V 176 H 41.5 V 168 H 25.5 V 165 H 22.4 M 4.23,179 C 3.55,179 3,180 3,181 V 187 C 3,188 3.55,189 4.23,189 H 12.1 C 12.8,189 13.3,188 13.3,187 V 181 C 13.3,180 12.8,179 12.1,179 H 4.23 M 19.9,179 C 19.2,179 18.8,180 18.8,181 V 187 C 18.8,188 19.2,189 19.9,189 H 27.8 C 28.5,189 29,188 29,187 V 181 C 29,180 28.5,179 27.8,179 H 19.9 M 35.9,179 C 35.2,179 34.7,180 34.7,181 V 187 C 34.7,188 35.2,189 35.9,189 H 43.7 C 44.4,189 45,188 45,187 V 181 C 45,180 44.4,179 43.7,179 H 35.9' /><rect x='0' y='192' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 16.8,210 23.1,216 8,218 6.4,224 11.4,229 3.7,237 6.9,240 H 45 C 46.7,240 48,238.7 48,237 L 48,212 31.4,195'/><path style='fill:white;' d='M 17.4,195 C 16.7,195 16.2,196 16.2,197 V 208 C 16.2,209 16.7,210 17.4,210 H 30.6 C 31.3,210 31.8,209 31.8,208 V 197 C 31.8,196 31.3,195 30.6,195 H 17.4 M 22.4,213 V 216 H 6.41 V 224 H 9.4 V 220 H 22.4 V 224 H 25.5 V 220 H 38.5 V 224 H 41.5 V 216 H 25.5 V 213 H 22.4 M 4.23,227 C 3.55,227 3,228 3,229 V 235 C 3,236 3.55,237 4.23,237 H 12.1 C 12.8,237 13.3,236 13.3,235 V 229 C 13.3,228 12.8,227 12.1,227 H 4.23 M 19.9,227 C 19.2,227 18.7,228 18.7,229 V 235 C 18.7,236 19.2,237 19.9,237 H 27.8 C 28.5,237 29,236 29,235 V 229 C 29,228 28.5,227 27.8,227 H 19.9 M 35.9,227 C 35.2,227 34.7,228 34.7,229 V 235 C 34.7,236 35.2,237 35.9,237 H 43.7 C 44.4,237 45,236 45,235 V 229 C 45,228 44.4,227 43.7,227 H 35.9' /></g></svg>", imgmenu = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='80' width='16' viewBox='0 0 48 240'><g><circle cy='24' cx='24' style='fill:rgb(146, 69, 101);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,41.8 22.3,31.1 36.7,17.9 44,25.2 C 43.5,30.6 41,37.7 33,41.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,19 H 13 L 24,30 35,19' /><circle cy='72' cx='24' style='fill:rgb(209, 8, 3);' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,89.8 22.3,79.1 36.7,65.9 44,73.2 C 43.5,78.6 41,85.7 33,89.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,67 H 13 L 24,78 35,67' /><circle cy='120' cx='24' style='fill:rgb(243, 135, 37);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.8,138 22,127 36.7,114 44,121 C 43.5,127 40.9,134 32.8,138 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 34.9,115 H 13.1 L 24,126 34.9,115' /><circle cy='168' cx='24' style='fill:rgb(21, 161, 99);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.9,186 22,175 36.7,162 44,169 C 43.5,175 40.9,182 32.9,186 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,163 H 13 L 24,174 35,163' /><circle cy='216' cx='24' style='fill:rgb(0, 120, 173);' r='20'/><path style='opacity:0.25;fill:black;' d='M 32.8,234 22,223 36.7,210 44,217 C 43.5,223 40.9,230 32.8,234 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,211 H 13 L 24,222 35,211' /></g></svg>"; */ doreload = true; // Перезагрузить страницу var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var r = (name, svg) => { var subst = id + "-" + name; rph.setSubstitution(subst, Services.io.newURI("data:image/svg+xml;charset=utf-8," + svg)); return `resource://${subst}/`; } var img = r("img", "<svg style='fill: context-fill;' xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3'/><path style='opacity:0.25;fill:black;' d='M 16.8,17.6 23.1,23.9 8,26 6.4,32.2 11.4,37.2 3.7,44.8 6.9,48 45,48 C 46.7,48 48,46.7 48,45 V 20 L 31.4,3.4'/><path style='fill:white;' d='M 17.4,3 C 16.7,3 16.2,3.82 16.2,4.91 V 15.9 C 16.2,17 16.7,17.8 17.4,17.8 H 30.6 C 31.3,17.8 31.8,17 31.8,15.9 V 4.91 C 31.8,3.82 31.3,3 30.6,3 H 17.4 M 22.4,20.5 V 23.7 H 6.41 V 32.2 H 9.35 V 28.2 H 22.4 V 32.4 H 25.5 V 28.2 H 38.5 V 32.4 H 41.5 V 23.7 H 25.5 V 20.5 H 22.4 M 4.23,35.1 C 3.55,35.1 3,35.9 3,37.1 V 43 C 3,44.1 3.55,45 4.23,45 H 12.1 C 12.8,45 13.3,44.1 13.3,43 V 37.1 C 13.3,35.9 12.8,35.1 12.1,35.1 H 4.23 M 19.9,35.1 C 19.2,35.1 18.7,35.9 18.7,37.1 V 43 C 18.7,44.1 19.2,45 19.9,45 H 27.8 C 28.5,45 29,44.1 29,43 V 37.1 C 29,35.9 28.5,35.1 27.8,35.1 H 19.9 M 35.9,35.1 C 35.2,35.1 34.7,35.9 34.7,37.1 V 43 C 34.7,44.1 35.2,45 35.9,45 H 43.7 C 44.4,45 45,44.1 45,43 V 37.1 C 45,35.9 44.4,35.1 43.7,35.1 H 35.9' /></g></svg>"); var imgmenu = r("imgmenu", "<svg style='fill: context-fill;' xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><circle cy='24' cx='24' r='20'/><path style='opacity:0.25;fill:black;' d='M 33,41.8 22.3,31.1 36.7,17.9 44,25.2 C 43.5,30.6 41,37.7 33,41.8 Z'/><path style='fill:white;stroke:white;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;' d='M 35,19 H 13 L 24,30 35,19' /></g></svg>"); ....... /* #${id}-button { list-style-image: url("${img}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; margin-inline-end: 0 !important; } #${id}-button-menu { list-style-image: url("${imgmenu}") !important; -moz-image-region: rect(0px, 16px, 16px, 0px) !important; margin-inline-start: 0px !important; } #${id}[activated="1"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(16px, 16px, 32px, 0px) !important; } #${id}[activated="2"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(32px, 16px, 48px, 0px) !important; } #${id}[activated="4"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(48px, 16px, 64px, 0px) !important; } #${id}[activated="5"] :-moz-any(#${id}-button,#${id}-button-menu) { -moz-image-region: rect(64px, 16px, 80px, 0px) !important; } */ #${id}-button { list-style-image: url("${img}") !important; margin-inline-end: 0 !important; } #${id}-button-menu { list-style-image: url("${imgmenu}") !important; margin-inline-start: 0px !important; } #${id}[activated="0"] :is(#${id}-button,#${id}-button-menu) { fill: rgb(146,69,101) !important; } #${id}[activated="1"] :is(#${id}-button,#${id}-button-menu) { fill: rgb(209,8,3) !important; } #${id}[activated="2"] :is(#${id}-button,#${id}-button-menu) { fill: rgb(243,135,37) !important; } #${id}[activated="4"] :is(#${id}-button,#${id}-button-menu) { fill: rgb(21,161,99) !important; } #${id}[activated="5"] :is(#${id}-button,#${id}-button-menu) { fill: rgb(0,120,173) !important; } |
b0ttle > 30-09-2023 23:31:44 |
Dumby скрытый текст Выделить код Код:var file = Services.dirsvc.get("UChrm", Ci.nsIFile); ["user_chrome_files","_","opera-proxy.windows-386.exe"].forEach(file.append); var {path} = file; |
kokoss > 30-09-2023 23:53:41 |
rubel пишет
Ну если с ATB всё нормально, то ничего. |
rubel > 01-10-2023 07:34:18 |
Dumby
Этот вариант лучше. Значок Меню стал ближе к значку Переключить прокси. Спасибо. |
Dumby > 01-10-2023 09:49:39 |
b0ttle пишет
Да, действительно, так и надо было сделать, скрытый текст Выделить код Код:/* var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); */ var file = Services.dirsvc.get("UChrm", Ci.nsIFile); ["user_chrome_files", "_", "opera-proxy.windows-386.exe"].forEach(file.append); |
b0ttle > 01-10-2023 22:02:47 |
Dumby |
Dobrov > 07-10-2023 05:59:31 |
Как переделать загрузчик AttributesInspector.js, чтобы вместо левой кнопки мыши код выполнялся при клике правой кнопкой ? Или колёсиком ? Выделить код Код:(async (id) => CustomizableUI.createWidget({ label:id, id:id, localized: false, onCreated(btn) { btn.setAttribute("image","data:image/webp;base64,UklGRjwAAABXRUJQVlA4TC8AAAAvD8ADAAoGbSM5Ov6k774XCPFP/0/03/8JGPxzroIzuOW06Ih60Genn1S/gHe+BgA="); btn.onmouseenter = btn.onmouseleave = this.onmouse; btn.setAttribute("oncommand","handleCommand(this)"); btn.handleCommand = this.handleCommand; }, onmouse: e => e.target.focusedWindow = e.type.endsWith("r") && Services.wm.getMostRecentWindow(null), get handleCommand() { delete this.handleCommand; return this.handleCommand = btn => {(btn.handleCommand = new btn.ownerGlobal.Function(this.code).bind(btn))();} }, get code() { delete this.code; var s = Ff.c +"custom_scripts/AttributesInspector.js"; try { id = 'this.focusedWindow && this.focusedWindow.focus();\n' + Cu.readUTF8URI(Services.io.newURI(s)) } catch {} return this.code = id; } }))("AttributesInspector"); |
Dumby > 08-10-2023 09:31:12 |
Dobrov пишет
скрытый текст Выделить код Код:/* btn.setAttribute("oncommand","handleCommand(this)"); btn.handleCommand = this.handleCommand; */ btn.setAttribute("oncontextmenu", "return event.ctrlKey || (handleCommand(this), false)"); btn.handleCommand = this.handleCommand;
скрытый текст Выделить код Код:/* btn.setAttribute("oncommand","handleCommand(this)"); btn.handleCommand = this.handleCommand; */ btn.setAttribute("onauxclick", "if (event.button == 1) handleCommand(this)"); btn.handleCommand = this.handleCommand; ....... /* return this.code = id; */ return this.code = id.replace("canInspect: function(e) {\n", "$&\t\t\tif(e.button == 1 && e.target == context.button) return false;\n"); |
xrun1 > 13-10-2023 15:20:17 |
Выложу здесь свой код google-translate.js. Ссылка на источник, ничего не удалял. Ненужное закомментировано, изменения прокомментированы и ссылки присутствуют. скрытый текст Выделить код Код:// https://forum.mozilla-russia.org/viewtopic.php?pid=780231#p780231 (this.googletranslate = { init(that) { var lc = navigator.lastClick = {}, w = null, xhtmlns = 'http://www.w3.org/1999/xhtml'; var mouseUp = (e) => { if (e.button) return; lc.X = e.screenX - mozInnerScreenX; lc.Y = e.screenY - mozInnerScreenY; }; gBrowser.tabpanels.addEventListener('mouseup', mouseUp, false); this.destructor = () => { gBrowser.tabpanels.removeEventListener('mouseup', mouseUp, false); if (w) w.closeWin(); }; that.unloadlisteners.push("googletranslate"); var createWindow = function(text, status, title, id, pos, size) { var win = window, doc = win.document, wId = 'ujs_window'+(id || ''); w = doc.getElementById(wId); var keyDown = function(e) {if (!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode == 27)doc.getElementById(wId).closeWin();}; var mouseDown = function() {doc.getElementById(wId).closeWin();}; if (w) w.closeWin(); w = doc.createElementNS(xhtmlns, 'div'); w.setAttribute('style', 'position:fixed;display:block;visibility:hidden;left:0;top:0;width:auto;height:auto;border:1px solid gray;padding:2px;margin:0;z-index:99999;overflow:hidden;cursor:move;'+(typeof w.style.borderRadius === 'string' ? 'background-color:#eaeaea;padding-top:0px;border-radius:4px;box-shadow:0 0 15px rgba(0,0,0,.4);' : 'background:-o-skin("Window Skin");')); w.id = wId; w.closeWin = function() { doc.removeEventListener('keydown', keyDown, false); gBrowser.tabpanels.removeEventListener('mousedown', mouseDown, false); this.parentNode.removeChild(this); w = null; }; w.addEle = function(str, style) { var ele = doc.createElementNS(xhtmlns, 'div'); ele.setAttribute('style', style); if (str) { ele.innerHTML = str; for (var el, all = ele.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)) { el.parentNode.removeChild(el); } else { for (var att = el.attributes, j = att.length; j--;) { if (/^on[a-z]+$/i.test(att[j].name))att[j].value = ''; } } } } return this.appendChild(ele); }; /* https://forum.mozilla-russia.org/viewtopic.php?pid=807299#p807299 w.addEle1 = function(str, style) { var ele = doc.createElementNS(xhtmlns, 'textarea'); ele.setAttribute('style', style); if (str) { ele.innerHTML = str; for (var el, all = ele.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)) { el.parentNode.removeChild(el); } else { for (var att = el.attributes, j = att.length; j--;) { if (/^on[a-z]+$/i.test(att[j].name))att[j].value = ''; } } } } return this.appendChild(ele); }; */ var img = doc.createElementNS(xhtmlns, 'div'); img.setAttribute('style', 'display:block;float:right;width:16px;height:16px;padding:0;margin-top:2px;margin-right:1px;border:none;cursor:pointer;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACQUlEQVR4Xm2SPUhbURTHfzfNJ4nU0Axx7CJCN2kQtIgVCtq6OdQuBUftWIQqFNsKDo6iHTqIqN3a0kklUKTS2AZrcOjioFtRjFWUfH+803cS9GHwB4dzcu75/+8L9xgaSEDbLXhaASzAyXAMn5/DHxwwjeJgKLRxd3Q0atxuLhGgWqmQmp9PJ7LZJ5Ow3WhQFweDG20LC1FfRwc3kUsm+T48fPIzl3s8VTdxxLt+/2FhdlZkc1MkmdR8Pba2ajlrz3z1+9OvIOaIfb7DwsSEyNKSyM6OSLksEo/rbw2ttadntV7Gnv3k86VfqskvmDzv7hZ580Zkelrk4kJqFIsii4satVrRs+rYmBQHBuRvS4u8g/fuCmDOz+HgAIWpKRgfh3AYhoZQ8Hqxjo4o9PdT3d1FcQEl8KoBnJ7C/j6KZkZGYG4OIhEUFed7erD29q69jGrd1qVBqcQVKgwEuMSEQhjtXRk4JvW/kM1i2WGMga4uzMoKBIOIfbNiolEC6+uU+/qQRALFA1QBlwVYxmBcLmhuxqytQSgEKu7t1dBavwKvbeINh/Has2IMqnXpem4bky6qWLdvZgaOj2FwEHNyoqG19vRMZ8jZs1+NOfsNcZS3EFvzeNL51laRe/dEYrFadsLpZeyZDx7P6QN4Btwx1OE1xO4HAquP2tsjAZ+Pm8gWi3xMpc6W8/kXPyAO/DM4oOsZa2pafdjZGXF7PAgOpXKZL4nE2XImcyUGMDSg63kbhgvgtYCq8+akIL4J3y7Fyn+DokZOnLlMyQAAAABJRU5ErkJggg==");background:-o-skin("Caption Close Button Skin");'); img.title = (win.navigator.language.indexOf('ru') == 0) ? '\u0417\u0430\u043A\u0440\u044B\u0442\u044C' : 'Close'; img.addEventListener('click', function() {this.parentNode.closeWin();}, false); w.appendChild(img); var title = w.addEle(title, 'display:table;color:#000;font:17px Times New Roman;width:auto;height:auto;padding:0;margin:0 2px;cursor:text;'); title.onclick = e => { e.preventDefault(); var url = e.target.href; // Здесь открываем url как хотим. var ctabpos = gBrowser.selectedTab._tPos +1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos); doc.getElementById(wId).closeWin(); }; /* https://forum.mozilla-russia.org/viewtopic.php?pid=807299#p807299 var cnt = w.addEle1(text, 'display:block;border:1px solid #aaa;padding-bottom:3px;padding-left:3px;background-color:#fafcfe;color:#000;font:16px Times New Roman;width:310px;height:160px;overflow:auto;cursor:text;-moz-user-focus:normal;-moz-user-select:text;'); cnt.contentEditable="true"; cnt.context="contentAreaContextMenu"; */ var cnt = doc.createElement("textarea"); cnt.style.cssText = ` color: #000; width: 310px; height: 160px; outline: none; padding-left: 3px; padding-bottom: 3px; border: 1px solid #aaa; background-color: #fafcfe; font: 17px Times New Roman; `; // if (text) cnt.value = text; --> if (text) cnt.value = text.trim(); if (text) cnt.value = text.trim(); w.append(cnt); w.addEle(status, 'display:table;font:12px Times New Roman;font-weight:bold;color:blue;width:auto;height:auto;padding-top:2px;margin:0 3px;cursor:pointer;'); w.addEventListener('mousedown', function(e) { if (e.target == w) { e.preventDefault(); /* https://forum.mozilla-russia.org/viewtopic.php?pid=807257#p807257 var grabX = e.clientX, grabY = e.clientY, origX = parseInt(w.style.left), origY = parseInt(w.style.top); var mouseMove = function(ev) { w.style.left = origX+ev.clientX-grabX+'px'; w.style.top = origY+ev.clientY-grabY+'px'; }; */ var st = w.style; var mouseMove = e => { st.top = parseInt(st.top) + e.movementY + "px"; st.left = parseInt(st.left) + e.movementX + "px"; } doc.addEventListener('mousemove', mouseMove, false); doc.addEventListener('mouseup', function() {doc.removeEventListener('mousemove', mouseMove, false);}, false); } }, false); doc.documentElement.appendChild(w); if (size) { cnt.style.height = size.height; cnt.style.width = size.width; } else { for (var i = 3; i < 10; i++) { if (cnt.scrollHeight > cnt.offsetHeight || cnt.scrollWidth > cnt.offsetWidth) { cnt.style.height = 80*i+'px'; cnt.style.width = 160*i+'px'; } else break; } } var docEle = (doc.compatMode == 'CSS1Compat' && win.postMessage) ? doc.documentElement : doc.body; var mX = docEle.clientWidth-w.offsetWidth, mY = docEle.clientHeight-w.offsetHeight; if (mX < 0) {cnt.style.width = parseInt(cnt.style.width)+mX+'px'; mX = 0;} if (mY < 0) {cnt.style.height = parseInt(cnt.style.height)+mY+'px'; mY =0;} var hW = parseInt(w.offsetWidth/2); w.style.left = (pos && pos.X < mX+hW ? (pos.X > hW ? pos.X-hW : 0) : mX)+'px'; w.style.top = (pos && pos.Y+10 < mY ? pos.Y+10 : mY)+'px'; w.style.visibility = 'visible'; doc.addEventListener('keydown', keyDown, false); gBrowser.tabpanels.addEventListener('mousedown', mouseDown, false); // https://forum.mozilla-russia.org/viewtopic.php?pid=807326#p807326 if (text) { var st = cnt.style; var div = cnt.editor.rootElement; var range = new Range(); range.selectNode(div.firstChild); var rect = range.getBoundingClientRect(); let w = Math.ceil(rect.width); if (cnt.scrollTopMax) { if (!matchMedia("(-moz-overlay-scrollbars)").matches) // ??? w += InspectorUtils.getChildrenForNode(div, true, false).at(-1).clientWidth; } else st.height = Math.max(50, Math.ceil(rect.height) + 1) + "px"; // к строке выше; изменить, если font-size > 22 https://forum.mozilla-russia.org/viewtopic.php?pid=807332#p807332 st.width = Math.max(200, w) + "px"; } return w; }; var getHash = function (txt) { TKK=eval('((function(){var a\x3d817046147;var b\x3d-335196159;return 410049+\x27.\x27+(a+b)})())'); function sM(a) { var b; if (null !== yr) b = yr; else { b = wr(String.fromCharCode(84)); var c = wr(String.fromCharCode(75)); b = [b(), b()]; b[1] = c(); b = (yr = window[b.join(c())] || "") || ""; } var d = wr(String.fromCharCode(116)), c = wr(String.fromCharCode(107)), d = [d(), d()]; d[1] = c(); c = "&" + d.join("") + "="; d = b.split("."); b = Number(d[0]) || 0; for (var e = [], f = 0, g = 0; g < a.length; g++) { var l = a.charCodeAt(g); 128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023), e[f++] = l >> 18 | 240, e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224, e[f++] = l >> 6 & 63 | 128), e[f++] = l & 63 | 128); } a = b; for (f = 0; f < e.length; f++) a += e[f], a = xr(a, "+-a^+6"); a = xr(a, "+-3^+b+-f"); a ^= Number(d[1]) || 0; 0 > a && (a = (a & 2147483647) + 2147483648); a %= 1E6; return c + (a.toString() + "." + (a ^ b)); } var yr = null; var wr = function(a) { return function() { return a; }; }, xr = function(a, b) { for (var c = 0; c < b.length - 2; c += 3) { var d = b.charAt(c + 2), d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d), d = "+" == b.charAt(c + 1) ? a >>> d : a << d; a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d; } return a; }; return sM(txt); }; var ujs_google_translate = function (dir) { var lng = window.navigator.language.slice(0, 2), txt = gContextMenu.selectionInfo.fullText, l = dir.split('|'); var encTxt = encodeURIComponent(txt); var winWait = function(lng) {createWindow('', (lng == 'ru' ? 'Подождите идет перевод' : 'Wait, is going Translating')+'\u2026', 'Google Translate', '_gt', window.navigator.lastClick);}; if (txt) { winWait(lng); var xhr = new XMLHttpRequest(); var url = 'https://translate.google.com/translate_a/single?client=gtx&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt); // для urlt изменил http --> https (14.10.2023); тестирую var urlt = "https://translate.google.com/translate_t?text=" + encTxt + "&sl=' + langFrom_google_text + '&tl=' + langTo_google_text +'&hl=' + lng + '&eotf=0&ujs=gtt"; xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8'); xhr.onreadystatechange = function() { try { if (xhr.readyState == 4 && xhr.status == 200) { // var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />")); var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "")); for (var i = 0, n; n = tmp[0][i]; i++) { if (n[0])result += n[0].toString(); }; status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase(); createWindow(result, status, '<a href="'+urlt.replace(/&/g,'&')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Google Translate</a>', '_gt', window.navigator.lastClick); } } catch(e) {}; }; xhr.send('q=' + encodeURIComponent(txt)); } else { var urlt = gBrowser.currentURI.spec; // Изменил строку ниже. Добавил параметр '&tl='+l[1] https://forum.mozilla-russia.org/viewtopic.php?pid=796999#p796999 & http --> https (14.10.2023) var url = "https://translate.google.com/translate?u=" + encodeURIComponent(urlt) + '&tl=' + l[1] + "&hl=" + lng + "&langpair=" + dir + "&tbb=1"; var ctabpos = gBrowser.selectedTab._tPos +1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos); }; }; var contextMenu = document.getElementById("contentAreaContextMenu"); var nextEleMenu = document.getElementById("context-inspect"); var menuItem = document.createXULElement("menuitem"); menuItem.setAttribute("id", "context-ru-google-translate"); menuItem.setAttribute("label", "Перевести на русский"); menuItem.setAttribute("class", "menuitem-iconic"); menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABBUlEQVR4Ac2RMU4DMRREB2MqihQpAkUaqnAduuQw4Sx03CGcJYIiDYqQ0lCsZ77535ZFcgAkRuPvV7zd/dLiz3N1PFb8hmRckrfELZrF9ONQ1B6Yz0MyM7S0O6zGkVprh/3+Kw/JzkHSpRpJKZkpr9fYbOx0cjVsCbWG31oHBM9mtt0q73ZcrdLhAMlYQKkUI22aqsNo8HKZAMQhvVaKSHWj2Q2aPU3mJQFY7nuHyvYFduP83WF3AJRfcPNYnr/Lp1G1uK4m9sno1LaUbnX/htf8BNzoneUD5NhjvLCMhURQSQ93QCZwXYjFwg3I0NZKrvoknQPMIHkt/jRAQKMeG2yX89/mB4EJbKbZxIhFAAAAAElFTkSuQmCC"); menuItem.addEventListener("command", function() {ujs_google_translate('auto|ru');}, false); contextMenu.insertBefore(menuItem, nextEleMenu); menuItem = document.createXULElement("menuitem"); menuItem.setAttribute("id", "context-en-google-translate"); menuItem.setAttribute("label", "Перевести на английский"); menuItem.setAttribute("class", "menuitem-iconic"); menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAAB5UlEQVR4AWOgPZg0c9+Oq2+qpx9LaQaiw4mNB27efbs2uXFNQh2Q4Zm9zSNth23MhqjGnXMC86vnHmUS4udxv7OvOd2yPE7PTlfCTk9GVVEoyJA7WI8dyPA0k3U1l+jJMV7CeThpTZeoKDdDUsvBPSff/V+6/P/Bvf///2+bdvU/EKRm/k9IBNIlfZe+LFrzvbsbyJ636pKkyQyQhoUb7tZNvPpw3/0/TfX/ISAm5n94BIiRm/n/xYsLd946ei4vajoiqDuRAejQf//+o4PQ0P9+fmhiQGVnrr1kXJNYG2zEzXDxDsPv3wy/fkFJoOTPn39+/fr/69e/37//AUX+/mXRkO458wWHDba2f8wswCyQ3N+/f//8/fP7z5+TV18w2Mdt6plzPiptx5Wr7/+/ffMzOR6kysjkt74hWMPfp06O+2dulZCeFZKwnkE4m8E8bN3i9aCQ+dxY96GrK6bkGJD9R1v3l6Y20NVW9kt+/v//ZdbcFwkxTVPPMQimM8XEqkb7a/zoqLxkH9v4zVyI5+///wyMmtKMmhJAnbLqQjHxaw5r2orOmZN5uj470Zahat6BKS7JzpmLBHXm8GhM5lCdcP7ai1ZpixZxk9NXXjKIFzOIFjAI54oY1vXuue5qmscw+AAAW0tKxtPoicEAAAAASUVORK5CYII="); menuItem.addEventListener("command", function() {ujs_google_translate('auto|en');}, false); contextMenu.insertBefore(menuItem, nextEleMenu); contextMenu.insertBefore(document.createXULElement("menuseparator"), nextEleMenu); } }).init(this); UPD: Заменил http --> https (2 правки, см. по дате 14.10.2023). |
unter_officer > 14-10-2023 09:46:32 |
xrun1 пишет
Спасибо. И у меня вопросик. |
xrun1 > 14-10-2023 11:07:41 |
unter_officer пишет
Скрипт написал, примерно, в 2015-м году Алексей Рузанов aka Lex1. Остальные авторы его только модифицировали. Подробнее. Здесь есть сниппет для перевода Яндекса (сейчас не работает, проверил). скрытый текст Выделить код Код:var ujs_google_translate = function (dir) { var lng = window.navigator.language.slice(0, 2), txt = gContextMenu.selectionInfo.fullText, l = dir.split('|'); var encTxt = encodeURIComponent(txt); var winWait = function(lng) {createWindow('', (lng == 'ru' ? 'Подождите идет перевод' : 'Wait, is going Translating')+'\u2026', 'Google Translate', '_gt', window.navigator.lastClick);}; if (txt) { winWait(lng); var xhr = new XMLHttpRequest(); var url = 'https://translate.google.com/translate_a/single?client=gtx&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt); var urlt = "http://translate.google.com/translate_t?text=" + encTxt + "&sl=' + langFrom_google_text + '&tl=' + langTo_google_text +'&hl=' + lng + '&eotf=0&ujs=gtt"; xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8'); xhr.onreadystatechange = function() { try { if (xhr.readyState == 4 && xhr.status == 200) { // var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />")); var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "")); for (var i = 0, n; n = tmp[0][i]; i++) { if (n[0])result += n[0].toString(); }; status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase(); createWindow(result, status, '<a href="'+urlt.replace(/&/g,'&')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Google Translate</a>', '_gt', window.navigator.lastClick); } } catch(e) {}; }; xhr.send('q=' + encodeURIComponent(txt)); } else { var urlt = gBrowser.currentURI.spec; // Изменил строку ниже. Добавил параметр '&tl='+l[1] https://forum.mozilla-russia.org/viewtopic.php?pid=796999#p796999 var url = "http://translate.google.com/translate?u=" + encodeURIComponent(urlt) + '&tl=' + l[1] + "&hl=" + lng + "&langpair=" + dir + "&tbb=1"; var ctabpos = gBrowser.selectedTab._tPos +1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos); }; }; |
fuchsfan > 14-10-2023 11:13:11 |
unter_officer пишет
На всякий случай просто к сведению. Расширение Simple Translate https://addons.mozilla.org/ru/firefox/a … translate/ добавляет два своих пункта в контекстном меню "перевести выделенное" и "перевести страницу" + плавающую кнопку. |
rubel > 19-10-2023 08:59:25 |
xrun1
Что-то он не хочет работать с моим UCF. |
xrun1 > 19-10-2023 14:13:06 |
rubel Выделить код Код:load: [ // По событию "load" { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar ... { path: "google-translate.js", ucfobj: true, }, |
rubel > 19-10-2023 15:10:55 |
xrun1 скрытый текст |
xrun1 > 19-10-2023 15:56:30 |
rubel пишет
Давно заметил, что скрипты, которые делал/редактировал Виталий, надо подписывать true. Все остальные false. |
xrun1 > 01-11-2023 00:48:13 |
Не знаю, куда написать. Отвалилось расширение async_run_applications@vitaliy.ru.xpi. Правильнее сказать, работает, но добавить ничего не получается. Кто пользуется, проверьте, пожалуйста. |
fuchsfan > 01-11-2023 09:08:39 |
xrun1 пишет
Не юзаю, но проверил, то же самое. Скорее всего, дело в config.js. |
Farby > 01-11-2023 09:40:39 |
xrun1 пишет
там надо поправить в двух местах parent.js Выделить код Код://var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); //var {CustomizableUI} = ChromeUtils.import("resource:///modules/CustomizableUI.jsm"); //ChromeUtils.defineModuleGetter(this, "OS", "resource://gre/modules/osfile.jsm"); var Services = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services; var CustomizableUI = globalThis.CustomizableUI || ChromeUtils.import("resource:///modules/CustomizableUI.jsm").CustomizableUI; Components.utils.importGlobalProperties(['IOUtils']); Выделить код Код:// await OS.File.writeAtomic(this._storeFile.path, JSON.stringify(data), { tmpPath: this._storeFile.path + ".tmp" }).then(() => { await IOUtils.writeJSON(this._storeFile.path, data, { tmpPath: this._storeFile.path + ".tmp" }).then(() => { |
xrun1 > 02-11-2023 00:30:07 |
Farby |
Dobrov > 02-11-2023 08:05:44 |
Dumby - Приветствую! Вопрос по скрипту перехвата click, dblclick и долгое нажатие на кнопках панелей. (2021 года) Если пауза между кликами примерно как в скрипте 300 мс, в консоли видно срабатывание DBLClick. (и мышь не виновата!) Выделить код Код:(async (id) =>{ // hookClicks TEST BUTTON var Mouse = { //meta*64 Ctrl*32 Шифт*16 Alt*8 (Wh ? 2 : But*128) long*4 dbl [id]: { 0(){ console.clear(); log('CLICK 0'); }, 1(){ log('DUBLE 0')}, 4(){ log('LONG 0')}, }}; CustomizableUI.createWidget({ id: id, label: id, tooltiptext: id, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn){ btn.style.setProperty("list-style-image","url(chrome://devtools/skin/images/settings.svg)"); } }); function log(s){console.log('■ '+ s +' '+ Math.random())} var Mus = {}; Object.keys(Mouse).forEach((k) =>{Mus["#"+ k] = Mus["."+ k] = Mouse[k]}); var listener = { // дополнительные клики кнопок и перехват существующих filter(sel) { return this.closest(sel); }, find(sel) { //условия запуска ? return Mus[sel][this] || Mus[sel][this + 1]; }, get selectors() { this.exec = (trg, obj, num) => { this.clickTID = null; obj[num](trg); } // this.onLongPress = (trg, obj, num) => { // this.mousedownTID = null; // this.longPress = true; // obj[num*4](trg); // } delete this.selectors; return this.selectors = Object.keys(Mus); }, handleEvent(e) { if (this.skip || e.detail > 2) return; if (e.type == "mouseenter") return; //update tooltips var trg = e.target; var sels = this.selectors.filter(this.filter, trg); var {length} = sels; if (!length) return; var dbl = e.detail == 2; var wheel = e.type.startsWith("w"); var num = e.metaKey*64 +e.ctrlKey*32 +e.shiftKey*16 +e.altKey*8 +(wheel ? 2 : e.button*128 +dbl); //long*4 var obj = Mus[ length > 1 && sels.find(this.find, num) || sels[0] ]; // wheel if (wheel) return obj[num]?.(trg, e.deltaY < 0); // mousedown if (e.type.startsWith("m")) { obj.mousedownTarget && this.stop(e); if (dbl) return; // this.longPress = false; //+ задержка при обычном клике // if (++num in obj) // this.mousedownTID = setTimeout(this.onLongPress, 640, trg, obj, num); if (e.button == 2) this.ctx = trg.getAttribute("context"), trg.setAttribute("context",""); return; } // click obj.mousedownTarget || this.stop(e); // if (this.longPress) return this.longPress = false; dbl ? this.clickTID &&= clearTimeout(this.clickTID) : this.mousedownTID &&= clearTimeout(this.mousedownTID); if (!obj[num]) { if (e.button == 1) return; if (e.button) { num = "context"; for(var p in this.a) this.a[p] = e[p]; } else num = "dispatch", this.mdt = obj.mousedownTarget; obj = this; } dbl ? obj[num](trg) : this.clickTID = setTimeout(this.exec, 300, trg, obj, num); }, get mdEvent() { delete this.mdEvent; return this.mdEvent = new MouseEvent("mousedown", {bubbles: true}); }, context(trg) { this.ctx ? trg.setAttribute("context", this.ctx) : trg.removeAttribute("context"); trg.dispatchEvent(new MouseEvent("contextmenu", this.a)); }, dispatch(trg) { this.skip = true; this.mdt ? trg.dispatchEvent(this.mdEvent) : trg.click(); this.skip = false; }, stop: e => { e.preventDefault(); e.stopImmediatePropagation(); }, a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0} }; var events = ["click", "mousedown", "wheel", "mouseenter"]; var els = document.querySelectorAll("#navigator-toolbox,#ucf-additional-vertical-bar,#appMenu-popup,#widget-overflow-mainView"); for(var el of els) for(var type of events) el.addEventListener(type,listener,true); ucf_custom_script_win.unloadlisteners.push(id); ucf_custom_script_win[id] = {destructor(){ for(var el of els) for(var type of events) el.removeEventListener(type,listener,true); }}; })('ucf_hookClicks_test'); //клики-подсказки |
Dumby > 02-11-2023 11:06:42 |
Dobrov пишет
Что-то не вижу такого.
Да, согласен, 300 — это довольно погранично. Если, зачем-то, есть желание лупить по клавише |
Dobrov > 02-11-2023 16:32:45 |
Dumby пишет
Чём больше задержка, тем позже срабатывает действие. То есть, после одинарного клика сначала пауза на время двойного клика, потом действие. Dumby – может придумаешь способ назначить перехват кликов на всех кнопках панелей, используя системные onclick ondblclick ? Выделить код Код:btn.linkedObject = this; for(var type of ["command", "contextmenu"]) // тут dblclick можно добавить… btn.setAttribute("on" + type, `linkedObject.${type}(event)`); |
Kot DaVinci > 04-11-2023 15:18:24 |
Что ТУТ надо добавить/убавить чтобы окошко с переводом закрывалось только при нажатии на кнопку "закрыть ❌"? |
Dobrov > 15-11-2023 05:06:47 |
Dumby — твоя кнопка Быстрое переключение опций about:config содержала два контекстных меню. Я оставил одно меню, — прошу убрать лишний код поддержки нескольких меню: popups, popupshowing… (может попроще код станет) ucf_QuickToggle.js Выделить код Код:/* Быстрое переключение опций about:config для окна [ChromeOnly] © Dumby 30 скрытых настроек. Ctrl+Click или Правый: сброс опции по-умолчанию клик по параметру с Shift или колёсиком блокирует авто-закрытие меню ⟳ Обновить страницу, ↯ Перезапуск браузера строки с pYellow = шрифт italic, цвет = ключ, пусто:Red refresh: false - reload current tab, true - reload skip cache restart: false - restart browser, true - restart with confirm */ (async (name, func) => { // mod by Dobrov, нужен ucf_hookClicks.js return CustomizableUI.createWidget(func()); //only UCF })(this.constructor.name, () => { var {prefs} = Services, db = prefs.getDefaultBranch(""), ua = glob.ua(true), //real ЮзерАгент I = [AppConstants.platform == "win" ? '#124' : '#e8e8e8', //текст под курсором, без Aero '#fff' "https://antizapret.prostovpn.org/proxy.pac", "user.pacfile", glob.pref(['browser.sessionstore.interval', 15e3]), parseInt(Services.appinfo.version),"general.useragent.override", "Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Android 12.0; Mobile; rv:109.0) Gecko/97.0 Firefox/97.0","Mozilla/5.0 ("], fonts = arr => arr.map(n => [(n == arr[arr.length-1] ? null : n), n]), //array с вложениями serif = fonts("Arial|Cantarell|DejaVu Sans|Roboto|PT Serif|Segoe UI|Ubuntu|Cambria|Fira Sans|Georgia|Noto Sans|Calibri|Times|системный".split('|')), sans = [["PT Sans","PT Sans"], ...serif] hints = new Map([ //опция отсутствует ? выполнить код и вернуть строку ["ucf.savedirs", `glob.crop(glob.dirsvcget(""),34)`], [I[5], `glob.ua()`]]), //текущий ЮзерАгент secondary = [{ // menu: [apref, lab, akey, hint, [undef, str], code] radio: [val, lab, str-val, add-hint, code] pref: ["dom.disable_open_during_load", "Всплывающие окна"], pDefGreen: 2, pYellow: true, values: [[true, "Блокировать"], [false, "Разрешить"]] },{ pref: ["javascript.enabled", "Выполнять скрипты Java",,"Поддержка интерактивных сайтов, рекламы\nтакже разрешает действия горячих клавиш"], pDefGreen: true, refresh: true, values: [[true, "Да"], [false, "Нет"]] },{ pref: ["browser.safebrowsing.downloads.remote.block_dangerous", "Опасные файлы, сайты",,"browser.safebrowsing.downloads.remote.block_dangerous_host"], pDefGreen: true, pYellow: false, values: [[true, "Запрет",,,`glob.pref('browser.safebrowsing.downloads.remote.block_dangerous_host',true)`], [false, "Открыть",,,`glob.pref('browser.safebrowsing.downloads.remote.block_dangerous_host',false)`]] },{ pref: ["ucf.savedirs", "Загрузки",,'Пути сохранения Страниц и Графики\nСинтаксис «_Html/subdir|_Pics/subdir»\nsubdir: пусто | 0 заголовок | 1 домен', ["", "всё в общей папке"]], pDefGreen: "_Сайты||_Фото|0", pYellow: "_Web|1|_Images|0", pGray: "", values: [ // сохранение Html/Pics. [Загрузки]/"_Html/subdir|_Pics/subdir" subdir: пусто | 0 заголовок | 1 домен ["", "всё в общую папку"], [`_Сайты||_Фото|0`, "_Сайты|_Фото/имя…"], [`_Web||_Photo|0`, "_Web|_Photo/имя"], [`_Web|1|_Pics|1`, "_Web/сайт|_Pics/…"], [`_Web|0|_Pics|`, "_Web/имя|_Pics"], [`_Web|1|_Images|0`, "_Web/сайт, _Images/имя"], //открыть опцию about:config: [`Сайт||Фото|`, "ввести свои пути",,"ключ в about:config",`glob.about_config("ucf.savedirs")`]] },null,{ pref: ["network.proxy.autoconfig_url", "Прокси (VPN)", "п", "network.proxy.type\n\nПереключение сетевых настроек"], pDefGreen: "localhost", pYellow: I[1], pGray: "", refresh: true, values: [ //фон кнопки Меню: серый, голубой, красный, жёлтый, зелёный ["localhost", "системный", "0",, `glob.pref('network.proxy.type', 0)`], ["127.0.0.1", "Tor или Opera", "1", "Необходим сервис tor или opera-proxy", `glob.pref('network.proxy.type', 1)`], [I[1], "АнтиЗапрет", "2", "Надёжный доступ на заблокированные сайты\n«Режим прокси» меняется на 2", `glob.pref('network.proxy.type', 2)`], // ["https://git.io/ac-anticensority-pac", "ac-anticensority", "3"], [glob.pref([I[2], "file:///etc/proxy.pac"]), "user .pac файл", "4", "about:config "+ I[2]], // нужен диалог выбора pac-файла [null, "сброшен",""]] },{ pref: ["network.proxy.type", "Режим прокси", "р"], pDefGreen: 5, pYellow: 2, pGray: 1, refresh: true, values: [ [5, "системный", "5"], [0, "Без прокси", "0", "по-умолчанию"], [2, "Автонастройка", "2", "about:config "+ I[2]], [1, "Ручная настройка", "1", "Используется network.proxy.autoconfig_url"], [4, "Автоопределение", "4"] ] },{ pref: ["network.trr.mode", "DNS поверх HttpS",, "Шифрование DNS-трафика для\nзащиты персональных данных"], pDefGreen: 0, pYellow: 2, pGray: 5, refresh: true, values: [ [0, "по-умолчанию", "0"], [1, "автоматически", "1", "используется DNS или DoH, в зависимости от того, что быстрее"], [2, "DoH, затем DNS", "2"], [3, "только DoH", "3"], [4, "DNS и DoH", "4"], [5, "отключить DoH", "5"] ] },{ pref: ["network.cookie.cookieBehavior", "Получать куки",, "Персональные настройки посещённых сайтов"], pDefGreen: 3, pYellow: 0, pGray: 4, values: [[0, "со всех сайтов"], [3, "посещённые сайты"], [4, "кроме трекеров"], [1, "кроме сторонних"], [2, "никогда"]] },null,{ pref: ["browser.display.use_document_fonts", "Загружать шрифты страниц"], pDefGreen: 1, pGray: 0, refresh: true, values: [[1, "Да"], [0, "Нет"]] },{ pref: ["font.name.sans-serif.x-cyrillic", "Шрифт без засечек ",,"Также влияет на всплывающие подсказки\nСистемный: загрузка шрифтов документа"], pDefGreen: "", pYellow: "Roboto", pGray: "Arial", values: sans },{ pref: ["font.name.serif.x-cyrillic", "Шрифт с засечками"], pDefGreen: "", pYellow: "Arial", values: serif },{ pref: ["gfx.webrender.force-disabled", "Ускорять отрисовку страниц", ,"gfx.webrender.compositor.force-enabled\ngfx.webrender.all\n\nАппаратная отрисовка страниц видеокартой.\nотключите при разных проблемах с графикой"], pDefGreen: false, pYellow: true, pGray: undefined, restart: true, values: [ [true, "Нет",,,`[["gfx.webrender.compositor.force-enabled", false], ["gfx.webrender.all", false]].map((a) =>{glob.pref(...a)})`], [false, "Да",,,`[["gfx.webrender.compositor.force-enabled", true], ["gfx.webrender.all", true]].map((a) =>{glob.pref(...a)})`]] },null,{ pref: ["media.autoplay.default", "Авто-play аудио/видео"], pDefGreen: 0, pYellow: 2, pGray: 5, refresh: true, values: [ [0, "Разрешить", "0"], [2, "Спрашивать", "2"], [1, "Запретить", "1"], [5, "Блокировать", "5"]] },{ pref: ["dom.storage.enabled", "Локальное хранилище",, "Сохранение персональных данных, по\nкоторым вас можно идентифицировать"], pDefGreen: false, pYellow: true, values: [[true, "Разрешить"], [false, "Запретить"]] },{ pref: ["privacy.resistFingerprinting", "Изоляция Firstparty-Fingerprint", ,"privacy.firstparty.isolate\n\nЗащита данных пользователя также\nзапрещает запоминать размер окна"], pDefGreen: false, values: [[true, "Да", , "Защита от слежки",`glob.pref('privacy.firstparty.isolate', true)`], [false, "Нет", , "Защита от слежки",`glob.pref('privacy.firstparty.isolate', false)`]] },(()=>{ if (I[4] > 114) return { //опции зависят от версии FF pref: ["browser.translations.enable", "Встроенный перевод сайтов"], pDefGreen: true, pGray: false, refresh: true, values: [[true, "Да"], [false, "Откл",,,`glob.toStatus("Перевод отключен для новых вкладок")`]] }; else return { pref: ["media.peerconnection.enabled", "WebRTC ваш реальный IP"], pDefGreen: false, values: [[true, "Выдать"], [false, "Скрыть"]] } })(),null,{ pref: ["network.http.sendRefererHeader", "Referer: для чего"], pDefGreen: 2, pYellow: 1, values: [[0, "Ни для чего", "0"], [1, "Только ссылки", "1"], [2, "Ссылки, графика", "2"]] },{ pref: ["browser.cache.disk.capacity", "Кэш браузера",,"\ncache.memory.max_entry_size:\nДиск и память: 5120\nтолько Память: -1"], pDefGreen: 1048576, pYellow: 0, pGray: 256e3, values: [ [256e3, "По-умолчанию"], [1048576, "Диск и Память",,,`[["browser.cache.memory.enable", true], ["browser.cache.disk.enable", true], ["browser.cache.memory.max_entry_size", 5120]].map((a) =>{glob.pref(...a)})`], [0, "только Память",,,`[["browser.cache.memory.enable", true], ["browser.cache.disk.enable", false], ["browser.cache.memory.max_entry_size", -1]].map((a) =>{glob.pref(...a)})`], [2097152, "только Диск",,,`[["browser.cache.memory.enable", false], ["browser.cache.disk.enable", true]].map((a) =>{glob.pref(...a)})`]] },{ pref: ["browser.sessionstore.interval", "Резервирование сессий",,"Браузер резервирует сессии на\nслучай сбоя, снижая ресурс SSD"], pDefGreen: 3e5, pYellow: I[3], pGray: 15e3, values: [ [I[3], `${I[3]/60e3 + " мин"}`], [15e3, "15 сек"], [6e4, "1 мин"], [3e5, "5 мин"], [9e5, "15 мин"], [18e5, "30 мин"]] },{ pref: [I[5], "User Agent",,"Тип гаджета меняет вид сайта", [ua, "встроенный"]], pDefGreen: ua, pYellow: I[8] + I[6], pGray: I[8] + I[7], refresh: true, values: [ [ua, "По-умолчанию"], [I[8] + I[6], "Chrome 118 Win10"], [I[8] + I[7], "Firefox 97 Android 12"], [I[8] + "Windows; U; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)", "MSIE 6.0 Windows"], ["Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12 Version/12.16", "Opera12 W8"], [I[8] + "Linux; Android 5.1.1; SM-G928X Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36", "Samsung Galaxy S6"], [I[8] + "PlayStation 4 3.11) AppleWebKit/537.73 (KHTML, like Gecko)", "Playstation 4"], ["Windows NT 10.0; Win64; x64; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 Edge/44.18363.8131", "Edge 44 Xbox One"], [I[8] + "compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; SAMSUNG; GT-I8350)", "Windows Phone"], [I[8] + "Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.143 YaBrowser/22.5.0.1916 Yowser/2.5 Safari/537.36", "Yandex OSX"], [I[8] + "compatible; Googlebot/2.1; +http://www.google.com/bot.html)", "GoogleBot"]] }]; return { id: "ToggleButton", label: "Журнал, Меню опций", localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, icon: "data:image/webp;base64,UklGRkYCAABXRUJQVlA4WAoAAAAQAAAAFwAAFwAAQUxQSJcAAAANcGJr25S8mH4SNGxAgsguPCZ0BcMOiDSNRpvVaCTa3AI2qm2e2ofz7OuwgIiYgMzb4kVjGvegnQFAwXgFVnvcOmtnMJtutAa3Vo4mhRMDpWq8AjfU+yQoYf1/oTkTIdUrknKswNQ5yAdDzqgr4CYbsJWQfEyEU5QNEl2eKFM2AAIbjmSIMjwXPGyEdj6Bdn4mj9KO63sAAFZQOCCIAQAAdAgAnQEqGAAYAD6dRppKgoCqgAE4lsAKwgisgG27uzPePSvBIu/Pr0HJqW+AfoAIHl2DrAnRo/G3JBpTx8yE7L6LFQyD+yUNvuRYAAD+7mwmpaoBcsJ1hVKsMI2ucqid8qndm+WEvH4l4il6lA8FPscgnrRHrnSjjyNcfUV21+TkfqOWKou2UvVsZSl1z+jKs760Vij5XCWF9Uo6TZAhKfrJpeILyQYwq2Ee/g1uyEH/dJMI/91DsVpI6i2vV/Jqpd4/KniJtTm1woLvaotA2ikt3eeBaqlHf8WPe++lSWS7fETjgvzzbflp0Rj+v23kbb9e/VjUcPaD83shRuwzEo6CAO/AGxE+Zwbvv9NDsQT6T+S4CCDOFTuMRVv9/0E4P+uK+Vc3bMfQQD05gY/fes+ZX6ZHkvFdMn7zX8LMVvI59p7F806HPD2lBjs4lWWhQ5ckJDNflZL49370shr3/Q9uMJN9i/NVCu4OT7K3+4+/RkAMnjuY09u+3i4y4CldQG789iIAAAA=", defGreen: "data:image/webp;base64,UklGRgoBAABXRUJQVlA4TP0AAAAvD8ADEI9hpG2kwpf60h8+nBQkbSSp/tW9hIMPFw5E0kaSKuP9q3kJDx8ePDjQSCQp2z8RkhhIHBVAEdD9J4JYEkEUJSiDD0EIEcFgBSIspCAcbdlyRzfeYpwnDotGYFHIfXe6pdToDwUE2bZNRzds24qTx9b8h+chHET0fwLiX3vNO6jyh5aWbwMaqX3Ttu/j0VDG+5ZB9nQ2nYwBUGepB8vqYH9v+qrpnsESzDcnh9i3DZ4oB3cfPD0+kmSTuyCucHH+8dXwLphnt5+6vgQlz3KwrB90f3drUFqXYE/zJz9KsufsQbatX741WnxtabN4hjds8X2veQdVxr8CAA==", Gray: "data:image/webp;base64,UklGRsgAAABXRUJQVlA4TLsAAAAvD8ADEFW4rbVtaVj67ViCCWhDSugiHSSVle7uMoJnhO973wgztW2IIZo4RvFEMdqu2rZtGJfNqWfYX0SisXgaGvkBFK5k4EEDTtS7Q31XN3ei94VeQuI61k6unuRaB86CMExsYWnFt+imhRgmCMMWJmYWliTRJgrYIAzfJfUMSCK7hDdji3VQkkTjE9hMrsCmNheZy9gzEqlhndwlMoJ5NSqr+KCIfPuDUm+Uoz7+FEmkmIjg/Pcf/6EBAA==", Red: "data:image/webp;base64,UklGRhwBAABXRUJQVlA4TBABAAAvD8ADEL+hNJKkaOTJkycJn7CQJ5GjeXIgE4ZY/5Qq+HyMRJJyEvkR6K+IQwQk8qSRSFJWfgwkMZD0b0IC1KZtwDhl9h1Afx+SIEmAIEmChO+PwVWRpOsj2EgllBRDKy1EiJmhs5ztdaTnOAkEFBjQIGAdDiPJNq37bdu2nX9uDOGevQcR/SeQtNn+Aovh/vL2eF1FYR/cz9tNJKgHvf+4jseiYn59JAC38yqV8N57SDibw3OXzaQlyWKE3dPhtSzkshkiAttSHa4VLRXzqkqhogJIvVEjLbNWScIVeC3araaGoOqxeDk89z3rdphZzMITuF3mA/SJCFA2B9xPs9FkbKTsP8JcDtMhB7nQ747/CA==", Yellow: "data:image/webp;base64,UklGRv4AAABXRUJQVlA4TPEAAAAvD8ADEFeBppGkTMdJQAKSkI0MSsoTgAhDkW1sG3VEF0EER06Mtm1jWBi4/68cNBJJykpiIHFUQNK/CQlIOO+Lr4fmLsUtio7rgkBiUAjszusVxAQkHiEB8xAnXoQwz5sOM4QYHEaSbVrnWf8/21b+GX6GsBvRfwJBCHHADPlLlGQhM0Qfif18v7HTj9/3mI7z4onp8Wrkj+t2ANg4+pEgdYZ5WTdwmQcnFWRF2w8zAPZtkQnCik3bAWhZMRRQAVDVrEoFCAWZoamkApKakQlSV4f2BnBTQRSYxgcGkQDx0zLfWM+PYwLPNml7iH//+A8AAA==", onCreated(btn) { btn.setAttribute("image", this.icon); var doc = btn.ownerDocument; btn.domParent = null; btn.popups = new btn.ownerGlobal.Array(); this.createPopup(doc, btn, "secondary", secondary); btn.linkedObject = this; for(var type of ["contextmenu", "command"]) // "mousedown" "auxclick" события btn.setAttribute("on" + type, `linkedObject.${type}(event)`); this.addSheet(btn); }, addSheet(btn) { //текст под курсором var cb = Array.isArray(btn._destructors); var id = cb ? btn.id : "ToggleButton"; var css = `#${id} menu[_moz-menuactive] { color: ${I[0]} !important; }`; var args = [ "data:text/css;charset=utf-8," + encodeURIComponent(css), Ci.nsIDOMWindowUtils.USER_SHEET ]; if (cb) var destructor = function() { this.removeSheetUsingURIString(...args); } var add = b => b.ownerGlobal.windowUtils.loadSheetUsingURIString(...args); (this.addSheet = !cb ? add : btn => { add(btn); btn._destructors.push({destructor, context: btn.ownerGlobal.windowUtils}); })(btn); }, createPopup(doc, btn, name, data) { var popup = doc.createXULElement("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) { // pref if (!obj) return doc.createXULElement("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, hint, undef, code] = val; // строка меню pref.pref = apref; pref.lab = lab || apref; if (hint) { if (RegExp(/\p{L}/,'u').test(hint[0]) && (hint[0] === hint[0].toUpperCase())) hint = '\n'+ hint; pref.hint = hint; } if (undef) pref.undef = undef; //если не массив: undef || undef == "" if (code) pref.code = code; } 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`]; var map, set = prefs[`set${str}Pref`]; if (pref.hasVals) { for(var [val, , , , code] of obj.values) code && (map || (map = new Map())).set(val, code); if (map) pref.set = (key, val) => { set(key, val); map.has(val) && eval(map.get(val)); // выполнить код } } if (!map) pref.set = set; node = doc.createXULElement("menu"); node.className = "menu-iconic"; 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.createXULElement("menupopup")) ); if ("pDefGreen" in obj) pref.noAlt = !("pYellow" in obj); return node; }, regexpRefresh: /^(?:view-source:)?(?:https?|ftp)/, upd(node) { var {pref} = node, def = false, user = false, val; // если опция не найдена if (prefs.getPrefType(pref.pref) != prefs.PREF_INVALID) { try { val = pref.defVal = db[pref.get.name](pref.pref); def = true; // опция по-умолчанию получена } catch {def = false} user = prefs.prefHasUserValue(pref.pref); if (user) try {val = pref.get(pref.pref, undefined);} catch {} } if (val == pref.val && def == pref.def && user == pref.user) return; pref.val = val; pref.def = def; pref.user = user; var exists = def || user; if (!exists && pref.undef) // опция не найдена ? вернуть default-значение val = pref.undef[0]; var hint = eval(hints.get(pref.pref)); if (!hint) hint = val != undefined ? val : "Эта опция не указана"; if (hint === "") hint = "[ пустая строка ]"; hint += "\n" + pref.pref; if (pref.hint) hint += "\n" + pref.hint; node.tooltipText = hint; //+ текст var img, alt = "pYellow" in pref && val == pref.pYellow, pro = "pGray" in pref && val == pref.pGray; if (alt) img = this.Yellow; if (pro) img = this.Gray; if ("pDefGreen" in pref) if (val == pref.pDefGreen) node.style.removeProperty("color"), img = this.defGreen; else { node.style.setProperty("color", "#702020", "important"); if (!alt && !pro) img = this.Red; } node.setAttribute("image", img || this.Gray); // серый значок, если нет pDefGreen 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}`; } lab = exists ? lab : '['+ lab + `${"restart" in pref ? " ↯" : "refresh" in pref ? " ⟳" : ""}` +']'+ `${pref.undef ? " - "+ pref.undef[1] : ""}`; node.setAttribute("label", lab); // имя = [имя] если преф не существует }, createRadios(doc, vals, popup) { for(var arr of vals) { var [val, lab, key, hint] = arr; var menuitem = doc.createXULElement("menuitem"); with (menuitem) setAttribute("type","radio"), setAttribute("closemenu","none"), setAttribute("label", popup.parentNode.pref.vals[val] = lab), key && setAttribute("accesskey", key); var tip = menuitem.val = val === "" ? "[ пустая строка ]" : val; if (hint) tip += "\n" + hint; menuitem.tooltipText = `${tip != undefined ? tip + "\n\n" : ""}клик с Shift блокирует авто-закрытие`; popup.append(menuitem); } }, openPopup(popup) { var btn = popup.parentNode; if (btn.domParent != btn.parentNode) { btn.domParent = btn.parentNode; if (btn.matches(".widget-overflow-list > :scope")) var 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); }, 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.BrowserReloadSkipCache() : win.BrowserReload();} }, maybeClosePopup(e, trg) { (e.shiftKey || e.button == 1) || trg.parentNode.hidePopup(); }, 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 (!pref.val && pref.val != "" && pref.undef) pref.val = pref.undef[0]; // опции нет ? вернуть по-умолчанию 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;} } }, click(e, trg = e.target) { //строки меню if (e.button) return; var {pref} = trg; if (!pref) return; }, command(e, trg = e.target) { // LMB на кнопке var newVal = trg.val, menu = trg.closest("menu"); if (!menu) return; this.maybeClosePopup(e, menu); if (newVal != menu.pref.val) menu.pref.set(menu.pref.pref, newVal), this.maybeRe(menu, true); menu.pref.code && eval(menu.pref.code); //run }, contextmenu(e, trg = e.target) { if ("pref" in trg) { this.maybeClosePopup(e, trg); if (trg.pref.user) prefs.clearUserPref(trg.pref.pref), this.maybeRe(trg); var code = trg.pref.code; code && eval(code); //run } e.preventDefault(); } }; }); |
Dobrov > 20-11-2023 09:55:48 |
В скрипт ucf_hookClicks.js добавил меню команд пользователя, которое открывается по клику колёсиком на кнопке QuickToggle about:config или на любой другой кнопке, например: Теперь в одном скрипте есть меню пользователя, перехват нажатий клавиш, событий мыши, подсказки кнопок, меню настроек. |
_zt > 21-11-2023 16:09:50 |
Помню был скрипт для смены User-Agent для определенного сайта. Подскажите рабочий для 115 код или ссылку на код. |
_zt > 21-11-2023 21:13:17 |
egorsemenov06 |
unter_officer > 21-11-2023 22:07:08 |
Лично у меня он расположен в config.js. P.S. Там чуть ниже ещё маленькая правочка от Dumby есть. |
kokoss > 21-11-2023 22:16:12 |
_zt пишет
У меня подключён в custom_script_win после строки -> // Здесь может быть ваш код который сработает по событию "DOMContentLoaded" |
b0ttle > 21-11-2023 23:11:36 |
Dobrov |
Black_Monk > 22-11-2023 08:16:45 |
Подскажите как в 120 убрать иконки в Панели меню? У меня установлен последний Lepton и раньше я делал всё как в этом сообщении, но сейчас этот способ не проходит... |
Dobrov > 22-11-2023 11:02:51 |
Финальный вариант скрипта перехвата кликов-нажатий ucf_hookClicks.js — оптимизировал код и быстрые настройки. ucf_QuickToggle.js удалён и код перенесён в ucf_hookClicks.js (всё равно без него не работало), айдишник кнопки меню быстрых настроек изменён, менюшка команд вызывается кликом колёсика (все сочетания кликов мыши и горячие клавиши можно изменить). Cкрипт сохранения страниц SingleHTML.jsm немного улучшен. Black_Monk - вы ошиблись темой, в стилях надо спрашивать… |
b0ttle > 23-11-2023 07:32:58 |
Dobrov |
Dobrov > 23-11-2023 16:39:42 |
b0ttle - исправил. |
_zt > 23-11-2023 21:18:29 |
all |
b0ttle > 26-11-2023 16:22:09 |
Нельзя тут как-то добавить PanelUI-menu-button, чтобы он тоже мог переноситься? Пробовал, что-то не выходит. И что за кнопка alltabs-button, все время забываю? config.js Выделить код Код:// https://forum.mozilla-russia.org/viewtopic.php?pid=806232#p806232 806233#p806233 // установить для кнопок #alltabs-button и #unified-extensions-button атрибут "removable" как "true" (async topic => { var obs = doc => { doc.getElementById("alltabs-button")?.setAttribute("removable", true); doc.getElementById("unified-extensions-button")?.setAttribute("removable", true); doc.getElementById("PanelUI-menu-button")?.setAttribute("removable", true); } Services.obs.addObserver(obs, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(obs, topic); }, "quit-application-granted"); })("chrome-document-interactive"); upd: fuchsfan, a точно Спасибо. |
fuchsfan > 26-11-2023 17:56:56 |
b0ttle пишет
Видимо, это кропка справа сверху в виде стрелки вниз ˅, при клике на ней покажет список открытых табов. |
Dobrov > 28-11-2023 09:29:38 |
Скрипт перехвата кликов-нажатий ucf_hookClicks.js — небольшие добработки и устранение ошибок: 1) Вернул сочетания кнопок мыши на вкладках и кнопке «Новая вкладка» — описание во всплывающих подсказках. В ucf_hookClicks треть объёма занимают блоки данных, которые можно менять «под себя» |
b0ttle > 28-11-2023 15:32:28 |
Dobrov. Интересно сделано "настройки UCF", в плане тултипа. |
Dumby > 30-11-2023 11:56:36 |
Прошу прощения, я тут отсутствовал какое-то время. egorsemenov06 пишет
Конкретный цвет можно прямо в SVG'шке указать, там, где stroke А если надо чтобы context-properties подхватывались, скрытый текст Выделить код Код:/* bt.image = img; */ var subst = this.id + "-svg-image"; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(subst, Services.io.newURI(img)); var url = `resource://${subst}/`; (this.onCreated = btn => btn.image = url)(bt); b0ttle пишет
Эта кнопка не сама по себе, а в составе родительского <toolbaritem>'а, Можно попробовать регистрировать его как "custom" виджет, скрытый текст Выделить код Код:(async id => CustomizableUI.createWidget({ id, type: "custom", localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild(doc) { var item = doc.getElementById(id); item.setAttribute("removable", true); return item; } }))("PanelUI-button"); |
Dobrov > 30-11-2023 18:18:36 |
Скрипт ucf_hookClicks.js — изменил меню пользователя, чтобы проще подключать команды, устранил пару ошибок. обновлены скрипты: ucf_hookClicks.js ucf_mousedrag.js SingleHTML.jsm ClickPicSave.jsm и файлы профиля: prefs.js custom_styles_all_user.css userChrome.css userChrome_macosx.css |
iG0R > 02-12-2023 06:09:03 |
Dobrov |
iG0R > 02-12-2023 06:52:31 |
Dobrov Выделить код Код:pref: ["privacy.resistFingerprinting.block_mozAddonManager","Unblock addons.mozilla.org",,"Enables scripts & addons to run on the addons.mozilla.org page"], Def3el: true, refresh: true, keys: [[true, "Unblock"], [false, "Block (default)"]] он один в один повторяет "Выполнять скрипты Java" Выделить код Код:pref: ["javascript.enabled", "Выполнять скрипты Java",,"Поддержка интерактивных сайтов, рекламы\nтакже разрешает действия горячих клавиш"], Def3el: true, refresh: true, keys: [[true, "Да"], [false, "Нет"]] но у моего пункта, почему-то, стиль шрифта наклонный, в отличие пункта с обычным шрифтом у "Выполнять скрипты Java". |
b0ttle > 02-12-2023 13:16:20 |
iG0R custom_styles_all_user.css Выберите что-то одно. Подсмотреть id можно через Attributes-Inspector, судя по тому, что у вас ucf_hookClicks.js. Там идет отдельным файлом Attributes-Inspector.js, а код кнопка уже встроена в ucf_hookClicks.js. Есть способ без ничего, Ctrl+Alt+Shift+I > pick. Тема "настройка внешнего вида". Насчет другого, не в курсе. Может потом посмотрю. |
iG0R > 02-12-2023 13:23:57 |
b0ttle Просто хотелось бы, чтобы скрипты работали без всяких лишних дополнительных движений. |
b0ttle > 02-12-2023 13:36:58 |
iG0R. Так не бывает) Как это, без лишних движений? скрытый текст Выделить код Код:Setup = [ { pref: ["privacy.resistFingerprinting.block_mozAddonManager","Unblock addons.mozilla.org",,"Enables scripts & addons to run on the addons.mozilla.org page"], Def3el: true, refresh: true, keys: [[true, "Unblock"], [false, "Block (default)"]] },null, { // быстрые настройки. есть Def3el: несовпадения выделяются pref: ["dom.disable_open_during_load", "Всплывающие окна"], Def3el: true, Yellow: false, keys: [[true, "Блокировать"], [false, "Разрешить"]], |
Dobrov > 02-12-2023 13:46:37 |
iG0R пишет
Иконка зелёная или серая и шрифт обычный - значит опция в значении по-умолчанию, для вашей настройки это false. По двойному разделителю в менюшке поиска не знаю, у меня на разных профилях этого нет. |
Farby > 06-12-2023 16:33:30 |
Dumby, здравствуйте. |
Dumby > 07-12-2023 10:09:20 |
Farby пишет
В смысле присваивать как дату изменения? Я посмотрел как это сделано в S3, и, если правильно понял, В custom_script.js скрытый текст Выделить код Код:(async (url, ...cc) => { var re = /^.*\//; var f = Components.Constructor(...cc); var setLastModified = (file, date) => { if (file.exists()) file.lastModifiedTime = date; } var {Downloads} = ChromeUtils.importESModule(url); (await Downloads.getList(Downloads.ALL)).addView({ onDownloadChanged(download) { if (download.succeeded) try { var date = new Date(download.saver.entityID.replace(re, "")); +date && setTimeout(setLastModified, 2e3, f(download.target.path), date); } //catch(ex) {console.error(ex);} catch {} } }); })( "resource://gre/modules/Downloads.sys.mjs", "@mozilla.org/file/local;1", "nsIFile", "initWithPath" ); |
Farby > 07-12-2023 12:32:35 |
Dumby |
Dobrov > 07-12-2023 15:44:30 |
Сделал отдельный скрипт на основе кнопки от Dumby «Быстрые опции about:config»: (меньше оригинала + некоторые улучшения) Dumby, раз ты на связи, вот мои Хотелки и Проблемы к скрипту Быстрые опции: 2) надо, чтобы radio-строка подменю была выбрана (с флажком), если опция сброшена и отсутствует. 3) при клике по родительской строке меню открывать эту опцию в about:config – функция about_config прилагается. 4) оригинальная кнопка "Быстрое переключение опций about:config" содержала два контекстных меню. «Быстрые опции about:config» (не совместим с Custom Buttons) Выделить код Код:/* Быстрые настройки меню опций about:config. Колёсико, Лев+Shift не закрывать Опция изменена: курсив; Цвет = ключ, по-умолчанию серый, иначе Red есть Def3el: несовпадения выделяются красной обводкой текста refresh=true ⟳ перечитать без кэша, restart=false ↯ без запроса pref: pref,lab,key,hint,[val,str],code | keys:val,lab,dat,+hint,code | icon:значок предыдущее значение: menu.pref.val Новое: newVal и trg.val данные trg.label метка keys: */ (async id =>{ var {prefs} = Services, db = prefs.getDefaultBranch(""); Pref = (key, set)=>{ //или key = [key,default] if (!Array.isArray(key)) key = [key]; var t = prefs.getPrefType(key[0]), m = {b:"Bool",n:"Int",s:"String"}; t = m[t == 128 ? "b" : t == 64 ? "n" : t == 32 ? "s" : ""]; if (set == "get") return t; //тип опции if (!t) t = m[set != undefined ? (typeof set)[0] : (typeof key[1])[0]]; if (t) if (set != undefined) prefs[`set${t}Pref`](key[0],set) else set = prefs[`get${t}Pref`](...key); return set; } Icon = (c = '0c0')=>"data:image/svg+xml;charset=utf-8,<svg viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'><defs><linearGradient id='a' x1='16' x2='16' y1='32' gradientUnits='userSpaceOnUse'><stop stop-color='%23"+ c +"'/><stop stop-color='%23fff' offset='.8'/></linearGradient><linearGradient id='b' x2='32' y1='16' gradientTransform='matrix(1 0 0 1 2 2)'><stop stop-opacity='.5'/></linearGradient></defs><circle cx='16' cy='16' r='15' fill='url(%23a)' stroke='url(%23b)' stroke-width='2'/></svg>"; about_config = (filter) => { //на опцию if (gURLBar.value.startsWith("about:config")) switchTab(gURLBar.value); var setFilter = (e,input = (e?.target || window.content.document).getElementById("about-config-search")) => { try { if (e || input.value != filter) input.setUserInput(filter);} catch{} }, found = window.switchToTabHavingURI("about:config",true, {relatedToCurrent: true, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); if (found) setFilter(null,window); else gBrowser.selectedBrowser.addEventListener("pageshow",setFilter, {once: true}); }; ua = (real = false, ua_my = "general.useragent.override")=>{ //текущий или вшитый ЮзерАгент ttt = Pref(ua_my); prefs.clearUserPref(ua_my); ua = Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).userAgent; //костыль ttt && Pref(ua_my, ttt); ttt ||= ua; if (real) ttt = ua; return ttt; } switchTab = (url = 'about:config', go)=>{ //открыть вкладку | закрыть её | выбрать for(var tab of gBrowser.visibleTabs) if (tab.linkedBrowser.currentURI.spec == url) {go ? gBrowser.selectedTab = tab : gBrowser.removeTab(tab); return;} gBrowser.addTrustedTab(url); gBrowser.selectedTab = gBrowser.visibleTabs[gBrowser.visibleTabs.length -1]; } var uar = ua(true), //real ЮзерАгент fonts = arr => arr.map(n => [(n == arr[arr.length-1] ? null : n), n]), //array с вложениями serif = fonts("Arial|Roboto|Cantarell|Segoe UI|Cambria|Calibri".split('|')), sans = [["Times","Times"], ...serif], hints = new Map([ //опция отсутствует ? вернуть строку ["general.useragent.override", "UserAgent"]]); UserMenu = { //массив команд пользователя, alt() клик правой кнопкой "Настройки профайлера": { cmd(){switchTab('about:profiling')} }, DwDir: {lab: `папка Загрузки`, cmd(){ Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(),Cu.reportError)}, img: "chrome://devtools/skin/images/folder.svg" }, } AboutCfg = [{ pref: ["dom.disable_open_during_load", "Всплывающие окна"], Def3el: true, Yellow: false, keys: [[true, "Блокировать"], [false, "Разрешить"]], },null,{ pref: ["extensions.user_chrome_files.savedirs", "Загрузки",,'Пути сохранения Страниц и Графики\nСинтаксис «_Html/subdir|_Pics/subdir»\nsubdir: пусто | 0 заголовок | 1 домен', ["", "всё в общей папке"]], Blue: "_Web|1|_Images|0", Gray: "", keys: [ ["_Сайты||_Фото|0", "_Сайты|_Фото/имя…"], ["_Web|1|_Images|0", "_Web/сайт|_Images/имя"], ["Сайт||Фото|", "ваши данные…",,"ключ в about:config", `console.log("введите ваши данные…")`]] },{ pref: ["general.useragent.override", "User Agent",,"Изменяет вид сайта", [uar,"встроенный"]], refresh: true, Def3el: uar, keys: [ ["Windows", "ваши данные…",,,`console.log("введите ваши данные…")`], ["Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36", "Chrome 118 Win10"], ["Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12 Version/12.16", "Opera12 W8"], ["Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)", "GoogleBot"], [uar, "по-умолчанию"]] //родной ЮзерАгент }]; CustomizableUI.createWidget({ defaultArea: CustomizableUI.AREA_NAVBAR, label: "Журнал, Меню опций", localized: false, id: id, onCreated(btn) { btn.setAttribute("image", "chrome://devtools/skin/images/settings.svg"); var doc = btn.ownerDocument, m = nn => doc.createXULElement(nn); btn.domParent = null; btn.popups = new btn.ownerGlobal.Array(); this.createPopup(doc, btn, "config", AboutCfg); btn.linkedObject = this; for(var type of ["contextmenu", "command"]) btn.setAttribute("on"+ type, `linkedObject.${type}(event)`); var popup = m("menupopup"), menu = m("menuitem"); menu.m = m; menu.fill = this.fill; menu.render = this.render; popup.append(menu); btn.prepend(popup); }, render(){ var popup = this.parentNode; this.remove(); this.fill(UserMenu, popup); }, fill(o, popup){if (typeof o == "object") for (key in o){ var {lab, sep, sub, cmd, alt, inf, img} = o[key]; var name = sub ? "menu" : "menuitem"; sep && popup.append(this.m("menuseparator")); var item = this.m(name); item.setAttribute("label", lab || key); if (img) item.className = name +"-iconic", item.setAttribute("image",img); if (inf) item.tooltipText = inf; item.alt = alt; //cmd2 sub || cmd && item.setAttribute("oncommand", cmd.toString().replace(/cmd\(.*?\)/,'')); /^(sub|sep|inf|lab|img)$/.test(key) || popup.append(item); sub && this.fill(o[key], item.appendChild(this.m("menupopup"))); }}, createPopup(doc, btn, prop, data) { var popup = doc.createXULElement("menupopup"); btn.popups.push(btn[prop] = popup); popup.id = this.id +"-"+ prop; for (var type of ["popupshowing"]) popup.setAttribute("on"+ type, `parentNode.linkedObject.${type}(event)`); for(var obj of data) popup.append(this.createElement(doc, obj)); btn.append(popup); }, createElement(doc, obj) { //pref if (!obj) return doc.createXULElement("menuseparator"); var pref = doc.ownerGlobal.Object.create(null), node, bool, img; for(var [key, val] of Object.entries(obj)) { if (key == "pref") { var [apref, lab, akey, hint, undef, code] = val; //строка меню pref.pref = apref; pref.lab = lab || apref; if (hint) { if (RegExp(/\p{L}/,'u').test(hint[0]) && (hint[0] === hint[0].toUpperCase())) hint = '\n'+ hint; pref.hint = hint; } if (undef) pref.undef = undef; //если не массив: undef || undef == "" if (code) pref.code = code; } else if (key == "icon") img = val, pref.img = true; else if (key != "keys") pref[key] = val; else pref.hasVals = true; } var t = prefs.getPrefType(pref.pref), m = {b: "Bool", n: "Int", s: "String"}; var str = m[t == prefs.PREF_INVALID ? obj.keys ? (typeof obj.keys[0][0])[0] : "b" : t == prefs.PREF_BOOL ? "b" : t == prefs.PREF_INT ? "n" : "s"]; //String по-умолчанию pref.get = prefs[`get${str}Pref`]; var map, set = prefs[`set${str}Pref`]; if (pref.hasVals) { for(var [val,,,,code] of obj.keys) code && (map || (map = new Map())).set(val, code); if (map) pref.set = (key, val) => { set(key, val); map.has(val) && eval(map.get(val)); //код2 если pref изменён } } if (!map) pref.set = set; node = doc.createXULElement("menu"); node.className = "menu-iconic"; 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.keys, node.appendChild(doc.createXULElement("menupopup")) ); if ("Def3el" in obj) pref.noAlt = !("Yellow" in obj); return node; }, createRadios(doc, vals, popup) { for(var arr of vals) { var [val, lab, key, hint] = arr; var menuitem = doc.createXULElement("menuitem"); with (menuitem) setAttribute("type","radio"), setAttribute("closemenu","none"), setAttribute("label", popup.parentNode.pref.vals[val] = lab), key && setAttribute("accesskey", key); var tip = menuitem.val = val === "" ? "[ пустая строка ]" : val; if (hint) tip += "\n" + hint; menuitem.tooltipText = `${tip != undefined ? tip + "\n\n" : ""}клик с Shift блокирует авто-закрытие`; popup.append(menuitem); } }, regexpRefresh: /^(?:view-source:)?(?:https?|ftp)/, upd(node) { var {pref} = node, def = false, user = false, val; //если опция не найдена if (prefs.getPrefType(pref.pref) != prefs.PREF_INVALID) { try { val = pref.defVal = db[pref.get.name](pref.pref); def = true; //опция по-умолчанию получена } catch {def = false} user = prefs.prefHasUserValue(pref.pref); if (user) try {val = pref.get(pref.pref, undefined);} catch {} } if (val == pref.val && def == pref.def && user == pref.user) return; pref.val = val; pref.def = def; pref.user = user; var exists = def || user; if (!exists && pref.undef) //опции нет ? вернуть default val = pref.undef[0]; var hint = hints.get(pref.pref); hint ||= val != undefined ? val : "Эта опция не указана"; if (hint === "") hint = "[ пустая строка ]"; hint += "\n" + pref.pref; if (pref.hint) hint += "\n"+ pref.hint; node.tooltipText = hint; //+ текст var img = Icon("999"), alt = "Yellow" in pref && val == pref.Yellow, clr = "Gray" in pref && val == pref.Gray, blu = "Blue" in pref && val == pref.Blue; if (blu) img = Icon("a0f"); if (alt) img = Icon("f80"); if ("Def3el" in pref) if (val == pref.Def3el) img = Icon(), node.style.removeProperty('filter'); else if (val != pref.defVal) { if (!alt && !clr && !blu) img = Icon("f26"); // Red node.style.filter = "drop-shadow(1px 1px 1px #B8F)"; } pref.img || node.setAttribute("image", img); //нет Def3el ? серый 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}`; } lab = exists ? lab : '['+ lab + `${"restart" in pref ? " ↯" : "refresh" in pref ? " ⟳" : ""}` +']'+ `${pref.undef ? " - "+ pref.undef[1] : ""}`; node.setAttribute("label", lab); //имя = [имя] если преф не существует }, openPopup(popup) { var btn = popup.parentNode; if (btn.domParent != btn.parentNode) { btn.domParent = btn.parentNode; if (btn.matches(".widget-overflow-list > :scope")) var 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); }, 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.BrowserReloadSkipCache() : win.BrowserReload();} }, maybeClosePopup(e, trg) { (e.shiftKey || e.button == 1) || trg.parentNode.hidePopup(); }, 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 (!pref.val && pref.val != "" && pref.undef) pref.val = pref.undef[0]; //опции нет ? вернуть default 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; } } }, command(e, trg = e.target) { //LMB if (trg.id == id) { if (trg.config.state != "open") trg.menupopup.openPopup(trg, "after_start") else console.log("Здесь нужен переход на опцию about:config"); return; } var menu = trg.closest("menu"), newVal = trg.val; if (!menu || !menu.pref) return; this.maybeClosePopup(e, menu); menu.pref.code && eval(menu.pref.code); //run1 if (newVal != menu.pref.val) menu.pref.set(menu.pref.pref, newVal), this.maybeRe(menu, true); }, contextmenu(e, trg = e.target) { //RMB if ((trg.id == id) && (!e.ctrlKey && !e.altKey && !e.shiftKey)) if (trg.config.state != "open") this.openPopup(trg.config); else trg.config.hidePopup(); else if ("pref" in trg) { this.maybeClosePopup(e, trg); if (trg.pref.user) prefs.clearUserPref(trg.pref.pref), this.maybeRe(trg); trg.pref.code && eval(trg.pref.code); //run } e.preventDefault(); } }); })("ucf_AboutConfig"); |
Dumby > 10-12-2023 19:48:49 |
Dobrov пишет
Попробовал это записать, но как-бы слегка снаружи. Врезка в createRadios() перед строкой popup.append(menuitem); дополнительный стафф в объект скрытый текст Выделить код Код:// asInput(menuitem, val) { menuitem.ttsfx = (menuitem.ittt = menuitem.tooltipText) .slice(String(menuitem.ival = val).length); menuitem.linkedObject = this; menuitem.setAttribute("oncommand", "linkedObject.input(event)"); menuitem.render = this.renderInputOnce; }, input(e) { e.stopImmediatePropagation(); var trg = e.target, {pref} = trg.parentNode.parentNode; var res = {value: trg.tt ? pref.val : trg.ival}; if (Services.prompt.prompt( null, `Введите значение (${pref.isInt ? "целое" : "строка"})`, pref.pref, res, null, {} )) { if (pref.isInt) { // from old about:config var val = res.value | 0; if (val != res.value - 0) return Services.prompt.alert( null, "Недействительное значение", "Введённый вами текст не является числом." ); } else val = res.value; pref.set(pref.pref, val); } }, renderInputOnce() { delete this.render; this.render(); var {pref} = this.parentNode.parentNode; pref.isInt = pref.get.name[3] == "I"; if (!("val" in pref)) try {pref.val = pref.get(pref.pref);} catch {} this.linkedObject.hookUncheck(this); // for Shif+Click outside (this.render = this.linkedObject.renderInput).call(this); }, hookUncheck(menuitem) { var rtt = function() { this.tt = false; this.tooltipText = this.ittt; } var desc = {configurable: true, enumerable: true, value(attr) { this.ownerGlobal.Element.prototype.removeAttribute.call(this, attr); attr.startsWith("c") && this.popup.state.startsWith("o") && this.parentNode.rtt(); }}; (this.hookUncheck = menuitem => { menuitem.rtt = rtt; var box = menuitem.firstChild; box.popup = menuitem.parentNode; menuitem.ownerGlobal.Object.defineProperty(box, "removeAttribute", desc); })(menuitem); }, get renderInput() { delete this.renderInput; return this.renderInput = Cu.getGlobalForObject(Cu).eval(`(${async function() { await new Promise(this.ownerGlobal.requestAnimationFrame); var popup = this.parentNode, menu = popup.parentNode; menu.hasAttribute("_moz-menuactive") || this.linkedObject.popupshowing(null, popup, false); // force var checked = popup.querySelector("[checked]"); var {pref} = menu, checkedThis = checked == this; if (checked && !checkedThis || !pref.user) return this.tt && this.rtt(); this.tt = true; this.tooltipText = pref.val + this.ttsfx; if (checkedThis) return; menu.label = menu.label.replace(/другое$/, this.label); this.setAttribute("checked", true); }})`); }, и чуть модифицировать popupshowing() чтобы была возможность пропустить проверку state скрытый текст Выделить код Код:/* popupshowing(e, trg = e.target) { if (trg.state == "closed") return; */ popupshowing(e, trg = e.target, checkstate = true) { if (checkstate && trg.state == "closed") return;
Не понял. Какая radio-строка остаётся не выбранной? Вот для extensions.user_chrome_files.savedirs есть pref.undef И, даже если бы подходящая radio-строка была,
У себя вижу, что на кликнутое ссылается e.explicitOriginalTarget
Да нет, особо попроще код не станет. В popupshowing здесь менять нечего, скрытый текст Выделить код Код:.... //btn.popups = new btn.ownerGlobal.Array(); .... //btn.popups.push(btn[prop] = popup); btn[prop] = popup; .... //for(var p of btn.popups) p.setAttribute("position", pos); btn.config.setAttribute("position", pos);
Я добавил запятую как написано, и у меня всё работает. А вот если перед ua добавить var |
b0ttle > 15-12-2023 17:46:47 |
Можно в ucf_aom-button.js как-то добавить функцию, как у unified_extensions_button, чтобы при клике вылазило окно, не настройки? Можно эти дополнения с меню, отдельно выделять используя тот шарик с цветом. Во, или на ПКМ посадить unified_extensions_button, а саму кнопку скрыть. |
Dobrov > 16-12-2023 05:48:28 |
b0ttle пишет
Не понял, нужен скриншот или подробные разьяснения. b0ttle пишет
Вообще-то удобнее иконку скрипта ucf_aom-button.js убрать, а на правый клик unified_extensions_button назначить меню управления расширениями от ucf_aom-button (но не разбирался, как в этом скрипте привязать клики по меню, открытому из другой кнопки). |
b0ttle > 16-12-2023 12:15:14 |
|
b0ttle > 16-12-2023 15:37:58 |
|
Dobrov > 17-12-2023 19:00:50 |
b0ttle пишет
Нет, менюшки расширений не рассматриваются, и я не проверял их открытие над другой кнопкой, если кнопка расширения не закреплена на панели инструментов. |
Dobrov > 31-12-2023 13:27:12 |
Обновил скрипта перехвата кликов-нажатий ucf_hookClicks.js — исправил ошибки несрабатывания некоторых команд пользовательского меню по клику из кнопок. Cкрипт сохранения страниц SingleHTML.jsm исправлена связка Путь сохранения <-> установка пути из Опций быстрых настроек. Всех с наступающим праздником! |
Northtech > 31-12-2023 15:23:29 |
Dobrov |
b0ttle > 31-12-2023 16:19:51 |
Northtech |
Northtech > 31-12-2023 19:37:43 |
b0ttle
Всех с праздником, наступившим и наступающим! |
Dobrov > 31-12-2023 22:03:49 |
Northtech пишет
Попробуй включить "Кнопки управления окна" в диалоге "Настройки UserChromeFiles" |
xrun1 > 19-02-2024 15:40:28 |
egorsemenov06 |
Farby > 19-02-2024 17:32:09 |
egorsemenov06 Browser search engine Выделить код Код:// ==UserScript== // @name Browser search engine // @author Vitaliy V. // @include main // @shutdown window.contextsearch.destructor(); // @note https://forum.mozilla-russia.org/viewtopic.php?pid=780283#p780283 // ==/UserScript== (this.contextsearch = { topic: "browser-search-engine-modified", hide: "browser.search.hiddenOneOffs", defaultImg: "chrome://browser/skin/search-engine-placeholder.png", searchSelect: null, popup: null, init(that) { var searchSelect = this.searchSelect = document.querySelector("#context-searchselect"); if (!searchSelect) return; var popup = this.popup = searchSelect.closest("menupopup"); popup.addEventListener("popupshowing", this); that.unloadlisteners?.push("contextsearch"); }, destructor() { this.popup.removeEventListener("popupshowing", this); if (this.popupshowing == this.handler) { this.popup.removeEventListener("popuphidden", this); Services.obs.removeObserver(this, this.topic); Services.prefs.removeObserver(this.hide, this); } }, handleEvent(e) { this[e.type](e); }, popupshowing(e) { var popup = this.popup; var searchSelect = this.searchSelect; if (e.target != popup || searchSelect.hidden) return; var menu = document.createXULElement("menu"); menu.className = "menu-iconic"; var menupopup = document.createXULElement("menupopup"); menu.append(menupopup); menu.ePopup = menupopup; searchSelect.style.setProperty("display", "none", "important"); searchSelect.before(menu); menu.onclick = this.search.bind(this); this.handler = e => e.target != popup || (menu.hidden = searchSelect.hidden); this.handlerRebuild = e => this.handler(e) || this.rebuild(menu); this.popuphidden = ev => { if (ev.target != popup) return; menu.hidden = true; }; this.popup.addEventListener("popuphidden", this); this.rebuild(menu); }, getEngines() { var args = "hideOneOffButton" in Services.search.defaultEngine ? [e => !e.hideOneOffButton] : Object.defineProperty( [function(e) {return !this.includes(e.name);}], "1", { get: () => Services.prefs.getStringPref(this.hide)?.split(",") || [] } ); return (this.getEngines = async () => (await Services.search.getVisibleEngines()).filter(...args) )(); }, async rebuild(menu) { var de = Services.search.defaultEngine; de = de.wrappedJSObject || de; this.setAttrs(menu, de, `Искать в ${de.name} или в ...`); menu.ePopup.textContent = ""; for(let engine of await this.getEngines()) { if (engine == de) continue; var menuitem = document.createXULElement("menuitem"); menuitem.className = "menuitem-iconic"; this.setAttrs(menuitem, engine); menu.ePopup.append(menuitem); } this.popupshowing = this.handler; Services.obs.addObserver(this, this.topic, false); Services.prefs.addObserver(this.hide, this); }, setAttrs(node, engine, label = engine.name) { node.engine = engine; node.setAttribute("label", label); node.setAttribute("image", engine._iconURI ? engine._iconURI.spec : engine.iconURI ? engine.iconURI.spec : this.defaultImg); }, observe() { this.popupshowing = this.handlerRebuild; Services.obs.removeObserver(this, this.topic); Services.prefs.removeObserver(this.hide, this); }, search(e) { var {engine} = e.target; if (!engine) return; var searchSelect = this.searchSelect; var submission = engine.getSubmission( searchSelect.searchTerms, null, "contextmenu" ); if (submission) { let tab = gBrowser.addTab(submission.uri.spec, { postData: submission.postData, index: (gBrowser.selectedTab._tPos + 1), triggeringPrincipal: searchSelect.principal }); if (e.button == 0) gBrowser.selectedTab = tab; } var popup = this.popup; e.button != 1 && popup.state == "open" && popup.hidePopup(); } }).init(this); |
Dumby > 19-02-2024 19:18:10 |
egorsemenov06 пишет
Это баг 1872673 - Remove 'console' export from Console.sys.mjs Но держать отладочный консольский стафф в кнопке постоянно Однако, вернуть в укфский сандбокс консоль не помешает. скрытый текст Выделить код Код:/* if ("defineLazyModuleGetters" in XPCOMUtils) XPCOMUtils.defineLazyModuleGetters(scope, { console: "resource://gre/modules/Console.jsm", AddonManager: "resource://gre/modules/AddonManager.jsm", AppConstants: "resource://gre/modules/AppConstants.jsm", E10SUtils: "resource://gre/modules/E10SUtils.jsm", FileUtils: "resource://gre/modules/FileUtils.jsm", OS: "resource://gre/modules/osfile.jsm", PlacesUtils: "resource://gre/modules/PlacesUtils.jsm", setTimeout: "resource://gre/modules/Timer.jsm", setTimeoutWithTarget: "resource://gre/modules/Timer.jsm", clearTimeout: "resource://gre/modules/Timer.jsm", setInterval: "resource://gre/modules/Timer.jsm", setIntervalWithTarget: "resource://gre/modules/Timer.jsm", clearInterval: "resource://gre/modules/Timer.jsm", }); */ var data = { AddonManager: null, AppConstants: null, E10SUtils: null, FileUtils: null, PlacesUtils: null, Timer: ["setTimeout", "setTimeoutWithTarget", "clearTimeout", "setInterval", "setIntervalWithTarget", "clearInterval"] }; var sfx, def, modules = {}; var vers = parseInt(Services.appinfo.platformVersion); if (vers <= 114) data.osfile = "OS"; if (vers <= 122) def = XPCOMUtils.defineLazyModuleGetters, sfx = "jsm", data.Console = "console"; else def = ChromeUtils.defineESModuleGetters, sfx = "sys.mjs", ChromeUtils.defineLazyGetter(scope, "console", () => Cu.getGlobalForObject(Cu).console.createInstance()); var set = (key, val) => modules[key] = `resource://gre/modules/${val}.${sfx}`; for(var key in data) { var val = data[key] || key; if (Array.isArray(val)) for(var str of val) set(str, key); else set(val, key); } def(scope, modules); |
b0ttle > 19-02-2024 21:43:04 |
В шапке бы поправить ссылку на рабочую - "Восстановить фавиконки закладок". |
Farby > 19-02-2024 22:12:42 |
b0ttle пишет
На этом форуме нет шапок, есть только первый пост, посему это могут сделать либо создатель либо модератор... b0ttle пишет
Если у вас все работает, b0ttle пишет
пользуйтесь... Речь шла про 1945 год, ой про 123 найди различия... |
b0ttle > 19-02-2024 23:25:44 |
Farby |
Dobrov > 25-02-2024 06:52:58 |
b0ttle пишет
Раз это не в скрипте проблема, шапку пока не менял. Dumby пишет
Dumby - Благодарю! |
b0ttle > 25-02-2024 12:00:42 |
Dobrov. Ура, ждал обновы) |
Dumby > 26-02-2024 08:26:11 |
Dobrov пишет
Кстати, скрипт под багом ходит (1552815).
А вот и баг о временах и сроках. Может завести какую-нибудь папку с любым условным названием типа «129». Это я в том смысле, что время пока есть, |
Dobrov > 27-02-2024 15:22:40 |
Dumby пишет
когда JSM уберут, то UCF практически перестанет работать! |
Farby > 27-02-2024 16:19:42 |
Dobrov пишет
там нечего сложного глаза бояться, руки делают, здесь Dumby писал как... |
Northtech > 28-02-2024 12:36:01 |
Dobrov |
Dobrov > 29-02-2024 01:50:06 |
Northtech пишет
Поиск и так открывается в фоновой вкладке по клику правой кнопкой или колёсиком на любых строках меню и подменю. |
xrun1 > 29-02-2024 05:12:23 |
egorsemenov06 |
Dobrov > 29-02-2024 06:06:58 |
Dumby возникла хотелка для менюшки кнопки, которую я немного доработал. это меню создаётся однократно и перед кликом на кнопке его не существует, т.е. однократно выполняется menu.render = this.render; Прошу доработать код, чтоб ключи «lab» могли быть с backticks-кавычками и текст мог обновляться перед каждым открытием меню: Автономное меню для тех, кому не нужен ucf_hookClicks.js Выделить код Код:(async id => { // by Dumby forum.mozilla-russia.org/viewtopic.php?pid=807581#p807581 MyMenu = { //массив команд пользователя, alt() клик правой кнопкой Pics: { lab: `Графика сайтов вкл/выкл | Right Click`, inf: 'текст обновляется перед открытием меню', cmd(){ var n = uc.pref(E.v) == 2; uc.pref(E.v, n ? 1 : 2); BrowserReload(); }, alt(){ /* для этих действий нужен ucf_hookClicks.js */}, }, "Прочие команды": { sep: 1, //сперва разделитель cmd(){console.log("OK");} }, } CustomizableUI.createWidget({ id: id, label: id, tooltiptext: id, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.style.setProperty("list-style-image", "url(chrome://branding/content/icon32.png)"); btn.type = "menu"; var doc = btn.ownerDocument, m = nn => doc.createXULElement(nn); var popup = m("menupopup"), menu = m("menuitem"); menu.m = m; menu.fill = this.fill; menu.render = this.render; popup.append(menu); btn.prepend(popup); }, render(){ var popup = this.parentNode; this.remove(); this.fill(MyMenu, popup); }, fill(o, popup){ if (typeof o == "object") for (key in o){ var {lab, sep, sub, cmd, alt, inf, img} = o[key]; var name = sub ? "menu" : "menuitem"; sep && popup.append(this.m("menuseparator")); var item = this.m(name); item.setAttribute("label", lab || key); //update при изменении настроек if (img) item.className = name +"-iconic", item.setAttribute("image",img); if (inf) item.tooltipText = inf; item.alt = alt; //cmd2 sub || cmd && item.setAttribute("oncommand", cmd.toString().replace(/cmd\(.*?\){/,'{var trg = event.target || event;')); /^(sub|sep|inf|lab|img)$/.test(key) || popup.append(item); sub && this.fill(o[key], item.appendChild(this.m("menupopup"))); } }, }); E = { v: "permissions.default.image" } window.uc = { //all ChromeOnly-scripts pref(key,set){ //или key = [key,default] if (!Array.isArray(key)) key = [key]; var t = prefs.getPrefType(key[0]), m = {b:"Bool",n:"Int",s:"String"}; t = m[t == 128 ? "b" : t == 64 ? "n" : t == 32 ? "s" : ""]; if (set == "get") return t; //тип опции if (!t) t = m[set != undefined ? (typeof set)[0] : (typeof key[1])[0]]; if (t) if (set != undefined) prefs[`set${t}Pref`](key[0],set) else set = prefs[`get${t}Pref`](...key); return set; } } })("ucf_test_menu"); xrun1 я просто останусь на старой версии браузера, как это делает Dumby (у него вроде FF78) |
Dumby > 29-02-2024 15:21:27 |
egorsemenov06 пишет
Здесь можно переделать. Переименовать UcfTextToLinkActorChild.{ jsm —> mjs } и правки скрытый текст В text-to-link.js Выделить код Код:/* moduleURI: "chrome://user_chrome_files/content/custom_scripts/UcfTextToLinkActorChild.jsm", */ esModuleURI: "chrome://user_chrome_files/content/custom_scripts/UcfTextToLinkActorChild.mjs" В UcfTextToLinkActorChild.mjs Выделить код Код:/* var EXPORTED_SYMBOLS = ["UcfTextToLinkActorChild"]; var {XPCOMUtils} = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyGlobalGetters(this, ["NodeFilter", "Node"]); XPCOMUtils.defineLazyGetter(this, "excludedTags", () => { return 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"]); }); class UcfTextToLinkActorChild extends JSWindowActorChild { */ var excludedTags = Object.defineProperty({}, "has", { value: tag => (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" ])).has(tag) }); export class UcfTextToLinkActorChild extends JSWindowActorChild {
Для этого кода нужен дебаггер. Но, наверно, можно пробросить implementation из кода само́й кнопки,
Этот скрипт — часть UCF.
Здесь можно попробовать влепить что-нибудь такое, скрытый текст Выделить код Код:/* try { */ 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 { Dobrov пишет
Ничего себе «немного». Как там задумана обработка Ну хорошо хоть вопрос не об этом. Можно ввести ещё один ключ — upd Ключевое слово this в этой функции будет ссылаться на сам item. upd() { Далее, учитываем новый ключ в var {lab, sep, sub, cmd, alt, inf, img, upd} = o[key]; Однако, хоть lab и убран, код тогда всё равно проставляет вместо него label — key, |
Dobrov > 29-02-2024 15:59:36 |
Dumby пишет
Спасибо за помошь! |
Dumby > 01-03-2024 16:45:40 |
Dobrov пишет
Да, теперь чуть понятнее, наверно. Оказывается, что если вписан sub, код прогоняет через for in Если значение ключа окажется строкой, то тогда создаётся не <menuitem>, Эти ненужные элементы можно посмотреть в консоли, Вот чтобы всё это низачем-созданное добро скрытый текст Выделить код Код:// fill(o, popup) { for (key in o) { var val = o[key]; if (typeof val != "object") continue; var {lab, sep, sub, cmd, alt, inf, img, upd} = val; sep && popup.append(this.m("menuseparator")); var name = sub ? "menu" : "menuitem"; var item = this.m(name); item.setAttribute("label", lab || key); if (img) item.className = name + "-iconic", item.setAttribute("image", img); item.alt = alt; //cmd2 if (inf) item.tooltipText = inf; sub || cmd && item.setAttribute("oncommand", cmd.toString().replace( /cmd\(.*?\){/, "{var trg = event.target || event;" )); popup.append(item); upd && (item.render = upd).call(item); sub && this.fill(val, item.appendChild(this.m("menupopup"))); } }, egorsemenov06 пишет
скрытый текст Выделить код Код:// Switch Keyboard Layout (async keybUtils => CustomizableUI.createWidget(({ localized: false, id: "SwitchKeyboardLayout", init() { this.label = this.tooltiptext = "Switch Keyboard Layout"; var args = ["keydown", e => { if (e.key != "F8" || e.ctrlKey || e.shiftKey || e.altKey || e.repeat) return; //e.preventDefault(); //e.stopPropagation(); this.switch(e.view.document); }, true]; var unload = e => e.target.ownerGlobal.removeEventListener(...args); var obs = win => { win.addEventListener(...args); win.addEventListener("unload", unload, {once: true}); } var topic = "browser-delayed-startup-finished"; Services.obs.addObserver(obs, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(quit, t); Services.obs.removeObserver(obs, topic); }, "quit-application-granted"); return this; }, onCreated(btn) { btn.linkedObj = this; btn._handleClick = this.click; btn.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAk1BMVEX///8/Pz8BAQF8fHwJCQkCAgIJCQl8fHx9fX0AAABJSUkBAQENDQ0wMDBVVVUAAABra2t0dHR7e3thYWEBAQEAAAAAAAABAQEAAAAgICABAQEBAQH8/Pzw8PDp6en39/fj4+Pe3t41V9I/YeWKioqDg4N9fX0jRa8wUrVoaGhkhuxWeNx1dXVCZMhvb28kRqsqTL4KidXxAAAAHHRSTlMAAABndwAAAAA0blVZcm1naWhNa6hrcJ8AAKRU4jk/3gAAAHVJREFUeF6FyMUCwjAUBdEbaQupUMOjqMv/fx1dQN6yZ3aDcWnyw6ezoRWNYc15kqKQZCFlgTKQQwgllL/dn5f3+bPb+6P3CpWNw56srdCZOMzDmA61i8O9nKvRaHLVukEryFKIFtnkj7ENYxmNdd5v+5xj1BcJ/w9Kj6K7ZAAAAABJRU5ErkJggg=="; }, click() { this.linkedObj.switch(this.ownerDocument); }, switch(doc) { var br = doc.activeElement; br && br.localName == "browser" && br.isRemoteBrowser ? br.messageManager.loadFrameScript(this.url, false) : this.keybUtils.switchSelKeybLayout(); }, get url() { delete this.url; return this.url = `data:;charset=utf-8,(${ encodeURIComponent(keybUtils) }).switchSelKeybLayout()`; }, get keybUtils() { delete this.keybUtils; var def = "let{KeyEvent,HTMLInputElement,HTMLTextAreaElement}=Cu.getGlobalForObject(Services);"; var url = `data:;charset=utf-8,${def}%0Athis.keybUtils=${encodeURIComponent(keybUtils)}`; Services.scriptloader.loadSubScript(url, this); var {id} = this; this.keybUtils.getFocusedElement = function(_subCall, _focusFixed) { var window = Services.focus.activeWindow, {document} = window; var button = document.getElementById(id); if( !_focusFixed && "closeMenus" in window && document.commandDispatcher.focusedElement == button ) { window.closeMenus(button); window.setTimeout(function(_this) { _this.switchSelKeybLayout(_subCall, true); }, 0, this); return; } return document.commandDispatcher.focusedElement; } return this.keybUtils; } }).init()))(`{ //== Options noSelBehavior: "BeginLine", //"EndLine", //"All", //"Top", //"Bottom", //"PageUp", //"PageDown", // etc // falsy - do nothing // Or use string like following to call cmd_select{string} convTableForward: { // ru -> en "\\"": "@", ":": "^", ";": "$", "?": "&", ",": "?", "/": "|", ".": "/", "э": "'", "б": ",", "ю": ".", "Ж": ":", "ж": ";", "Б": "<", "Ю": ">", "Э": "\\"", "х": "[", "ъ": "]", "ё": "\`", "Х": "{", "Ъ": "}", "Ё": "~", "№": "#", "Ф": "A", "ф": "a", "И": "B", "и": "b", "С": "C", "с": "c", "В": "D", "в": "d", "У": "E", "у": "e", "А": "F", "а": "f", "П": "G", "п": "g", "Р": "H", "р": "h", "Ш": "I", "ш": "i", "О": "J", "о": "j", "Л": "K", "л": "k", "Д": "L", "д": "l", "Ь": "M", "ь": "m", "Т": "N", "т": "n", "Щ": "O", "щ": "o", "З": "P", "з": "p", "Й": "Q", "й": "q", "К": "R", "к": "r", "Ы": "S", "ы": "s", "Е": "T", "е": "t", "Г": "U", "г": "u", "М": "V", "м": "v", "Ц": "W", "ц": "w", "Ч": "X", "ч": "x", "Н": "Y", "н": "y", "Я": "Z", "я": "z", __proto__: null }, //== End of options get convTableBackward() { var ctb = { __proto__: null }; var ctf = this.convTableForward; for(var c in ctf) ctb[ctf[c]] = c; delete this.convTableBackward; return this.convTableBackward = ctb; }, inPrimaryLayout: function(s) { for(var i = 0, l = s.length; i < l; ++i) { var c = s.charAt(i); var primary = c in this.convTableForward; if(primary ^ c in this.convTableBackward) return primary; } return false; }, switchKeybLayout: function(s, convTable) { var res = ""; for(var i = 0, l = s.length; i < l; ++i) { var c = s.charAt(i); res += c in convTable ? convTable[c] : c; } return res; }, getFocusedElement: function() { return Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, {}); }, switchSelKeybLayout: function(_subCall, _focusFixed) { var fe = this.getFocusedElement(_subCall, _focusFixed); if(!fe) return; if(HTMLInputElement.isInstance(fe) || HTMLTextAreaElement.isInstance(fe)) { var ta = fe; try { var val = ta.value; var sel = val.substring(ta.selectionStart, ta.selectionEnd); } catch(e) { // Non-text HTMLInputElement return; } if(!sel && val && this.noSelBehavior && !_subCall) { if(this.noSelBehavior == 1) { ta.selectionStart = 0; ta.selectionEnd = val.length; sel = val; } else { this.handleNoSel(ta); return; } } if(!sel) return; var res = this.switchKeybLayout( sel, this.inPrimaryLayout(sel) ? this.convTableForward : this.convTableBackward ); if(res != sel) this.insertText(ta, res); } else if(fe.contentEditable == "true") { var doc = fe.ownerDocument; var docURI = doc.documentURI; if( docURI.substr(0, 5) == "data:" && docURI.indexOf("chrome://browser/skin/devtools/") != -1 ) { //~ todo: seems like we only can use paste from clipboard here... return; } var sel = doc.defaultView.getSelection(); var rng = sel.rangeCount && sel.getRangeAt(0); var tmpNode; if(!rng || rng.collapsed) { if(!this.noSelBehavior || _subCall) return; if(this.noSelBehavior == 1) { var r = doc.createRange(); r.selectNodeContents(fe); sel.removeAllRanges(); sel.addRange(r); tmpNode = fe.cloneNode(true); } else { this.handleNoSel(fe); return; } } else { tmpNode = doc.createElementNS("http://www.w3.org/1999/xhtml", "div"); tmpNode.appendChild(rng.cloneContents()); } var orig = tmpNode.innerHTML; var convTable = this.inPrimaryLayout(tmpNode.textContent) ? this.convTableForward : this.convTableBackward; var _this = this; var parseChildNodes = function(node) { if(Element.isInstance(node)) { var childNodes = node.childNodes; for(var i = childNodes.length - 1; i >= 0; --i) parseChildNodes(childNodes[i]); } else if(node.nodeType == node.TEXT_NODE) { var text = node.nodeValue; var newText = _this.switchKeybLayout(node.nodeValue, convTable); if(newText != text) node.parentNode.replaceChild(doc.createTextNode(newText), node); } } parseChildNodes(tmpNode); var res = tmpNode.innerHTML; if(res != orig) doc.execCommand("insertHTML", false, res); } }, handleNoSel: function(node) { this.select(node); this.switchSelKeybLayout(true); }, select: function(node) { // var e = this.noSelBehavior; // if(!e || typeof e != "object") // return; // var evt = node.ownerDocument.createEvent("KeyboardEvent"); // evt.initKeyEvent( // "keypress", true /*bubbles*/, true /*cancelable*/, node.ownerDocument.defaultView, // e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, // e.keyCode, e.charCode // ); // node.dispatchEvent(evt); var beh = this.noSelBehavior; beh && node.ownerGlobal.docShell.doCommand("cmd_select" + beh); }, beh2cmd: { // Ctrl_Shift_VK false_true_36: "cmd_selectLinePrevious", // Shift+Home }, insertText: function(ta, text) { //var editor = ta.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor var editor = ta.editor .QueryInterface(Components.interfaces.nsIPlaintextEditor || Ci.nsIEditor); if(editor.flags & editor.eEditorReadonlyMask) return; var sTop = ta.scrollTop; var sHeight = ta.scrollHeight; var sLeft = ta.scrollLeft; // var sWidth = ta.scrollWidth; if(text) editor.insertText(text); else editor.deleteSelection(0, 0); ta.scrollTop = sTop + (ta.scrollHeight - sHeight); ta.scrollLeft = sLeft; // + (ta.scrollWidth - sWidth); } }`); |
Dobrov > 02-03-2024 02:34:07 |
Dumby пишет
Спасибо! Я делал так же: (обработать только объект), но результат разный: Dumby пишет
Исправил свой код менюшки и убрал имя переменной sub. |
Vitaliy V. > 03-03-2024 01:03:06 |
UserChromeFiles обнова https://github.com/VitaliyVstyle/Vitali … hromeFiles |
xrun1 > 03-03-2024 01:54:42 |
Vitaliy V. |
Viatcheslav > 03-03-2024 06:00:33 |
xrun1 пишет
А он есть |
b0ttle > 03-03-2024 13:45:21 |
Vitaliy V.. Рады вас видеть. Спасибо за новую сборку. |
unter_officer > 03-03-2024 15:18:10 |
Vitaliy V. пишет
Vitaliy V. |
Vitaliy V. > 03-03-2024 17:12:24 |
- |
unter_officer > 03-03-2024 18:46:27 |
Vitaliy V. пишет
Спасибо за ответ. Я уже успел интереса ради немного потестировать на 115 ESR. |
Vitaliy V. > 03-03-2024 20:28:20 |
- |
unter_officer > 03-03-2024 21:47:20 |
Vitaliy V. пишет
Vitaliy V., большое спасибо за патч. Теперь на 115 ESR всё нормально. |
Dumby > 04-03-2024 08:12:11 |
egorsemenov06 пишет
В этом смысле — вроде не должна. Vitaliy V. STR: Включаю de, рестарт. Открываю «Настройки UserChromeFiles», ER: Локализация в окне меняется на uk, ведь uk есть. Да, я понимаю, что STR довольно экзотичен. И по коду. UcfPrefs.defineGlobalGetters есть, но в само́м UCF нигде не используется. UcfPrefs.defineLazyGlobalGetters есть, но нужно ли это? скрытый текст Выделить код Код:// (globalProperties => { var result = []; var global = Cu.getGlobalForObject(Cu); var max = Math.max(...globalProperties.map(prop => prop.length)) + 2; for(var name of globalProperties) { var desc = global.Object.getOwnPropertyDescriptor(global, name); if (desc) { for(var key in desc) { var type = typeof desc[key]; if (type != "boolean") desc[key] = type; } } result.push(name.padEnd(max) + JSON.stringify(desc)); } Services.obs.addObserver(async function test(win, topic) { Services.obs.removeObserver(test, topic); await win.gBrowserInit.idleTasksFinishedPromise; var text = encodeURIComponent(result.join("\n")); var url = "data:text/plain;charset=utf-8," + text; var gb = win.gBrowser; gb.selectedTab = gb.addTrustedTab(url); }, "browser-delayed-startup-finished"); })([ "atob", "btoa", "Blob", "CSS", "CSSRule", "DOMParser", "Event", "File", "FileReader", "InspectorUtils", "URL", "XMLHttpRequest", "fetch", "L10nFileSource", "L10nRegistry", "Localization", // test non-existens "absent", "alert", // candidates "TextEncoder", "TextDecoder", ]); Код собирает дескрипторы свойств и визуализирует во вкладке первого окна браузера (не сразу, нужно чуть подождать). Насколько я вижу, все свойства уже есть, и у всех сразу value (не get). Кстати, почему только эти. |
grom17 > 04-03-2024 12:42:17 |
Vitaliy V. пишет
Сделал всё по инструкции ...никаких изменений. Видимо чего-то не понимаю. 125.0a1 (2024-03-03) (64-разрядный) |
fuchsfan > 04-03-2024 14:15:35 |
grom17 пишет
В v124.0beta6 работает. Кэш автозапуска очищал? Сразу должны быть видны три кнопки доп. тулбаров и доступны Промежуток и Разделитель. Зайди в настройки UCF и в нижней части проставь все птички, по умолчанию они все сняты. Не все скрипты, работающие в Aris-t2, работают в UCF. 04-03-2024 14:17:46 |
Vitaliy V. > 04-03-2024 19:12:11 |
Dumby пишет
Т. е. не происходит без перезагрузки ? Так и не было цели чтобы локали изменялись без перезагрузки, на панелях и кнопках UCF вообще ничего не происходит там просто при старте браузера один раз выбирается наиболее подходящая локаль и все, DOMLocalization не следит за ними. скрытый текст /** * Returns a list of locales that the application should be localized to. * * The result is a ordered list of valid locale IDs and it should be * used for all APIs that accept list of locales, like ECMA402 and L10n APIs. * * This API always returns at least one locale. * * When retrieving the locales for language negotiation and matching * to language resources, use the language tag form. * When retrieving the locales for Intl API or ICU locale settings, * use the BCP47 form. * * Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"] */ readonly attribute Array<ACString> appLocalesAsLangTags; readonly attribute Array<ACString> appLocalesAsBCP47; А availableLocales возвращает неупорядочный список (хоть это и не важно в данном случае) всех доступных локалей, ну и как бы он не нужен весь список если локаль только один раз при старте инициализируется скрытый текст /** * Returns a list of locales that the app can be localized to. * * The result is an unordered list of locale IDs which should be * used as a availableLocales input list for language negotiation. * * Example: ["en-US", "de", "pl", "sr-Cyrl", "zh-Hans-HK"] */ attribute Array<ACString> availableLocales; Dumby пишет
В XPCOMUtils.sys.mjs так и записано Dumby пишет
Это я хотел использовать но потом не потребовалось, но оставил может пригодится для использования в пользовательском коде Dumby пишет
Возможно излишняя но мне нравится lazy, не используешь не загружается лишнее Dumby пишет
Хм что-то не вижу где в прошлом UCF это было? Но ок добавлю 04-03-2024 19:28:26 fuchsfan пишет
Значек шестеренка, в зависимости от локали может отличаться, например для en-US так И вообще она по умолчанию находится на дополнительной панели |
b0ttle > 04-03-2024 19:53:05 |
Vitaliy V. Это лишь мой каприз, может другим нужны переводы. Мне и одного вполне хватает, если код от этого будет меньше и выпиливать будет легче. Да, можно просто под коврик спрятать все эти потроха, но они и там в глаза бросаются. Вместо одного spring, висят аж 4) Можно не прятать, оставляя на местах. Но все равно, не то. Зачем их именовать по-разному, чтобы не путаться? В коде, их тоже так и хочется выпиливать, возможно это лишь мой причуды и не критично. (В общем, пытался их убрать в "async formatMessages(){}", файл UcfPrefs.mjs, и у меня пропали пункты выбора, раскрыть-спрятать вертикальную панель и другие. Пришлось их вернуть, а так, вроде везде выпилил). |
Dumby > 05-03-2024 00:43:51 |
Vitaliy V. пишет
OK, принято.
Точно. Запись довольно старая, старше чем globalThis.
Проблем нет никаких.
OK, принято.
Наоборот. Когда случится обращение к этому свойству, Создание множества этих функций, которые проверяют уже заранее известное,
Да-да, не было. Именно поэтому мне и было странно чем они впали в немилость. Вообще-то да, это проблема, как выбрать то, что следует пробросить. Гобальные свойства проброшены не все, но их хотя бы немного, Например, IOUtils и PathUtils кажутся вполне достойными кандидатами. |
Vitaliy V. > 05-03-2024 01:23:32 |
b0ttle пишет
Предлагаете переводить юзерам в коде потому что вам сложно разобраться с кодом а им типа легко. b0ttle пишет
Первое пробовали отключить в настройках ненужные панели? Вместе с панелями отключаются и соответствующие кнопки, интервалы скрытый текст Выделить код Код:(ids => ({ init() { CustomizableUI.addListener(this); Services.obs.addObserver(this, "browser-delayed-startup-finished"); }, observe() { Services.obs.removeObserver(this, "browser-delayed-startup-finished"); CustomizableUI.removeListener(this); }, onWidgetCreated(aWidgetId) { if (ids.has(aWidgetId)) CustomizableUI.destroyWidget(aWidgetId); }, }).init())(new Set([ "ucf-open-about-config-button", "ucf-additional-vertical-spring", "ucf-additional-top-spring", "ucf-additional-bottom-spring", "ucf-restart-app", "ucf-view-history-sidebar-button", "ucf-view-bookmarks-sidebar-button", "ucf-open-directories-button", ])); |
Vitaliy V. > 05-03-2024 01:55:43 |
Dumby пишет
Да это понятно но следует добавить что это происходит только один раз при первом вызове Dumby пишет
Так а где гарантии что это сейчас заведомо существующее не станет потом просто существующим или вообще не существующим. |
b0ttle > 05-03-2024 07:16:51 |
Vitaliy V. Спасибо. До меня потом дошло, что можно просто оставить все как есть. Если не пытаться выпилить сразу, то потом может и привыкнуть можно. Про настройки, что-то не подумал. Код попробую. Чисто мой закидоны) |
Dumby > 05-03-2024 09:26:14 |
Vitaliy V. пишет
Да, разумеется. Но могло бы не происходить вовсе.
Ну так можно вообще обо всём сказать. Кстати, Console.sys.mjs же собираются выпилить, Ещё, при переключении тулбаров посредством контекстного меню, Когда был проект встроить в UCF дебаггер, А теперь, наверно, надо какую-то функцию переопределять. |
Vitaliy V. > 05-03-2024 18:29:32 |
Dumby пишет
Да уж 6 лет выпиливали Console.jsm не выпилили, выпилили jsm теперь Console.sys.mjs выпиливают Dumby пишет
Что за проект? Нашел только настройки 05-03-2024 18:32:38 Dumby пишет
Её вообще выпиливать нужно а не id'шники в BROWSER_UI_CONTAINER_IDS добавлять |
Dumby > 05-03-2024 22:14:54 |
Vitaliy V. пишет
Поскольку никто не мог знать, что нарисуется UCF 2024 от самого́ Автора, Я уже упоминал, что, увы, для некоторых задач, необходим дебаггер. Собственно, ничего особо сделать не успел, И это, несомненно, к лучшему. Так вот, в config.js предполагалось оставить только самый минимум, А сырой набросок init.js был такой, скину какой был. Дебаггер, собственно, это некая цитата из ранее добавленного в CB, скрытый текст Выделить код Код:(url => { (file = file.parent).append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) return; Components.manager.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(file); var sysp = Cu.getObjectPrincipal(this), SB = opts => Cu.Sandbox(sysp, opts); var sb = SB({sandboxName: "UserChromeFiles", wantGlobalProperties: ["ChromeUtils"]}); Services.scriptloader.loadSubScript(url, sb); var unload = ["unload", e => e.target.ownerGlobal.windowRoot.removeEventListener(...ins), {once: true}]; var ins = ["DOMDocElementInserted", e => { var win = e.target.ownerGlobal; if (win.windowRoot.ownerGlobal == win) { if (win.location == "about:blank") return; win.addEventListener(...unload); } win.isChromeWindow && sb.user_chrome.initWindow(win); }]; Services.obs.addObserver(win => win.windowRoot.addEventListener(...ins), "domwindowopened"); var re = Cu.reportError; var sandbox = SB({freshCompartment: true}); Cc["@mozilla.org/jsdebugger;1"].createInstance(Ci.IJSDebugger).addClass(sandbox); var dbg = sb.dbg = new sandbox.Debugger(); var g = Cu.getGlobalForObject(Cu); var gref = dbg.gref = dbg.makeGlobalObjectReference(g); var envRef = function(name) { var val = this.find(name).getVariable(name); return val.unsafeDereference?.() || val; } dbg.ref = (arg, func, glob) => { var go = glob === undefined ? g : glob || Cu.getGlobalForObject(func); var has = dbg.hasDebuggee(go); has || dbg.addDebuggee(go); try { var ref = go == g ? gref : dbg.makeGlobalObjectReference(go); var env = ref.makeDebuggeeValue(func).environment; var cn = arg.constructor.name; if (cn == "Object") for(var name in arg) try { env.find(name).setVariable(name, ref.makeDebuggeeValue(arg[name])); } catch(err) {re(err);} else return cn == "Array" ? arg.map(envRef, env) : envRef.call(env, arg); } catch(ex) {re(ex);} finally {has || dbg.removeDebuggee(go);} } // Meds. Prevent "widgetId is undefined" console spam // from BrowserUsageTelemetry.sys.mjs when toggle ucf-toolbars. if (sb.UcfPrefs.vertical_top_bottom_bar_enable) try { var exp = ChromeUtils.importESModule("resource:///modules/BrowserUsageTelemetry.sys.mjs"); var ids = dbg.ref("BROWSER_UI_CONTAINER_IDS", exp.BrowserUsageTelemetry.init); ids && ["top", "vertical", "bottom"].forEach(pos => ids[`ucf-additional-${pos}-bar`] = ""); } catch(ex) {re(ex);} })("chrome://user_chrome_files/content/user_chrome.js"); И да, я согласен, что BrowserUsageTelemetry следует душить как угодно. Но, если абстрагироваться от нашей к нему неприязни, и рассмотреть просто как задачу: «Как получить ссылу на BROWSER_UI_CONTAINER_IDS?». Пока нынешний Ку.import() ещё с нами можно использовать его. Но метод сгинет вместе с JSM. |
kokoss > 06-03-2024 10:08:18 |
grom17 пишет
В 123 тоже не работает ? Add, если не работает, тогда опишите что сделали, желательно по пунктам! Add, ладно.... user_chrome_files. С остальным надеюсь сами разберётесь. |
Vitaliy V. > 06-03-2024 15:42:09 |
Dumby пишет
Ну именно для BrowserUsageTelemetry я бы не стал добавлять его, но если нужно для некоего кода в custom_script.js что если добавить этот модуль |
Dumby > 06-03-2024 18:18:58 |
Vitaliy V. пишет
Не-не, конечно же, в первую очередь, для пользовательского кода. Просто когда он уже есть, возникает соблазн Мягонькое такое воздействие, никакого насилия, Если будет принято решение заткнуть BrowserUsageTelemetry Наверно лучше как свойство UcfPrefs. Он определён как в сандбоксе, так и в окнах браузера. Вот, поискал, нашёл, например, такой код.
Да, указанные методы этого модуля делают часть работы. |
Vitaliy V. > 07-03-2024 00:34:13 |
Dumby Но чтобы не мусорила BrowserUsageTelemetry просто переопределил Также убрал Lazy, побавил TextEncoder TextDecoder https://github.com/VitaliyVstyle/Vitali … me.js#L179 |
Dumby > 07-03-2024 10:20:57 |
Vitaliy V. пишет О, спасибо! скрытый текст Выделить код Код:(async sep => { if (!sep) return; var key = "hasRemoveTransaction"; var raws = UcfPrefs.dbg.ref("lazy", PlacesTransactions.undo).TransactionsHistory.proxifiedToRaw; raws[key] ??= entry => { for(var transaction of entry) { if (raws.get(transaction) instanceof PlacesTransactions.Remove) return true; } } var menuitem = document.createXULElement("menuitem"); for(var args of Object.entries({ closemenu: "single", class: "menuitem-iconic", id: "placesCmd_undoRemove", label: "Восстановить удалённое", oncommand: "PlacesTransactions.undo().catch(Cu.reportError);", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQEAYAAABPYyMiAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAAAQAAAAEABcxq3DAAAEd0lEQVRIx53Ve2yW5RkG8N/7ft8Hxa/9CgjSSDnMA4xVTUMQWzadhzhnjSCC0y0jSjom+JdGp844ZhSjHLJsowaNZoCCHOWglXGoQbo2fBW3obDNUBfXKpsUVhxn6OHdH8+31GXGmL3/3M913ffzPNed93qeBxvmI8umCNjyPFEDSRJw40qKa9jyHSbdzY77Ar+9FTvZ+nHAb9T7P76YcwlOktlBdJia2SSthfRvaR/Mync5tp85Q2mbEHJ/X0bqRTpOBJyehog3C3j1HV9RQP91xG9T8z2SofyphMELWH4zW5s40s7kQ/T0cnYfXfPD1OgM0TlGzSN1DZkzxG1EdURjaa9HCfddEupfuSkIfHXJ5wVENA8Iw9QcRnbzXj31++g8w+WVZHMhXzaKhu2MGMtd36f5CTrn8WAJyf001KCYpA6dDBtLlOfoYuI6kgp6XuLsbhQRfw39ovDPx7/JgYS1b3NkCxcvoPgTevIULyFVTm4jyinp4uRJiirYt5BMLc15kvE0lnCsgZaE2wdx6LVCo9/ghQn4LhdFxEOonELv8ogVV9Iyjd9fx8T1FE2nq5XSQWQuJbsmrJH9JclMsldhFsW3EU0iuxsb6f9zTA3dHj1J1yPsKaPrIOtnkn6KDY2cvYF/vkfmINGuiPdnUD6Pd/7Mur/x0RCqXqTfj+m5glyO1B8ovR1pijeil6KvBw8V1QaB/QYWzNgSYu+TmMm5GVhKT47OBWR28kgnvxvKS/OjvuMGuTSr72FtBR/WctNe4l+H3GUt7DxB2TKe+CmnF5IZRzSZzFmS4wy9n2QGY2eR3Mx193DqAao+4vh04lZS2/EkQyqo7cWux4Kjwf4gKF3N5hEs+QsLlwVuVRPLP2FeTSh95hZSpSx6OOAkwWCWLSEqYWVz4JtLqd3GiuX0/oS6XKjd/BQbF6SRJynij4eJKpl7WSg8cCdzxjHjH3QuIsaorQx7NCx8QQdxCYM2kzxL423BbGN6SP+I6tmcO86hahqu4MA2To3mX+eTxbA2er6VJjcA/Yl2kOzlrutJxrDraaI1XH09j3fQVk7pcG5sCgIOttLVzejpmMPrnxJvYnIZXelwxGHTCOaX0PorsmUMOC/wpeNofg4fjg9EW3+k6CzcYJ99M7h6fSfxFFJrMZzFm0I+fzXxlTQ1EHf3eSlJyI3mlYGs/yEPx4F7/NkQ11zEymFhnDoY9RnwcHmIZ34Q1CcTkBD9FSM58gu8SmUHbmVuJbYRt2AiE/cwZT/tG3h+Gh29lH3A+VPZ+zMq1rHwcq6tY1U31ReQXPgFt3M+/9+xJRvM9f5S3NnX6btLqfqYt1p44xQrFnH0aX6zmBXIj+Hae0N95qG+ea/PJjrB7tV47csE7CzEJqKXyTcW8CquaibfwTOX0FjPLSfYk+G8XWyb+rlTUcndVUQjWXOK+FiBn/QfQen/FVBVVdhoc4FIkczqM5WBvPMWp4fQMpzFHeEN2NCFCcyNSH2b1AiSl3nhVnrnkjpNkqP9jrBvdzX8G2rIlxvMK3a7AAAAInpUWHRTb2Z0d2FyZQAAeNorLy/Xy8zLLk5OLEjVyy9KBwA22AZYEFPKXAAAAABJRU5ErkJggg==", })) menuitem.setAttribute(...args); var desc = Object.getOwnPropertyDescriptor(XULElement.prototype, "hidden"); var {set} = desc; desc.set = () => { var entry = PlacesTransactions.topUndoEntry; set.call(menuitem, !entry || !raws[key](entry)); } Object.defineProperty(menuitem, "disabled", {}); Object.defineProperty(menuitem, "hidden", desc); sep.before(menuitem); })(document.getElementById("placesContext_deleteSeparator")); Так же, вижу улучшение для UcfPrefs.global Всё ещё функция, но лишь до первого обращения, затем просто значение, как и могло бы быть сразу, но всяко лучше, чем было. Кстати, и в геттере UcfPrefs.dbg Это глобальный объект всех модулей.
Да, вижу, теперь в консоли тишина. onViewToolbarCommand, было - стало Выделить код Код:data:image/png;base64,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
Благодарю, надеюсь достойны.
Ну здесь я не смог тебя убедить просто сразу скопировать |
Vitaliy V. > 07-03-2024 14:55:43 |
Dumby пишет
Это типа оператором присваивания ? |
Dumby > 07-03-2024 17:21:07 |
Vitaliy V. пишет
Да-да, именно им.
Ууу, мысль, несомненно, интересная.
Не загружать, а сослаться. Они уже загружены. |
Vitaliy V. > 07-03-2024 18:57:13 |
Dumby пишет
Что ж пусть так и будет. Модули только нужно подгружать по необходимости |
Dumby > 08-03-2024 10:27:29 |
Vitaliy V. пишет
Сунул в custom_script.js скрытый текст Выделить код Код:var bla = "bla"; var test = { "globalThis.bla": globalThis.bla, // user box, expected string "SystemGlobal.bla": Cu.getGlobalForObject(Cu).bla, // SystemGlobal, expected undefined // expected all exsists // dom idl PathUtils: PathUtils, AbortController: AbortController, HTMLAnchorElement: HTMLAnchorElement, // global properties FileReader: FileReader, XMLSerializer: XMLSerializer, URLSearchParams: URLSearchParams, // modules PlacesUtils: PlacesUtils, AppConstants: AppConstants, CustomizableUI: CustomizableUI, // internal stuff UcfPrefs: UcfPrefs, user_chrome: user_chrome, user_chrome_files_sandbox: user_chrome_files_sandbox, }; for(let key in test) test[key] = typeof test[key]; console.log(JSON.stringify(test, null, "\t")); Парадигма сдвинута. |
unter_officer > 13-03-2024 23:48:54 |
Есть вот такой скрипт: "Переключить текущий поисковик" (первый спойлер) Кто-нибудь на FF123 пользуется этим скриптом? Дело в том, что на Windows 7, по понятным причинам, крайнюю версию оригинального FF я поставить не могу. Кому не сложно, проверьте пожалуйста этот скрипт в оригинальном FF123. |
Dumby > 14-03-2024 08:24:55 |
unter_officer пишет
Это Bug 1870644 - Provide a single function for obtaining icon URLs from search engines Farby предложил такую конструкцию: Затем getIconURL() сделали асинхронной, А когда приземлится это, надо будет смотреть, Ну, и на самой кнопке иконка не подхватывается, нужно прицепить wrappedJSObject. скрытый текст Выделить код Код:/* var engine = popup.getDefaultEngine(); */ var engine = popup.getDefaultEngine().wrappedJSObject; |
unter_officer > 14-03-2024 10:22:31 |
Dumby |
Farby > 14-03-2024 10:28:50 |
Dumby пишет
Спасибо, забрал. excludeHiddenOneOffs Выделить код Код:// excludeHiddenOneOffs: false, excludeHiddenOneOffs: true, // скрыть не нужные поисковики .. // if (this.excludeHiddenOneOffs) // var ex = Services.prefs.getStringPref(this.pref, "").split(","); var visibleEngines = await Services.search.getVisibleEngines(); if (this.excludeHiddenOneOffs) { var args = "hideOneOffButton" in Services.search.defaultEngine ? [e => !e.hideOneOffButton] : Object.defineProperty( [function(e) {return !this.includes(e.name);}], "1", { get: () => Services.prefs.getStringPref("browser.search.hiddenOneOffs")?.split(",") || [] }); visibleEngines = visibleEngines.filter(...args); } .. // for(var engine of await Services.search.getVisibleEngines()) { for(var engine of visibleEngines) { .. // if (this.excludeHiddenOneOffs && ex.includes(engine.name)) continue; |
xrun1 > 14-03-2024 17:10:30 |
Vitaliy V. Тултипы с URL Выделить код Код:// Ссылка у курсора в тултипе, кнопка https://forum.mozilla-russia.org/viewtopic.php?pid=783755#p783755 (async () => { var id = "ucf-toggle-tooltip-url", label = "Тултипы с URL", tooltiptext = "Переключить тултипы", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' style='fill:context-fill rgb(142, 142, 152);'><path d='M9.618 6.721a2.483 2.483 0 0 0-.39-.317l-.735.734A1.486 1.486 0 0 1 8.91 9.55l-2.12 2.122a1.486 1.486 0 0 1-2.122 0 1.486 1.486 0 0 1 0-2.121l.605-.605a3.53 3.53 0 0 1-.206-1.209L3.961 8.843a2.506 2.506 0 0 0 0 3.535 2.506 2.506 0 0 0 3.535 0l2.122-2.121a2.506 2.506 0 0 0 0-3.536z'/><path d='M6.79 9.55c.12.121.25.226.389.317l.734-.734a1.486 1.486 0 0 1-.417-2.411L9.618 4.6a1.486 1.486 0 0 1 2.121 0 1.486 1.486 0 0 1 0 2.121l-.605.605c.137.391.211.798.206 1.209l1.106-1.107a2.506 2.506 0 0 0 0-3.535 2.506 2.506 0 0 0-3.535 0L6.789 6.014a2.506 2.506 0 0 0 0 3.536z'/><circle style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round' cx='8' cy='8' r='7.4'/></svg>", imgcolordisable = "color-mix(in srgb, currentColor 20%, #e31b5d)"; var branch = "extensions.ucf.", pref = "tooltip_url_enable"; var tpurl = { initialised: false, tooltip_url_enable: true, get ext_branch() { delete this.ext_branch; return this.ext_branch = Services.prefs.getBranch(branch); }, init() { if (this.initialised) return; Services.prefs.getDefaultBranch(branch).setBoolPref(pref, true); Services.prefs.addObserver(`${branch}${pref}`, this); if (this.tooltip_url_enable = this.ext_branch.getBoolPref(pref)) this.registerActor(); this.initialised = true; }, observe(subject, topic, data) { var fill = ""; if ((this.tooltip_url_enable = this.ext_branch.getBoolPref(pref)) === true) this.registerActor(); else { fill = imgcolordisable; this.unregisterActor(); } this.callWithEachWindow(id, {fill: fill}); }, 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]); } }, registerActor() { ChromeUtils.registerWindowActor("UcfTooltipUrl", { child: { moduleURI: "chrome://user_chrome_files/content/custom_scripts/cs/UcfTooltipUrlChild.jsm", events: { mouseover: { capture: true }, }, }, allFrames: true, matches: ["<all_urls>"], messageManagerGroups: ["browsers"], }); }, unregisterActor() { ChromeUtils.unregisterWindowActor("UcfTooltipUrl"); }, }; CustomizableUI.createWidget({ id: id, label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { tpurl.init(); btn.style.setProperty("list-style-image", `url("${img}")`, "important"); if (!tpurl.tooltip_url_enable) btn.style.setProperty("fill", imgcolordisable); }, onCommand(e) { tpurl.ext_branch.setBoolPref(pref, !tpurl.ext_branch.getBoolPref(pref)); }, }); })(); UcfTooltipUrlChild.jsm Выделить код Код:var EXPORTED_SYMBOLS = ["UcfTooltipUrlChild"]; ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); class UcfTooltipUrlChild extends JSWindowActorChild { handleEvent(e) { timer.cancel(); timer.initWithCallback(() => { var elm = e.isTrusted && e.composedTarget, el, titl; if (!elm) return; do { if (!elm.matches) continue; if (elm.matches(":any-link")) { if (elm.matches("[href='#'], [href^='javascript']")) return; el = elm; if (elm.matches("[title]")) titl = elm; else while (elm = elm.flattenedTreeParentNode) { if (!elm.matches) continue; if (elm.matches("[title]")) { titl = elm; break; } } break; } if (elm.matches("[title]")) { titl = elm; while (elm = elm.flattenedTreeParentNode) { if (!elm.matches) continue; if (elm.matches(":any-link")) { if (elm.matches("[href='#'], [href^='javascript']")) return; el = elm; break; } } break; } } while (elm = elm.flattenedTreeParentNode); if (!el) return; var href = el.href; if (titl) el = titl; titl = (el.title || ""); var title = titl.trim(), pre = "", path = ""; try { href = Services.io.newURI(href); pre = href.displayPrePath; path = `\n${href.pathQueryRef}`; if (path === "\n/") path = ""; href = `${pre}${path}`; } catch (e) {} try { href = decodeURIComponent(href); } catch (e) {} el.title = title = `${href}${title === "" ? "" : `\nTitle: ${title}`}`; this.contentWindow.addEventListener("mouseout", () => { try { if (!el || title !== el.title) return; if (titl !== "") el.title = titl; else el.removeAttribute("title"); } catch (e) {} }, { once: true }); }, 100, Ci.nsITimer.TYPE_ONE_SHOT); /* было 400 */ } didDestroy() { timer.cancel(); } } Пока работает, но можно переделать на mjs? P.S. Может, уже переделывали в теме, не уследил... |
Dumby > 14-03-2024 17:59:39 |
Farby пишет
Не, Виталий такую шляпу не пишет, у него всё как-то более академично. Настройка "browser.search.hiddenOneOffs" дефолтно существовала (до 116), Dumby пишет
Ха, оказывается они уже слетели (причём, во всём браузере), Впрочем, теперь не важно, баг приземлился, настройку включили, Но ничего, теперь хотя бы понятно, что engine._iconURI для них больше не подходит. скрытый текст Выделить код Код:try {CustomizableUI.createWidget({ label: "Переключить текущий поисковик", id: "ucf-cbbtn-ToggleCurrentSearchEngine", image: "data:image/png;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA", excludeHiddenOneOffs: true, gn: () => Services.search.defaultEngine, gp: () => Services.search.defaultPrivateEngine, sn: val => Services.search.defaultEngine = val, sp: val => Services.search.defaultPrivateEngine = val, onCreated(btn) { btn.type = "menu"; btn.owner = this; btn.setAttribute("image", this.image); var win = btn.ownerGlobal; var popup = btn.appendChild(win.document.createXULElement("menupopup")); var pr = win.PrivateBrowsingUtils.isWindowPrivate(win); popup.getDefaultEngine = pr ? this.gp : this.gn; popup.setDefaultEngine = pr ? this.sp : this.sn; popup.setAttribute("oncommand", "setDefaultEngine(event.target.engine)"); popup.setAttribute("onpopupshowing", "this.shouldRebuild && owner.rebuild(this, document)"); this.autoOpenCloseFeature(win, btn); this.updButton(btn, win); }, getEngines() { var ve = Services.search.getVisibleEngines; if (!this.excludeHiddenOneOffs) return (this.getEngines = ve)(); var arr = []; var args = this.fx116 ? [e => !e.hideOneOffButton] : Object.defineProperty( [function(e) {return !this.includes(e.name);}], "1", {get: () => { var str = Services.prefs.getStringPref(this.pref); return str ? str.split(",") : arr; }} ); return (this.getEngines = async () => (await ve()).filter(...args))(); }, async rebuild(popup, doc) { popup.textContent = ""; var df = doc.createDocumentFragment(); var de = popup.getDefaultEngine().wrappedJSObject, jsde = this.json(de); var check = true; for(var engine of await this.getEngines()) { if (check && engine.name == de.name && this.json(engine) == jsde) { check = false; continue; } var menuitem = df.appendChild(doc.createXULElement("menuitem")); menuitem.engine = engine; menuitem.label = engine.name; menuitem.className = "menuitem-iconic"; menuitem.image = await this.img(engine); } popup.append(df); delete popup.shouldRebuild; }, async updButton(btn, win) { this.updButton = () => {}; Services.search.isInitialized || await Services.search.init(); this.fx116 = "hideOneOffButton" in Services.search.defaultEngine; var topics = ["browser-search-engine-modified", "quit-application-granted"]; for(var topic of topics) Services.obs.addObserver(this, topic, false); this.observe = (s, topic) => this[topic[0]](); var remove = () => topics.forEach( topic => Services.obs.removeObserver(this, topic) ); var {id} = this; var wins = callback => { for(var win of CustomizableUI.windows) { var btn = win.document.getElementById(id); btn && callback(btn, win); } } if (this.excludeHiddenOneOffs && !this.fx116) { var setRebuild = btn => btn.firstChild.shouldRebuild = true; var {pref} = this, obs = () => wins(setRebuild); Services.prefs.addObserver(pref, obs); this.q = () => remove(Services.prefs.removeObserver(pref, obs)); } else this.q = remove; var updButton = (btn, win) => { var popup = btn.firstChild; var engine = popup.getDefaultEngine(); /*btn.label =*/ btn.tooltipText = engine.name; popup.shouldRebuild = true; win.requestAnimationFrame(async () => btn.icon.src = await this.img(engine)); } (this.b = () => wins(updButton))(); this.updButton = updButton; btn.tooltipText || updButton(btn, win); }, pref: "browser.search.hiddenOneOffs", json: e => JSON.stringify(e.toJSON()), img: async e => await e.getIconURL?.() || e.iconURI?.spec || "chrome://browser/skin/search-engine-placeholder.png", // https://github.com/Infocatcher/Custom_Buttons/blob/master/code_snippets/autoOpenCloseMenu.js // Automatically open menu on mouse over (and hide it on mouse out) autoOpenCloseFeature(win, btn, openDelay = 200, closeDelay = 350) { var _openTimer = 0; var _closeTimer = 0; btn.onmouseover = function(e) { win.clearTimeout(_closeTimer); if(e.target == btn && closeOtherMenus()) { btn.open = true; return; } _openTimer = win.setTimeout(function() { btn.open = true; }, openDelay); }; btn.onmouseout = function(e) { win.clearTimeout(_openTimer); _closeTimer = win.setTimeout(function() { btn.open = false; }, closeDelay); }; function closeOtherMenus() { return win.Array.prototype.some.call( btn.parentNode.getElementsByTagName("*"), function(node) { if( node != btn && win.XULElement.isInstance(node) // 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; } ); } } });} catch(ex) {Cu.reportError(ex);} |
unter_officer > 14-03-2024 18:55:25 |
Dumby пишет
Dumby, в консоль пишет: CustomizableUI: Could not localize property 'ucf-cbbtn-ToggleCurrentSearchEngine.tooltiptext'. Если в код добавить что-то типа: |
Dumby > 14-03-2024 20:06:02 |
egorsemenov06 пишет
Ну, что значит не будет работать? А правка там простая скрытый текст Выделить код Код:/* node.setAttribute("image", engine._iconURI ? engine._iconURI.spec : engine.iconURI ? engine.iconURI.spec : this.defaultImg); */ node.setAttribute("image", await engine.getIconURL?.() || engine.iconURI?.spec || this.defaultImg); unter_officer пишет
Да, есть такое, за всем не уследишь. xrun1 пишет
Что-то я не вижу там ничего такого, Никаких выкрутасов, никаких __URI__ (которого в ESM нет), В скрипте меняем скрытый текст Выделить код Код:/* moduleURI: "chrome://user_chrome_files/content/custom_scripts/cs/UcfTooltipUrlChild.jsm", */ esModuleURI: "chrome://user_chrome_files/content/custom_scripts/cs/UcfTooltipUrlChild.mjs", а в модуле скрытый текст Выделить код Код:/* var EXPORTED_SYMBOLS = ["UcfTooltipUrlChild"]; ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm"); var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); class UcfTooltipUrlChild extends JSWindowActorChild { */ var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); export class UcfTooltipUrlChild extends JSWindowActorChild { Вот и всё. |
unter_officer > 14-03-2024 20:24:16 |
Dumby пишет
Спасибо, теперь всё нормально. |
Farby > 14-03-2024 22:46:44 |
Dumby пишет
Каюсь, простите великодушно, уже крыша едет где что взял... К сожалению я не умею писать, но зато умею читать и чуть чуть переставлять слова... |
Farby > 14-03-2024 23:43:16 |
Dumby пишет
ой а без директивы localized: false вы сразу отшибаете таких пользователей как например я.. |
Farby > 15-03-2024 00:15:46 |
Dumby |
unter_officer > 15-03-2024 01:08:46 |
Dumby скрытый текст Выделить код Код:(async initCode => CustomizableUI.createWidget({ id: "ucf_UpDownCenterPage", label: "Up/Down/Center Page", // defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAACXBIWXMAAAAAAAAAAAHqZRakAAACvElEQVQ4y3VTX0jTURT+rrsqmm3gwm02dZOZOk3RFCTMp4ggEQIT9GUD7VV8mDNF2NaD4qY2X8PBBpGkDwX64EP6YILGilzl3B/dnI5UMHSUWHO/3+1h/pva93S595zvfN8551IcgyYcZMYbHhpV17MU4xShABBV17MU9xR5xjSMAsCIe34ZAKb7F86S00aJ77CN3aJNUpVbnpYhX2pNvj7b5gQVJaceEEJWZ4mzEgBolHGrHPicwg5FxGtdF51ydCjKI9Z1lwgXQAGgr7CWJQkEGKh+yLqc00Tdlb+TdCTA92G/hAJAj3eenGQUmPKYsDsNAKBKzY3r1sgLJ+wlDxr1vg+TFsMS8RsulDiPfE3OWKg0fLvgh3Lf8yJQeykg4NhsBgAPAmcMnP0t48w2pLiniFIjn7hrL238rPdOeizBBjpYXMcslhHwACw1j9ioyO1y6da2wRMFAFDdyhxheffZoUqB9JlRgsUr+kBC7wlC8YuaaAkDgHZBJ1oE2vi8RiH1hcXXeOPPtaLFlGXymrOzFoGWnDK0VtUVoKQCRkc3AODk8co+XAWlRj6htMsaZRAjBxK8089NeizBhksEHYryyJDRKBzoM6PHt3BahYDEFmyf/NE9RLMOxFQUE2YmKDDllbFekwmc2QbObIOOiqFT1zPD7xD6N76RgGOzGY54whZ2sYXdxC4ZQl+JQfv4vxZUT3Od6S9JVfpRBm5yUrh7g19WhgKVCRbaFWVLaYTKjijhwZDE87Eda8BVVj2oZnyUAzVT8AwI89uQZIkrsi1ZbKZzkZwSRGJ//SPSonKIJYA0G/q5Nx8BwKlzk9wmmTv7VWYxOZ7f807TL89wUJigwBH2PnGEvVda2BjfUm+Mb6GwQxFpsWpFlzYlvvNFY/fC+3f28Cd6IBbTfVHGrjXgqj0f7LWuX/py/wDHfA2DzTMorQAAAABJRU5ErkJggg=="); new btn.ownerGlobal.Function(initCode).call(btn); } }))(`(u => { var id, lfs = url => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false); var max = () => { var url = u([ "var args = [scroller.scrollHeight, 0];", "scroller.scrollTop != 0 || args.reverse();", "content.scrollTo(...args);" ].join("\\n\\t")); (max = () => lfs(url))(); } var mid = () => { var url = u("content.scrollTo(0, (scroller.scrollHeight - scroller.clientHeight) / 2);"); (mid = () => id = lfs(url))(); } var obj = { mousedown: () => id = setTimeout(mid, 500), mouseup: () => id && max(id = clearTimeout(id)) }; this.onmousedown = this.onmouseup = e => e.button || obj[e.type](); this.tooltipText = "ЛКМ: Вверх/Вниз по странице \\nдЛКМ: Центрирование страницы"; }) (code => "data:," + encodeURIComponent(\`(doc => { var root = doc.documentElement; var body = doc.body || root; var scroller = body.scrollHeight > root.scrollHeight ? body : root; \${code} })(content.document)\`));`); Если в исходном коде страницы сайта отсутствует элемент <!DOCTYPE>, то кнопка начинает работать неправильно. Проверить можно, например, на forum.ru-board.com Это возможно как-то поправить? |
Dobrov > 15-03-2024 05:20:16 |
Dumby - поправь код менюшки! Не работает upd(){… для подменю! Выделить код Код:(async id => { // forum.mozilla-russia.org/viewtopic.php?pid=808738#p808738 MyMenu = { //массив команд пользователя, alt() клик правой кнопкой Pics: { // Графика сайтов Вкл/Выкл permissions.default.image upd() { // обновлять сроку перед показом меню // var {G} = this.ownerGlobal; var val = G.pref(G.v), s = val == 1, i = G.pdi; s ? i = i.replace("-blocked","") : 0; this.label = `Графика сайтов ${s ? "загружается" : val == 3 ? "кроме сторонних" : "отключена"}`; this.image = i || G.chk; this.tooltipText = G.v +" "+ val +"\nRClick – кроме сторонних"; }, cmd(){ G.pref(G.v, G.pref(G.v) == 2 ? 1 : 2); BrowserReload(); }, // alt(){ //для RClick нужен ucf_hookClicks.js // G.pref(G.v, 3); BrowserReload(); // }, }, "SubMenu": { men: 1, //подменю "SubItem": { lab: "SubItem Mod", // img: G.opt, upd() { // обновлять сроку перед показом меню var val = G.pref(G.v), s = val == 1, i = G.pdi; s ? i = i.replace("-blocked","") : 0; this.label = `SubItem: Графика ${s ? "загружается" : val == 3 ? "кроме сторонних" : "отключена"}`; this.image = i || G.chk; this.tooltipText = G.v +" "+ val +"\nRClick – кроме сторонних"; }, cmd(){console.log(this.label)}, }, }, "End Menu": { sep: 1, //сперва разделитель upd() { //обновить иконку var val = G.pref(G.v), s = val == 1, i = G.pdi; s ? i = i.replace("-blocked","") : 0; this.image = i; }, }, } CustomizableUI.createWidget({ id: id, label: id, tooltiptext: id, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.style.setProperty("list-style-image", "url(chrome://branding/content/icon32.png)"); btn.type = "menu"; var doc = btn.ownerDocument, m = nn => doc.createXULElement(nn); var popup = m("menupopup"), menu = m("menuitem"); menu.m = m; menu.fill = this.fill; menu.render = this.render; popup.append(menu); btn.prepend(popup); }, render(){ var popup = this.parentNode; this.remove(); this.fill(MyMenu, popup); }, fill(o, popup) { for (key in o) { var val = o[key]; if (typeof val != "object") continue; var {lab, inf, img, cmd, alt, sep, men, upd} = val; sep && popup.append(this.m("menuseparator")); var name = men ? "menu" : "menuitem"; var item = this.m(name); item.setAttribute("label", lab || key); // item.alt = alt; //RClick в ucf_hookClicks.js {Mouse… if (inf) item.tooltipText = inf; if (img || /this\.image.*=/.test(upd)) item.className = name + "-iconic", item.setAttribute("image", img || G.nul); men || cmd && item.setAttribute("oncommand", cmd.toString().replace( /cmd\(.*?\){/, "{var trg = event.target || event;" )); popup.append(item); upd && (item.render = upd).call(item); men && this.fill(val, item.appendChild(this.m("menupopup"))); } }, }); var {prefs} = Services; G = { pref(key,set){ //или key = [key,default] if (!Array.isArray(key)) key = [key]; var t = prefs.getPrefType(key[0]), m = {b:"Bool",n:"Int",s:"String"}; t = m[t == 128 ? "b" : t == 64 ? "n" : t == 32 ? "s" : ""]; if (set == "get") return t; //тип опции if (!t) t = m[set != undefined ? (typeof set)[0] : (typeof key[1])[0]]; if (t) if (set != undefined) prefs[`set${t}Pref`](key[0],set) else set = prefs[`get${t}Pref`](...key); return set; }, v: "permissions.default.image", pdi: "chrome://browser/skin/canvas-blocked.svg", chk: "chrome://devtools/skin/images/check.svg", nul: "chrome://devtools/skin/images/blocked.svg", } })("ucf_test_menu"); |
Dumby > 15-03-2024 14:46:57 |
unter_officer пишет
Даже не знаю, может так попробовать скрытый текст Выделить код Код:/* var root = doc.documentElement; var body = doc.body || root; var scroller = body.scrollHeight > root.scrollHeight ? body : root; */ var scroller = doc.scrollingElement; Dobrov пишет
Разве? Код-то как раз пашет, но пункт не render'ится. Когда добавляешь пункт в основное меню он render'ится сразу, Можно сразу принудительно отрендерить, но лучше, наверно, отложить. Вобщем, так поменял фрагмент кода создания виджета скрытый текст Выделить код Код:CustomizableUI.getWidget(id)?.label || (self => CustomizableUI.createWidget(self = { id, label: id, tooltiptext: id, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.style.setProperty("list-style-image", "url(chrome://branding/content/icon32.png)"); btn.type = "menu"; var doc = btn.ownerDocument, m = nn => doc.createXULElement(nn); var popup = m("menupopup"), menu = m("menuitem"); menu.m = m; menu.fill = this.fill; menu.render = this.render; popup.append(menu); btn.prepend(popup); }, render(){ var popup = this.parentNode; this.remove(); this.fill(MyMenu, popup); }, fill(o, popup) { for (key in o) { var val = o[key]; if (typeof val != "object") continue; var {lab, inf, img, cmd, alt, sep, men, upd} = val; sep && popup.append(this.m("menuseparator")); var name = men ? "menu" : "menuitem"; var item = this.m(name); item.setAttribute("label", lab || key); // item.alt = alt; //RClick в ucf_hookClicks.js {Mouse… if (inf) item.tooltipText = inf; if (img || /this\.image.*=/.test(upd)) item.className = name + "-iconic", item.setAttribute("image", img || G.nul); men || cmd && item.setAttribute("oncommand", cmd.toString().replace( /cmd\(.*?\){/, "{var trg = event.target || event;" )); popup.append(item); if (upd) if (item.renderedOnce) (item.render = upd).call(item); else item.upd = upd, item.render = self.renderSub; men && this.fill(val, item.appendChild(this.m("menupopup"))); } }, renderSub() { delete this.render; this.render(); this.render = self.updSub; this.upd(); }, updSub() { this.parentNode.state.startsWith("c") || this.upd(); } }))(); |
unter_officer > 15-03-2024 17:16:39 |
Dumby пишет
Dumby, большое спасибо. Как всегда всё супер! |
Dobrov > 16-03-2024 16:59:51 |
Dumby - спасибо, добавил примеры в пользовательское меню, где меняются иконки, текст и подсказки в зависимости от настроек. Обновил меню в ucf_hookClicks.js и исправил совместимость с UCF 2024. |
Vitaliy V. > 16-03-2024 18:41:23 |
Dobrov пишет
Немного запоздало я как раз недавно обновил несколько файлов config.js user_chrome.js vertical_top_bottom_bar.css |
Dobrov > 16-03-2024 18:56:23 |
Vitaliy V. - спасибо! |
b0ttle > 16-03-2024 22:42:39 |
Dobrov |
_zt > 16-03-2024 23:32:57 |
Vitaliy V. |
Dobrov > 17-03-2024 04:13:31 |
Dumby такой глупый вопрос: JS скрипты будут дóльше поддерживаться в Firefox, чем JSM-ки? Если это так, то возможно переделать в JS скрипт сохранения страниц SingleHTML.JSM (в custom_scripts UCF 2024 тоже JS-скрипты) b0ttle пишет
в ucf_hookClicks.js код слишком компактный, чтоб легко подстроить «под себя» строки меню/нажатия клавиш/клики мыши в первых блоках. Позже отформатирую по правилам, разграничив блоки разных назначений. |
Dobrov > 17-03-2024 07:08:48 |
Vitaliy V. - пожелание: Выделить код Код:const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm"); var os = name => `${name.replace(/\.[^.$]+$/,'')}_${AppConstants.platform}${name.lastIndexOf('.') > 0 ? "."+ name.split('.').pop() : ""}`; ………… stylesall: [ // Для всех документов { path: "custom_styles_all_user.css", type: "USER_SHEET", sheet() { registerSheet(this); }, }, // стиль для вашей операционной системы: *_macosx.css, *_linux.css, *_win.css { path: os("custom_styles_all_user.css"), type: "USER_SHEET", sheet() { registerSheet(this); }, }, ], |
Vitaliy V. > 17-03-2024 13:24:36 |
Dobrov пишет
Да, но для стилей есть медиа запросы, например: |
Dobrov > 17-03-2024 13:57:49 |
Vitaliy V. пишет
Для портабельного или личного профиля, запускаемого и используемого на всяких OS. Примеры стилей обычно только для винды, я пробовал @media (-moz-platform:, но неудобство в том, что придётся править стили при каждом их обновлении. |
Dumby > 18-03-2024 20:30:25 |
_zt пишет
Не понял. Если сделал как написано в первой строке Неизменившийся у меня не работает, хотя мне казалось, что будет.
Хорошо, попробую. скрытый текст Выделить код Код:var clickInterval = 5*60; var intervals = [ 10, 15, 30, 60, 3*60,/* 5*60,*/ 15*60, 30*60, 60*60, ]; var name = "TreeStyleTabAutoReloader"; var addonId = "treestyletab@piro.sakura.ne.jp"; var sfx = "ucf-tst-tab-autoreload", id = `extension:${addonId}:${sfx}`; var sheets = { def(name, css) { Object.defineProperty(this, name, {configurable: true, get() { delete this[name]; return this[name] = this.pre(name, css); }}); }, pre(name, css) { var ios = Services.io; var rph = ios.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var type = "USER_SHEET"; return (this.pre = (name, css) => { var subst = "tst-autoreload-stylesheet-" + name; rph.setSubstitution(subst, ios.newURI("data:text/css," + encodeURIComponent(css))); return [sss.preloadSheet(ios.newURI(`resource://${subst}/`), sss[type]), Ci.nsIDOMWindowUtils[type]]; })(name, css); } }; if (!ChromeUtils.domProcessChild.childID) { var ep = "resource://gre/modules/ExtensionParent.sys.mjs"; var manager = ChromeUtils.importESModule(ep).ExtensionParent.apiManager; var tt = manager.global.tabTracker; var ss = "resource:///modules/sessionstore/SessionStore.sys.mjs"; ss = ChromeUtils.importESModule(ss).SessionStore; var gsec = tab => ss.getCustomTabValue(tab, id); var webExt, addonUUID; var waitAddon = (e, isAppShutdown) => isAppShutdown || ( webExt = null, manager.on("ready", onReady) ); var onReady = (e, addon) => { if (addon.id != addonId) return; manager.off("ready", onReady); addon.once("shutdown", waitAddon); onAddon(addon); } var onAddon = addon => { webExt = addon; if (addonUUID == addon.uuid) return; addonUUID && ChromeUtils.unregisterWindowActor(name); var esModuleURI = Components.stack.filename; ChromeUtils.registerWindowActor(name, { parent: {esModuleURI}, remoteTypes: ["extension"], messageManagerGroups: ["webext-browsers"], child: {esModuleURI, events: {pageshow: {}}}, matches: [`moz-extension://${addonUUID = addon.uuid}/sidebar/sidebar.html?*`] }); } var format = sec => { var map = new Map(); // resource://gre/modules/PluralForm.jsm var f = n => n % 10 == 1 && n % 100 != 11 ? 0 : n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 10 || n % 100 >= 20) ? 1 : 2; var hh = ["", "а", "ов"], ms = ["а", "ы", ""]; return (format = sec => { var res = map.get(sec = +sec); if (!res) { var num, arr = []; if ((num = Math.floor(sec / 3600)) > 0) sec -= num * 3600, arr.push(`${num} час${hh[f(num)]}`); if ((num = Math.floor(sec / 60)) > 0) sec -= num * 60, arr.push(`${num} минут${ms[f(num)]}`); sec > 0 && arr.push(`${sec} секунд${ sec > Math.floor(sec) ? "ы" : ms[f(sec)] }`); map.set(sec, res = arr.join(" ")); } return res; })(sec); } var hasDef = intervals.includes(clickInterval); hasDef || intervals.push(clickInterval); sheets.def("sb", ` #context_autoreloadTab:not([checked]) > .menu-iconic-left,${ hasDef ? "" : "\n\t\t#context_autoreloadTab[checked][def=true] > menupopup > :nth-child(2)," } #context_autoreloadTab:not([checked]) > menupopup > :first-child { fill: gray !important; -moz-context-properties: fill !important; list-style-image: url("chrome://global/skin/icons/reload.svg") !important; } #context_autoreloadTab[checked] > .menu-iconic-left > image { fill: currentColor !important; -moz-context-properties: fill !important; list-style-image: url("chrome://global/skin/icons/check.svg") !important; } `); clickInterval = String(clickInterval); var sym = Symbol(name); var TreeStyleTabAutoReloaderParent = class extends JSWindowActorParent { actorCreated() { var win = this.browsingContext.embedderElement.ownerGlobal; var mo = win[sym]; if (!mo) { win.windowUtils.addSheet(...sheets.sb); mo = win[sym] = new win.MutationObserver(this.handleMutations); var popup = win.document.getElementById("contentAreaContextMenu"); mo.obs = mo.observe.bind(mo, popup, {childList: true}); mo.win = win; } ((mo.actor = this).mo = mo).obs(); } didDestroy() { this.mo.disconnect(); } get menu() { var value = this.mo.menu; if (!value) { value = this.mo.win.MozXULElement.parseXULToFragment( `<menu id="context_autoreloadTab" class="menu-iconic" onclick="if (event.target == this) linkedObject.click(this);" > <menupopup oncommand="parentNode.linkedObject.cmd(event);"/> </menu>` ); (value = this.mo.menu = value.firstChild).remove(); value.linkedObject = this; (value.popup = value.firstChild).initShadowDOM = this.initShadowDOM; } return Object.defineProperty(this, "menu", {value}).menu; } initShadowDOM() { delete this.initShadowDOM; this.initShadowDOM(); var df = this.ownerGlobal.MozXULElement.parseXULToFragment( `<menuitem closemenu="single" label="Не перезагружать" oncommand="event.stopPropagation(); parentNode.parentNode.click();"/> <menuitem label="Другой…" oncommand="event.stopPropagation(); parentNode.parentNode.linkedObject.prompt();"/> <menuseparator/>` ); var doc = this.ownerDocument; for(var sec of intervals) { var menuitem = doc.createXULElement("menuitem"); menuitem.setAttribute("type", "radio"); menuitem.setAttribute("closemenu", "single"); menuitem.setAttribute("value", sec); menuitem.setAttribute("label", format(sec)); df.append(menuitem); } hasDef || df.firstChild.after(df.lastChild); this.append(df); this.parentNode.linkedObject.updMenupopup(this); this.setAttribute("onpopupshowing", "parentNode.linkedObject.updMenupopup(this);"); } handleMutations(muts) { var cm = this.win.gContextMenu; if (cm) for(var mut of muts) for(var node of mut.addedNodes) if (node.id == "treestyletab_piro_sakura_ne_jp-menuitem-_context_duplicateTab") { var {tabId} = cm.contentData.webExtContextData; var tab = tt.getTab(tabId); //if (tab?.linkedBrowser.currentURI.scheme.startsWith("http")) { if (tab) { var {menu} = this.actor; menu.tabId = tabId; node.after(menu); this.actor.maybeSetLabel(tab); webExt.apiManager.global.gMenuBuilder.itemsToCleanUp.add(menu); } break; } } maybeSetLabel(tab) { var sec = gsec(tab); var has = this.menu.hasAttribute("checked"); if (Boolean(sec) ^ has) has = !has, this.menu.toggleAttribute("checked"); var curr = has && sec; curr !== this.menu.sec && this.setLabel(curr); } setLabel(sec) { this.menu.setAttribute("label", (this.menu.sec = sec) ? `Интервал перезагрузки: ${format(sec)}` : "Задать интервал перезагрузки" ); hasDef || this.menu.setAttribute("def", sec == clickInterval); } click(menu) { var {tabId} = menu; var has = menu.toggleAttribute("checked"); has ? this.initTab(tabId, clickInterval) : this.destroyTab(tabId); var w = menu.clientWidth; this.setLabel(has && clickInterval); if (menu.popup.state == "open") this.updMenupopup(menu.popup), menu.clientWidth != w && menu.ownerGlobal.setTimeout(this.move, 50, menu); } cmd(e) { var {value} = e.target; if (value == this.menu.sec) return; var {tabId} = this.menu; this.setLabel(value); if (this.menu.hasAttribute("checked")) this.changeInterval(tt.getTab(tabId), value); else this.menu.toggleAttribute("checked"), this.initTab(tabId, value); } changeInterval(tab, sec) { var win = tab.ownerGlobal; win.clearInterval(tab.getAttribute(sfx)); ss.setCustomTabValue(tab, id, sec); tab.setAttribute(sfx, win.setInterval(bro.reload, sec * 1e3, tab)); } async prompt(val) { var {menu} = this, {sec} = menu, {prompt} = Services; var res = await prompt.asyncPrompt( null, prompt.MODAL_TYPE_WINDOW, val ? "ЕЩЁ РАЗ:" : "Задать интервал обновления", "Введите число секунд авто-обновления", val || sec || clickInterval, null, null ); if (!res.get("ok")) return; var val = res.get("value"); if (!val) return; if (!isFinite(val)) return this.prompt(val); var {tabId} = menu, val = String(Math.round(val) || 1); sec ? this.changeInterval(tt.getTab(tabId), val) : this.initTab(tabId, val); } move(menu) { menu.popup.moveToAnchor(menu, "end_before"); } updMenupopup(popup) { var old = popup.querySelector("[checked=true]"); var {sec} = this.menu; var cur = sec && popup.querySelector(`[value="${sec}"]`); if (old != cur) old?.removeAttribute("checked"), cur && cur.setAttribute("checked", true); } initTab(tabId, sec, skipSet) { bro.initTab(tt.getTab(tabId), sec); this.sendAsyncMessage(tabId, true); } destroyTab(tabId) { bro.destroyTab(tt.getTab(tabId)); this.sendAsyncMessage(tabId); } receiveMessage(msg) { msg.name && bro.destroyTab(tt.getTab(+msg.name)); } } var bro = { async observe(win) { var tc = win.document.getElementById("tabbrowser-tabs"); var tp = win.document.getElementById("tabbrowser-tabpanels") var types = ["EndSwapDocShells", "TabClose", "SSTabRestored"]; var destructor = (meth = "removeEventListener") => types.forEach( (type, ind) => (ind ? tc : tp)[meth](type, this, ind == 0) ); destructor("addEventListener"); win.ucf_custom_script_win[id] = {destructor}; win.ucf_custom_script_win.unloadlisteners.push(id); await ss.promiseAllWindowsRestored; for(var tab of win.gBrowser.tabs) tab.linkedPanel || this.maybeInitTab(tab); }, maybeInitTab(tab) { var sec = gsec(tab); sec && this.initTab(tab, sec, true); }, handleEvent(e) { this[e.type](e); }, reload(tab) { tab.ownerGlobal.gBrowser.reloadTab(tab); }, initTab(tab, sec, skipSet) { skipSet || ss.setCustomTabValue(tab, id, sec); tab.setAttribute(sfx, tab.ownerGlobal.setInterval(this.reload, sec * 1e3, tab)); }, destroyTab(tab) { tab.ownerGlobal.clearInterval(tab.getAttribute(sfx)); ss.deleteCustomTabValue(tab, id); tab.removeAttribute(sfx); }, TabClose(e) { var intervalId = e.target.getAttribute(sfx); if (!intervalId) return; e.target.ownerGlobal.clearInterval(intervalId); var tab = e.detail.adoptedBy; tab && this.initTab(tab, gsec(e.target)); }, SSTabRestored(e) { var tab = e.target; tab.hasAttribute(sfx) || this.maybeInitTab(tab); }, async EndSwapDocShells(e) { var br = e.detail, trg = e.target, win = br.ownerGlobal; await new Promise(win.requestAnimationFrame); if (!win.closed) return; var tab = win.gBrowser.getTabForBrowser(br); if (!tab) return; var sec = gsec(tab); if (sec) tab = trg.ownerGlobal.gBrowser.getTabForBrowser(trg), tab.hasAttribute(sfx) || this.initTab(tab, sec); } }; var topic = "browser-delayed-startup-finished"; var {obs} = Services; obs.addObserver(bro, topic); obs.addObserver(function quit(s, t) { obs.removeObserver(quit, t); obs.removeObserver(bro, topic); }, "quit-application-granted"); var policy = WebExtensionPolicy.getByID(addonId); if (policy) onAddon(policy.extension), policy.extension.once("shutdown", waitAddon); else waitAddon(); } else { sheets.def("tst", ` :root { --ar-ind-width: 22px; } .autoreload-indicator { height: 14px !important; position: relative !important; z-index: var(--tab-ui-z-index) !important; opacity: .6 !important; fill: currentColor !important; -moz-context-properties: fill !important; min-width: var(--ar-ind-width) !important; background: no-repeat center/60% url("chrome://global/skin/icons/reload.svg") !important; } .autoreload-indicator:hover { opacity: 1 !important; } tab-item-substance[autoreload] > .extra-items-container.front { right: calc(var(--tab-label-end-offset) + var(--ar-ind-width)) !important; } tab-item.faviconized .autoreload-indicator { min-width: 12px !important; background-size: 100% !important; } tab-item.faviconized > tab-item-substance[autoreload] { padding-inline-start: 0 !important; } `); var opts = {childList: true}; var TreeStyleTabAutoReloaderChild = class extends JSWindowActorChild { handleEvent(e) { this.sendAsyncMessage(""); this.stopReload = this.stopReload.bind(this); var doc = e.target, win = doc.ownerGlobal; win.windowUtils.addSheet(...sheets.tst); var mos = this.mos = new Set(); for(var div of doc.querySelectorAll( "#pinned-tabs-container, #normal-tabs-container > .virtual-scroll-container" )) { var mo = new win.MutationObserver(this.catchUL); mos.add(mo); mo.actor = this; mo.observe(mo.div = div, opts); } } catchUL() { var ul = this.div.querySelector(":scope > ul"); if (!ul) return; this.disconnect(); this.actor.mos.delete(this); var mo = new this.constructor(this.actor.catchTabItem); (mo.actor = this.actor).mos.add(mo); mo.observe(ul, opts); for(var node of ul.children) mo.actor.check(node); } catchTabItem(muts) { for(var mut of muts) for(var node of mut.addedNodes) this.actor.check(node); } check(node) { node.nodeName == "TAB-ITEM" && this.onTab(node); } async onTab(tab, tabId) { var subs = tab.querySelector("tab-item-substance"); var win = tab.ownerDocument.defaultView.wrappedJSObject; if (!tabId) { if (subs.hasAttribute("autoreload")) subs.removeAttribute("autoreload"), subs.querySelector(".autoreload-indicator")?.remove(); var {tabId} = subs.dataset; var sec = await win.browser.sessions.getTabValue(+tabId, sfx); if (!sec) return; } subs.toggleAttribute("autoreload", true); var ind = win.document.createElement("span"); ind.className = "autoreload-indicator"; ind.title = "Остановить перезагузку"; ind.tabId = tabId; ind.onmousedown = this.stopReload; subs.querySelector("tab-closebox").before(ind); } stopReload(e) { if (e.button) return; e.stopImmediatePropagation(); var trg = e.target.wrappedJSObject; this.sendAsyncMessage(trg.tabId); this.removeIndicator(trg); } removeIndicator(ind) { ind.closest("tab-item-substance").removeAttribute("autoreload"); ind.remove(); } receiveMessage(msg) { var tab = this.contentWindow.document.getElementById("tab-" + msg.name); if (tab) msg.data ? this.onTab(tab, msg.name) : this.removeIndicator(tab.querySelector(".autoreload-indicator")); } didDestroy() { var {mos} = this; if (!mos) return; for(var mo of mos) mo.disconnect(); mos.clear(); } } } export {TreeStyleTabAutoReloaderParent, TreeStyleTabAutoReloaderChild}; скрытый текст Выделить код Код:var timeout = 500; if (!ChromeUtils.domProcessChild.childID) { var popupWidth = 300; var label = "Some Label"; var tooltiptext = "Some Tooltip Text"; var imgEnabled = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="16"><rect fill="limegreen" width="16" height="16"/></svg>'; var imgDisabled = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="16"><rect fill="orangered" width="16" height="16"/></svg>'; var btnImage, popupPosition, enabled, addonUUID, registeredUUID; var mo = (p, r = "gre") => ChromeUtils.importESModule(`resource://${r}/modules/${p}.sys.mjs`)[p]; //-------[ Addon ]------------------------------------------------------ var addonId = "treestyletab@piro.sakura.ne.jp"; var manager = mo("ExtensionParent").apiManager; var tt = manager.global.tabTracker; var waitAddon = (e, isAppShutdown) => isAppShutdown || ( addonUUID = null, manager.on("ready", onReady) ); var onReady = (e, addon) => { if (addon.id != addonId) return; manager.off("ready", onReady); addon.once("shutdown", waitAddon); addonUUID = addon.uuid; checkRegistration(); } waitAddon(); //-------[ Actor registration ]------------------------------------------------------ var name = "TreeStyleTabPreviewPopup"; var esModuleURI = Components.stack.filename; var reg = () => ChromeUtils.registerWindowActor(name, { parent: {esModuleURI}, remoteTypes: ["extension"], messageManagerGroups: ["webext-browsers"], child: {esModuleURI, events: {mouseover: {}}}, matches: [`moz-extension://${registeredUUID = addonUUID}/sidebar/sidebar.html*`] }); var unreg = () => { registeredUUID = null; ChromeUtils.unregisterWindowActor(name); } var checkRegistration = () => { if (enabled) { if (registeredUUID) { if (registeredUUID == addonUUID) return; addonUUID && unreg(); } addonUUID && reg(); } else if (registeredUUID && addonUUID) unreg(); } //------[ Observer ]------------------------------------------------------ var {prefs, obs} = Services; var pref = "ucf_tst_preview_popup"; var branch = prefs.getBranch("sidebar."); var prefObs = { observe(b, t, data) { this[data]?.(branch.getBoolPref(data, true)); }, position_start: val => popupPosition = val ? "end_before" : "start_before", [pref](val) { btnImage = (enabled = val) ? imgEnabled : imgDisabled; this.setBtnsImg(); checkRegistration(); }, setBtnsImg: () => prefObs.setBtnsImg = () => { var widget = cui.getWidget(btnId); for(var win of cui.windows) widget.forWindow(win).node?.setAttribute("image", btnImage); } }; for (let p of [pref, "position_start"]) prefObs.observe(null, null, p); branch.addObserver("", prefObs); obs.addObserver(function quit(s, topic) { obs.removeObserver(quit, topic); branch.removeObserver("", prefObs); }, "quit-application-granted"); //-------[ Widget ]------------------------------------------------------ var popupId = "ucf-tst-preview-popup"; var btnId = popupId + "-button"; var cui = mo("CustomizableUI", ""); var toggle = () => branch.setBoolPref(pref, !enabled); cui.createWidget({ id: btnId, label, tooltiptext, localized: false, onCreated(btn) { btn._handleClick = toggle; btn.setAttribute("image", btnImage); } }); //-------[ Actor ]------------------------------------------------------ var TreeStyleTabPreviewPopupParent = class extends JSWindowActorParent { actorCreated() { var doc = this.browsingContext.topChromeWindow.document; var popup = doc.getElementById(popupId); if (!popup) { popup = doc.createXULElement("menupopup"); popup.id = popupId; popup.setAttribute("ignorekeys", true); popup.setAttribute("rolluponmousewheel", true); popup.setAttribute("consumeoutsideclicks", "never"); popup.shadowRoot.querySelector("style").append(` :host { padding: 0 !important; -moz-appearance: none !important; } arrowscrollbox::part(scrollbutton-up), arrowscrollbox::part(scrollbutton-down) { display: none !important; } `); (popup.canvas = popup.appendChild(doc.createElement("canvas"))) .width = popupWidth; popup.context = popup.canvas.getContext("2d", {alpha: false}); doc.getElementById("mainPopupSet").append(popup); } this.popup = popup; } receiveMessage(msg) { var id = msg.data; if (!id) return this.popup.hidePopup(); var tab = tt.getTab(+id.slice(4)); if (tab/* && !tab.selected*/) { var cwg = tab.linkedBrowser.browsingContext?.currentWindowGlobal; cwg && this.drawSnapshot(tab.ownerGlobal, cwg, id); } } async drawSnapshot(win, cwg, id) { var {width, height} = await cwg.getActor("Thumbnails") .sendQuery("Browser:Thumbnail:ContentInfo"); if (width < 200) return; var k = popupWidth / width; try {var bitmap = await cwg.drawSnapshot( new DOMRect(0, 0, width, height), k, "white" );} catch {} if (!bitmap) return; var data = await this.sendQuery(id, win.devicePixelRatio); if (!data) return; this.popup.canvas.height = k * height; this.popup.context.drawImage(bitmap, 0, 0); bitmap.close(); this.popup.openPopupAtScreenRect(popupPosition, ...data); } didDestroy() { this.popup.hidePopup(); this.popup = null; } } } export {TreeStyleTabPreviewPopupParent}; export class TreeStyleTabPreviewPopupChild extends JSWindowActorChild { actorCreated() { this.args = ["mouseleave", () => { this.tab = null; this.tid || this.sendAsyncMessage(""); this.tid = this.clearTimeout(); }, {once: true}]; } mult(val) { return this * val; } receiveMessage(msg) { var tab = this.document.getElementById(msg.name); var res = tab?.matches(":hover"); if (res) { var {x, y, width, height} = tab.getBoundingClientRect(); var win = tab.ownerGlobal; res = [ x + win.mozInnerScreenX, y + win.mozInnerScreenY, width, height ]; var z = win.devicePixelRatio; if (z != 1 || msg.data != 1) res = res.map(this.mult, z / msg.data); } return res; } handleEvent(e) { var tab = e.target.closest("tab-item"); if (!tab || tab == this.tab) return; this.clearTimeout(); this.tid = this.contentWindow .setTimeout(this.onTab, timeout, this.tab = tab, this); tab.addEventListener(...this.args); } clearTimeout() { this.tid && this.contentWindow.clearTimeout(this.tid); } onTab(tab, self) { self.tid = null; tab.wrappedJSObject.apiTab.discarded || self.sendAsyncMessage("", tab.id); } didDestroy() { this.tab = null; } } Dobrov пишет
Ну почему, не такой уж глупый, если имеются в виду Увы, в обозримом прошлом и настоящем,
А вот это уже глупее. Кстати, а чего там win до сих пор торчит? fp.init(win, "", fp.modeSave); Vitaliy V. Удаление псевдокласса :-moz-lwtheme уже пошло в autoland, |
Dobrov > 19-03-2024 01:47:00 |
Dumby пишет
А как сделать, чтоб скрипт SingleHTML.mjs был совместим с FF115+ …… FF125+ ? посмотрел custom_buttons-0.0.7.0.0.33-fx. У тебя в SelfHelper.jsm: SingleHTML.mjs (или JSM, если child: {moduleURI: __URI__}) Выделить код Код:/* SingleHtml © Лекс, правка Dumby, mod Dobrov вызов: Cu.getGlobalForObject(Cu)[Symbol.for("SingleHTML")](to, window) scriptsbackground [System Principal], «to» пуст: выбор пути */ var self, name = "SingleHTML", EXPORTED_SYMBOLS = [name + "Child"]; var {io, focus, obs, prefs, dirsvc} = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services; export class SingleHTMLChild extends JSWindowActorChild { //класс = name + Child receiveMessage() { return htmlAndName(this.contentWindow);} } ChromeUtils.domProcessChild.childID || ({ init(topic) { ChromeUtils.registerWindowActor(name, { allFrames: true, child: {esModuleURI: Components.stack.filename}, messageManagerGroups: ["browsers"] }); obs.addObserver(self = this, topic); obs.addObserver(function quit(s, t) { obs.removeObserver(quit, t); obs.removeObserver(self, topic); }, "quit-application-granted"); this.handleEvent = e => this[e.type](e); globalThis[Symbol.for(name)] = this.SingleHTML; //общие функции globalThis[Symbol.for('TitlePath')] = this.TitlePath; }, observe(win) { win.document.getElementById("appMenu-popup").addEventListener("popupshowing", this); win.addEventListener("unload", this); }, popupshowing(e) { this.unload(e); var popup = e.target; var btn = popup.ownerDocument.createXULElement("toolbarbutton"); btn.id = "appMenu-ucf-save-html-button"; btn.setAttribute("label", "Всё или выбранное в единый HTML"); var before = "appMenu-save-file-button2", subviewbutton = "subviewbutton"; btn.className = subviewbutton; btn.setAttribute("oncommand", "SingleHTML();"); btn.SingleHTML = this.SingleHTML; popup.querySelector('toolbarbutton[id^="'+ before +'"]').before(btn); }, unload(e) { var win = e.target.ownerGlobal; win.removeEventListener("unload", this); win.document.getElementById("appMenu-popup").removeEventListener("popupshowing", this); }, TitlePath(win, to, f, u, n = 0, h = 99) { //global if(parseInt(to) > 0) [n,to] = [to,n]; if(parseInt(to) < 0) h = Math.abs(to); if (typeof(to) != 'string' || !/.*\|/.test(to)) to = prefs.getStringPref("extensions.user_chrome_files.savedirs","|||0"); to = to.split('|').slice(0 + n, 2 + n); //Dir/Sub|[empty|0 title|1 url] f ||= win.gBrowser.selectedTab.label; f = f.replace(/\s+/g,' ').replace(/[\\\/?*\"'`]+/g,'').replace(/[|<>]+/g,'_').replace(/:/g,'։').slice(0,h).trim(); u ||= decodeURIComponent(win.gURLBar.value); n = f, h = u; u = /^file:\/\//.test(u) ? 'file' : u.replace(/^.*u=|https?:\/\/|www\.|\/.*/g,'').replace(/^ru\.|^m\./,'').replace(/\/.*/,''); to[1] = (to[1] == "0") ? f : (to[1] == "1") ? u : ""; f += "_"+ new Date().toLocaleDateString('ru', {day: 'numeric',month: 'numeric',year: '2-digit'}) +'-'+ new Date().toLocaleTimeString('en-GB').replace(/:/g,"։"); //дата-часы try {var dir = dirsvc.get("DfltDwnld",Ci.nsIFile);} catch {dir = prefs.getComplexValue("browser.download.dir",Ci.nsIFile)} var map = l => win.DownloadPaths.sanitize(l); //FIX имён to.map(map).forEach(dir.append); to = dir.clone(); to.append(f +'.html'); return [dir, to.path, n, f, h, u]; //… имя, +дата, URL, домен }, async Succes(win, dir, dw = true, bg) { var {setTimeout} = ChromeUtils.import("resource://gre/modules/Timer.jsm"); var d = await win.Downloads.createDownload({source: "about:blank",target: win.FileUtils.File(dir)}); (await win.Downloads.getList(win.Downloads.ALL)).add(d); if (dw) await d.refresh(d.succeeded = true); //flash DWButton d = win.document.getElementById('urlbar-input-container'); d.style.background = dw ? 'rgba(0,200,0,0.3)' : 'rgba(250,0,0,0.2)'; setTimeout(() => {d.style.removeProperty('background-color')}, 350); }, async SingleHTML(to, win = this.ownerGlobal) { var br = win.gBrowser.selectedBrowser, bc = focus.focusedContentBrowsingContext; if (bc?.top.embedderElement != br) bc = br.browsingContext; var actor = bc?.currentWindowGlobal?.getActor(name); actor && self.save(win, ...await actor.sendQuery(""), to); //htmlAndName }, async save(win, data, fname, host, to) { var path = this.TitlePath(win, to, fname, host); //путь в зависимости от опций var dir = path[0], path = path[1]; dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777); if (!to) { // диалог выбора папки var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker); fp.init(win, "", fp.modeSave); fp.defaultString = path.split(/.*[\/|\\]/)[1]; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); var res = await new Promise(fp.open); if (res == fp.returnOK || res == fp.returnReplace) path = fp.file.path else return; } this.write(path, data); //нужна проверка на ошибки записи await this.Succes(win, path); }, write(path, html) { //без Ff 79-84 в save() IOUtils.writeUTF8 вместо this.write if (typeof IOUtils == "object") var write = IOUtils.writeUTF8 || IOUtils.writeAtomicUTF8; // Fx 85+ || 82-84 if (!write) { // Fx 79-81 var {OS} = ChromeUtils.import("resource://gre/modules/osfile.jsm"); write = (path, txt) => OS.File.writeAtomic(path, new TextEncoder().encode(txt)); } (this.write = write)(path, html); } }).init("browser-delayed-startup-finished"); var htmlAndName = async mainWin => { //не сохраняет SVG var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec;} catch {} }, getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r;} catch(e) {} } }, encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else img = obj; if (img.complete) try { canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }, toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','\x22':'\\\x22','\\':'\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }, selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location, ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild), meta = doc.createElement('meta'), sheets = doc.styleSheets; meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); var title = doc.getElementsByTagName('title')[0]; if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet);} } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var onlyName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); return [doctype + sel.innerHTML +'\n<a href='+ (loc.protocol != 'data:' ? loc.href : 'data:uri') +'><small><blockquote>источник: '+ new Date().toLocaleString("ru") +'</blockquote></small></a>', onlyName, loc.hostname]; } |
Farby > 19-03-2024 15:22:08 |
Dobrov пишет
.browsingContext нужен только для случая Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);, посему я придумал такой вариант: nsIFilePicker Выделить код Код:// fp.init(win fp.init((parseInt(Services.appinfo.platformVersion) >= 125 ? win.browsingContext : win) |
unter_officer > 19-03-2024 16:34:41 |
Dumby скрытый текст Выделить код Код:// // Открывать ссылки длинным кликом .......... // Dumby: https://forum.mozilla-russia.org/viewtopic.php?pid=797864#p797864 ..... // var delay = 500; // время удержания в мс var inBackground = false; // открывать в фоновой вкладке var relatedToCurrent = false; // открывать рядом с related вкладкой var name = "LPA", EXPORTED_SYMBOLS = [name + "Child", name + "Parent"]; var u = {get timer() { delete this.timer; return this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); }}; inBackground == null ? Object.defineProperty(u, "bg", { get: Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch) .getBoolPref.bind(null, "browser.tabs.loadInBackground") }) : u.bg = inBackground; if (!ChromeUtils.domProcessChild.childID) { var triggeringPrincipal = Cu.getObjectPrincipal(Cu); var LPAParent = class extends JSWindowActorParent { receiveMessage(msg) { var [link, inBackground, ref] = msg.data; this.manager.browsingContext.top .embedderElement.ownerGlobal.gBrowser.addTab(link, { triggeringPrincipal, relatedToCurrent, inBackground, }); } } ChromeUtils.registerWindowActor(name, { allFrames: true, parent: {moduleURI: __URI__}, messageManagerGroups: ["browsers"], child: {moduleURI: __URI__, events: {mousedown: {}}} }); } class LPAChild extends JSWindowActorChild { handleEvent(e) { if (e.type == "mousedown") { if (e.button || e.shiftKey || e.altKey || e.detail != 1) return; var a = e.originalTarget.closest("a[href]"); if (!a || a.href.startsWith("javascript:")) return; this.ctrl = e.ctrlKey; this.initLongPress(a); } else e.type == "click" && !this.link && e.preventDefault(), this.destroyLongPress(); } timeout() { var bg = this.ctrl != u.bg; var data = [this.link.href, bg]; this.sendAsyncMessage("", data); this.link = null; bg || this.destroyLongPress() //|| this.contentWindow.windowUtils.sendMouseEventToWindow("mouseup", -1, -1, 0, 1, 0); // Linux (?) } initLongPress(a) { this.contentWindow.addEventListener("click", this, true); this.contentWindow.addEventListener("dragstart", this, false); u.timer.initWithCallback(() => this.timeout(), delay, u.timer.TYPE_ONE_SHOT); this.link = a; } destroyLongPress() { this.contentWindow.removeEventListener("click", this, true); this.contentWindow.removeEventListener("dragstart", this, false); this.link && u.timer.cancel(); this.link = null; } didDestroy() { this.link && this.destroyLongPress(); } } |
_zt > 19-03-2024 17:49:49 |
Dumby пишет
Сделал давно, и уже забыл.
Спасибо, на 115esr работают.
|
Dumby > 20-03-2024 09:46:42 |
Farby пишет
Тут — да.
Да, суть выражена верно. Dobrov пишет
Не вижу какой-то несовместимости с FF115+ Там, где Services, просто сразу пишем Services. Метод write() подлежит удалению, Модуль Timer.jsm в 115 уже сконвертирован в Timer.sys.mjs Но, нужен ли этот импорт как таковой? Вот точно так же, вместо setTimeout можно написать win.setTimeout unter_officer пишет
Чисто формально, достаточно заменить парочку и перед class LPAChild extends JSWindowActorChild { export Но сам код какой-то неполноценный, _zt пишет
Так ты определил асинхронную функцию импрота модуля. Но если добавить перед оконечной точкой с запятой «;» url тоже можно заменить на круглые скобки, раз не используется. (не обязательно) Vitaliy V. скрытый текст Выделить код Код:@supports selector(:-moz-lwtheme) { * { color: green !important; } } @supports not selector(:-moz-lwtheme) { * { color: red !important; } } В 115 и 125 — всё зелёное. А в 126 — уже всё красное. |
unter_officer > 20-03-2024 10:46:28 |
Dumby пишет
Dumby, большое спасибо. Всё работает. |
_zt > 20-03-2024 18:38:38 |
Dumby
вы выше написали про встроенный метод, вот я и подумал, что это пример импорта. |
unter_officer > 20-03-2024 22:52:54 |
Dumby скрытый текст Выделить код Код:// // Кнопка сохраняет страницу с картинками или её часть, если она выделена, в html одним файлом .......... // Dumby: https://forum.mozilla-russia.org/viewtopic.php?pid=796993#p796993 ..... // var name = "UCFSaveSnapshotToHTML", EXPORTED_SYMBOLS = [name + "Child"]; if (!ChromeUtils.domProcessChild.childID) { ChromeUtils.import("resource:///modules/CustomizableUI.jsm").CustomizableUI.createWidget({ label: "Cохранить страницу в html", tooltiptext: "Cохранить страницу в html", id: "ucf_SaveSnapshotToHTML", localized: false, onCreated(btn) { btn._handleClick = click; btn.setAttribute("image", "chrome://devtools/skin/images/tool-application.svg"); } }); var click = async function() { var win = this.ownerGlobal; var bc = win.gBrowser.selectedBrowser.browsingContext; var fbc = win.Services.focus.focusedContentBrowsingContext; if (!fbc || fbc.top.id != bc.id) fbc = bc; var cwg = fbc.currentWindowGlobal; var fp = picker(win, "", Ci.nsIFilePicker.modeSave); var [fileContent, fileName] = await cwg.domProcess.getActor(name).sendQuery("", cwg.innerWindowId); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); await new Promise(fp.open) != fp.returnCancel && IOUtils.writeUTF8(fp.file.path, fileContent, {mode: "overwrite"}); } var picker = (...args) => { ChromeUtils.registerProcessActor(name, { includeParent: true, child: {moduleURI: __URI__} }); return (picker = Components.Constructor( "@mozilla.org/filepicker;1", "nsIFilePicker", "init" ))(...args); } } class UCFSaveSnapshotToHTMLChild extends JSProcessActorChild { receiveMessage(msg) { return snap(WindowGlobalChild.getByInnerWindowId(msg.data).browsingContext.window); } } var snap = mainWin => { var resolveURL = function (url, base) { try { return (new URL(url, base)).href; } catch {} }; var getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r; } catch(e) {} } }; var encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else { img = obj; }; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }; var toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild); var meta = doc.createElement('meta'); meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); var title = doc.getElementsByTagName('title')[0]; if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; var sheets = doc.styleSheets; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '').replace(/[\.]+/ig, ' ').replace(/[\,]+/ig, ' ').replace(/[\']+/ig, ' ').replace(/^\s+|\s+$/g, '').replace(/\s+/g, '_').slice(0, 100); fileName += (function () { var d = new Date(), z = function(n){return (n < 10 ? '0' : '') + n}; return '_' + '[' + z(d.getFullYear()) + '_' + z(d.getMonth()+1) + '_' + z(d.getDate()) + '\u2014' + z(d.getHours()) + '_' + z(d.getMinutes()) + '_' + z(d.getSeconds()) + ']'; })(); if(!/\.html?$/.test(fileName))fileName += '.html'; return [doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->', fileName]; } |
Dobrov > 21-03-2024 01:17:05 |
unter_officer на предыдущей странице SingleHTML.mjs сохраняет страницу или выделенное. |
unter_officer > 21-03-2024 02:36:34 |
Dobrov пишет
Ваш код добавляет пункт меню "Всё или выбранное в единый HTML" в "гамбургер". |
Dobrov > 21-03-2024 03:58:15 |
unter_officer - код универсальный, вы прочитали середину, но не увидели команду вызова в начале! Кроме того, SingleHTML.mjs позволяет 1) сохранять страницу с выбором папки или автоматически. Vitaliy V. может сможешь решить давнюю проблему скрипта SingleHTML.mjs ? Этот код не сохраняет SVG-графику, но работает быстрее, чем дополнение SingleFile и сохраняет страницу более компактно. |
unter_officer > 21-03-2024 09:47:46 |
Dobrov |
Dumby > 21-03-2024 11:09:50 |
_zt пишет
Чтобы далеко не ходить, заменил image на "about:logo". Но никакого «еще и меню» при этом увидеть не сподобился. unter_officer пишет
Да, но сам принцип конвертации от этого же не меняется. Всё тот же esModuleURI: Components.stack.filename вместо moduleURI: __URI__ И ChromeUtils.importESModule("resource:///modules/CustomizableUI.sys.mjs") EXPORTED_SYMBOLS тогда долой (не обязательно). |
unter_officer > 21-03-2024 11:40:03 |
Dumby пишет
Dumby, большое спасибо. Всё получилось. _zt пишет
_zt, вы смогли понять, когда начинает появляться контекстное меню? |
_zt > 21-03-2024 18:54:14 |
Dumby |
unter_officer > 21-03-2024 19:57:01 |
_zt скрытый текст Выделить код Код:(async () => CustomizableUI.createWidget({ id: "additional-toolbars-button", label: "Панели", tooltiptext: "ЛКМ: Переключить верт. панель\nПКМ: Переключить доп. панель", localized: false, // defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.setAttribute("context", false); btn.setAttribute("image", "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 16 16'><g><rect x='0' y='0' width='16' height='16' rx='1' ry='1' style='fill:rgb(0, 120, 173);'/><path style='fill:white;' d='M 2.5,1 C 1.7,1 1,1.7 1,2.5 V 13.5 C 1,14.3 1.7,15 2.5,15 H 13.5 C 14.3,15 15,14.3 15,13.5 V 2.5 C 15,1.7 14.3,1 13.5,1 Z M 3,2 H 13 C 13.7,2 14,2.3 14,3 V 13 C 14,13.7 13.7,14 13,14 H 3 C 2.3,14 2,13.7 2,13 V 3 C 2,2.3 2.3,2 3,2 Z M 7.3,3.03 C 7.11,3.03 6.95,3.2 6.95,3.4 V 4.09 C 6.6,4.18 6.28,4.34 5.96,4.5 L 5.45,3.99 C 5.39,3.93 5.3,3.9 5.23,3.9 5.14,3.9 5.04,3.93 4.95,3.99 L 3.99,4.98 C 3.84,5.1 3.85,5.33 3.99,5.49 L 4.5,5.96 C 4.31,6.28 4.18,6.6 4.09,6.95 H 3.37 C 3.17,6.95 3.01,7.11 3.01,7.3 V 8.67 C 3.01,8.89 3.17,9.05 3.37,9.05 H 4.09 C 4.18,9.4 4.31,9.72 4.5,10 L 3.99,10.5 C 3.85,10.7 3.84,10.9 3.99,11 L 4.95,12 C 5.1,12.1 5.33,12.1 5.45,12 L 5.96,11.5 C 6.28,11.7 6.6,11.8 6.95,11.9 V 12.6 C 6.95,12.8 7.11,13 7.3,13 H 8.7 C 8.89,13 9.05,12.8 9.05,12.6 V 11.9 C 9.4,11.8 9.72,11.7 10,11.5 L 10.5,12 C 10.7,12.1 10.9,12.1 11.1,12 L 12,11 C 12.2,10.9 12.2,10.7 12,10.5 L 11.5,10 C 11.7,9.72 11.8,9.4 11.9,9.05 H 12.6 C 12.8,9.05 13,8.89 13,8.67 V 7.3 C 13,7.11 12.8,6.95 12.6,6.95 H 11.9 C 11.8,6.6 11.7,6.28 11.5,5.96 L 12,5.49 C 12.2,5.33 12.2,5.1 12,4.98 L 11.1,3.99 C 10.9,3.86 10.7,3.86 10.5,3.99 L 10,4.5 C 9.72,4.34 9.4,4.18 9.05,4.09 V 3.4 C 9.05,3.2 8.89,3.03 8.7,3.03 Z M 8,6.5 C 8.8,6.5 9.5,7.2 9.5,8 9.5,8.8 8.8,9.5 8,9.5 7.2,9.5 6.5,8.8 6.5,8 6.5,7.2 7.2,6.5 8,6.5 Z'/></g></svg>"); }, 0: "ucf-additional-vertical-bar", 2: "ucf-additional-top-bar", onClick(e) { var id = this[e.button]; id && CustomizableUI.setToolbarVisibility(id, e.target.ownerDocument.querySelector('#' + id).collapsed); } }))(); |
xrun1 > 21-03-2024 20:53:50 |
_zt пишет
Насколько понимаю, для ЛКМ эти две строки не нужны. Они только для ПКМ, чтобы меню не появлялось.
Это сказано по ссылке в посте №1381 (выше). |
Dumby > 21-03-2024 22:35:27 |
_zt пишет
Потаскал. По этим четырём. И после каждого такого потаскушества, честно жал ПКМ. Тем не менее, любая осознанная модификация кода |
unter_officer > 21-03-2024 23:16:24 |
Dumby пишет
Dumby, да тут и правда мистика какая-то. P.S. В общем посмотрю как в дальнейшем будет работать скрипт, который я выложил чуть выше. |
_zt > 22-03-2024 00:32:54 |
unter_officer пишет
Не стал, так как вперед попробовал предложенное Dumby btn.setAttribute("oncontextmenu", "return false"); |
unter_officer > 22-03-2024 00:48:19 |
_zt пишет
Вот с этим у меня пока проблем нет. |
Dobrov > 22-03-2024 05:04:43 |
Вопрос: чем заменить Services.wm.getMostRecentWindow("navigator:browser") на что-то попроще? пробовал разные варианты, пока в SingleHTML.mjs вписал такой второй аргумент по-умолчанию: |
Vitaliy V. > 22-03-2024 20:24:43 |
Тестируйте обновление UCF https://github.com/VitaliyVstyle/Vitali … hromeFiles скрытый текст Dobrov пишет
Посмотрел код, вывод такой нужно изображения искать не в клонированном DOM а оригинальном там значения img.width img.height не равны нулю. скрытый текст Выделить код Код:encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else img = obj; if (img.complete) try { canvas.width = img.naturalWidth || img.width || 128; canvas.height = img.naturalHeight || img.height || 128; canvas.getContext('2d').drawImage(img, 0, 0, canvas.width, canvas.height); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }, _zt пишет
Если в обновленном UCF проблемма присутствует сделайте видео как это происходит |
Dobrov > 23-03-2024 13:01:57 |
Vitaliy V. пишет
У меня появляющаяся дополнительная панель перекрывает и верхнюю часть страницы. |
VORON > 23-03-2024 14:10:26 |
Vitaliy V. |
Vitaliy V. > 23-03-2024 14:39:01 |
Dobrov пишет
Так и было задумано, так же как и верт. панель, сомневаюсь что кому то понравится постоянно дергающаяся разметка страницы. Dobrov пишет
Не понял, высота доп. панели никак не ограничена зависит от размера кнопок и т.д. что мешает сделать стилем как нравится Dobrov пишет
А где логика, если избыток места по ширине, то по высоте для доп. панели как раз и хорошо сделать автоскрытие, мне например неудобно пользоваться верт. панелью разве что для редко используемых кнопок. Да и насчет пожелание я не забыл пока руки не дошли, |
fuchsfan > 23-03-2024 14:57:17 |
egorsemenov06 Можно внешним css, а встроить его в скрипт я не умею. скрытый текст Выделить код Код:/* userChrome.css */ /* Icon Copy Link Text */ #context-copylinktext::before { /* margin-left: 4px !important; /* отступ от левой гран. до иконки. 0px - без отступа; -8px - меньше; 4px - больше */ margin-right: 4px !important; /* отступ от иконки до текста */ content: "" !important; display: block !important; width: 19px !important; height: 15px !important; background-image: url("file:///D:/your/path/to/icon/copy_link_text.png") !important; background-repeat: no-repeat !important; background-position: 0px 0px !important; background-size: 15px 15px !important; } |
Dumby > 23-03-2024 15:12:16 |
Dobrov пишет
Не только страницы, а вообще. Добавлено: упс, уже 57-я страница. egorsemenov06 пишет
Если не стилем, то, где-то перед menuitem.render(); скрытый текст Выделить код Код:// menuitem.className = "menuitem-iconic"; menuitem.image = "chrome://browser/content/robot.ico"; |
b0ttle > 23-03-2024 21:54:50 |
Vitaliy V. Вопрос, user_chrome.js и UcfPrefs.mjs, в этот раз оставил настройки по дефолту. Мне казалось, если потом включить в настройках нужные пункты. То один из файлов, подхватит, чтобы следующий раз не приходилось переназначать. Оказалось, ничего не меняется. Потому, странно, зачем 2 файла? К примеру, мне нужны включенные пункты стилей и скриптов. Их всегда нужно отдельно включать, или как раньше в файле свой значения выставить и все? |
Dobrov > 24-03-2024 00:26:21 |
Как заметил b0ttle, в новом профиле проблема, что стили/скрипты всегда отключены и нужно открывать опции UCF, затем сбрасывать startupCache (винда иногда глючит и нужно вручную удалять startupCache). Vitaliy V. пишет
Нужен Firefox 99+ для @media (-moz-platform:… , у меня как всегда нестандарт - на работе Астра Linux 1.6, где Firefox 84.
Мне удобна только вертикальная панель, она часто скрыта, там размещаю кнопки расширений, для которых нужен перехват кликов/клавиш, т.е. чтоб они инициализировались. |
_zt > 24-03-2024 03:42:23 |
Vitaliy V. пишет
Проблема присутствовала и скрипты тут не виноваты, кнопки прыгали и при скрытии через меню панелей. |
Vitaliy V. > 24-03-2024 22:38:59 |
b0ttle UPD: обновил архив UserChromeFiles.zip, а то забыл |
b0ttle > 25-03-2024 15:44:52 |
Vitaliy V. upd: Немного понял, но почти ничего. Точнее, нужно вникать в ход работы отдельных стилей. Легче в каждый отдельный код пришивать @-moz-document url, чем потом париться, в какой их кидать, в chrome, all, или еще куда. Ну, я так понял. Иначе, как-то запутанно выглядит. скрытый текст /** ************************▼ Settings ▼************************ */ /** Styles Settings: * path: path to file from folder custom_styles * type: style rights AGENT_SHEET,AUTHOR_SHEET or USER_SHEET */ styleschrome:[ //For documents of all windows [ChromeOnly] {path:"includes/special_widgets.css",type:"USER_SHEET"}, /*{path:"auto_hide_sidebar.css",type:"USER_SHEET"}*/ ], stylesall:[ //For all documents {path:"custom_styles_all_user.css",type:"USER_SHEET"}, //- внутри прописан импорт userchrome и другие. {path:"custom_styles_all_agent.css",type:"AGENT_SHEET"} //- импорт usercontent. ], |
Vitaliy V. > 25-03-2024 16:59:33 |
b0ttle пишет
Ну если не заморачиваться можно и в all, однако я не подключаю много стилей в all documents, для всех это то и значит вообще всех при каждом открытии страницы сайта, фрейма все эти стили будут загружаться а если отсутствует @-moz-document url то и пытаться применится где не надо, потому они и не включены по умолчанию. Короче в all подключаю стили для сайтов и общие, те стили для интерфейса что работают в userChrome.css в chrome, для служебных страниц в CustomStylesScriptsChild.mjs |
_zt > 26-03-2024 03:05:04 |
Вроде был скрипт добавляющий в контекстное меню изображений пункт открытия изображения в новой активной вкладке? скрытый текст Выделить код Код:browser.contextMenus.create({ title : "Открыть изображение", type : "normal", contexts : [ "image" ], onclick : viewimage }); function viewimage(data) { var imageurl = data.srcUrl; chrome.tabs.create({url: imageurl, active: true}); }; Сейчас открывается вообще после всех вкладок. Или, как заставить родной пункт контекстного меню , #context-viewimage, открывать изображения в новой активной вкладке и рядом с родителем? Сейчас пункт открывает вкладки как ссылки (т.е. после всех открытых ранее из этой вкладки ссылок) и не активирует их. Менять порядок открытия ссылок не вариант. |
fuchsfan > 26-03-2024 12:07:06 |
_zt пишет
В расширении Glitter Drag (by harytfw) есть такая опция, но драг-н-дропом. |
darex > 26-03-2024 12:24:53 |
Vitaliy V. |
Dumby > 26-03-2024 23:00:14 |
_zt пишет
Из какого ещё «расширения»? скрытый текст Выделить код Код:var q = {active: true}; browser.contextMenus.create({ title: "Открыть изображение", contexts: ["image"], onclick: async data => browser.tabs.create({ url: data.srcUrl, index: (await browser.tabs.query(q))[0].index + 1 }) });
Может так подойдёт скрытый текст Выделить код Код:(async extra => ChromeUtils.defineLazyGetter( document.getElementById("context-viewimage"), "gContextMenu", () => { var vm = eval( `(function ${nsContextMenu.prototype.viewMedia})` .replace('"tab";', extra) .replace(/referrerInfo,/g, "$& forceForeground,") ); return {viewMedia: e => vm.call(gContextMenu, e)}; } ))("$& var forceForeground = true; gBrowser.clearRelatedTabs();"); Vitaliy V. darex пишет
Вот кстати да, интересно. Для 115, насколько я понимаю, Но, в 121, влепили this.#handleQuickSuggestOptInCommand Такой метод, как я понимаю, ничем не достанешь, даже дебаггером, Но метод небольшой, зависит от другого подобного, который тоже небольшой. Вот, сочинял вариант, выходит какая-то жуть. Это я к тому, что повозиться, конечно, интересно, но, возможно, скрытый текст Выделить код Код:(async patchName => { await window.delayedStartupPromise; var btns = gURLBar.view.oneOffSearchButtons; btns.handleSearchCommand = function() { var proto = btns.constructor.prototype; var patch = proto[patchName]; if (!patch) { patch = proto[patchName] = Object.create(null); var func = proto.handleSearchCommand.toString(); var re = /if\s\([\n\s]+?userTypedSearchString\s&&[\n\s]+?engine\s&&[\n\s]+?\(event\.shiftKey\s\|\|\swhere\s!=\s"current"\)[\n\s]+?\)/; var code = `({${func}`.replace(" lazy.", " ").replace(re, "if (engine && !event.shiftKey)"); if (patch.priv = func.includes(".#")) { var privQuote = { handleQS(element) { var cont = this[symContainer]; if (cont && element?.compareDocumentPosition(cont) & Node.DOCUMENT_POSITION_CONTAINS) { this[symProvider]._handleCommand(element, this.view.controller, null, cont); return true; } } }; code = code.replace("#handleQuickSuggestOptInCommand", "handleQS") + ",\n" + privQuote.handleQS; } patch.code = code + "})"; } if (patch.priv) { var syms = UcfPrefs.dbg.gref.makeDebuggeeValue(btns).getOwnPrivateProperties(); var find = str => syms.find(sym => String(sym).includes(str)); var symProvider = find("quickSuggestOptInProvider"); var symContainer = find("quickSuggestOptInContainer"); } Object.assign(btns, eval(patch.code)).handleSearchCommand.apply(btns, arguments); } })("oneOffHandleSearchCommandPatch"); |
_zt > 27-03-2024 00:18:47 |
Dumby пишет
Это только для вас имеет значение. Но я постараюсь в вашем присутствии больше не оскорблять расширения приравнивая к ним дополнения. Dumby пишет
Отлично, то что нужно. Спасибо. Dumby пишет
А оно только активацию дает, открывает так же - в конце других дочерних. |
Vitaliy V. > 27-03-2024 00:41:57 |
darex Dumby пишет
Да тут же достаточно event.shiftKey изменить и все. скрытый текст Выделить код Код:(async () => { var {UrlbarSearchOneOffs} = ChromeUtils.importESModule("resource:///modules/UrlbarSearchOneOffs.sys.mjs"); var orig = UrlbarSearchOneOffs.prototype.handleSearchCommand; UrlbarSearchOneOffs.prototype.handleSearchCommand = function() { Object.defineProperty(arguments[0], "shiftKey", { enumerable: true, configurable: true, writable: false, value: !arguments[0].shiftKey ? true : false, }); return orig.apply(this, arguments); } })(); |
darex > 27-03-2024 07:36:41 |
Vitaliy V. Vitaliy V. пишет
Спасибо, всё работает! Dumby Dumby пишет
Спасибо, работает в custom_script_win.js! |
Dumby > 27-03-2024 12:26:45 |
_zt пишет
Это слегка сомнительно. Попробовал проверить с ним, и, вкладка с картинкой открывается как надо, Тогда модифицировал код так, чтобы он на какое-то время менял настройку TST И перепрыгивание вкладки с картинкой прекратилось. скрытый текст Выделить код Код:(async extra => ChromeUtils.defineLazyGetter( document.getElementById("context-viewimage"), "gContextMenu", () => { var func = win => { var cfg = win.configs, key = "autoAttachOnOpenedWithOwner"; var was = cfg[key]; cfg[key] = 6; // kNEWTAB_OPEN_AS_CHILD_TOP win.setTimeout(() => cfg[key] = was, 500); } var url = `data:,(${encodeURIComponent(func)})(content.wrappedJSObject);`; var vm = eval( `(function ${nsContextMenu.prototype.viewMedia})` .replace('"tab";', extra) .replace(/referrerInfo,/g, "$& forceForeground,") ); var send = () => WebExtensionPolicy.getByID("treestyletab@piro.sakura.ne.jp") ?.extension._backgroundPageFrameLoader.messageManager.loadFrameScript(url, false); return {viewMedia: e => vm.call(gContextMenu, e, send())}; } ))("$& var forceForeground = true; gBrowser.clearRelatedTabs();"); Vitaliy V. пишет
Хмм, действительно. Глаз — алмаз. Проверил — работает. Только причесал чуть-чуть, writable удалил, оно, вроде, автоматически становится false, Единственная разница с прошлым eval-патчем, это когда |
_zt > 27-03-2024 12:43:41 |
Dumby пишет
Да, точно. Забыл об этом. Dumby пишет
Еще как полезно. Спасибо. Этот вариант лучше, так как всегда открывает первой дочкой, а расширение в некоторых случаях открывает сестринской и даже "следующей соседней, но выше уровнем", если вкладка последняя в последнем дереве. |
Vitaliy V. > 27-03-2024 18:22:39 |
Dumby пишет
Точно он там лишний это я машинально записал не задумываясь скрытый текст Выделить код Код:(async ({UrlbarSearchOneOffs}) => { var orig = UrlbarSearchOneOffs.prototype.handleSearchCommand; UrlbarSearchOneOffs.prototype.handleSearchCommand = function handleSearchCommand() { var e = arguments[0]; Object.defineProperty(e, "shiftKey", { enumerable: true, configurable: true, writable: false, value: !e.shiftKey, }); return orig.apply(this, arguments); }; })(ChromeUtils.importESModule("resource:///modules/UrlbarSearchOneOffs.sys.mjs")); |
Dobrov > 28-03-2024 15:07:01 |
Vitaliy V. а что делает этот скрипт? Переделал под UCF 2024 коллекцию скриптов и Демо-профиль из шапки темы. p.s. форум часто недоступен – 504 Gateway Time-out |
Vitaliy V. > 28-03-2024 17:06:21 |
Dobrov пишет
При клике ЛКМ по значкам поисковиков по умолчанию входит в режим поиска данного поисковика, тут надо заметить что влияет настройка browser.search.openintab если true то страница поиска открывается в новой вкладке сразу после клика, но например на about:newtab поведение остается прежним. Скрипт делает везде чтобы поиск происходил сразу, а с зажатой клавишей Shift входил в режим поиска, т.е. делает наоборот раньше нужно было зажать Shift для немедленного поиска. |
Dobrov > 29-03-2024 07:43:38 |
Vitaliy V. - спасибо! При публикации кодов иногда не хватает их краткого описания! Вопрос: иногда файл пишется в папку с запретом записи или нет места в этой папке. |
Dumby > 29-03-2024 10:37:38 |
Dobrov IOUtils.writeUTF8(…).catch(log); |
Dobrov > 29-03-2024 19:03:05 |
Dumby спасибо! ClickPicSave.mjs Выделить код Код:// by Dumby сохранить картинку колёсиком или перетащив вправо; DBL поиск похожих export {MouseImgSaverChild, MouseImgSaverParent}; // forum.mozilla-russia.org/viewtopic.php?pid=800469#p800469 var u = {get it() { delete this.it; return this.it = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools); }}; ["E10SUtils", "PrivateBrowsingUtils"].forEach(name => Object.defineProperty(u, name, { configurable: true, enumerable: true, get() { var url = `resource://gre/modules/${name}.`; try {var exp = ChromeUtils.importESModule(url + "sys.mjs");} catch {exp = ChromeUtils.import(url + "jsm");} delete this[name]; return this[name] = exp[name]; } })); class MouseImgSaverChild extends JSWindowActorChild { handleEvent(e) { //клики мыши if (e.button > 1) return; //ЛКМ+СКМ var trg = e.explicitOriginalTarget; // dragstart trg.nodeType == Node.ELEMENT_NODE && trg instanceof Ci.nsIImageLoadingContent && this[e.type](trg, e); } handleDragEvent(e) { this[e.type](e); } dragstart(trg, e) { this.trg = trg; this.x = e.screenX; this.y = e.screenY; this.drag("add"); this.handleEvent = this.handleDragEvent; this.checkTextLinkyTool(trg.ownerDocument); } events = ["dragover", "drop", "dragend"]; drag(meth = (delete this.handleEvent, delete this.trg, "remove")) { meth += "EventListener"; var win = this.contentWindow; for(var type of this.events) win[meth](type, this, true); } drop() { this.drag(); } dragover(e) { var {x, y} = this, cx = e.screenX, cy = e.screenY, dx = cx - x, ax = Math.abs(dx), ay = Math.abs(cy - y); if (ax < 10 && ay < 10) return; if (dx < 0 || ax < ay) return this.drag(); this.x = cx; this.y = cy; } dragend(e) { // перетаскивание рисунка var dt = e.dataTransfer, {trg} = this; this.drag(); dt.mozUserCancelled || this.send(trg, e.screenX); // сохранить // dt.mozUserCancelled || this.sendAsyncMessage("dragend", (trg.currentRequestFinalURI || uri).spec); } auxclick(trg) { //СКМ trg.matches(":any-link :scope") || this.send(trg); } dblclick(trg) { // ЛКМ trg.matches(":any-link :scope") || this.sendAsyncMessage("dblclick", (trg.currentRequestFinalURI || uri).spec); } send(trg, sx) { var uri = trg.currentURI; if (!uri) return; var doc = trg.ownerDocument; var cookieJarSettings = u.E10SUtils .serializeCookieJarSettings(doc.cookieJarSettings); var referrerInfo = Cc["@mozilla.org/referrer-info;1"] .createInstance(Ci.nsIReferrerInfo); referrerInfo.initWithElement(trg); referrerInfo = u.E10SUtils.serializeReferrerInfo(referrerInfo); var contentType = null, contentDisposition = null; try { var props = u.it.getImgCacheForDocument(doc).findEntryProperties(uri, doc); var cs = Ci.nsISupportsCString; try {contentType = props.get("type", cs).data;} catch {} try {contentDisposition = props.get("content-disposition", cs).data;} catch {} } catch {} this.sendAsyncMessage("", { title: trg.closest("[title]")?.title, url: (trg.currentRequestFinalURI || uri).spec, contentType, referrerInfo, cookieJarSettings, contentDisposition, sx, isPrivate: u.PrivateBrowsingUtils.isContentWindowPrivate(trg.ownerGlobal) }); } checkTextLinkyTool(doc) { if (doc.title || !doc.documentURI.startsWith("moz-extension:")) return; var lab = doc.querySelector("body > label#lblFrom:first-child")?.textContent; if (lab) doc.title = lab.slice(0, lab.lastIndexOf("(")); } } if (!ChromeUtils.domProcessChild.childID) { var esModuleURI = Components.stack.filename; ChromeUtils.registerWindowActor("MouseImgSaver", { allFrames: true, parent: {esModuleURI}, messageManagerGroups: ["browsers"], child: {esModuleURI, events: {auxclick: {capture: true}, dblclick: {capture: true}, dragstart: {capture: true}}} }); var wref, titles = Object.create(null); var data = Object.assign(Object.create(null), { "browser.download.dir": {type: "String", get set() { var win = wref.get(), {prefs, dirsvc} = win.Services var {DownloadPaths, FileUtils} = win; var map = val => DownloadPaths.sanitize(val); win.Downloads.getList(win.Downloads.ALL).then(list => list.addView({ onDownloadChanged(download) { if (!download.stopped) return; var {url} = download.source, title = titles[url]; if (!title) return; delete titles[url]; if (!download.succeeded) return; var file = FileUtils.File(download.target.path), {leafName} = file; var ext = leafName.slice(leafName.lastIndexOf(".")); var newName = map(title) + ext, {parent} = file; var newFile = parent.clone(); newFile.append(newName); try { newFile.createUnique(file.NORMAL_FILE_TYPE, file.permissions); file.renameTo(parent, newFile.leafName); download.target.path = newFile.path; download.refresh(); } catch {} } })); Object.defineProperty(this, "set", {get() { try {var dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {var dir = dirsvc.get("DfltDwnld", Ci.nsIFile);} var arr = prefs.getStringPref("extensions.user_chrome_files.savedirs", "_Web||_Pics|0").split('|').slice(2, 4); // подпапки в [Загрузках]: нет | папка графики | имя вкладки | домен arr[1] = (arr[1]) ? wref.get().gBrowser.selectedTab.label.slice(0, 64) .replace(/\s+/g,' ').replace(/:/g,'։').replace(/[|<>]+/g,'_').replace(/([\\\/?*\"'`]+| ։։ .*)/g,'').trim() : ""; arr.map(map).forEach(dir.append); try {dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777);} catch{console.error(dir.path)} return dir.path; }}); return this.set; }}, "browser.download.folderList": {type: "Int", set: 2}, "browser.download.useDownloadDir": {type: "Bool", set: true} }); var MouseImgSaverParent = class extends JSWindowActorParent { receiveMessage(msg) { var win = msg.target.browsingContext.topChromeWindow, {name} = msg; if (name) return this[name](win, msg.data); var {url, contentType, contentDisposition, sx, title, isPrivate, referrerInfo, cookieJarSettings} = msg.data; if (sx && sx > win.mozInnerScreenX + win.innerWidth) return; if (title) titles[url] = title; wref = Cu.getWeakReference(win); var p = win.Services.prefs; for(var pref in data) { var obj = data[pref], meth = `et${obj.type}Pref`; obj.val = p.prefHasUserValue(pref) ? p["g" + meth](pref) : null; p["s" + meth](pref, obj.set); } try { var args = [url, null, // document null, // file name contentDisposition, contentType, false, // no cache null, // filepicker title key null, // chosen data u.E10SUtils.deserializeReferrerInfo(referrerInfo), u.E10SUtils.deserializeCookieJarSettings(cookieJarSettings), win.document, // initiating doc true, // skip prompt for where to save null, // cache key isPrivate, win.document.nodePrincipal], {length} = win.internalSave, lfix = length >15; lfix && args.splice(1, 0, null); //FIX FF113+ win.internalSave(...args); } finally { for(var pref in data) data[pref].val === null ? p.clearUserPref(pref) : p[`set${data[pref].type}Pref`](pref, data[pref].val); } } dblclick(win, imgURL) { var gb = win.gBrowser, index = gb.selectedTab._tPos + 1; gb.selectedTab = gb.addTrustedTab('https://yandex.ru/images/search?rpt=imageview&url=' + imgURL, {index}); } } } |
Dumby > 29-03-2024 22:30:06 |
Dobrov пишет
Попробовал (на 124) воспроизвести — не получилось.
В data["browser.download.dir"].set ничего не запоминается. |
Dobrov > 30-03-2024 01:34:57 |
Dumby пишет
Отбой, картинка запишется в путь Загрузок по-умолчанию, если запись в другую папку не удалась, например, прав на запись не хватило. |
Dobrov > 31-03-2024 00:14:56 |
Оптимизировал скрипты ucf_hookClicks SingleHTML.mjs ClickPicSave.mjs в части глобальных функций. |
Alex_one > 02-04-2024 17:49:38 |
|
xrun1 > 02-04-2024 18:40:28 |
Alex_one |
Alex_one > 02-04-2024 19:29:04 |
xrun1 |
Dobrov > 06-04-2024 03:11:36 |
Dumby – исчезающая панель не пашет в UCF scriptsbackground [System Principal] (custom_script.js) Ошибка на строке: var header = div.appendChild(doc.createElement("div")).appendChild(new Text()); Выделить код Код:// ChromeUtils.domProcessChild.childID || ({………………………… getwin(){ //self = Services.obs.addObserver(self = this, topic); //в custom_script.js return this.ownerGlobal || Services.wm.getMostRecentWindow("navigator:browser"); }, ask(head, run, info = "", sec = 3, x, y = 58, win = self.getwin()){ // x < 0 отсчёт смещения справа var doc = win.document, wary = doc.createXULElement("panel"), popupset = doc.getElementById("mainPopupSet"); wary.setAttribute("onpopupshown", "move()"); wary.setAttribute("onpopuphidden", "this.remove()"); var div = wary.appendChild(doc.createElement("div")); var header = div.appendChild(doc.createElement("div")).appendChild(new Text()); var txt = div.appendChild(header.parentNode.cloneNode(true)); var s = run ? [250, 20, 8] : [0, 14, 5]; //без команды вывод сведений: аналог tooltip wary.style.cssText = `filter: sepia(100%) hue-rotate(${s[0]}deg)`; div.style.cssText = `font-size: ${s[1]}px; ${run ? "font-weight: bold;" : ""} margin: 0.${s[2]}em; max-width: 680px; white-space: pre-wrap`; txt.style.cssText = `font-size: 14px; font-style: italic; margin-top: ${info.length > 0 ? "1" : "0"}em`; txt = txt.firstChild; wary.move = (pr = wary.getOuterScreenRect(), x = -win.outerWidth) => { if (x < 0) x = Math.abs(x) - pr.width; wary.moveTo(pr.x + x, pr.y + y); wary.style.opacity = "1"; } header.data = head, txt.data = info, wary.style.opacity = "0"; wary.onclick =()=>{ run(); wary.hidePopup(); }; popupset.append(wary); wary.openPopup(); win.setTimeout(() => { wary.hidePopup(); wary.onclick = null; }, (sec + (head + info).length*0.04)*1000); // время показа зависит от кол-ва букв } |
Dumby > 06-04-2024 07:46:51 |
Dobrov пишет
new win.Text() Но, если панель создаётся каждый раз новая, |
Dobrov > 06-04-2024 08:04:54 |
Dumby => Выделить код Код:var header = wary.appendChild(document.createElement("div")); header.append(head); var txt = header.appendChild(new Text()); |
Dumby > 06-04-2024 13:34:56 |
Dobrov пишет
Ну, переносу-то с чего не работать, должен работать. Это вот header ещё можно не создавать, а просто написать div.append(head); |
Dobrov > 07-04-2024 02:14:46 |
Dumby спасибо, сделал! Вот ещё хотелка для любителей ярлыков любых прог: В кнопке «Меню пользователя» создавать последний пункт меню из опции, загружаемой из about:config. Пригодиться многим: возможность вбить код, делающий то, что нужно юзеру. После правки строка меню должна измениться. Меню пользователя - заготовка Выделить код Код:(async id => { // UserMenu, последний пункт меню брать из extensions.user_chrome_files.MenuItem MyMenu = { //имя курсивом: есть подсказка, обводка: изменяемые строки, alt() клик правой кнопкой Pics: { // Графика сайтов Вкл/Выкл permissions.default.image upd() { // обновлять сроку перед показом меню var s = G.pref(G.v) == 1, i = "chrome://browser/skin/canvas-blocked.svg"; this.label = `Графика страниц ${s ? "загружается" : G.pref(G.v) == 3 ? "кроме сторонних" : "отключена"}`; this.image = s ? i.replace("-blocked","") : i; this.tooltipText = `${G.v} = ${G.pref(G.v)}\nRClick – кроме сторонних`; }, cmd(){ G.pref(G.v, G.pref(G.v) == 2 ? 1 : 2); BrowserReload(); }, }, "SubMenu": { men: 1, //подменю "SubItem": { cmd(){console.log(this.label)}, }, }, MenuItem: { sep: 1, //сперва разделитель lab: "User MenuItem", inf: `Правый клик: изменить данное меню Эту строку и все её значения брать из extensions.user_chrome_files.MenuItem`, cmd(){ console.log("User MenuItem:\n"+ G.pref("extensions.user_chrome_files.MenuItem")) }, }, } CustomizableUI.createWidget({ id: id, label: id, tooltiptext: id, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.style.setProperty("list-style-image", "url(chrome://branding/content/icon32.png)"); btn.type = "menu"; var doc = btn.ownerDocument, m = nn => doc.createXULElement(nn); var popup = m("menupopup"), menu = m("menuitem"); menu.m = m; menu.fill = this.fill; menu.render = this.render; popup.append(menu); btn.prepend(popup); }, render(){ var popup = this.parentNode; this.remove(); this.fill(MyMenu, popup); }, fill(o, popup) { for (key in o) { if (typeof o[key] != "object") continue; var {lab, inf, img, cmd, alt, sep, men, upd} = o[key]; sep && popup.append(this.m("menuseparator")); var name = men ? "menu" : "menuitem"; var item = this.m(name); item.setAttribute("label", lab || key); // item.alt = alt; //RClick в ucf_hookClicks.js {Mouse… if (inf) item.tooltipText = inf, item.style.setProperty("font-style", "italic", "important"); if(img || /this\.image.*=/.test(upd)) item.className = name + "-iconic", item.setAttribute("image", img || F.nul); men || cmd && item.setAttribute("oncommand", cmd.toString().replace( /cmd\(.*?\){/, "{var trg = event.target || event;")); popup.append(item); if(upd){ //выделить обновляемый пункт меню item.style.filter = "drop-shadow(0.1px 1px 0.1px #c99)"; if(item.renderedOnce) (item.render = upd).call(item); else item.upd = upd, item.render = self.renderSub; } men && this.fill(o[key], item.appendChild(this.m("menupopup"))); } } }); G = { v: "permissions.default.image", pref(key,set){ //или key = [key,default] if (!Array.isArray(key)) key = [key]; var t = Services.prefs.getPrefType(key[0]), m = {b:"Bool",n:"Int",s:"String"}; t = m[t == 128 ? "b" : t == 64 ? "n" : t == 32 ? "s" : ""]; if (set == "get") return t; //тип опции if (!t) t = m[set != undefined ? (typeof set)[0] : (typeof key[1])[0]]; if (t) if (set != undefined) Services.prefs[`set${t}Pref`](key[0],set) else set = Services.prefs[`get${t}Pref`](...key); return set; } } })("ucf_test_menu"); |
b0ttle > 08-04-2024 09:11:54 |
Здравствуйте. Можно как-то переделать код, убрать лишнее сделав его из папки, а не полного пути? скрытый текст {let file=Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); //let arguments=["-no-remote","-P","XXX","-foreground"]; //Профиль выбран. Введите здесь «XXX» — желаемое имя профиля. let arguments=["-no-remote","-P","p","-foreground"]; //Выбор профиля. Вместо Test-User ведите имя профиля так, как оно отображается в about:profiles file.initWithPath("Х:\\LibreWolf\\librewolf.exe"); let process=Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); process.init(file);process.run(false,arguments,arguments.length); //Профиль подтвержден },//ProfileChanger_v1.11 https://www.camp-firefox.de/forum/thema/136664/?postID=1233642#post1233642 /**/ Примерно, чтобы был такой путь, где можно назад по папкам. Может сделать по другому? Есть что-то подобное как GreD, но чтобы открывал на папку ниже? Обычно запускаю через батник с такими параметрами: скрытый текст @start /d "%~dp0" LibreWolf\librewolf.exe -profile p ::@start /d "%~dp0" LibreWolf-Portable.exe -P p ::@echo off|firefox -profile p1 Ну и может совет, как лучше запускать для теста другие профили? Тыкать в батник такое себе. Может все делаю неправильно. Да, можно оставить как есть, все работает и в таком виде. Но как-то не то. Кстати, когда добавили перезапуск из-под браузера? Ctrl+Alt+R, похоже перезапускает без кэша. Круто) upd: dobrov, ок спасибо, посмотрю. |
Dobrov > 08-04-2024 15:15:50 |
b0ttle пишет
Профили могут требовать и разные версии браузеров. Ява код не нужен, проще VBS ярлык запускать в Windows: Выделить код Код:Set WshShell = CreateObject("WScript.Shell") CurrPath = CreateObject("Scripting.FileSystemObject").GetFile(WScript.ScriptFullName).ParentFolder ProfileDir = CurrPath & "\ProfileDobrov" ProfileUser = "C:\UserTarget\MozillaFirefox\ProfileDobrovRAM" ProfileCD = CurrPath & "\ProfileDobrov" RamDir = "R:\UserTarget\MozillaFirefox\ProfileDobrov" If CreateObject("Scripting.FileSystemObject").FolderExists(RamDir) Then ' CurrPath = FirefoxDir WshShell.Run "cmd /c @echo " & chr(007), 0, false End If If CreateObject("Scripting.FileSystemObject").FolderExists(ProfileUser) Then ProfileDir = ProfileUser End If If CreateObject("Scripting.FileSystemObject").FolderExists(ProfileCD) Then ProfileDir = ProfileCD End If ' result = WshShell.Popup(ProfileDir, 3, "FireFox", vbQuestion) WshShell.Run(Quote(CurrPath & "\firefox.exe") & " -no-remote -profile " & Quote(ProfileDir)) Function Quote(PathFile) 'заключить в кавычки, если путь содержит пробелы If InstrRev(PathFile," ") = 0 Then Quote = PathFile Else Quote = Chr(34) & PathFile & Chr(34) End Function |
Dumby > 11-04-2024 21:35:26 |
Dobrov пишет
скрытый текст Опять CustomizableUI.createWidget() в оконном коде торчит. Без никаких проверок — в следующем окне будет ошибка. И дело даже не столько в мусоре в консоли, а в том, что ошибка оборвёт исполнение кода в обёртке, и последующее определение объекта G не состоится. Да, я понимаю, ты одноокошечник. И я одноокошечник. И даже если проверку делать, то виджет, рождённый в каком-то окне, Поэтому, создавать виджет в окне, в общем случае, не рекомендуется. Здесь, проще всего, в SystemGlobal, но там CustomizableUI надо импортировать. то пользовательский сандбокс, разве что только дебаггером всё перебирать. Вот есть scope.UcfPrefs = UcfPrefs;
А мне кажется, так чуть проще, чем отдельный MenuItem. Но, опять же, следует понимать, что если в настройку писать А если больше одного мегабайта — будет отказ с ошибкой. И, прикинь как расколбасит строку этой настройки на странице about:config
Direct eval() — как же ещё, eval-like стафф всё ещё позволен тем,
Кстати, тебе (и всем заинтересованным) здесь рекомендую обратить внимание на То есть, в 126, вместо BrowserReload(); уже нужен BrowserCommands.reload();
Это ты предлагаешь написать такой диалог мне? И всё только ради того, чтобы редактировать без перезапуска? Нет, ну можно что-то такое подзапилить, чисто для прикола, Вот, вызов — СКМ по самой кнопке. Выделить код Код:(async id => { var MyMenuFunc = () => ({ //имя курсивом: есть подсказка, обводка: изменяемые строки, alt() клик правой кнопкой Pics: { // Графика сайтов Вкл/Выкл permissions.default.image upd() { // обновлять сроку перед показом меню var s = G.pref(G.v) == 1, i = "chrome://browser/skin/canvas-blocked.svg"; this.label = `Графика страниц ${s ? "загружается" : G.pref(G.v) == 3 ? "кроме сторонних" : "отключена"}`; this.image = s ? i.replace("-blocked","") : i; this.tooltipText = `${G.v} = ${G.pref(G.v)}\nRClick – кроме сторонних`; }, cmd(){ G.pref(G.v, G.pref(G.v) == 2 ? 1 : 2); BrowserReload(); }, }, "SubMenu": { men: 1, //подменю "SubItem": { cmd(){console.log(this.label)}, }, }, MenuItem: { sep: 1, //сперва разделитель lab: "User MenuItem", inf: `Правый клик: изменить данное меню Эту строку и все её значения брать из extensions.user_chrome_files.MenuItem`, cmd(){ console.log("User MenuItem:\n"+ G.pref("extensions.user_chrome_files.MenuItem")) }, }, }); var widget = CustomizableUI.getWidget(id); if (!widget?.label) { var func = (id, sym, self, widget) => widget = CustomizableUI.createWidget(self = { id, label: id, tooltiptext: id, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, get disallowSubView() { return (this.f = !this.f) || delete this.f && delete this.disallowSubView && this; }, get ut() { return Services.wm.getMostRecentBrowserWindow().MyMenu[sym]; }, setupMyMenu(data) { var {prefs} = Services, pref = "extensions.user_chrome_files.MyMenuSource"; var utils = class { constructor(data) { Object.assign(this, data); } get pref() { return prefs.getStringPref(pref, ""); } get code() { return this.pref || this.src; } get src() { var proto = this.constructor.prototype; delete proto.src; return proto.src = String(this.mmf).slice(7, -1); } changePref(val) { val ? prefs.setStringPref(pref, val) : prefs.clearUserPref(pref); } reinit() { var {pref} = this; if (pref) try { var mm = this.eval(`(${pref})`); } catch { self.error = true; } (this.win.MyMenu = typeof mm == "object" ? mm : this.mmf())[sym] = this; } }; (this.setupMyMenu = data => (new utils(data)).reinit())(data); }, onCreated(btn) { btn.type = "menu"; btn.style.setProperty("list-style-image", "url(chrome://branding/content/icon32.png)"); var doc = btn.ownerDocument, m = nn => doc.createXULElement(nn); var tmp = btn.tmp = m("menuitem"); var popup = btn.popup = m("menupopup"); popup.toggleAttribute("context"); //popup.setAttribute("oncontextmenu", 'if (event.target.nodeName == "menuitem") this.activateItem(event.target, event);'); tmp.m = m; tmp.fill = this.fill; tmp.render = this.render; popup.append(tmp); btn.prepend(popup); btn.reinit = this.reinit; btn.onauxclick = this.auxclick; }, reinit() { var {popup, tmp} = this; if (popup.firstChild == tmp) return; popup.removeAttribute("hasbeenopened"); popup.textContent = ""; popup.append(tmp); }, auxclick(e) { e.button == 1 && e.target == this && self.edit(e.view); }, render(){ var popup = this.parentNode; this.remove(); this.fill(this.ownerGlobal.MyMenu, popup); }, wt: "UCF:EditMyMenuObj", edit(win) { var w = Services.wm.getMostRecentWindow(this.wt); if (w) return w.focus(); var features = "chrome,centerscreen,resizable,dependent,width=1200,height=750"; if (Services.appinfo.widgetToolkit == "windows") features += ",dialog=no"; var w = win.openDialog("about:blank", "", features, null); var lss = Services.scriptloader.loadSubScript; lss("chrome://global/content/customElements.js", w); lss("chrome://global/content/globalOverlay.js", w); try {lss("chrome://global/content/editMenuOverlay.js", w);} catch {} w.onpageshow = this.editorShown; }, editorShown(e) { var doc = e.target, win = doc.ownerGlobal; doc.title = "Edit MyMenu Object"; doc.documentElement.setAttribute("windowtype", self.wt); var wu = win.windowUtils; for(var sub of ["menu", "popup", "global-shared", "in-content/common-shared"]) wu.loadSheetUsingURIString(`chrome://global/skin/${sub}.css`, wu.AUTHOR_SHEET); var style = doc.head.appendChild(doc.createElement("style")); style.append(` * {border-radius: 0 !important; outline-width: 1px !important;} :root, body {margin: 0; height: 100vh; overflow: hidden;} body {display: grid; grid-template-rows: 1fr auto;} body > * {margin: 8px !important;} textarea {resize: none; margin-bottom: 0 !important; white-space: pre; font-family: monospace !important;} div {display: grid; grid-template-columns: 1fr auto auto; column-gap: 1em; align-items: center;} span {display: flex; align-items: center; justify-content: center; color: light-dark(crimson, tomato); font-family: monospace;} button {border: 1px solid gray !important; margin: 0 !important;} `); var ta = win.ta = doc.body.appendChild(doc.createElement("textarea")); ta.value = self.ut.code; ta.onchange = self.change; ta.onkeypress = self.keypress; var btns = doc.body.appendChild(doc.createElement("div")); win.err = btns.appendChild(doc.createElement("span")).appendChild(new win.Text()); for(var lab of ["Применить", "Готово"]) { var btn = btns.appendChild(doc.createElement("button")); btn.onclick = self.btnClick; btn.append(lab); } doc.getElementById("cmd_selectAll")?.setAttribute( "oncommand", "ta.blur(); Services.focus.setFocus(ta, Services.focus.FLAG_NOSCROLL);" ); if (self.error) return delete self.error, self.btnClick.call(btn.previousSibling); ta.editor.beginningOfDocument(); ta.focus(); }, change() { this.ownerGlobal.newCode = true; }, keypress(e) { if (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) return; if (e.key == "Tab") return e.preventDefault(), this.editor.insertText("\t"); if (e.key != "Enter") return; e.preventDefault(); var ss = this.selectionStart; var beg = this.value.slice(0, ss); var ind = beg.lastIndexOf("\n") + 1; var indent = beg.slice(ind).match(/^(?:[ \t]*)?/); this.editor.insertText("\n" + indent); }, btnClick() { var wnd = this.ownerGlobal; var {ta, err, newCode} = wnd, code = ta.value; wnd.newCode = false; var done = this.matches(":last-child"); if (newCode || err.ex) { var some = /\S/.test(code), {ut} = self; if (newCode) err.data = ""; if (some) try { if (newCode) ut.eval(`(${code})`); else throw err.ex; } catch(ex) { var num = ex.lineNumber; var ed = ta.editor, sc = ed.selectionController; ed.beginningOfDocument(); while(num--) sc.lineMove(true, !num); var div = ed.rootElement; var dr = div.getBoundingClientRect(); var dp = dr.top + div.clientHeight / 2.6; var sr = ed.selection.getRangeAt(0).getBoundingClientRect(); var sc = sr.top + sr.height / 2 div.scrollBy(0, sc - dp); if (newCode) err.data = err.ex = ex; return ta.focus(); } err.ex = null; ut.changePref(some && code); if (!some && !done) ta.focus(), ta.value = ut.src; for(var win of Services.wm.getEnumerator("navigator:browser")) if (!win.closed) win.MyMenu?.[sym]?.reinit(), widget.forWindow(win)?.node?.reinit(); } done && wnd.close(); }, renderSub() { delete this.render; this.render(); this.render = self.updSub; this.upd(); }, updSub() { this.parentNode.state.startsWith("c") || this.upd(); }, fill(o, popup) { for(var key in o) { if (typeof o[key] != "object") continue; var {lab, inf, img, cmd, alt, sep, men, upd} = o[key]; sep && popup.append(this.m("menuseparator")); var name = men ? "menu" : "menuitem"; var item = this.m(name); item.setAttribute("label", lab || key); // item.alt = alt; //RClick в ucf_hookClicks.js {Mouse… if (inf) item.tooltipText = inf, item.style.setProperty("font-style", "italic", "important"); if (img || /this\.image.*=/.test(upd)) item.className = name + "-iconic", item.setAttribute("image", img || "chrome://browser/content/robot.ico"); men || cmd && item.setAttribute("oncommand", cmd.toString().replace( /cmd\(.*?\){/, "{var trg = event.target || event;")); popup.append(item); if (upd) { //выделить обновляемый пункт меню item.style.filter = "drop-shadow(0.1px 1px 0.1px #c99)"; if (item.renderedOnce) (item.render = upd).call(item); else item.upd = upd, item.render = self.renderSub; } men && this.fill(o[key], item.appendChild(this.m("menupopup"))); }} }); widget = Cu.evalInSandbox(`(${func})("${id}", Symbol());`, Cu.getGlobalForObject( Cc["@mozilla.org/network/protocol/about;1?what=user-chrome-files"].getService().wrappedJSObject )); } widget.disallowSubView.setupMyMenu({win: window, eval: code => eval(code), mmf: MyMenuFunc}); G = { v: "permissions.default.image", pref(key,set){ //или key = [key,default] if (!Array.isArray(key)) key = [key]; var t = Services.prefs.getPrefType(key[0]), m = {b:"Bool",n:"Int",s:"String"}; t = m[t == 128 ? "b" : t == 64 ? "n" : t == 32 ? "s" : ""]; if (set == "get") return t; //тип опции if (!t) t = m[set != undefined ? (typeof set)[0] : (typeof key[1])[0]]; if (t) if (set != undefined) Services.prefs[`set${t}Pref`](key[0],set) else set = Services.prefs[`get${t}Pref`](...key); return set; } } })("ucf_test_menu"); |
Dobrov > 12-04-2024 17:08:00 |
Dumby пишет
Dumby – спасибо за изменяемое пользователем меню, потестирую! Наверное, код станет проще без диалога настройки, если объект меню хранить в опции в виде base64. Dumby пишет
java API браузеров сложна для меня, только чужие примеры переделываю. Не нашёл статей, где можно последовательно изучить API браузеров с нуля, от developer.mozilla.org толку мало. |
Dumby > 13-04-2024 18:38:05 |
Dobrov пишет
То есть, содержимое файла как бинарную строку, а не как текст, Тогда надо ещё делать метод конвертирования настройки в текст,
А зачем? Он от этого только больше станет. Если имеется в виду, что он будет одной длинной строкой, В base64, возможно, лучше если только в gzip, но не всегда, и это заморочно.
Я не знаю что такое «закрыл файл». А если сохранил, значит у файла изменится lastModifiedTime И там сравниваем lastModifiedTime на момент события или топика Можно предусмотреть ручной выход из режима редактирования, Вобщем, можешь пофантазировать на эту тему. |
Vitaliy V. > 14-04-2024 15:04:22 |
Dumby пишет
Обновил, добавил UcfPrefs.customSandbox, в случае если отключены в настройках фоновые скрипты Для всех: |
Dumby > 15-04-2024 18:58:41 |
Vitaliy V. пишет
О, замечательно!
Кстати, был, когда-то, вообще ультимативный проект. То есть, в папке user_chrome_files — только пользовательский стафф. А рядом с этой пользовательской папкой user_chrome_files Собственно, идея в том, чтобы последний раз переломаться обновить, Ну, это некая маниловщина, если бы, да кабы. И, внезапно меняя тему, я смотрю ATB обновился. Это хорошо. Dumby пишет
|
Dumby > 15-04-2024 22:10:00 |
egorsemenov06 пишет
Ну, и здесь 404, так что ... |
Dobrov > 16-04-2024 02:36:39 |
Dumby пишет
Vitaliy V. globalThis[Symbol.for('UcfGlob')] = this.UcfGlob; //общие функции И почему CustomStylesScripts.mjs расположен отдельно? Ведь после добавления скриптов его надо править (пока не будет GUI-менеджера подключенных скриптов/стилей) И если убраны файлы стилей, то хотя бы сохранить их закомментированными в stylesall: [ // For all documents |
Dumby > 16-04-2024 10:20:38 |
egorsemenov06 пишет
Другое дело. Но, fp.init(window, в трёх местах торчат, так что нет, не принимается. |
Vitaliy V. > 16-04-2024 14:47:52 |
Dumby пишет
Т.е. в папке chrome две папки UserChromeFiles ? По моему это излишне... Dumby пишет
Спс, исправил. Dobrov пишет
Например из поста №1440 Dobrov пишет
Это что, в background скрипт находится? Dobrov пишет
Да чтобы не искать его среди других скриптов только для этого Dobrov пишет
Да пофиг мне на рекламу, на этом не заработаешь, количество пользователей тоже не волнует Dobrov пишет
Для примера что ли, а одного недостаточно? А тип стилей там в описании есть type: style rights AGENT_SHEET, AUTHOR_SHEET or USER_SHEET |
xrun1 > 16-04-2024 15:30:11 |
Vitaliy V. пишет
Не надо убирать, а то совсем запутаемся. |
_zt > 16-04-2024 18:04:32 |
Vitaliy V. |
Dumby > 16-04-2024 18:27:33 |
Vitaliy V. пишет
Да-да, именно две. Новоначальный (if any) — разворачивает обе две.
Не надо ничего нигде убирать. Идея была услышана, рассмотрена, прикинута, и отвергнута. Продолжаем так, как оно есть сейчас, |
b0ttle > 16-04-2024 23:09:03 |
выглядит красиво |
Vitaliy V. > 17-04-2024 00:34:23 |
_zt пишет
Да возможно так и сделаю это уже мелочи, в принципе и сами можете в двух местах пути подправить в user_chrome.js и StylesScriptsChild.mjs _zt пишет
Нет этого делать не буду, это может задерживать запуск не случайно же даже для userChrome.css userContent.css сделали настройку чтобы не искать файлы в директории _zt пишет
Я не любитель gui там где это не к чему, не потому что это сложно сделать, хотя и это тоже это вам не userChromeJS (или как там называется) где одинаковые оконные скрипты по одному событию загружаются и все. Так что кому нужны gui, автозакрузки ищите замену если найдете |
Dobrov > 17-04-2024 01:19:02 |
Vitaliy V. пишет
globalThis[Symbol.for('UcfGlob')] = this.UcfGlob; - общие функции в scriptsbackground: Так Dumby подсказал: надо что-то в SystemGlobal добавить, чтобы с других мест вызывать. Я пробовал делать общий объект в background скрипте через UcfPrefs.customSandbox, но не получилось: оконный скрипт выдаёт undefined |
Vitaliy V. > 17-04-2024 01:51:02 |
Dobrov |
_zt > 17-04-2024 11:12:47 |
Vitaliy V. пишет
Я что то пропустил, что за настройка? А, типа что б только по импорту в основных файлах? |
Vitaliy V. > 17-04-2024 12:06:37 |
_zt пишет
Наверняка знаете давно сделали toolkit.legacyUserProfileCustomizations.stylesheets не помню с какой версии |
Dumby > 17-04-2024 13:22:31 |
Bug 1541233 - Stop loading userContent.css or userChrome.css by default unless a preference is set Status: RESOLVED FIXED |
brake > 17-04-2024 15:42:54 |
Dummy Bug 1880914 Move Browser* helper functions used from global menubar and similar commands to a single object in a separate file, loaded as-needed What is the relplacement of BrowserReloadSkipCache() in the latest version Edit: I searched through the code at searchfox.org, may be this can work. |
Dobrov > 18-04-2024 02:04:44 |
brake пишет
этот баг закрыт и он 2020 года. |
Dumby > 18-04-2024 09:25:07 |
Dobrov пишет
Это оно и было, разве нет?
Откуда ты такое взял? |
_zt > 18-04-2024 14:54:01 |
Dumby скрытый текст Выделить код Код:// https://forum.mozilla-russia.org/viewtopic.php?pid=788786#p788786 // Для custom_script.js в user_chrome_files try {CustomizableUI.createWidget({ label: "Пароли / Cookies", tooltiptext: "ЛКМ: Показать пароли\nПКМ: Показать cookies", id: "ucf-logins-sitedata", localized: false, onCreated(btn) { btn._handleClick = btn.oncontextmenu = e => this.view(e, btn.ownerGlobal); btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAADo0lEQVR42pWUf0idVRzGP+d4vVfbFFeu/SErV1bUBiI6ivajUcEiiiBoaTEEo7Lsj2W1P6Q2xFiL0Qp0q/7pB2GLijZGG/aDSPuBxBbkGm3O7IJuRJmod+t6r+89p+d9b6TWhu17uefe97zn+5zn+3yfcwznCz9e7c2S5fr3i8Ec5yLCzHtq96txdGNZSoE+a8mxgRG2cx/t5uTFAd7u17GOPrbl9oDdibGjdPgrtOIlwd7TtI2aN8zCbGcBn/dJJb7LdtP2n1XP+Q8Z+a2St5bVzVPmlPInBVKHnw/Y7tdr7OE7yjhksnM2sTxrHJ/7Sr0booIbaDSDeC9pjec8EQH6TdRzgofNALddqBR/HWNU84B5n0+j533EWcYKKZwyjZyZz/BJ36XxVkrpZPDnOMUJy4xmCmOSsxDSZwPKrtylhjXwqtnvR3mGczxBwOXEbIaU+4YMLWYNSUPTcA9pt1GLFQEUFek3fBCQE6oNp204NUXvWIUfrGsmyS6mNV/bo+F6bfg0HP/gNHWsMmwaDCKLhGGtwwks5mweKcS2OawrYOJchz9Y08ExsjgxTweOm/pNhhvD3YPE+B0JPv5kh2HzcEogi0XOEQtfCcxGdKeEWRqRDfHHf7/L71hjuYSDpFVFThQvXeGpOkqaJa6YPsPXt/xqaBhWoitRWi4PmFH2oja6K3fyYLILm20hq6ljRzb6vfUZyvmS6bi2KTBk0lpaDtVbHGO9hhOf/WFoTKaEIoaiFdO6YMZhF9fyzvIBGpJ3knOHKEy8RnfFY35AJnexVn1d1FAn/81MezUklC3Bn7wSAk4JpYRpARa5nMovJBv7iKnE/ZS508RzX/B2ZYP/kRcFslXsQq3lQSeHSPrY338X5Yaoyq6eZZgVYFyAQUbtLe7lK1fP0p+2cvTuVn9SzNK05hsVWslGWNhgMqqqwB0W10fN1fLkPxo6aRjHRQydPUV31bWRgb+3ezT/ePiGbNwSm56Uo/qY4GW1bUgbeXMvo7PG3jw8KcDSqMs2ZBgaMPYm+65qkoFfV+IjODVBFlUFlkTwgrmGNi4QAkz6yHuhP0JtstYwemaV79xQBdkDcnq+UiffpYNmbuY9Y0jNOZQS0My5HJpGugTYooLziamz8EP/Wn/4oRpm4p1IAbl4QjrtNytp+n/XV/PYSpV5GaYge2RvSXHtt/JaGVsk9O6o1BKekuC7FwKbfx/++3Y5oINvdFBzGsvpN+uj07tg/AUtF37/2LRsMgAAAABJRU5ErkJggg=="); }, view(e, win) { if (e && (e.ctrlKey || e.shiftKey)) return; var uri = win.gBrowser.selectedBrowser.currentURI; try { var url = win.ReaderMode.getOriginalUrl(uri.spec); if (url) uri = Services.io.newURI(url); } catch {} try {var tld = Services.eTLD.getBaseDomain(uri);} catch {var tld = uri.asciiHost;} e ? this.viewCookies(tld, win) : this.viewPasswords(tld, uri, win); return false; }, viewPasswords(tld, uri, win) { try { tld = Services.io.newURI(`${uri.scheme}://${tld}`).displayHost; } catch {} var params = new win.URLSearchParams({...(tld && {filter: tld})}); var gb = win.gBrowser; var separator = params.toString() ? "?" : ""; var tabToSelect, url = `about:logins${separator}${params}`; for (var tab of gb.visibleTabs) { var {spec} = tab.linkedBrowser.currentURI; if (!spec.startsWith("about:logins")) continue; if (spec != url) { var pending = tab.hasAttribute("pending"); if (pending) gb.selectedTab = tab; tab.linkedBrowser.fixupAndLoadURIString( url, {triggeringPrincipal: tab.nodePrincipal} ); if (pending) return; } tabToSelect = tab; break; } gb.selectedTab = tabToSelect || gb.addTrustedTab(url); }, async viewCookies(tld, window) { var wt = "Browser:SiteDataSettings"; var win = Services.wm.getMostRecentWindow(wt); if (!win) { await window.SiteDataManager.updateSites(); var url = "chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml"; var id = "SiteDataSettingsDialog", xs = Services.xulStore; var x = xs.getValue(url, id, "screenX") || 0; var y = xs.getValue(url, id, "screenY") || 0; var features = "chrome,dialog=no,resizable," + ( x || y ? `screenX=${x},screenY=${y}` : "centerscreen" ); win = window.openDialog(url, wt, features); //var xenoWin = win.document.readyState == "complete"; // ??? var e = await new Promise(resolve => win.windowRoot.addEventListener("DOMContentLoaded", resolve, {once: true}) ); e.target.documentElement.setAttribute("windowtype", wt); } var doc = win.document; doc.documentElement.setAttribute("persist", "screenX screenY width height"); var sb = doc.querySelector("#searchBox"); sb.inputField.setUserInput(tld); setTimeout(() => sb.editor.selection.collapseToEnd(), 50); win.focus(); } });} catch(ex) {Cu.reportError(ex);} Vitaliy V. В ATB такая же история, новый уже поставил. А этот скрипт нормально работает, первый спойлер. Точнее, такой вариант: скрытый текст Выделить код Код:(this.viewcookieswithrightclick = { init(that) { var star = this.star = document.querySelector("#star-button-box"); if (!star) return; star.addEventListener("contextmenu", this, true); star.addEventListener("click", this, true); that.unloadlisteners.push("viewcookieswithrightclick"); }, handleEvent(e) { if (e.button != 2) return; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); if (e.type != "click") return; this.viewCookies(); }, getETDL(uri) { var eTLD = ""; try { eTLD = Services.eTLD.getBaseDomain(uri); } catch (e) { try { eTLD = uri.asciiHost; } catch (e) {} } return eTLD; }, async viewCookies() { var sds = "chrome://ucfsdswnd/content/sds.xhtml"; var type = "Browser:SiteDataSettings", g = Cu.getGlobalForObject(Cu); if (!Object.hasOwn(g, sds)) { var xhtml = (await (await fetch("chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml")).text()) .replace(/(persist=".+)"/, `$1 screenX screenY sizemode" windowtype="${type}"`); g[sds] = Cc["@mozilla.org/addons/addon-manager-startup;1"] .getService(Ci.amIAddonManagerStartup).registerChrome( Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)), [["override", sds, "data:application/xhtml+xml," + encodeURIComponent(xhtml)]] ); } (this.viewCookies = async () => { var uri = gBrowser.selectedBrowser.currentURI; try { let _uri = ReaderMode.getOriginalUrl(uri.spec); if (_uri) uri = Services.io.newURI(_uri); } catch(e) {} uri = this.getETDL(uri); var _win = Services.wm.getMostRecentWindow(type); await SiteDataManager.updateSites(); if (!_win) await new Promise(resolve => (_win = openDialog(sds, type, "chrome,dialog=no,resizable")) .addEventListener("DOMContentLoaded", resolve, {once: true}) ); else if ("_gSiteDataSettings" in _win) _win._gSiteDataSettings(); else { Services.scriptloader.loadSubScript("data:," + encodeURIComponent(` var _gSiteDataSettings = gSiteDataSettings._gSiteDataSettings = (function() { SiteDataManager.getSites().then(sites => { this._sites = sites; var sortCol = document.querySelector("treecol[data-isCurrentSortCol=true]"); this._sortSites(this._sites, sortCol); this._buildSitesList(this._sites); }); }).bind(gSiteDataSettings); _gSiteDataSettings(); var updateSetInterval = setInterval(async () => { await SiteDataManager.updateSites(); _gSiteDataSettings(); }, 5000); let removeBtns = document.querySelectorAll("#removeSelected, #removeAll"); var updateClearInterval = () => { clearInterval(updateSetInterval); for (let btn of removeBtns) btn.removeEventListener("command", updateClearInterval); updateClearInterval = null; }; for (let btn of removeBtns) btn.addEventListener("command", updateClearInterval); `), _win); _win.addEventListener("unload", () => { _win.updateClearInterval?.(); }, { once: true }); } _win.focus(); var filter = _win.document.getElementById("searchBox"); if (!filter) return; filter.value = uri; filter.focus(); filter.dispatchEvent(new _win.Event("input", { bubbles: true })); })(); }, destructor() { this.star.removeEventListener("contextmenu", this, true); this.star.removeEventListener("click", this, true); }, }).init(this); Dumby Еще fileToBase64 не открывает обзор файлов в . |
_zt > 18-04-2024 20:07:10 |
Уже было, но на всякий случай продублирую. "126+ Функция Ctrl+Shift+R по ПКМ на стандартной кнопке обновления страницы" Выделить код Код:// 126+ Функция Ctrl+Shift+R по ПКМ на стандартной кнопке обновления страницы // https://forum.mozilla-russia.org/viewtopic.php?pid=784200#p784200 try { (() => { var node = CustomizableUI.getWidget("stop-reload-button").forWindow(window).node.querySelector("#reload-button"), tooltipid = "reload-button-shortcut-tooltip", tooltiporig = node.tooltip; if (!document.querySelector(`#${tooltipid}`)) { document.querySelector("#dynamic-shortcut-tooltip").after(MozXULElement.parseXULToFragment(` <tooltip id="${tooltipid}"> <description class="tooltip-label">ЛКМ Обновить страницу (Ctrl+R)</description> <description class="tooltip-label">СКМ Дублировать вкладку (Ctrl+ЛКМ)</description> <description class="tooltip-label">ПКМ Обновить минуя кэш (Ctrl+Shift+R)</description> </tooltip> `)); } node.tooltip = tooltipid; node.setAttribute("context", "false"); var click = e => { if (e.button != 2) return; e.preventDefault(); e.stopPropagation(); e.stopImmediatePropagation(); BrowserCommands.reloadSkipCache(); }; node.addEventListener("click", click); this.browsercommands.reloadskipcache = { destructor() { node.removeEventListener("click", click); node.tooltip = tooltiporig; node.removeAttribute("context"); } }; this.unloadlisteners.push("browsercommands.reloadskipcache"); })(); } catch(e) {} 18-04-2024 20:30:52 |
Dumby > 18-04-2024 20:46:53 |
_zt пишет
Хмм, у меня, с этого окна — не падает. Однако, какой-то crash-жести, определённо, завезли целый вагон.
[censored]
|
_zt > 18-04-2024 21:24:35 |
Dumby Выделить код Код:var x = xs.getValue(url, id, "screenX") || 100; var y = xs.getValue(url, id, "screenY") || 100; и заработало! У меня размер экрана подделывается, это может быть связано? |
Vitaliy V. > 19-04-2024 13:54:32 |
_zt пишет
Это тоже с BrowserCommands связано, добавил совместимость с |
_zt > 19-04-2024 14:28:08 |
Vitaliy V. |
_zt > 20-04-2024 11:35:23 |
Vitaliy V. Выделить код Код:let sx = xs.getValue(url, id, "screenX") || 10; let sy = xs.getValue(url, id, "screenY") || 10; Браузер больше не падает. |
Vitaliy V. > 20-04-2024 14:26:57 |
_zt пишет
Видел но у меня не падает, скорее всего баг , И удалить xulstore.json |
Dobrov > 20-04-2024 16:37:26 |
Помогите решить задачу: Если убрать «var», то код работает, но мусорит переменными в окно браузера. Как «пробросить» нужные функции, которых много ? (BrowserReloadEx и прочие) Выделить код Код:(async id => { // UserMenu var BrowserReloadEx = (skip) =>{ // ошибка –> Uncaught ReferenceError is not defined if(parseInt(Services.appinfo.version) < 126) skip ? BrowserReloadSkipCache() : BrowserReload(); else skip ? BrowserCommands.reloadSkipCache() : BrowserCommands.reload(); }, G = { v: "permissions.default.image", Pref(key,set){key = [key]; var t = Services.prefs.getPrefType(key[0]), m = {b:"Bool",n:"Int",s:"String"}; t = m[t == 128 ? "b" : t == 64 ? "n" : t == 32 ? "s" : ""]; if (!t) t = m[set != undefined ? (typeof set)[0] : (typeof key[1])[0]]; if (t) if (set != undefined) Services.prefs[`set${t}Pref`](key[0],set) else set = Services.prefs[`get${t}Pref`](...key); return set; } } var MyMenu = { //имя курсивом: есть подсказка, обводка: изменяемые строки, alt() клик правой кнопкой Pics: { // Графика сайтов Вкл/Выкл permissions.default.image upd() { // обновлять сроку перед показом меню var s = G.Pref(G.v) == 1, i = "chrome://browser/skin/canvas-blocked.svg"; this.label = `Графика страниц ${s ? "загружается" : G.Pref(G.v) == 3 ? "кроме сторонних" : "отключена"}`; this.image = s ? i.replace("-blocked","") : i; this.tooltipText = `${G.v} = ${G.Pref(G.v)}\nRClick – кроме сторонних`; }, cmd(){ BrowserReloadEx(); G.Pref(G.v, G.Pref(G.v) == 2 ? 1 : 2); } }, "SubMenu": { //сперва разделитель sep: 1, men: 1, //это подменю "Censor Tracker": { upd(){this.image = `chrome://devtools/skin/images/${G.Pref("network.proxy.type") == 2 ? "check" : "close"}.svg`} } } } CustomizableUI.getWidget(id)?.label || (self => CustomizableUI.createWidget(self = {id, id: id, label: id, tooltiptext: id, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.style.setProperty("list-style-image", "url(chrome://branding/content/icon32.png)"); btn.type = "menu"; var doc = btn.ownerDocument, m = nn => doc.createXULElement(nn); var popup = m("menupopup"), menu = m("menuitem"); menu.m = m; menu.fill = this.fill; menu.render = this.render; popup.append(menu); btn.prepend(popup); }, render(){ var popup = this.parentNode; this.remove(); this.fill(MyMenu, popup); }, renderSub(){ delete this.render; this.render(); this.render = self.updSub; this.upd(); }, updSub(){ this.parentNode.state.startsWith("c") || this.upd(); }, fill(o, popup){ for (key in o){ var val = o[key]; if(typeof val != "object") continue; var {lab, inf, img, cmd, alt, sep, men, upd} = val; sep && popup.append(this.m("menuseparator")); var name = men ? "menu" : "menuitem"; var item = this.m(name); item.setAttribute("label", lab || key); item.alt = alt; //RClick в ucf_hookClicks.js {Mouse… if (inf) item.tooltipText = inf, item.style.setProperty("font-style", "italic", "important"); if(img || /this\.image.*=/.test(upd)) item.className = name + "-iconic", item.setAttribute("image", img || "chrome://devtools/skin/images/blocked.svg"); men || cmd && item.setAttribute("oncommand", cmd.toString().replace( /cmd\(.*?\){/, "{var trg = event.target || event;")); popup.append(item); if(upd){ //выделить обновляемый пункт меню item.style.filter = "drop-shadow(0.1px 1px 0.1px #c99)"; if(item.renderedOnce) (item.render = upd).call(item); else item.upd = upd, item.render = self.renderSub; } men && this.fill(val, item.appendChild(this.m("menupopup"))); } } }))(); })("ucf_test_menu"); |
_zt > 20-04-2024 16:43:03 |
Vitaliy V. скрытый текст Выделить код Код:@-moz-document url("chrome://global/content/alerts/alert.xhtml") { :root { min-height: 216px !important; min-width: 400px !important; } #alertNotification { padding: 18px 16px 0 0 !important; } #alertTitleBox { font-size: 12px !important; color: #0074E8 !important; padding: 0 !important; margin: 0 !important; } #alertTextBox { min-width: 300px !important; font-weight: bold; flex-direction: row !important; align-items: center !important; justify-content: center !important; padding: 0 !important; margin: 0 !important; } #alertBox { box-shadow: rgba(10, 10, 12, 0.32) 0 0 5px !important; } @media (prefers-color-scheme: dark) { #alertBox { border-color: #0074E8 !important; background-color: var(--menu-background-color, var(--arrowpanel-background, Field)) !important; color: var(--menu-color, var(--arrowpanel-color, FieldText)) !important; } } /* !!! */ } up^ Закрыл сайдбар с TST, вызвал пару алертов и они сместились ближе к правому краю экрана, но не в край. На всякий случай отключил нижнюю панель UCF, но это результата не дало. |
Vitaliy V. > 21-04-2024 13:43:05 |
Dobrov пишет
Ну с cmd.toString() это не представляется возможным, скрытый текст Выделить код Код:(async id => { // UserMenu var BrowserReloadEx = (win, skip) =>{ // ошибка –> Uncaught ReferenceError is not defined if(parseInt(Services.appinfo.version) < 126) skip ? win.BrowserReloadSkipCache() : win.BrowserReload(); else skip ? win.BrowserCommands.reloadSkipCache() : win.BrowserCommands.reload(); }; var G = { v: "permissions.default.image", Pref(key,set){key = [key]; var t = Services.prefs.getPrefType(key[0]), m = {b:"Bool",n:"Int",s:"String"}; t = m[t == 128 ? "b" : t == 64 ? "n" : t == 32 ? "s" : ""]; if (!t) t = m[set != undefined ? (typeof set)[0] : (typeof key[1])[0]]; if (t) if (set != undefined) Services.prefs[`set${t}Pref`](key[0],set) else set = Services.prefs[`get${t}Pref`](...key); return set; } }; var MyMenu = { //имя курсивом: есть подсказка, обводка: изменяемые строки, alt() клик правой кнопкой Pics: { // Графика сайтов Вкл/Выкл permissions.default.image upd() { // обновлять сроку перед показом меню var s = G.Pref(G.v) == 1, i = "chrome://browser/skin/canvas-blocked.svg"; this.label = `Графика страниц ${s ? "загружается" : G.Pref(G.v) == 3 ? "кроме сторонних" : "отключена"}`; this.image = s ? i.replace("-blocked","") : i; this.tooltipText = `${G.v} = ${G.Pref(G.v)}\nRClick – кроме сторонних`; }, cmd(e){ BrowserReloadEx(e.view); G.Pref(G.v, G.Pref(G.v) == 2 ? 1 : 2); } }, "SubMenu": { //сперва разделитель sep: 1, men: 1, //это подменю "Censor Tracker": { upd(){this.image = `chrome://devtools/skin/images/${G.Pref("network.proxy.type") == 2 ? "check" : "close"}.svg`} } } }; (self => CustomizableUI.createWidget(self = { id: id, label: id, tooltiptext: id, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.style.setProperty("list-style-image", "url(chrome://branding/content/icon32.png)"); btn.type = "menu"; var doc = btn.ownerDocument, m = nn => doc.createXULElement(nn); var popup = m("menupopup"), menu = m("menuitem"); menu.m = m; menu.fill = this.fill; menu.render = this.render; popup.append(menu); btn.prepend(popup); }, render(){ var popup = this.parentNode; this.remove(); this.fill(MyMenu, popup); }, renderSub(){ delete this.render; this.render(); this.render = self.updSub; this.upd(); }, updSub(){ this.parentNode.state.startsWith("c") || this.upd(); }, fill(o, popup){ for (key in o){ var val = o[key]; if(typeof val != "object") continue; var {lab, inf, img, cmd, alt, sep, men, upd} = val; sep && popup.append(this.m("menuseparator")); var name = men ? "menu" : "menuitem"; var item = this.m(name); item.setAttribute("label", lab || key); item.alt = alt; //RClick в ucf_hookClicks.js {Mouse… if (inf) item.tooltipText = inf, item.style.setProperty("font-style", "italic", "important"); if(img || /this\.image.*=/.test(upd)) item.className = name + "-iconic", item.setAttribute("image", img || "chrome://devtools/skin/images/blocked.svg"); men || (item.cmd = cmd) && item.setAttribute("oncommand", "this.cmd(event);"); popup.append(item); if(upd){ //выделить обновляемый пункт меню item.style.filter = "drop-shadow(0.1px 1px 0.1px #c99)"; if(item.renderedOnce) (item.render = upd).call(item); else item.upd = upd, item.render = self.renderSub; } men && this.fill(val, item.appendChild(this.m("menupopup"))); } } }))(); })("ucf_test_menu"); _zt пишет
Обновил расширение сделал без centerscreen все равно это не особо нужно, проверяйте _zt пишет
Ну возможно скриптом можно и то не всегда и не везде, зависит от оконного менеджера позволит он перемещать окна или нет. |
_zt > 21-04-2024 15:26:40 |
Vitaliy V. Vitaliy V. пишет
Да я с удовольствием бы, но они мелькают ровно на секунду и в истории не сохраняются, хотя в настройках уведомлений Win, для Fx указано иное. 21-04-2024 15:38:29 |
Dobrov > 21-04-2024 16:59:07 |
Vitaliy V. пишет
Я так переделал, и всё работает: item.onclick = cmd |
Vitaliy V. > 21-04-2024 17:06:17 |
Dobrov пишет
Нет я же написал это не пойдет, открой второе окно и понажимай там пункт, перезагружаться будет в первом окне |
b0ttle > 21-04-2024 19:41:40 |
Vitaliy V. || Спасибо, обновился. add: Просто ATB бесит тем, что он горит красным в about:addons, плюс правки в about:config, плюс лишние кнопки тоже мозолят(у меня ноут) в "Настройка панели инструментов". Насчет "Long Left Click", может его добавить в AMO? Если бы еще добавить правый клик. Отдельным скриптом тоже будет норм. Ладно, в общем, если завал просьбами то пойму. Оставлю как есть, пока работает. |
_zt > 22-04-2024 01:45:32 |
b0ttle |
b0ttle > 22-04-2024 12:34:03 |
_zt |
Vitaliy V. > 22-04-2024 15:43:55 |
b0ttle пишет
Ну хорошо, только сначала нужно обновить UCF, незначительное обновление добавлен модуль ExtensionParent, может пригодится и для других скриптов. скрытый текст Выделить код Код:(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 b0ttle пишет
Не планирую, не заинтеросован в данной функции b0ttle пишет
Experimental WebExtensions APIs невозможно добавить на AMO, и также нельзя просто подписать подобное расширение. |
Vitaliy V. > 23-04-2024 19:18:19 |
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(); }, }); })(); |
b0ttle > 24-04-2024 00:32:29 |
Vitaliy V. |
b0ttle > 24-04-2024 01:44:20 |
Нечаянно забрел, и увидел такое. С каких пор в путях можно прописывать %ProfD%\\..\\..\\? Возможно у него это реализовано в самом Handy_Clicks? |
_zt > 24-04-2024 02:51:01 |
b0ttle |
fuchsfan > 24-04-2024 09:19:19 |
Скрипт "Переключить куки" под третим спойлером https://forum.mozilla-russia.org/viewto … 11#p809311 , по ЛКМ пять опций, опишите, плиз, их назначение. |
Farby > 24-04-2024 09:28:51 |
b0ttle пишет
Это обычный массив, который обрабатывает расширение Handy_Clicks |
_zt > 24-04-2024 11:13:37 |
fuchsfan 24-04-2024 11:30:08 |
Vitaliy V. > 24-04-2024 16:46:34 |
egorsemenov06 пишет
скрытый текст Выделить код Код://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); }); }, }); })(); _zt пишет
Где нет? В кнопке есть network.cookie.cookieBehavior = 0, |
fuchsfan > 24-04-2024 17:09:58 |
Парни, спасибо за разъяснения, все понял. |
b0ttle > 24-04-2024 22:59:55 |
Тоже всем благодарен за разъяснения. Farby, спасибо за наглядный пример, взял в заначки. |
_zt > 24-04-2024 23:09:14 |
Vitaliy V. пишет
Да я не смотрел скрипт, выше написали что пунктов пять. скрытый текст Выделить код Код:(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; } }); })(); |
fuchsfan > 25-04-2024 07:11:16 |
_zt пишет
Если только about:config, без доп. бантиков, то работает это (изменить в конце третьей строки снизу на желаемое) |
Farby > 25-04-2024 13:14:06 |
_zt пишет
Пока Vitaliy V. не пришёл, сделает лучше, можно попробовать такой вариант: ucf-open-about-config Выделить код Код:// 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; }, }); })(); ЗЫ: добавил URL: "about:cfg" через Shift, Разумеется "about:cfg" должен быть доступен. Скрипт из поста №1494 by Vitaliy V.. |
Vitaliy V. > 25-04-2024 14:32:21 |
_zt пишет
Надо было выложить сам about:cfg полностью, а то ссылки недействительны кроме https://forum.mozilla-russia.org/viewto … 48#p806748 скрытый текст Выделить код Код:(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; }, }); })(); |
_zt > 25-04-2024 15:13:54 |
Vitaliy V. |
_zt > 25-04-2024 18:36:47 |
fuchsfan скрытый текст Выделить код Код:(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); } }; }); |
Dumby > 25-04-2024 20:55:36 |
_zt пишет
Что-то я не припомню, чтобы после 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); } } |
Farby > 25-04-2024 22:47:48 |
_zt пишет
Ну и пользуйтесь на здоровье... |
_zt > 25-04-2024 22:57:22 |
Dumby |
Dumby > 27-04-2024 08:05:46 |
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; |
Dumby > 27-04-2024 10:51:58 |
egorsemenov06 скрытый текст Выделить код Код:/* onCreated(btn) { btn.setAttribute("image", "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>"); */ 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); |
Dumby > 27-04-2024 21:55:16 |
egorsemenov06 пишет
Не получилось воспроизвести.
В смысле какого-то отвала — нет, не вижу ничего такого. |
Vitaliy V. > 28-04-2024 12:48:50 |
egorsemenov06 скрытый текст Выделить код Код:onCreated(btn) { ... btn.setAttribute("image", this.image); }, get image() { var img = `${this.id.toLowerCase()}-img`; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(img, Services.io.newURI("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 .6C1.6.6.6 1.6.6 3v10c0 1.4 1 2.4 2.4 2.4h10c1.4 0 2.4-1 2.4-2.4V4.84L11.2.602Zm5.4 5.8h2V1m-2 0v5.4H7L5.6 5V1m-2 14v-2.6l1-1h6.8l1 1V15'/></svg>")); delete this.image; return this.image = `resource://${img}`; }, А в этих двух кнопках заменить image: ..., Для defaultFavicon также заменить defaultFavicon: ..., и изменить строку var img = ...; скрытый текст Выделить код Код:get defaultFavicon() { var img = `${this.id.toLowerCase()}-default-favicon-img`; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(img, Services.io.newURI("иконка")); delete this.defaultFavicon; return this.defaultFavicon = `resource://${img}`; }, |
Vitaliy V. > 28-04-2024 14:12:22 |
А смотрю со своими иконками наверно не справитесь скрытый текст Выделить код Код:data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity;' d='M10 3H4a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1zm10 0h-6a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1zM10 13H4a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-6a1 1 0 0 0-1-1zm8 1h-2v2h-2v2h2v2h2v-2h2v-2h-2z'/></svg> скрытый текст Выделить код Код: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='M13.384 3.408c.535.276 1.22 1.152 1.556 1.963a8 8 0 0 1 .503 3.897l-.009.077-.026.224A7.758 7.758 0 0 1 .006 8.257v-.04q.025-.545.114-1.082c.01-.074.075-.42.09-.489l.01-.051a6.6 6.6 0 0 1 1.041-2.35q.327-.465.725-.87.35-.358.758-.65a1.5 1.5 0 0 1 .26-.137c-.018.268-.04 1.553.268 1.943h.003a5.7 5.7 0 0 1 1.868-1.443 3.6 3.6 0 0 0 .021 1.896q.105.07.2.152c.107.09.226.207.454.433l.068.066.009.009a2 2 0 0 0 .213.18c.383.287.943.563 1.306.741.201.1.342.168.359.193l.004.008c-.012.193-.695.858-.933.858-2.206 0-2.564 1.335-2.564 1.335.087.997.714 1.839 1.517 2.357a4 4 0 0 0 .439.241q.114.05.228.094c.325.115.665.18 1.01.194 3.043.143 4.155-2.804 3.129-4.745v-.001a3 3 0 0 0-.731-.9 3 3 0 0 0-.571-.37l-.003-.002a2.68 2.68 0 0 1 1.87.454 3.92 3.92 0 0 0-3.396-1.983q-.116.001-.23.01l-.042.003V4.31h-.002a4 4 0 0 0-.8.14 7 7 0 0 0-.333-.314 2 2 0 0 0-.2-.152 4 4 0 0 1-.088-.383 5 5 0 0 1 1.352-.289l.05-.003c.052-.004.125-.01.205-.012C7.996 2.212 8.733.843 10.17.002l-.003.005.003-.001.002-.002h.002l.002-.002h.015a.02.02 0 0 1 .012.007 2.4 2.4 0 0 0 .206.48q.09.153.183.297c.49.774 1.023 1.379 1.543 1.968.771.874 1.512 1.715 2.036 3.02l-.001-.013a8 8 0 0 0-.786-2.353'/> </svg> скрытый текст Выделить код Код:data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity;' d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M6,4H13L18,9V17.58L16.16,15.74C17.44,13.8 17.23,11.17 15.5,9.46C14.55,8.5 13.28,8 12,8C10.72,8 9.45,8.5 8.47,9.46C6.5,11.41 6.5,14.57 8.47,16.5C9.44,17.5 10.72,17.97 12,17.97C12.96,17.97 13.92,17.69 14.75,17.14L17.6,20H6V4M14.11,15.1C13.55,15.66 12.8,16 12,16C11.2,16 10.45,15.67 9.89,15.1C9.33,14.54 9,13.79 9,13C9,12.19 9.32,11.44 9.89,10.88C10.45,10.31 11.2,10 12,10C12.8,10 13.55,10.31 14.11,10.88C14.67,11.44 15,12.19 15,13C15,13.79 14.68,14.54 14.11,15.1Z' /></svg> |
Vitaliy V. > 28-04-2024 14:40:13 |
egorsemenov06 скрытый текст Выделить код Код:(async () => CustomizableUI.createWidget({ id: "ucf-cbbtn-Save", tooltiptext: "Сохранить", localized: false, get initCode() { delete this.initCode; return this.initCode = Cu.readUTF8URI(Services.io.newURI( "chrome://user_chrome_files/content/custom_scripts/Save.js" )); }, cbu: { types: { 128: "Bool", boolean: "Bool", 64: "Int", number: "Int", 32: "String", string: "String" }, getPrefs(pref) { try { return Services.prefs[`get${ this.types[Services.prefs.getPrefType(pref)] }Pref`](pref); } catch {return null;} }, setPrefs(pref, val) { Services.prefs[`set${this.types[typeof val]}Pref`](pref, val); } }, gClipboard: { get ch() { delete this.ch; return this.ch = Cc["@mozilla.org/widget/clipboardhelper;1"] .getService(Ci.nsIClipboardHelper); }, write(str) { this.ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard); } }, custombuttonsUtils: { writeFile(path, data) { try { if (path.includes(":\\")) path = path.replace(/\//g, "\\"); var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); file.exists() && file.remove(false); var strm = Cc["@mozilla.org/network/file-output-stream;1"] .createInstance(Ci.nsIFileOutputStream); strm.init(file, 0x04 | 0x08, 420, 0); strm.write(data, data.length); strm.flush(); strm.close(); } catch(ex) { Cu.reportError("Custom Buttons: " + [path, "---", ex, ex.stack].join("\n")); } } }, addDestructor(destructor, context) { this._destructors.push({destructor, context}); }, addEventListener(...args) { var trg = args[3]; if (!trg) trg = args[3] = this.ownerGlobal; trg.addEventListener(...args); this._handlers.push(args); }, onCreated(btn) { var win = btn.ownerGlobal; btn._handlers = new win.Array(); btn._destructors = new win.Array(); win.addEventListener("unload", this, {once: true}); new win.Function( "self,_id,cbu,xhtmlns,addDestructor,addEventListener,gClipboard,custombuttonsUtils", this.initCode ).call( btn, btn, this.id, this.cbu, "http://www.w3.org/1999/xhtml", this.addDestructor.bind(btn), this.addEventListener.bind(btn), this.gClipboard, this.custombuttonsUtils ); btn.setAttribute("image", this.image); }, get image() { var img = `${this.id.toLowerCase()}-img`; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(img, Services.io.newURI("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 .6C1.6.6.6 1.6.6 3v10c0 1.4 1 2.4 2.4 2.4h10c1.4 0 2.4-1 2.4-2.4V4.84L11.2.602Zm5.4 5.8h2V1m-2 0v5.4H7L5.6 5V1m-2 14v-2.6l1-1h6.8l1 1V15'/></svg>")); delete this.image; return this.image = `resource://${img}`; }, handleEvent(e) { var btn = e.target.getElementById(this.id); for(var args of btn._handlers) args.pop().removeEventListener(...args); delete btn._handlers; for(var {destructor, context} of btn._destructors) try {destructor.call(context, "destructor");} catch(ex) {Cu.reportError(ex);} delete btn._destructors; } }))(); а из Save.js нужно удалить self.image = ... ; Вкладки в контейнере............. скрытый текст Выделить код Код://Вкладки в контейнере............. (async () => CustomizableUI.createWidget(({ label: "Вкладки в контейнере", get image() { var img = `${this.id.toLowerCase()}-img`; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(img, Services.io.newURI("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity;' d='M10 3H4a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1zm10 0h-6a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1zM10 13H4a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1v-6a1 1 0 0 0-1-1zm8 1h-2v2h-2v2h2v2h2v-2h2v-2h-2z'/></svg>")); delete this.image; return this.image = `resource://${img}`; }, get defaultFavicon() { var img = `${this.id.toLowerCase()}-default-favicon-img`; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(img, Services.io.newURI("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='M13.384 3.408c.535.276 1.22 1.152 1.556 1.963a8 8 0 0 1 .503 3.897l-.009.077-.026.224A7.758 7.758 0 0 1 .006 8.257v-.04q.025-.545.114-1.082c.01-.074.075-.42.09-.489l.01-.051a6.6 6.6 0 0 1 1.041-2.35q.327-.465.725-.87.35-.358.758-.65a1.5 1.5 0 0 1 .26-.137c-.018.268-.04 1.553.268 1.943h.003a5.7 5.7 0 0 1 1.868-1.443 3.6 3.6 0 0 0 .021 1.896q.105.07.2.152c.107.09.226.207.454.433l.068.066.009.009a2 2 0 0 0 .213.18c.383.287.943.563 1.306.741.201.1.342.168.359.193l.004.008c-.012.193-.695.858-.933.858-2.206 0-2.564 1.335-2.564 1.335.087.997.714 1.839 1.517 2.357a4 4 0 0 0 .439.241q.114.05.228.094c.325.115.665.18 1.01.194 3.043.143 4.155-2.804 3.129-4.745v-.001a3 3 0 0 0-.731-.9 3 3 0 0 0-.571-.37l-.003-.002a2.68 2.68 0 0 1 1.87.454 3.92 3.92 0 0 0-3.396-1.983q-.116.001-.23.01l-.042.003V4.31h-.002a4 4 0 0 0-.8.14 7 7 0 0 0-.333-.314 2 2 0 0 0-.2-.152 4 4 0 0 1-.088-.383 5 5 0 0 1 1.352-.289l.05-.003c.052-.004.125-.01.205-.012C7.996 2.212 8.733.843 10.17.002l-.003.005.003-.001.002-.002h.002l.002-.002h.015a.02.02 0 0 1 .012.007 2.4 2.4 0 0 0 .206.48q.09.153.183.297c.49.774 1.023 1.379 1.543 1.968.771.874 1.512 1.715 2.036 3.02l-.001-.013a8 8 0 0 0-.786-2.353'/> </svg>")); delete this.defaultFavicon; return this.defaultFavicon = `resource://${img}`; }, id: "ucf-cbbtn-LnkCreator", localized: false, onCreated(btn) { btn.owner = this; btn.tooltipText = this.label; btn.setAttribute("image", this.image); btn.setAttribute("oncommand", "owner.createLnk(this)"); }, init() { this.widget.parent = this; this.widget.contextmenu.destroy = id => { CustomizableUI.destroyWidget(id); delete this.data[id.slice(8)]; this.save(); } try {this.data = JSON.parse(Cu.readUTF8URI(Services.io.newURI( `chrome://user_chrome_files/content/custom_scripts/${this.id}-data.json` )))} catch {this.data = {}; return this;} for(var [id, inf] of Object.entries(this.data)) this.createWidget(id, inf.url, inf.name); return this; }, get fs() { delete this.fs; return this.fs = Cc["@mozilla.org/browser/favicon-service;1"] .getService(Ci.nsIFaviconService); }, createLnk(btn) { var id = Date.now(); var gb = btn.ownerGlobal.gBrowser; var uri = gb.currentURI; var label = gb.contentTitle.slice(0, 75); var widget = this.createWidget(id, uri, label); var {area, position} = CustomizableUI.getPlacementOfWidget(this.id); CustomizableUI.addWidgetToArea(widget.id, area, position + 1); this.data[id] = {name: label, url: uri.spec}; this.save(); }, createWidget(id, url, label) { var obj = { uri: url.spec ? url : Services.io.newURI(url), id: "ucf-lnk-" + id, label, ...this.widget }; var widget = obj.widget = CustomizableUI.createWidget(obj); this.fs.getFaviconDataForPage(obj.uri, obj); return widget; }, tip: "\nShift+ПКМ - Удалить кнопку", widget: { localized: false, onCreated(btn) { btn.uri = this.uri; btn.addTab = this.addTab; btn.oncontextmenu = this.contextmenu; btn.setAttribute("oncommand", "addTab(this)"); btn.tooltipText = this.label + this.parent.tip; this.image && btn.setAttribute("image", this.image); }, addTab(btn) { var gb = btn.ownerGlobal.gBrowser; gb.selectedTab = gb.addTrustedTab(btn.uri.spec, {userContextId: 1}); }, contextmenu: function checkShift(e) { if (e.shiftKey) e.preventDefault(), checkShift.destroy(e.target.id); }, onComplete(uri, len, arr, mmt) { this.image = len ? `data:${mmt};base64,${btoa(String.fromCharCode(...arr))}` : this.parent.defaultFavicon for(var {node} of this.widget.instances) node.hasAttribute("image") || node.setAttribute("image", this.image); delete this.widget; } }, save() { var file = Services.dirsvc.get("UChrm", Ci.nsIFile), CC = Components.Constructor; ["user_chrome_files", "custom_scripts", this.id + "-data.json"].forEach(file.append); var te = new (Cu.getGlobalForObject(Cu).TextEncoder)(); var fos = CC("@mozilla.org/network/file-output-stream;1", "nsIFileOutputStream", "init") // MODE_{WRONLY, CREATE, TRUNCATE}, PERMS_FILE .bind(null, file, 0x02 | 0x08 | 0x20, 0o644, 0); var bos = CC("@mozilla.org/binaryoutputstream;1", "nsIBinaryOutputStream", "setOutputStream"); (this.save = () => { var stream = new fos(); try {new bos(stream).writeByteArray( te.encode(JSON.stringify(this.data)) );} catch(ex) {Cu.reportError(ex);} finally {stream.close();} })(); } }).init()))(); Третью кнопку тоже выкладывать? |
Vitaliy V. > 28-04-2024 14:54:43 |
egorsemenov06 скрытый текст Выделить код Код://Атрибут инспектор........................... (async () => CustomizableUI.createWidget({ id: "AttributesInspector", label: "Attributes Inspector", get image() { var img = `${this.id.toLowerCase()}-img`; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(img, Services.io.newURI("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24'><path style='fill:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity;' d='M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2M6,4H13L18,9V17.58L16.16,15.74C17.44,13.8 17.23,11.17 15.5,9.46C14.55,8.5 13.28,8 12,8C10.72,8 9.45,8.5 8.47,9.46C6.5,11.41 6.5,14.57 8.47,16.5C9.44,17.5 10.72,17.97 12,17.97C12.96,17.97 13.92,17.69 14.75,17.14L17.6,20H6V4M14.11,15.1C13.55,15.66 12.8,16 12,16C11.2,16 10.45,15.67 9.89,15.1C9.33,14.54 9,13.79 9,13C9,12.19 9.32,11.44 9.89,10.88C10.45,10.31 11.2,10 12,10C12.8,10 13.55,10.31 14.11,10.88C14.67,11.44 15,12.19 15,13C15,13.79 14.68,14.54 14.11,15.1Z' /></svg>")); delete this.image; return this.image = `resource://${img}`; }, localized: false, onCreated(btn) { btn.setAttribute("image", this.image); btn.setAttribute("tooltiptext", this.label); btn.onmouseenter = btn.onmouseleave = this.onmouse; btn.setAttribute("oncommand", "handleCommand(this)"); btn.handleCommand = this.handleCommand; }, get handleCommand() { delete this.handleCommand; return this.handleCommand = btn => { (btn.handleCommand = new btn.ownerGlobal.Function(this.code).bind(btn))(); } }, get code() { delete this.code; return this.code = "this.focusedWindow && this.focusedWindow.focus();\n" + Cu.readUTF8URI(Services.io.newURI( "chrome://user_chrome_files/content/custom_scripts/custom_script/attributesInspector.js" )); }, onmouse: e => e.target.focusedWindow = e.type.endsWith("r") && Services.wm.getMostRecentWindow(null) }))(); |
Vitaliy V. > 28-04-2024 15:21:35 |
egorsemenov06 пишет
Я хз почему не работает, и что значит добавил, нужно заменить код в custom_script.js |
Vitaliy V. > 28-04-2024 15:55:12 |
egorsemenov06 |
Dobrov > 29-04-2024 04:23:05 |
Vitaliy V. раз тут завал просьб, добавлю свои 3 копейки: Просьба улучшить ucf_contextmenuopenwith для нормальной работы с yt-dlp: ucf_contextmenuopenwith.js – возможно, этот код устарел Выделить код Код:(this.contextmenuopenwith = { _eventlisteners: [], menupage: {}, menulink: {}, init(that) { var attrimage = true; // true или false Добавить иконки (атрибут "image") или нет var submenu = false; // true или false Добавить подменю для пунктов или нет var prelabpage = false; // Добавить вначале "Открыть страницу в "; var prelablink = false; // Добавить вначале "Открыть ссылку в "; // [true или false Показывать пункт на странице или нет, true или false Показывать пункт на ссылках или нет, 'ID пункта', 'имя приложения', 'путь к приложению', 'аргументы через пробел (то что в двойных кавычках считается за один аргумент)', 'иконка (для Windows необязательно)'], var arrayWindows = [ // [true, true, 'edge', 'Microsoft Edge', 'C:\\Windows\\explorer.exe', '"microsoft-edge:%OpenURI "', 'moz-icon://file://C:\\ndows\\SystemApps\\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\\MicrosoftEdge.exe?size=16'], [true, true, 'videodownloader', '4K Downloader', 'C:\\Program Files (x86)\\4KDownload\\4kvideodownloader\\4kvideodownloader.exe', '%OpenURI'], // [true, true, 'potplayer', 'DAUM PotPlayer', 'C:\\Program Files\\PotPlayer\\PotPlayerMini64.exe', '%OpenURI'], // [true, true, 'vlc', 'VLC', 'C:\\Program Files\\VideoLAN\\VLC\\vlc.exe', '%OpenURI'], ]; var arrayLinux = [ // для Linux // [true, true, 'vlc', 'VLC', '/usr/bin/vlc', '%OpenURI', 'moz-icon://stock/vlc?size=menu'], // [false, true, 'thunderbird', 'Thunderbird', '/usr/bin/thunderbird', '-compose "to=%OpenURI"', 'moz-icon://stock/thunderbird?size=menu'], [true, true, 'yt-dlp', 'Скачать видео в yt-dlp', '/usr/bin/xterm', '-e "yt-dlp \'%OpenURI\'; beep; sleep 3"', 'moz-icon://stock/go-down?size=menu'], // терминал вашей Рабочей среды, в ~/.config/yt-dlp.conf указан каталог загрузки [false, true, 'mpv', 'Смотреть в MPV плеер', '/usr/bin/mpv', '--ytdl-format=bestvideo[height<=?720][fps<=?30]+bestaudio/best[height<=?720][fps<=?30] "%OpenURI"', 'moz-icon://stock/mpv?size=menu'], ]; var arrayMacos = [ // для MacOS // [true, true, 'downie', 'Скачать видео в Downie 4', '/usr/bin/open', '-b com.charliemonroe.Downie-4 %OpenURI', 'moz-icon://file:///Applications/Downie 4.app?size=16'], [true, true, 'yt-dlp', 'Найти/скачать видео: yt-dlp', '/usr/bin/osascript', `-e "tell app %quotTerminal%quot to activate do script %quotyt-dlp '%OpenURI' && say 'download complete'; exit%quot"`, 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAAAAAClZ7nPAAAAAXRSTlMAQObYZgAAACNJREFUCNdjYH/AgBX9/89Q/4/B/g+D/A8G/g8gEeYDDIwNAIB7EDCcKCcMAAAAAElFTkSuQmCC'], // 'moz-icon://file:///System/Library/Image Capture/Support/Application/AutoImporter.app?size=16' [true, true, 'mpv', 'Смотреть в MPV плеер', '/usr/bin/open', '-n -a mpv --args --ytdl-format=bestvideo[height<=?720][fps<=?30]+bestaudio/best[height<=?720][fps<=?30] %OpenURI', 'moz-icon://file:///Applications/mpv.app?size=16'], [true, true, 'Safari', 'Обзор страницы в Safari', '/usr/bin/open', '-b com.apple.Safari %OpenURI', 'chrome://branding/content/icon32.png'], ]; var arrayOS, platform = AppConstants.platform, length; if (platform == "win") arrayOS = arrayWindows; else if (platform == "linux") arrayOS = arrayLinux; else if (platform == "macosx") arrayOS = arrayMacos; else return; if (!(length = arrayOS.length)) return; var addEventListener = this.addEventListener.bind(this); var popup = document.querySelector("#contentAreaContextMenu"); var create = evt => { if (evt.target != popup || gContextMenu.webExtBrowserType === "popup") return; popup.removeEventListener("popupshowing", create); var seppage = popup.querySelector("#context-sep-selectall") || popup.querySelector("#frame-sep") || popup.lastElementChild; var seplink = popup.querySelector("#context-sep-copylink") || popup.querySelector("#context-sep-open") || popup.firstElementChild; var fragpage = document.createDocumentFragment(), fraglink = document.createDocumentFragment(), _prelabpage = "", _prelablink = ""; if (length == 1) submenu = false; if (!submenu) _prelabpage = prelabpage ? "Открыть страницу в " : "", _prelablink = prelablink ? "Открыть ссылку в " : ""; arrayOS.forEach(item => { var id = item[2], name = item[3], path = item[4], arg = !item[5] ? "" : item[5]; if (!id || !name || !path) return; var iconpath = !item[6] ? (`moz-icon://file://${path}?size=16`) : item[6]; if (item[0]) { let menuitem_0 = document.createXULElement("menuitem"); menuitem_0.id = `open-current-page-with-${id}`; menuitem_0.className = "menuitem-iconic open-current-page-with-application"; menuitem_0.setAttribute("label", `${_prelabpage}${name}`); menuitem_0.applicationpath = path; menuitem_0.applicationarg = arg; if (attrimage) menuitem_0.setAttribute("image", iconpath); fragpage.append(menuitem_0); addEventListener(menuitem_0, "command", function page(event) { try { var target = event.currentTarget, arg = target.applicationarg, file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(target.applicationpath); if (!file.exists() || !file.isExecutable()) return; arg = (arg !== "") ? arg.split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/g).map(sp => { if (/%OpenURI/g.test(sp)) { let uri = gBrowser.selectedBrowser.currentURI.displaySpec; try { let _uri = ReaderMode.getOriginalUrl(uri); if (_uri) uri = Services.io.newURI(_uri).displaySpec; } catch(e) {} try { uri = decodeURIComponent(uri); } catch(e) {} return sp.replace(/^"|"$/g, "").replace(/%quot/g, '"').replace(/%OpenURI/g, uri); } return sp.replace(/^"|"$/g, "").replace(/%quot/g, '"'); }) : []; var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); process.init(file); process.runwAsync(arg, arg.length); } catch(e) {} }); } if (item[1]) { let menuitem_1 = document.createXULElement("menuitem"); menuitem_1.id = `open-link-with-${id}`; menuitem_1.className = "menuitem-iconic open-link-with-application"; menuitem_1.setAttribute("label", `${_prelablink}${name}`); menuitem_1.applicationpath = path; menuitem_1.applicationarg = arg; if (attrimage) menuitem_1.setAttribute("image", iconpath); fraglink.append(menuitem_1); addEventListener(menuitem_1, "command", function link(event) { try { var target = event.currentTarget, arg = target.applicationarg, file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(target.applicationpath); if (!file.exists() || !file.isExecutable() || !window.gContextMenu?.linkURI?.displaySpec) return; arg = (arg !== "") ? arg.split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/g).map(sp => { if (/%OpenURI/g.test(sp)) { let uri = gContextMenu.linkURI.displaySpec; try { let _uri = ReaderMode.getOriginalUrl(uri); if (_uri) uri = Services.io.newURI(_uri).displaySpec; } catch(e) {} try { uri = decodeURIComponent(uri); } catch(e) {} return sp.replace(/^"|"$/g, "").replace(/%quot/g, '"').replace(/%OpenURI/g, uri); } return sp.replace(/^"|"$/g, "").replace(/%quot/g, '"'); }) : []; var process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); process.init(file); process.runwAsync(arg, arg.length); } catch(e) {} }); } }); that.unloadlisteners.push("contextmenuopenwith"); var funcpopupshowing, funcpopuphiding; if (!submenu) { seppage.after(fragpage); seplink.before(fraglink); funcpopupshowing = () => { var link = gContextMenu.onLink || gContextMenu.onMailtoLink; for(let arr of this._eventlisteners) { if (arr[2].name === "page") arr[0].hidden = link; else if (arr[2].name === "link") arr[0].hidden = !link; } }; funcpopuphiding = () => { for(let arr of this._eventlisteners) { if (arr[1] === "command") arr[0].hidden = true; } }; } else { if (fragpage.children.length) { let menu = this.menupage = document.createXULElement("menu"); menu.id = "open-current-page-with-submenu"; menu.className = "menu-iconic open-current-page-with-application"; menu.setAttribute("label", "Открыть страницу в..."); let menupopup = document.createXULElement("menupopup"); menupopup.append(fragpage); menu.append(menupopup); seppage.after(menu); } if (fraglink.children.length) { let menu = this.menulink = document.createXULElement("menu"); menu.id = "open-link-with-submenu"; menu.className = "menu-iconic open-link-with-application"; menu.setAttribute("label", "Открыть ссылку в..."); let menupopup = document.createXULElement("menupopup"); menupopup.append(fraglink); menu.append(menupopup); seplink.before(menu); } funcpopupshowing = () => { var link = gContextMenu.onLink || gContextMenu.onMailtoLink; this.menupage.hidden = link; this.menulink.hidden = !link; }; funcpopuphiding = () => { this.menupage.hidden = true; this.menulink.hidden = true; }; } funcpopupshowing(); addEventListener(popup, "popupshowing", e => { if (e.target != popup || gContextMenu.webExtBrowserType === "popup") return; funcpopupshowing(); }); addEventListener(popup, "popuphiding", e => { if (e.target != popup) return; funcpopuphiding(); }); }; popup.addEventListener("popupshowing", create); }, addEventListener(...arr) { var elm = arr[0]; if (!elm) return; elm.addEventListener(...arr.slice(1)); this._eventlisteners.push(arr); }, destructor() { for(let arr of this._eventlisteners) arr.shift().removeEventListener(...arr); delete this._eventlisteners; } }).init(this); |
Vitaliy V. > 30-04-2024 11:29:13 |
Dobrov пишет
Ссылки с m3u не всегда так заканчиваются, может быть так .m3u8?бла-бла-бла, и почему только плейлисты m3u а просто медиа файлы и т.д. Dobrov пишет
А разве не работает на moz-extension:// там вроде только в popup отключено, короче не знаю проверь сам на Video DownloadHelper Код упростил теперь один и тот же пункт для ссылок, страницы, выделенного, буфера скрытый текст Выделить код Код:// Script For browser window document [ChromeOnly] /** * @param {String | Symbol} id (required) ID * @param {Boolean} attrimage (required) Добавить иконки (атрибут "image") или нет * @param {Boolean} submenu (required) Добавить подменю для пунктов или нет * @param {String} preitem (required) Prefix для пунктов, где Prefix не указан в name * @param {String} menuname (required) Название меню, если submenu = true * @param {String} selector (required) Селектор в контекстном меню перед которым добавлять пункты * * @param {String} name: (required) * '[Prefix |]Название', * @param {String} path: (required) * 'Путь к приложению', * @param {String} tooltip: (optional) * Подсказка для пункта меню * @param {String} args: (optional) * `Аргументы через пробел "то что в двойных кавычках считается за один аргумент"`, * Собственные аргументы: * %OpenURL% - адрес * %ProfD% - путь до профиля * %FilePicker% - выбор папки, например для скачивания * %Prompt(message)% - вызвать диалоговое окно для изменения текста, например названия медиа файла * %quot% - двойные кавычки * @param {String} rcargs: (optional) * Тоже что и args но выполняется по правому клику * @param {Boolean} clipboard: (optional) * Адрес из буфера обмена * @param {String} iconpath: (optional) * 'Иконка', */ (async ( id = Symbol("contextmenuopenwith"), attrimage = true, submenu = true, preitem = "Открыть в ", menuname = "Открыть в...", selector = "#context-sep-open", Linux = [ { name: 'VLC', path: '/usr/bin/vlc', iconpath: 'moz-icon://stock/vlc?size=menu', }, { name: 'Haruna', path: '/usr/bin/haruna', iconpath: 'moz-icon://stock/haruna?size=menu', }, { name: 'Скачать в |Yt-dlp', path: '/usr/bin/konsole', tooltip: 'ПКМ: Скачать в Yt-dlp с выбором папки', // yt-dlp скачать видео, используя куки браузера, предпочтительно .mp4 с кодеком hevc|h265|avc|h264 с разрешением <=1080 args: `--hold --workdir ~/Загрузки -e "yt-dlp --cookies-from-browser firefox:%ProfD% -f %quot%bv[height<=1080][ext=mp4][vcodec~='^(hevc|h265|avc|h264)']+ba[ext~='(aac|m4a)']/best[height<=1080][ext=mp4]/best[height<=1080]/best%quot% %OpenURL%"`, // с выбором папки rcargs: `--hold --workdir %FilePicker% -e "yt-dlp --cookies-from-browser firefox:%ProfD% -f %quot%bv[height<=1080][ext=mp4][vcodec~='^(hevc|h265|avc|h264)']+ba[ext~='(aac|m4a)']/best[height<=1080][ext=mp4]/best[height<=1080]/best%quot% %OpenURL%"`, iconpath: 'moz-icon://stock/youtube-dl?size=menu', }, { name: 'Скачать из буфера в |FFmpeg', path: '/usr/bin/konsole', tooltip: 'ПКМ: Скачать из буфера в FFmpeg с выбором папки и названия файла', // ffmpeg копировать поток видео аудио в контейнер mp4 args: `--hold --workdir ~/Загрузки -e "ffmpeg -i %OpenURL% -c copy -f mp4 Video.mp4"`, // с выбором папки и названия файла rcargs: `--hold --workdir %FilePicker% -e "ffmpeg -i %OpenURL% -c copy -f mp4 %Prompt(Video.mp4)%"`, clipboard: true, iconpath: 'moz-icon://stock/utilities-terminal?size=menu', }, ], Windows = [ { name: 'VLC', path: 'C:\\Program Files\\VideoLAN\\VLC\\vlc.exe', }, ], macOS = [ ], /***************************************************/ popup, showing = e => (e.target != popup || gContextMenu.webExtBrowserType === "popup" || (gContextMenu.isContentSelected || gContextMenu.onTextInput) && !gContextMenu.linkURL), hiding = e => (e.target != popup), ) => (this[id] = { get ProfD() { delete this.ProfD; return this.ProfD = Services.dirsvc.get("ProfD", Ci.nsIFile).path; }, _eventListeners: [], _eventCListeners: [], init() { switch (Services.appinfo.OS) { case "Linux": this.arrOS = Linux; break; case "WINNT": this.arrOS = Windows; break; case "Darwin": this.arrOS = macOS; break; default: return; } var alength = this.arrOS.length; if (!alength) return; if (alength == 1) submenu = false; popup = document.querySelector("#contentAreaContextMenu"); this.addListener(popup, "popupshowing", this); setUnloadMap(id, () => this.destructor()); }, addListener(elm, type, listener) { elm.addEventListener(type, listener); this._eventListeners.push({elm, type, listener}); }, addCListener(elm, type, listener) { elm.addEventListener(type, listener); this._eventCListeners.push({elm, type, listener}); }, handleEvent(e) { this[e.type](e); }, popupshowing(e) { if (showing(e)) return; var contextsel = popup.querySelector(`:scope > ${selector}`) || popup.querySelector(":scope > menuseparator:last-of-type"); var fragment = document.createDocumentFragment(); var itemId = 0; this.arrOS.forEach(item => { var {name, path, tooltip, args, rcargs, clipboard, iconpath} = item; if (!name) name = "contextmenuopenwith"; name = name.split("|"); var mitem = document.createXULElement("menuitem"); mitem.id = `ucf-menu-open-with-${++itemId}`; mitem.className = "menuitem-iconic ucf-menu-open-with"; var str = name.join(""), len = name.length > 1; if (submenu) { mitem.setAttribute("label", len ? name.slice(1).join("") : str); if (tooltip) mitem.tooltipText = `${str}\n${tooltip}`; else if (len) mitem.tooltipText = str; } else { mitem.setAttribute("label", `${len ? "" : preitem}${str}`); if (tooltip) mitem.tooltipText = tooltip; } mitem.apppath = path; mitem.appargs = args; mitem.apprcargs = rcargs; mitem.appclipboard = clipboard; if (attrimage) mitem.setAttribute("image", iconpath || `moz-icon://file://${path}?size=16`); fragment.append(mitem); this.addCListener(mitem, "click", this); }); if (submenu) { let rootmenu = this.rootmenu = document.createXULElement("menu"); rootmenu.id = "ucf-menu-open-with-submenu"; rootmenu.className = "menu-iconic ucf-menu-open-with"; rootmenu.setAttribute("label", menuname); let mpopup = document.createXULElement("menupopup"); mpopup.append(fragment); rootmenu.append(mpopup); contextsel.before(rootmenu); this.popupshowing = this.menuShow; this.popuphiding = this.menuHide; } else { contextsel.before(fragment); this.popupshowing = this.itemsShow; this.popuphiding = this.itemsHide; } this.addListener(popup, "popuphiding", this); }, menuShow(e) { if (showing(e)) return; this.rootmenu.hidden = false; }, itemsShow(e) { if (showing(e)) return; for (let {elm} of this._eventCListeners) elm.hidden = false; }, menuHide(e) { if (hiding(e)) return; this.rootmenu.hidden = true; }, itemsHide(e) { if (hiding(e)) return; for (let {elm} of this._eventCListeners) elm.hidden = true; }, async click(e) { try { let {appargs, apprcargs, apppath: path, appclipboard: clipboard} = e.currentTarget, file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); if (!file.exists()) return; if (file.isExecutable()) { let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); process.init(file); let args = !(e.button === 2 && apprcargs) ? appargs : apprcargs; let URL = !clipboard === !(e.shiftKey || e.button === 1) ? (gContextMenu?.linkURI?.displaySpec || this.getCurrentURL()) : this.readFromClipboard(); if (args) { let openuri = false; args = args.split(/\s+(?=(?:[^"]*"[^"]*")*[^"]*$)/); for (let [ind, sp] of args.entries()) { sp = sp.replace(/^["']+|["']+$/g, "").replace(/%quot%/g, '"').replace("%ProfD%", this.ProfD); if (/%FilePicker%/.test(sp)) { let filePicker = await this.filePicker(); if (!filePicker) throw "Отмена!"; sp = sp.replace(/%FilePicker%/, filePicker); } let match = sp.match(/%Prompt\((.*?)\)%/); if (match) { let newName = { value: match[1] }; if (!Services.prompt.prompt(window, "Запрос", "Введите название", newName, null, {})) throw "Отмена!"; sp = sp.replace(/%Prompt\(.*?\)%/, newName.value); } if (/%OpenURL%/.test(sp)) { openuri = true; sp = sp.replace("%OpenURL%", URL); } args[ind] = sp; } if (!openuri) args.push(URL); } else args = [URL]; process.runwAsync(args, args.length); } else file.launch(); } catch (e) {console.log(e);} }, filePicker() { return new Promise(resolve => { var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); try { fp.init(window.browsingContext, "Выбор папки", fp.modeGetFolder); } catch { fp.init(window, "Выбор папки", fp.modeGetFolder); } fp.open(res => resolve(res == fp.returnOK ? fp.file.path : null)); }); }, readFromClipboard() { try { let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); trans.init(docShell.QueryInterface(Ci.nsILoadContext)); trans.addDataFlavor("text/plain"); let {clipboard} = Services, data = {}, url = ""; clipboard.getData(trans, clipboard.kGlobalClipboard); trans.getTransferData("text/plain", data); if (data.value) url = data.value.QueryInterface(Ci.nsISupportsString).data.trim(); if (/^(?:https?|ftp):/.test(url)) return url; } catch {} throw "Нет адреса в буфере обмена!"; }, getCurrentURL() { var url = gBrowser.selectedBrowser.currentURI.displaySpec; try { let _url = ReaderMode.getOriginalUrl(url); if (_url) url = Services.io.newURI(_url).displaySpec; } catch {} return url; }, destructor() { for (let {elm, type, listener} of this._eventListeners) elm.removeEventListener(type, listener); for (let {elm, type, listener} of this._eventCListeners) elm.removeEventListener(type, listener); }, }).init())(); |
Dobrov > 01-05-2024 04:42:13 |
Vitaliy V. – спасибо! Вопрос: делаю общие функции в MJS-скрипте через scriptsbackground: [ // In background [System Principal]: Выделить код Код:var {Services} = globalThis || ChromeUtils.import("resource://gre/modules/Services.jsm"); var win = wm.getMostRecentWindow("navigator:browser") || globalThis; var name = "Dobrov", EXPORTED_SYMBOLS = [`${name}Child`]; // так не работает: globalThis[Symbol.for('Dobrov')] = Dobrov; ChromeUtils.domProcessChild.childID || ({ init(topic) { globalThis[Symbol.for('Dobrov')] = Dobrov; //общие функции } }).init("browser-delayed-startup-finished"); var Dobrov = { toTab(url = 'about:serviceworkers', go){ //открыть вкладку | закрыть её | выбрать for(var tab of win.gBrowser.visibleTabs) if(tab.linkedBrowser.currentURI.spec == url) {go ? win.gBrowser.selectedTab = tab : win.gBrowser.removeTab(tab); return;} win.gBrowser.addTrustedTab(url); win.gBrowser.selectedTab = win.gBrowser.visibleTabs[win.gBrowser.visibleTabs.length -1]; }, async Status(text,time){ var StatusPanel = win.StatusPanel; if(StatusPanel.update.tid) win.clearTimeout(StatusPanel.update.tid) else { var {update} = StatusPanel; StatusPanel.update = () => {}; StatusPanel.update.ret = () => { StatusPanel.update = update,StatusPanel.update(); } } StatusPanel.update.tid = win.setTimeout(StatusPanel.update.ret,time || 5e3); StatusPanel._label = text; }, }; |
Vitaliy V. > 01-05-2024 17:24:31 |
Dobrov пишет
Так а как она заработает если на тот момент переменная var Dobrov = ещё не определена. Тогда пиши ниже или сразу так |
Dumby > 04-05-2024 08:36:14 |
Bug 1892965 - Rename Sidebar launcher and SidebarUI Vitaliy V. Кстати, ещё, из-за этого бага, onViewToolbarsPopupShowing() В результате, в консоли появляется запись типа Так вот, это относится и к тулбарам UCF. |
_zt > 04-05-2024 08:44:17 |
Vitaliy V. |
Dobrov > 04-05-2024 13:15:03 |
Vitaliy V. спасибо за новый ucf_contextmenu_openwith ! Скрипт создаёт строку в контекст-меню даже при отсутствии yt-dlp, поэтому нужна ещё проверка. |
Vitaliy V. > 04-05-2024 14:54:02 |
Dumby пишет
Хорошо, буду иметь ввиду если не исправят, пока это ничего не ломает, останова кода нигде не вызывает, _zt пишет
Смотря какой, DOM есть не только на сайтах, а где есть HTML XHTML XML, интерфейс браузера в том числе. _zt пишет
А подробнее как воспроизвести это, может как раз какой-нибудь скрипт у вас это и делает. Dobrov пишет
Такие проверки дорого стоят, может быть задержка появления меню или пунктов, лучше сделать например так: при клике на пункт если приложение отсутствует, то выводится уведомление типа такое то приложение по данному пути не найдено, установите, или скрыть пункт меню |
Алексей У. > 05-05-2024 19:12:34 |
А где можно достать UserChromeFiles для Firefox 88? Тот, который для последних версий, в нем не работает. |
kokoss > 05-05-2024 21:23:52 |
Алексей У. пишет
|
Vitaliy V. > 07-05-2024 15:14:53 |
Добавил поддержку Гром-птицы, но без панелей и кнопок, CustomizableUI там урезанный поэтому кнопки таким способом не добавить. скрытый текст |
LGS > 08-05-2024 12:18:50 |
В [firefox]125 Add Toolbar Buttons отвалился, само расширение есть, а кнопок нет... в 117, вроде, было подобное. Можно ли как-то вылечить..? |
Vitaliy V. > 08-05-2024 13:34:38 |
LGS |
_zt > 08-05-2024 14:47:44 |
Vitaliy V. пишет
Да нет, нет такого и никогда не ставил, даже в обезьяну, просто такое не интересует. |
Vitaliy V. > 08-05-2024 15:02:51 |
_zt |
_zt > 08-05-2024 17:48:47 |
Vitaliy V. |
LGS > 08-05-2024 19:16:37 |
Vitaliy V. пишет
Я немного по другому думаю - почему у вас и других работает, а у меня нет..? Vitaliy V. пишет
Ни 2021, ни 2024 версии не работают. АТВ устанавливается, в списке установленных отображается, но кнопок нет. В ФФ124 все нормально. |
unter_officer > 08-05-2024 19:48:49 |
LGS пишет
Попробуйте этот: https://forum.mozilla-russia.org/viewto … 53#p808453 |
LGS > 08-05-2024 20:28:47 |
unter_officer пишет
С этим заработало. Тысяча благодарностей. |
Dobrov > 09-05-2024 05:16:58 |
Vitaliy V. пишет
Скрипты в Thunderbird всё же редко необходимы… |
Vitaliy V. > 09-05-2024 13:45:20 |
Dobrov пишет
В текущую сборку UCF добавить поддержку Palemoon нереально, там код древний. Разве что как отдельную сборку, но абсолютно весь код UCF переписывать на древний такое себе... Да и зачем там же xul расширения можно установить или свои написать. |
unter_officer > 09-05-2024 13:47:25 |
Vitaliy V. пишет
А какая минимальная поддерживаемая версия Гром-птицы? На 78 или 91 будет работать? |
Vitaliy V. > 09-05-2024 14:16:11 |
- |
_zt > 09-05-2024 16:51:22 |
Vitaliy V. пишет
Не подходит, ломает работу расширений. Например этого Link Text and Location Copier |
Vitaliy V. > 09-05-2024 17:46:46 |
_zt пишет
Но мне подходит, с какого какие то веб сайты будут перезаписывать мне буфер обмена, нет уж у меня всегда отключена данная настройка. |
_zt > 09-05-2024 21:21:17 |
Vitaliy V. скрытый текст
Напишите? ) |
Vitaliy V. > 10-05-2024 01:22:34 |
_zt пишет
Тут ещё вопрос ломает ли, в этом расширении Link Text and Location Copier изменил в linktextlocationcopier.js скрытый текст Выделить код Код:/* const code = 'copyToClipboard(' + JSON.stringify(outputtext) + ',' + clickedItem.outputAsHTML +');'; browser.tabs.executeScript({ code: 'typeof copyToClipboard === "function";', }).then((results) => { if (!results || results[0] !== true) { return browser.tabs.executeScript(tab.id, { file: 'clipboard-helper.js' }); } }).then(() => { return browser.tabs.executeScript(tab.id, { code }); }).catch((error) => { console.error('Failed to copy text: ' + error); }); */ const type = clickedItem.outputAsHTML ? "text/html" : "text/plain"; const blob = new Blob([outputtext], { type }); const data = [new ClipboardItem({ [type]: blob })]; navigator.clipboard.write(data); и нормально копируется с настройкой dom.event.clipboardevents.enabled = false egorsemenov06 скрытый текст Выделить код Код:(async ( id = "context-copylink", image = "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:context-fill rgb(0, 142, 152);fill-opacity:context-fill-opacity'><path d='M4.715 6.542 3.343 7.914a3 3 0 1 0 4.243 4.243l1.828-1.829A3 3 0 0 0 8.586 5.5L8 6.086a1.002 1.002 0 0 0-.154.199 2 2 0 0 1 .861 3.337L6.88 11.45a2 2 0 1 1-2.83-2.83l.793-.792a4.018 4.018 0 0 1-.128-1.287z'/><path d='M6.586 4.672A3 3 0 0 0 7.414 9.5l.775-.776a2 2 0 0 1-.896-3.346L9.12 3.55a2 2 0 1 1 2.83 2.83l-.793.792c.112.42.155.855.128 1.287l1.372-1.372a3 3 0 1 0-4.243-4.243L6.586 4.672z'/></g></svg>", substitution = `ucf-${id.toLowerCase()}-img`, PHandler = Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler), ) => { if (!PHandler.hasSubstitution(substitution)) PHandler.setSubstitution(substitution, Services.io.newURI(image)); var menuitem = document.createXULElement("menuitem"); document.getElementById(id).after(menuitem); var hidden = () => !nsContextMenu.contentData.context.linkTextStr; menuitem.hidden = true; menuitem.render = () => { if (hidden()) return; menuitem.hidden = false; menuitem.id = `${id}text`; menuitem.label = "Скопировать текст ссылки"; menuitem.setAttribute("oncommand", "navigator.clipboard.writeText(gContextMenu.linkTextStr);"); delete menuitem.render; menuitem.className = "menuitem-iconic"; menuitem.style.cssText = `list-style-image:url("resource://${substitution}");-moz-context-properties:fill,fill-opacity;fill:currentColor;`; menuitem.render(); menuitem.render = () => menuitem.hidden = hidden(); } })(); |
_zt > 10-05-2024 10:03:56 |
Vitaliy V. пишет
Я не знаю как это воспроизвести, у меня не работает, в том числе на чистом профиле. Проверял на |
Ultima2m > 10-05-2024 12:47:28 |
Привет всем. Подскажите, как уменьшить высоту панели вкладок? |
Vitaliy V. > 10-05-2024 12:59:07 |
_zt пишет
Да это работает только на пока Но здесь же не нужно копировать изображения вроде достаточно будет navigator.clipboard.writeText(), попробуйте так скрытый текст Выделить код Код:/* const code = 'copyToClipboard(' + JSON.stringify(outputtext) + ',' + clickedItem.outputAsHTML +');'; browser.tabs.executeScript({ code: 'typeof copyToClipboard === "function";', }).then((results) => { if (!results || results[0] !== true) { return browser.tabs.executeScript(tab.id, { file: 'clipboard-helper.js' }); } }).then(() => { return browser.tabs.executeScript(tab.id, { code }); }).catch((error) => { console.error('Failed to copy text: ' + error); }); */ navigator.clipboard.writeText(outputtext); |
Vitaliy V. > 10-05-2024 14:53:09 |
Ultima2m пишет
Почему в этой теме непонятно, ну да ладно скрытый текст Выделить код Код::@-moz-document url("chrome://browser/content/browser.xhtml") { :root { --tab-min-height: 26px !important; --tab-block-margin: 1px !important; } :root[uidensity="touch"] { /* мобильный режим */ --tab-min-height: 32px !important; } .tab-label-container { height: 1.75em !important; } .tab-label { line-height: 1.25em !important; height: 1.25em !important; margin-block: 0 !important; } .tab-secondary-label { margin-block: -.25em 0 !important; font-size: .75em !important; } .tab-icon-sound-label { line-height: 1.25em !important; height: 1.25em !important; margin-block: 0 !important; } } |
_zt > 10-05-2024 15:30:23 |
Vitaliy V. |
Ultima2m > 10-05-2024 15:36:07 |
Vitaliy V. пишет
Спасибо. Не работает. Менял --tab-min-height: 20px !important; |
Vitaliy V. > 10-05-2024 16:30:38 |
Ultima2m пишет
Так бы и сказали что нужно так сильно уменьшить скрытый текст Выделить код Код:@-moz-document url("chrome://browser/content/browser.xhtml") { :root { --tab-min-height: 20px !important; --tab-block-margin: 0px !important; --tabs-navbar-shadow-size: 0px !important; --tab-border-radius: 4px !important; } :root[uidensity="touch"] { /* мобильный режим */ --tab-min-height: 32px !important; } .tab-background { border-end-start-radius: 0 !important; border-end-end-radius: 0 !important; } .tab-label-container { height: 1.5em !important; } .tab-label { line-height: 1.25em !important; height: 1.25em !important; margin-block: 0 !important; } .tab-secondary-label { margin-block: -.25em 0 !important; font-size: .75em !important; } .tab-icon-sound-label { line-height: 1.25em !important; height: 1.25em !important; margin-block: 0 !important; } .tab-close-button { width: 18px !important; height: 18px !important; padding: 3px !important; } } |
Ultima2m > 10-05-2024 16:47:36 |
Vitaliy V. пишет
Vitaliy V. Спасибо. Теперь нормально. Прямо камень с души упал. |
Алексей У. > 10-05-2024 20:30:16 |
kokoss пишет
Благодарю, установил - работает. Правда хочу отметить замеченный мной нюанс (вернее, недоработку). Когда в адресную строку вводится поисковый запрос, dropmarker заменяется кнопкой "Перейти" (есть такая настройка в скрипте); однако если вместо запроса вставляется готовая ссылка, dropmarker остается на месте, хотя так же должен заменяться кнопкой перехода. Было бы неплохо автору исправить это. И еще небольшой вопрос - можно ли убрать из персонализации кнопку перезапуска или хотя бы перекрасить ее в черный цвет (она красная и этим сильно выделяется из ряда остальных кнопок)? |
Dobrov > 11-05-2024 16:24:33 |
ucf_hookClicks.js – оптимизация скрипта меню и кнопок, устранены ошибки, больше не мусорит переменными в окно. ucf_contextmenu_openwith.js от Vitaliy V. – убрал OpenClipboardURI, чтоб не путаться при кликах, добавил tooltips. Правый клик аналогичен левому с Shift и передаёт ссылку из буфера обмена или выделенного текста. Добавил roll - на строке "Ссылку в плеер MPV" клик колёсиком выполнит команду, указанную в подсказке. Для Linux могу сделать автопоиск терминала, но это усложнит код: path: '/usr/bin/sh', args: `-c "term=$(which konsole xterm xfce4-…` |
Vitaliy V. > 11-05-2024 18:05:50 |
Алексей У. пишет
Это в этом скрипте https://forum.mozilla-russia.org/viewto … 88#p781188 скрытый текст Выделить код Код:// menuItem.setAttribute("image", "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='17' height='16'><path fill='rgb(0, 116, 232)' fill-opacity='context-fill-opacity' d='M15.37 15H17l-3.63-8.54a.75.75 0 0 0-.69-.46h-.82c-.3 0-.58.18-.7.46L9.32 10.8l-.01-.01a10.8 10.8 0 0 1-3.27-2.2 12.38 12.38 0 0 0 2.54-4.18L9.08 3H10V1.5H5.75V0h-1.5v1.5H0V3h7.5l-.33.91c-.47 1.31-1.2 2.52-2.13 3.56-.7-.9-1.25-1.9-1.63-2.97H1.8l.18.48a12.43 12.43 0 0 0 1.97 3.56c-.9.75-1.89 1.35-2.96 1.78v1.58a12.3 12.3 0 0 0 3.96-2.26 12.31 12.31 0 0 0 3.77 2.54L7.53 15h1.64l1.06-2.5h4.08l1.06 2.5Zm-4.5-4 1.4-3.3 1.4 3.3h-2.8Z'/></svg>"); var image = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path fill='context-fill rgb(0, 116, 232)' fill-opacity='context-fill-opacity' d='M15.37 15H17l-3.63-8.54a.75.75 0 0 0-.69-.46h-.82c-.3 0-.58.18-.7.46L9.32 10.8l-.01-.01a10.8 10.8 0 0 1-3.27-2.2 12.38 12.38 0 0 0 2.54-4.18L9.08 3H10V1.5H5.75V0h-1.5v1.5H0V3h7.5l-.33.91c-.47 1.31-1.2 2.52-2.13 3.56-.7-.9-1.25-1.9-1.63-2.97H1.8l.18.48a12.43 12.43 0 0 0 1.97 3.56c-.9.75-1.89 1.35-2.96 1.78v1.58a12.3 12.3 0 0 0 3.96-2.26 12.31 12.31 0 0 0 3.77 2.54L7.53 15h1.64l1.06-2.5h4.08l1.06 2.5Zm-4.5-4 1.4-3.3 1.4 3.3h-2.8Z'/></svg>"; var substitution = `ucf-${menuItem.id.toLowerCase()}-img`; var PHandler = Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler); if (!PHandler.hasSubstitution(substitution)) PHandler.setSubstitution(substitution, Services.io.newURI(image)); menuItem.style.cssText = `list-style-image:url("resource://${substitution}");-moz-context-properties:fill,fill-opacity;fill:currentColor;`; Dobrov |
Алексей У. > 11-05-2024 20:32:44 |
Vitaliy V. пишет
Да, я этот скрипт имел в виду. Зачем вообще убрали из адресной строки dropmarker - не пойму, с ним было очень удобно просматривать выпадающий список. А чтобы недоделку с вставляемой ссылкой устранить, это нужно сам скрипт править? |
Vitaliy V. > 12-05-2024 01:59:01 |
Алексей У. пишет
У меня не воспроизводится dropmarker скрывается с настройкой hidewhenusertyping: true, пробовал на 88, вот только иконка dropmarker'а не загрузилась заменил arrow-down.svg на arrow-dropdown-16.svg. А так да для новых версий нужно править. |
Dobrov > 12-05-2024 03:07:46 |
Vitaliy V. пишет
Шеф, я усё исправил! – там arrOS.length надо было, т.к. имена текущей OS и массивов равны. Vitaliy V. - шапку обновил, добавив ссылку на твой скрипт ucf_contextmenuopenwith.js. |
Dumby > 12-05-2024 15:22:35 |
egorsemenov06 пишет
Странно, у меня ничего подобного не пишет, XML'ка подхватывается. Заресурсить SVG'шки попробовал так: Код Save.js — оставил без изменений, таким, как ты выложил. А в коде создания виджета — убрал get image() {…}, скрытый текст Выделить код Код:// get initCode() { var count = 0; var prfx = "ucf-cbbtn-save-resurl-"; var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var ss = url => { var subst = prfx + ++count; rph.setSubstitution(subst, Services.io.newURI(url)); return "resource://" + subst; } this.image = ss("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 .6C1.6.6.6 1.6.6 3v10c0 1.4 1 2.4 2.4 2.4h10c1.4 0 2.4-1 2.4-2.4V4.84L11.2.602Zm5.4 5.8h2V1m-2 0v5.4H7L5.6 5V1m-2 14v-2.6l1-1h6.8l1 1V15'/></svg>"); var arr = [ "@-moz-document url(chrome://browser/content/browser.xhtml) {", ` #${this.id} menuitem, #content-baseItem, #content-saveItem, #content-editorItem {`, " fill: currentColor !important;", " -moz-context-properties: fill, fill-opacity !important;", " }", " @media (-moz-platform: windows) {", ` #${this.id} menugroup > menuitem {`, " padding-block: .5em !important;", " padding-inline-start: 1em !important;", " }", " }", "}" ]; var url = "data:text/css;charset=utf-8," + encodeURIComponent(arr.join("\n")); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(Services.io.newURI(ss(url)), sss.USER_SHEET); delete this.initCode; return this.initCode = Cu.readUTF8URI(Services.io.newURI( "chrome://user_chrome_files/content/custom_scripts/custom_script/Save.js" )) .replace(/data:image\/svg[^"]+/g, ss); }, Для пунктов в <menugroup> (это, наверно, те, которые у тебя потерялись), там прописан padding, а то что-то у меня его почти совсем никакого не видно. Можно указать свои значения, или удалить строки @media блока, если не требуется. |
Vitaliy V. > 12-05-2024 16:25:57 |
egorsemenov06 пишет
О даже не посмотрел что там иконки ещё есть думал они в начале только |
Vitaliy V. > 12-05-2024 17:57:36 |
egorsemenov06 скрытый текст Выделить код Код:var arr = [ "@-moz-document url(chrome://browser/content/browser.xhtml) {", ` #${this.id} menuitem, #content-baseItem, #content-saveItem, #content-editorItem {`, " fill: currentColor !important;", " fill-opacity: .8 !important;", " -moz-context-properties: fill, fill-opacity !important;", " }", " @media (-moz-platform: windows) {", ` #${this.id} menugroup > menuitem {`, " padding-block: .5em !important;", " padding-inline-start: 1em !important;", " }", " }", "}" ]; |
Алексей У. > 12-05-2024 18:26:51 |
Как убрать из персонализации кнопку перезапуска (появилась после установки UserChromeFiles) или хотя бы перекрасить ее в тот же цвет, что и соседние значки (она красная и этим сильно выделяется из ряда остальных кнопок)? скрытый текст |
Vitaliy V. > 12-05-2024 21:40:06 |
Алексей У. пишет
Отключить в настройках Создать панели и кнопки скрытый текст try { CustomizableUI.createWidget({ id: "add-restart-app", type: "custom", label: "Перезагрузка", ... }); } catch(e) {} Для нового можно скрипт для удаления кнопок https://forum.mozilla-russia.org/viewto … 70#p808770 Перекрасить стилем или в vertical_top_bottom_bar.css изменить скрытый текст |
Алексей У. > 13-05-2024 19:12:12 |
Vitaliy V. пишет
Благодарю, воспользовался первым, самым простым способом. Я, собственно, UserScriptFiles установил ради возвращения dropmarker'а, дополнительные панели и кнопки мне без надобности. Хотя не исключаю того, что в будущем могут понадобиться еще какие-нибудь скриптты. Кстати, нет ли скрипта для возвращения системного вида скроллбаров (как в Windows 7)? В Firefox 69 есть две настройки в about:config, в 88 версии их уже нет. |
Dobrov > 14-05-2024 01:34:57 |
Алексей У., egorsemenov06 и другие "любители" украшательств: |
Dobrov > 19-05-2024 05:15:51 |
Dumby и Vitaliy V. Vitaliy V. - исправил твой код чтения буфера обмена для бóльшей совместимости с FF Выделить код Код:function readFromClip({clipboard} = Services, data = {}){ try {let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable), flavor = `text/${parseInt(Services.appinfo.platformVersion) >= 111 ? "plain" : "unicode"}`; trans.init(docShell.QueryInterface(Ci.nsILoadContext)); trans.addDataFlavor(flavor); clipboard.getData(trans, clipboard.kGlobalClipboard); trans.getTransferData(flavor, data); if (data.value) return data.value.QueryInterface(Ci.nsISupportsString).data; } catch {return ""} } |
Ultima2m > 19-05-2024 05:52:25 |
Dobrov пишет
У меня 3.7 не запускается на 115. Сейчас 3.1 работает. |
Dobrov > 19-05-2024 07:44:08 |
Ultima2m не используй старый скрипт, он более объёмный, содержит много ошибок и меньше возможностей. Пробуй папку Демо UCF-профиля - на FF 115.0.2 пашет без проблем (объём 407 Кб) |
Ultima2m > 19-05-2024 14:13:22 |
Dobrov пишет
Да, так рааботает. Но пришлось повозиться перекидывая свои скрипты. |
Dumby > 20-05-2024 08:51:51 |
Dobrov пишет
Да ты шутишь . Я слишком глуп, Однако, одну ошибку нашёл. Поскольку никакая Node в коде нигде не определена, Ну, и compat-проблемы из последних. Но продолжают торчать BrowserFullScreen(), BrowserPageInfo(), Плюс, я говорил, что в 127, |
unter_officer > 20-05-2024 13:04:54 |
Dumby |
Dobrov > 20-05-2024 14:50:23 |
Dumby – спасибо! правлю код и вижу странности на чистом пустом профиле без UCF: Выделить код Код:// ...arguments почему-то работает только с function. Так не пашет: var BrowserEx = () => { function BrowserEx(){ let args = [...arguments], b = args.shift(); eval(`${parseInt(Services.appinfo.version) < 126 ? "Browser"+ b[0].toUpperCase() + b.slice(1) : "BrowserCommands."+ b}(...args)`); } |
Dumby > 20-05-2024 15:36:34 |
unter_officer пишет
Ну, navigator.clipboard — это попробовать, пощупать, попривыкнуть к веб-технологиям. скрытый текст Выделить код Код:/* async find(e, findPrevious) { var win = e.view.windowRoot.ownerGlobal; var searchString = (await win.navigator.clipboard.readText())?.slice(0, 150); */ find(e, findPrevious) { var win = e.view.windowRoot.ownerGlobal; var searchString = win.readFromClipboard()?.slice(0, 150); Dobrov пишет
Что значит откуда?
У стрелочной функции нет своего arguments, и нет своего this. скрытый текст Выделить код Код:(() => console.log(arguments))("test"); // Array [ "about:home" ] (function() { (() => console.log(arguments))("test"); // Arguments { 0: "my argument", … } })("my argument"); |
unter_officer > 20-05-2024 16:27:13 |
Dumby пишет
Dumby, большое спасибо. |
Vitaliy V. > 20-05-2024 17:07:39 |
Обновил UCF, изменения касаются custom_script_win.js custom_script_all_win.js теперь это просто по умолчанию пустые файлы добавленные или нет в CustomStylesScripts.mjs, Также специально для Dobrov добавленны новые параметры для стилей и скриптов см. тут https://github.com/VitaliyVstyle/Vitali … cripts.mjs |
unter_officer > 21-05-2024 00:36:54 |
Vitaliy V. Выделить код Код:scriptsbackground: [ // В фоне [System Principal] { func: 'ChromeUtils.importESModule("chrome://user_chrome_files/content/custom_scripts/ReloadUserChromeContentCss.mjs")', }, В консоли пишет: ospath is undefined Если в файле user_chrome.js, вот в этом месте: Выделить код Код:try { if (path) loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${path}`, scope, "UTF-8"); else if ((!isos || isos.includes(OS)) && (!ver || (!ver.min || ver.min <= VER) && (!ver.max || ver.max >= VER))) loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${ospath.replace(/%OS%/g, OS)}`, scope, "UTF-8"); if (func) new scope.Function(func).apply(scope); } catch (e) {Cu.reportError(e);} переместить if (func) выше: Выделить код Код:try { if (func) new scope.Function(func).apply(scope); if (path) loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${path}`, scope, "UTF-8"); else if ((!isos || isos.includes(OS)) && (!ver || (!ver.min || ver.min <= VER) && (!ver.max || ver.max >= VER))) loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${ospath.replace(/%OS%/g, OS)}`, scope, "UTF-8"); } catch (e) {Cu.reportError(e);} то все кнопки начинают работать нормально, но в консоли всё равно присутствует: ospath is undefined |
Vitaliy V. > 21-05-2024 01:17:57 |
- |
_zt > 21-05-2024 01:32:03 |
Vitaliy V. |
Vitaliy V. > 21-05-2024 01:37:43 |
_zt пишет
Да просто не дофиксил , теперь должно работать |
unter_officer > 21-05-2024 01:46:59 |
Vitaliy V. Ещё вопросик. Я так понимаю, что новую версию UCF нет смысла пытаться установить на 115 ESR? |
_zt > 21-05-2024 01:47:31 |
Vitaliy V. |
Vitaliy V. > 21-05-2024 01:54:48 |
_zt пишет
Что за лоадер? Нужен код для проверки... |
unter_officer > 21-05-2024 01:56:13 |
_zt Выделить код Код:scriptsbackground: [ // В фоне [System Principal] { func: 'ChromeUtils.importESModule("chrome://user_chrome_files/content/custom_scripts/ReloadUserChromeContentCss.mjs")', }, |
_zt > 21-05-2024 02:01:52 |
Vitaliy V. |
unter_officer > 21-05-2024 02:02:23 |
Vitaliy V. пишет
Так в новой версии UCF нет vertical_top_bottom_bar.css, который присутствует в патче. Или это неважно? |
_zt > 21-05-2024 02:05:55 |
unter_officer |
Vitaliy V. > 21-05-2024 02:10:52 |
_zt |
_zt > 21-05-2024 02:16:37 |
Vitaliy V. |
Vitaliy V. > 21-05-2024 02:25:17 |
_zt |
_zt > 21-05-2024 02:29:43 |
Vitaliy V. |
Vitaliy V. > 21-05-2024 02:38:51 |
_zt |
_zt > 21-05-2024 02:39:34 |
Vitaliy V. |
unter_officer > 21-05-2024 02:48:14 |
Vitaliy V. пишет
Vitaliy V., спасибо. Обновился на 115 ESR, на первый взгляд всё работает нормально. |
Vitaliy V. > 21-05-2024 03:12:34 |
_zt пишет
Значит придется сделать как было, иначе пишет global null на раннем этапе загрузки обновил два файла user_chrome.js user_chrome_tb.js |
_zt > 21-05-2024 03:32:02 |
Vitaliy V. скрытый текст Вы когда то на win7 рамку окна скрыть смогли, может и здесь получится? |
unter_officer > 21-05-2024 11:34:50 |
Dumby, поправьте пожалуйста кнопочку под 126. скрытый текст Выделить код Код:// (async func => CustomizableUI.createWidget({ id: "ucf_SaveAsPNG", label: "Сохранить как PNG", tooltiptext: "Сохранить как PNG", localized: false, // defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { var win = btn.ownerGlobal; new win.Function("_id, xhtmlns, addDestructor", func.toString().slice(7, -1)).call( btn, this.id, "http://www.w3.org/1999/xhtml", destructor => win.addEventListener("unload", destructor, {once: true}) ); btn.setAttribute("image", "data:image/png;base64,....."); } }))(() => { ((main, parts) => this._handleClick = () => { var df = MozXULElement.parseXULToFragment(` <menupopup> <menuitem class="menuitem-iconic" image="data:image/png;base64,....." label="Сохранить всю страницу как PNG" value="all"/> <menuitem class="menuitem-iconic" image="data:image/png;base64,....." label="Сохранить видимую часть страницы как PNG" value="page"/> <menuitem class="menuitem-iconic" image="data:image/png;base64,....." label="Сохранить выбранный элемент страницы как PNG" value="click"/> <menuitem class="menuitem-iconic" image="data:image/png;base64,....." label="Сохранить выбранную область страницы как PNG" value="clipping"/> </menupopup> `); var popup = df.firstChild; popup.setAttribute("context", ""); popup.setAttribute("oncommand", "handleCommand(event);"); popup.handleCommand = e => { var name = _id + ":DataURLReady"; main = main.replace("%MESSAGE_NAME%", name); var urls = {}, configurable = true, enumerable = true; Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, { configurable, enumerable, get() { var value = `data:;charset=utf-8,({${ encodeURIComponent(main + part) }%0A}).init("${key}")`; Object.defineProperty(urls, key, {configurable, enumerable, value}); return value; }})); // Получить название вкладки без не сохраняемых символов и лишних пробелов ..... var getTabLabel = () => { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); } var listener = msg => { var fp = makeFilePicker(); fp.init(window, "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); var fileName = getTabLabel(); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '').replace(/\s+/g, '_').slice(0, 100).replace(/^\s+|\s+$/g, ''); var fileDate = (function () { var d = new Date(), z = function(n){return (n < 10 ? '0' : '') + n}; return '[' + z(d.getFullYear()) + '_' + z(d.getMonth()+1) + '_' + z(d.getDate()) + '\u00F7' + z(d.getHours()) + '_' + z(d.getMinutes()) + '_' + z(d.getSeconds()) + ']'; })(); fp.defaultString = fileName + "_" + fileDate + ".png"; fp.open(res => res == fp.returnCancel || !fp.file || makeWebBrowserPersist().saveURI( Services.io.newURI(msg.data), document.nodePrincipal, null, null, null, null, null, fp.file, null, null )); } messageManager.addMessageListener(name, listener); addDestructor(() => messageManager.removeMessageListener(name, listener)); (popup.handleCommand = e => gBrowser.selectedBrowser.messageManager .loadFrameScript(urls[e.target.value], false) )(e); } this.append(df); (this._handleClick = () => popup.openPopup(this, "after_start"))(); })(` init(cmd) { cmd.startsWith("c") ? this[cmd].init(this[cmd].parent = this) : this[cmd](); }, capture(win, x, y, width, height) { var canvas = win.document.createElementNS("${xhtmlns}", "canvas"); canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); var tryDraw = ind => { try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")} catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);} } tryDraw(17); sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png")); }, `, { all: `all() { var win = content; this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY); }`, page: `page() { var win = content, doc = win.document, body = doc.body, html = doc.documentElement; var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft; var scrY = (body.scrollTop || html.scrollTop) - html.clientTop; this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight); }`, clipping: `clipping: { handleEvent(e) { if (e.button) return false; e.preventDefault(); e.stopPropagation(); switch(e.type) { case "mousedown": this.downX = e.pageX; this.downY = e.pageY; this.bs.left = this.downX + "px"; this.bs.top = this.downY + "px"; this.body.appendChild(this.box); this.flag = true; break; case "mousemove": if (!this.flag) return; this.moveX = e.pageX; this.moveY = e.pageY; if (this.downX > this.moveX) this.bs.left = this.moveX + "px"; if (this.downY > this.moveY) this.bs.top = this.moveY + "px"; this.bs.width = Math.abs(this.moveX - this.downX) + "px"; this.bs.height = Math.abs(this.moveY - this.downY) + "px"; break; case "mouseup": this.uninit(); break; } }, init() { var win = {}; Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, win); this.win = win.value; this.doc = this.win.document; this.body = this.doc.body; if (!HTMLBodyElement.isInstance(this.body)) { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService) .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!"); return false; } this.flag = null; this.box = this.doc.createElement("div"); this.bs = this.box.style; this.bs.border = "red dashed 1px"; this.bs.position = "absolute"; this.bs.zIndex = "2147483647"; this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor; this.body.style.cursor = "crosshair"; ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)]; this.body.style.cursor = this.defaultCursor; this.body.removeChild(this.box); this.parent.capture.apply(this, pos); ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }`, click: `click: { getPosition() { var html = this.doc.documentElement; var body = this.doc.body; var rect = this.target.getBoundingClientRect(); return [ this.win, Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft, Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop, parseInt(rect.width), parseInt(rect.height) ]; }, highlight() { this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false; this.target.style.cssText += "outline: red 1px solid; outline-offset: 1px; -moz-outline-radius: 2px;"; }, lowlight() { if (this.orgStyle) this.target.style.cssText = this.orgStyle; else this.target.removeAttribute("style"); }, handleEvent(e) { switch(e.type){ case "click": if (e.button) return; e.preventDefault(); e.stopPropagation(); this.lowlight(); this.parent.capture.apply(this, this.getPosition()); this.uninit(); break; case "mouseover": if (this.target) this.lowlight(); this.target = e.target; this.highlight(); break; } }, init() { this.win = content; this.doc = content.document; ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { this.target = false; ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }` }); }); |
Farby > 21-05-2024 12:35:31 |
unter_officer пишет
код на замену: nsIFilePicker.init Выделить код Код:// fp.init(window, "Сохранить как…", fp.modeSave); fp.init( !("inIsolatedMozBrowser" in window.browsingContext.originAttributes) ? window.browsingContext : window , "Сохранить как…", fp.modeSave); |
unter_officer > 21-05-2024 12:51:01 |
Farby, большое спасибо. |
xrun1 > 21-05-2024 14:35:12 |
Farby |
Farby > 21-05-2024 14:55:39 |
xrun1 |
_zt > 21-05-2024 15:03:52 |
Dumby |
Dobrov > 21-05-2024 16:24:26 |
Vitaliy V. потестил новый UCF, есть пожелания: 1) неудобно, что в path: "…" не грузятся скрипты JSM и MJS – пока гружу так: 2) зачем лишний ospath ? Проще заменять %OS% сразу в path: "custom_styles_all_user_%OS%.css" |
Dumby > 21-05-2024 17:11:50 |
Vitaliy V. пишет
Наконец-то в методах {_}load{All}ChromeScripts() "UTF-8" так и кочует из версии в версию. И, немного напрягает использование там new win.Function() setTimeout( В предыдущей версии UCF — логируется объект ucf_custom_script_all_win Да, я понимаю, пример высосан из пальца. И потыкать по кнопкам на <html:sidebar-main> Призрачно маячит и совсем серьёзная угроза. То есть, как я понимаю, есть планы подсадить CSP-гадости и в окна браузера. |
Vitaliy V. > 21-05-2024 18:39:37 |
_zt пишет
Это врядли, это же системная рамка, панель вкладок или что либо от её не перекроет, но убрать всю рамку вероятно можно, но пока не пробовал, и у меня нет 10 только 11, не знаю есть разница или нет. Кстати напомните если сохранился код как я на win7 рамку окна скрывал, там вроде была замена системной рамки на рамку от ? Dumby пишет
Согласен мне это тоже не нравится, но пока не нашел способа. А есть ли он кроме использования файла с loadSubScript? Dumby пишет
Ясно же что я совершенно не слежу за этими багами, я не настолько погружен в |
_zt > 21-05-2024 19:24:30 |
Vitaliy V. |
Dumby > 21-05-2024 20:10:51 |
Vitaliy V. пишет
Ну, loadSubScript() ведь грузит data: адреса. ChromeUtils.compileScript() вроде тоже компилит с data: адресов.
Ну, если уж не жалко создавать для окон сандбоксы, Я вот так пробовал. Это не в смысле правки, а просто вспоминал как это делается. скрытый текст Выделить код Код:/* new win.Function(` */ UcfPrefs.dbg.makeGlobalObjectReference(win).executeInGlobal(` window.ucf_custom_script_all_win = { //....... }; `); /* `).apply(win); */ |
Dobrov > 22-05-2024 00:35:35 |
Vitaliy V. пишет
Добавь пожалуйста! MJS скрипты нужны, здесь уже несколько таких есть. |
_zt > 22-05-2024 20:57:45 |
Появилась тестовая с вертикальными вкладками. Скачать можно здесь Directory Listing: /pub/firefox/nightly/latest-larch/ |
Vitaliy V. > 23-05-2024 16:49:15 |
Dumby пишет
Да но вроде это не рекомендуемый способ, впрочем сделал так для параметра func, Dobrov пишет
Добавил проверь, только для фоновых скриптов, для оконных то скриптов вроде не требуется. |
Vitaliy V. > 23-05-2024 19:10:24 |
_zt пишет
Да вот скриптик для scriptschrome.domload чтобы скрыть совсем, у меня на 11 даже углы закругленные убрались скрытый текст Выделить код Код:(async () => { if (AppConstants.platform !== "win") return; var margin = "0,0,0,0"; if (TabsInTitlebar.enabled) document.documentElement.setAttribute("chromemargin", margin); TabsInTitlebar._update = eval(`(${`${TabsInTitlebar._update}`.replace(/^(async\s)?.*?\(/, `$1function ${TabsInTitlebar._update.name}(`) .replace(/\.setAttribute\("chromemargin",\s*"0,2,2,2"\)\;/g, `.setAttribute("chromemargin", "${margin}");`)})`); })(); |
Алексей У. > 23-05-2024 19:22:42 |
Почему при внесении любых изменений в user_chrome.manifest браузер перестает "видеть" UserChromeFiles, как будто его нет вообще? Windows 7, Firefox 88.0.1, UserChromeFiles отсюда. |
_zt > 23-05-2024 21:06:53 |
Алексей У. |
Dobrov > 24-05-2024 01:00:46 |
Vitaliy V. пишет
Спасибо! MJS работают, но как подключить mjs скрипт, который должен запускать функцию ? Выделить код Код:export {registerUCFTitleChanged, UCFTitleChangedChild}; // Замены в именах вкладок var reg = /^Скачать |-\sПоиск\sв\sGoogle$| \| Форум Mozilla Россия$/; function registerUCFTitleChanged() { var esModuleURI = Components.stack.filename; ChromeUtils.registerWindowActor("UCFTitleChanged", { child: { esModuleURI, events: { DOMTitleChanged: { capture: true }}, }, matches: ["https://*"], messageManagerGroups: ["browsers"], }); } class UCFTitleChangedChild extends JSWindowActorChild { handleEvent(e) { if (reg.test(this.document.title)) this.document.title = this.document.title.replace(reg, ""); } } |
Dumby > 24-05-2024 08:45:22 |
Vitaliy V. пишет
Ну, я не прям уж такой мёртвой хваткой вцепившись в багзиллу. Так что, более чем запросто, могу что-то пропустить, проворонить. Кстати, было бы неплохо, если бы был какой-то репортинг А если нет, то можно убрать «e». |
Vitaliy V. > 24-05-2024 16:29:13 |
Dobrov пишет
Ну смотря откуда хочешь запускать, можешь так записать Dumby пишет
Done! |
Алексей У. > 24-05-2024 18:25:36 |
_zt пишет
Если не трудно, можно подробнее по каждому из пунктов. |
_zt > 24-05-2024 20:47:36 |
Алексей У. |
Алексей У. > 24-05-2024 21:00:43 |
_zt пишет
По пунктам 2-4 все в порядке. Что касается пункта 1, то обнаружил, что стандартный Блокнот предлагает при сохранении следующие варианты кодировки: ANSI, UTF-8, Юникод, Юникод Big Endian. Какую из них выбрать? |
_zt > 24-05-2024 21:12:40 |
Алексей У. |
Dobrov > 25-05-2024 08:56:40 |
Доработал ucf_hookClicks.js и исправил неоткрытие менюшек в многооконом режиме. |
Dumby > 25-05-2024 09:59:48 |
Vitaliy V. пишет
Похоже, здесь не всё так просто. Рестарт, Ctrl+N, Alt+F4 — и получаю в консоли две записи Немного странно что две, но вполне приемлимо. Но, рассмотрим такой код: скрытый текст Выделить код Код:((key, ucf) => { ucf[key] = { destructor() { bbbla(); } }; ucf.unloadlisteners.push(key); })("bbbla", ucf_custom_script_win); Те же действия, но получаю уже две одинаковые записи «bbbla is not defined». То есть, тут получается, что кривой деструктор вызывается дважды. egorsemenov06 пишет
Попробовал посмотреть на 128. Жму ПКМ — в консоли куча всяких |
Vitaliy V. > 25-05-2024 13:24:02 |
Dumby пишет
А чего такого нехорошего, ну вызвало два раза на что это повлияет, на скорость закрытия окна, вряд ли. egorsemenov06 пишет
А это похоже моя ошибка, но кроме мусора ни на что не влияет, можно добавить пока не обновил UCF |
Dobrov > 25-05-2024 14:34:34 |
Vitaliy V. пишет
Ещё SaveHTML.mjs при сохранении страницы about:newtab эту же ошибку выводит в консоль. |
Dumby > 25-05-2024 14:53:46 |
Vitaliy V. пишет
Ну, например, код, который идёт до строки с ошибкой,
Как зачем? В тестовых целях, посмотреть что случится.
Может проверять как-то так, даже не знаю скрытый текст Выделить код Код:/* try { val.func.apply(val.context); } catch (e) { try { this.ucfo[key].destructor(); } catch (e) {Cu.reportError(e);} Cu.reportError(e); } */ if (val.func) try {val.func.apply(val.context);} catch(ex) {Cu.reportError(ex);} else if (this.ucfo[key]?.destructor) try {this.ucfo[key].destructor();} catch(ex) {Cu.reportError(ex);} else Cu.reportError("Missing destructor for key " + key); |
Vitaliy V. > 25-05-2024 16:18:01 |
Dobrov пишет
Да, если включены стили, скрипты для контента, как убрать ошибку в посте выше. Dumby пишет
Или так, сообщение об ошибке, побуждает её исправить, ну и заменить на setUnloadMap скрытый текст Выделить код Код:try { val.func.apply(val.context); } catch (e) { if (!val.func) try { this.ucfo[key].destructor(); } catch (e) {Cu.reportError(e);} Cu.reportError(e); } кстати не вижу толку от getUnloadMap наверное заменю или добавлю UPD: обновил на getDelUnloadMap(key, del) del удаляет если true |
Алексей У. > 25-05-2024 18:15:31 |
Подскажите, пожалуйста, нет ли скрипта (или любого другого способа) вернуть системный вид скроллбаров на ВСЕХ сайтах? скрытый текст скрытый текст |
xrun1 > 25-05-2024 20:08:43 |
Алексей У. |
Алексей У. > 25-05-2024 21:15:03 |
xrun1 пишет
Это нужно в custom_script_win.js добавить? |
Dobrov > 26-05-2024 06:09:31 |
Добавляю текст буфера обмена к подсказке url в строке адреса, но получается изменить только tooltip рамки. Там «aHTMLTooltip» и на http без шифрования подсказки адреса нет. скрипт для окна, событие mouseenter на urlbar-input-box Выделить код Код:(async id => { // добавить текст буфера обмена к подсказке url в строке адреса var listener = { // изменить aHTMLTooltip handleEvent(e){ let trg = e.target, clip = readFromClip(); // let box = document.getElementById("urlbar-input-container").childNodes[6]; //"urlbar-input-box" trg.tooltipText = gBrowser.currentURI.spec + "\n\nбуфер обмена (текст)\n" + crop(clip, 88 ,'…\n', 1); console.log(trg.tooltipText); }, } var events = ["mouseenter"], els = document.getElementById("urlbar-input"); els.addEventListener(events,listener,true); ucf_custom_script_win.unloadlisteners.push(id); ucf_custom_script_win[id] = { destructor(){ el.removeEventListener(events,listener,true); } } var addDestructor = nextDestructor => { var {destructor} = ucf_custom_script_win[id]; ucf_custom_script_win[id].destructor =()=> { try {destructor();} catch(ex){Cu.reportError(ex)} nextDestructor(); } } var readFromClip = ({clipboard} = Services, data = {}) => { try {let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable), flavor = `text/${parseInt(Services.appinfo.platformVersion) >= 111 ? "plain" : "unicode"}`; trans.init(docShell.QueryInterface(Ci.nsILoadContext)); trans.addDataFlavor(flavor); clipboard.getData(trans, clipboard.kGlobalClipboard); trans.getTransferData(flavor, data); if (data.value) return data.value.QueryInterface(Ci.nsISupportsString).data; } catch {return ""} }, crop = (z = "",cut = 30,ch = '…\n',g = 0) => { //обрезать/разбить текст z = z.match(new RegExp('.{1,'+ cut +'}','g')); cut = z.slice(-1); return g ? z.join(ch) : z[0] == cut ? z[0] : z[0] + ch +'…'+ cut; } })("ucf_clipboard_in_url"); |
xrun1 > 26-05-2024 09:14:50 |
Алексей У. пишет
Да, попробуйте. |
Dumby > 26-05-2024 11:23:22 |
Dobrov пишет
Вот уж нет! Кстати, к вопросу о кривых деструкторах. |
Алексей У. > 26-05-2024 12:50:31 |
xrun1 пишет
Добавил - ничего не изменилось. |
Dobrov > 26-05-2024 15:39:25 |
Dumby пишет
Но ведь удобно, когда подсказка в строке адреса покажет ещё фрагмент буфера обмена. |
xrun1 > 26-05-2024 16:49:26 |
Алексей У. |
Ultima2m > 26-05-2024 16:49:48 |
В скрипте есть ссылка на иконку "..." (я думаю) |
xrun1 > 26-05-2024 17:17:23 |
Ultima2m |
Dumby > 26-05-2024 18:48:03 |
Dobrov пишет
При чём здесь «удобно»? «Вот уж нет!» — относится к слову «правильно». Я заменил trg.tooltipText на trg.title — у меня тултип появился, Vitaliy V. скрытый текст Выделить код Код:// return this._preload = (async () => { try { let path = this.path || (((!this.isos || this.isos.includes(lazy.OS)) && (!this.ver || (!this.ver.min || this.ver.min <= lazy.VER) && (!this.ver.max || this.ver.max >= lazy.VER))) ? this.ospath.replace(/%OS%/g, lazy.OS) : undefined); if (!path) { obj.sheet = () => {}; return this._preload = await (async () => null)(); } return this._preload = await lazy.UcfSSS.preloadSheetAsync( Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${path}`), this.type ); } catch { obj.sheet = () => {}; return this._preload = await (async () => null)(); } })(); Для чего используется конструкция await (async () => null)(); Почему не просто сразу null; Вопрос не риторический, может на это есть причина, И, как тебе идея чуть упростить код. То есть, if (!path) throw 0; или if (path) return …; else throw 0; Кстати, в UcfStylesScriptsChild, для stylescontent написано: Но, по факту, это не так. Стиль добавляется, даже если type не указан. |
Ultima2m > 26-05-2024 19:38:56 |
xrun1 пишет
Спасибо. |
Vitaliy V. > 26-05-2024 20:49:31 |
Dumby пишет
Потому что видимо переменная сначала становится null, а потом обещанием скрытый текст Выделить код Код:var Test = (async () => { return Test = await (async () => null)(); })(); setTimeout(() => console.log("Test", Test), 100); скрытый текст Выделить код Код:var Test = (async () => { return Test = null; })(); setTimeout(() => console.log("Test", Test), 100); скрытый текст Выделить код Код:var Test = (async () => { Test = null; console.log("Test 1", Test); })(); setTimeout(() => console.log("Test 2", Test), 100); Dumby пишет
Да можно конечно, правда упрощать там особо нечего, две строчки Dumby пишет
Тогда можно сделать, если не указанно то чтобы был USER_SHEET |
Dumby > 26-05-2024 22:37:21 |
Vitaliy V. пишет
Ооо, круто! Просто вынос мозга. Спасибо. И, вообще жесть — вот так получается null скрытый текст Выделить код Код:var Test = (async () => { return Test = await null; })(); setTimeout(() => console.log("Test", Test), 100); |
Dobrov > 27-05-2024 02:26:33 |
Dumby пишет
Да, спасибо! Пока код в работе, на гитхабе скрипты часто обновляю и новые фишки скоро будут. Как получить число зарегистрированных Worker'ов и включенных расширений? Иногда нужно видеть важную информацию о состоянии , скрытую в опциях или вообще недоступную. |
Vitaliy V. > 27-05-2024 19:08:10 |
Dumby пишет
Да точно, можно и так, я привык писать await перед асинхронными функциями Dobrov скрытый текст * @param {String} tooltip: (optional) * Подсказка для пункта меню * @param {String} args: (optional) * `Аргументы через пробел "то что в двойных кавычках считается за один аргумент"`, * Собственные аргументы: * %ProfD% - путь до профиля * %FilePicker% - выбор папки, например для скачивания * %Prompt(message)% - вызвать диалоговое окно для изменения текста, например названия медиа файла * @param {String} rcargs: (optional) * Тоже что и args но выполняется по правому клику * @param {Boolean} clipboard: (optional) * Адрес из буфера обмена и разные изменения... |
Dumby > 28-05-2024 08:37:04 |
Dobrov пишет
Нашёл кого спросить. У меня-то откуда Worker'ы возьмутся? Чисто теоретически, получаем nsIWorkerDebuggerManager И nsISimpleEnumerator Worker'ов nsISimpleEnumerator уже довольно давно вещь итерируемая, Перечисляться будут экземпляры nsIWorkerDebugger То есть, TYPE_DEDICATED, TYPE_SHARED, или TYPE_SERVICE
Мало ли что там перечислено. Например, торчит включённая тема, а это не расширение, а... тема. Вобщем, например, можно перечислить добро в XPIDatabase.addonDB |
Dobrov > 28-05-2024 17:38:03 |
Dumby - у меня всего 1 Worker получился вместо полсотни:
Vitaliy V.
|
aivazkin > 28-05-2024 20:50:24 |
Впервые решил попробовать UserChromeFiles от Vitaliy V. |
Dumby > 28-05-2024 21:51:22 |
Dobrov пишет
Ааа, точно, остальные же в других процессах. Наверно, посмотреть в консоли можно так скрытый текст Выделить код Код:Services.ppmm.loadProcessScript("data:," + encodeURIComponent(` var wdm = Cc["@mozilla.org/dom/workers/workerdebuggermanager;1"].getService(Ci.nsIWorkerDebuggerManager); for (var worker of wdm.getWorkerDebuggerEnumerator()) console.log(worker); `), false); Нужно, чтобы «Режим консоли браузера» был «Мультипроцессный», и «Выберите контекст оценки» — «Первичная». Теперь прикинь, как это оттуда выковыривать. И, это всё глобальные вещи, не оконные. |
Farby > 28-05-2024 22:16:01 |
aivazkin UserChromeFiles_Settings
Попробуйте заменить стили для 115 fix https://github.com/VitaliyVstyle/Vitali … 15_ESR.zip Ну или на худой случай искать что у вас мешает отображению всяких разных фишек Предполагаю и вас не голый ??!! Может какие ошибки в консоле есть?? |
Vitaliy V. > 28-05-2024 22:41:00 |
Dobrov пишет
Странно в прошлой версии сам же удалил аргумент а теперь он понадобился. Что то длинная проверка, попробуй так скрытый текст Выделить код Код:let URL = !clipboard === !(e.shiftKey || e.button === 1) ? (gContextMenu?.linkURI?.displaySpec || this.getCurrentURL()) : this.readFromClipboard(); Farby пишет
Факт, новый UCF поддерживает 115+ (с заменой стилей) 117+ (без замены) |
aivazkin > 29-05-2024 09:22:51 |
Farby |
Dobrov > 30-05-2024 00:58:41 |
Vitaliy V. пишет
Vitaliy V. - А зачем так усложнять с фиксом UCF для Fix_115_ESR ? Ещё вопрос: в чём преимущество нового UCF 2024 в сравнении со старым ? добавить в config.js, user_chrome.js, prefs.js: var Services = globalThis.Services || ChromeUtils.import("resource://gre/modules/Services.jsm").Services; |
unter_officer > 30-05-2024 10:23:41 |
Dobrov пишет
А я хочу попросить продолжить поддержку UCF для 115 ESR и после прекращения поддержки Mozilla. |
Vitaliy V. > 30-05-2024 14:34:41 |
Dobrov пишет
Наверно ты не допонял, в плане результата, они вообще не отличаются. Dobrov пишет
В том что он совместим с новыми версиями это же очевидно. UCF 78+ работу стилей/скриптов может и обеспечивает (пока), но вот с панелями там есть изменения. Dobrov пишет
Если ты предлагаешь добавить это в новый UCF для совместимости с 78, то этого не достаточно, там нет поддержки ESM, Fluent ... |
Dobrov > 04-06-2024 03:48:46 |
Код занятой браузером памяти показал ~700Mb, но одна вкладка about:processes выдаёт для Firefox 345Мб, Расширения 230Мб . Выделить код Код:(async ()=> { function formatBytes(b = 0,d = 1){ //объём байт…Тб let i = Math.log2(b)/10|0; return parseFloat((b/1024**(i=i<=0?0:i)).toFixed(d))+`${i>0?'KMGT'[i-1]:''}b`; } var info = await ChromeUtils.requestProcInfo(), bytes = info.memory; for(var child of info.children) bytes += child.memory; console.log(formatBytes(bytes)); })(); |
Dumby > 04-06-2024 22:07:02 |
Dobrov пишет
Это вот «memory», вместо residentSetSize и residentUniqueSize, Но мне никогда и не казалось, что это может быть Интерес представляет лишь относительная разница между процессами, |
Dobrov > 05-06-2024 00:37:35 |
Dumby пишет
Может возврат на старый код красные строки Bug 1665318 даст более правдоподобный результат, но не хочу усложнять. |
gg.user > 06-06-2024 13:11:21 |
Здравствуйте, добавил панель Sidebar tabs https://forum.mozilla-russia.org/viewtopic.php?pid=784824#p784824 не как не могу понять как правильно добавить кнопку для панели - скрывать/показывать кнопку добавляю в custom_script_win.js (как в инструкции в custom_script.js не работает) - кнопка появляется - но не работает - нажатие на нее нечего не дает подскажите - как правильно кнопку добавить чтоб работала? |
xrun1 > 06-06-2024 15:17:00 |
gg.user |
gg.user > 06-06-2024 16:02:48 |
xrun1 пишет
пойдет) работает!) так тоже сойдет - спасибо!! |
Dobrov > 07-06-2024 00:53:08 |
Вопрос: как открыть сайт в Sidebar из скрипта ? Выделить код Код:// в scriptschrome: и scriptsbackground: не работает. через DOM Inspector глянуть не могу, он опять «вылетает» browser.sidebarAction.setPanel({ panel: 'about:blank' }); browser.sidebarAction.setPanel({ panel: 'https://meteo7.ru' }); |
Vitaliy V. > 08-06-2024 00:50:16 |
gg.user пишет
Кроме кнопки есть настраиваемые Сочетания клавиш, по умолчанию это Ctrl + Alt + B gg.user пишет
Dobrov пишет
Тестируйте, подключать в scriptschrome.domload , кнопка уже встроена в данный скрипт |
Dobrov > 08-06-2024 03:24:20 |
Vitaliy V. превосходно! Хорошая замена для Open in Sidebar и Tile Tabs ! Вопрос: как из другого кода открыть сайт в твоей Sidebar ? |
Vitaliy V. > 08-06-2024 12:56:54 |
Dobrov пишет
У меня не было такого на , не знаю может на и так, обновил проверь помогло или нет. Dobrov пишет
Нужно знать индекс вкладки в которой открывать, например так Выделить код Код:ucf_custom_script_win.ucf_sidebar_tabs.setPanel(4, "https://forum.mozilla-russia.org"); или индекс можно поискать в menus если есть один или более пункта меню |
Dumby > 08-06-2024 13:55:46 |
Vitaliy V. пишет
Разве метод setUnloadMap() не разработан, чтобы писать так:
Что-то у меня наблюдается какой-то слегка неожиданный outline Воспроизводится при запуске браузера с ранее открытым Sidebar Tabs. скрытый текст Выделить код Код:data:image/png;base64,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 Кстати, может скрывать пункт «Открыть ссылку в Sidebar Tabs», если активная вкладка открыта в контейнере. Просто, в таком случае, ссылка должна бы открыться в том же контейнере, Или, наоборот — чётко заявить в описании: |
_zt > 08-06-2024 21:51:57 |
Vitaliy V. Выделить код Код:#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 23:02:40 |
Vitaliy V. |
Dumby > 08-06-2024 23:19:03 |
_zt пишет
0vw dashed тоже работает . |
_zt > 08-06-2024 23:29:58 |
Dumby |
Dobrov > 09-06-2024 00:55:33 |
Vitaliy V. пишет
1) как вызвать ucf_custom_script_win.ucf_sidebar_tabs… из scriptsbackground: ? (из твоего скрипта ЮзерМеню) |
Vitaliy V. > 09-06-2024 11:55:25 |
egorsemenov06 Dumby пишет
Да но работает и так без контекста, а так да фунций внутри фунций лучше меньше Dumby пишет
Хорошо что напомнил про контейнеры, вроде как сделал чтобы открывалось в том же контейнере, посмотри можно ли сделать без browser.remove(); _zt пишет
// var st = window.ucf_custom_script_win?.sidebar_tabs || window.ucf_custom_script_all_win?.sidebar_tabs; Dobrov пишет
Ну как, добавляешь вначале объект window текущего окна Dobrov пишет
Так они и прижаты влево что в что в |
Dumby > 09-06-2024 15:12:06 |
Vitaliy V. пишет
В смысле без использования именно этого метода? А если в смысле вообще без удаления, то тогда, наверно, нет. скрытый текст Выделить код Код:/* 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); Тестовый кусок внутри этого кода показывает, что browser.destroy() вызывается дважды. Первый раз — при манипуляции с атрибутом "usercontextid". Проверяю, запуская с консоли Вроде, показывает то, что должно быть. А без пере-подвешивания браузера на DOM-дерево, атрибут-то есть, |
Dobrov > 09-06-2024 16:08:46 |
Vitaliy V. - спасибо! Все заработало в scriptsbackground: и заголовки вкладок не смещаются. Помогите сделать глобальную функцию для кода в receiveMessage() макет скрипта. Указал, где нужна общая функция Выделить код Код:/* 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 ………… } |
Vitaliy V. > 10-06-2024 11:57:10 |
Dumby пишет
Да это и имел ввиду про replaceWith что то и забыл, спасибо заменил. Dumby пишет
Да проверил ещё browser.construct() он не вызывается значит и destroy() не нужно принудительно вызывать, 10-06-2024 12:10:14 _zt пишет
Не совсем так, но теперь должно быть менее навязчивым. |
Dobrov > 10-06-2024 13:28:50 |
Vitaliy V. пишет
Я уже решил задачу другим способом. Хотел получить URL вкладки, учитывая ReaderMode и расширения. ещё в Sidebar Tabs не обозначено действие по клику колёсиком. Может так добавить: |
_zt > 10-06-2024 14:38:38 |
Vitaliy V. пишет
Уже лучше, но... щелкаешь по изображению >> "Открыть в SidebarTabs", ожидается открытие изображения, а открывается страница. |
Vitaliy V. > 10-06-2024 17:22:50 |
Dobrov пишет
Что такое текущий URL, фрейма? На текущей странице может быть много фреймов, _zt пишет
О нет, если так сделать то например на этой же странице не найти свободного места, везде изображения открываются. _zt пишет
Да это же настройки юзера запишите как надо. Там можно вообще удалять или добавлять нужные вкладки если не поняли. _zt пишет
В оригинальном сайдбаре не работает почему в моем должно, это ж api расширений нужно подключать, а вкладки где взять их нет для сайдбара |
_zt > 10-06-2024 19:54:44 |
Vitaliy V. пишет
А было бы прикольно, картинки там открывать. скрытый текст Выделить код Код:... 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; } }; Хотя нет, для .onImage этот код не работает. Браузер как то различает фоновые картинки и обычные. Для фона контекстные пункты изображений не показываются. |
Dumby > 10-06-2024 22:53:31 |
egorsemenov06 пишет
Попробуй так скрытый текст Выделить код Код:/* var openAddonsMgr = window.BrowserOpenAddonsMgr // Firefox */ var openAddonsMgr = window.BrowserOpenAddonsMgr || window.BrowserAddonUI.openAddonsMgr // Firefox |
xrun1 > 11-06-2024 05:57:43 |
Vitaliy V. |
Dobrov > 11-06-2024 12:37:54 |
xrun1 пишет
Получается наложение имён вкладок Sidebar Tabs (загловок у меня отключен). При этом ещё и закрыть новую вкладку мышью не получается. |
Dobrov > 12-06-2024 08:36:07 |
Как отследить, что сайт не переключился в ReaderMode и выполнить при этой ошибке свой код ? document.getElementById("key_toggleReaderMode", window).doCommand(); Надо учесть, что эта команда повторным вызовом закрывает режим чтения.Переделал демо-профиль в шапке, другое оформление плюс корпоративные настройки-закладки для новых профилей. Добавил "открыть сайт в Sidebar" в меню пользователя и клик колёсиком на щите (повторный вызов закроет Sidebar) и на жест мыши: тащить ссылку вниз. При сохранении из ReaderMode (правый клик на кнопке Загрузки) в конце страницы правильная ссылка на оригинал. |
Farby > 12-06-2024 15:36:12 |
Dumby здравствуйте. Dumby пишет
Поставил себе на посмотреть 128b1, ну всё таки ESR 128 будет , понял что new search configuration просто так не отключить. new search engine disabler Выделить код Код:. // Permanently enable the new search configuration until we remove the old code as part of bug 1870686. // lockPref("browser.search.newSearchConfig.enabled": false) no more work try {(async (su) => { let {ChromeUtils} = Cu.getGlobalForObject(Cu), impESM = ChromeUtils.importESModule, {SearchUtils} = impESM(su); SearchUtils.newSearchConfigEnabled = false; })("resource://gre/modules/SearchUtils.sys.mjs");} catch(ex) {Cu.reportError(ex);} |
Dumby > 13-06-2024 11:38:14 |
Farby пишет
Мудро.
Добавить-то нет, а прокомментировать код могу. Скармливать асинхронную обёртку блоку try {} бессмысленно, Ну, кроме синтаксической, но тогда уже ничто не поможет. И, let-батарея выглядит избыточно. скрытый текст Выделить код Код:(async su => ChromeUtils.importESModule(su).SearchUtils.newSearchConfigEnabled = false)( "resource://gre/modules/SearchUtils.sys.mjs" ); |
Farby > 13-06-2024 12:54:52 |
Dumby |
Vitaliy V. > 13-06-2024 15:23:24 |
Решил Sidebar Tabs в виде юзер скрипта добавить в UCF, обновляем его, раскомментируем https://github.com/VitaliyVstyle/Vitali … ts.mjs#L50 |
_zt > 13-06-2024 16:20:53 |
Vitaliy V.
обновите пожалуйста скрипт 24-04-2024 16:46:34 |
Vitaliy V. > 13-06-2024 20:40:47 |
_zt пишет
А добавить в _zt пишет
А как раньше было ? В самом Sidebar Tabs не было автоскрытия, а то что у вас стиль и/или скрипт был то там было просто показать/скрыть, наверное этот скрипт можно подправить чтобы работал так же. Обнаружил баг не баг, но если модуль CustomizableUI вызывается слишком рано при старте, то получаем проблемы при сбросе настроек панелей инструментов скрытый текст Выделить код Код:CustomizeMode: TypeError: can't access property "enable", gDefaultTheme is undefined _resetUIState resource:///modules/CustomizableUI.sys.mjs:3289 reset resource:///modules/CustomizableUI.sys.mjs:3248 reset resource:///modules/CustomizableUI.sys.mjs:4444 reset resource:///modules/CustomizeMode.sys.mjs:1234 Console.sys.mjs:506 Иправил в user_chrome.js на ленивую загрузку модуля https://github.com/VitaliyVstyle/Vitali … 93d9c6a709 PS: хотя это не ново, помница раньше вообще не загружались кнопки и т.д. |
_zt > 13-06-2024 21:47:03 |
Vitaliy V. пишет
Нет, не просто скрытый текст Выделить код Код:try {(() => { var label = "Sidebar Tabs", tooltiptext = "ЛКМ Sidebar Tabs\nShift+ЛКМ Toggle AutoHide", img = "data:image/svg+xml;base64...", pref = "extensions.ucf.sidebar_tabs.auto_hide"; var sidebar_tabs_button = { get style() { delete this.style; return this.style = "data:text/css;charset=utf-8," + encodeURIComponent(` #st_toolbox { --v-sidebar-min-width: 2px; --v-sidebar-min-width-normal: 10px; --v-sidebar-max-width: 20em; --v-sidebar-transition-delay-show: .3s; --v-sidebar-transition-delay-hide: .6s; --v-sidebar-transition-duration: .3s; /* ********************************************** */ position: relative !important; z-index: 1 !important; min-width: var(--v-sidebar-max-width) !important; width: var(--v-sidebar-max-width) !important; max-width: var(--v-sidebar-max-width) !important; overflow: hidden !important; opacity: 0 !important; --v-sidebar-margin-max-width: calc(-1 * var(--v-sidebar-max-width)); --v-sidebar-margin-left-locale-dir: 0; --v-sidebar-margin-right-locale-dir: var(--v-sidebar-margin-max-width); --v-sidebar-transform-locale-dir: -1; --v-sidebar-transform-locale-dir-visible: 1; margin-left: var(--v-sidebar-margin-left-locale-dir) !important; margin-right: var(--v-sidebar-margin-right-locale-dir) !important; transform: translateX(calc(var(--v-sidebar-transform-locale-dir) * (var(--v-sidebar-max-width) - var(--v-sidebar-min-width)))) !important; transition-timing-function: linear, step-start !important; transition-delay: var(--v-sidebar-transition-delay-hide), calc(var(--v-sidebar-transition-delay-hide) + var(--v-sidebar-transition-duration)) !important; transition-duration: var(--v-sidebar-transition-duration), 0s !important; transition-property: transform, opacity !important; border-inline-end: 1px solid var(--chrome-content-separator-color, rgba(127,127,127,.5)) !important; } *|*:root[sidebar_tabs_right="true"] #st_toolbox { border-inline-start: 1px solid var(--chrome-content-separator-color, rgba(127,127,127,.5)) !important; border-inline-end: none !important; } *|*:root[sidebar_tabs_right="true"] #st_toolbox, #st_toolbox:-moz-locale-dir(rtl) { --v-sidebar-margin-left-locale-dir: var(--v-sidebar-margin-max-width); --v-sidebar-margin-right-locale-dir: 0; --v-sidebar-transform-locale-dir: 1; --v-sidebar-transform-locale-dir-visible: -1; } *|*:root[sidebar_tabs_right="true"] #st_toolbox:-moz-locale-dir(rtl) { --v-sidebar-margin-left-locale-dir: 0; --v-sidebar-margin-right-locale-dir: var(--v-sidebar-margin-max-width); --v-sidebar-transform-locale-dir: -1; --v-sidebar-transform-locale-dir-visible: 1; } *|*:root[sizemode="normal"] #st_toolbox { --v-sidebar-min-width: var(--v-sidebar-min-width-normal) !important; } #st_toolbox:hover, #st_toolbox[sidebardrag] { transform: translateX(0px) !important; opacity: 1 !important; transition-delay: var(--v-sidebar-transition-delay-show) !important; } *|*:root[v_vertical_bar_visible][v_vertical_bar_start="true"][sidebar_tabs_right="false"] #st_toolbox, *|*:root[v_vertical_bar_visible][v_vertical_bar_start="false"][sidebar_tabs_right="true"] #st_toolbox { transform: translateX(calc(var(--v-sidebar-transform-locale-dir-visible) * var(--v-vertical_bar_width, 0px))) !important; opacity: 1 !important; transition-delay: 0s !important; } #browser > #st_splitter { display: none !important; } `); }, loadstyle(win) { try { win.windowUtils.loadSheetUsingURIString(this.style, win.windowUtils.USER_SHEET); } catch (e) {} }, removestyle(win) { try { win.windowUtils.removeSheetUsingURIString(this.style, win.windowUtils.USER_SHEET); } catch (e) {} }, }; CustomizableUI.createWidget({ id: "sidebar_tabs_button", label: label, tooltiptext: tooltiptext, defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onBeforeCreated(doc) { if (Services.prefs.getBoolPref(pref, true)) sidebar_tabs_button.loadstyle(doc.defaultView); }, onCreated: function(btn) { btn.style.setProperty("list-style-image", `url("${img}")`); }, onCommand: function(e) { if (!e.shiftKey) e.target.sidebar_tabs_toggle(); else { let prf = Services.prefs.getBoolPref(pref, true), loadremove = !prf ? "loadstyle" : "removestyle"; Services.prefs.setBoolPref(pref, !prf); for (let win of CustomizableUI.windows) sidebar_tabs_button[loadremove](win); } } }); })();} catch(e) {} Еще бы кнопочки добавить в историю и закладки "Свернуть все папки". Типа этих. Опять же для сокращения сущностей. "Развернуть все папки" не особо нужны, а вот "свернуть" полезные. Vitaliy V. пишет
Да вроде работает, по крайней мере куки и историю удаляет. |
Vitaliy V. > 13-06-2024 22:37:45 |
_zt пишет
Не просто это то что сейчас, раньше был просто стиль но это было не полноценное решение, сейчас можно изменять размер сайдбара, при перетаскивании или открытии ссылок сайдбар автоматически открывается ну и т.д. Но изменить режим работы на лету без перезагрузки довольно сложно так что пожалуй я не стану этого делать чтобы не усложнять. Но можете продолжать использовать этот стиль для обычного режима сайдбара, немного подправить только надо, если надо? _zt пишет
Ну тут видимо лучше отдельные скрипты использовать это другие документы chrome://browser/content/places/(bookmarksSidebar | historySidebar).xhtml |
_zt > 13-06-2024 23:06:35 |
Vitaliy V. Vitaliy V. пишет
Понятно. |
xrun1 > 14-06-2024 02:25:18 |
Как вызвать информацию о странице? win.BrowserPageInfo(); не работает. Vitaliy V. скрытый текст Выделить код Код:try { CustomizableUI.createWidget({ id: "add-decoder-app", type: "custom", label: "Декодеры", tooltiptext: [ "ЛКМ: Декодер Арт. Лебедева", "ПКМ: Универсальный декодер" ].join("\n"), localized: false, onBuild: function(document) { var trbn = document.createXULElement("toolbarbutton"); trbn.id = this.id; trbn.tooltipText = this.tooltiptext; trbn.label = this.label; trbn.setAttribute("context", false); trbn.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAD///8AraXnAKWl5wCEe94Ac3PeAHNr1gAhGMYAGBC9ABgIvQAICL0AEAC9AAgAvQAAALUAAAAAAAAAAAAAAAAAiYmJiYmJiYiYmJiYmJiYmYmJiYmJiYmIiZmZmZmZmZmZmZmJiYmJiYkBBjBQBQOGmQEHMFAFA5iJAQdAUAUDh5kBCDBQBQOYiQEIMFAFA4iZAQYwUAUDmImJiYmJiYmJmJiYmJiYmJiJiYmJiYmJiZiYmJiYmJiYiYmJiYmJiYkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="); trbn.addEventListener("click", function(event) { var win = event.target.ownerDocument.defaultView; win.SidebarController.hide(); if (event.button == 0) { win.gBrowser.selectedTab = win.gBrowser.addWebTab("https://www.artlebedev.ru/decoder/"); } if (event.button == 2) { win.gBrowser.selectedTab = win.gBrowser.addWebTab("https://2cyr.com/decode/"); } }, false); trbn.classList.add("toolbarbutton-1"); trbn.classList.add("chromeclass-toolbar-additional"); return trbn; } }); } catch(e) {} |
unter_officer > 14-06-2024 11:07:06 |
xrun1 пишет
Попробуйте так: win.BrowserCommands.pageInfo(); |
xrun1 > 14-06-2024 13:31:09 |
unter_officer |
Vitaliy V. > 14-06-2024 20:24:48 |
_zt пишет
В скрипте Sidebar Tabs должно быть AUTO_HIDE = false, если true то не сможете включить обычный режим. скрытый текст Выделить код Код:(async ( id = "ucf_sidebar_tabs_button", label = "Sidebar Tabs", tooltiptext = "ЛКМ: Открыть / Закрыть\nControl + ЛКМ: Отключить / Включить\nСКМ: Отключить / Включить\nПКМ: Переключить AutoHide", img = "resource://ucf_sidebar_tabs", pref = "extensions.ucf.sidebar_tabs.auto_hide", sidebar_tabs = { get style() { delete this.style; return this.style = `data:text/css;charset=utf-8,${encodeURIComponent(` #browser > #st_toolbox { --v-sidebar-min-width: 10px; --v-sidebar-transition-delay-show: .3s; --v-sidebar-transition-delay-hide: 2s; --v-sidebar-transition-duration: .2s; /* ********************************************** */ position: relative !important; z-index: calc(var(--browser-area-z-index-tabbox, 2) + 2) !important; min-width: var(--v-sidebar-tabs-width) !important; width: var(--v-sidebar-tabs-width) !important; max-width: var(--v-sidebar-tabs-width) !important; overflow: hidden !important; opacity: 0 !important; --v-sidebar-margin-max-width: calc(-1 * var(--v-sidebar-tabs-width)); --v-sidebar-transform-locale-dir: -1; --v-sidebar-transform-locale-dir-visible: 1; margin-inline-start: 0 !important; margin-inline-end: var(--v-sidebar-margin-max-width) !important; transform: translateX(calc(var(--v-sidebar-transform-locale-dir) * (var(--v-sidebar-tabs-width) - var(--v-sidebar-min-width)))) !important; &[sidebar_tabs_auto_hide] { transition-timing-function: linear, step-start, linear !important; transition-delay: var(--v-sidebar-transition-delay-hide), calc(var(--v-sidebar-transition-delay-hide) + var(--v-sidebar-transition-duration)), 0s !important; transition-duration: var(--v-sidebar-transition-duration), 0s, .2s !important; transition-property: transform, opacity, margin-top !important; } &[sidebar_tabs_auto_hide][sidebar_tabs_visible="hidden"] { transition-delay: 0s, var(--v-sidebar-transition-duration), 0s !important; } :root[sidebar_tabs_start="false"] & { margin-inline-start: var(--v-sidebar-margin-max-width) !important; margin-inline-end: 0 !important; } :root[sidebar_tabs_start="false"]:-moz-locale-dir(ltr) &, :root[sidebar_tabs_start="true"]:-moz-locale-dir(rtl) & { --v-sidebar-transform-locale-dir: 1; --v-sidebar-transform-locale-dir-visible: -1; } &[sidebar_tabs_auto_hide]:hover { transform: translateX(0px) !important; opacity: 1 !important; transition-delay: var(--v-sidebar-transition-delay-show), var(--v-sidebar-transition-delay-show), 0s !important; } &[sidebar_tabs_auto_hide][sidebar_tabs_visible^="visible"] { transform: translateX(0px) !important; opacity: 1 !important; transition-delay: 0s !important; } :root[v_vertical_bar_start="true"][sidebar_tabs_start="true"]:is([v_vertical_bar_visible="visible"],[v_vertical_bar_sidebar="true"]) &[sidebar_tabs_auto_hide], :root[v_vertical_bar_start="false"][sidebar_tabs_start="false"]:is([v_vertical_bar_visible="visible"],[v_vertical_bar_sidebar="true"]) &[sidebar_tabs_auto_hide] { transform: translateX(calc(var(--v-sidebar-transform-locale-dir-visible) * var(--v-vertical-bar-width, 0px))) !important; opacity: 1 !important; transition-delay: 0s !important; } :root[v_vertical_bar_visible] & { padding-inline: 0 !important; } } #browser > #st_splitter { display: none !important; } `)}`; }, async loadstyle(win) { win.windowUtils.loadSheetUsingURIString(this.style, win.windowUtils.USER_SHEET); win.setTimeout(() => win.ucf_custom_scripts_win.ucf_sidebar_tabs.toolbox.setAttribute("sidebar_tabs_auto_hide", "true"), 0); }, async removestyle(win) { win.windowUtils.removeSheetUsingURIString(this.style, win.windowUtils.USER_SHEET); win.ucf_custom_scripts_win.ucf_sidebar_tabs.toolbox.removeAttribute("sidebar_tabs_auto_hide"); }, showHide(win) { var st = win.ucf_custom_scripts_win.ucf_sidebar_tabs; if (!st.toolbox.hasAttribute("sidebar_tabs_auto_hide")) { st.toggle(); return; } st.st_vbox_container ||= st.toolbox; if (!st._open && st._visible) { st.isPanel = false; st.hideToolbar(true); } st.showHide(); if (!st._visible) win.setTimeout(() => st.toolbox.removeAttribute("sidebar_tabs_visible"), 0); }, }, ) => CustomizableUI.createWidget({ id, label, tooltiptext, defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onBeforeCreated_(doc) { if (Services.prefs.getBoolPref(pref, true)) sidebar_tabs.loadstyle(doc.defaultView); }, onBeforeCreated(doc) { this.onBeforeCreated = this.onBeforeCreated_; this.onBeforeCreated_(doc); CustomizableUI.destroyWidget("ucf_sidebar_tabs"); }, onCreated(btn) { btn.style.setProperty("list-style-image", `url("${img}")`); btn.setAttribute("context", ""); var st = btn.ownerGlobal.ucf_custom_scripts_win.ucf_sidebar_tabs; btn.checked = st._open; st.button = btn; var func = st.mouseup.toString(); Services.scriptloader.loadSubScript(`data:charset=utf-8,${encodeURIComponent(`this.mouseup = ${func.replace(/^(async\s)?.*?\(/, '$1function mouseup(') .replace(/\}$/g, 'setTimeout(() => this.toolbox.removeAttribute("sidebar_tabs_visible"), 0);}')}`)}`, st); }, onClick(e) { switch (e.button) { case 0: if (!e.getModifierState("Control")) sidebar_tabs.showHide(e.view); else e.view.ucf_custom_scripts_win.ucf_sidebar_tabs.toggle(); break; case 1: e.view.ucf_custom_scripts_win.ucf_sidebar_tabs.toggle(); break; case 2: let prf = Services.prefs.getBoolPref(pref, true), loadremove = !prf ? "loadstyle" : "removestyle"; Services.prefs.setBoolPref(pref, !prf); for (let win of CustomizableUI.windows) sidebar_tabs[loadremove](win); break; } }, }))(); |
xrun1 > 14-06-2024 23:48:00 |
Vitaliy V. |
Dobrov > 15-06-2024 02:19:21 |
Вопрос: как открыть Историю за месяц в окне Библиотеки ? win.PlacesCommandHook.showPlacesOrganizer("History"); //покажет только за текущий день unter_officer пишет
Зачем повторы вопросов? на 64 странице задача уже решена, код совместим для старых/новых версий : Ещё в скрипте ucf_hookClicks.js много примеров решений разных вопросов, обсуждавшихся в теме. |
xrun1 > 15-06-2024 09:26:23 |
Dobrov пишет
1. Разница в том, что Вы - разработчик и должны учитывать варианты. А я пользователь последней версии, в которой команда должна работать. Меня не интересует настройка в моём варианте предыдущих версий. В облаке есть бэкапы моих профилей с 80-й версии, установлю и откачусь, если понадобится. |
_zt > 15-06-2024 13:49:05 |
Vitaliy V. |
Vitaliy V. > 15-06-2024 16:55:35 |
_zt пишет
На ваше усмотрение, можно добавить действие после case 1: |
_zt > 15-06-2024 19:48:16 |
Vitaliy V. |
xrun1 > 15-06-2024 20:50:09 |
_zt 15-06-2024 21:00:08 |
_zt > 15-06-2024 21:19:00 |
xrun1 |
xrun1 > 15-06-2024 21:25:08 |
_zt |
_zt > 15-06-2024 21:38:12 |
Не работает на 128 dev и , а на 127 dev и старый код работает, Browser.reload(); никак не мешает. Только уведомления пустые были, просто галочка. |
Dobrov > 16-06-2024 04:22:40 |
Vitaliy V. пишет
Vitaliy V. или Dumby – кнопка-меню для Sidebar Tabs неудобна – адреса не изменить ! |
Dumby > 16-06-2024 19:48:43 |
Dobrov пишет
А в чём именно затруднение? Создаёшь и добавляешь. Пишем, для начала, что-нибудь такое, и смотрим, скрытый текст Выделить код Код:(async sel => { var sep = document.querySelector(sel); if (!sep) return; var popup = sep.parentNode; var menuitem = document.createXULElement("menuitem"); for(var args of Object.entries({ "node-type": "link", "selection-type": "single", label: "Открыть в Sidebar Tabs", id: "placesContext_open:sidebartabs", })) menuitem.setAttribute(...args); menuitem.addEventListener("command", () => { var {uri} = popup.triggerNode._placesNode || popup._view.selectedNode; Services.wm.getMostRecentBrowserWindow() .ucf_custom_script_win.ucf_sidebar_tabs.setPanel(4, uri); }); sep.before(menuitem); })("menupopup#placesContext > #placesContext_openSeparator"); |
Vitaliy V. > 16-06-2024 23:11:16 |
_zt пишет
скрытый текст Выделить код Код:(async ( id = Symbol("urlbarhistorydropmarker"), hidewhenusertyping = true, // скрывать dropmarker при вводе copyvalueistyped = true, // при вводе копировать содержимое адресной строки вместо URL currentURIlabel = "Адрес текущей страницы в буфере обмена!", valueIsTypedlabel = "Содержимое адресной строки в буфере обмена!", Ltooltiptext = "ЛКМ: Показать историю", Mtooltiptext = "СКМ: Обновить текущую страницу", // или false Rtooltiptext = "ПКМ: Копировать URL в буфер обмена", // или false ) => (this[id] = { dropmarker: null, pref: "browser.urlbar.suggest.history", get style() { delete this.style; return this.style = `data:text/css;charset=utf-8,${encodeURIComponent(` #urlbar .urlbar-history-dropmarker { list-style-image: url("chrome://global/skin/icons/arrow-down.svg") !important; transition: opacity 0.15s ease; } #urlbar[switchingtabs] > :is(#urlbar-input-container,.urlbar-input-container) > .urlbar-history-dropmarker { transition: none; } ${hidewhenusertyping ? `#urlbar[usertyping] > :is(#urlbar-input-container,.urlbar-input-container) > .urlbar-history-dropmarker { display: none; }` : ""} #nav-bar:not([customizing="true"]) > #nav-bar-customization-target > #urlbar-container:not(:hover) > #urlbar:not([focused]) > :is(#urlbar-input-container,.urlbar-input-container) > .urlbar-history-dropmarker { opacity: 0; } `)}`; }, get helper() { delete this.helper; return this.helper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, init() { this.UrlbarProviderPlaces = ChromeUtils.importESModule("resource:///modules/UrlbarProviderPlaces.sys.mjs").UrlbarProviderPlaces; this.UrlbarProviderInputHistory = ChromeUtils.importESModule("resource:///modules/UrlbarProviderInputHistory.sys.mjs").UrlbarProviderInputHistory; Services.prefs.addObserver(this.pref, this); setUnloadMap(id, this.destructor, this); if (Services.prefs.getBoolPref(this.pref, false)) this.createDropmarker(); }, get tooltipText() { delete this.tooltipText; return this.tooltipText = `${Ltooltiptext}${Mtooltiptext ? `\n${Mtooltiptext}` : ""}${Rtooltiptext ? `\n${Rtooltiptext}` : ""}`; }, createDropmarker() { windowUtils.loadSheetUsingURIString(this.style, windowUtils.USER_SHEET); var dropmarker = this.dropmarker = document.createXULElement("image"); dropmarker.className = "urlbar-page-action urlbar-history-dropmarker urlbar-icon"; dropmarker.tooltipText = this.tooltipText; document.querySelector("#urlbar #page-action-buttons").before(dropmarker); dropmarker.addEventListener("mousedown", this); if (Rtooltiptext || Mtooltiptext) dropmarker.addEventListener("click", this); }, removeDropmarker() { this.removeListeners(); this.dropmarker.remove(); this.dropmarker = null; windowUtils.removeSheetUsingURIString(this.style, windowUtils.USER_SHEET); }, removeListeners() { this.dropmarker.removeEventListener("mousedown", this); if (Rtooltiptext || Mtooltiptext) this.dropmarker.removeEventListener("click", this); }, observe() { if (!this.dropmarker) { if (Services.prefs.getBoolPref(this.pref, false)) this.createDropmarker(); } else this.removeDropmarker(); }, handleEvent(e) { this[e.type](e); }, mousedown(e) { if (e.button) return; e.preventDefault(); e.stopPropagation(); if (gURLBar.view.isOpen) gURLBar.view.close(); else { if (!gURLBar.valueIsTyped) this.UrlbarProviderPlaces.getPriority = this.UrlbarProviderInputHistory.getPriority = function() { delete this.getPriority; return 3; }; gURLBar.focus(); gURLBar.startQuery(); } }, click(e) { if (e.button === 0) return; e.preventDefault(); e.stopPropagation(); if (e.button === 1 && Mtooltiptext) { BrowserCommands.reload(); return; } if (!Rtooltiptext) return; var url, val; if (!gURLBar.valueIsTyped || !copyvalueistyped) url = gURLBar.makeURIReadable(gBrowser.selectedBrowser.currentURI).displaySpec, val = currentURIlabel; else url = gURLBar.untrimmedValue, val = valueIsTypedlabel; this.helper.copyString(url); ConfirmationHint.show(this.dropmarker, "", { hideArrow: true }); ConfirmationHint._message.removeAttribute("data-l10n-id"); ConfirmationHint._message.textContent = val; }, destructor() { if (this.dropmarker) this.removeListeners(); Services.prefs.removeObserver(this.pref, this); }, }).init())(); |
Dobrov > 17-06-2024 07:26:16 |
Dumby пишет
С нуля делать не умею, изучал контекст-меню undoBookmarks, но это не совсем то… Добавил в шапку версию Sidebar Tabs с поддержкой закладок (два скрипта в одном) |
_zt > 17-06-2024 11:51:58 |
Vitaliy V. |
Vitaliy V. > 17-06-2024 14:09:33 |
Dobrov пишет
Напрасно, тебе же Dumby сделал чтобы не только в основном окне работало но также в библиотеке или в самом сайдбаре Небольшое обновление Sidebar Tabs, устранил проблему в режиме автоскрытия, когда при открытии из меню не всегда срабатывало авто открытие |
Dobrov > 17-06-2024 17:06:16 |
Vitaliy V. пишет
Спасибо за разбор ошибок! |
Vitaliy V. > 17-06-2024 19:11:30 |
egorsemenov06 скрытый текст Выделить код Код:class: "menuitem-iconic", style: 'list-style-image:url("resource://ucf_sidebar_tabs");-moz-context-properties:fill,stroke,fill-opacity;stroke:currentColor;fill:currentColor;fill-opacity:var(--toolbarbutton-icon-fill-opacity,.8);', |
xrun1 > 19-06-2024 00:54:43 |
Vitaliy V. |
Vitaliy V. > 19-06-2024 10:30:44 |
- |
xrun1 > 19-06-2024 11:42:26 |
Vitaliy V. |
Farby > 22-06-2024 19:19:11 |
egorsemenov06 скрытый текст Выделить код Код:` get buttonID() { delete this.buttonID; return this.buttonID = new Map([ ["PanelUI-menu-button", "appMenu-popup"], ["star-button", "editBookmarkPanel"], ]); }, у меня так, но для вас может быть много лишнего... скрытый текст Выделить код Код:` get buttonID() { delete this.buttonID; return this.buttonID = new Map([ ["PanelUI-menu-button", "appMenu-popup"], ["library-button", "customizationui-widget-panel"], ["fxa-toolbar-menu-button", "customizationui-widget-panel"], ["nav-bar-overflow-button", "widget-overflow"], ["unified-extensions-button","toolbarbutton-1"], ["star-button", "editBookmarkPanel"], ["pageActionButton", "pageActionPanel"], ]); }, 22-06-2024 19:29:28 egorsemenov06 пишет
А тестировать как, а по мне можно два в одном, ну тобошь в один файл. |
Dumby > 22-06-2024 23:30:29 |
Farby пишет
Это что ещё за дичь? Работает добавить #unified-extensions-button А ["unified-extensions-button", "unified-extensions-panel"], STR: наводим указатель мыши на аддонскую кнопку. Теперь, не сходя с места, наводим указатель мыши А если добавить, то аддонская панелька, Кстати, недавно, запилили метод nsIAppWindow.rollupAllPopups() |
Dobrov > 24-06-2024 03:10:07 |
Всем привет! Как правильно подключить в Библиотеку скрипт Восстановить удалённое ? Выделить код Код:scriptschrome: { domload: [ // фрагмент скрипта CustomStylesScripts.mjs { path: "undoBookmarks.js", ucfobj: true }, ], }, scriptsallchrome: { load: [ { path: "undoBookmarks.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, ], }, |
Farby > 24-06-2024 10:47:52 |
Dumby пишет
Спасибо!! Теперь я точно знаю, что ничего не знаю mouseoveropentoolbarbutton Выделить код Код:.. ["alltabs-button","customizationui-widget-panel"], ["unified-extensions-button","unified-extensions-panel"], |
Dumby > 24-06-2024 11:15:00 |
Dobrov Быть может, для тебя это представляет Но тогда, консоль должна была бы подсказать, А ещё, у меня, с этого кода наблюдается |
Dobrov > 24-06-2024 16:14:01 |
Dumby пишет
По аналогии с Sidebars Tabs хотел в Библиотеке в контекст-меню пункт: "Восстановить закладку"
То есть, стóит вернуться на предыдущий универсальный скрипт "Восстановить закладку" ? |
_zt > 24-06-2024 19:27:14 |
Восстановить закладку (последний спойлер) скрытый текст Выделить код Код:. scriptschrome: { // Для докум. окна браузера [ChromeOnly] domload: [ // По событию "DOMContentLoaded" ... ], load: [ // По событию "load" { path: "ucf_UndoBookmarksContextMenu.uc.js", ucfobj: false, }, ], scriptsallchrome: { // Для докум. всех окон [ChromeOnly] domload: [ // По событию "DOMContentLoaded" ... ], load: [ // По событию "load" { path: "ucf_UndoBookmarksContextMenu.uc.js", urlregxp: /chrome:\/\/browser\/content\/places\/bookmarksSidebar\.xhtml/, ucfobj: false, }, { path: "ucf_UndoBookmarksContextMenu.uc.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, ], scriptscontent: { DOMWindowCreated: [ // По событию "DOMWindowCreated" ... ], DOMContentLoaded: [ // По событию "DOMContentLoaded" ... ], pageshow: [ // По событию "pageshow" { path: "ucf_UndoBookmarksContextMenu.uc.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, }, ], }, |
Vitaliy V. > 25-06-2024 15:12:15 |
наконец дошли руки для отлавливания этих менюшек, тестируйте кому надо новый скрипт скрытый текст Выделить код Код:(async ( id = Symbol("mouseover_openpopup"), delay = 300, hidedelay = 1000, btnSelectors = [ "#PanelUI-menu-button", "#library-button", "#fxa-toolbar-menu-button", "#nav-bar-overflow-button", "#star-button-box", "#pageActionButton", "#unified-extensions-button", "#downloads-button", "#alltabs-button", ], excludeBtnSelectors = [ "#tabs-newtab-button", "#new-tab-button", "#back-button", "#forward-button", ], areaSelectors = [ "toolbar", ], hideAreaSelectors = [ // "#PlacesToolbarItems", ], excludeHidePopupSelectors = [ "#contentAreaContextMenu", "#contentAreaContextMenu :scope", "#PopupSearchAutoComplete", "#PopupAutoComplete", ], ) => (this[id] = { timer: null, hidetimer: null, hideArea: [], open_: false, get popups() { delete this.popups; return this.popups = new Set(); }, get btnSelectors() { delete this.btnSelectors; return this.btnSelectors = btnSelectors.join(","); }, get ExtensionParent() { delete this.ExtensionParent; return this.ExtensionParent = ChromeUtils.importESModule("resource://gre/modules/ExtensionParent.sys.mjs").ExtensionParent; }, get browserActionFor() { delete this.browserActionFor; return this.browserActionFor = this.ExtensionParent.apiManager.global.browserActionFor; }, get exclude() { delete this.exclude; return this.exclude = excludeBtnSelectors.join(","); }, get excludePopup() { delete this.excludePopup; return this.excludePopup = excludeHidePopupSelectors.join(","); }, async init() { await delayedStartupPromise; for (let elm of (this.areasList = document.querySelectorAll(areaSelectors.join(",")))) { elm.addEventListener("mouseover", this); elm.addEventListener("mouseout", this); elm.addEventListener("mousedown", this); } for (let elm of (this.popupsList = document.querySelectorAll("toolbar, popupset"))) elm.addEventListener("popupshown", this); setUnloadMap(id, this.destructor, this); if (!hideAreaSelectors.length) return; if (excludeHidePopupSelectors.length) this.popupShown = this.pShown; this.popupShown_ = this.popupShown.bind(this); this.popupHidden_ = this.popupHidden.bind(this); this.hidePopup = this.hPopup; for (let elm of (this.hideArea = document.querySelectorAll(hideAreaSelectors.join(",")))) elm.addEventListener("popupshown", this.popupShown_); }, destructor() { for (let elm of this.areasList) { elm.removeEventListener("mouseover", this); elm.removeEventListener("mouseout", this); elm.removeEventListener("mousedown", this); } for (let elm of this.popupsList) elm.removeEventListener("popupshown", this); for (let elm of this.hideArea) elm.removeEventListener("popupshown", this.popupShown_); }, popupShown({target}) { if (target.localName === "tooltip") return; this.pShow(target); }, pShown({target}) { if (target.localName === "tooltip" || target.matches(this.excludePopup)) return; this.pShow(target); }, pShow(target) { target.addEventListener("mouseenter", this); target.addEventListener("popuphidden", this.popupHidden_, { once: true }); if (this.open_) return; this.open_ = true; gBrowser.tabpanels.addEventListener("mouseenter", this); }, popupHidden({target}) { target.removeEventListener("mouseenter", this); }, handleEvent(e) { this[e.type](e); }, mouseenter({currentTarget}) { clearTimeout(this.hidetimer); if (currentTarget != gBrowser.tabpanels) return; this.hidetimer = setTimeout(() => this.hidePopup(), hidedelay); }, popuphidden({target}) { this.popups.delete(target); }, popupshown({target}) { if (target.localName === "tooltip") return; this.popups.add(target); target.addEventListener("popuphidden", this, { once: true }); }, hidePopup() { this.popups.forEach(p => p.hidePopup?.()); this.popups.clear(); }, hPopup() { this.popups.forEach(p => p.hidePopup?.()); this.popups.clear(); if (!this.open_) return; gBrowser.tabpanels.removeEventListener("mouseenter", this); this.open_ = false; }, mousedown() { clearTimeout(this.timer); }, mouseout() { clearTimeout(this.timer); }, mouseover({target}) { clearTimeout(this.timer); this.timer = setTimeout(() => { if (target?.matches?.(`${this.exclude},:is(menupopup,panel) :scope`) ?? true) return; let extensionid, isbtn = target.matches(this.btnSelectors) || !!(target.parentElement.matches(this.btnSelectors) && (target = target.parentElement)); if (!target.hasAttribute("open") && (isbtn || target.menupopup || target.getAttribute("widget-type") === "view" || target.classList.contains("toolbarbutton-combined-buttons-dropmarker") || ((extensionid = target.dataset?.extensionid) && this.browserActionFor(this.ExtensionParent.WebExtensionPolicy.getByID(extensionid).extension).action.tabContext.get(gBrowser.selectedTab).popup))) { this.hidePopup(); let params = { bubbles: true, cancelable: true, }; target.dispatchEvent(new MouseEvent("mousedown", params)); target.dispatchEvent(new MouseEvent("click", params)); } }, delay); }, }).init())(); |
xrun1 > 25-06-2024 17:23:23 |
Vitaliy V. |
Vitaliy V. > 25-06-2024 18:57:31 |
egorsemenov06 пишет
Все что ли? тогда попробуйте добавить в hideAreaSelectors |
Vitaliy V. > 25-06-2024 19:57:36 |
egorsemenov06 пишет
Ну как в excludeBtnSelectors добавляете селекторы, ID или например так сразу для всех расширений |
Dobrov > 26-06-2024 10:22:12 |
_zt пишет
Спасибо! У меня не было подключено в pageshow:. И вот здесь правильней оставить только load: Выделить код Код:domload: [ // По событию "DOMContentLoaded" { path: "ucf_UndoBookmarksContextMenu.uc.js", urlregxp: /chrome:\/\/browser\/content\/places\/bookmarksSidebar\.xhtml/, ucfobj: false, }, ], load: [ // По событию "load" { path: "ucf_UndoBookmarksContextMenu.uc.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, |
_zt > 26-06-2024 12:13:26 |
Dobrov |
Vitaliy V. > 26-06-2024 16:23:18 |
egorsemenov06 пишет
Разве что обновить в смысле оформить для UCF скрытый текст Выделить код Код:(async ( timeout = 150, trg = document.querySelector("#tabbrowser-tabs tab.tabbrowser-tab").flattenedTreeParentNode, ) => ({ id: 0, tab: null, init() { trg.addEventListener("mouseover", this); setUnloadMap(Symbol("tab_focus"), this.destructor, this); }, handleEvent({target}) { var tab = target.closest("tab:not([selected])"); if (tab && this.tab != tab) clearTimeout(this.id), this.id = setTimeout((t, x) => { if (t.matches(":hover") && Math.abs(x - t.screenX) < 50) gBrowser.selectedTab = t; this.tab = null; }, timeout, this.tab = tab, tab.screenX); }, destructor() { trg.removeEventListener("mouseover", this); }, }).init())(); egorsemenov06 пишет
Добавил excludeHidePopupSelectors туда можно добавлять селекторы Pop-Up |
Vitaliy V. > 26-06-2024 20:26:56 |
egorsemenov06 пишет
Ничего себе кнопка это моё расширение, но модифицированное, почему бы вам к автору мода Dumby не обратится? _zt пишет
Многовато подключений это же регулярные выражения, можно заменить три в scriptschrome и scriptsallchrome скрытый текст Выделить код Код:{ path: "ucf_UndoBookmarksContextMenu.uc.js", urlregxp: /^chrome:\/\/browser\/content\/(?:browser|places\/(?:bookmarksSidebar|places))\.xhtml/, }, |
Den199 > 26-06-2024 21:11:13 |
Крайние оригинальные UserChromeFiles и sidebar_tabs.js.
Как сделать так, чтобы при постоянно видимом вертикальном тулбаре, при нажатии на кнопку панель sidebar_tabs появлялась поверх контента на странице? |
_zt > 26-06-2024 21:30:14 |
Vitaliy V. пишет
Точно, спасибо. Даже не задумывался об этом. Den199 пишет
Вот мне тоже по наведению не нравится, хотелось бы иметь возможность вызывать кнопкой. Но это не к sidebar_tabs относится, а к кнопке. Так будет меньше времени тратиться, а сейчас надо медленно позиционировать курсор или увеличивать область срабатывания, первое тратит время и отвлекает внимание, а второе приведет к ложным вызовам. |
Den199 > 28-06-2024 10:10:04 |
_zt пишет
Всё равно не понимаю как скрестить кнопку+sidebar_tabs для нужного мне режима отображения. Есть ли какой-то вариант сделать так, чтобы нажимая на родную кнопку sidebar_tabs, выезжала боковая панель, но не сдвигая страницу вправо, а поверх содержимого страницы? |
Vitaliy V. > 28-06-2024 13:17:41 |
Den199 пишет
Хорошо добавил параметр SHOW_HIDE https://github.com/VitaliyVstyle/Vitali … abs.js#L41 28-06-2024 13:26:14 _zt пишет
Ну не знаю показать можно сделать но чтобы скрыть тоже кликать по кнопке придется, там по СКМ добавить можно или как? Dumby пишет
А почему не установить расширение например так |
_zt > 28-06-2024 15:13:53 |
Vitaliy V. |
Dumby > 28-06-2024 22:57:56 |
Vitaliy V. пишет
Для меня «из дополнения сделать скрипт для UCF» Хотя да, согласен, задача странная. Вот, попробовал так, но, Создаём папку, кладём туда .xpi файл расширения (как есть). скрытый текст Выделить код Код:(async () => { var fn = Components.stack.filename; var folder = fn.slice(0, fn.lastIndexOf("/") + 1); var dir = Cc["@mozilla.org/chrome/chrome-registry;1"] .getService(Ci.nsIXULChromeRegistry) .convertChromeURL(Services.io.newURI(folder)) .QueryInterface(Ci.nsIFileURL); for(var {leafName} of dir.file.directoryEntries) if (leafName.endsWith(".xpi")) break; var rootURI = `jar:${dir.spec + leafName}!/`; var sym = "llc about br"; var read = async sub => (await fetch(rootURI + sub)).text(); var opts = await read("options.xhtml"); var what = "llc"; var flags = Ci.nsIAboutModule.ALLOW_SCRIPT; var factory = { newChannel(...args) { var nc = Services.io.newChannelFromURIWithLoadInfo; opts = opts.replace(/((?:href|src)=")(.+?")/g, `$1${rootURI}$2`).replace(/<\/head>/, ` <script>var browser = windowRoot.ownerGlobal.UcfPrefs.customSandbox[Symbol.for("${sym}")];</script>\n $&` ); var uri = Services.io.newURI("data:application/xhtml+xml," + encodeURIComponent(opts)); var sysp = Services.scriptSecurityManager.getSystemPrincipal(); return (this.newChannel = (u, loadInfo) => { var channel = nc(uri, loadInfo); channel.owner = sysp; return channel; })(...args); }, getURIFlags: () => flags, createInstance: () => factory, QueryInterface: ChromeUtils.generateQI(["nsIAboutModule"]) }; Components.manager.QueryInterface(Ci.nsIComponentRegistrar).registerFactory( Components.ID("{747e75d6-3146-4c55-b241-f751fa2e73b5}"), null, "@mozilla.org/network/protocol/about;1?what=" + what, factory ); var locData = Object.create(null); var locs = Array.from((await read("_locales/")).match(/\n201: .+?\//g), s => s.slice(6, -1)); for(var loc of locs) locData[loc] = JSON.parse(await read(`_locales/${loc}/messages.json`)); var getMessage = msg => (locData[Services.locale.appLocaleAsBCP47] || locData["en-US"])[msg].message; var obj = {ExtensionAPI: class {}}; obj.ExtensionAPI.prototype.extension = { resourceURL: rootURI, localeData: {localizeMessage: getMessage} }; Services.scriptloader.loadSubScript(rootURI + "parent.js", obj); var LLC = obj.LongLeftClick.prototype; var br = globalThis[Symbol.for(sym)] = {i18n: {getMessage}}; Object.assign(br, LLC.getAPI()); var {getPref} = br.LongLeftClick; br.LongLeftClick.getPref = async arr => getPref(arr); Services.scriptloader.loadSubScript("data:,var llcc = longLClick;", obj); var {lgltck} = obj, proto = obj.llcc.prototype; Object.assign(proto, eval(`({${proto.openLink}})`.replace( "addListeners();", "$&\n if (this.maybeSelectTab(link, win)) return;" ))); // Options var b_tabs = "tabs"; // "tabs" or "visibleTabs" var b_equals = "equals"; // "equals" or "equalsExceptRef" var b_allWins = false; var b_skipContainerTabs = true; var wins = b_allWins ? win => new Set([win, ...Services.wm.getEnumerator("navigator:browser")]) : win => [win]; proto.maybeSelectTab = (link, win) => { var uri = Services.io.newURI(link); for(var w of wins(win)) for(var tab of w.gBrowser[b_tabs]) try { if (b_skipContainerTabs && tab.userContextId) continue; if (uri[b_equals](tab.linkedBrowser.currentURI)) return w != win && w.focus(), w.gBrowser.selectedTab = tab; } catch {}; } LLC.onStartup(); })(); Правда у меня с самим LLC наблюдаются некоторые непонятки. В сайдбаре, производишь долгий клик по закладке — открывается вкладка. Лечится удалением из parent.js всех mozSystemGroup: true Ещё, похоже, контейнер, в котором отрывается вкладка, И, в parent.js замечен toolbar#add-additional-vertical-bar |
Vitaliy V. > 29-06-2024 11:57:37 |
_zt пишет
Проверяйте Dumby пишет
Это нужно для panel'ей , без системных слушателей не перехватываются события от мыши и они закрываются, а этого не нужно если не включена соответствующая настройка Dumby пишет
Мне так надо было, добавил настройку. Dumby пишет
Да прикольно, исправил на просто toolbar, так не устареет, наверно 29-06-2024 12:05:43 egorsemenov06 пишет
Ну я так в расширении делать не буду для правильной работы нужно учитывать перенаправления а для этого нужен сетевой запрос, что слегка долго |
Vitaliy V. > 29-06-2024 12:45:11 |
egorsemenov06 пишет
Ну а вы как хотели, не буду же я после каждого обновления расширения проверять работает ли оно с нестандартным загрузчиком, если используете то не обновляйте. |
_zt > 29-06-2024 15:22:55 |
egorsemenov06 |
brake > 29-06-2024 15:53:41 |
Dummy, I need your help. I want to remove the blue line in the box (Show as follow picture) Выделить код Код:// ==UserScript== // @name UnifiedExtensionsSearch.uc.js // @description 在扩展面板中搜索扩展 // @author Ryan // @include main // @version 0.1 // @compatibility Firefox 126 // @destroy window.UnifiedExtensionsSearch.onUnload(); // @homepageURL https://github.com/benzBrake/FirefoxCustomize // ==/UserScript== (window.UnifiedExtensionsSearch = { timer: [], init: function (v, c) { if (!v) return; this.view = v; var pi = document.createProcessingInstruction( 'xml-stylesheet', 'type="text/css" href="data:text/css;utf-8,' + encodeURIComponent(c) + '"' ); this.style = document.insertBefore(pi, document.documentElement); ["ViewHiding"].forEach(t => v.addEventListener(t, this, false)); window.addEventListener("unload", this, false); // Corrected line let w = document.createElement('html:div'); for (let [k, v] of Object.entries({ id: 'unified-extensions-search-input-container', class: 'unified-extensions-search-input-container', role: 'searchbox', })) { w.setAttribute(k, v) } let i = document.createElement('html:div'); for (let [k, v] of Object.entries({ id: 'unified-extensions-search-input', class: 'unified-extensions-search-input', role: 'search', contenteditable: true, empty: true })) { i.setAttribute(k, v) } this.input = w.appendChild(i); ['input', 'change', 'keypress'].forEach(e => i.addEventListener(e, this, false)); let cl = document.createElement('html:button'); for (let [k, v] of Object.entries({ id: 'unified-extensions-search-clear', class: 'unified-extensions-search-clear', role: 'button', })) { cl.setAttribute(k, v) } this.btn = w.appendChild(cl); cl.addEventListener('click', this, false); v.querySelector('.panel-subview-body[context="unified-extensions-context-menu"]').before(w); }, handleEvent (event) { const { type } = event; // 防止回车换行 if (type == 'keypress' && event.keyCode == 13) { event.preventDefault(); event.stopPropagation(); return; } if (this.timer[type]) clearTimeout(this.timer[type]); this.timer[type] = setTimeout(() => { this.timer[type] = null; let fnName = 'on' + type[0].toUpperCase() + type.slice(1); if (this[fnName]) this[fnName](event); else console.log(`UnifiedExtensionsSearch.uc.js: Unhandled event: ${type}`) }, 100); }, onViewHiding () { this.input.textContent = ''; this.input.setAttribute("empty", true); this.resetExtensions(); }, onInput () { let val = this.input.textContent; if (val) { this.input.setAttribute("empty", false); this.searchExtensions(); } else { this.input.setAttribute("empty", true); this.input.innerHTML = ''; this.resetExtensions(); } }, searchExtensions () { let val = this.input.textContent.trim(); if (val) { let search = val.toLowerCase(); let items = this.view.querySelectorAll('.unified-extensions-item'); for (let item of items) { let name = item.querySelector('.unified-extensions-item-name').textContent.toLowerCase(); if (name.includes(search)) { item.removeAttribute("hidden"); } else { item.setAttribute("hidden", true); } } } }, resetExtensions () { let items = document.querySelectorAll('.unified-extensions-item'); for (let item of items) { item.removeAttribute("hidden"); } }, onClick () { if (this.input.getAttribute('empty') === "true") return; this.input.innerHTML = ''; this.input.setAttribute("empty", true); this.resetExtensions(); }, onUnload () { window.removeEventListener('unload', this, false); if (this.style && this.style.parentNode) { this.style.parentNode.removeChild(this.style); this.style = null; } ["ViewHiding"].forEach(t => this.view.removeEventListener(t, this, false)); let c = view.querySelector('#unified-extensions-search-input-container'); if (c && c.parentNode) c.parentNode.removeChild(c); delete window.UnifiedExtensionsSearch; } }).init(gUnifiedExtensions.panel && PanelMultiView.getViewNode( document, "unified-extensions-view" ), ` #unified-extensions-search-input-container { min-height: 20px; margin:5px 10px; border: 1px solid var(--panel-border-color); display: flex; flex-direction: row; overflow: hidden; } #unified-extensions-search-input { flex-grow: 1; height: 100%; padding: 5px; line-height: 20px; font-size: 16px; max-width: calc(100% - 40px); &[empty="true"] { &+#unified-extensions-search-clear { background-position: -30px 50%, 8px 50%; } } } #unified-extensions-search-clear { width: 20px; height: 20px; padding: 5px; flex-shrink: 0; background-image: url(chrome://global/skin/icons/close.svg), url(chrome://global/skin/icons/search-glass.svg); background-position: 8px 50%, 30px 50%; background-repeat: no-repeat no-repeat; transition: background-position 0.2s ease-in-out; } .unified-extensions-item[hidden=true] { display: none; visibility: collapse; opacity: 0; } `); |
Dumby > 29-06-2024 17:09:55 |
Vitaliy V. пишет
О! Теперь увидел, на примере кнопки «Библиотека» (#library-button).
Чисто теоретически, можно опрашивать child actor
Похоже, отвалился кейс #PlacesToolbarItems > toolbarbutton.bookmark-item:not([type=menu]) egorsemenov06 пишет
Можно попробовать добавить ещё насилия. После LLC.onStartup(); скрытый текст Выделить код Код:// await new Promise(ChromeUtils.idleDispatch); // works without, but ... var m = "resource://long_left_click/LLCWinActorParent.mjs"; try {var actorProto = ChromeUtils.importESModule(m).LLCWinActorParent.prototype;} catch {return;} var lazy = globalThis, re = /^about:(?:newtab|home)$/; Object.assign(actorProto, eval(`({${actorProto.receiveMessage}})`.replace( "var tab ", "if (re.test(browser.currentURI.spec) && proto.maybeSelectTab(link, browser.ownerGlobal)) return;\n $&" ))); brake пишет
outline: none; |
Dumby > 01-07-2024 13:31:04 |
egorsemenov06 пишет
Ну, можно заменить xulns собственно на сам неймспейс или node.namespaceURI == xulns на XULElement.isInstance(node) |
Dumby > 01-07-2024 16:59:24 |
egorsemenov06 пишет
Уж не знаю, при каких таких «этих настройках», Первое — эти пункты не расчитаны на autopopup-фичу. Поэтому, удаляем строку if(!isContextOpened()) скрытый текст Выделить код Код:/* function isContextOpened() { return inBtn(document.popupNode); } function inBtn(node) { for(; node; node = node.parentNode) if(node == self) return true; return false; } */ (desc => { var {set} = desc; desc.set = val => { if (val) delete this.open, this.onmousedown?.({}); set.call(this, val); } Object.defineProperty(this, "open", desc); })(Object.getOwnPropertyDescriptor(MozElements.ButtonBase.prototype, "open")); Второе — у тебя кривая XML'ка. SVG'шки должным образом не оформлены для пребывания в атрибуте. Попробуй так скрытый текст Выделить код Код:/* var df = MozXULElement.parseXULToFragment(` <menugroup orient="vertical"> <menuseparator/> <menuitem class="menuitem-iconic" image="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='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>" label="Сохранить всю страницу как PNG" value="all"/> <menuitem class="menuitem-iconic" image="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='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>" label="Сохранить видимую часть страницы как PNG" value="page"/> <menuitem class="menuitem-iconic" image="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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M11.108 8.852c.327 0 .591-.27.591-.602a.596.596 0 0 0-.59-.602c-.327 0-.591.27-.591.602 0 .332.264.602.59.602z'/><path d='M4.808 7.047c0-.665.53-1.203 1.182-1.203h6.3c.652 0 1.18.538 1.18 1.203v4.01c0 .665-.528 1.203-1.18 1.203h-6.3a1.192 1.192 0 0 1-1.182-1.203v-4.01zm1.182 0v3.524l1.639-1.808a.972.972 0 0 1 1.446 0l2.074 2.287-.008.007h1.149v-4.01h-6.3zm2.362 2.691-1.195 1.32h2.39l-1.195-1.32z'/><path d='M3.036 1.833C1.406 1.833.083 3.18.083 4.841v6.818c0 1.661 1.323 3.008 2.953 3.008h9.844c1.631 0 2.953-1.347 2.953-3.008V4.84c0-1.661-1.322-3.008-2.953-3.008H3.036zM1.265 4.841c0-.997.793-1.805 1.771-1.805h9.844c.979 0 1.772.808 1.772 1.805v6.818c0 .997-.793 1.805-1.772 1.805H3.036c-.978 0-1.771-.808-1.771-1.805V4.84z'/></g></svg>" label="Сохранить выбранный элемент страницы как PNG" value="click"/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path fill-rule='evenodd' d='M2.63 1.255c-.76 0-1.375.616-1.375 1.375v2.685a.625.625 0 0 1-1.25 0V2.63A2.625 2.625 0 0 1 2.63.005h2.685a.625.625 0 1 1 0 1.25H2.63ZM10.06.63c0-.345.28-.625.625-.625h2.685a2.625 2.625 0 0 1 2.625 2.625v2.685a.625.625 0 1 1-1.25 0V2.63c0-.76-.616-1.375-1.375-1.375h-2.685A.625.625 0 0 1 10.06.63Zm5.31 9.43c.345 0 .625.28.625.625v2.685a2.625 2.625 0 0 1-2.625 2.625h-2.685a.625.625 0 1 1 0-1.25h2.685c.76 0 1.375-.616 1.375-1.375v-2.685c0-.345.28-.625.625-.625ZM2.729 7.3c-.79 0-1.43.64-1.43 1.429v4.542c0 .79.64 1.43 1.43 1.43H7.27c.79 0 1.43-.64 1.43-1.43V8.73c0-.79-.64-1.43-1.43-1.43H2.73ZM0 8.728A2.729 2.729 0 0 1 2.729 6H7.27A2.729 2.729 0 0 1 10 8.729v4.542A2.729 2.729 0 0 1 7.271 16H2.73A2.729 2.729 0 0 1 0 13.271V8.73Z' clip-rule='evenodd'/><path d='M6.9 14.005H2.73a.5.5 0 0 1-.372-.835l2.085-2.317a.5.5 0 0 1 .744 0l2.085 2.317a.5.5 0 0 1-.371.835ZM8 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'/></svg>" label="Сохранить выбранную область страницы как PNG" value="clipping"/> </menugroup> `); */ var df = MozXULElement.parseXULToFragment(` <menugroup orient="vertical"> <menuseparator/> <menuitem class="menuitem-iconic" image="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='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>" label="Сохранить всю страницу как PNG" value="all"/> <menuitem class="menuitem-iconic" image="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='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>" label="Сохранить видимую часть страницы как PNG" value="page"/> <menuitem class="menuitem-iconic" image="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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M11.108 8.852c.327 0 .591-.27.591-.602a.596.596 0 0 0-.59-.602c-.327 0-.591.27-.591.602 0 .332.264.602.59.602z'/><path d='M4.808 7.047c0-.665.53-1.203 1.182-1.203h6.3c.652 0 1.18.538 1.18 1.203v4.01c0 .665-.528 1.203-1.18 1.203h-6.3a1.192 1.192 0 0 1-1.182-1.203v-4.01zm1.182 0v3.524l1.639-1.808a.972.972 0 0 1 1.446 0l2.074 2.287-.008.007h1.149v-4.01h-6.3zm2.362 2.691-1.195 1.32h2.39l-1.195-1.32z'/><path d='M3.036 1.833C1.406 1.833.083 3.18.083 4.841v6.818c0 1.661 1.323 3.008 2.953 3.008h9.844c1.631 0 2.953-1.347 2.953-3.008V4.84c0-1.661-1.322-3.008-2.953-3.008H3.036zM1.265 4.841c0-.997.793-1.805 1.771-1.805h9.844c.979 0 1.772.808 1.772 1.805v6.818c0 .997-.793 1.805-1.772 1.805H3.036c-.978 0-1.771-.808-1.771-1.805V4.84z'/></g></svg>" label="Сохранить выбранный элемент страницы как PNG" value="click"/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path fill-rule='evenodd' d='M2.63 1.255c-.76 0-1.375.616-1.375 1.375v2.685a.625.625 0 0 1-1.25 0V2.63A2.625 2.625 0 0 1 2.63.005h2.685a.625.625 0 1 1 0 1.25H2.63ZM10.06.63c0-.345.28-.625.625-.625h2.685a2.625 2.625 0 0 1 2.625 2.625v2.685a.625.625 0 1 1-1.25 0V2.63c0-.76-.616-1.375-1.375-1.375h-2.685A.625.625 0 0 1 10.06.63Zm5.31 9.43c.345 0 .625.28.625.625v2.685a2.625 2.625 0 0 1-2.625 2.625h-2.685a.625.625 0 1 1 0-1.25h2.685c.76 0 1.375-.616 1.375-1.375v-2.685c0-.345.28-.625.625-.625ZM2.729 7.3c-.79 0-1.43.64-1.43 1.429v4.542c0 .79.64 1.43 1.43 1.43H7.27c.79 0 1.43-.64 1.43-1.43V8.73c0-.79-.64-1.43-1.43-1.43H2.73ZM0 8.728A2.729 2.729 0 0 1 2.729 6H7.27A2.729 2.729 0 0 1 10 8.729v4.542A2.729 2.729 0 0 1 7.271 16H2.73A2.729 2.729 0 0 1 0 13.271V8.73Z' clip-rule='evenodd'/><path d='M6.9 14.005H2.73a.5.5 0 0 1-.372-.835l2.085-2.317a.5.5 0 0 1 .744 0l2.085 2.317a.5.5 0 0 1-.371.835ZM8 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'/></svg>" label="Сохранить выбранную область страницы как PNG" value="clipping"/> </menugroup> `); |
Dumby > 01-07-2024 21:20:15 |
egorsemenov06 пишет
Ой, прошу прощения, у меня код, создающий кнопку, оказался не тот.
Не-не, вот этот кусок скрытый текст Выделить код Код:(desc => { var {set} = desc; desc.set = val => { if (val) delete this.open, this.onmousedown?.({}); set.call(this, val); } Object.defineProperty(this, "open", desc); })(Object.getOwnPropertyDescriptor(MozElements.ButtonBase.prototype, "open")); он сугубо для кнопки Save, его добавлять не надо было, удали. Кстати, file picker не поправлен скрытый текст Выделить код Код:/* fp.init(popup.ownerGlobal, "Укажите путь к программе", fp.modeOpen); */ fp.init(popup.ownerGlobal.browsingContext, "Укажите путь к программе", fp.modeOpen); |
_zt > 02-07-2024 17:44:21 |
All |
Vitaliy V. > 02-07-2024 20:41:28 |
_zt пишет
Вот только это не для всех, данная кнопка нерекомендуемый способ, т.е. костыль, кому надо переключать урезанное AutoHide. С остальным лучше справится кнопка в составе Sidebar Tabs. |
_zt > 02-07-2024 23:36:59 |
Vitaliy V. |
Selten > 03-07-2024 00:00:56 |
Подскажите пожалуйста как поставить и где взять вертикальную панель на 115.12.0 |
fuchsfan > 03-07-2024 08:09:02 |
Selten пишет
Взять здесьhttps://github.com/Aris-t2/CustomJSforF … ical.uc.js Активировать методом Aris-t2 https://forum.ru-board.com/topic.cgi?fo … art=1360#1 (шапка). |
Den199 > 03-07-2024 08:23:32 |
Есть ли вариант сделать так, чтобы открытые в sidebar_tabs сайты учитывали настройку браузера в части предпочитаемой цветовой схемы для страниц? |
_zt > 03-07-2024 13:42:52 |
Den199 |
Den199 > 03-07-2024 16:02:51 |
_zt пишет
Я и проверил https://github.com/VitaliyVstyle/VitaliyVstyle.github.io - в обычной вкладке отображается в темной цветовой схеме. Вкладки "Bookmarks" и "History" в sidebar_tabs с тёмным фоном. Вкладки "Downloads" и "Add-ons" в sidebar_tabs со светлым фоном, хотя при их открытии в обычном окне - фон тёмный. В настройках браузера выбрана темная тема и темная цветовая схема для сайтов. |
_zt > 03-07-2024 16:43:46 |
Den199 |
Dumby > 03-07-2024 23:47:17 |
Den199 пишет
У меня системная, которая светлая.
Да.
Да. Синтетическая file:/// страница во вкладке «Sites» |
_zt > 04-07-2024 02:37:10 |
Den199 пишет
2024.07.04_013909.png 2024.07.04_014101.png Dumby пишет
Но стили подхватываются. @media (prefers-color-scheme: dark) работает. |
Vitaliy V. > 04-07-2024 03:06:46 |
Dumby пишет
В вообще не воспроизводится, посмотрел в действительно так. |
Dumby > 04-07-2024 09:25:56 |
_zt пишет
Ну, Stylus, например, работает. Vitaliy V. пишет
Ух ты! browser { И, теперь, во вкладках «Downloads» и «Add-ons» — контент тёмный. Более того, синтетическая file:/// страница во вкладке «Sites» Таким образом — похоже, решение найдено. Просто чего я подорвался: зт закошмарил дэна, |
_zt > 04-07-2024 16:39:31 |
Dumby Den199 пишет
Den199 пишет
Это я потом уже, после вашего поста, скринов налепил и с сайтами и без.
однако все темное (за исключением сайтов без адаптивных тем). |
Vitaliy V. > 04-07-2024 17:27:16 |
_zt пишет
Что сделали? Настройка для поддержки или неподдержки сайтов например с функцией light-dark |
Dumby > 04-07-2024 18:25:25 |
_zt пишет
Хорошо, не буду. Действительно, херли я встрял? Тем не менее, commit есть. |
6e73epo > 04-07-2024 20:24:29 |
_zt пишет
В том числе и для переопределения стилей браузера пользовательскими стилями, в которых light-dark задается не явно |
_zt > 05-07-2024 01:05:14 |
Dumby |
Den199 > 05-07-2024 08:50:40 |
_zt пишет
На данный момент 127.0.2 на Windows 10. Ребята, давайте жить дружно! (© Кот Леопольд). Не хотел своим вопросом вызвать такую острую дискуссию |
Den199 > 06-07-2024 12:27:29 |
С последней версией sidebar_tabs.js цвета во всех вкладках учитывают настройки браузера (в моём случае всё в тёмных цветах). Остался один незначительный визуальный раздражитель (персонально для меня в моей стратегии использования sidebar_tabs.js). |
Vitaliy V. > 06-07-2024 23:48:49 |
Den199 пишет
Это не баг, так и задумано кнопка не выделенна только когда сайдбар полностью закрыт т.е. отключен, а в режиме автоскрытия он обычно просто скрыт т.е. находится за пределами окна и невидим, а при активации просто "въезжает" в окно, это значит что в сайдбаре может выполнятся сценарий сайта даже когда сайдбар скрыт. А сделать чтобы сайт выгружался когда сайдбар скрывается может быть не удобно по причине автоскрытия и отображения поверх страницы. |
Dumby > 09-07-2024 00:09:02 |
egorsemenov06 пишет
Чтобы использовать в функции оператор await скрытый текст Выделить код Код:/* setAttrs(node, engine, label = engine.name) { */ async setAttrs(node, engine, label = engine.name) { |
Dobrov > 09-07-2024 05:11:04 |
SideBarTabs — запоминание сайта вкладки Sites в about: config—изменил пару строк. |
_zt > 09-07-2024 12:57:37 |
Dobrov |
xrun1 > 16-07-2024 20:43:09 |
Dumby скрытый текст Выделить код Код:(async id => ({ delay: 2e3, val: "", init(topic, mm) { Services.obs.addObserver(mm = this, topic); Services.obs.addObserver(function quit(s, t) { this.timer?.cancel(); Services.obs.removeObserver(mm, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); }, observe(win) { var df = win.MozXULElement.parseXULToFragment( `<hbox id="${id}" tooltiptext="${ "ЛКМ: Минимизировать потребление памяти
ПКМ: about:performance
Ctrl+ПКМ: about:debugging#/runtime/this-firefox" }" onclick="event.button || ${ "memoryMinimizationButton.doMinimize(event)" }"><label id="${id += "-label"}"/></hbox>` ); this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); (this.observe = async win => { this.timer.cancel(); await new Promise(ChromeUtils.idleDispatch); var clone = win.document.importNode(df, true); clone.firstChild.oncontextmenu = this.about; win.document.getElementById("star-button-box").after(clone); this.notify(); })(win); }, about(e) { var gb = e.view.gBrowser; gb.selectedTab = gb.addTrustedTab(`about:${ e.ctrlKey ? "debugging#/runtime/this-firefox" : "performance" }`); }, async notify() { var info = await ChromeUtils.requestProcInfo(); var bytes = info.memory; for(var child of info.children) bytes += child.memory; this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT); var prev = this.val; if ((this.val = this.mgb(bytes)) != prev) for(var win of CustomizableUI.windows) { var lab = win.document.getElementById(id); if (lab) lab.value = this.val; } }, mgb: bytes => bytes < 1073741824 ? Math.round(bytes / 1048576) + "MB" : (bytes / 1073741824).toFixed(2) + "GB" }).init("browser-delayed-startup-finished"))("ucf-mem-indicator"); Возможно приблизить значение к диспетчеру задач или about:processes? Сейчас у меня так: скрытый текст |
_zt > 16-07-2024 21:51:53 |
xrun1 |
Dobrov > 17-07-2024 01:56:51 |
_zt пишет
Тоже самое с Linux и Mac несоответствие занимаемой памяти, поэтому тут явно браузер выдаёт неверные данные. _zt пишет
Нет, у вас тоже сайт не сохраняется при перезапуске браузера и будет снова открываться адрес по-умолчанию, который устроит не всех. |
_zt > 17-07-2024 03:46:48 |
Dobrov Dobrov пишет
Да нет, просто вы не понимаете, что диспетчер задач Windows отображает только "приватный рабочий набор" и, видимо, ваши диспетчеры "Linux и Mac" тоже, а браузер отдает виджету значения "рабочего набора" и, по моему мнению, это правильно. Dobrov пишет
И я этому рад. Dobrov пишет
Да, будет, но так же, при запуске браузера, вам будут прилетать куки, с сайта который сохранился в этой вкладке, независимо от открытой вкладки и статуса sidebar_tabs. Мне этого не надо. Поэтому лучший вариант прописать туда страницу от дополнения или внутреннюю. |
Dumby > 17-07-2024 08:13:06 |
xrun1 пишет
Попытка такого приближения была, где-то здесь. Ну, там чуть причесать надо, и на ESM перевести.
К странице about:processes приближать не требуется. Если с ChromeUtils.requestProcInfo() |
xrun1 > 17-07-2024 16:32:23 |
Dumby пишет
Смеёшься? Я не догадался взять калькулятор и посчитать about:processes. |
_zt > 17-07-2024 17:02:37 |
xrun1 пишет
Сейчас проверил: скрипт , Process Hacker, J.A.C.K показывают примерно одинаковые результаты. Но нет, по вашему именно обрубок от MS прав! |
fuchsfan > 17-07-2024 18:18:56 |
С точностью до байта |
_zt > 17-07-2024 21:37:10 |
fuchsfan |
xrun1 > 17-07-2024 22:02:02 |
_zt, fuchsfan |
xrun1 > 17-07-2024 22:34:26 |
_zt пишет
А можно ликбез по терминам, очень интересно. |
unter_officer > 18-07-2024 01:10:42 |
Vitaliy V. скрытый текст Выделить код Код:Services.search.getEnginesByExtensionID("google@search.mozilla.org").then(engine => { if (!engine.length) return; engine[0]._iconURI = Services.io.newURI("chrome://user_chrome_files/content/icon/google.png"); }); Поправьте пожалуйста, если возможно. |
Dobrov > 18-07-2024 02:25:23 |
xrun1 пишет
В менеджерах памяти много фишек, экономящих память. Система может использовать общие страницы памяти (одну и более) для нескольких приложений и библиотек, но каждая из программ, работающих в изолированной области, будет считать свои страницы отдельно. Поэтому или другое приложение выдаёт результат занимаемой памяти, который в системе (или утилите показа процессов, запущеной от админа), может быть меньше. Dobrov пишет
_zt пишет
_zt – Вы из-за недоработки оригинального скрипта обречены переубеждать всех, что это не недостаток sidebar_tabs.js от Виталия. _zt пишет
Поэтому лучший вариант – не лазить в скрипт. Мне ваши страницы не нужны, а Вы убеждаете всех править sidebar_tabs.js после каждого обновления. |
_zt > 18-07-2024 15:03:22 |
xrun1 |
Vitaliy V. > 18-07-2024 21:22:11 |
Dobrov пишет
Удалено |
unter_officer > 18-07-2024 22:42:54 |
Vitaliy V. пишет
Так работает. Большое спасибо! |
Dobrov > 19-07-2024 03:30:15 |
Vitaliy V. пишет
Отзываю свои слова, что sidebar_tabs.js недоработан. Переформулирую так: из-за неудобства изменить адрес вкладки Sites (особенно после перезапуска браузера) я и сделал свой мод, где можно это изменить и легко запомнить адрес каждой вкладки без правки скрипта. |
LGS > 05-08-2024 13:35:36 |
Vitaliy V. скрытый текст Выделить код Код:Windows = [ { name: 'PotPlayer', path: 'C:\\PotPlayer Portable\\PotPlayerMini64.exe', //tooltip: 'ПКМ: Ссылка из буфера обмена', //clipboard: true, }, { name: 'Просмотр в |yt-dlp', path: 'C:\\yt-dlp\\Просмотр с yt-dlp в MPC-HC.bat', tooltip: 'ПКМ: Скачать видео с помощью yt-dlp', // yt-dlp скачать видео, используя куки браузера, предпочтительно .mp4 с кодеком hevc|h265|avc|h264 с разрешением <=1080 /*args: `--hold --workdir ~/Загрузки -e "yt-dlp.exe -f %quot%bv[height<=1080][ext=mp4][vcodec~='^(avc|h264)']+ba[ext~='(aac|m4a)']/best[height<=1080][ext=mp4]/best[height<=1080]/best%quot% %OpenURL%"`,*/ // с выбором папки /*rcargs: `--workdir %FilePicker% -e "yt-dlp.exe -f %quot%bv[height<=1080][ext=mp4][vcodec~='^(avc|h264)']+ba[ext~='(aac|m4a)']/best[height<=1080][ext=mp4]/best[height<=1080]/best%quot% %OpenURL%"`,*/ clipboard: true, iconpath: } , Если для PotPlayer добавляю clipboard: true,, то в плеере открываются ссылки из буфера обмена, а ссылки, выделение и пр. со страницы не открываются. Если clipboard: true, закомментировать или убрать - ссылки со страницы открываются, но буфер обмена в "пролете". Поэтому и хотелось бы развести кнопками мыши вызов плеера для просмотра ссылок из буфера и со страницы браузера. yt-dlp с прописанными в скрипте параметрами и аргументами мне запустить так и не удалось, поэтому просто повесил на ЛКМ вызов батника для просмотра в плеере. Теперь вот нужно на ПКМ повесить запуск батника для скачивания... |
egorsemenov06 > 06-08-2024 12:32:04 |
Dumby посмотрите пожауйста кнопку ToggleRestartlessAddons скрытый текст Выделить код Код:(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 || window.BrowserAddonUI.openAddonsMgr // 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СКМ – открыть страницу дополнений" + "\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() { 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; } ); } UPD:разобрался .В этой строке ? "chrome://global/skin/icons/loading.png" заменил loading.png на loading.svg |
unter_officer > 07-08-2024 18:59:19 |
Dumby, поправьте пожалуйста кнопочку под 129. скрытый текст Выделить код Код:// // Compact Menu .......... // Dumby: https://forum.mozilla-russia.org/viewtopic.php?pid=797110#p797110 ..... // (async icons => CustomizableUI.createWidget({ id: "ucf_CompactMenu", label: "Compact Menu", tooltiptext: "Compact Menu", localized: false, onCreated(btn) { btn.type = "menu"; btn.setAttribute("image", "resource://usercontext-content/briefcase.svg"); var doc = btn.ownerDocument; var menupopup = doc.createXULElement("menupopup"); menupopup.toggleAttribute("context"); btn.prepend(menupopup); var bar = doc.getElementById("main-menubar"); bar.querySelector("#bookmarksMenu")._placesView?.uninit(); for(var menu of Array.from(bar.children)) { var popup = menu.menupopup; popup.remove(); menu.textContent = menu.renderedOnce = ""; var img = icons[menu.id]; if (img) menu.className = "menu-iconic", menu.setAttribute("image", img); menupopup.append(menu); menu.render(); menu.append(popup); menu.disabled = false; } } }))({ "file-menu": "chrome://browser/content/robot.ico", "edit-menu": "chrome://browser/skin/preferences/face-smile.svg", "view-menu": "chrome://browser/skin/preferences/face-sad.svg", "history-menu": "chrome://browser/content/robot.ico", "bookmarksMenu": "chrome://browser/skin/preferences/face-smile.svg", "tools-menu": "chrome://browser/skin/preferences/face-sad.svg", "helpMenu": "chrome://browser/content/robot.ico" }); |
Dumby > 08-08-2024 09:18:56 |
unter_officer скрытый текст Выделить код Код:/* btn.prepend(menupopup); var bar = doc.getElementById("main-menubar"); bar.querySelector("#bookmarksMenu")._placesView?.uninit(); for(var menu of Array.from(bar.children)) { */ btn.setAttribute("popup", menupopup.id = "main-menubar-popup"); var bar = doc.getElementById("main-menubar"); bar.append(menupopup); for(var menu of Array.from(bar.querySelectorAll(":scope > menu"))) { Кстати, face-s{ad, mile}.svg выкинули больше года назад в пользу емоджей. |
unter_officer > 08-08-2024 11:00:43 |
Dumby пишет
Так работает, но побочный эффект тот же, что и там:
Это можно как-то пофиксить? |
Dumby > 08-08-2024 13:10:27 |
unter_officer пишет
Ааа, наконец-то дошло о чём речь. Но, переместил кнопку на другой тулбар, Не знаю как это разрулить. скрытый текст Выделить код Код:/* addDestructor(() => { */ var func = AutoHideMenubar._setActive; AutoHideMenubar._setActive = () => {}; addDestructor(() => { AutoHideMenubar._setActive = func; Это для CB. А для UCF-виджета, соответственно, только одна строка btn.ownerGlobal.AutoHideMenubar._setActive = () => {}; |
unter_officer > 08-08-2024 13:18:58 |
Dumby пишет
Теперь всё супер. Большое спасибо! 08-08-2024 13:41:19 скрытый текст Выделить код Код:// // Сохранять изображение без запроса в указанную папку, из контекстного меню .......... // (this.contextsaveimg = { path: "E:\\Download", init(that) { var contextMenu = this.contextMenu = document.querySelector("#contentAreaContextMenu"); if (!contextMenu) return; contextMenu.addEventListener("popupshowing", this); that.unloadlisteners.push("contextsaveimg"); }, destructor() { this.contextMenu.removeEventListener("popupshowing", this); }, handleEvent(e) { if (!gContextMenu.onImage || gContextMenu.webExtBrowserType === "popup") return; var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("id", "ucf_SaveImg"); menuitem.setAttribute("label", "Сохранить изображение в папку: " + this.path); menuitem.setAttribute("oncommand", "saveImg();"); menuitem.className = "menuitem-iconic"; menuitem.setAttribute("image", "data:image.........."); (this.contextMenu.querySelector("#context-sendimage") || this.contextMenu.lastElementChild).after(menuitem); this.handleEvent = () => menuitem.hidden = (!gContextMenu.onImage || gContextMenu.webExtBrowserType === "popup"); menuitem.saveImg = () => { var p = Services.prefs; var data = Object.assign(Object.create(null), { "browser.download.folderList": { type: "Int", set: 2 }, "browser.download.useDownloadDir": { type: "Bool", set: true }, "browser.download.dir": { type: "String", set: this.path } }); var save = eval(`(function ${gContextMenu.saveMedia})`.replace( "\n false, // don't", "\n true, //" )); (menuitem.saveImg = () => { for(var pref in data) { var obj = data[pref], meth = `et${obj.type}Pref`; obj.val = p.prefHasUserValue(pref) ? p["g" + meth](pref) : null; p["s" + meth](pref, obj.set); } try {save.call(gContextMenu);} finally { for(var pref in data) data[pref].val === null ? p.clearUserPref(pref) : p[`set${data[pref].type}Pref`](pref, data[pref].val); } })(); } } }).init(this); |
manuk > 08-08-2024 14:31:05 |
Dumby пишет
Для CB тоже отлично. Большое спасибо! |
Dumby > 08-08-2024 15:39:20 |
unter_officer пишет
Вот, кстати, интересно, откуда этот lazy вообще берётся... Но, может быть, что-то тупенькое прокатит? перед |
unter_officer > 08-08-2024 19:51:07 |
Dumby пишет
Прокатило. Огромное спасибо! |
momo2000 > 12-08-2024 13:05:49 |
Скрипт "Открыть изображение" стал открывать картинки сразу в 2 новых вкладках, кто знает почему? Выделить код Код:(function() { if (!window.gBrowser) return; function viewMedia(event) { let where = BrowserUtils.whereToOpenLink(event, false, false); let referrerInfo = gContextMenu.contentData.referrerInfo; let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); if (gContextMenu.onCanvas) { gContextMenu._canvasToBlobURL(gContextMenu.targetIdentifier).then(function(blobURL) { openTrustedLinkIn(blobURL, where = "tab", { referrerInfo, triggeringPrincipal: systemPrincipal, }); }, Cu.reportError); } else { urlSecurityCheck( gContextMenu.mediaURL, gContextMenu.principal, Ci.nsIScriptSecurityManager.DISALLOW_SCRIPT ); openTrustedLinkIn(gContextMenu.mediaURL, where = "tab", { referrerInfo, forceAllowDataURI: true, triggeringPrincipal: gContextMenu.principal, csp: gContextMenu.csp, }); } } let item = document.getElementById('context-viewimage'); item.setAttribute('oncommand', '(' + viewMedia.toString() + ')(event);'); item.label = 'Открыть изображение'; })(); |
egorsemenov06 > 12-08-2024 21:04:59 |
Dumby посмотрите пожалуиста кнопку Save в ней не работают пункты "Сохранить значок веб-сайта" и "Сохранить выделенный текст как txt файл" скрытый текст Выделить код Код:(async () => CustomizableUI.createWidget({ id: "ucf-cbbtn-Save", tooltiptext: "Сохранить", localized: false, get initCode() { var count = 0; var prfx = "ucf-cbbtn-save-resurl-"; var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var ss = url => { var subst = prfx + ++count; rph.setSubstitution(subst, Services.io.newURI(url)); return "resource://" + subst; } this.image = ss("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 .6C1.6.6.6 1.6.6 3v10c0 1.4 1 2.4 2.4 2.4h10c1.4 0 2.4-1 2.4-2.4V4.84L11.2.602Zm5.4 5.8h2V1m-2 0v5.4H7L5.6 5V1m-2 14v-2.6l1-1h6.8l1 1V15'/></svg>"); var arr = [ "@-moz-document url(chrome://browser/content/browser.xhtml) {", ` #${this.id} menuitem, #content-baseItem, #content-saveItem, #content-editorItem {`, " fill: currentColor !important;", " -moz-context-properties: fill, fill-opacity !important;", " }", "}", "}" ]; var url = "data:text/css;charset=utf-8," + encodeURIComponent(arr.join("\n")); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(Services.io.newURI(ss(url)), sss.USER_SHEET); delete this.initCode; return this.initCode = Cu.readUTF8URI(Services.io.newURI( "chrome://user_chrome_files/content/custom_scripts/custom_script/ucf-cbbtn-Save.js" )) .replace(/data:image\/svg[^"]+/g, ss); }, cbu: { types: { 128: "Bool", boolean: "Bool", 64: "Int", number: "Int", 32: "String", string: "String" }, getPrefs(pref) { try { return Services.prefs[`get${ this.types[Services.prefs.getPrefType(pref)] }Pref`](pref); } catch {return null;} }, setPrefs(pref, val) { Services.prefs[`set${this.types[typeof val]}Pref`](pref, val); } }, gClipboard: { get ch() { delete this.ch; return this.ch = Cc["@mozilla.org/widget/clipboardhelper;1"] .getService(Ci.nsIClipboardHelper); }, write(str) { this.ch.copyStringToClipboard(str, Services.clipboard.kGlobalClipboard); } }, custombuttonsUtils: { writeFile(path, data) { try { if (path.includes(":\\")) path = path.replace(/\//g, "\\"); var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); file.initWithPath(path); file.exists() && file.remove(false); var strm = Cc["@mozilla.org/network/file-output-stream;1"] .createInstance(Ci.nsIFileOutputStream); strm.init(file, 0x04 | 0x08, 420, 0); strm.write(data, data.length); strm.flush(); strm.close(); } catch(ex) { Cu.reportError("Custom Buttons: " + [path, "---", ex, ex.stack].join("\n")); } } }, addDestructor(destructor, context) { this._destructors.push({destructor, context}); }, addEventListener(...args) { var trg = args[3]; if (!trg) trg = args[3] = this.ownerGlobal; trg.addEventListener(...args); this._handlers.push(args); }, onCreated(btn) { var win = btn.ownerGlobal; btn._handlers = new win.Array(); btn._destructors = new win.Array(); win.addEventListener("unload", this, {once: true}); new win.Function( "self,_id,cbu,xhtmlns,addDestructor,addEventListener,gClipboard,custombuttonsUtils", this.initCode ).call( btn, btn, this.id, this.cbu, "http://www.w3.org/1999/xhtml", this.addDestructor.bind(btn), this.addEventListener.bind(btn), this.gClipboard, this.custombuttonsUtils ); btn.setAttribute("image", this.image); }, handleEvent(e) { var btn = e.target.getElementById(this.id); for(var args of btn._handlers) args.pop().removeEventListener(...args); delete btn._handlers; for(var {destructor, context} of btn._destructors) try {destructor.call(context, "destructor");} catch(ex) {Cu.reportError(ex);} delete btn._destructors; } }))(); скрытый текст Выделить код Код:self.label = "Save"; this.type = "menu"; var folderpath="C:\\Users\\Роман\\Desktop"; var array = [ { label: "Сохранить значок веб-сайта", func: "saveFavicon()", image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='context-fill' fill-opacity='context-fill-opacity'><path d='M8.5 1a7.5 7.5 0 1 0 0 15 7.5 7.5 0 0 0 0-15zm2.447 1.75a6.255 6.255 0 0 1 3.756 5.125h-2.229A9.426 9.426 0 0 0 10.54 2.75h.407zm-2.049 0a8.211 8.211 0 0 1 2.321 5.125H5.781A8.211 8.211 0 0 1 8.102 2.75h.796zm-2.846 0h.408a9.434 9.434 0 0 0-1.934 5.125H2.297A6.254 6.254 0 0 1 6.052 2.75zm0 11.5a6.252 6.252 0 0 1-3.755-5.125h2.229A9.426 9.426 0 0 0 6.46 14.25h-.408zm2.05 0a8.211 8.211 0 0 1-2.321-5.125h5.437a8.211 8.211 0 0 1-2.321 5.125h-.795zm2.846 0h-.409a9.418 9.418 0 0 0 1.934-5.125h2.229a6.253 6.253 0 0 1-3.754 5.125z'/></svg>"}, { label: "Запомнить значок веб-сайта как base64", func: "copyFaviconData()", image: "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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z'/><path d='M8.646 6.646a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L10.293 9 8.646 7.354a.5.5 0 0 1 0-.708zm-1.292 0a.5.5 0 0 0-.708 0l-2 2a.5.5 0 0 0 0 .708l2 2a.5.5 0 0 0 .708-.708L5.707 9l1.647-1.646a.5.5 0 0 0 0-.708z'/></g></svg>"}, { separator: ''}, { label: "Сохранить ярлык страницы как…", func: "saveShortcuts()", image: "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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M0 1.512v13.101c0 .835.677 1.512 1.512 1.512h13.101c.835 0 1.512-.677 1.512-1.512V1.512C16.125.677 15.448 0 14.613 0H1.512C.677 0 0 .677 0 1.512zm2.719.188a.6.596 0 0 1-.598.6.6.6 0 0 1 0-1.198.6.596 0 0 1 .598.598zm2.22 0a.6.596 0 0 1-.598.6.599.599 0 0 1 0-1.198.6.596 0 0 1 .598.598zm2.221 0a.6.596 0 0 1-.599.6.6.6 0 0 1 0-1.198.6.596 0 0 1 .599.598zm-5.9 1.576h13.606v11.337a.253.251 0 0 1-.253.252H1.512a.253.251 0 0 1-.253-.252V3.276z' class='st0'/><path d='M8.314 6.047h4.787v1.008H8.314V6.047zm-5.543 5.04h10.33v1.007H2.77v-1.008zm0-5.04h3.78v3.78H2.77v-3.78zm6.14 3.527h-.597V8.567h4.788v1.007H8.912z' class='st0'/></g></svg>"}, { separator: ''}, { label: "Кодировать изображение(текст.файл) в base64", func: "copyFaviconbase()", image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path fill-rule='evenodd' d='M11.188 5.058a.625.625 0 0 1 .884 0l2.146 2.147c.44.439.44 1.151 0 1.59l-2.146 2.147a.625.625 0 1 1-.884-.884L13.246 8l-2.058-2.058a.625.625 0 0 1 0-.884ZM9.557 3.034c.33.103.513.454.41.783l-2.74 8.74a.625.625 0 0 1-1.193-.374l2.74-8.74a.625.625 0 0 1 .783-.41ZM4.812 5.058a.625.625 0 0 1 0 .884L2.754 8l2.058 2.058a.625.625 0 1 1-.884.884L1.782 8.796a1.125 1.125 0 0 1 0-1.591l2.146-2.147a.625.625 0 0 1 .884 0Z' clip-rule='evenodd'/></svg>"}, { separator: ''}, { label: "Сохранить всю страницу как PDF", func: "savePageToPDF()", image: "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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M14 14V4.5L9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2zM9.5 3A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5v2z'/><path d='M4.603 14.087a.81.81 0 0 1-.438-.42c-.195-.388-.13-.776.08-1.102.198-.307.526-.568.897-.787a7.68 7.68 0 0 1 1.482-.645 19.697 19.697 0 0 0 1.062-2.227 7.269 7.269 0 0 1-.43-1.295c-.086-.4-.119-.796-.046-1.136.075-.354.274-.672.65-.823.192-.077.4-.12.602-.077a.7.7 0 0 1 .477.365c.088.164.12.356.127.538.007.188-.012.396-.047.614-.084.51-.27 1.134-.52 1.794a10.954 10.954 0 0 0 .98 1.686 5.753 5.753 0 0 1 1.334.05c.364.066.734.195.96.465.12.144.193.32.2.518.007.192-.047.382-.138.563a1.04 1.04 0 0 1-.354.416.856.856 0 0 1-.51.138c-.331-.014-.654-.196-.933-.417a5.712 5.712 0 0 1-.911-.95 11.651 11.651 0 0 0-1.997.406 11.307 11.307 0 0 1-1.02 1.51c-.292.35-.609.656-.927.787a.793.793 0 0 1-.58.029zm1.379-1.901c-.166.076-.32.156-.459.238-.328.194-.541.383-.647.547-.094.145-.096.25-.04.361.01.022.02.036.026.044a.266.266 0 0 0 .035-.012c.137-.056.355-.235.635-.572a8.18 8.18 0 0 0 .45-.606zm1.64-1.33a12.71 12.71 0 0 1 1.01-.193 11.744 11.744 0 0 1-.51-.858 20.801 20.801 0 0 1-.5 1.05zm2.446.45c.15.163.296.3.435.41.24.19.407.253.498.256a.107.107 0 0 0 .07-.015.307.307 0 0 0 .094-.125.436.436 0 0 0 .059-.2.095.095 0 0 0-.026-.063c-.052-.062-.2-.152-.518-.209a3.876 3.876 0 0 0-.612-.053zM8.078 7.8a6.7 6.7 0 0 0 .2-.828c.031-.188.043-.343.038-.465a.613.613 0 0 0-.032-.198.517.517 0 0 0-.145.04c-.087.035-.158.106-.196.283-.04.192-.03.469.046.822.024.111.054.227.09.346z'/></g></svg>"}, { label: "Сохранить всю страницу или выбранное как HTML", func: "savePageToHTML()", image: "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path d='M12.225.01H2.656v5.993l.955-.125L3.569.677 11 .76l-.042 4.375h4.275l.041 10.125-12.575.042-.042.708h13.281V3.737L12.225.01zm-.272 1.613 2.384 2.394h-2.384V1.623zm2.93 10.318.062 1.333-2.992.063V8.003h1.328v4l1.601-.063zM4.647 8.002h-.664v1.334h.664v4h1.329v-4h.664V8.003H4.648zm5.313 0-.664 1.074-.664-1.074H7.305v5.334h1.328V10.53l.664 1.073.664-1.073v2.807h1.328V8.003H9.961zm-7.969 2h-.664v-2H0v5.334h1.328v-2h.664v2H3.32V8.003H1.992v2z'/></svg>"}, { label: "Сохранить выделенный текст как txt файл", func: "saveSelectionToTxt()", image: "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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M5.5 7a.5.5 0 0 0 0 1h5a.5.5 0 0 0 0-1h-5zM5 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z'/><path d='M9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.5L9.5 0zm0 1v2A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5z'/></g></svg>"}, { separator: ''}, { label: "Запомнить изображение как base64, в контекстном меню", value: "Save.WebScreenShotOnImage"}, { label: "Сохранить выделенный текст в файл, в контекстном меню", value: "Save.SelectionToFile" }, { label: "Открыть выделенный текст в внешнем редакторе, в контекстном меню", value: "Save.TextToEditor"}, ]; var menuPopup = self.appendChild(document.createXULElement("menupopup")); var PHandler = Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler), count = 0; array.forEach((m,i)=> { if ("separator" in m) { menuPopup.appendChild(document.createXULElement("menuseparator")); return }; var mItem = menuPopup.appendChild(document.createXULElement("menuitem")); mItem.setAttribute("label", m.label); mItem.setAttribute("class", "menuitem-iconic"); if ("image" in m) { let substitution = `ucf-cbbtn-save-${++count}-img`; if (!PHandler.hasSubstitution(substitution)) PHandler.setSubstitution(substitution, Services.io.newURI(m.image || array[i-1].image)); mItem.style.cssText = `list-style-image:url("resource://${substitution}");-moz-context-properties:fill,fill-opacity;fill:currentColor;`; } if ("value" in m) { mItem.setAttribute('type', 'checkbox'); mItem.setAttribute('checked', cbu.getPrefs(m.value) ); mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value)); } if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString())); }); menuPopup.setAttribute("onclick", "event.stopPropagation()"); function aDate() { var t=new Date(); var y=1900+t.getYear(); var min=t.getMinutes(); if (min<10){min="0"+min}; var h=t.getHours(); var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";} var d=t.getDate(); var curdate=d+" "+m+" "+y+" "+"г"; var myfilename=curdate; return myfilename; } function WebScreenShotonImage(image) { var canvas = document.createElementNS(xhtmlns, 'canvas'); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; var ctx = canvas.getContext('2d'); ctx.drawImage(image, 0, 0); var base64 = canvas.toDataURL(); gClipboard.write(base64); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(base64, self.label, "Изображение копировано как base64", false, "", (s, t)=> { if (t == 'alertfinished') sss.unregisterSheet(uri, 0); }, ""); }; var saveToFile = function (fileContent, fileName) { var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); uc.charset = 'utf-8'; fileContent = uc.ConvertFromUnicode(fileContent); var nsIFilePicker = Components.interfaces.nsIFilePicker; var fp = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker); fp.init(window.browsingContext, '', fp.modeSave); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); fp.open(function (rv) { if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) { var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream); stream.init(fp.file, 0x02|0x20|0x08, 0666, 0); stream.write(fileContent, fileContent.length); stream.close(); } }); }; function savePageToHTML() { var vert = String.raw`javascript:(function(){var getSelWin=function(w){if(w.getSelection().toString())return w;for(var i=0,f,r;f=w.frames[i];i++){try{if(r=getSelWin(f))return r}catch(e){}}};var selWin=getSelWin(window),win=selWin||window,doc=win.document,loc=win.location;var qualifyURL=function(url,base){if(!url||/^([a-z]+:|%23)/.test(url))return url;var a=doc.createElement('a');if(base){a.href=base;a.href=a.protocol+(url.charAt(0)=='/'%3F(url.charAt(1)=='/'%3F'':'//'+a.host):'//'+a.host+a.pathname.slice(0,(url.charAt(0)!='%3F'&&a.pathname.lastIndexOf('/')+1)||a.pathname.length))+url}else{a.href=url};return a.href};var encodeImg=function(src,obj){var canvas,img,ret=src;if(/^https%3F:%5C/%5C//.test(src)){canvas=doc.createElement('canvas');if(!obj||obj.nodeName.toLowerCase()!='img'){img=doc.createElement('img');img.src=src}else{img=obj};if(img.complete)try{canvas.width=img.width;canvas.height=img.height;canvas.getContext('2d').drawImage(img,0,0);ret=canvas.toDataURL((/%5C.jpe%3Fg/i.test(src)%3F'image/jpeg':'image/png'))}catch(e){};if(img!=obj)img.src='about:blank'};return ret};var toSrc=function(obj){var strToSrc=function(str){var chr,ret='',i=0,meta={'%5Cb':'%5C%5Cb','%5Ct':'%5C%5Ct','%5Cn':'%5C%5Cn','%5Cf':'%5C%5Cf','%5Cr':'%5C%5Cr','%5Cx22':'%5C%5C%5Cx22','%5C%5C':'%5C%5C%5C%5C'};while(chr=str.charAt(i++)){ret+=meta[chr]||chr};return'%5Cx22'+ret+'%5Cx22'},arrToSrc=function(arr){var ret=[];for(var i=0;i<arr.length;i++){ret[i]=toSrc(arr[i])||'null'};return'['+ret.join(',')+']'},objToSrc=function(obj){var val,ret=[];for(var prop in obj){if(Object.prototype.hasOwnProperty.call(obj,prop)&&(val=toSrc(obj[prop])))ret.push(strToSrc(prop)+': '+val)};return'{'+ret.join(',')+'}'};switch(Object.prototype.toString.call(obj).slice(8,-1)){case'Array':return arrToSrc(obj);case'Boolean':case'Function':case'RegExp':return obj.toString();case'Date':return'new Date('+obj.getTime()+')';case'Math':return'Math';case'Number':return isFinite(obj)%3FString(obj):'null';case'Object':return objToSrc(obj);case'String':return strToSrc(obj);default:return obj%3F(obj.nodeType==1&&obj.id%3F'document.getElementById('+strToSrc(obj.id)+')':'{}'):'null'}};var ele,pEle,clone,reUrl=/(url%5C(%5Cx22%3F)(.+%3F)(%5Cx22%3F%5C))/g;if(selWin){var rng=win.getSelection().getRangeAt(0);pEle=rng.commonAncestorContainer;ele=rng.cloneContents()}else{pEle=doc.documentElement;ele=(doc.body||doc.getElementsByTagName('body')[0]).cloneNode(true)};while(pEle){if(pEle.nodeType==1){clone=pEle.cloneNode(false);clone.appendChild(ele);ele=clone};pEle=pEle.parentNode};var sel=doc.createElement('div');sel.appendChild(ele);for(var el,all=sel.getElementsByTagName('*'),i=all.length;i--;){el=all[i];if(el.style&&el.style.backgroundImage)el.style.backgroundImage=el.style.backgroundImage.replace(reUrl,function(a,b,c,d){return b+encodeImg(qualifyURL(c))+d});switch(el.nodeName.toLowerCase()){case'link':case'style':case'script':el.parentNode.removeChild(el);break;case'a':case'area':if(el.hasAttribute('href')&&el.getAttribute('href').charAt(0)!='%23')el.href=el.href;break;case'img':case'input':if(el.hasAttribute('src'))el.src=encodeImg(el.src,el);break;case'audio':case'video':case'embed':case'frame':case'iframe':if(el.hasAttribute('src'))el.src=el.src;break;case'object':if(el.hasAttribute('data'))el.data=el.data;break;case'form':if(el.hasAttribute('action'))el.action=el.action;break}};var head=ele.insertBefore(doc.createElement('head'),ele.firstChild);var meta=doc.createElement('meta');meta.httpEquiv='content-type';meta.content='text/html; charset=utf-8';head.appendChild(meta);var title=doc.getElementsByTagName('title')[0];if(title)head.appendChild(title.cloneNode(true));head.copyScript=function(){if('$'in win)return;var f=doc.createElement('iframe');f.src='about:blank';f.setAttribute('style','position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;');doc.documentElement.appendChild(f);var str,script=doc.createElement('script');script.type='text/javascript';for(var name in win){if(name in f.contentWindow||!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name))continue;try{str=toSrc(win[name]);if(!/%5C{%5Cs*%5C[native code%5C]%5Cs*%5C}/.test(str)){script.appendChild(doc.createTextNode('var '+name+' = '+str.replace(/<%5C/(script>)/ig,'<%5C%5C/$1')+';%5Cn'))}}catch(e){}};f.parentNode.removeChild(f);if(script.childNodes.length)this.nextSibling.appendChild(script)};head.copyScript();head.copyStyle=function(s){if(!s)return;var style=doc.createElement('style');style.type='text/css';if(s.media&&s.media.mediaText)style.media=s.media.mediaText;try{for(var i=0,rule;rule=s.cssRules[i];i++){if(rule.type!=3){if((!rule.selectorText||rule.selectorText.indexOf(':')!=-1)||(!sel.querySelector||sel.querySelector(rule.selectorText))){style.appendChild(doc.createTextNode(rule.cssText.replace(reUrl,function(a,b,c,d){var url=qualifyURL(c,s.href);if(rule.type==1&&rule.style&&rule.style.backgroundImage)url=encodeImg(url);return b+url+d})+'%5Cn'))}}else{this.copyStyle(rule.styleSheet)}}}catch(e){if(s.ownerNode)style=s.ownerNode.cloneNode(false)};this.appendChild(style)};var sheets=doc.styleSheets;for(var j=0;j<sheets.length;j++)head.copyStyle(sheets[j]);head.appendChild(doc.createTextNode('%5Cn'));var doctype='',dt=doc.doctype;if(dt&&dt.name){doctype+='<!DOCTYPE '+dt.name;if(dt.publicId)doctype+=' PUBLIC %5Cx22'+dt.publicId+'%5Cx22';if(dt.systemId)doctype+=' %5Cx22'+dt.systemId+'%5Cx22';doctype+='>%5Cn'};var href = 'data:text/html;charset=utf-8,' + encodeURIComponent(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->');var a = document.documentElement.appendChild(document.createElement("a"));a.setAttribute("href", href);var name = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());name=name.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');name += (function () {var d = new Date(), z=function(n){return '_' + (n < 10 ? '0' : '') + n};return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());})();a.setAttribute("download", name + ".html");a.click();a.remove();})();`; gBrowser.fixupAndLoadURIString(vert, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()}); }; function saveShortcuts() { var file = Components.classes["@mozilla.org/file/local;1"]. createInstance(Components.interfaces.nsIFile); file.initWithPath(folderpath); if( !file.exists() || !file.isDirectory() ) { file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0x1B6);} var savetodir=folderpath+"\\"; var urllink=gBrowser.currentURI.spec; var out=getTabLabel(); var filename=savetodir+out+'.url'; var data="[InternetShortcut]\r\nURL="+urllink+"\r\n"; saveToFile(data, filename); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); var notific = 'Сохранил в: ' + folderpath; var image = gBrowser.selectedBrowser.mIconURL; Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(image, filename, notific); }; function copyFaviconbase(){ var fp = window.makeFilePicker(); fp.init(window.browsingContext, "Открыть файл", fp.modeOpen); fp.appendFilter("Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml; *.xhtml; *.jpe; *.jpg; *.jpeg;\ *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw"); fp.open(re=> { if ( re != fp.returnOK ) return; var file = fp.file; var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); inputStream.init(file, 0x01, 0600, 0); var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream); stream.setInputStream(inputStream); var encoded = btoa(stream.readBytes(stream.available())); var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file); var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded; gClipboard.write(dataURI); //Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Текст скопирован как base64"); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }')); sss.loadAndRegisterSheet(uri, 0); // alertsService.showAlertNotification(base64, self.label, "Изображение скопировано как base64", false, "", (s, t)=> { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Изображение скопировано как base64", false, "", (s, t)=> { if (t == 'alertfinished') sss.unregisterSheet(uri, 0); }, ""); }); }; function savePageToPDF() { var loc = gBrowser.currentURI.spec; var vert = "http://pdfmyurl.com?url=" + loc; gBrowser.fixupAndLoadURIString(vert, { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }); }; if (typeof window.saveImageURL != "function") var saveImageURL = internalSave.length == 16 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : internalSave.length == 15 ? (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, null, a7, a5, null, priv, prin) : (url, name, a3, a4, a5, a6, a7, type, a9, priv, prin) => internalSave(url, null, name, a9, type, a4, a3, null, a6, a7, a5, null, priv, prin); function saveFavicon() { var uri = gBrowser.currentURI; function getSiteName() { try { var domain = uri.host.split('.') } catch(e) { return "" }; domain = (domain.length == 2) ? domain[0] : domain[1] return domain.charAt(0).toUpperCase() + domain.slice(1).split('.')[0] + " "; }; var url = gBrowser.selectedTab.image; url && saveImageURL( url, getSiteName(), null, false, false, null, null, /^data:(image\/[^;,]+)/i.test(url) ? RegExp.$1.toLowerCase() : Cc["@mozilla.org/mime;1"] .getService(Ci.nsIMIMEService).getTypeFromURI(Services.io.newURI(url)), null, PrivateBrowsingUtils.isContentWindowPrivate(content || window), document.nodePrincipal ); }; function copyFaviconData() { var img = new Image(); img.src = gBrowser.selectedTab.image; WebScreenShotonImage(img); }; (popup => addEventListener("popupshowing", { handleEvent(e) { if (this.shouldHide) return; var menuitem = document.createXULElement("menuitem"); menuitem.id = "content-baseItem"; menuitem.className = "menuitem-iconic"; menuitem.setAttribute("oncommand", "copyImageAsBase64()"); menuitem.setAttribute("label", "Запомнить изображение как base64"); menuitem.setAttribute("image", "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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z'/><path d='M8.646 6.646a.5.5 0 0 1 .708 0l2 2a.5.5 0 0 1 0 .708l-2 2a.5.5 0 0 1-.708-.708L10.293 9 8.646 7.354a.5.5 0 0 1 0-.708zm-1.292 0a.5.5 0 0 0-.708 0l-2 2a.5.5 0 0 0 0 .708l2 2a.5.5 0 0 0 .708-.708L5.707 9l1.647-1.646a.5.5 0 0 0 0-.708z'/></g></svg>"); popup.append(menuitem); addDestructor(() => menuitem.remove()); menuitem.copyImageAsBase64 = () => { var {osPid} = gContextMenu.actor.manager.browsingContext.currentWindowGlobal; if (osPid == -1) osPid = Services.appinfo.processID; for(var ind = 0, len = Services.ppmm.childCount; ind < len; ind++) { var pmm = Services.ppmm.getChildAt(ind); if (pmm.osPid == osPid) break; } pmm.loadProcessScript("data:;charset=utf-8," + encodeURIComponent(this.code()), false); } this.handleEvent = () => menuitem.hidden = this.shouldHide; }, get shouldHide() { return !(gContextMenu.onImage && Services.prefs.getBoolPref("Save.WebScreenShotOnImage", false)); }, code: () => `(targetIdentifier => { var image = ChromeUtils.import("resource://gre/modules/ContentDOMReference.jsm") .ContentDOMReference.resolve(targetIdentifier); var canvas = image.ownerDocument.createElementNS("${xhtmlns}", "canvas"); canvas.width = image.naturalWidth; canvas.height = image.naturalHeight; var ctx = canvas.getContext("2d"); ctx.drawImage(image, 0, 0); var base64 = canvas.toDataURL(); Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper) .copyStringToClipboard(base64, Ci.nsIClipboard.kGlobalClipboard); Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService) .showAlertNotification(base64, "${self.label}", "Запомнил изображение как base64"); })(${ JSON.stringify(gContextMenu.targetIdentifier) })` }, false, popup || 1))(document.getElementById("contentAreaContextMenu")); function saveSelectionToTxt() { var {length} = saveURL, splice = length > 9, l11 = length == 11; var msgName = _id + ":Save:GetSelection"; var receiver = msg => { var args = [ "data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + "\r\n\r\n" + msg.data), getTabLabel() + ' ' + aDate().replace(/:/g, ".") + ".txt", null, false, false, null, window.document ]; splice && args.splice(5, 0, null) && l11 && args.splice(1, 0, null); saveURL(...args); } messageManager.addMessageListener(msgName, receiver); addDestructor(() => messageManager.removeMessageListener(msgName, receiver)); var func = fm => { var res, fed, win = {}; var fe = fm.getFocusedElementForWindow(content, true, win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed) { var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if (sel.isCollapsed) fed && fed.blur(), docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(), docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("NAME", res); } var url = "data:charset=utf-8," + encodeURIComponent(`(${func})`.replace("NAME", msgName)) + '(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelectionToTxt = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); } ((contextMenu, el)=> { var saveItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el); saveItem.id = "content-saveItem"; saveItem.setAttribute("label", "Сохр./добавить выбранный текст в файл"); saveItem.setAttribute("class", "menuitem-iconic"); saveItem.setAttribute("image", "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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M5.5 7a.5.5 0 0 0 0 1h5a.5.5 0 0 0 0-1h-5zM5 9.5a.5.5 0 0 1 .5-.5h5a.5.5 0 0 1 0 1h-5a.5.5 0 0 1-.5-.5zm0 2a.5.5 0 0 1 .5-.5h2a.5.5 0 0 1 0 1h-2a.5.5 0 0 1-.5-.5z'/><path d='M9.5 0H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V4.5L9.5 0zm0 1v2A1.5 1.5 0 0 0 11 4.5h2V14a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h5.5z'/></g></svg>"); saveItem.onclick =()=> saveSelectionToFile(); var editorItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el); editorItem.id = "content-editorItem"; editorItem.setAttribute("label", "Открыть выбранный текст в редакторе"); editorItem.setAttribute("class", "menuitem-iconic"); editorItem.setAttribute("image", "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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M4.513 8.821h7.036v1.143H4.513zM4.513 11.107h7.036v1.143H4.513zM4.513 6.536h7.036v1.143H4.513z'/><path d='M11.55 1.393V.25h-1.006v1.143h-2.01V.25H7.529v1.143h-2.01V.25H4.512v1.143H2V16.25h12.062V1.393H11.55zm1.507 13.714H3.005V2.536h1.508v1.143h1.005V2.536h2.01v1.143h1.006V2.536h2.01v1.143h1.005V2.536h1.508v12.571z'/></g></svg>"); editorItem.onclick =()=> textToEditor(); addEventListener('popupshowing', e=> { if (e.target != e.currentTarget) return; var sel = gContextMenu.isTextSelected; saveItem.hidden = !sel || !cbu.getPrefs("Save.SelectionToFile"); editorItem.hidden = !sel || !cbu.getPrefs("Save.TextToEditor"); }, false, contextMenu); addDestructor(()=> { saveItem.remove(); editorItem.remove(); }); })(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open")); function saveSelectionToFile() { var line = ".".repeat(62) + "\n"; var hint = "Нажмите чтобы открыть файл"; var prfx = "Выделенный текст сохранен в файл "; var img = self.getAttribute("image"); var desk = Services.dirsvc.get("Desk", Ci.nsIFile); var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); (saveSelectionToFile = async () => { var time = aDate(), url = gBrowser.currentURI.displaySpec; var text = `${line}${getTabLabel()} - ${time}\n${url}\n\n${ gContextMenu.contentData.selectionInfo.fullText }\n\n\n`; try { var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile); var msg = prfx + "в папку " + file.leafName; await IOUtils.makeDirectory(file.path); } catch(ex) { file && Cu.reportError(ex); file = desk.clone(); var msg = prfx + "на рабочий стол"; } file.append(`Save - ${time}.txt`); await IOUtils.writeUTF8(file.path, text, {mode: file.exists() ? "append" : "create"}); var name = "sstf-" + Cu.now(); as.showAlertNotification( gBrowser.selectedTab.image || img, msg, hint, true, "", (s, t) => t == "alertclickcallback" && file.launch(), name ); setTimeout(as.closeAlert, 8e3, name); })(); }; function textToEditor() { let browserMM = gBrowser.selectedBrowser.messageManager; browserMM.addMessageListener('getSelect', function listener(message) { var text = convertFromUnicode("UTF-8", message.data); try {var file = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {file = Services.dirsvc.get("Desk", Ci.nsIFile);} file.append("TextToEditor.txt"); custombuttonsUtils.writeFile(file.path, text); file.launch(); browserMM.removeMessageListener('getSelect', listener, true); }); browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false); }; function convertFromUnicode(charset, str) { var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter); converter.charset = charset; str = converter.ConvertFromUnicode(str); return str + converter.Finish(); }; function getTabLabel() { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); }; ((main, parts) => this.onmousedown = e => { if (e.button) return; this.onmousedown = null; var df = MozXULElement.parseXULToFragment(` <menugroup orient="vertical"> <menuseparator/> <menuitem class="menuitem-iconic" image="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='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>" label="Сохранить всю страницу как PNG" value="all"/> <menuitem class="menuitem-iconic" image="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='M13.946 2.353c.273 0 .498.23.498.513v10.262l-.156-.209-4.233-5.647a.737.737 0 0 0-1.183 0l-2.584 3.446-.95-1.37a.732.732 0 0 0-1.214.003l-2.49 3.594-.14.199V2.866c0-.282.224-.513.498-.513h11.954zM1.992.813C.893.813 0 1.732 0 2.865v10.268c0 1.133.893 2.054 1.992 2.054h11.954c1.098 0 1.992-.921 1.992-2.054V2.866c0-1.133-.894-2.054-1.992-2.054H1.992zm2.49 6.16a1.494 1.54 0 1 0 0-3.08 1.494 1.54 0 1 0 0 3.08z'/></svg>" label="Сохранить видимую часть страницы как PNG" value="page"/> <menuitem class="menuitem-iconic" image="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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity'><path d='M11.108 8.852c.327 0 .591-.27.591-.602a.596.596 0 0 0-.59-.602c-.327 0-.591.27-.591.602 0 .332.264.602.59.602z'/><path d='M4.808 7.047c0-.665.53-1.203 1.182-1.203h6.3c.652 0 1.18.538 1.18 1.203v4.01c0 .665-.528 1.203-1.18 1.203h-6.3a1.192 1.192 0 0 1-1.182-1.203v-4.01zm1.182 0v3.524l1.639-1.808a.972.972 0 0 1 1.446 0l2.074 2.287-.008.007h1.149v-4.01h-6.3zm2.362 2.691-1.195 1.32h2.39l-1.195-1.32z'/><path d='M3.036 1.833C1.406 1.833.083 3.18.083 4.841v6.818c0 1.661 1.323 3.008 2.953 3.008h9.844c1.631 0 2.953-1.347 2.953-3.008V4.84c0-1.661-1.322-3.008-2.953-3.008H3.036zM1.265 4.841c0-.997.793-1.805 1.771-1.805h9.844c.979 0 1.772.808 1.772 1.805v6.818c0 .997-.793 1.805-1.772 1.805H3.036c-.978 0-1.771-.808-1.771-1.805V4.84z'/></g></svg>" label="Сохранить выбранный элемент страницы как PNG" value="click"/> <menuitem class="menuitem-iconic" image="data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16' fill='context-fill' fill-opacity='context-fill-opacity'><path fill-rule='evenodd' d='M2.63 1.255c-.76 0-1.375.616-1.375 1.375v2.685a.625.625 0 0 1-1.25 0V2.63A2.625 2.625 0 0 1 2.63.005h2.685a.625.625 0 1 1 0 1.25H2.63ZM10.06.63c0-.345.28-.625.625-.625h2.685a2.625 2.625 0 0 1 2.625 2.625v2.685a.625.625 0 1 1-1.25 0V2.63c0-.76-.616-1.375-1.375-1.375h-2.685A.625.625 0 0 1 10.06.63Zm5.31 9.43c.345 0 .625.28.625.625v2.685a2.625 2.625 0 0 1-2.625 2.625h-2.685a.625.625 0 1 1 0-1.25h2.685c.76 0 1.375-.616 1.375-1.375v-2.685c0-.345.28-.625.625-.625ZM2.729 7.3c-.79 0-1.43.64-1.43 1.429v4.542c0 .79.64 1.43 1.43 1.43H7.27c.79 0 1.43-.64 1.43-1.43V8.73c0-.79-.64-1.43-1.43-1.43H2.73ZM0 8.728A2.729 2.729 0 0 1 2.729 6H7.27A2.729 2.729 0 0 1 10 8.729v4.542A2.729 2.729 0 0 1 7.271 16H2.73A2.729 2.729 0 0 1 0 13.271V8.73Z' clip-rule='evenodd'/><path d='M6.9 14.005H2.73a.5.5 0 0 1-.372-.835l2.085-2.317a.5.5 0 0 1 .744 0l2.085 2.317a.5.5 0 0 1-.371.835ZM8 9a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z'/></svg>" label="Сохранить выбранную область страницы как PNG" value="clipping"/> </menugroup> `); var menugroup = df.firstChild; menugroup.setAttribute("context", ""); menugroup.setAttribute("oncommand", "handleCommand(event);"); menugroup.handleCommand = e => { var name = _id + ":DataURLReady"; main = main.replace("%MESSAGE_NAME%", name); var urls = {}, configurable = true, enumerable = true; Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, { configurable, enumerable, get() { var value = `data:;charset=utf-8,({${ encodeURIComponent(main + part) }%0A}).init("${key}")`; Object.defineProperty(urls, key, {configurable, enumerable, value}); return value; }})); var getTabLabel = () => { var label = gBrowser.selectedTab.label; var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " "); return label.substring(0, 50); } var listener = msg => { var fp = makeFilePicker(); fp.init(window.browsingContext, "Сохранить как…", fp.modeSave); fp.appendFilter("", "*.png"); fp.defaultString = getTabLabel() + ".png"; fp.open(res => { if (res == fp.returnCancel || !fp.file) return; var wbp = makeWebBrowserPersist(), args = [ Services.io.newURI(msg.data), document.nodePrincipal, null, null, null, null, fp.file, null ]; var {length} = wbp.saveURI; length >= 9 && splice(args); length == 10 && args.splice(3, 0, null); wbp.saveURI(...args); setTimeout(async lp => { var d = await Downloads.createDownload({ source: "about:blank", target: fp.file }); (await lp).add(d); d.refresh(d.succeeded = true); }, 777, Downloads.getList(Downloads.ALL)); }); } var splice = arr => { var fox74 = parseInt(Services.appinfo.platformVersion) >= 74; var args = [fox74 ? 7 : 2, 0, fox74 ? Ci.nsIContentPolicy.TYPE_IMAGE : null]; (splice = arr => arr.splice(...args))(arr); } messageManager.addMessageListener(name, listener); addDestructor(() => messageManager.removeMessageListener(name, listener)); (menugroup.handleCommand = e => gBrowser.selectedBrowser.messageManager .loadFrameScript(urls[e.target.value], false) )(e); } menuPopup.querySelector('menuitem[label*="ярлык"]').after(df); })(` init(cmd) { cmd.startsWith("c") ? this[cmd].init(this[cmd].parent = this) : this[cmd](); }, capture(win, x, y, width, height) { var canvas = win.document.createElementNS("${xhtmlns}", "canvas"); canvas.width = width; canvas.height = height; var ctx = canvas.getContext("2d"); var tryDraw = ind => { try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")} catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);} } tryDraw(17); sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png")); }, `, { all: `all() { var win = content; this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY); }`, page: `page() { var win = content, doc = win.document, body = doc.body, html = doc.documentElement; var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft; var scrY = (body.scrollTop || html.scrollTop) - html.clientTop; this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight); }`, clipping: `clipping: { handleEvent(e) { if (e.button) return false; e.preventDefault(); e.stopPropagation(); switch(e.type) { case "mousedown": this.downX = e.pageX; this.downY = e.pageY; this.bs.left = this.downX + "px"; this.bs.top = this.downY + "px"; this.body.appendChild(this.box); this.flag = true; break; case "mousemove": if (!this.flag) return; this.moveX = e.pageX; this.moveY = e.pageY; if (this.downX > this.moveX) this.bs.left = this.moveX + "px"; if (this.downY > this.moveY) this.bs.top = this.moveY + "px"; this.bs.width = Math.abs(this.moveX - this.downX) + "px"; this.bs.height = Math.abs(this.moveY - this.downY) + "px"; break; case "mouseup": this.uninit(); break; } }, init() { var win = {}; Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager) .getFocusedElementForWindow(content, true, win); this.win = win.value; this.doc = this.win.document; this.body = this.doc.body; if (!HTMLBodyElement.isInstance(this.body)) { Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService) .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!"); return false; } this.flag = null; this.box = this.doc.createElement("div"); this.bs = this.box.style; this.bs.border = "#0f0 dashed 2px"; this.bs.position = "absolute"; this.bs.zIndex = "2147483647"; this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor; this.body.style.cursor = "crosshair"; ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)]; this.body.style.cursor = this.defaultCursor; this.body.removeChild(this.box); this.parent.capture.apply(this, pos); ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }`, click: `click: { getPosition() { var html = this.doc.documentElement; var body = this.doc.body; var rect = this.target.getBoundingClientRect(); return [ this.win, Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft, Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop, parseInt(rect.width), parseInt(rect.height) ]; }, highlight() { this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false; this.target.style.cssText += "outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;"; }, lowlight() { if (this.orgStyle) this.target.style.cssText = this.orgStyle; else this.target.removeAttribute("style"); }, handleEvent(e) { switch(e.type){ case "click": if (e.button) return; e.preventDefault(); e.stopPropagation(); this.lowlight(); this.parent.capture.apply(this, this.getPosition()); this.uninit(); break; case "mouseover": if (this.target) this.lowlight(); this.target = e.target; this.highlight(); break; } }, init() { this.win = content; this.doc = content.document; ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true)); }, uninit() { this.target = false; ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true)); } }` }); // 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() { self.open = false; }, closeDelay); }; function closeOtherMenus() { return Array.prototype.some.call( self.parentNode.getElementsByTagName("*"), function(node) { if( node != self && XULElement.isInstance(node) // 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; } ); } (desc => { var {set} = desc; desc.set = val => { if (val) delete this.open, this.onmousedown?.({}); set.call(this, val); } Object.defineProperty(this, "open", desc); })(Object.getOwnPropertyDescriptor(MozElements.ButtonBase.prototype, "open")); |
Dumby > 13-08-2024 00:03:21 |
momo2000 пишет
Нет, не стал. Он всё также открывает одну вкладку. Просто если раньше он переопределял открытие, Bug 1898764 - Remove inline event handlers from the context menu Иначе говоря — скрипт теперь открывает свою вкладку, а браузер свою. скрытый текст Выделить код Код:/* item.setAttribute('oncommand', '(' + viewMedia.toString() + ')(event);'); */ item.addEventListener("command", e => { e.stopImmediatePropagation(); viewMedia(e); }); egorsemenov06 пишет
Видимо, это Bug 1898380 Поэтому, пока можно заменить в оператор «равно» ( == ) на |
egorsemenov06 > 13-08-2024 08:32:10 |
Dumby пишет
СПАСИБО ОГРОМНОЕ!!!!!! |
momo2000 > 13-08-2024 09:00:39 |
Dumby скрытый текст |
Dobrov > 16-08-2024 15:50:13 |
Dumby - приветствую! Перестал сохранять картинку при перетаскивании скрипт ClickPicSave.mjs И как там исправить код internalSave для работы на FF 115…129+ ? Вроде в Save по другому сделано… Выделить код Код:{length} = win.internalSave, lfix = length > 15; // фрагмент из ClickPicSave.mjs lfix && args.splice(1, 0, null); //FIX FF113+ win.internalSave(...args); |
momo2000 > 17-08-2024 16:04:58 |
Скрипт обновить закладку, можно чтобы после обновления контекстное меню не закрывалось? Выделить код Код:location == AppConstants.BROWSER_CHROME_URL && (function () { var placesContext = document.getElementById("placesContext"); var separator = document.getElementById("placesContext_openSeparator"); var repBM = document.createXULElement('menuitem'); placesContext.insertBefore(repBM, separator); repBM.id = "placesContext_replaceURL"; repBM.setAttribute("label", "ЗАМЕНИТЬ"); repBM.setAttribute("accesskey", "U"); repBM.addEventListener("command", () => { var itemGuid = placesContext.triggerNode._placesNode.bookmarkGuid; PlacesUtils.bookmarks.update({ guid: itemGuid, url: gBrowser.currentURI, // title: gBrowser.contentTitle }); }); var openBM = document.getElementById("show-other-bookmarks_PersonalToolbar"); placesContext.addEventListener("popupshowing", () => { if (openBM.getAttribute("hidden") == "true") { repBM.setAttribute("hidden", "true"); } else { repBM.removeAttribute("hidden"); } }); })(); |
Dumby > 17-08-2024 18:36:02 |
Dobrov пишет
Никак.
Вроде не требуется, и так нормально. 17-08-2024 18:51:18 momo2000 пишет
К парочке repBM.setAttribute(…); |
momo2000 > 18-08-2024 08:17:38 |
Dumby |
dim222 > 18-08-2024 10:27:45 |
Dumby |
Dumby > 18-08-2024 15:02:24 |
dim222 пишет
Мне эту шляпу взять негде.
У меня вот так нажалось скрытый текст Выделить код Код:content.document.getElementById("cf-turnstile") .firstChild.openOrClosedShadowRoot.firstChild.contentDocument .body.openOrClosedShadowRoot.querySelector("#content input").click(); Это с консоли браузера (не с веб-консоли). |
dim222 > 18-08-2024 15:15:14 |
Dumby пишет
Прошу прощения, не знал что кроме web-консоли есть еще. |
Dumby > 18-08-2024 16:24:34 |
dim222 пишет
Ctrl+Shift+J
Можно и через расширение. CB, например, подойдёт. |
manuk > 21-08-2024 10:38:52 |
Зд. Можно что-то придумать для автоскрытия контекстного меню, когда оно не в фокусе? |
vv07 > 24-08-2024 15:05:35 |
Уважаемые пользователи! Подскажите пожалуйста, где взять (желательно прямую ссылку) рабочий user_chrome_files для r3dfox 129.0.2 и какая версия custom_buttons заработает на последней версии форка r3dfox. Спасибо. |
Dumby > 24-08-2024 18:39:14 |
vv07 пишет
Плохой, весьма плохой пример. Непедагогично.
config.js Выделить код Код:data:image/png;base64,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 Services.appinfo.ID, возможно, было бы лучше.
Та, которую ты скачал в своё время последней. |
manuk > 25-08-2024 04:18:02 |
Dumby, |
vv07 > 25-08-2024 05:09:28 |
Dumby
, что то сродни Китайскому. скрытый текст Выделить код Код:// (async () => { var sandbox = Cu.Sandbox(Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal), { wantComponents: true, sandboxName: "UserChromeFiles", wantGlobalProperties: ["ChromeUtils"], }); Cu.evalInSandbox(` var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); var user_chrome_files_sandbox = { init() { Services.obs.addObserver(this, "domwindowopened"); Services.obs.addObserver(this, "profile-after-change"); }, observe(aWindow, aTopic, aData) { Services.obs.removeObserver(this, "profile-after-change"); this.observe = (window, topic, data) => { if (!(window instanceof Ci.nsIDOMChromeWindow)) return; var docElementInserted = e => { var win = e.target.defaultView; if (win instanceof Ci.nsIDOMChromeWindow) user_chrome.initWindow(win); }; window.windowRoot.addEventListener("DOMDocElementInserted", docElementInserted, true); window.addEventListener("load", e => { window.addEventListener("unload", e => { window.windowRoot.removeEventListener("DOMDocElementInserted", docElementInserted, true); }, { once: true }); }, { once: true }); }; var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("user_chrome_files"); file.append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) { this.removeObs(); return; } try { Components.manager.QueryInterface(Ci.nsIComponentRegistrar) .autoRegister(file); Services.scriptloader.loadSubScript("chrome://user_chrome_files/content/user_chrome.js", globalThis, "UTF-8"); } catch(ex) { this.removeObs(); return; } if (aTopic === "domwindowopened") this.observe(aWindow, aTopic, aData); }, removeObs() { Services.obs.removeObserver(this, "domwindowopened"); }, }; user_chrome_files_sandbox.init(); `, sandbox); })(); // lockPref("xpinstall.signatures.required", false); // lockPref("extensions.experiments.enabled", true); // lockPref("extensions.langpacks.signatures.required", false); PS Скачал другой архив. Внес поправку, но увы Появились только кнопки панелей, а настройки нет Картинка скрытый текст |
vv07 > 25-08-2024 06:49:49 |
Уважаемый unter_officer! Раз для вас понятно и вы смогли исправить Compact Menu, поделитесь пожалуйста кодом для r3dfox-129.0.2 |
Dumby > 25-08-2024 08:21:14 |
vv07 пишет
Абсолютно ни в чём, будь уверен.
А должно бы было быть. Ну, и весь набор, ясен пень, должен быть актуализирован.
Жму на кнопке обозначеной стрелкой, |
unter_officer > 25-08-2024 10:25:19 |
vv07 пишет
скрытый текст Выделить код Код:// // Compact Menu .......... // (async icons => CustomizableUI.createWidget({ id: "ucf_CompactMenu", label: "Compact Menu", tooltiptext: "Compact Menu", // defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { btn.type = "menu"; btn.setAttribute("image", "resource://usercontext-content/briefcase.svg"); var doc = btn.ownerDocument; var menupopup = doc.createXULElement("menupopup"); menupopup.toggleAttribute("context"); btn.ownerGlobal.AutoHideMenubar._setActive = () => {}; btn.setAttribute("popup", menupopup.id = "main-menubar-popup"); var bar = doc.getElementById("main-menubar"); bar.append(menupopup); for(var menu of Array.from(bar.querySelectorAll(":scope > menu"))) { var popup = menu.menupopup; popup.remove(); menu.textContent = menu.renderedOnce = ""; var img = icons[menu.id]; if (img) { menu.className = "menu-iconic", menu.setAttribute("image", img); } menupopup.append(menu); menu.render(); menu.append(popup); menu.disabled = false; } } }))({ "file-menu": "chrome://browser/content/robot.ico", "edit-menu": "chrome://browser/content/robot.ico", "view-menu": "chrome://browser/content/robot.ico", "history-menu": "chrome://browser/content/robot.ico", "bookmarksMenu": "chrome://browser/content/robot.ico", "tools-menu": "chrome://browser/content/robot.ico", "helpMenu": "chrome://browser/content/robot.ico" }); |
vv07 > 25-08-2024 18:39:15 |
unter_officer Вам спасибо большое. |
manuk > 25-08-2024 19:26:59 |
Dumby > 25-08-2024 21:04:58 |
Ещё скриншот скрытый текст Выделить код Код:data:image/png;base64,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 |
manuk > 25-08-2024 21:17:44 |
Dumby, да вы Макаренко, Сухомлинский и Ушинский в одном флаконе. А ещё говорите, что непедагогично... |
vv07 > 26-08-2024 01:37:03 |
manuk пишет
Может быть и так. Спорить не буду, но у меня не работает увы. скрытый текст |
Dobrov > 26-08-2024 08:44:06 |
Dumby — приветствую! Опять (двойка) просьба/вопрос: возможно ли упростить код с совместимостью 115+ ? saveSelToTxt — используется в ucf_hookClicks.js Выделить код Код:var addDestructor = nextDestructor => { //для saveSelToTxt var {destructor} = ucf_custom_script_win["ucf_hookExpert"]; ucf_custom_script_win["ucf_hookExpert"].destructor =()=> { try {destructor();} catch {} nextDestructor(); } } var saveSelToTxt = async () => { //в .txt Всё или Выбранное var {length} = saveURL, splice = length > 9, l11 = length == 11, msgName = F.id + ":Save:GetSelection"; //FIX FF103+ var receiver = msg => {var txt = "data:text/plain,"+ encodeURIComponent(gBrowser.currentURI.spec +"\n\n"+ msg.data); var args = [txt, (document.title || gBrowser.selectedTab.label) +'.txt',null,false,true,null,window.document]; splice && args.splice(5,0,null) && l11 && args.splice(1,0,null); saveURL(...args); } messageManager.addMessageListener(msgName,receiver); addDestructor(() => messageManager.removeMessageListener(msgName,receiver)); var sfunc = fm => { var res,fed,win = {},fe = fm.getFocusedElementForWindow(content,true,win); var sel = (win = win.value).getSelection(); if (sel.isCollapsed){ var ed = fe && fe.editor; if (ed && ed instanceof Ci.nsIEditor) sel = ed.selection, fed = fe; } if(sel.isCollapsed) fed && fed.blur(),docShell.doCommand("cmd_selectAll"), res = win.getSelection().toString(),docShell.doCommand("cmd_selectNone"), fed && fed.focus(); res = res || sel.toString(); /\S/.test(res) && sendAsyncMessage("saveSelToTxt",res); } var url = "data:;charset=utf-8,"+ encodeURIComponent(`(${sfunc})`.replace("saveSelToTxt",msgName)) +'(Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager));'; (saveSelToTxt =()=> gBrowser.selectedBrowser.messageManager.loadFrameScript(url,false))(); } saveSelToTxt(); |
Alex_one > 27-08-2024 16:39:10 |
manuk, |
manuk > 27-08-2024 17:14:06 |
Alex_one, сам спрашивал. Ниже ответили: https://forum.mozilla-russia.org/viewto … 05#p799505. Точно не помню, что-то из этого. У меня путь: r:\Firefox 100.0\profile\chrome\css\buttons\buttons_on_navbar_classic_appearance.css скрытый текст Выделить код Код:/* Firefox userChrome.css tweaks ********************************************************/ /* Github: https://github.com/aris-t2/customcssforfx ************************************/ /****************************************************************************************/ /**************************** ******* BUTTONS ************* ****************************/ /*******************************************/ /* Classic Button ui on navigation toolbar */ /*******************************************/ /* main menu button adjustment */ #PanelUI-button { margin-inline-start: 0px !important; border-inline-start: 0px solid !important; border-image-slice: 0 !important; padding-left: 2px !important; padding-right: 0px !important; } #PanelUI-menu-button { appearance: unset !important; background: unset !important; box-shadow: unset !important; border-image: unset !important; border: unset !important; padding: 2px !important; margin: unset !important; min-width: unset !important; width: unset !important; max-width: unset !important; min-height: unset !important; height: unset !important; max-height: unset !important; } #PanelUI-button #whats-new-menu-button:not([hidden="true"]) { margin-inline-end: 3px !important; } /* back button adjustment */ #nav-bar #back-button .toolbarbutton-icon { border: 0 !important; } /* adjust zoom reset and copy buttons position */ #nav-bar :is(#copy-button,#zoom-reset-button) { margin-inline-start: -1px !important; margin-inline-end: -1px !important; } #nav-bar :is(#edit-controls, #zoom-controls) separator { visibility: collapse !important; } /* classic button style */ #main-window:not([customizing]) #nav-bar .toolbarbutton-1:not(#PlacesChevron)[disabled=true]:is([open],[checked],:hover:active,:active) > .toolbarbutton-icon, #main-window:not([customizing]) #nav-bar .toolbarbutton-1[disabled=true]:is([open],[checked],:hover:active,:active) > .toolbarbutton-text, #main-window:not([customizing]) #nav-bar .toolbarbutton-1[disabled=true]:is([open],[checked],:hover:active,:active) > .toolbarbutton-badge-stack, #nav-bar toolbarbutton[type="menu-button"] > .toolbarbutton-icon, #nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button[open] + .toolbarbutton-menubutton-dropmarker > .dropmarker-icon, #nav-bar .toolbarbutton-1[open] > .toolbarbutton-menubutton-button > .toolbarbutton-icon, #nav-bar .toolbarbutton-1[open] > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon, #nav-bar .toolbarbutton-1:not(#PlacesChevron):not([checked]):not([open]):not(:active) > .toolbarbutton-icon, #nav-bar .toolbarbutton-1:not([checked]):not([open]):not(:active) > .toolbarbutton-text, #nav-bar .toolbarbutton-1:not([checked]):not([open]):not(:active) > .toolbarbutton-badge-stack, #nav-bar .toolbarbutton-1:not([buttonover]):not([open]):not(:active) > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon { background: rgba(151,152,153,.05) linear-gradient(rgba(251,252,253,.95), rgba(246,247,248,.47) 49%, rgba(231,232,233,.45) 51%, rgba(225,226,229,.3)) !important; border-color: rgba(0,0,0,.12) rgba(0,0,0,.19) rgba(0,0,0,.38) !important; box-shadow: 0 0 0 1px rgba(255,255,255,.3) inset, 0 0 0 2px rgba(255,255,255,.1) inset, 0 0 0 1px rgba(0,0,0,.4) inset !important; } #nav-bar .toolbarbutton-1:not([disabled=true]) > .toolbarbutton-menubutton-button[open] + .toolbarbutton-menubutton-dropmarker > .dropmarker-icon, #nav-bar .toolbarbutton-1:not([disabled=true]):is(:hover,[open]) > .toolbarbutton-menubutton-button > .toolbarbutton-icon, #nav-bar .toolbarbutton-1:not([disabled=true]):is(:hover,[open]) > .toolbarbutton-menubutton-dropmarker > .dropmarker-icon, #nav-bar .toolbarbutton-1:not(#PlacesChevron):not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-icon, #nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-text, #nav-bar .toolbarbutton-1:not([disabled=true]):not([checked]):not([open]):not(:active):hover > .toolbarbutton-badge-stack, #nav-bar .toolbarbutton-1:not([buttonover]):not([open]):not(:active):hover > .toolbarbutton-menubutton-dropmarker:not([disabled]) > .dropmarker-icon { background-color: hsla(190,60%,70%,.5) !important; border-color: hsla(190,50%,65%,.8) hsla(190,50%,50%,.8) hsla(190,50%,40%,.8) !important; box-shadow: 0 0 0 1px rgba(255,255,255,.3) inset, 0 0 0 1.5px rgba(255,255,255,.1) inset, 0 0 3.5px hsl(190,90%,80%), 0 0 0 1px rgba(0,0,0,.4) inset !important; transition: background-color .3s ease-in, border-color .2s ease-in, box-shadow .2s ease-in !important; } #nav-bar toolbarbutton:not(#PlacesChevron)[type="menu"][open]:not([disabled]):not(.bookmark-item):not([container="true"]) > .toolbarbutton-icon, #nav-bar toolbarbutton:not(#PlacesChevron)[type="menu-button"]:not([open]):hover:not([disabled]):not(.bookmark-item):active > .toolbarbutton-icon, #nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button:not([disabled=true]):is(:hover:active,:active, [open]) > .toolbarbutton-icon, #nav-bar .toolbarbutton-1[open] > .toolbarbutton-menubutton-dropmarker:not([disabled=true]) > .dropmarker-icon, #nav-bar .toolbarbutton-1:not(#PlacesChevron):not([disabled=true]):is([open],[checked],:hover:active,:active) > .toolbarbutton-icon, #nav-bar .toolbarbutton-1:not([disabled=true]):is([open],[checked],:hover:active,:active) > .toolbarbutton-text, #nav-bar .toolbarbutton-1:not([disabled=true]):is([open],[checked],:hover:active,:active) > .toolbarbutton-badge-stack { background-color: transparent !important; border-color: rgba(0,0,0,.65) rgba(0,0,0,.55) rgba(0,0,0,.5) !important; box-shadow: 0 0 6.5px rgba(0,0,0,.4) inset, 0 0 2px rgba(0,0,0,.4) inset, 0 1px 0 rgba(255,255,255,.4), 0 0 0 1px rgba(0,0,0,.4) inset !important; } #nav-bar toolbarbutton[disabled=true] > .toolbarbutton-icon { opacity: .6 !important; } #nav-bar toolbarbutton[disabled=true]{ opacity: 1.0 !important; } |
Alex_one > 27-08-2024 18:46:49 |
manuk, |
vv07 > 29-08-2024 14:54:51 |
Уважаемый Dumby! Помогите хотя бы с кнопкой Autocopy, для r3dfox 127. Ну не выходит ничего с 129, буду пока оставаться на 127. Выделить код Код:this.closest("toolbarpaletteitem") || (script => { var id = `CB${_id.slice(20)}:Autocopy`, pid = id + "Parent"; var nsvoStr = `Components.utils.import("resource://gre/modules/Services.jsm", {})`; var nsvo = eval(nsvoStr), {Services} = nsvo, parent = nsvo[pid]; if (!parent) { var cid = id + "Child", u = code => "data:," + encodeURIComponent(code); var pref = "CB.Autocopy.settings", topic = "quit-application-granted"; var PREF_ENABLED = 1, PREF_BLINK = 2, PREF_RESET = 4; (parent = nsvo[pid] = { init() { this.readSettings(); if (!this[PREF_ENABLED]) return; this.initChild(); if (this[PREF_RESET]) this.setObserver(true); }, destroy(reason) { var ud = reason[5] == "e"; if (ud || !this.obsAdded) this.saveSettings(); delete nsvo[pid]; if (reason == "delete") Services.prefs.clearUserPref(pref); if (!this[PREF_ENABLED]) return; this.destroyChild(); if (ud && this[PREF_RESET]) this.setObserver(false); }, get processURL() { delete this.processURL; this.frameURL = u(`${nsvoStr}["${cid}"].init(this);`); return this.processURL = u(script.replace(/%ID%/g, cid) .replace("%NSVO%", nsvoStr) .replace("%PREF%", pref) .replace("%PREF_BLINK%", PREF_BLINK) ); }, get frameURLDestroy() { delete this.frameURLDestroy; this.processURLDestroy = u(`${nsvoStr}["${cid}"].forget();`); return this.frameURLDestroy = u(`${nsvoStr}["${cid}"].destroy(this);`); }, initChild() { Services.ppmm.loadProcessScript(this.processURL, true); Services.mm.loadFrameScript(this.frameURL, true); }, destroyChild() { Services.mm.removeDelayedFrameScript(this.frameURL); Services.mm.loadFrameScript(this.frameURLDestroy, false); Services.ppmm.removeDelayedProcessScript(this.processURL); Services.ppmm.loadProcessScript(this.processURLDestroy, false); }, readSettings() { var val = Services.prefs.getIntPref(pref, 3); for(var setting of [PREF_ENABLED, PREF_BLINK, PREF_RESET]) this[setting] = Boolean(val & setting); }, saveSettings() { var settings = 0; for(var setting of [PREF_ENABLED, PREF_BLINK, PREF_RESET]) if (this[setting]) settings += setting; Services.prefs.setIntPref(pref, settings); }, btns: new Set(), register(btn) { this.btns.add(btn); btn._handleClick = this.click; btn.oncontextmenu = this.context; this.setImg(btn, this[PREF_ENABLED]); }, unregister(btn, reason) { this.btns.delete(btn); if (!this.btns.size) this.destroy(reason); }, setImg(btn, state) { (btn.icon || btn.ownerDocument.getAnonymousElementByAttribute( btn, "class", "toolbarbutton-icon" )).src = state ? "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgMBAAQIAAcEBwAIBAcACAQHAAgEBwAIBAcACAQHAAgEBwAIBAcACAMEAQEAAAAAAAAAAAAAAAACAwADAAAAABUnAB9cqgC3a7wB4Gq5Ad1qugHearoB3mq6Ad5qugHearoB3mi4AN1qugHgYrMAxR43AC8AAAAAAAEAAAECAAQAAAQAV6AAprP9Vv/W/qn80/+f/9T/ov/U/6L/1P+i/9T/ov/U/6L/1/+n/9X+pfy3/WL/Y7QAvwEAAQAAAAAAFSgAH1ehAKlyzwD1htgf/YzcJ/2K2yP9i9sk/YvbJf2L2yX9i9sm/YnaIv2b4kP92/21/Nf+qv9quwHdBQkACAAAAQBeqwCzr/tR/8X0j/u+8X//vvJ//77ygP++8oD/vvKA/77yf/+98n7/wvSH/4zcKv+e4kv93v+0/2i5AN0DBwAIBQkACGu8AdzV/af/4v/B/d//u//h/7//4f+//+H/v//h/7//4f+//9/+u//n/8n/w/GK/4zaK/3g/7r/aroC3gMHAAgEBwAIarkC3dX/pf/g/sD93v67/9/+vv/g/r//4P6//+D+v//f/r7/3f66/+T/xv/B8Yb/j9st/eT/w/9qugPeAwcACAQHAAhqugLe2v+w/+j/z/3l/8r/5//N/+f/zv/n/87/5//O/+f/zf/l/sj/7P/W/8Xyj/+Q2y/96f/N/2q6A94DBwAIBAcACGq6At7f/7n/7v/c/ev/1v/t/9n/7f/a/+3/2v/t/9r/7f/Z/+r+1f/y/+P/yPKW/5DbMf3s/9X/aroE3gMHAAgEBwAIaroC3uP/wf/z/+j98P/h//L/5P/z/+X/8//l//P/5f/y/+T/8P7g//j/7v/L8p3/kdsy/fD/3P9rugTeAwcACAQHAAhqugLe5v/J//j/8v31/+r/9v/t//f/7v/3/+//9//u//b/7f/0/un//f/4/87yo/+R2zL98f/f/2q5Bd0DBwAIBAcACGq6At7p/8///P/6/fj/8f/6//T/+v/1//r/9f/6//X/+v/0//f+8P//////0fGo/5PbNf30/+f/a7wE3AQJAAgEBwAIabkC3er/0f/+//79+v/0//v/9//8//j//P/4//z/+P/7//f/+f70///////T8qz/i9go+8P9ef9dqwCzAAACAAUJAAhquwHd7f7a//////z+//39/////f////3////9/////f////39/vz9/////dzzvv5v0AD1VqECqRUnAB8AAAAAAQACAGK0AL/J/Yf/8v7k/O3/1//u/9n/7v/Z/+7/2f/u/9n/7v/Z/+3/1//x/eP8vfxu/1WgAKYAAAUAAQIABAABAAAAAAAAHjcALmGzAMVquwLgarkC3Wq6At5qugLearoC3mq6At5qugLearkC3Wu8AeBbqgC3FScAHwAAAAACAwADAAAAAAAAAAAAAAAAAwQCAQQIAAgEBwAIBAcACAQHAAgEBwAIBAcACAQHAAgEBwAIBAgABwMDAgAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=" : "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAgEDAAQACAcEAAcIBAAHCAQABwgEAAcIBAAHCAQABwgEAAcIBAAHCAMBBAEAAAAAAAAAAAAAAAACAAMDAAAAABUAJx9cAKq3awG84GoBud1qAbreagG63moBut5qAbreagG63mgAuN1qAbrgYgCzxR4ANy8AAAAAAAABAAEAAgQABAAAVwCgprNW/f/Wqf7805///9Si///Uov//1KL//9Si///Uov//16f//9Wl/vy3Yv3/YwC0vwEBAAAAAAAAFQAoH1cAoalyAM/1hh/Y/Ywn3P2KI9v9iyTb/Ysl2/2LJdv9iybb/Yki2v2bQ+L927X9/Neq/v9qAbvdBQAJCAABAABeAKuzr1H7/8WP9Pu+f/H/vn/y/76A8v++gPL/voDy/75/8v+9fvL/wof0/4wq3P+eS+L93rT//2gAud0DAAcIBQAJCGsBvNzVp/3/4sH//d+7///hv///4b///+G////hv///4b///9+7/v/nyf//w4rx/4wr2v3guv//agK63gMABwgEAAcIagK53dWl///gwP793rv+/9++/v/gv/7/4L/+/+C//v/fvv7/3br+/+TG///BhvH/jy3b/eTD//9qA7reAwAHCAQABwhqArre2rD//+jP//3lyv//583//+fO///nzv//587//+fN///lyP7/7Nb//8WP8v+QL9v96c3//2oDut4DAAcIBAAHCGoCut7fuf//7tz//evW///t2f//7dr//+3a///t2v//7dn//+rV/v/y4///yJby/5Ax2/3s1f//agS63gMABwgEAAcIagK63uPB///z6P/98OH///Lk///z5f//8+X///Pl///y5P//8OD+//ju///LnfL/kTLb/fDc//9rBLreAwAHCAQABwhqArre5sn///jy//316v//9u3///fu///37///9+7///bt///06f7//fj//86j8v+RMtv98d///2oFud0DAAcIBAAHCGoCut7pz////Pr//fjx///69P//+vX///r1///69f//+vT///fw/v//////0ajx/5M12/305///awS83AQACQgEAAcIaQK53erR///+/v/9+vT///v3///8+P///Pj///z4///79///+fT+///////TrPL/iyjY+8N5/f9dAKuzAAIAAAUACQhqAbvd7dr+//////z+/f/9/////f////3////9/////f////39/P79/////dy+8/5vAND1VgKhqRUAJx8AAAAAAQIAAGIAtL/Jh/3/8uT+/O3X///u2f//7tn//+7Z///u2f//7tn//+3X///x4/38vW78/1UAoKYABQAAAQACBAAAAQAAAAAAHgA3LmEAs8VqArvgagK53WoCut5qArreagK63moCut5qArreagK53WsBvOBbAKq3FQAnHwAAAAACAAMDAAAAAAAAAAAAAAAAAwIEAQQACAgEAAcIBAAHCAQABwgEAAcIBAAHCAQABwgEAAcIBAAIBwMCAwAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; }, click() { var newState = parent[PREF_ENABLED] = !parent[PREF_ENABLED]; for(var btn of parent.btns) parent.setImg(btn, newState); newState ? parent.initChild() : parent.destroyChild(); if (parent[PREF_RESET]) parent.setObserver(newState); }, context(e) { if (e.ctrlKey || e.shiftKey) return; var btn = e.target; if (btn.btnPopup && e.detail > 1) return btn.btnPopup.hidePopup(); e.preventDefault(); (btn.btnPopup || parent.getPopup(btn)).openPopup(btn, "after_start"); }, getPopup(btn) { var win = btn.ownerGlobal, doc = win.document; var popup = doc.createElementNS(xulns, "menupopup"); popup.setAttribute("onclick", "event.stopPropagation();"); popup.setAttribute("oncommand", "handleCommand(event.target);"); popup.setAttribute("onpopupshowing", "handlePopupshowing();"); popup.menuitems = []; for(var [lab, pref] of win.Object.entries({ "Выделенный текст мигает при автокопировании": PREF_BLINK, "Выключать автокопирование при выходе из браузера": PREF_RESET })) { var menuitem = popup.appendChild(doc.createElementNS(xulns, "menuitem")); menuitem.setAttribute("label", lab); menuitem.setAttribute("type", "checkbox"); menuitem.pref = pref; popup.menuitems.push(menuitem); } popup.handleCommand = menuitem => { var newState = this[menuitem.pref] = menuitem.hasAttribute("checked"); if (!this[PREF_ENABLED]) return; if (menuitem.pref == PREF_BLINK) this.saveSettings(), Services.ppmm.broadcastAsyncMessage(cid + ":FromParent", {blink: newState}); else if (menuitem.pref == PREF_RESET) this.setObserver(newState); } popup.handlePopupshowing = () => { for(var menuitem of popup.menuitems) this[menuitem.pref] ? menuitem.setAttribute("checked", true) : menuitem.removeAttribute("checked"); } return btn.appendChild(btn.btnPopup = popup); }, obsAdded: false, setObserver(set) {this.obsAdded = set ? Services.obs.addObserver(this, topic, false) : Services.obs.removeObserver(this, topic); }, observe() { Services.obs.removeObserver(this, topic); this[PREF_ENABLED] = false; this.saveSettings(); } }).init(); } parent.register(this); addDestructor(reason => parent.unregister(this, reason), parent); })(`(nsvo => (nsvo["%ID%"] = { x: -1, y: -1, down: false, handleEvent(e) {e.button || this[e.type](e);}, mousedown(e) {this.x = e.screenX; this.y = e.screenY, this.down = true;}, mouseup(e) { var {down} = this; this.down = false; if (!down) return; if (e.screenX == this.x && e.screenY == this.y && (e.detail == 1 || e.target.matches( "textarea[disabled],input[disabled],button,select,summary" ))) return; var name = e.originalTarget.nodeName; if (/^(?:(?:xul:)?(?:slider|scrollbarbutton)|resizer)$/.test(name)) return; this.x = this.y = -1; var win = this.getFocusedWin(e.target.ownerGlobal); var sel = win.getSelection(); if (sel.toString()) { (win.docShell || win.document.docShell).doCommand("cmd_copy", null, win); this.blinkEnabled && this.blink(win, e.detail > 1); } }, blinkEnabled: Boolean( Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService) .getIntPref("%PREF%", 3) & %PREF_BLINK% ), blink(win, pause) { if (pause) return win.setTimeout(() => this.blink(win), 100); var sc = (win.docShell || win.document.docShell) .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsISelectionDisplay) .QueryInterface(Components.interfaces.nsISelectionController); sc.setDisplaySelection(sc.SELECTION_OFF); sc.repaintSelection(sc.SELECTION_NORMAL); win.setTimeout(() => { sc.setDisplaySelection(sc.SELECTION_ON); sc.repaintSelection(sc.SELECTION_NORMAL); }, 150); }, getFocusedWin(win) { var focusedWin = {}; var elm = this.fm.getFocusedElementForWindow(win.top, true, focusedWin); return focusedWin.value; }, get fm() { delete this.fm; return this.fm = Components.classes["@mozilla.org/focus-manager;1"] .getService(Components.interfaces.nsIFocusManager); }, count: 0, init(cfmm) { this.count += 1; cfmm.addEventListener("mousedown", this); cfmm.addEventListener("mouseup", this); cfmm.addEventListener("unload", this); if (this.count == 1) this.cpmm.addMessageListener("%ID%:FromParent", this); }, destroy(cfmm) { this.count -= 1; cfmm.removeEventListener("mousedown", this); cfmm.removeEventListener("mouseup", this); cfmm.removeEventListener("unload", this); if (!this.count) this.cpmm.removeMessageListener("%ID%:FromParent", this); }, receiveMessage(msg) { if ("blink" in msg.data) this.blinkEnabled = msg.data.blink; }, unload(e) {this.destroy(e.target);}, forget: () => delete nsvo["%ID%"] }).cpmm = this)(%NSVO%);`); (()=> { var code = ` function handleEvent(e) { if (e.button != 1) return; e.preventDefault(); e.stopPropagation(); sendSyncMessage("response",{},{}); } addEventListener('click', handleEvent, false); function removeListener() { removeMessageListener("destroy", removeListener); removeEventListener("click", handleEvent, false); } addMessageListener("destroy", removeListener); `; var url = "data:," + encodeURIComponent(code); var mm = window.getGroupMessageManager("browsers"); mm.loadFrameScript(url, true); function run(message) { insertText(gClipboard.read()); Services.console.logStringMessage(message.name); } mm.addMessageListener("response", run); addDestructor(() => { mm.removeDelayedFrameScript(url); mm.broadcastAsyncMessage("destroy"); mm.removeMessageListener("response", run); }); })(); // Ставить текст в текстовое поле ............. function insertText(text) { var docShell = "docShell" in document && document.docShell instanceof Ci.nsIDocShell ? document.docShell : window.docShell; function insert(text) { var params = "createCommandParams" in Components.utils ? Cu.createCommandParams() : Components.classes["@mozilla.org/embedcomp/command-params;1"].createInstance(Components.interfaces.nsICommandParams); params.setStringValue("state_data", text); docShell.doCommandWithParams("cmd_insertText", params); }; var br = document.activeElement; !br || br.localName != "browser" || !br.isRemoteBrowser ? insert(text) : br.messageManager.loadFrameScript(`data:,(${insert})(`+encodeURIComponent(text.toSource())+`)`, false, true); }; |
manuk > 29-08-2024 18:00:09 |
vv07 > 30-08-2024 03:05:53 |
manuk |
iG0R > 01-09-2024 23:47:59 |
Уважаемые, форумчане. |
_zt > 03-09-2024 10:58:35 |
iG0R |
iG0R > 03-09-2024 11:16:51 |
_zt |
xrun1 > 03-09-2024 12:22:41 |
iG0R |
iG0R > 03-09-2024 12:50:57 |
xrun1 03-09-2024 12:53:22 |
Dobrov > 03-09-2024 14:38:39 |
iG0R пишет
Показ эскизов зависит от browser.tabs.cardPreview.enabled. iG0R пишет
Уберите ненужные сочетания кликов из ucf_hookClicks.js, в коде всё подробно подписано, строка 244 |
iG0R > 03-09-2024 15:54:14 |
Dobrov пишет
Спасибо за ответ. Dobrov пишет
Просто я пытался искать по тем словосочетаниям, что видны во всплывающей подсказке скрытый текст Выделить код Код:`◉ + Shift Закрыть вкладки слева ◉ ролик +Alt …справа от активной`, [F.C]: //NewTab. SideBar открыт: код нажатий в консоль А в строках, которые соотвествуют сочетаниям кликов, словосочетания разнятся, а рыскать глазами по всему коду... ну, такое себе удовольствие, потому и не нашел: скрытый текст Выделить код Код:[F.B +"s"]: { //<> вкладки колёсиком 2(trg,forward){ gBrowser.tabContainer.advanceSelectedTab(forward ? -1 : 1,true)}, 128(btn){ //СМ if(btn.id == F.C) gBrowser.removeAllTabsBut(gBrowser.selectedTab) else gBrowser.removeTab(TabAct(btn));}, //вкладка под мышью 136(){ gBrowser.removeTabsToTheEndFrom(gBrowser.selectedTab, {animate: true}); }, //C+Alt закрыть вкладки справа 144(){ //C+Shift … слева gBrowser.removeTabsToTheStartFrom(gBrowser.selectedTab, {animate: true}); }, 8(){},16(){},64(){} //выбор }, Правильно ли я нашел участок кода, отвечающий за всплывающую подсказку над вкладкой? скрытый текст Выделить код Код:get [F.B](){ var trg = window.event?.target; //get исполняет код trg.tooltipText = trg.label; }, |
xrun1 > 03-09-2024 23:06:01 |
iG0R пишет
Предположил по словосочетанию на скрине колёсико/ролик. |
Dobrov > 04-09-2024 02:53:27 |
iG0R пишет
Да, но как видно в приведённом коде, над вкладкой подсказка только имя вкладки trg.label Обновил демо-профиль, более 600 изменений в файлах, исправил несколько ошибок, сделал доработки согласно пожеланиям, дополнил встроенную справку (доступную в UserMenu по правому клику на unified-extensions), улучшил совместимость. |
iG0R > 04-09-2024 17:41:21 |
xrun1 пишет
ХитрО Dobrov пишет
Возможно ли добавить в неё Preview страницы, чтобы пользоваться только подсказками из пакета UCF? |
Dobrov > 04-09-2024 23:32:14 |
iG0R пишет
Нет. Предпросмотр вкладок по наведению и по Ctrl+Tab делается браузером. Проси Dumby или ищи расширение, мой скрипт, отображающий подсказки, предназначен для другого — описание в первой строке. |
_zt > 05-09-2024 09:07:56 |
iG0R скрытый текст |
Dobrov > 05-09-2024 14:27:42 |
iG0R здесь есть TST TabPreview.mjs _zt нечего скрывать чужой труд, это не ваш скрипт, вы сами попрошайничаете: |
_zt > 05-09-2024 18:20:38 |
Dobrov |
Den199 > 20-09-2024 09:43:47 |
Можно ли с помощью UCF добавить в контекстное меню, вызываемое кликом правой кнопки мыши на странице, добавить свой пункт? |
Dobrov > 20-09-2024 13:33:21 |
Den199 |
xrun1 > 24-09-2024 16:25:18 |
Dumby, приветствую! 1) 2) из глубин omni.ja 3) строчку закомментарил я, у меня с ней не работает. И что здесь лишнего? |
Dobrov > 25-09-2024 02:16:21 |
xrun1 |
fuchsfan > 25-09-2024 08:42:04 |
xrun1 пишет
Системная очистка не подойдет? http://clipdiary.com/rus/clear-clipboard/ |
Dumby > 25-09-2024 17:16:12 |
xrun1 пишет
Всё ещё склоняюсь избегать обсуждения вопроса "правильности". Способ 1) пишет в буфер два формата Способ 2) очищает буфер полностью. Способ 3) пишет в буфер один формат "utiputi" — два нулевых байта, Services.clipboard.setData( |
xrun1 > 26-09-2024 02:34:17 |
Dobrov пишет
Интересно. Я в этих системах в такие системные дебри работы с буфером не забирался. Всё было проще и утилитарнее: в макОС графика и вёрстка, в линукс скрипты на перле - вытащить данные из баз и конвертнуть в Excel для Windows. Dumby пишет
Я помню. Спасибо. скрытый текст
Скопировал --> очистил 2-м способом. И так 100500+ раз. Буфер чистый, но данные в памяти остались. Т.е. память занята и свободная уменьшается по мере копирования. Мне стало интересно, может ли это привести к падению системы или браузера из-за отсутствия свободной памяти? Чисто гипотетически и теоретически. |
CoolCmd > 27-09-2024 22:09:34 |
в tor browser в файле Tor Browser\Browser\browser\omni.ja\defaults\preferences\000-tor-browser.js из-за locked я не могу в user.js задать эту настройку. менять omni.ja - это плохой вариант. |
Dumby > 28-09-2024 09:32:16 |
CoolCmd пишет
Я попробовал в Tor Browser 13.5.5 добавить в config-prefs.js и мне, как about:config, так и консоль с кода |
CoolCmd > 28-09-2024 11:17:02 |
Dumby спасибо, работает |
xrun1 > 28-09-2024 13:55:14 |
Dumby скрытый текст После применения способов 1), 2) или "nircmd.exe clipboard clear" там чисто. кнопка Выделить код Код:try { CustomizableUI.createWidget({ id: "add-additional-clearbuffer-button", label: "Очистить буфер", tooltiptext: "Очистить буфер обмена", onCreated: btn => btn.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH1gQUDhI4eCDW3QAAAoFJREFUOMuNkl1Ik2EUx//ned69m9pc2nTMULPyI/yoFBLxojWxjLBuwktRRqYEkh9dpmE3kauboIHdRHUl3ZhQYClEhZkhQ1fiCCTLL3Qudc2923yfLpprIGr/q8PhOb9znv85hD10s6M9K9GQWMpIPAIQD2BRVanmRnvHewCQdivutncdYkx8AIShurpGl2JMZVpdvPLQcfc+gFPbAN322wwAA0Q+ES4TidaGK9fjA4EAJEmCEAKMsSS93qB//MTRUFfb1EORTjnERA8EOYlEfYTHbLbmuHAoxMPhMMLhEIxGE1yusVBaWsbgwJv+3LrapsPUbe8yMyZena28VDTwug+NV1tJVVV4PEuQZS00Gg18vnX4fGsAcbinXGGL5Rz6+ntfeJY99YwIjQDStVqZMjOyKBgMIhAIYHr6G+bnZ7Gx4YckafDj5wzW1rywWs/zkZF3qndl+SKASgkkqmy25sRfXg8URcHQ0EtUVFxAgvMLJlvaMBnj0QqAaYAAyCYAv0+XOSQCSgjgsqyDxVIFp/MTxsY+Yq6lDeXWjB03pCqbGH47nCIl7NPD7/cJIkZCCAgh/v43okOD36G4J+DKLQIAFEyNQ5tTCPfxVACARMQWOefmzU0Bzjmys49hddWLLYTinoA2pxAlQkShinsiGjNVVUeJmIiL00Gj0cBkMiM52Rh9sNU5VrE5SZblI73Pn87sNyRlEmN0INkIzjn+V4xz/sDv33AsLMzOFZ8oDWYfzYPb/TU6b8HU+Lai2BxtBfZ7XXeIRG3xydIUszkdn/PypXJrxq4mjo4v/QNETjoXhDOMxDVTa2dBWflBhNeDO46/DRCrZ0AngFt7WND7B7pB9xb6bPwiAAAAAElFTkSuQmCC", onCommand: function(event) { // https://forum.mozilla-russia.org/viewtopic.php?pid=811013#p811013 // 1) // let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); // clipboard.copyString(""); // 2) // Services.clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard); // 3) Services.clipboard.setData( Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable), null, Ci.nsIClipboard.kGlobalClipboard ); var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); alertsService.showAlertNotification("chrome://browser/skin/customizableui/whimsy.png", "Clipboard", "Буфер обмена очищен!"); setTimeout(() => alertsService.closeAlert(), 2000); } }); } catch(e) {} |
unter_officer > 01-10-2024 12:45:28 |
Dumby скрытый текст Выделить код Код:// // Заменить значок Google-поисковика (FF128) ..... // Services.search.getEnginesByExtensionID("google@search.mozilla.org").then(engine => engine[0].getIconURL = async () => "chrome://user_chrome_files/content/icon/google.ico" ); |
Farby > 01-10-2024 13:43:59 |
unter_officer скрытый текст Выделить код Код:```Diff - Services.search.getEnginesByExtensionID("google@search.mozilla.org") + Services.search.getEngineByName("Google") ``` |
Dumby > 02-10-2024 09:50:52 |
xrun1 пишет
О, интересная штука. Показывает даже то, чего не показывает InsideClipboard скрытый текст Ну в смысле скорее показывает наличие некоторых форматов, чем данные.
Ну где же чисто, когда нет Выделить код Код:data:image/png;base64,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 Вот после применения способа 2) — совершенно чисто.
Действительно, торчат DataObject и Ole Private Data Кстати, поискал коммент «This clears the logical clipboard, doesn't remove data». * This empties the clipboard and notifies the clipboard owner. Но что-то мне сомнительно, выглядит как раз наоборот. Выделить код Код:(url => { var {ctypes} = ChromeUtils.importESModule(url); var ole32 = ctypes.open("ole32.dll"); ole32.declare("OleSetClipboard", ctypes.winapi_abi, ctypes.long, ctypes.voidptr_t)(null); ole32.close(); })("resource://gre/modules/ctypes.sys.mjs"); то clipbrd.exe также показывает, что очистка полная. Так вот, там, в PlacesController, в следующей функции, используется способ 3) Ремарка почтенного возраста, например, в Firefox 28 она уже есть, Farby пишет
вместо ExtensionID использовать Name или Id скрытый текст Выделить код Код:(async icon => { await Services.search.promiseInitialized; icon = Promise.resolve(icon); Services.search.getEngineById("google") .wrappedJSObject.getIconURL = () => icon; })("chrome://user_chrome_files/content/icon/google.ico"); В Firefox 131 немного покусали UCF. Bug 1896764 - onViewToolbarsPopupShowing and ToolbarContextMenu should move out of browser.js То есть, создание ToolbarContextMenu переместили в модуль, В результате, в тулбарском контекстном меню У себя пока сделал так, перенёс часть кода из toolbars.js в UcfPrefs.mjs toolbars.js Выделить код Код:/* var newStrFn; if (toolbarcreate) { window.addEventListener("toolbarvisibilitychange", this); window.addEventListener("unload", () => this.destructor(), { once: true }); let oVTC = window.onViewToolbarCommand; if (typeof oVTC === "function") { let strFn = `${oVTC}`, regExr = /(BrowserUsageTelemetry\s*\.\s*recordToolbarVisibility\s*\(\s*toolbarId.+?\)\s*\;)/g; if (regExr.test(strFn)) { newStrFn = `window.onViewToolbarCommand = ${strFn.replace(/^(async\s)?.*?\(/, `$1function ${oVTC.name}(`) .replace(regExr, 'if (!/ucf-additional-.+?-bar/.test(toolbarId)) { $1 }')};`; } } } if (externalToolbars) { let oVTPS = window.onViewToolbarsPopupShowing; if (typeof oVTPS === "function") { let strFn = `${oVTPS}`, regExr = /toolbarNodes\s*=\s*gNavToolbox\s*\.\s*querySelectorAll\s*\(\s*\"\s*toolbar\s*\"\s*\)/g; if (regExr.test(strFn)) { newStrFn = `${newStrFn}${"\n"}window.onViewToolbarsPopupShowing = ${strFn.replace(/^(async\s)?.*?\(/, `$1function ${oVTPS.name}(`) .replace(regExr, 'toolbarNodes = Array.from(document.querySelectorAll("toolbar[toolbarname]"))')};`; } } } if (!newStrFn) return; UcfPrefs.setSubToolbars(newStrFn); ChromeUtils.compileScript("resource://ucf_on_view_toolbars").then(script => script.executeInGlobal(window)); */ toolbarcreate && UcfPrefs.handleToolbars(window, externalToolbars); UcfPrefs.mjs Выделить код Код:/* setSubToolbars(newStrFn) { this.setSubToolbars = () => {}; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution("ucf_on_view_toolbars", Services.io.newURI(`data:charset=utf-8,${encodeURIComponent(newStrFn)}`)); }, */ handleToolbars: function handleToolbars(win, externalToolbars) { if ((handleToolbars.wins ??= new Set()).add(win).size > 1) return; var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var resURL = (code, sfx = "") => { var subst = "ucf_on_view_toolbars" + sfx rph.setSubstitution(subst, Services.io.newURI("data:charset=utf-8," + encodeURIComponent(code))); return "resource://" + subst; } var script = 'window.addEventListener("toolbarvisibilitychange", ucf_toolbars);\n' + 'window.addEventListener("unload", () => ucf_toolbars.destructor(), {once: true});'; var oVTC = win.onViewToolbarCommand; if (typeof oVTC === "function") { var strFn = `${oVTC}`, regExr = /(BrowserUsageTelemetry\s*\.\s*recordToolbarVisibility\s*\(\s*toolbarId.+?\)\s*\;)/g; if (regExr.test(strFn)) { script += `\nwindow.onViewToolbarCommand = ${strFn.replace(/^(async\s)?.*?\(/, `$1function ${oVTC.name}(`) .replace(regExr, 'if (!/ucf-additional-.+?-bar/.test(toolbarId)) { $1 }')};`; } } if (externalToolbars) { var tcm = win.ToolbarContextMenu; var navToolbars = 'gNavToolbox.querySelectorAll("toolbar")'; var oVTPS = tcm.onViewToolbarsPopupShowing || win.onViewToolbarsPopupShowing; if (typeof oVTPS == "function" && (strFn = String(oVTPS)).includes(navToolbars)) { strFn = strFn.replace(navToolbars, 'Array.from(document.querySelectorAll("toolbar[toolbarname]"))'); if (strFn.startsWith("f")) script += "\n" + strFn; else { var key = "temp_ToolbarContextMenu"; var code = `Object.assign(${key}, {${strFn.replace("gNavToolbox", "window: lazy")}});`; globalThis[key] = tcm; ChromeUtils.compileScript(resURL(code, "_mjs")) .then(ps => ps.executeInGlobal(globalThis), Cu.reportError) .finally(() => delete globalThis[key]); } } } var func; ChromeUtils.compileScript(resURL(script)).then( ps => func = win => ps.executeInGlobal(win), ex => func = () => Cu.reportError(ex) ).finally(() => { this.handleToolbars = func; for(var win of handleToolbars.wins) try {func(win);} catch(ex) {Cu.reportError(ex);} }); }, |
unter_officer > 02-10-2024 12:24:40 |
Dumby пишет
Dumby, большое спасибо. |
xrun1 > 02-10-2024 19:04:37 |
Dumby |
unter_officer > 04-10-2024 14:39:53 |
Dumby P.S. Надеюсь, не очень путанно описал свою хотелку. |
Dobrov > 05-10-2024 01:06:53 |
unter_officer - именно делает скрипт ucf_hookClicks.js из демо-профиля. вот код функции, можете вырезать его в ваш скрипт, только подсказка берётся отсюда… |
unter_officer > 06-10-2024 01:59:51 |
Dobrov скрытый текст Выделить код Код:(this.ucfaddbookmark = { init(that) { if (!Services.prefs.getIntPref('bookmarksparentguid', '')) { Services.prefs.setIntPref('bookmarksparentguid', 0); } var starbuttonbox = this.starbuttonbox = document.querySelector("#star-button-box"); if (!starbuttonbox) return; starbuttonbox.addEventListener("click", this, true); that.unloadlisteners.push("ucfaddbookmark"); }, handleEvent(e) { toFav =()=> {with (PlacesUtils.bookmarks) { var url = gBrowser.selectedBrowser.currentURI.spec; search({url}).then(async array => { try {await insert({ url: Services.io.newURI(url), title: (gBrowser.contentTitle || gBrowser.selectedTab.label || url), parentGuid: [() => toolbarGuid, () => menuGuid, () => unfiledGuid][Services.prefs.getIntPref("bookmarksparentguid",0)](), index: DEFAULT_INDEX });} catch(e) { Cu.reportError(e); } }); }} if (e.button != 0) return; e.preventDefault(); e.stopPropagation(); if (e.type != "click") return; toFav(); }, }).init(this); |
Dumby > 06-10-2024 09:54:00 |
unter_officer пишет
Ну так, на четвёрочку. Первый пункт, я так понимаю, относится и к звезде, Второй пункт, видимо, относится к первому пункту, а не вообще «всегда». Третий пункт я просто не понял. Если имеется в виду сохранение А если заказано чтобы звёздочная панелька в состоянии «Изменить закладку» Однако, на всякий случай, задумал, чтобы если звезда активируется Вот, в окно браузера (не в сандбокс). скрытый текст Выделить код Код:(async mod => (await ChromeUtils.compileScript("data:," + encodeURIComponent( `Object.assign(PlacesCommandHook, {${ String(PlacesCommandHook.bookmarkPage) .replace("{", `{\n let e = window.event;\n let mod = ${mod};`) .replace("!info", "(StarUI._isRealNewBookmark = $&) || mod") .replace( "await PlacesUIUtils.defaultParentGuid", `mod ? "${PlacesUtils.bookmarks.toolbarGuid}" : $&` ) }});\n\nObject.assign(StarUI, {${ String(StarUI._handlePopupHiddenEvent) .replace("BookmarkingUI", "this._isRealNewBookmark && $&") }});` ))).executeInGlobal(window))( 'e && (e.target?.id == "Browser:AddBookmarkAs" || !e.ctrlKey && !e.shiftKey)' ); Впрочем, это код вмешательства, а твоя адаптация Dobrov'ского, хоть и весьма кривовата, но это всё таки скорее код созидания. |
unter_officer > 06-10-2024 12:03:48 |
Dumby пишет
Dumby |
unter_officer > 09-10-2024 18:02:53 |
Dumby, поправьте пожалуйста кнопочку для FF 131. скрытый текст Выделить код Код:// // Сохранять изображение без запроса в указанную папку из контекстного меню ..... // try { (this.contextsaveimg = { path: "E:\\Download", init(that) { var contextMenu = this.contextMenu = document.querySelector("#contentAreaContextMenu"); if (!contextMenu) return; contextMenu.addEventListener("popupshowing", this); that.unloadlisteners.push("contextsaveimg"); }, destructor() { this.contextMenu.removeEventListener("popupshowing", this); }, handleEvent(e) { if (!gContextMenu.onImage || gContextMenu.webExtBrowserType === "popup") return; var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("id", "ucf_SaveImg"); menuitem.setAttribute("label", "Сохранить изображение в папку: " + this.path); menuitem.setAttribute("oncommand", "saveImg();"); menuitem.className = "menuitem-iconic"; menuitem.setAttribute("image", "data:image/x-icon;base64,....."); (this.contextMenu.querySelector("#context-sendimage") || this.contextMenu.lastElementChild).after(menuitem); this.handleEvent = () => menuitem.hidden = (!gContextMenu.onImage || gContextMenu.webExtBrowserType === "popup"); menuitem.saveImg = () => { var p = Services.prefs; var data = Object.assign(Object.create(null), { "browser.download.folderList": { type: "Int", set: 2 }, "browser.download.useDownloadDir": { type: "Bool", set: true }, "browser.download.dir": { type: "String", set: this.path } }); var save = eval(`(function ${gContextMenu.saveMedia})`.replace( "\n false, // don't", "\n true, //" )); (menuitem.saveImg = () => { for(var pref in data) { var obj = data[pref], meth = `et${obj.type}Pref`; obj.val = p.prefHasUserValue(pref) ? p["g" + meth](pref) : null; p["s" + meth](pref, obj.set); } try {save.call(gContextMenu);} finally { for(var pref in data) data[pref].val === null ? p.clearUserPref(pref) : p[`set${data[pref].type}Pref`](pref, data[pref].val); } })(); } } }).init(this); } catch(e) { Cu.reportError(e); } |
Farby > 10-10-2024 09:46:59 |
unter_officer |
unter_officer > 10-10-2024 10:01:17 |
Farby, спасибо. |
fuchsfan > 12-10-2024 07:52:42 |
unter_officer пишет
Кстати, место сохранения закладок по умолчанию можно назначить средствами браузера. |
doud > 21-10-2024 14:44:39 |
Уважаемые Гуру! В 128 версии перестал работать скрипт "вернуть в адресную строку значок "Копировать ссылку" (async (url, pa = ChromeUtils.import(url).PageActions) => pa.addAction(new pa.Action({ title: "Копировать ссылку", iconURL: "chrome://global/skin/icons/link.svg", id: "ucf-copyURL", var show = eval(`(function ${e.view.ConfirmationHint.show})`); (this.onCommand = e => { var anchor = win.BrowserPageActions.panelAnchorNodeForAction(this, e); |
Dumby > 21-10-2024 15:32:36 |
doud пишет
Консоль что ли не подруга? (async (url, pa = ChromeUtils.importESModule(url).PageActions) => pa.addAction(new pa.Action({ |
doud > 21-10-2024 16:47:52 |
Dumby скрытый текст (async (url, pa = ChromeUtils.importESModule(url).PageActions) => pa.addAction(new pa.Action({ title: "Копировать ссылку", iconURL: "chrome://global/skin/icons/link.svg", id: "ucf-copyURL", var show = eval(`(function ${e.view.ConfirmationHint.show})`); (this.onCommand = e => { var anchor = win.BrowserPageActions.panelAnchorNodeForAction(this, e); |
Farby > 21-10-2024 17:34:08 |
Dumby скрытый текст Выделить код Код:if (settings.hideThatStupidGreenTooltipOnSaving) { // document.querySelector('#confirmation-hint').style.display = 'none'; // Null since FF78 or 79 because of “lazy load” (see browser.js) let hint = document.querySelector('#confirmation-hint') || ConfirmationHint._panel; // This creates the hint in FF78-79 if missed or just gets it in older versions hint.style.display = 'none'; } Конечно ничего не видно... |
Dumby > 21-10-2024 17:46:56 |
doud пишет
Вот спецом скачал и собрал 128.3.1esr Всё работает скрытый текст Выделить код Код:data:image/png;base64,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 Следует ли мне знать что-то ещё, чтобы воспроизвести это твоё «Не работает..»? Farby пишет
Само звено тоже не видно? |
doud > 21-10-2024 17:55:02 |
Dumby |
Farby > 21-10-2024 18:10:47 |
Dumby пишет
Звено на месте, копируется, но пока стиль не поправил фразы "Скопировано в буфер обмена!" небыло |
Dumby > 21-10-2024 19:42:19 |
doud пишет
128 на Win7? Farby пишет
Вроде как, это называется: « |
doud > 21-10-2024 20:02:56 |
Dumby https://github.com/adeii/supermium-portable/releases/tag/F127 |
Dumby > 22-10-2024 12:06:14 |
doud пишет
Скачал Firefox-portable-128.0-x86-win7.7z
Хмм, странно. скрытый текст Выделить код Код:data:image/png;base64,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 И, я глупость написал, что добавлять в custom_script_win.js Конечно же код для сандбокса, то есть для custom_script.js Следует убедиться, что в настройках UCF стоит галка Enable scripts: [✔] In the background [System Principal] Вобщем, добавил ожидание promiseAllWindowsRestored и вызов init() скрытый текст Выделить код Код://(async (url, pa = ChromeUtils.importESModule(url).PageActions) => pa.addAction(new pa.Action({ (async (url, pa = ChromeUtils.importESModule(url).PageActions) => await ChromeUtils.importESModule("resource:///modules/sessionstore/SessionStore.sys.mjs") .SessionStore.promiseAllWindowsRestored || pa.init() || pa.addAction(new pa.Action({ И появилась и звезда, и работоспособное звено с хинтом. скрытый текст Выделить код Код:data:image/png;base64,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 Иначе говоря, получается, |
doud > 22-10-2024 14:26:46 |
Dumby |
Viatcheslav > 28-10-2024 15:02:29 |
Farby пишет
115.15, текст скрипта скрытый текст // URL copy button in the address bar (async (url, pa = ChromeUtils.import(url).PageActions) => pa.addAction(new pa.Action({ title: "Копировать ссылку", id: "ucf-copyURL", (this.onCommand = e => { var anchor = win.BrowserPageActions.panelAnchorNodeForAction(this, e); Кнопка копирования в адресной строке есть, после нажатия на неё https://s1.hostingkartinok.com/uploads/images/2024/10/6526712a1a2426cc57f7bb129962718a.png Это скриншот текста скрипта с номерами строк https://s1.hostingkartinok.com/uploads/images/2024/10/e62a6902c7b375f1ba23311f2b2ae143.png Подскажите, пожалуйста, чего надо поправить в коде скрипта, |
unter_officer > 28-10-2024 23:17:51 |
Viatcheslav скрытый текст Выделить код Код:// (async (url, pa = ChromeUtils.import(url).PageActions) => pa.addAction(new pa.Action({ title: "Копировать ссылку", tooltip: "Копировать ссылку", iconURL: "chrome://global/skin/icons/link.svg", id: "ucf-copyURL", pinnedToUrlbar: true, onCommand(e) { var MozXULElement = {insertFTLIfNeeded() {}}; var document = {l10n: {setAttributes: msg => msg.textContent = "Скопировано в буфер обмена!"}}; var show = eval(`(function ${e.view.ConfirmationHint.show})`); var helper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); (this.onCommand = e => { var win = e.view; var uri = win.gBrowser.selectedBrowser.currentURI; helper.copyString(win.gURLBar.makeURIReadable(uri).displaySpec); var anchor = win.BrowserPageActions.panelAnchorNodeForAction(this, e); show.call(win.ConfirmationHint, anchor, "", {event: e, hideArrow: true}); })(e); } })))("resource:///modules/PageActions.jsm"); |
Viatcheslav > 29-10-2024 07:48:36 |
unter_officer пишет
О, замечательно, благодарствую |
doud > 11-11-2024 18:53:26 |
Уважаемые Гуру! Был такой скрипт для открытия Findbar двойным щелчком СКМ. На новых версиях уже не работает. Что надо исправить? скрытый текст addEventListener("click", async e => { if (e.button != 1 || e.detail != 2) return; var findbar = gFindBar; }, false, gBrowser.tabpanels || 1); |
vassemm > 11-11-2024 22:55:20 |
Добрый день, уважаемые! скрытый текст Выделить код Код:(this.autohidesidebar = { events: ["dragenter", "drop", "dragexit", "MozLayerTreeReady"], init() { var sidebar = this.sidebar = document.querySelector("#sidebar-box"); if(!sidebar) return; ["dragenter", "drop", "dragexit", "mouseenter", "mouseleave"].forEach((type) => { sidebar.addEventListener(type, this, false); }); ucf_custom_script_win.unloadlisteners.push("autohidesidebar"); }, destructor: function() { var sidebar = this.sidebar; ["dragenter", "drop", "dragexit", "mouseenter", "mouseleave"].forEach((type) => { sidebar.removeEventListener(type, this, false); }); }, handleEvent: function(event) { this[event.type](event); }, click: function(event) { var sidebar = this.sidebar; var boxObj = sidebar.getBoundingClientRect(), boxScrn = !sidebar.boxObject ? sidebar : sidebar.boxObject; if (event.screenY < boxScrn.screenY || event.screenY > boxScrn.screenY + boxObj.height || event.screenX < boxScrn.screenX || event.screenX > boxScrn.screenX + boxObj.width) { window.removeEventListener("click", this, false); this.listener = false; if (sidebar.hasAttribute("sidebardrag")) sidebar.removeAttribute("sidebardrag"); } }, mouseenter: function() { var sidebar = this.sidebar; if (!sidebar.hasAttribute("sidebardrag") && !this.listener) { clearTimeout(this.timer); var delay = this.delay || (this.delay = +getComputedStyle(sidebar).getPropertyValue("transition-delay").replace(/[^0-9\.]/g, "") * 1000); this.timer = setTimeout(() => { sidebar.setAttribute("sidebardrag", "true"); this.listener = true; window.addEventListener("click", this, false); }, delay); } }, mouseleave: function() { clearTimeout(this.timer); }, dragenter: function() { if (!this.sidebar.hasAttribute("sidebardrag")) this.sidebar.setAttribute("sidebardrag", "true"); }, drop: function() { if (this.sidebar.hasAttribute("sidebardrag")) this.sidebar.removeAttribute("sidebardrag"); }, dragexit: function(event) { var sidebar = this.sidebar; var boxObj = sidebar.getBoundingClientRect(), boxScrn = !sidebar.boxObject ? sidebar : sidebar.boxObject; if ((!event.relatedTarget || event.screenY <= (boxScrn.screenY + 5) || event.screenY >= (boxScrn.screenY + boxObj.height - 5) || event.screenX <= (boxScrn.screenX + 5) || event.screenX >= (boxScrn.screenX + boxObj.width - 5)) && sidebar.hasAttribute("sidebardrag")) sidebar.removeAttribute("sidebardrag"); } }).init(this); Выделить код Код:@-moz-document url("chrome://browser/content/browser.xhtml") { #sidebar-box { --v-sidebar-min-width: 2px; --v-sidebar-min-width-normal: 5px; --v-sidebar-max-width: 26em; --v-sidebar-transition-delay-show: .2s; --v-sidebar-transition-delay-hide: .0s; --v-sidebar-transition-duration: .1s; /* ********************************************** */ position: relative !important; z-index: 2 !important; min-width: var(--v-sidebar-max-width) !important; width: var(--v-sidebar-max-width) !important; max-width: var(--v-sidebar-max-width) !important; overflow: hidden !important; opacity: 0 !important; --v-sidebar-margin-max-width: calc(-1 * var(--v-sidebar-max-width)); --v-sidebar-transform-locale-dir: -1; --v-sidebar-transform-locale-dir-visible: 1; margin-inline-start: 0 !important; margin-inline-end: var(--v-sidebar-margin-max-width) !important; border: none !important; border-inline-end: 1px solid var(--sidebar-border-color, ThreeDShadow) !important; transform: translateX(calc(var(--v-sidebar-transform-locale-dir) * (var(--v-sidebar-max-width) - var(--v-sidebar-min-width)))) !important; transition-timing-function: linear, step-start !important; transition-delay: var(--v-sidebar-transition-delay-hide), calc(var(--v-sidebar-transition-delay-hide) + var(--v-sidebar-transition-duration)) !important; transition-duration: var(--v-sidebar-transition-duration), 0s !important; transition-property: transform, opacity !important; } #sidebar-box[positionend="true"] { margin-inline-start: var(--v-sidebar-margin-max-width) !important; margin-inline-end: 0 !important; border-inline-start: 1px solid var(--sidebar-border-color, ThreeDShadow) !important; border-inline-end: none !important; } #sidebar-box[positionend="true"]:-moz-locale-dir(ltr), #sidebar-box:not([positionend="true"]):-moz-locale-dir(rtl) { --v-sidebar-transform-locale-dir: 1; --v-sidebar-transform-locale-dir-visible: -1; } :root[v_vertical_bar_autohide][v_vertical_bar_sidebar="true"] #sidebar-box:not(:hover,[sidebardrag]), :root[v_vertical_bar_autohide]:not([v_vertical_bar_sidebar]) #sidebar-box:not(:hover,[sidebardrag]) { transition-delay: 0s, var(--v-sidebar-transition-duration) !important; } :root[sizemode="normal"] #sidebar-box { --v-sidebar-min-width: var(--v-sidebar-min-width-normal) !important; } #sidebar-box:hover, #sidebar-box[sidebardrag] { transform: translateX(0px) !important; opacity: 1 !important; transition-delay: var(--v-sidebar-transition-delay-show) !important; } :root[v_vertical_bar_visible][v_vertical_bar_start="true"] #sidebar-box:not([positionend="true"]), :root[v_vertical_bar_visible][v_vertical_bar_start="false"] #sidebar-box[positionend="true"] { transform: translateX(calc(var(--v-sidebar-transform-locale-dir-visible) * var(--v-vertical_bar_width, 0px))) !important; opacity: 1 !important; transition-delay: 0s !important; } #browser > #sidebar-splitter { display: none !important; } #sidebar-box > #sidebar { min-width: 0 !important; width: auto !important; max-width: none !important; -moz-box-flex: 1 !important; } } |
Farby > 12-11-2024 09:16:51 |
vassemm auto_hide_sidebar.css |
vassemm > 12-11-2024 15:38:13 |
Farby пишет
Вы мой спаситель. |
rubel > 15-11-2024 10:08:56 |
Как вытащить отдельную кнопку Перезагрузка браузера из UCF или из расширения add_toolbar_buttons ? |
Farby > 15-11-2024 10:30:56 |
rubel ucf-appmenu-restart-button Выделить код Код:// ==UserScript== // @name MENU`s Restart Items // @author Vitaliy V. // @include main // @note https://forum.mozilla-russia.org/viewtopic.php?pid=785107#p785107 // @shutdown window.menusrestartitems.uninit(); // ==/UserScript== location.href.startsWith("chrome://browser/content/browser.x") && (this.menusrestartitems = { init(that) { var btnClass = "ucf-appmenu-restart-button", muimID = "ucf_menu_FileRestartItem", rLocale = Services.locale.requestedLocale.startsWith("ru"), rLabel = rLocale ? "Перезапуск": "Restart", rToolTiptext = rLocale ? "ЛКМ: Перезапустить приложение\nСКМ: Перезапустить без дополнений\nПКМ: Перезапустить и заново создать кэш быстрого запуска" : "L: Restart the application\nM: Restart without add-ons\nR: Restart and recreate the quick start cache.", ucf_script = (window.ucf_custom_script_win == that) ? "ucf_custom_script_win" : (window.ucf_custom_script_all_win == that) ? "ucf_custom_script_all_win" : "window"; var abtns = document.querySelector("template#appMenu-viewCache")?.content.querySelectorAll("#appMenu-quit-button, #appMenu-quit-button2") || document.querySelectorAll("#appMenu-quit-button"); for (let abtn of abtns) { let frag = MozXULElement.parseXULToFragment(`<toolbarbutton/>`); let btn = frag.firstElementChild; btn.id = muimID + '1'; btn.className = `${btnClass} subviewbutton${abtn.classList.contains("subviewbutton-iconic") ? "" : " subviewbutton-iconic"}`; btn.setAttribute("label", rLabel); btn.setAttribute("tooltiptext", rToolTiptext); btn.setAttribute("shortcut", "Ctrl+Alt+Q"); btn.setAttribute("onclick", `${ucf_script}.menusrestartitems.restart_mozilla(event)`); abtn.before(frag); } var aftermuim = document.querySelector("#menu_FilePopup #menu_FileQuitItem"); if (aftermuim) { let muim = document.createXULElement("menuitem"); muim.id = muimID; muim.className = "menuitem-iconic"; muim.setAttribute("label", rLabel); muim.setAttribute("tooltiptext", rToolTiptext); muim.setAttribute("acceltext", "Ctrl+Alt+Q"); muim.setAttribute("context", ""); muim.setAttribute("onclick", `${ucf_script}.menusrestartitems.restart_mozilla(event)`); aftermuim.before(muim); } var style = "data:text/css;charset=utf-8," + encodeURIComponent(` .${btnClass}.subviewbutton-iconic, #${muimID} { list-style-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M11.4 5.6h4v-4M14.8 5C14.1 3.5 12 .6 8 .6S.6 4 .6 8 4 15.4 8 15.4s6.3-2.9 7-5'/></svg>") !important; } .${btnClass}.subviewbutton-iconic .toolbarbutton-icon, #${muimID} .menu-iconic-icon { -moz-context-properties: fill !important; fill: color-mix(in srgb, currentColor 20%, #f38525) !important; } `); try { windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); } catch (e) {} window.addEventListener("keydown", this); that.unloadlisteners?.push("menusrestartitems"); }, restart_mozilla(e) { if (e.button == 0) this._restart_mozilla(); else if (e.button == 1) e.view.safeModeRestart(); else if (e.button == 2) this._restart_mozilla(true); }, _restart_mozilla(nocache = false) { var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart"); if (cancelQuit.data) return false; if (nocache) Services.appinfo.invalidateCachesOnRestart(); var restart = Services.startup; restart.quit(restart.eAttemptQuit | restart.eRestart); }, handleEvent(e) { if (e.code == "KeyQ" && e.ctrlKey && e.altKey) this._restart_mozilla(); }, destructor() { window.removeEventListener("keydown", this); }, uninit() { var muimID = "ucf_menu_FileRestartItem"; this.destructor(); document.getElementById(muimID).remove(); document.getElementById(muimID + "1").remove(); delete menusrestartitems; } }).init(this); |
rubel > 15-11-2024 15:41:14 |
Farby |
Dumby > 16-11-2024 12:36:50 |
doud пишет
О, я смотрю на руборде не поленились заняться Тогда можно попробовать заменить click на mousedown. Код не для CB (а то приведённый выглядит именно так). скрытый текст Выделить код Код:(async () => { var dblmmd = async () => { var findbar = gFindBar; if (findbar) { if (!findbar.hidden) return //findbar.close(); } else { findbar = await gFindBarPromise; //await new Promise(setTimeout); } findbar.onFindCommand(); } gBrowser.tabpanels.addEventListener( "mousedown", e => e.button == 1 && e.detail == 2 && dblmmd() ); })(); |
doud > 16-11-2024 16:06:35 |
Dumby скрытый текст addEventListener("popuphiding", async e => { if (e.target.id != "autoscroller") return; var findbar = gFindBar; |
Dumby > 16-11-2024 20:00:06 |
doud пишет
Охотно верю. Но работал чуть иначе. В CB такой код добавляет слушатель клика а в UCF он добавляет слушатель клика
Вариант немного странный. Чтобы работало нужен включённый autoscroller, Но вот, допустим, начинаем обычную autoscroll-сессию, скроллим сколько надо, |
doud > 16-11-2024 21:17:44 |
Dumby Dumby пишет
Согласен |
dinn > 17-11-2024 12:33:46 |
Dumby пишет
А если бы не получилось, в том числе и через mouseup, то какие есть альтернативы? Не факт, что нативную функцию preventClickEvent() ваяли только для авто скролла и с каким-то странным пояснением; |
Dobrov > 17-11-2024 15:15:03 |
Всем привет! Вопрос: как из JS-кода показать в проводнике последний загруженный файл ? |
Dumby > 19-11-2024 12:45:31 |
doud пишет
Это довольно заморочно. Надо полагать, что чем-то не устраивает "новый" UCF. Так что же не так с новым? dinn пишет
скрытый текст
Что значит «если бы не получилось»? А если, и в итоге не получилось,
Что значит «ваяли только»? Это типа А ваяли именно для автоскролла. Bug —> part 2 —> webidl diff.
Что значит «запустить»? Запустить на чём? Так что, либо разворачивать что-то в контентских процессах, Вот, допустим, попробуем вызов автоскроллера по Alt+ЛКМ. Выделить код Код:(() => { var callHandleEvent = (makeEvent, ids, x, y) => { for(var id of ids) { var actor = WindowGlobalChild .getByInnerWindowId(id).getActor("AutoScroll"); var win = actor.document.ownerGlobal; if (win.windowRoot.ownerGlobal == win) { // ??? var r = win.devicePixelRatio; x /= r; y /= r; } var trg = win.windowUtils.elementFromPoint( x - win.mozInnerScreenX, y - win.mozInnerScreenY, true, false ); if (trg && !trg.matches("iframe,frame")) { actor.handleEvent(makeEvent(trg, x, y)); break; } } } var makeEvent = (trg, x, y) => ({ button: 1, screenX: x, screenY: y, isTrusted: true, type: "mousedown", originalTarget: trg, composedTarget: trg, view: trg.ownerGlobal, clickEventPrevented() {} }); var prfx = "data:,(" + encodeURIComponent( callHandleEvent + ")(" + makeEvent + ", " ); var loadScripts = (bbc, x, y) => { var map = new Map(); for(var bc of bbc.getAllBrowsingContextsInSubtree()) { var cwg = bc.currentWindowGlobal; if (!cwg) continue; var id = cwg.innerWindowId; var pid = cwg.osPid, arr = map.get(pid); arr ? arr.push(id) : map.set(pid, [id]); } var {ppmm} = Services; for(var ind = 0, count = ppmm.childCount; ind < count; ind++) { var pmm = ppmm.getChildAt(ind); var ids = map.get(pmm.osPid); ids && pmm.loadProcessScript(prfx + `[${ids}], ${x}, ${y});`, false); } } gBrowser.tabpanels.addEventListener("click", e => { if (e.button || !e.altKey || e.ctrlKey || e.shiftKey) return; var br = gBrowser.selectedBrowser; if (!br.matches(":hover")) return; var x = e.screenX, y = e.screenY; if (br.isRemoteBrowser) { var r = window.devicePixelRatio; loadScripts(br.browsingContext, x *= r, y *= r); } else e.target.ownerGlobal .windowGlobalChild.getActor("AutoScroll") .handleEvent(makeEvent(e.originalTarget, x, y)); }); })(); Dobrov пишет
Список можно получить так (если вместе с приватными) Объект Downloads есть в окне браузера. Выражение вернёт копию массива объектов Download Возможно, надо отфильтровать от каких-нибудь Последний загруженный — наверно, у которого endTime Показать в проводнике файл — nsIFile.reveal() |
Dobrov > 19-11-2024 13:31:58 |
Dumby пишет
Спасибо! |
Dumby > 19-11-2024 17:02:07 |
Dobrov скрытый текст Выделить код Код:(async () => { var list = await Downloads.getList(Downloads.ALL); list.addView({ onDownloadChanged(download) { if (!download.succeeded) return; console.log("download.succeeded", download); list.removeView(this); FileUtils.File(download.target.path).reveal(); } }); })(); |
Dobrov > 19-11-2024 18:42:36 |
Dumby |
Garalf > 25-11-2024 20:34:36 |
Dobrov |
Northtech > 26-11-2024 11:18:46 |
Кнопка Firefox View перестала работать на вертикальной панели add_toolbar_buttons.2024.10.14.21 в firefox 133. Если её переместить например в навигационную панель, то работает. |
kokoss > 26-11-2024 12:18:21 |
Garalf пишет
У vassemm есть! |
Garalf > 26-11-2024 13:26:46 |
kokoss |
Dumby > 26-11-2024 16:19:08 |
Northtech пишет
Вот, кстати, да. И не только она. Я пользуюсь только верхним тулбаром, Короче, видимо, эта песня (баг) Вобщем, надо как-то пробросить это добро |
kokoss > 26-11-2024 18:31:22 |
Garalf пишет
Какую версию UCF используйте ? |
Dumby > 27-11-2024 00:58:43 |
Northtech Dumby пишет
Попытка запилить временный фикс-код для custom_script_win.js скрытый текст Выделить код Код:(async url => { var bars = document.querySelectorAll( "#ucf-additional-vertical-bar, #ucf-additional-bottom-bar" ); if (!bars.length) return; var src = Cu.readUTF8URI(Services.io.newURI(url)); for(var info of Services.els.getListenerInfoFor(gNavToolbox)) { var listener = info.listenerObject; if (typeof listener == "function" && src.includes(String(listener))) for(var bar of bars) bar.addEventListener(info.type, listener, info.capturing); } })("chrome://browser/content/navigator-toolbox.js"); |
Garalf > 27-11-2024 06:41:35 |
kokoss |
Northtech > 27-11-2024 08:17:44 |
Dumby |
kokoss > 27-11-2024 08:44:16 |
Garalf пишет
Обновите версию UCF до актуальной_2024-10-31, и так проверьте. |
egorsemenov06 > 28-11-2024 16:19:52 |
Обновил UCF до версии 2024-11-27 перестала работать кнопка перезагрузки в appmenu скрытый текст Выделить код Код://Кнопка перезагрузки (this.menusrestartitems = { init(that) { var btnClass = "ucf-appmenu-restart-button", muimID = "ucf_menu_FileRestartItem", ucf_script = (window.ucf_custom_script_win == that) ? "ucf_custom_script_win" : "ucf_custom_script_all_win"; var abtns = document.querySelector("template#appMenu-viewCache")?.content.querySelectorAll("#appMenu-quit-button, #appMenu-quit-button2") || document.querySelectorAll("#appMenu-quit-button"); for (let abtn of abtns) { let frag = MozXULElement.parseXULToFragment(`<toolbarbutton/>`); let btn = frag.firstElementChild; btn.id = btnClass; btn.className = "subviewbutton subviewbutton-iconic"; btn.setAttribute("label", "Перезапуск"); btn.setAttribute("tooltiptext", "ЛКМ: Перезапустить приложение\nСКМ: Перезапустить без дополнений\nПКМ: Перезапустить и заново создать кэш быстрого запуска"); btn.setAttribute("shortcut", "Ctrl+Alt+Q"); btn.setAttribute("onclick", `${ucf_script}.menusrestartitems.restart_mozilla(event)`); abtn.before(frag); } var aftermuim = document.querySelector("#menu_FilePopup #menu_FileQuitItem"); if (aftermuim) { let muim = document.createXULElement("menuitem"); muim.id = muimID; muim.className = "menuitem-iconic"; muim.setAttribute("label", "Перезапуск"); muim.setAttribute("tooltiptext", "ЛКМ: Перезапустить приложение\nСКМ: Перезапустить без дополнений\nПКМ: Перезапустить и заново создать кэш быстрого запуска"); muim.setAttribute("acceltext", "Ctrl+Alt+Q"); muim.setAttribute("context", ""); muim.setAttribute("onclick", `${ucf_script}.menusrestartitems.restart_mozilla(event)`); aftermuim.before(muim); } var style = "data:text/css;charset=utf-8," + encodeURIComponent(` #${btnClass}.subviewbutton-iconic, #${muimID} { list-style-image: url("chrome://global/skin/icons/reload.svg") !important; } #${btnClass}.subviewbutton-iconic .toolbarbutton-icon, #${muimID} .menu-iconic-icon { -moz-context-properties: fill !important; fill: #e31b5d !important; } `); try { windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); } catch (e) {} window.addEventListener("keydown", this); that.unloadlisteners.push("menusrestartitems"); }, restart_mozilla(e) { if (e.button == 0) this._restart_mozilla(); else if (e.button == 1) e.view.safeModeRestart(); else if (e.button == 2) this._restart_mozilla(true); }, _restart_mozilla(nocache = false) { var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart"); if (cancelQuit.data) return false; if (nocache) Services.appinfo.invalidateCachesOnRestart(); var restart = Services.startup; restart.quit(restart.eAttemptQuit | restart.eRestart); }, handleEvent(e) { if (e.code == "KeyQ" && e.ctrlKey && e.altKey) this._restart_mozilla(); }, destructor() { window.removeEventListener("keydown", this); } }).init(this); скрытый текст Выделить код Код:(async ( id = "ucf_sidebar_tabs_button", label = "Sidebar Tabs", tooltiptext = "ЛКМ: Открыть / Закрыть\nControl + ЛКМ: Отключить / Включить\nСКМ: Отключить / Включить\nПКМ: Переключить AutoHide", img = "resource://ucf_sidebar_tabs", pref = "extensions.ucf.sidebar_tabs.auto_hide", sidebar_tabs = { get style() { delete this.style; return this.style = `data:text/css;charset=utf-8,${encodeURIComponent(` #browser > #st_toolbox { --v-sidebar-min-width: 10px; --v-sidebar-transition-delay-show: .3s; --v-sidebar-transition-delay-hide: 2s; --v-sidebar-transition-duration: .2s; /* ********************************************** */ position: relative !important; z-index: 2 !important; min-width: var(--v-sidebar-tabs-width) !important; width: var(--v-sidebar-tabs-width) !important; max-width: var(--v-sidebar-tabs-width) !important; overflow: hidden !important; opacity: 0 !important; --v-sidebar-margin-max-width: calc(-1 * var(--v-sidebar-tabs-width)); --v-sidebar-transform-locale-dir: -1; --v-sidebar-transform-locale-dir-visible: 1; margin-inline-start: 0 !important; margin-inline-end: var(--v-sidebar-margin-max-width) !important; transform: translateX(calc(var(--v-sidebar-transform-locale-dir) * (var(--v-sidebar-tabs-width) - var(--v-sidebar-min-width)))) !important; &[sidebar_tabs_auto_hide] { transition-timing-function: linear, step-start, linear !important; transition-delay: var(--v-sidebar-transition-delay-hide), calc(var(--v-sidebar-transition-delay-hide) + var(--v-sidebar-transition-duration)), 0s !important; transition-duration: var(--v-sidebar-transition-duration), 0s, .2s !important; transition-property: transform, opacity, margin-top !important; } &[sidebar_tabs_auto_hide][sidebar_tabs_visible="hidden"] { transition-delay: 0s, var(--v-sidebar-transition-duration), 0s !important; } :root[sidebar_tabs_start="false"] & { margin-inline-start: var(--v-sidebar-margin-max-width) !important; margin-inline-end: 0 !important; } :root[sidebar_tabs_start="false"]:-moz-locale-dir(ltr) &, :root[sidebar_tabs_start="true"]:-moz-locale-dir(rtl) & { --v-sidebar-transform-locale-dir: 1; --v-sidebar-transform-locale-dir-visible: -1; } &[sidebar_tabs_auto_hide]:hover { transform: translateX(0px) !important; opacity: 1 !important; transition-delay: var(--v-sidebar-transition-delay-show), var(--v-sidebar-transition-delay-show), 0s !important; } &[sidebar_tabs_auto_hide][sidebar_tabs_visible^="visible"] { transform: translateX(0px) !important; opacity: 1 !important; transition-delay: 0s !important; } :root[v_vertical_bar_start="true"][sidebar_tabs_start="true"]:is([v_vertical_bar_visible="visible"],[v_vertical_bar_sidebar="true"]) &[sidebar_tabs_auto_hide], :root[v_vertical_bar_start="false"][sidebar_tabs_start="false"]:is([v_vertical_bar_visible="visible"],[v_vertical_bar_sidebar="true"]) &[sidebar_tabs_auto_hide] { transform: translateX(calc(var(--v-sidebar-transform-locale-dir-visible) * var(--v-vertical-bar-width, 0px))) !important; opacity: 1 !important; transition-delay: 0s !important; } :root[v_vertical_bar_visible] & { padding-inline: 0 !important; } } #browser > #st_splitter { display: none !important; } `)}`; }, async loadstyle(win) { win.windowUtils.loadSheetUsingURIString(this.style, win.windowUtils.USER_SHEET); win.setTimeout(() => win.ucf_custom_script_win.ucf_sidebar_tabs.toolbox.setAttribute("sidebar_tabs_auto_hide", "true"), 0); }, async removestyle(win) { win.windowUtils.removeSheetUsingURIString(this.style, win.windowUtils.USER_SHEET); win.ucf_custom_script_win.ucf_sidebar_tabs.toolbox.removeAttribute("sidebar_tabs_auto_hide"); }, showHide(win) { var st = win.ucf_custom_script_win.ucf_sidebar_tabs; if (!st.toolbox.hasAttribute("sidebar_tabs_auto_hide")) { st.toggle(); return; } st.st_vbox_container ||= st.toolbox; if (!st._open && st._visible) { st.isPanel = false; st.hideToolbar(true); } st.showHide(); if (!st._visible) win.setTimeout(() => st.toolbox.removeAttribute("sidebar_tabs_visible"), 0); }, }, ) => CustomizableUI.createWidget({ id, label, tooltiptext, defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onBeforeCreated_(doc) { if (Services.prefs.getBoolPref(pref, true)) sidebar_tabs.loadstyle(doc.defaultView); }, onBeforeCreated(doc) { this.onBeforeCreated = this.onBeforeCreated_; this.onBeforeCreated_(doc); CustomizableUI.destroyWidget("ucf_sidebar_tabs"); }, onCreated(btn) { btn.style.setProperty("list-style-image", `url("${img}")`); btn.setAttribute("context", ""); var st = btn.ownerGlobal.ucf_custom_script_win.ucf_sidebar_tabs; btn.checked = st._open; st.button = btn; var func = st.mouseup.toString(); Services.scriptloader.loadSubScript(`data:charset=utf-8,${encodeURIComponent(`this.mouseup = ${func.replace(/^(async\s)?.*?\(/, '$1function mouseup(') .replace(/\}$/g, 'setTimeout(() => this.toolbox.removeAttribute("sidebar_tabs_visible"), 0);}')}`)}`, st); }, onClick(e) { switch (e.button) { case 0: if (!e.getModifierState("Control")) sidebar_tabs.showHide(e.view); else e.view.ucf_custom_script_win.ucf_sidebar_tabs.toggle(); break; case 1: e.view.ucf_custom_script_win.ucf_sidebar_tabs.toggle(); break; case 2: let prf = Services.prefs.getBoolPref(pref, true), loadremove = !prf ? "loadstyle" : "removestyle"; Services.prefs.setBoolPref(pref, !prf); for (let win of CustomizableUI.windows) sidebar_tabs[loadremove](win); break; } }, }))(); скрытый текст Выделить код Код:(async ( id = Symbol("mouseover_openpopup"), delay = 300, hidedelay = 1000, btnSelectors = [ "#PanelUI-menu-button", "#library-button", "#nav-bar-overflow-button", "#star-button-box", "#pageActionButton", "#translations-button", "#unified-extensions-button", "#downloads-button", "#alltabs-button", ], excludeBtnSelectors = [ //исключить кнопки "#tabs-newtab-button", "#new-tab-button", "#back-button", "#forward-button", "#panic-button", "#alltabs-button", "#ucf-cbbtn-OpenPageInOtherBrowser", "#ucf-cbbtn-ToggleRestartlessAddons", "#ucf-cbbtn-Save", "#fxa-toolbar-menu-button", "toolbarbutton[data-extensionid]", ], areaSelectors = [ "toolbar", ], hideAreaSelectors = [ "toolbar", "popupset", // "#PlacesToolbarItems", ], excludeHidePopupSelectors = [ "#contentAreaContextMenu", "#contentAreaContextMenu :scope", "#PopupSearchAutoComplete", "#PopupAutoComplete", ], ) => (this[id] = { timer: null, hidetimer: null, hideArea: [], open_: false, get popups() { delete this.popups; return this.popups = new Set(); }, get btnSelectors() { delete this.btnSelectors; return this.btnSelectors = btnSelectors.join(","); }, get ExtensionParent() { delete this.ExtensionParent; return this.ExtensionParent = ChromeUtils.importESModule("resource://gre/modules/ExtensionParent.sys.mjs").ExtensionParent; }, get browserActionFor() { delete this.browserActionFor; return this.browserActionFor = this.ExtensionParent.apiManager.global.browserActionFor; }, get exclude() { delete this.exclude; return this.exclude = excludeBtnSelectors.join(","); }, get excludePopup() { delete this.excludePopup; return this.excludePopup = excludeHidePopupSelectors.join(","); }, async init() { await delayedStartupPromise; for (let elm of (this.areasList = document.querySelectorAll(areaSelectors.join(",")))) { elm.addEventListener("mouseover", this); elm.addEventListener("mouseout", this); elm.addEventListener("mousedown", this); } for (let elm of (this.popupsList = document.querySelectorAll("toolbar, popupset"))) elm.addEventListener("popupshown", this); setUnloadMap(id, this.destructor, this); if (!hideAreaSelectors.length) return; if (excludeHidePopupSelectors.length) this.popupShown = this.pShown; this.popupShown_ = this.popupShown.bind(this); this.popupHidden_ = this.popupHidden.bind(this); this.hidePopup = this.hPopup; for (let elm of (this.hideArea = document.querySelectorAll(hideAreaSelectors.join(",")))) elm.addEventListener("popupshown", this.popupShown_); }, destructor() { for (let elm of this.areasList) { elm.removeEventListener("mouseover", this); elm.removeEventListener("mouseout", this); elm.removeEventListener("mousedown", this); } for (let elm of this.popupsList) elm.removeEventListener("popupshown", this); for (let elm of this.hideArea) elm.removeEventListener("popupshown", this.popupShown_); }, popupShown({target}) { if (target.localName === "tooltip") return; this.pShow(target); }, pShown({target}) { if (target.localName === "tooltip" || target.matches(this.excludePopup)) return; this.pShow(target); }, pShow(target) { target.addEventListener("mouseenter", this); target.addEventListener("popuphidden", this.popupHidden_, { once: true }); if (this.open_) return; this.open_ = true; gBrowser.tabpanels.addEventListener("mouseenter", this); }, popupHidden({target}) { target.removeEventListener("mouseenter", this); }, handleEvent(e) { this[e.type](e); }, mouseenter({currentTarget}) { clearTimeout(this.hidetimer); if (currentTarget != gBrowser.tabpanels) return; this.hidetimer = setTimeout(() => this.hidePopup(), hidedelay); }, popuphidden({target}) { this.popups.delete(target); }, popupshown({target}) { if (target.localName === "tooltip") return; this.popups.add(target); target.addEventListener("popuphidden", this, { once: true }); }, hidePopup() { this.popups.forEach(p => p.hidePopup?.()); this.popups.clear(); }, hPopup() { this.popups.forEach(p => p.hidePopup?.()); this.popups.clear(); if (!this.open_) return; gBrowser.tabpanels.removeEventListener("mouseenter", this); this.open_ = false; }, mousedown() { clearTimeout(this.timer); }, mouseout() { clearTimeout(this.timer); }, mouseover({target}) { clearTimeout(this.timer); this.timer = setTimeout(() => { if (target?.matches?.(`${this.exclude},:is(menupopup,panel) :scope`) ?? true) return; let extensionid, isbtn = target.matches(this.btnSelectors) || !!(target.parentElement.matches(this.btnSelectors) && (target = target.parentElement)); if (!target.hasAttribute("open") && (isbtn || target.menupopup || target.getAttribute("widget-type") === "view" || target.classList.contains("toolbarbutton-combined-buttons-dropmarker") || ((extensionid = target.dataset?.extensionid) && this.browserActionFor(this.ExtensionParent.WebExtensionPolicy.getByID(extensionid).extension).action.tabContext.get(gBrowser.selectedTab).popup))) { this.hidePopup(); let params = { bubbles: false, cancelable: true, }; target.dispatchEvent(new MouseEvent("mousedown", params)); target.dispatchEvent(new MouseEvent("click", params)); } }, delay); }, }).init())(); |
Farby > 28-11-2024 17:38:59 |
egorsemenov06 |
egorsemenov06 > 28-11-2024 17:52:57 |
Farby пишет
<Большое СПАСИБО первые две кнопки заработали скрытый текст Выделить код Код:// Google Translate в контекстном меню....... (this.googletranslate = { init(that) { var lc = navigator.lastClick = {}, w = null, xhtmlns = 'http://www.w3.org/1999/xhtml'; var mouseUp = (e) => { if (e.button) return; lc.X = e.screenX - mozInnerScreenX; lc.Y = e.screenY - mozInnerScreenY; }; gBrowser.tabpanels.addEventListener('mouseup', mouseUp, false); this.destructor = () => { gBrowser.tabpanels.removeEventListener('mouseup', mouseUp, false); if (w) w.closeWin(); }; that.unloadlisteners.push("googletranslate"); var createWindow = function(text, status, title, id, pos, size) { var win = window, doc = win.document, wId = 'ujs_window'+(id || ''); w = doc.getElementById(wId); var keyDown = function(e) {if (!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode == 27)doc.getElementById(wId).closeWin();}; var mouseDown = function() {doc.getElementById(wId).closeWin();}; if (w) w.closeWin(); w = doc.createElementNS(xhtmlns, 'div'); w.setAttribute('style', 'position:fixed;display:block;visibility:hidden;left:0;top:0;width:auto;height:auto;border:1px solid gray;padding:2px;margin:0;z-index:99999;overflow:hidden;cursor:move;'+(typeof w.style.borderRadius === 'string' ? 'background-color:#eaeaea;padding-top:0px;border-radius:4px;box-shadow:0 0 15px rgba(0,0,0,.4);' : 'background:-o-skin("Window Skin");')); w.id = wId; w.closeWin = function() { doc.removeEventListener('keydown', keyDown, false); gBrowser.tabpanels.removeEventListener('mousedown', mouseDown, false); this.parentNode.removeChild(this); w = null; }; w.addEle = function(str, style) { var ele = doc.createElementNS(xhtmlns, 'div'); ele.setAttribute('style', style); if (str) { ele.innerHTML = str; for (var el, all = ele.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)) { el.parentNode.removeChild(el); } else { for (var att = el.attributes, j = att.length; j--;) { if (/^on[a-z]+$/i.test(att[j].name))att[j].value = ''; } } } } return this.appendChild(ele); }; var img = doc.createElementNS(xhtmlns, 'div'); img.setAttribute('style', 'display:block;float:right;width:16px;height:16px;padding:0;margin-top:2px;margin-right:1px;border:none;cursor:pointer;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACQUlEQVR4Xm2SPUhbURTHfzfNJ4nU0Axx7CJCN2kQtIgVCtq6OdQuBUftWIQqFNsKDo6iHTqIqN3a0kklUKTS2AZrcOjioFtRjFWUfH+803cS9GHwB4dzcu75/+8L9xgaSEDbLXhaASzAyXAMn5/DHxwwjeJgKLRxd3Q0atxuLhGgWqmQmp9PJ7LZJ5Ow3WhQFweDG20LC1FfRwc3kUsm+T48fPIzl3s8VTdxxLt+/2FhdlZkc1MkmdR8Pba2ajlrz3z1+9OvIOaIfb7DwsSEyNKSyM6OSLksEo/rbw2ttadntV7Gnv3k86VfqskvmDzv7hZ580Zkelrk4kJqFIsii4satVrRs+rYmBQHBuRvS4u8g/fuCmDOz+HgAIWpKRgfh3AYhoZQ8Hqxjo4o9PdT3d1FcQEl8KoBnJ7C/j6KZkZGYG4OIhEUFed7erD29q69jGrd1qVBqcQVKgwEuMSEQhjtXRk4JvW/kM1i2WGMga4uzMoKBIOIfbNiolEC6+uU+/qQRALFA1QBlwVYxmBcLmhuxqytQSgEKu7t1dBavwKvbeINh/Has2IMqnXpem4bky6qWLdvZgaOj2FwEHNyoqG19vRMZ8jZs1+NOfsNcZS3EFvzeNL51laRe/dEYrFadsLpZeyZDx7P6QN4Btwx1OE1xO4HAquP2tsjAZ+Pm8gWi3xMpc6W8/kXPyAO/DM4oOsZa2pafdjZGXF7PAgOpXKZL4nE2XImcyUGMDSg63kbhgvgtYCq8+akIL4J3y7Fyn+DokZOnLlMyQAAAABJRU5ErkJggg==");background:-o-skin("Caption Close Button Skin");'); img.title = (win.navigator.language.indexOf('ru') == 0) ? '\u0417\u0430\u043A\u0440\u044B\u0442\u044C' : 'Close'; img.addEventListener('click', function() {this.parentNode.closeWin();}, false); w.appendChild(img); var title = w.addEle(title, 'display:table;color:#000;font:17px Times New Roman;width:auto;height:auto;padding:0;margin:0 2px;cursor:text;'); title.onclick = e => { e.preventDefault(); var url = e.target.href; // Здесь открываем url как хотим. var ctabpos = gBrowser.selectedTab._tPos +1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos); doc.getElementById(wId).closeWin(); }; var cnt = doc.createElement("textarea"); cnt.style.cssText = ` color: #000; width: 310px; height: 160px; outline: none; padding-left: 3px; padding-bottom: 3px; border: 1px solid #aaa; background-color: #fafcfe; font: 17px Times New Roman; `; if (text) cnt.value = text; w.append(cnt); w.addEle(status, 'display:table;font:12px Times New Roman;font-weight:bold;color:blue;width:auto;height:auto;padding-top:2px;margin:0 3px;cursor:pointer;'); w.addEventListener('mousedown', function(e) { if (e.target == w) { e.preventDefault(); var grabX = e.clientX, grabY = e.clientY, origX = parseInt(w.style.left), origY = parseInt(w.style.top); var mouseMove = function(ev) { w.style.left = origX+ev.clientX-grabX+'px'; w.style.top = origY+ev.clientY-grabY+'px'; }; doc.addEventListener('mousemove', mouseMove, false); doc.addEventListener('mouseup', function() {doc.removeEventListener('mousemove', mouseMove, false);}, false); } }, false); doc.documentElement.appendChild(w); if (size) { cnt.style.height = size.height; cnt.style.width = size.width; } else { for (var i = 3; i < 10; i++) { if (cnt.scrollHeight > cnt.offsetHeight || cnt.scrollWidth > cnt.offsetWidth) { cnt.style.height = 80*i+'px'; cnt.style.width = 160*i+'px'; } else break; } } var docEle = (doc.compatMode == 'CSS1Compat' && win.postMessage) ? doc.documentElement : doc.body; var mX = docEle.clientWidth-w.offsetWidth, mY = docEle.clientHeight-w.offsetHeight; if (mX < 0) {cnt.style.width = parseInt(cnt.style.width)+mX+'px'; mX = 0;} if (mY < 0) {cnt.style.height = parseInt(cnt.style.height)+mY+'px'; mY =0;} var hW = parseInt(w.offsetWidth/2); w.style.left = (pos && pos.X < mX+hW ? (pos.X > hW ? pos.X-hW : 0) : mX)+'px'; w.style.top = (pos && pos.Y+10 < mY ? pos.Y+10 : mY)+'px'; w.style.visibility = 'visible'; doc.addEventListener('keydown', keyDown, false); gBrowser.tabpanels.addEventListener('mousedown', mouseDown, false); if (text) { var st = cnt.style; var div = cnt.editor.rootElement; var range = new Range(); range.selectNode(div.firstChild); var rect = range.getBoundingClientRect(); let w = Math.ceil(rect.width); if (cnt.scrollTopMax) { if (!matchMedia("(-moz-overlay-scrollbars)").matches) // ??? w += InspectorUtils.getChildrenForNode(div, true, false).at(-1).clientWidth; } else st.height = Math.max(50, Math.ceil(rect.height) + 2) + "px"; st.width = Math.max(200, w) + "px"; } return w; }; var getHash = function (txt) { TKK=eval('((function(){var a\x3d817046147;var b\x3d-335196159;return 410049+\x27.\x27+(a+b)})())'); function sM(a) { var b; if (null !== yr) b = yr; else { b = wr(String.fromCharCode(84)); var c = wr(String.fromCharCode(75)); b = [b(), b()]; b[1] = c(); b = (yr = window[b.join(c())] || "") || ""; } var d = wr(String.fromCharCode(116)), c = wr(String.fromCharCode(107)), d = [d(), d()]; d[1] = c(); c = "&" + d.join("") + "="; d = b.split("."); b = Number(d[0]) || 0; for (var e = [], f = 0, g = 0; g < a.length; g++) { var l = a.charCodeAt(g); 128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023), e[f++] = l >> 18 | 240, e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224, e[f++] = l >> 6 & 63 | 128), e[f++] = l & 63 | 128); } a = b; for (f = 0; f < e.length; f++) a += e[f], a = xr(a, "+-a^+6"); a = xr(a, "+-3^+b+-f"); a ^= Number(d[1]) || 0; 0 > a && (a = (a & 2147483647) + 2147483648); a %= 1E6; return c + (a.toString() + "." + (a ^ b)); } var yr = null; var wr = function(a) { return function() { return a; }; }, xr = function(a, b) { for (var c = 0; c < b.length - 2; c += 3) { var d = b.charAt(c + 2), d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d), d = "+" == b.charAt(c + 1) ? a >>> d : a << d; a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d; } return a; }; return sM(txt); }; var ujs_google_translate = function (dir) { var lng = window.navigator.language.slice(0, 2), txt = gContextMenu.selectionInfo.fullText, l = dir.split('|'); var encTxt = encodeURIComponent(txt); var winWait = function(lng) {createWindow('', (lng == 'ru' ? 'Подождите идет перевод' : 'Wait, is going Translating')+'\u2026', 'Google Translate', '_gt', window.navigator.lastClick);}; if (txt) { winWait(lng); var xhr = new XMLHttpRequest(); var url = 'https://translate.google.com/translate_a/single?client=gtx&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt); var urlt = "http://translate.google.com/translate_t?text="+encTxt+"&sl=' + langFrom_google_text + '&tl=' + langTo_google_text +'&hl=' + lng + '&eotf=0&ujs=gtt"; xhr.open('POST', url, true); xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8'); xhr.onreadystatechange = function() { try { if (xhr.readyState == 4 && xhr.status == 200) { var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, ' ')); for (var i = 0, n; n = tmp[0][i]; i++) { if (n[0])result += n[0].toString(); }; status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase(); createWindow(result, status, '<a href="'+urlt.replace(/&/g,'&')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Google Translate</a>', '_gt', window.navigator.lastClick); } } catch(e) {}; }; xhr.send('q=' + encodeURIComponent(txt)); } else { var urlt = gBrowser.currentURI.spec; var url = "http://translate.google.com/translate?u="+encodeURIComponent(urlt)+'&tl='+l[1]+"&hl="+lng+"&langpair="+dir+"&tbb=1"; var ctabpos = gBrowser.selectedTab._tPos +1; gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos); }; }; var contextMenu = document.getElementById("contentAreaContextMenu"); var nextEleMenu = document.getElementById("context-inspect"); var menuItem = document.createXULElement("menuitem"); menuItem.setAttribute("id", "context-ru-google-translate"); menuItem.setAttribute("label", "Перевести на русский"); menuItem.setAttribute("class", "menuitem-iconic"); var image = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path fill='context-fill rgb(0, 116, 232)' fill-opacity='context-fill-opacity' d='M15.37 15H17l-3.63-8.54a.75.75 0 0 0-.69-.46h-.82c-.3 0-.58.18-.7.46L9.32 10.8l-.01-.01a10.8 10.8 0 0 1-3.27-2.2 12.38 12.38 0 0 0 2.54-4.18L9.08 3H10V1.5H5.75V0h-1.5v1.5H0V3h7.5l-.33.91c-.47 1.31-1.2 2.52-2.13 3.56-.7-.9-1.25-1.9-1.63-2.97H1.8l.18.48a12.43 12.43 0 0 0 1.97 3.56c-.9.75-1.89 1.35-2.96 1.78v1.58a12.3 12.3 0 0 0 3.96-2.26 12.31 12.31 0 0 0 3.77 2.54L7.53 15h1.64l1.06-2.5h4.08l1.06 2.5Zm-4.5-4 1.4-3.3 1.4 3.3h-2.8Z'/></svg>"; var substitution = `ucf-${menuItem.id.toLowerCase()}-img`; var PHandler = Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler); if (!PHandler.hasSubstitution(substitution)) PHandler.setSubstitution(substitution, Services.io.newURI(image)); menuItem.style.cssText = `list-style-image:url("resource://${substitution}");-moz-context-properties:fill,fill-opacity;fill:currentColor;`; menuItem.addEventListener("command", function() {ujs_google_translate('auto|ru');}, false); contextMenu.insertBefore(menuItem, nextEleMenu); contextMenu.insertBefore(document.createXULElement("menuseparator"), nextEleMenu); var translate = async () => { var br = gBrowser.selectedBrowser; var fw = Services.focus.focusedWindow; if (fw == window) { if (document.activeElement != br) return; } else if (fw.browsingContext.top != br.browsingContext) return; var cb = navigator.clipboard; var was = await cb.readText(); if (was) await cb.writeText(""); docShell.doCommand("cmd_copy"); await new Promise(r => setTimeout(r, 100)); var txt = await cb.readText(); if (txt || was) cb.writeText(was); if (!txt && !br.currentURI.scheme.startsWith("http")) return; window.gContextMenu = {selectionInfo: { get fullText() { window.gContextMenu = null; return txt; } }}; ujs_google_translate("auto|ru"); } var ts = 0, destr = this.destructor, args = ["keyup", e => e.key == "Control" && ts - (ts = Cu.now()) > -300 && !e.shiftKey && !e.altKey && translate(ts = 0) ]; addEventListener(...args); this.destructor = () => destr(removeEventListener(...args)); } }).init(this); |
unter_officer > 29-11-2024 13:16:29 |
egorsemenov06 пишет
Попробовал накатить это обновление UCF на FF131, отвалилось более десятка скриптов. Или версия UCF от 2024-11-27 только для FF133+ и для FF131 не подходит? |
Farby > 29-11-2024 13:43:57 |
unter_officer |
unter_officer > 29-11-2024 14:24:22 |
Farby |
dinn > 29-11-2024 17:40:53 |
Dumby пишет
Сколько не тестил, ни разу эта функция не вызывалась из AutoScrollChild.sys.mjs, а из browser-custom-element.js вызывается всегда. Смог заткнуть пасть через обсервер + удаление оконных прослушек на mouseup и mousedown с последующим закрытием попапа, но часто этот autoscroll глючит (в сочетании зажатой средней кнопки и небольшого сдвига), выскакивает предупреждение с последующим сбросом моих действий, так что забил.
Да, спасибо. Крутой способ встраивания в контентский процесс и подсовывания юзер прослушки с имитацией нажатия средней кнопки мыши в handle(). Даже через скрипт работает, а не только из консоли. |
unter_officer > 01-12-2024 02:02:04 |
Farby пишет
А по какой причине удалён unloadlisteners? |
xrun1 > 01-12-2024 02:29:34 |
egorsemenov06 пишет
|
Dobrov > 01-12-2024 06:02:49 |
В теме много скриптов с unloadlisteners, например ucf-appmenu-restart-button Вопрос: в новом UCF из-за таких скриптов не будет переполнения памяти или других ошибок ? |
egorsemenov06 > 01-12-2024 08:27:52 |
xrun1 пишет
с новым UCF не работает |
xrun1 > 01-12-2024 14:04:44 |
egorsemenov06 пишет
Ясно. Я не перешёл на новый. Когда что-то отвалится, тогда и посмотрю. К чему спешить... |
Dumby > 01-12-2024 15:33:07 |
unter_officer пишет
Полагаю, лучше пока попробовать сделать заплатку скрытый текст Выделить код Код:(csw => { window[csw.replace("ts", window[csw] == this ? "t" : "t_all")] = this; this.unloadlisteners = {push: key => this.setUnloadMap(key, { apply: () => this[key].destructor.call(this[key]) })}; })("ucf_custom_scripts_win"); Подключать в CustomStylesScripts.mjs в scriptschrome в domload И, чтобы было ucfobj: true Ну, и чтобы расположен был сверху (первым), в смысле до подключения остальных скриптов. Как-то так: скрытый текст Выделить код Код:data:image/png;base64,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 Если нужно, точно так же подключить его и в scriptsallchrome в domload Наверно, можно записать проще, типа а то как-то половинчато, unloadlisteners выброшен, хотя, может здесь предлагается заменить все Dobrov пишет
Я уже высказывался на эту тему. Сколько мы там видим addEventListener() ? И ведь это разработчики, наверно понимают, |
unter_officer > 01-12-2024 16:17:53 |
Dumby пишет
Dumby, спасибо. Так все работает. |
Farby > Сегодня 16:03:39 |
Dumby, здравствуйте. |