>Форум 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,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 |
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); saveIt |