Подскажите, забыл, какая ф-ция в CB для окна выбора действий: "один" "два" "выход" ? Там alertbox или как-то так...
Замена\аналог консольному choice:
echo ^ ------------------------------------------------------------ echo ^ ^| ^| echo ^ ^| ¤¤¤ TOR - (t), или UltraSurf (u) ? (q) - Выход ¤¤¤ ^| echo ^ ^| ^| echo ^ ------------------------------------------------------------ choice /c tuq /T 15 /d q if %ERRORLEVEL% == 1 goto :tor if %ERRORLEVEL% == 2 goto :usurf if %ERRORLEVEL% == 3 goto :EOF
...программисты словно войну какую-то ведут за свои обновления. Блин, почему сейчас повсюду мания ухудшать интерфейсы и делать их максимально неудобными?! Radiation
Отсутствует
Если поиск пойдёт не в текущей вкладке, то можно, наверно
Класс, спасибо, да поиск открывается в новой вкладке
А можно ли добавить чтобы название для контейнера было такое же как и введенный текст в строке поиска?
Например если в строке поиска искать "солнечные панели" то и новый контейнер открывался с таким же названием
Отсутствует
Dumby
Как бы в Суммарном жоре памяти уменьшить размер шрифта? А то она иконки от дополнений растягивает.
Отсутствует
Недостаток SaveHTML в том, что сохранённые .html файлы не появляются в "Показать все загрузки".
Это можно исправить или хотя бы после сохранения .html помигать кнопкой Загрузки, как после скачивания файла?…
Недостаток?, как невхождение чего-либо в сам замысел?
Тут, как-то, на нечто подобное для кнопки Save,
предлагал фейковый download, и оно, вроде как, мигает кнопкой.
... notify("Страница сохранена в:", path); var d = await Downloads.createDownload({ source: "about:blank", target: FileUtils.File(path) }); (await Downloads.getList(Downloads.ALL)).add(d); d.refresh(d.succeeded = true);
Ещё нужен код, чтобы показать свой текст в строке статуса. Я пробовал, но ничего не показывается
У меня, с консоли, так работает
StatusPanel._label = "свой текст в строке статуса"; setTimeout(() => StatusPanel.update(), 2000);
может сделаешь пример, скрывающий панель вкладок, если вкладка одна и показывающий для нескольких?
Для CB
(url => { var num = gBrowser.tabs.length; var bar = document.getElementById("TabsToolbar"); if (num == 1) bar.collapsed = true; addEventListener("TabOpen", () => { if (++num == 2) bar.collapsed = false; }, false, gBrowser.tabContainer); addEventListener("TabClose", () => { if (--num == 1) bar.collapsed = true; }, false, gBrowser.tabContainer); var type = windowUtils.USER_SHEET; windowUtils.loadSheetUsingURIString(url, type); addDestructor(() => { windowUtils.removeSheetUsingURIString(url, type); if (num == 1) bar.collapsed = false; }); })("data:text/css;charset=utf-8,%23TabsToolbar[collapsed]:not([customizing]){visibility:collapse!important;}");
не получается поменять подсказку кнопки в зависимости от того, есть кнопка SingleSave или нет
Может, на момент исполнения кода, «кнопки SingleSave» ещё пока нет?
Просто запуск WebExtensions сильно тормозят (в угоду дражайшему стартап-перформансу).
Попробуй с таймаутом.
Подскажите, забыл, какая ф-ция в CB для окна выбора действий: "один" "два" "выход" ? Там alertbox или как-то так...
Оно чтоле?
var result = custombuttons.confirmBox3( "Header", "Message", "TOR", "Выход", "UltraSurf" ); var results = { 0: "TOR", 1: "Выход", 2: "UltraSurf" }; alert(results[result]);
А можно ли добавить чтобы название для контейнера было такое же как и введенный текст в строке поиска?
Например если в строке поиска искать "солнечные панели" то и новый контейнер открывался с таким же названием
(async (sel, self) => ({ icon: "circle", colors: [ "mediumseagreen", "silver", "crimson", "blue", "peru", ], initColors() { var colorName = "ucf-gen"; var css = "@-moz-document url(about:preferences#containers)," + " url-prefix(chrome://browser/content/browser.x) {\n"; this.colors.forEach((color, ind) => { var [ic, tc] = color.split(/\s*\|\s*/); css += `\t.identity-color-${colorName}${ind} {\n` + `\t\t--identity-tab-color: ${tc || ic};\n` + `\t\t--identity-icon-color: ${ic};\n\t}\n` }); var url = "data:text/css;charset=utf-8," + 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 len = this.colors.length; var pref = "ucf.openInGeneratedContainer.lastColor"; var ind = Math.min(Services.prefs.getIntPref(pref, -1), len - 1); this.nextColor = () => { var next = ind + 1; Services.prefs.setIntPref(pref, ind = next == len ? 0 : next); return colorName + ind; } }, init(topic) { Services.obs.addObserver(self = this, topic); Services.obs.addObserver(function quit(s, t) { Services.obs.removeObserver(self, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); this.initColors(); this.newUsercontext = name => this.cis.create( name || `[ ${this.cis._lastUserContextId + 1} ]`, this.icon, this.nextColor() ).userContextId; }, observe(doc) { var list = doc.querySelectorAll(sel); if (!list.length) return; var menuitem = doc.createXULElement("menuitem"); for(var args of Object.entries({ selectiontype: "single", oncommand: "cmd(window)", nodetype: "folder|query", selection: "folder|query", label: "Открыть всё в контейнере", id: "placesContext_openContainer:tabs:newUsercontext" })) menuitem.setAttribute(...args); menuitem.cmd = this.cmd; menuitem.rnd = menuitem.constructor.prototype.render; menuitem.render = this.render; var [m1, m2] = menuitem.list = Array.from(list); (m2 || m1).after(menuitem); if (doc.documentElement.getAttribute("windowtype") != "navigator:browser") return; for(var btn of [ doc.getElementById("tabs-newtab-button"), doc.getElementById("new-tab-button") || doc.ownerGlobal.gNavToolbox.palette.querySelector("#new-tab-button") ]) if (btn) btn.checkForMiddleClick = this.click; var win = doc.ownerGlobal; this.redefDoSearch(win, win.customElements.get("searchbar").prototype); }, redefDoSearch(win, proto) { this.cis = win.ContextualIdentityService; var code = `(openTrustedLinkIn => [ {${proto.doSearch}}, openTrustedLinkIn ])( function otl(url, where, params) { if (where != "current") params.userContextId = otl.newUsercontext( document.getElementById("searchbar").value ); openTrustedLinkIn(url, where, params); } );`; (this.redefDoSearch = (win, proto) => { var [obj, func] = win.eval(code); Object.assign(proto, obj); func.newUsercontext = this.newUsercontext; })(win, proto); }, click(btn, e) { if (!(e.button != 2 || e.ctrlKey || e.shiftKey)) { var txt = e.view.readFromClipboard(); if (txt) { var urls = txt.split("\n").map(self.map).filter(Boolean); if (urls.length) return e.preventDefault(), self.openFromClipboard(e.view, urls); } } e.view.checkForMiddleClick(btn, e); }, eo: Object.create(null), map(str) { str = str.trim(); try { var scheme = Services.io.extractScheme(str); var ph = Services.io.getProtocolHandler(scheme); if (ph.scheme == scheme) return Services.io.newURI(str) && {uri: str}; } catch {} }, openFromClipboard(win, urls) { if (win.OpenInTabsUtils.confirmOpenInTabs(urls.length, win)) urls.load = true, this.open(win, this.eo, urls); }, async render() { this.rnd(); await new Promise(this.ownerGlobal.requestAnimationFrame); this.hidden || (this.hidden = this.list.every(self.every)); }, every: node => node.disabled || node.hidden, cmd(win) { var view = this.parentNode._view; var node = win.document.popupNode; node = node._placesView && node._placesView.result.root; self.open(win, node || view.selectedNode || view.result.root); }, open(win, node, list) { var gbw = Cu.import("resource:///modules/PlacesUIUtils.jsm", {}).getBrowserWindow; var w = gbw(win); this.pu = w.PlacesUIUtils; this.fs = w.PlacesUtils.favicons; this.cis = w.ContextualIdentityService; this.sysp = w.E10SUtils.SERIALIZED_SYSTEMPRINCIPAL; (this.open = (win, node, list) => { this.openURLs(gbw(win), list || win.PlacesUtils.getURLsForContainerNode(node)); node.bookmarkGuid && this.pu.doCommand(win, "placesCmd_delete"); })(win, node, list); }, async openURLs(win, urls) { var userContextId = this.newUsercontext(); var mark = !win.PrivateBrowsingUtils.isWindowPrivate(win); var {load} = urls, gb = win.gBrowser, pos = gb.selectedTab._tPos; for(var {uri, title, isBookmark} of urls) try { if (mark) isBookmark ? this.pu.markPageAsFollowedBookmark(uri) : this.pu.markPageAsTyped(uri); if (load) { gb.addTrustedTab(uri, {index: ++pos, userContextId}); continue; } var state = {userContextId, entries: [{ url: uri, title: title || uri, triggeringPrincipal_base64: this.sysp }]}; var [,, data, mime] = await new Promise( resolve => this.fs.getFaviconDataForPage( Services.io.newURI(uri), (...args) => resolve(args), 16 ) ); if (data.length) state.image = `data:${ mime || "image/x-icon" };base64,${ btoa(String.fromCharCode(...data)) }`; var tab = gb.addTrustedTab(null, {index: ++pos, userContextId}); win.SessionStore.setTabState(tab, state); } catch {}; } }).init("chrome-document-loaded"))( "#placesContext_openBookmarkContainer\\:tabs,#placesContext_openContainer\\:tabs" );
размер шрифта
иконки от дополнений
???
Отсутствует
Оно чтоле?
Оно! Половина кнопок на батниках завязаны, вот решил перевести кой-чего в CB, а забыл название. Пасиб.
В итоге получилось так:
const prof = Services.dirsvc.get('ProfD', Ci.nsIFile), tor = prof.path + "\\SOFT_PM\\tor\\Tor\\tor.exe", usurf = prof.path + "\\SOFT_PM\\UltraSurf_Proxi\\u1902.exe"; let choice = custombuttons.confirmBox3( "Proxy utils", "Запустить что ", "TOR", "Выход", "UltraSurf" ), result = { 0: tor, 1: "Выход", 2: usurf }; //console.log("result of choise " + result[choice]); if(result[choice] == "Выход") return; else startProcess(result[choice], []); // ф-ция где проверяется аргументы и путь... ну и запускает прогу.
...программисты словно войну какую-то ведут за свои обновления. Блин, почему сейчас повсюду мания ухудшать интерфейсы и делать их максимально неудобными?! Radiation
Отсутствует
Не скачиваются, можно выложить еще раз?
Отсутствует
Dumby
Ну вот например открывается в контенере несколько вкладок
Потом все вкладки закрываются а контейнер созданный остается существовать
Можно ли сделать чтобы после закрытия последней вкладки контейнера он удалялся?
Отредактировано Stkvsky (22-04-2021 16:50:11)
Отсутствует
Ребят, если есть у кого рабочая кнопка
Добавить пункт подменю "Увеличить изображение".
Поделитесь пожалуйста. У меня на 88й не работает.
для custom_script_win.js
(this.ucf_img_scroll_zoom = { imgZoom: 190, // на сколько увеличить изображение из меню scrollZoom: 20, // на сколько увеличивать/уменьшать колесиком мыши scrollTop: 1, // или -1, переключение направление прокрутки для увеличение колёсиком init(that) { var popup = this.popup = document.querySelector("#contentAreaContextMenu"); if (!popup) return; popup.addEventListener("popupshowing", this); that.unloadlisteners.push("ucf_img_scroll_zoom"); }, receiveMessage(msg) { var container = document.documentElement .appendChild(document.createElement("div")); var image = container.appendChild(document.createXULElement("image")); image.style.cssText = "width: 100% !important; height: 100% !important;"; image.setAttribute("validate", "never"); var st = container.style; var dz = this.scrollZoom/100 * this.scrollTop; var currScale = 1, x, y, initialZoom = this.imgZoom/100 - 1; var hide, props = ["width", "height", "left", "top"], p = n => n + "px"; var set = (...args) => props.forEach((prop, ind) => st[prop] = p(args[ind])); (hide = () => { st.cssText = "position: fixed; display: none; z-index: 2147483647;"; currScale = 1; image.src = null; })(); container.onwheel = (e, ds = e.deltaY > 0 ? -dz : dz) => { if (currScale < .15 && ds < 0) return; st.transform = `scale(${currScale += ds})`; var {width, height, left, top, bottom, right} = container.getBoundingClientRect(); if (height < innerHeight) { if (top < 0) st.top = p(y -= top); if (bottom > innerHeight) st.top = p(y -= bottom - innerHeight); } if (width < innerWidth) { if (left < 0) st.left = p(x -= left); if (right > innerWidth) st.left = p(x -= right - innerWidth); } } (this.receiveMessage = msg => { var {src, width, height, left, top} = msg.data; image.src = src; left -= mozInnerScreenX; top -= mozInnerScreenY; set(width, height, x = left, y = top); st.display = "block"; container.onwheel(null, initialZoom); window.addEventListener("mousedown", hide, {once: true, capture: true}); })(msg); }, handleEvent(e) { if (!gContextMenu.onImage) return; var menuitem = document.createXULElement("menuitem"); menuitem.setAttribute("label", "Увеличить размер"); menuitem.className = "menuitem-iconic"; menuitem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADZElEQVR42oXSe0xbVRwH8N8597a35e7SAmUFukGhY66AMiNzw4GvTCQLCssc4pQsmTOa+ERMlrktW1zigpnEuWn8x2eMmiVGMBDCFjS+cJHEDIk8RoSNV1+3tLWX3t72nnO8sETJFrfvP7/k5Pw+Ob9fDoLrYi8ow9GFUbq+5aRLrGraqQcX6hlF2wkFEWn6EDIJAyQy9+3VT58cWb6PrmvmjGZS/FSHlxbXtbtLobGqJlPKMhNepWb0V8hKpi8FNd/gzCCogbdmvtg/8C9gz9+Eor5x5nn2tDOZ98Dx2i3C/uYai9mOGCxiDQIIg1/PgUCEhyvDMox9PXYBkPzaaoAzAFL0yle7ShtqO/eWJ9w1vJ1oGsVzYhTNATMQG4Q1G40ldDw6PB339fs7VgMmA0jnHfioo6F9Z3tDYYJzKSZKMYcDvAILiICfZUNYEYFixMKpKBk8MfTTasBsACnngU/6Wg4+VL/VFSOmBHAYY1BAhzAvgmyMEIkh0EUOBD1Eu49eStwA5D3z4TcPv9TYdHvxEhXSGgaEIMkJkKAS+ONmSKYolOVqMBlRSd8bv8v/AQXlJoiHUE5rZ1tFa/Nhj1uVrCaNMoQxYSaIqDxAGqAuQ2XZ1iS8HUTpkZMXe1eATOdtiCcJblGe1a3PnWp0uEvfv3tbeX5RhSet/q3wxh6xgAncZUmw2hxEryQx9/LHE7I2RV5HNudGFAtcZsuQd919u/kiz56JOwobcjd6xerqKnB4HIB4RvMzCM1DGj8X0GD64pL2Xdf850z+4djKC8wl24XUpj1P75sdfe/+sSHoq3uQnSuwa+s2Vy5uubd2jQWUTAYchJK8HpyIzvv7p/rMkV/OzPeeGEWi+x6LufiR573h8VO7Zr4n9fEZNeiqXHOofFvPsKPkS1fKsX5JU6uNZQh8Wh/hRcuvOC3/fLXrcGj52yOo7zzU9udvbzbN9uglggK2MhsnvfiE0tY9tfed7vM98D+x53tx1DdG0Z2b97Ejf3SRSiGGCysyENvdoipZa4+/8NmPp8+N+Ei2ZEVpQhG71rdcqFFozD+xcoQugFUvlDS8wWsl8Uebk5C79ujjHwyc6R/309ysDBRauEzhJkG9ErAdG0xEe6yVkwqcr+549/zZgcmQ7pAEkH2TDG6RfwCoJI0uEWJP5QAAAABJRU5ErkJggg=="); menuitem.setAttribute("oncommand", "handleCommand();"); e.target.append(menuitem); menuitem.handleCommand = () => this.cmd(); this.handleEvent = () => menuitem.hidden = !gContextMenu.onImage; }, cmd() { var msg = this.msg = "UCF:GetImageScreenRectForMosuseZoom"; var code = `(targetIdentifier => { var image = ChromeUtils.import("resource://gre/modules/ContentDOMReference.jsm") .ContentDOMReference.resolve(targetIdentifier); var mm = image.ownerGlobal.docShell.messageManager; var rect = image.getBoundingClientRect(); var win = image.ownerGlobal; var x = rect.left, y = rect.top; var parentFrame = win.frameElement; while (parentFrame) { win = parentFrame.ownerGlobal; let cstyle = win.getComputedStyle(parentFrame); let framerect = parentFrame.getBoundingClientRect(); x += framerect.left + parseFloat(cstyle.borderLeftWidth) + parseFloat(cstyle.paddingLeft); y += framerect.top + parseFloat(cstyle.borderTopWidth) + parseFloat(cstyle.paddingTop); parentFrame = win.frameElement; } x += win.mozInnerScreenX; y += win.mozInnerScreenY; var fullZoom = win.windowUtils.fullZoom; mm.sendAsyncMessage("${msg}", { src: image.currentSrc, left: x * fullZoom, top: y * fullZoom, width: rect.width * fullZoom, height: rect.height * fullZoom, } ); })(`; messageManager.addMessageListener(msg, this); (this.cmd = () => { var {osPid} = gContextMenu.actor.manager.browsingContext.currentWindowGlobal; if (osPid == -1) osPid = Services.appinfo.processID; for(var ind = 0, len = Services.ppmm.childCount; ind < len; ind++) { var pmm = Services.ppmm.getChildAt(ind); if (pmm.osPid == osPid) break; } pmm.loadProcessScript("data:;charset=utf-8," + encodeURIComponent( code + JSON.stringify(gContextMenu.targetIdentifier) + ")" ), false); })(); }, destructor() { this.popup.removeEventListener("popupshowing", this); if (this.msg) messageManager.removeMessageListener(this.msg, this); }, }).init(this);
Отсутствует
font-size
Намекаешь, что надо через userChrome.css регулировать? Эт я сделал, шрифт уменьшил, иконки приобрели нормальный вид. А в саму кнопку не можешь добавить регулировку шрифта, или сделать, чтоб она не влияла на другие иконки?
иконки от дополнений
???
Ну иконки от дополнений, которые их пихают в адресную строку. У меня это Scroll Up Folder и Save-To-Read
Отсутствует
Ну вот например открывается в контенере несколько вкладок
Потом все вкладки закрываются а контейнер созданный остается существовать
Можно ли сделать чтобы после закрытия последней вкладки контейнера он удалялся?
Что-то я сомневаюсь, что смогу это записать.
(async (sel, self) => ({ icon: "circle", colors: [ "mediumseagreen", "silver", "crimson", "blue", "peru", ], initColors() { var colorName = "ucf-gen"; var css = "@-moz-document url(about:preferences#containers)," + " url-prefix(chrome://browser/content/browser.x) {\n"; this.colors.forEach((color, ind) => { var [ic, tc] = color.split(/\s*\|\s*/); css += `\t.identity-color-${colorName}${ind} {\n` + `\t\t--identity-tab-color: ${tc || ic};\n` + `\t\t--identity-icon-color: ${ic};\n\t}\n` }); var url = "data:text/css;charset=utf-8," + 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 len = this.colors.length; var pref = "ucf.openInGeneratedContainer.lastColor"; var ind = Math.min(Services.prefs.getIntPref(pref, -1), len - 1); this.nextColor = () => { var next = ind + 1; Services.prefs.setIntPref(pref, ind = next == len ? 0 : next); return colorName + ind; } }, quit: false, init(topic) { Services.obs.addObserver(self = this, topic); Services.obs.addObserver(function quit(s, t) { self.quit = true; Services.obs.removeObserver(self, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); this.initColors(); this.newUsercontext = name => { var id = this.cis.create( name || `[ ${this.cis._lastUserContextId + 1} ]`, this.icon, this.nextColor() ).userContextId; this.saveGens(this.gens.add(id)); return id; } var cpref = "ucf.openInGeneratedContainer.containers"; this.gens = new Set( Services.prefs.getStringPref(cpref, "").split(",").map(Number).filter(Boolean) ); this.saveGens = () => Services.prefs.setStringPref(cpref, Array.from(this.gens).join(",")); }, observe(doc) { var list = doc.querySelectorAll(sel); if (!list.length) return; var menuitem = doc.createXULElement("menuitem"); for(var args of Object.entries({ selectiontype: "single", oncommand: "cmd(window)", nodetype: "folder|query", selection: "folder|query", label: "Открыть всё в контейнере", id: "placesContext_openContainer:tabs:newUsercontext" })) menuitem.setAttribute(...args); menuitem.cmd = this.cmd; menuitem.rnd = menuitem.constructor.prototype.render; menuitem.render = this.render; var [m1, m2] = menuitem.list = Array.from(list); (m2 || m1).after(menuitem); if (doc.documentElement.getAttribute("windowtype") != "navigator:browser") return; for(var btn of [ doc.getElementById("tabs-newtab-button"), doc.getElementById("new-tab-button") || doc.ownerGlobal.gNavToolbox.palette.querySelector("#new-tab-button") ]) if (btn) btn.checkForMiddleClick = this.click; var win = doc.ownerGlobal; this.redefDoSearch(win, win.customElements.get("searchbar").prototype); win.gBrowser.tabContainer.addEventListener("TabClose", this.tabClose); win.addEventListener("unload", this.winUnload, {once: true}); }, winUnload(e) { var win = e.target.ownerGlobal; win.removeEventListener("TabClose", self.tabClose); if (self.quit) return; var gb = win.gBrowser; if (gb) for(var tab of gb.tabs) self.tabClose(null, tab); }, closed: new Set(), cis: ChromeUtils.import("resource://gre/modules/ContextualIdentityService.jsm") .ContextualIdentityService, tabClose(e, tab = e.target) { var id = +tab.getAttribute("usercontextid"); id && self.gens.has(id) && self.closed.add(id); self.closed.size == 1 && ChromeUtils.idleDispatch(self.meaybeRemove); }, meaybeRemove() { var ids = Array.from(self.closed); self.closed.clear(); for(var id of ids) self.meaybeRemoveById(id); }, meaybeRemoveById(id) { for(var win of CustomizableUI.windows) if (win.document.querySelector(`tab.tabbrowser-tab[usercontextid="${id}"]`)) return; this.saveGens(this.gens.delete(id)); this.cis.remove(id); }, redefDoSearch(win, proto) { var code = `(openTrustedLinkIn => [ {${proto.doSearch}}, openTrustedLinkIn ])( function otl(url, where, params) { if (where != "current") params.userContextId = otl.newUsercontext( document.getElementById("searchbar").value ); openTrustedLinkIn(url, where, params); } );`; (this.redefDoSearch = (win, proto) => { var [obj, func] = win.eval(code); Object.assign(proto, obj); func.newUsercontext = this.newUsercontext; })(win, proto); }, click(btn, e) { if (!(e.button != 2 || e.ctrlKey || e.shiftKey)) { var txt = e.view.readFromClipboard(); if (txt) { var urls = txt.split("\n").map(self.map).filter(Boolean); if (urls.length) return e.preventDefault(), self.openFromClipboard(e.view, urls); } } e.view.checkForMiddleClick(btn, e); }, eo: Object.create(null), map(str) { str = str.trim(); try { var scheme = Services.io.extractScheme(str); var ph = Services.io.getProtocolHandler(scheme); if (ph.scheme == scheme) return Services.io.newURI(str) && {uri: str}; } catch {} }, openFromClipboard(win, urls) { if (win.OpenInTabsUtils.confirmOpenInTabs(urls.length, win)) urls.load = true, this.open(win, this.eo, urls); }, async render() { this.rnd(); await new Promise(this.ownerGlobal.requestAnimationFrame); this.hidden || (this.hidden = this.list.every(self.every)); }, every: node => node.disabled || node.hidden, cmd(win) { var view = this.parentNode._view; var node = win.document.popupNode; node = node._placesView && node._placesView.result.root; self.open(win, node || view.selectedNode || view.result.root); }, open(win, node, list) { var gbw = Cu.import("resource:///modules/PlacesUIUtils.jsm", {}).getBrowserWindow; var w = gbw(win); this.pu = w.PlacesUIUtils; this.fs = w.PlacesUtils.favicons; this.sysp = w.E10SUtils.SERIALIZED_SYSTEMPRINCIPAL; (this.open = (win, node, list) => { this.openURLs(gbw(win), list || win.PlacesUtils.getURLsForContainerNode(node)); node.bookmarkGuid && this.pu.doCommand(win, "placesCmd_delete"); })(win, node, list); }, async openURLs(win, urls) { var userContextId = this.newUsercontext(); var mark = !win.PrivateBrowsingUtils.isWindowPrivate(win); var {load} = urls, gb = win.gBrowser, pos = gb.selectedTab._tPos; for(var {uri, title, isBookmark} of urls) try { if (mark) isBookmark ? this.pu.markPageAsFollowedBookmark(uri) : this.pu.markPageAsTyped(uri); if (load) { gb.addTrustedTab(uri, {index: ++pos, userContextId}); continue; } var state = {userContextId, entries: [{ url: uri, title: title || uri, triggeringPrincipal_base64: this.sysp }]}; var [,, data, mime] = await new Promise( resolve => this.fs.getFaviconDataForPage( Services.io.newURI(uri), (...args) => resolve(args), 16 ) ); if (data.length) state.image = `data:${ mime || "image/x-icon" };base64,${ btoa(String.fromCharCode(...data)) }`; var tab = gb.addTrustedTab(null, {index: ++pos, userContextId}); win.SessionStore.setTabState(tab, state); } catch {}; } }).init("chrome-document-loaded"))( "#placesContext_openBookmarkContainer\\:tabs,#placesContext_openContainer\\:tabs" );
Ну иконки от дополнений, которые их пихают в адресную строку. У меня это Scroll Up Folder и Save-To-Read
Вот так у меня выглядит на нестилизированном профиле (сверху).
Но, если принудительно выкрутить font-size, то да, вытягивает (снизу).
data:image/png;base64,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
А в саму кнопку не можешь добавить регулировку шрифта, или сделать, чтоб она не влияла на другие иконки?
Ну, я же не владею какой-то высокой CSS-магией,
но, чтобы не влияла, вроде как работает min-height.
(async id => ({ style: `@-moz-document url(chrome://browser/content/browser.xhtml) { #${id} { min-height: 0 !important; } #${id}-label { font-size: 22px !important; } }`, 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}"><label id="${id += "-label"}"/></hbox>` ); Cc["@mozilla.org/content/style-sheet-service;1"] .getService(Ci.nsIStyleSheetService) .loadAndRegisterSheet(Services.io.newURI( "data:text/css;charset=utf-8," + encodeURIComponent(this.style) ), Ci.nsIStyleSheetService.USER_SHEET); delete this.style; this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); (this.observe = async win => { this.timer.cancel(); await new Promise(ChromeUtils.idleDispatch); win.document.getElementById("star-button-box") .after(win.document.importNode(df, true)); this.notify(); })(win); }, async notify() { var info = await ChromeUtils.requestProcInfo(); var bytes = info.residentSetSize; for(var child of info.children) bytes += child.residentUniqueSize; this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT); var prev = this.val; if ((this.val = this.mgb(bytes)) != prev) for(var win of CustomizableUI.windows) { var lab = win.document.getElementById(id); if (lab) lab.value = this.val; } }, mgb: bytes => bytes < 1073741824 ? Math.round(bytes / 1048576) + "MB" : (bytes / 1073741824).toFixed(2) + "GB" }).init("browser-delayed-startup-finished"))("ucf-mem-indicator");
Отсутствует
Что-то я сомневаюсь, что смогу это записать.
Так работает же, класс, спасибо, благодарю!
UPD
Блин, после перезагрузки браузера контейнеры удаляются даже те в которых открыты вкладки
Отредактировано Stkvsky (23-04-2021 15:31:20)
Отсутствует
Многие сайты показывают Картинки под div, которые нельзя сохранить.
Посоветуйте, каким расширением или user-скриптом сохранять такие картинки или убрать перекрывающий элемент страницы?
На данном сайте (https://mose.live) при клике по постеру открываются фото, которые нельзя сохранить.
Отредактировано Dobrov (23-04-2021 14:10:20)
Отсутствует
Многие сайты показывают Картинки под div, которые нельзя сохранить.
Посоветуйте, каким расширением или user-скриптом сохранять такие картинки или убрать перекрывающий элемент страницы?На данном сайте (https://mose.live) при клике по постеру открываются фото, которые нельзя сохранить.
Можно сделать скрин.
Отсутствует
Подскажите по кнопе AutoCopy. Может кто всё лишнее убрать из кода, нужна только функция автокопирования в буфер.
this.closest("toolbarpaletteitem") || (script => { var id = `CB${_id.slice(20)}:Autocopy`, pid = id + "Parent"; var nsvoStr = `Components.utils.import("resource://gre/modules/Services.jsm", {})`; var nsvo = eval(nsvoStr), {Services} = nsvo, parent = nsvo[pid]; if (!parent) { var cid = id + "Child", u = code => "data:," + encodeURIComponent(code); var pref = "CB.Autocopy.settings", topic = "quit-application-granted"; var PREF_ENABLED = 1; (parent = nsvo[pid] = { init() { this.readSettings(); if (!this[PREF_ENABLED]) return; this.initChild(); }, destroy(reason) { var ud = reason[5] == "e"; if (ud || !this.obsAdded) this.saveSettings(); delete nsvo[pid]; if (reason == "delete") Services.prefs.clearUserPref(pref); if (!this[PREF_ENABLED]) return; this.destroyChild(); }, get processURL() { delete this.processURL; this.frameURL = u(`${nsvoStr}["${cid}"].init(this);`); return this.processURL = u(script.replace(/%ID%/g, cid) .replace("%NSVO%", nsvoStr) ); }, get frameURLDestroy() { delete this.frameURLDestroy; this.processURLDestroy = u(`${nsvoStr}["${cid}"].forget();`); return this.frameURLDestroy = u(`${nsvoStr}["${cid}"].destroy(this);`); }, initChild() { Services.ppmm.loadProcessScript(this.processURL, true); Services.mm.loadFrameScript(this.frameURL, true); }, destroyChild() { Services.mm.removeDelayedFrameScript(this.frameURL); Services.mm.loadFrameScript(this.frameURLDestroy, false); Services.ppmm.removeDelayedProcessScript(this.processURL); Services.ppmm.loadProcessScript(this.processURLDestroy, false); }, readSettings() { this.prefVal = Services.prefs.getIntPref(pref, 3); for(var setting of [PREF_ENABLED]) this[setting] = Boolean(this.prefVal & setting); }, saveSettings() { var settings = 0; for(var setting of [PREF_ENABLED]) if (this[setting]) settings += setting; if (this.prefVal != settings) Services.prefs.setIntPref(pref, settings); }, obsAdded: false, setObserver(set) {this.obsAdded = set ? Services.obs.addObserver(this, topic, false) : Services.obs.removeObserver(this, topic); }, observe() { Services.obs.removeObserver(this, topic); this[PREF_ENABLED] = false; this.saveSettings(); } }).init(); } parent.register(this); addDestructor(reason => parent.unregister(this, reason), parent); }) (`(nsvo => (nsvo["%ID%"] = { x: -1, y: -1, d: false, handleEvent(e) {e.button || this[e.type](e);}, mousedown(e) {this.x = e.screenX; this.y = e.screenY, this.down = true;}, mouseup(e) { var {down} = this; this.down = false; if (!down) return; if (e.screenX == this.x && e.screenY == this.y && (e.detail == 1 || e.target.matches( "textarea[disabled],input[disabled],button,select,summary" ))) return; var name = e.originalTarget.nodeName; if (/^(?:(?:xul:)?(?:slider|scrollbarbutton)|resizer)$/.test(name)) return; this.x = this.y = -1; var win = this.getFocusedWin(e.target.ownerGlobal); var sel = win.getSelection(); if (sel.toString()) { (win.docShell || win.document.docShell).doCommand("cmd_copy", null, win); } }, get fm() { delete this.fm; return this.fm = Components.classes["@mozilla.org/focus-manager;1"] .getService(Components.interfaces.nsIFocusManager); }, getFocusedWin(win) { var focusedWin = {}; var elm = this.fm.getFocusedElementForWindow(win.top, true, focusedWin); return focusedWin.value; }, count: 0, init(cfmm) { this.count += 1; cfmm.addEventListener("mousedown", this); cfmm.addEventListener("mouseup", this); if (this.count == 1) this.cpmm.addMessageListener("%ID%:FromParent", this); }, destroy(cfmm) { this.count -= 1; cfmm.removeEventListener("mousedown", this); cfmm.removeEventListener("mouseup", this); if (!this.count) this.cpmm.removeMessageListener("%ID%:FromParent", this); }, }).cpmm = this)(%NSVO%);`)
Это я уже всё что мог лишнее убрал, но иконка кнопки стала мутной, значит что то не то.
Или может скрипт есть?
Отредактировано momo2000 (24-04-2021 10:29:53)
Отсутствует
momo2000
https://forum.mozilla-russia.org/viewto … 93#p785193
Add, или такой вариант
Отредактировано kokoss (24-04-2021 16:36:45)
Win7
Отсутствует
Или может скрипт есть?
Можно попробовать создать JSM'ку
и импортировать её из custom_script.js
var EXPORTED_SYMBOLS = ["AutoCopyChild"]; ChromeUtils.domProcessChild.childID || ChromeUtils.registerWindowActor("AutoCopy", { messageManagerGroups: ["browsers"], allFrames: true, child: {moduleURI: __URI__, events: {DOMDocElementInserted: {}}} }); var re = /\S/; var QueryInterface = ChromeUtils.generateQI(["nsISelectionListener"]); var reasons = ["MOUSEUP", "KEYPRESS", "SELECTALL"] .map(reason => Ci.nsISelectionListener[reason + "_REASON"]); class AutoCopyChild extends JSWindowActorChild { constructor() { super(); this.listener = { QueryInterface, notifySelectionChanged: (d, sel, reason) => reasons.includes(reason) && re.test(sel) && this.docShell.doCommand("cmd_copy") }; } async handleEvent() { await new Promise(ChromeUtils.idleDispatch); (this.sel = this.contentWindow.getSelection()) .addSelectionListener(this.listener); } didDestroy() { this.sel.removeSelectionListener(this.listener); this.sel = this.listener = null; } }
Отредактировано Dumby (25-04-2021 22:12:52)
Отсутствует
Dumby
(async (sel, self) => ({ icon: "circle", colors: [ "mediumseagreen", "silver", "crimson", "blue", "peru", ], initColors() { var colorName = "ucf-gen"; var css = "@-moz-document url(about:preferences#containers)," + " url-prefix(chrome://browser/content/browser.x) {\n"; this.colors.forEach((color, ind) => { var [ic, tc] = color.split(/\s*\|\s*/); css += `\t.identity-color-${colorName}${ind} {\n` + `\t\t--identity-tab-color: ${tc || ic};\n` + `\t\t--identity-icon-color: ${ic};\n\t}\n` }); var url = "data:text/css;charset=utf-8," + 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 len = this.colors.length; var pref = "ucf.openInGeneratedContainer.lastColor"; var ind = Math.min(Services.prefs.getIntPref(pref, -1), len - 1); this.nextColor = () => { var next = ind + 1; Services.prefs.setIntPref(pref, ind = next == len ? 0 : next); return colorName + ind; } }, quit: false, init(topic) { Services.obs.addObserver(self = this, topic); Services.obs.addObserver(function quit(s, t) { self.quit = true; Services.obs.removeObserver(self, topic); Services.obs.removeObserver(quit, t); }, "quit-application-granted"); this.initColors(); this.newUsercontext = name => { var id = this.cis.create( name || `[ ${this.cis._lastUserContextId + 1} ]`, this.icon, this.nextColor() ).userContextId; this.saveGens(this.gens.add(id)); return id; } var cpref = "ucf.openInGeneratedContainer.containers"; this.gens = new Set( Services.prefs.getStringPref(cpref, "").split(",").map(Number).filter(Boolean) ); this.saveGens = () => Services.prefs.setStringPref(cpref, Array.from(this.gens).join(",")); }, observe(doc) { var list = doc.querySelectorAll(sel); if (!list.length) return; var menuitem = doc.createXULElement("menuitem"); for(var args of Object.entries({ selectiontype: "single", oncommand: "cmd(window)", nodetype: "folder|query", selection: "folder|query", label: "Открыть всё в контейнере", id: "placesContext_openContainer:tabs:newUsercontext" })) menuitem.setAttribute(...args); menuitem.cmd = this.cmd; menuitem.rnd = menuitem.constructor.prototype.render; menuitem.render = this.render; var [m1, m2] = menuitem.list = Array.from(list); (m2 || m1).after(menuitem); if (doc.documentElement.getAttribute("windowtype") != "navigator:browser") return; for(var btn of [ doc.getElementById("tabs-newtab-button"), doc.getElementById("new-tab-button") || doc.ownerGlobal.gNavToolbox.palette.querySelector("#new-tab-button") ]) if (btn) btn.checkForMiddleClick = this.click; var win = doc.ownerGlobal; this.redefDoSearch(win, win.customElements.get("searchbar").prototype); win.gBrowser.tabContainer.addEventListener("TabClose", this.tabClose); win.addEventListener("unload", this.winUnload, {once: true}); }, winUnload(e) { var win = e.target.ownerGlobal; win.removeEventListener("TabClose", self.tabClose); if (self.quit) return; var gb = win.gBrowser; if (gb) for(var tab of gb.tabs) self.tabClose(null, tab); }, closed: new Set(), cis: ChromeUtils.import("resource://gre/modules/ContextualIdentityService.jsm") .ContextualIdentityService, tabClose(e, tab = e.target) { var id = +tab.getAttribute("usercontextid"); id && self.gens.has(id) && self.closed.add(id); self.closed.size == 1 && ChromeUtils.idleDispatch(self.meaybeRemove); }, meaybeRemove() { var ids = Array.from(self.closed); self.closed.clear(); for(var id of ids) self.meaybeRemoveById(id); }, meaybeRemoveById(id) { for(var win of CustomizableUI.windows) if (win.document.querySelector(`tab.tabbrowser-tab[usercontextid="${id}"]`)) return; this.saveGens(this.gens.delete(id)); this.cis.remove(id); }, redefDoSearch(win, proto) { var code = `(openTrustedLinkIn => [ {${proto.doSearch}}, openTrustedLinkIn ])( function otl(url, where, params) { if (where != "current") params.userContextId = otl.newUsercontext( document.getElementById("searchbar").value ); openTrustedLinkIn(url, where, params); } );`; (this.redefDoSearch = (win, proto) => { var [obj, func] = win.eval(code); Object.assign(proto, obj); func.newUsercontext = this.newUsercontext; })(win, proto); }, click(btn, e) { if (!(e.button != 2 || e.ctrlKey || e.shiftKey)) { var txt = e.view.readFromClipboard(); if (txt) { var urls = txt.split("\n").map(self.map).filter(Boolean); if (urls.length) return e.preventDefault(), self.openFromClipboard(e.view, urls); } } e.view.checkForMiddleClick(btn, e); }, eo: Object.create(null), map(str) { str = str.trim(); try { var scheme = Services.io.extractScheme(str); var ph = Services.io.getProtocolHandler(scheme); if (ph.scheme == scheme) return Services.io.newURI(str) && {uri: str}; } catch {} }, openFromClipboard(win, urls) { if (win.OpenInTabsUtils.confirmOpenInTabs(urls.length, win)) urls.load = true, this.open(win, this.eo, urls); }, async render() { this.rnd(); await new Promise(this.ownerGlobal.requestAnimationFrame); this.hidden || (this.hidden = this.list.every(self.every)); }, every: node => node.disabled || node.hidden, cmd(win) { var view = this.parentNode._view; var node = win.document.popupNode; node = node._placesView && node._placesView.result.root; self.open(win, node || view.selectedNode || view.result.root); }, open(win, node, list) { var gbw = Cu.import("resource:///modules/PlacesUIUtils.jsm", {}).getBrowserWindow; var w = gbw(win); this.pu = w.PlacesUIUtils; this.fs = w.PlacesUtils.favicons; this.sysp = w.E10SUtils.SERIALIZED_SYSTEMPRINCIPAL; (this.open = (win, node, list) => { this.openURLs(gbw(win), list || win.PlacesUtils.getURLsForContainerNode(node)); node.bookmarkGuid && this.pu.doCommand(win, "placesCmd_delete"); })(win, node, list); }, async openURLs(win, urls) { var userContextId = this.newUsercontext(); var mark = !win.PrivateBrowsingUtils.isWindowPrivate(win); var {load} = urls, gb = win.gBrowser, pos = gb.selectedTab._tPos; for(var {uri, title, isBookmark} of urls) try { if (mark) isBookmark ? this.pu.markPageAsFollowedBookmark(uri) : this.pu.markPageAsTyped(uri); if (load) { gb.addTrustedTab(uri, {index: ++pos, userContextId}); continue; } var state = {userContextId, entries: [{ url: uri, title: title || uri, triggeringPrincipal_base64: this.sysp }]}; var [,, data, mime] = await new Promise( resolve => this.fs.getFaviconDataForPage( Services.io.newURI(uri), (...args) => resolve(args), 16 ) ); if (data.length) state.image = `data:${ mime || "image/x-icon" };base64,${ btoa(String.fromCharCode(...data)) }`; var tab = gb.addTrustedTab(null, {index: ++pos, userContextId}); win.SessionStore.setTabState(tab, state); } catch {}; } }).init("chrome-document-loaded"))( "#placesContext_openBookmarkContainer\\:tabs,#placesContext_openContainer\\:tabs" );
Отредактировано Stkvsky (24-04-2021 18:13:02)
Отсутствует