Custom Buttons не отключается в приватном режиме, хотя соответствующая птичка поставлена. Это исправимо?
Отсутствует
Dumby
А можно как-то стили на кнопки по другому задать? А то в HELP типа, этого и стили в custom_падают...А если не через #nav-bar-customization-target , то в кнопке стиль не того.
#nav-bar-customization-target > #id > image {height: 18px !important; width: 18px !important; margin-left: -1px !important; margin-right: -1px !important;}
Теперь так: #nav-bar > hbox > #id{background: none !important; }
А раньше просто #id{background: none !important; } и этого хватало... Да, и сам код в ini
var style = custombutton.buttonGetHelp(self).replace(/id/g, _id); var uri = makeURI('data:text/css,'+ encodeURIComponent(style)); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(uri, 0);
Отредактировано ВВП (10-12-2021 17:20:56)
Отсутствует
Custom Buttons не отключается в приватном режиме, хотя соответствующая птичка поставлена. Это исправимо?
Никогда и не отключался. Исправлять нечего.
ВВП
Уж не знаю о чём ты, но, помимо отсутствия деструктора,
/id/g — не слишком ли странно? Так ведь и какой-нибудь width разреплейситься.
Отсутствует
Приветствую всех! Как можно имитировать нахождение на странице как бы в развёрнутом состоянии в свёрнутом браузере? На некоторых сайтах при свёрнутом режиме некоторые функции переходят в стадию заморозки и не подгружаются.
Отредактировано Senflex (13-12-2021 17:33:13)
Отсутствует
Dumby, приветствую!
Вы помогли написать код для аддона ContextSearch https://forum.mozilla-russia.org/viewto … 07#p770807
В результате работы кода в контекстном меню сразу виднелись значки всех поисковых машин
Автор ContextSearch обновил свой аддон и теперь наш код не работает
Можно ли попростить вас подправить?
Я думал просто изменился ID аддона, но там что-то посерьезней в чем я совершенно не разбираюсь.
вот обновленный аддон
https://github.com/ssborbis/ContextSear … tag/1.32a2
а вот код
/*ContextSearch-web-ext*/ (popup => { var id = "cswem-menugroup"; var mid = "_5dd73bb9-e728-4d1e-990b-c77d8e03670f_-menuitem-_search_engine_menu"; var css = ` #${id} { padding-left: 30px; display: grid; grid-template-columns: repeat(auto-fill, 32px); grid-auto-rows: 26px; } #${id} > menuitem { -moz-box-pack: center; } #${mid}, #${id}:empty, #${id} > menuitem > :not(.menu-iconic-left) { display: none; } `.replace(/;/g, " !important;"); var url = "data:text/css," + encodeURIComponent(css), type = windowUtils.USER_SHEET; windowUtils.loadSheetUsingURIString(url, type); var menugroup = document.createXULElement("menugroup"); menugroup.setAttribute("oncommand", "this.onclick(event)"); menugroup.id = id; menugroup.onclick = e => { var target = e.target.linkedMenuitem; if (!target) return; var handler = Services.els.getListenerInfoFor(target) .find(info => info.type == e.type).listenerObject; var {button, ctrlKey, shiftKey} = e; handler({button, ctrlKey, shiftKey, target, currentTarget: target}); } document.getElementById("context-searchselect").after(menugroup); addEventListener("popuphidden", e => { if (menugroup.firstChild && e.target == popup) menugroup.textContent = ""; }, false, popup); var fillMenugroup = menu => { var p = menu.querySelector(":scope > menupopup"); for(var menuitem of menu.getElementsByTagName("menuitem")) { var m = document.createXULElement("menuitem"); m.className = "menuitem-iconic"; m.setAttribute("image", menuitem.getAttribute("image")); var tt = menuitem.getAttribute("label"); if (menuitem.closest("menupopup") != p) tt = menuitem.closest("menu").getAttribute("label") + "\n" + tt; m.setAttribute("tooltiptext", tt); m.linkedMenuitem = menuitem; menugroup.append(m); } var lc = menugroup.lastChild; menugroup.style.setProperty( "height", (lc.screenY + lc.scrollHeight - menugroup.screenY) + "px", "important" ); } var mo = new MutationObserver(muts => { for(var mut of muts) for(var node of mut.addedNodes) if (node.id == mid) return fillMenugroup(node); }); mo.observe(popup, {childList: true}); addDestructor(() => { mo.disconnect(); menugroup.remove(); windowUtils.removeSheetUsingURIString(url, type); }); })(document.getElementById("contentAreaContextMenu")); (ss => ss.collapsed = !addDestructor(() => ss.collapsed = false))( document.getElementById("context-searchselect") );
Отредактировано leex (15-12-2021 15:13:41)
Отсутствует
Можно ли сделать, чтобы одна конкретная кнопка инициализировалась только на одном домене?
У меня есть кнопка, весь код которой заточен для одного домена. На остальных доменах кнопка просто висит и ничего не делает.
Отсутствует
Я думал просто изменился ID аддона
Изменился id <menu>.
Ещё, я смотрю, только событие "command" осталось.
(popup => { var id = "cswem-menugroup"; var mid = "_5dd73bb9-e728-4d1e-990b-c77d8e03670f_-menuitem-_root_menu"; var css = ` #${id} { padding-left: 30px; display: grid; grid-template-columns: repeat(auto-fill, 32px); grid-auto-rows: 26px; } #${id} > menuitem { -moz-box-pack: center; } #${mid}, #${id}:empty, #context-searchselect, #${id} > menuitem > :not(.menu-iconic-left) { display: none; } /* #${id} > menuitem > .menu-iconic-left > .menu-iconic-icon { margin-inline: 2px -3px; } */ `.replace(/;$/gm, " !important;"); var url = "data:text/css," + encodeURIComponent(css), type = windowUtils.USER_SHEET; windowUtils.loadSheetUsingURIString(url, type); var menugroup = document.createXULElement("menugroup"); menugroup.id = id; menugroup.hidden = true; var find = info => info.type == "command"; menugroup.setAttribute("oncommand", "handleCommand(event);"); menugroup.handleCommand = e => { var target = e.target.linkedMenuitem; var {button, ctrlKey, shiftKey, altKey, metaKey} = e; Services.els.getListenerInfoFor(target).find(find).listenerObject({ button, target, currentTarget: target, ctrlKey, shiftKey, altKey, metaKey }); } document.getElementById("context-searchselect").after(menugroup); addEventListener("popuphidden", e => { if (menugroup.firstChild && e.target == popup) menugroup.textContent = ""; }, false, popup); var fillMenugroup = menu => { var p = menu.querySelector(":scope > menupopup"); for(var menuitem of menu.getElementsByTagName("menuitem")) { var m = document.createXULElement("menuitem"); m.className = "menuitem-iconic"; m.setAttribute("image", menuitem.getAttribute("image")); var tt = menuitem.getAttribute("label"); if (menuitem.closest("menupopup") != p) tt = menuitem.closest("menu").getAttribute("label") + "\n" + tt; m.setAttribute("tooltiptext", tt); m.linkedMenuitem = menuitem; menugroup.append(m); } var lc = menugroup.lastChild; menugroup.style.setProperty( "height", (lc.screenY + lc.scrollHeight - menugroup.screenY) + "px", "important" ); } var mo = new MutationObserver(muts => { for(var mut of muts) for(var node of mut.addedNodes) if (node.id == mid) return fillMenugroup(node); }); mo.observe(popup, {childList: true}); addDestructor(() => { mo.disconnect(); menugroup.remove(); windowUtils.removeSheetUsingURIString(url, type); }); })(document.getElementById("contentAreaContextMenu"));
чтобы одна конкретная кнопка инициализировалась только
Словно сама госпожа Конкретность поцеловала в лоб.
Кнопка инициализируется при добавлении на DOM-дерево, cbClass.connectedCallback()
Отсутствует
Благодарю Dumby!
Все супер как и всегда
.
А можно ли попросить убрать из контекстного меню фразу
"добавить краткое имя для данного поиска"
Она появляется в контекстном меню, если выделить текст в любой поисковой строке, на любом сайте.
Этот пункт нам уже не нужен, так как мы используем аддон для этих целей
Отредактировано leex (15-12-2021 20:46:04)
Отсутствует
А можно ли попросить убрать из контекстного меню фразу
"добавить краткое имя для данного поиска"
Убрать — нет, а скрыть — вписал, надеюсь.
(popup => { var id = "cswem-menugroup"; var mid = "_5dd73bb9-e728-4d1e-990b-c77d8e03670f_-menuitem-_root_menu"; var css = ` #${id} { padding-left: 30px; display: grid; grid-template-columns: repeat(auto-fill, 32px); grid-auto-rows: 26px; } #${id} > menuitem { -moz-box-pack: center; } #${mid}, #${id}:empty, #context-searchselect, #context-keywordfield, #${id} > menuitem > :not(.menu-iconic-left) { display: none; } /* #${id} > menuitem > .menu-iconic-left > .menu-iconic-icon { margin-inline: 2px -3px; } */ `.replace(/;$/gm, " !important;"); var url = "data:text/css," + encodeURIComponent(css), type = windowUtils.USER_SHEET; windowUtils.loadSheetUsingURIString(url, type); var menugroup = document.createXULElement("menugroup"); menugroup.id = id; menugroup.hidden = true; var find = info => info.type == "command"; menugroup.setAttribute("oncommand", "handleCommand(event);"); menugroup.handleCommand = e => { var target = e.target.linkedMenuitem; var {button, ctrlKey, shiftKey, altKey, metaKey} = e; Services.els.getListenerInfoFor(target).find(find).listenerObject({ button, target, currentTarget: target, ctrlKey, shiftKey, altKey, metaKey }); } document.getElementById("context-searchselect").after(menugroup); var kwf = document.getElementById("context-keywordfield"); Object.defineProperty(kwf, "hidden", { configurable: true, enumerable: true, get: () => true, set() {} }); addEventListener("popuphidden", e => { if (menugroup.firstChild && e.target == popup) menugroup.textContent = ""; }, false, popup); var fillMenugroup = menu => { var p = menu.querySelector(":scope > menupopup"); for(var menuitem of menu.getElementsByTagName("menuitem")) { var m = document.createXULElement("menuitem"); m.className = "menuitem-iconic"; m.setAttribute("image", menuitem.getAttribute("image")); var tt = menuitem.getAttribute("label"); if (menuitem.closest("menupopup") != p) tt = menuitem.closest("menu").getAttribute("label") + "\n" + tt; m.setAttribute("tooltiptext", tt); m.linkedMenuitem = menuitem; menugroup.append(m); } var lc = menugroup.lastChild; menugroup.style.setProperty( "height", (lc.screenY + lc.scrollHeight - menugroup.screenY) + "px", "important" ); } var mo = new MutationObserver(muts => { for(var mut of muts) for(var node of mut.addedNodes) if (node.id == mid) return fillMenugroup(node); }); mo.observe(popup, {childList: true}); addDestructor(() => { mo.disconnect(); delete kwf.hidden; menugroup.remove(); windowUtils.removeSheetUsingURIString(url, type); }); })(document.getElementById("contentAreaContextMenu"));
Отсутствует
beggrr пишетчтобы одна конкретная кнопка инициализировалась только
Словно сама госпожа Конкретность поцеловала в лоб.
Кнопка инициализируется при добавлении на DOM-дерево, cbClass.connectedCallback()
А что именно надо конкретизировать?
Вот есть кнопка, она инициализируется вместе с остальными при запуске браузера.
Но остальные мне нужны постоянно, а эта только когда я открываю определенный сайт/домен.
Я взял весь код кнопки (вкладка инициализация, другого там нет) и заключил в условие
Теперь если домен "не тот", код просто не исполняется. Но кнопка то все равно потребляет ресурсы и нагружает браузер. Так вот я и думал, может можно сделать, чтоб она инициализировалась только если я захожу на определенный сайт?
Отсутствует
Вот есть кнопка, она инициализируется вместе с остальными при запуске браузера.
Но остальные мне нужны постоянно, а эта только когда я открываю определенный сайт/домен.
Я взял весь код кнопки (вкладка инициализация, другого там нет) и заключил в условие
Вот и переложи (добавь) код в одну из тех остальных, которые нужны постоянно.
А эту кнопку удали. Нет кнопки — нет и этой скряжной проблемы.
Отсутствует
Dumby
Возможно ли переделать эту кнопку для UCF?
/*Initialization Code*/ self._handleClick =()=> Translate.openPopup(this, "after_start"); var array = [ [ "Выделенный текст в G.Перевод (Auto –> Ru)", "https://translate.google.com/#view=home&op=translate&sl=auto&tl=ru&text=", "GTranslateEnRu", "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAACXBIWXMAAAAAAAAAAAHqZRakAAACy0lEQVQ4y32SX2iVdRjHP7/3fd7Xbe3M4aYzxW2gOMHUBNEisTRQ2NFwLgwz8sIlVDeiMBZCHIkgCTcpKFCv1IuEUep0HMwSEXWBiM4ksOafmqCVM/d6ztzO+/s9XrzHtXnh9/LH7/k+3z+PvNP+3/7D2ypbJO/8zekvc5ulqT3SH7aljHRssDTVH1dpao9093rLnuwIbY0xkns0/M2Hh8KPjCnj4cN+pLkj0tjB0e0pAyDVKY9/Iujvv6PGgFiFiWVK15krrHl9PtJ/3+IUjjxYxorcHWRdR6QYD1VwCgsHb03IZOaOUITEDr5+d4Rjl4XlDZa27+uHe3uvUVVVmXywFj4+FAKQ/dXDqfLtuRTTOcWGlUuRE62JvKf4YOvJW+lVk+pm1i/BOYe8vSdSq6AKJfGDZd+11p4dOyCKhwEUyJvSn4Fg/AeFtsYChRh2Zcuk9+pvOrm6ElXFWpsE8fmJgF3NBVThfF/Axc6D7NyyEVVNGHakC0SPDarQ/UcNrY1vcuX6DV6aWYc4B591BSgktM5w5PQvtKxdQRzHSGwtFEUm8FiwcCX3Bu4zfUoVkm2rGJfD6vey+nJ6BmGYCJXmjkiN8ZIVRapkHehw7sDRT6Zs4jkQB5gxGkaHAcIX3v+q8+aSVfPi38NQnIioc2Ctw/NU8/n4sGixhR3pAt1XfS796ZEqgcGh5P2n25Mb5r94o2FqdSlhGOL7hiDwUVVSKX+tOAem6NKYZGjOVMdrsxy7TwrWGfZdKGFeeQ8iPhZlIMoxo6aat5YuQpwmFnZ2/d9wT59HT583Gv2ATmNCxQL+vdtDaUlIy+rliEgxgyLBU6jq+FqKefz4Vy1bFz9mqJCj8/QFmt94NTmV7mfOdSwymYtlZ6/9nQMoL/cJXqmhtnYic+qmjdqW51WUySzKf/pFdsvc2RV7Z9WVEgQ+zlmMMYm1waG9TwBslkaEyL4QewAAAABJRU5ErkJggg==" ], [ "separator" ], [ "Выделенный текст в G.Перевод (Ru –> En)", "https://translate.google.com/#view=home&op=translate&sl=ru&tl=en&text=", "GTranslateRuEn", "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAACXBIWXMAAAAAAAAAAAHqZRakAAACy0lEQVQ4y32SX2iVdRjHP7/3fd7Xbe3M4aYzxW2gOMHUBNEisTRQ2NFwLgwz8sIlVDeiMBZCHIkgCTcpKFCv1IuEUep0HMwSEXWBiM4ksOafmqCVM/d6ztzO+/s9XrzHtXnh9/LH7/k+3z+PvNP+3/7D2ypbJO/8zekvc5ulqT3SH7aljHRssDTVH1dpao9093rLnuwIbY0xkns0/M2Hh8KPjCnj4cN+pLkj0tjB0e0pAyDVKY9/Iujvv6PGgFiFiWVK15krrHl9PtJ/3+IUjjxYxorcHWRdR6QYD1VwCgsHb03IZOaOUITEDr5+d4Rjl4XlDZa27+uHe3uvUVVVmXywFj4+FAKQ/dXDqfLtuRTTOcWGlUuRE62JvKf4YOvJW+lVk+pm1i/BOYe8vSdSq6AKJfGDZd+11p4dOyCKhwEUyJvSn4Fg/AeFtsYChRh2Zcuk9+pvOrm6ElXFWpsE8fmJgF3NBVThfF/Axc6D7NyyEVVNGHakC0SPDarQ/UcNrY1vcuX6DV6aWYc4B591BSgktM5w5PQvtKxdQRzHSGwtFEUm8FiwcCX3Bu4zfUoVkm2rGJfD6vey+nJ6BmGYCJXmjkiN8ZIVRapkHehw7sDRT6Zs4jkQB5gxGkaHAcIX3v+q8+aSVfPi38NQnIioc2Ctw/NU8/n4sGixhR3pAt1XfS796ZEqgcGh5P2n25Mb5r94o2FqdSlhGOL7hiDwUVVSKX+tOAem6NKYZGjOVMdrsxy7TwrWGfZdKGFeeQ8iPhZlIMoxo6aat5YuQpwmFnZ2/d9wT59HT583Gv2ATmNCxQL+vdtDaUlIy+rliEgxgyLBU6jq+FqKefz4Vy1bFz9mqJCj8/QFmt94NTmV7mfOdSwymYtlZ6/9nQMoL/cJXqmhtnYic+qmjdqW51WUySzKf/pFdsvc2RV7Z9WVEgQ+zlmMMYm1waG9TwBslkaEyL4QewAAAABJRU5ErkJggg==" ], [ "separator" ], [ "Выделенный текст в Y.Перевод (Auto –> Ru)", "https://translate.yandex.ru/?lang=auto-ru&text=", "YTranslateEnRu", "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAACXBIWXMAAAAAAAAAAAHqZRakAAACnElEQVQ4y22TXyidYRzHP297at7N2cmx4ghXLg7bboy8b1ygxFlTsivypxWiLPk37kYuRoqMqWWFC/+WbE3LWtRWJ+c5h62shXCh6KSUZSesdk7PLjDH8r39fn+f5/n+6icA0tLSmoSCVjye5wLAMIxJoTweld/RgeBMhmGo6elphIJp4BFSosXGaqGJAyml7RyiampqAJRQoDg+pmJuDk3TlgULC9DWxuvJyTsarP5jnI2+z87Ozrfb7WRmZlJZWRkQAArmgDykxFdYyE5qKk1NTQBCKPgNXKelBRoaiImKYtVm++B3OFqllD+EBmEK/tDVJejqAvDmHBw8ZHERgEt/ME1TV0p5gWggV0r57VLAbrcf9/b2srKywu7u7lelVEroJp74fD62trbQdZ2ZmRk0TfsoFNwG9pGSX0LQMD5OY2MjPT09VFVV+QSwD4Dfzy2LhRdTU3TGxODxeAgLC0s7fcLlguhosFi44fczPz9f7Xa7X1202N6GoyNYXweHg3PzPPCYkpJhABwOgIjQZpdqhiojIyMiGAx+UkqlJCYmsra2FmoHgAop5eiVANM07wUCge/x8fEkJydTXFzMyMgIOzs76LqO1+sVwIhhGA8uARTcA9LnNjfzP0dGshwMsh8Xh8ViISEhAavVimmaOJ1O2tvbAfKFAh1wAckA5OTgLCvDWVp6Sl1e5t3eHgVDQ/T39zMxMUFWVhYAmqY9E4AXuAtAXh4MDsLAAIyOQnk5KEXB2BitS0t8sdkAcLvdb4QQ1S6X66cAYgBIT4fZWdjbg/p6CA+Hujro6wOgc2OjVoOX/+9LAE50fZGiomskJcHm5oXb3Q1WKxwevr1qGEBo4OXkRKja2vvAUyAXuAms09w8DAxqp0dzpf4Cgj71r0vtOwcAAAAASUVORK5CYII=" ], [ "separator" ], [ "Выделенный текст в Y.Перевод (Ru –> En)", "https://translate.yandex.ru/?lang=ru-en&text=", "YTranslateRuEn", "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAACXBIWXMAAAAAAAAAAAHqZRakAAACnElEQVQ4y22TXyidYRzHP297at7N2cmx4ghXLg7bboy8b1ygxFlTsivypxWiLPk37kYuRoqMqWWFC/+WbE3LWtRWJ+c5h62shXCh6KSUZSesdk7PLjDH8r39fn+f5/n+6icA0tLSmoSCVjye5wLAMIxJoTweld/RgeBMhmGo6elphIJp4BFSosXGaqGJAyml7RyiampqAJRQoDg+pmJuDk3TlgULC9DWxuvJyTsarP5jnI2+z87Ozrfb7WRmZlJZWRkQAArmgDykxFdYyE5qKk1NTQBCKPgNXKelBRoaiImKYtVm++B3OFqllD+EBmEK/tDVJejqAvDmHBw8ZHERgEt/ME1TV0p5gWggV0r57VLAbrcf9/b2srKywu7u7lelVEroJp74fD62trbQdZ2ZmRk0TfsoFNwG9pGSX0LQMD5OY2MjPT09VFVV+QSwD4Dfzy2LhRdTU3TGxODxeAgLC0s7fcLlguhosFi44fczPz9f7Xa7X1202N6GoyNYXweHg3PzPPCYkpJhABwOgIjQZpdqhiojIyMiGAx+UkqlJCYmsra2FmoHgAop5eiVANM07wUCge/x8fEkJydTXFzMyMgIOzs76LqO1+sVwIhhGA8uARTcA9LnNjfzP0dGshwMsh8Xh8ViISEhAavVimmaOJ1O2tvbAfKFAh1wAckA5OTgLCvDWVp6Sl1e5t3eHgVDQ/T39zMxMUFWVhYAmqY9E4AXuAtAXh4MDsLAAIyOQnk5KEXB2BitS0t8sdkAcLvdb4QQ1S6X66cAYgBIT4fZWdjbg/p6CA+Hujro6wOgc2OjVoOX/+9LAE50fZGiomskJcHm5oXb3Q1WKxwevr1qGEBo4OXkRKja2vvAUyAXuAms09w8DAxqp0dzpf4Cgj71r0vtOwcAAAAASUVORK5CYII=" ], [ "separator" ], [ "Выделенный текст в DeepL.Перевод (Auto –> Ru)", "https://www.deepl.com/translator#en/ru/", "DeeplTranslateEnRu", "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAACNwAAAjcB9wZEwgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGZSURBVDiNjZKxaxRBFMZ/b2ZHbWITUxkRC4PnBUW0k1gkoFlMYmIR8R+w0UZBFAvtLAMS0ipC0guCd0GOa23EJGTPkBRCSCNHKiEgMzvPwmjCuiv3lft97zff7BuhQraWTouJLwE0mmf518a7spwUPxwZvlmLms8B4wWrLZhHPvuwUg44N9afGPcc4T5gK4pFgSUv/jHrre8HgKHJE4nzHWBgn/sZdBuYqQB1Q+5rbLR2DUBy1J89GIbEmNmQNW8DqxWAgcS5IQBT5vqYP3H1Gw9AHyosAKECVA4QuKfIPMhHVKygV4OVU8ByT4BDsiI6rWpusdbYUdgpBpLSMeGTRLYx2o5q9kT0ja2P3xU401ODQJz1neYdVRkT9C1gyob/Ngg/3VbifJf9TVg1L2Q43UC1eo3eb8KfB7O7uRf7T782Yo8hXBG4DFwvaRgFFoP4GTqt7u/bFuTOp5dU9BUw8u/BOhqy5fZ//4HvNL6ErHlNkSmFb4e9YM1WMV+5xjxrvM+P99VBngI/qnK96UI66OrpEhcnThatXx/tiqJJdDA6AAAAAElFTkSuQmCC" ], [ "separator" ], [ "Выделенный текст в DeepL.Перевод (Ru –> En)", "https://www.deepl.com/translator#ru/en/", "DeeplTranslateRuEn", "data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAACNwAAAjcB9wZEwgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGZSURBVDiNjZKxaxRBFMZ/b2ZHbWITUxkRC4PnBUW0k1gkoFlMYmIR8R+w0UZBFAvtLAMS0ipC0guCd0GOa23EJGTPkBRCSCNHKiEgMzvPwmjCuiv3lft97zff7BuhQraWTouJLwE0mmf518a7spwUPxwZvlmLms8B4wWrLZhHPvuwUg44N9afGPcc4T5gK4pFgSUv/jHrre8HgKHJE4nzHWBgn/sZdBuYqQB1Q+5rbLR2DUBy1J89GIbEmNmQNW8DqxWAgcS5IQBT5vqYP3H1Gw9AHyosAKECVA4QuKfIPMhHVKygV4OVU8ByT4BDsiI6rWpusdbYUdgpBpLSMeGTRLYx2o5q9kT0ja2P3xU401ODQJz1neYdVRkT9C1gyob/Ngg/3VbifJf9TVg1L2Q43UC1eo3eb8KfB7O7uRf7T782Yo8hXBG4DFwvaRgFFoP4GTqt7u/bFuTOp5dU9BUw8u/BOhqy5fZ//4HvNL6ErHlNkSmFb4e9YM1WMV+5xjxrvM+P99VBngI/qnK96UI66OrpEhcnThatXx/tiqJJdDA6AAAAAElFTkSuQmCC" ] ]; var Translate = this.appendChild(document.createXULElement("menupopup")); array.forEach((m)=> { if ( m[0] == "separator" ) { Translate.appendChild(document.createXULElement("menuseparator")); return }; var mItem = Translate.appendChild(document.createXULElement("menuitem")); mItem.setAttribute("label", m[0]); mItem.setAttribute("class", "menuitem-iconic"); mItem.setAttribute("id", m[2]); mItem.setAttribute("image", m[3]); mItem.onclick =e=> { let browserMM = gBrowser.selectedBrowser.messageManager; browserMM.addMessageListener('getSelect', function listener(message) { var selectionTxt = message.data; var url = m[1]; var txtUrl = (url + encodeURIComponent(selectionTxt)); gBrowser.selectedTab = gBrowser.addTab(txtUrl, { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }); browserMM.removeMessageListener('getSelect', listener, true); }); browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false); }; }); Translate.setAttribute("onclick", "event.stopPropagation()");
Отредактировано unter_officer (18-12-2021 19:10:24)
«The Truth Is Out There»
Отсутствует
unter_officer
Выделенное через clipboard. Не то же самое, но, надеюсь, не проблема.
id, label, tooltiptext не дадены, вписал pid поста. Но id лучше сразу
задать окончательный, они сами из browser.uiCustomization.state не исчезают.
(async () => CustomizableUI.createWidget({ id: "796945", label: "796945", tooltiptext: "796945", image: "chrome://devtools/skin/images/tool-application.svg", data: ` G.Перевод (Auto –> Ru) translate.google.com/#view=home&op=translate&sl=auto&tl=ru&text= iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAACXBIWXMAAAAAAAAAAAHqZRakAAACy0lEQVQ4y32SX2iVdRjHP7/3fd7Xbe3M4aYzxW2gOMHUBNEisTRQ2NFwLgwz8sIlVDeiMBZCHIkgCTcpKFCv1IuEUep0HMwSEXWBiM4ksOafmqCVM/d6ztzO+/s9XrzHtXnh9/LH7/k+3z+PvNP+3/7D2ypbJO/8zekvc5ulqT3SH7aljHRssDTVH1dpao9093rLnuwIbY0xkns0/M2Hh8KPjCnj4cN+pLkj0tjB0e0pAyDVKY9/Iujvv6PGgFiFiWVK15krrHl9PtJ/3+IUjjxYxorcHWRdR6QYD1VwCgsHb03IZOaOUITEDr5+d4Rjl4XlDZa27+uHe3uvUVVVmXywFj4+FAKQ/dXDqfLtuRTTOcWGlUuRE62JvKf4YOvJW+lVk+pm1i/BOYe8vSdSq6AKJfGDZd+11p4dOyCKhwEUyJvSn4Fg/AeFtsYChRh2Zcuk9+pvOrm6ElXFWpsE8fmJgF3NBVThfF/Axc6D7NyyEVVNGHakC0SPDarQ/UcNrY1vcuX6DV6aWYc4B591BSgktM5w5PQvtKxdQRzHSGwtFEUm8FiwcCX3Bu4zfUoVkm2rGJfD6vey+nJ6BmGYCJXmjkiN8ZIVRapkHehw7sDRT6Zs4jkQB5gxGkaHAcIX3v+q8+aSVfPi38NQnIioc2Ctw/NU8/n4sGixhR3pAt1XfS796ZEqgcGh5P2n25Mb5r94o2FqdSlhGOL7hiDwUVVSKX+tOAem6NKYZGjOVMdrsxy7TwrWGfZdKGFeeQ8iPhZlIMoxo6aat5YuQpwmFnZ2/d9wT59HT583Gv2ATmNCxQL+vdtDaUlIy+rliEgxgyLBU6jq+FqKefz4Vy1bFz9mqJCj8/QFmt94NTmV7mfOdSwymYtlZ6/9nQMoL/cJXqmhtnYic+qmjdqW51WUySzKf/pFdsvc2RV7Z9WVEgQ+zlmMMYm1waG9TwBslkaEyL4QewAAAABJRU5ErkJggg== G.Перевод (Ru –> En) translate.google.com/#view=home&op=translate&sl=ru&tl=en&text= Y.Перевод (Auto –> Ru) translate.yandex.ru/?lang=auto-ru&text= iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAACXBIWXMAAAAAAAAAAAHqZRakAAACnElEQVQ4y22TXyidYRzHP297at7N2cmx4ghXLg7bboy8b1ygxFlTsivypxWiLPk37kYuRoqMqWWFC/+WbE3LWtRWJ+c5h62shXCh6KSUZSesdk7PLjDH8r39fn+f5/n+6icA0tLSmoSCVjye5wLAMIxJoTweld/RgeBMhmGo6elphIJp4BFSosXGaqGJAyml7RyiampqAJRQoDg+pmJuDk3TlgULC9DWxuvJyTsarP5jnI2+z87Ozrfb7WRmZlJZWRkQAArmgDykxFdYyE5qKk1NTQBCKPgNXKelBRoaiImKYtVm++B3OFqllD+EBmEK/tDVJejqAvDmHBw8ZHERgEt/ME1TV0p5gWggV0r57VLAbrcf9/b2srKywu7u7lelVEroJp74fD62trbQdZ2ZmRk0TfsoFNwG9pGSX0LQMD5OY2MjPT09VFVV+QSwD4Dfzy2LhRdTU3TGxODxeAgLC0s7fcLlguhosFi44fczPz9f7Xa7X1202N6GoyNYXweHg3PzPPCYkpJhABwOgIjQZpdqhiojIyMiGAx+UkqlJCYmsra2FmoHgAop5eiVANM07wUCge/x8fEkJydTXFzMyMgIOzs76LqO1+sVwIhhGA8uARTcA9LnNjfzP0dGshwMsh8Xh8ViISEhAavVimmaOJ1O2tvbAfKFAh1wAckA5OTgLCvDWVp6Sl1e5t3eHgVDQ/T39zMxMUFWVhYAmqY9E4AXuAtAXh4MDsLAAIyOQnk5KEXB2BitS0t8sdkAcLvdb4QQ1S6X66cAYgBIT4fZWdjbg/p6CA+Hujro6wOgc2OjVoOX/+9LAE50fZGiomskJcHm5oXb3Q1WKxwevr1qGEBo4OXkRKja2vvAUyAXuAms09w8DAxqp0dzpf4Cgj71r0vtOwcAAAAASUVORK5CYII= Y.Перевод (Ru –> En) translate.yandex.ru/?lang=ru-en&text= DeepL.Перевод (Auto –> Ru) www.deepl.com/translator#en/ru/ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAACNwAAAjcB9wZEwgAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGZSURBVDiNjZKxaxRBFMZ/b2ZHbWITUxkRC4PnBUW0k1gkoFlMYmIR8R+w0UZBFAvtLAMS0ipC0guCd0GOa23EJGTPkBRCSCNHKiEgMzvPwmjCuiv3lft97zff7BuhQraWTouJLwE0mmf518a7spwUPxwZvlmLms8B4wWrLZhHPvuwUg44N9afGPcc4T5gK4pFgSUv/jHrre8HgKHJE4nzHWBgn/sZdBuYqQB1Q+5rbLR2DUBy1J89GIbEmNmQNW8DqxWAgcS5IQBT5vqYP3H1Gw9AHyosAKECVA4QuKfIPMhHVKygV4OVU8ByT4BDsiI6rWpusdbYUdgpBpLSMeGTRLYx2o5q9kT0ja2P3xU401ODQJz1neYdVRkT9C1gyob/Ngg/3VbifJf9TVg1L2Q43UC1eo3eb8KfB7O7uRf7T782Yo8hXBG4DFwvaRgFFoP4GTqt7u/bFuTOp5dU9BUw8u/BOhqy5fZ//4HvNL6ErHlNkSmFb4e9YM1WMV+5xjxrvM+P99VBngI/qnK96UI66OrpEhcnThatXx/tiqJJdDA6AAAAAElFTkSuQmCC DeepL.Перевод (Ru –> En) www.deepl.com/translator#ru/en/ `, localized: false, onCreated(btn) { var urls = []; var arr = this.data.split("\n").filter(s => /\S/.test(s)).map(s => s.trim()); var doc = btn.ownerDocument, count = 0; var popup = doc.createXULElement("menupopup"); popup.setAttribute("oncommand", "transTab(event.target.value);"); for(var ind = 0, num = arr.length - 1; ind < num; ind++) { var menuitem = doc.createXULElement("menuitem"); menuitem.setAttribute("value", count++); menuitem.setAttribute("label", "Выделенный текст в " + arr[ind]); urls.push(arr[++ind]); menuitem.className = "menuitem-iconic"; if (count % 2) var img = "data:image/png;base64," + arr[++ind]; menuitem.setAttribute("image", img); popup.append(menuitem); ind < num && popup.append(doc.createXULElement("menuseparator")); } delete this.data; var xul = popup.outerHTML; var write, read = () => { var cb = Services.clipboard, gc = cb.kGlobalClipboard, fl = "text/unicode"; var ch = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); write = str => ch.copyStringToClipboard(str, gc); var trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); trans.init(null); return (read = () => { trans.addDataFlavor(fl); cb.getData(trans, gc); var res = {}; trans.getTransferData(fl, res); res = res.value?.QueryInterface(Ci.nsISupportsString).data; trans.removeDataFlavor(fl); return res; })(); } var tt = async function(ind) { var clip = read(); clip && write(""); var win = this.ownerGlobal; win.docShell.doCommand("cmd_copy"); await new Promise(resolve => setTimeout(resolve, 100)); var sel = read(); clip && write(clip); if (sel) { var gb = win.gBrowser; gb.selectedTab = gb.addTrustedTab(`https://${urls[ind]}${encodeURIComponent(sel)}`); } }; (this.onCreated = (btn, node = btn.ownerGlobal.MozXULElement.parseXULToFragment(xul)) => { btn.setAttribute("type", "menu"); btn.setAttribute("image", this.image); btn.prepend(node); btn.firstChild.transTab = tt; })(btn, popup); } }))();
Отредактировано Dumby (19-12-2021 15:24:41)
Отсутствует
Dumby
Как всегда супер! Большое спасибо.
«The Truth Is Out There»
Отсутствует
Dumby
А ещё одну кнопочку не переделаете для UCF?
/*Initialization Code*/ // Кнопка сохраняет страницу с картинками или её часть, если она выделена, в html одним файлом .......... // Dumby: https://forum.mozilla-russia.org/viewtopic.php?pid=782032#p782032 ..... (func => this._handleClick = () => { var saveToFile = (fileContent, fileName) => { var uc = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); uc.charset = "utf-8"; fileContent = uc.ConvertFromUnicode(fileContent); var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); fp.init(window, "", fp.modeSave); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); fp.open(rv => { if (rv != fp.returnOK && rv != fp.returnReplace) return; var stream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream); stream.init(fp.file, 0x02|0x20|0x08, 0o666, 0); stream.write(fileContent, fileContent.length); stream.close(); }); } var msgName = _id + ":SaveSnapshotToHTML"; var msgListener = msg => saveToFile(...msg.data); messageManager.addMessageListener(msgName, msgListener); addDestructor(() => messageManager.removeMessageListener(msgName, msgListener)); var url = "data:," + encodeURIComponent( `(${func})(ChromeUtils.import("resource://gre/modules/Services.jsm").Services);`.replace("%MSG_NAME%", msgName) ); (this._handleClick = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false))(); })(({io, focus}) => { var resolveURL = function (url, base) { try { return io.newURI(url, null, io.newURI(base)).spec; } catch {} }; var getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r; } catch(e) {} } }; var encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else { img = obj; }; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }; var toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }; var 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); var meta = doc.createElement('meta'); meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); var title = doc.getElementsByTagName('title')[0]; if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; var sheets = doc.styleSheets; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '').replace(/[\.]+/ig, ' ').replace(/[\,]+/ig, ' ').replace(/\s+/g, '_').slice(0, 100).replace(/^\s+|\s+$/g, ''); fileName += (function () { var d = new Date(), z = function(n){return (n < 10 ? '0' : '') + n}; return '_' + '[' + z(d.getFullYear()) + '_' + z(d.getMonth()+1) + '_' + z(d.getDate()) + '\u2014' + z(d.getHours()) + '_' + z(d.getMinutes()) + '_' + z(d.getSeconds()) + ']'; })(); if(!/\.html?$/.test(fileName))fileName += '.html'; sendAsyncMessage("%MSG_NAME%", [doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->', fileName]); });
«The Truth Is Out There»
Отсутствует
xrun1
Это же целый комбайн, из которого мне надо только: "Сохранить всю страницу или выбранное как HTML".
Не вижу смысла ставить лишнее.
«The Truth Is Out There»
Отсутствует
Выложу кнопку. В ней код попроще, может кому-то пригодится.
custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname%3E%u0421%u043E%u0445%u0440%u0430%u043D%u0438%u0442%u044C%20%u0441%u0442%u0440%u0430%u043D%u0438%u0446%u0443%20%u043A%u0430%u043A...%3C/name%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bdata%3Aimage/svg+xml%3Bbase64%2CPCEtLSBUaGlzIFNvdXJjZSBDb2RlIEZvcm0gaXMgc3ViamVjdCB0byB0aGUgdGVybXMgb2YgdGhlIE1vemlsbGEgUHVibGljCiAgIC0gTGljZW5zZSwgdi4gMi4wLiBJZiBhIGNvcHkgb2YgdGhlIE1QTCB3YXMgbm90IGRpc3RyaWJ1dGVkIHdpdGggdGhpcwogICAtIGZpbGUsIFlvdSBjYW4gb2J0YWluIG9uZSBhdCBodHRwOi8vbW96aWxsYS5vcmcvTVBMLzIuMC8uIC0tPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiB2aWV3Qm94PSIwIDAgMTYgMTYiIGZpbGw9ImNvbnRleHQtZmlsbCAjMGMwYzBkIj4KICA8cGF0aCBkPSJNNCAwaDhhMyAzIDAgMCAxIDMgM3YxMGEzIDMgMCAwIDEtMyAzSDRhMyAzIDAgMCAxLTMtM1YzYTMgMyAwIDAgMSAzLTN6bTAgMmExIDEgMCAwIDAtMSAxdjEwYTEgMSAwIDAgMCAxIDFoOGExIDEgMCAwIDAgMS0xVjNhMSAxIDAgMCAwLTEtMUg0ek0zIDdoMTB2MUgzVjd6TTkuNSA0aC0zYS41LjUgMCAwIDAgMCAxaDNhLjUuNSAwIDAgMCAwLTF6TTkuNSAxMGgtM2EuNS41IDAgMCAwIDAgMWgzYS41LjUgMCAwIDAgMC0xeiIvPgo8L3N2Zz4K%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5B/*Initialization%20Code*/%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5BsaveBrowser%28gBrowser.selectedBrowser%29%3B%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E
Отсутствует
А ещё одну кнопочку не переделаете для UCF?
Переложил в JSM'ку, вроде завелось.
Как импортировать следует напомнить?
var name = "UCFSaveSnapshotToHTML", EXPORTED_SYMBOLS = [name + "Child"]; if (!ChromeUtils.domProcessChild.childID) { ChromeUtils.import("resource:///modules/CustomizableUI.jsm").CustomizableUI.createWidget({ label: "796961", tooltiptext: "796961", id: "796961", localized: false, onCreated(btn) { btn._handleClick = click; btn.setAttribute("image", "chrome://devtools/skin/images/tool-application.svg"); } }); var click = async function() { var win = this.ownerGlobal; var bc = win.gBrowser.selectedBrowser.browsingContext; var fbc = win.Services.focus.focusedContentBrowsingContext; if (!fbc || fbc.top.id != bc.id) fbc = bc; var cwg = fbc.currentWindowGlobal; var fp = picker(win, "", Ci.nsIFilePicker.modeSave); var [fileContent, fileName] = await cwg.domProcess.getActor(name).sendQuery("", cwg.innerWindowId); fp.defaultString = fileName; fp.appendFilters(fp.filterHTML); fp.appendFilters(fp.filterAll); await new Promise(fp.open) != fp.returnCancel && IOUtils.writeUTF8(fp.file.path, fileContent, {mode: "overwrite"}); } var picker = (...args) => { ChromeUtils.registerProcessActor(name, { includeParent: true, child: {moduleURI: __URI__} }); return (picker = Components.Constructor( "@mozilla.org/filepicker;1", "nsIFilePicker", "init" ))(...args); } } class UCFSaveSnapshotToHTMLChild extends JSProcessActorChild { receiveMessage(msg) { return snap(WindowGlobalChild.getByInnerWindowId(msg.data).browsingContext.window); } } var snap = mainWin => { var resolveURL = function (url, base) { try { return (new URL(url, base)).href; } catch {} }; var getSelWin = function (w) { if (w.getSelection().toString()) return w; for (var i = 0, f, r; f = w.frames[i]; i++) { try { if (r = getSelWin(f)) return r; } catch(e) {} } }; var encodeImg = function (src, obj) { var canvas, img, ret = src; if (/^https?:\/\//.test(src)) { canvas = doc.createElement('canvas'); if (!obj || obj.nodeName.toLowerCase() != 'img') { img = doc.createElement('img'); img.src = src; } else { img = obj; }; if (img.complete) try{ canvas.width = img.width; canvas.height = img.height; canvas.getContext('2d').drawImage(img, 0, 0); ret = canvas.toDataURL((/\.jpe?g/i.test(src) ? 'image/jpeg' : 'image/png')); } catch (e) {}; if (img != obj) img.src = 'about:blank'; }; return ret; }; var toSrc = function (obj) { var strToSrc = function (str) { var chr, ret = '', i = 0, meta = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\x22' : '\\\x22', '\\': '\\\\'}; while (chr = str.charAt(i++)) { ret += meta[chr] || chr; }; return '\x22' + ret + '\x22'; }, arrToSrc = function (arr) { var ret = []; for (var i = 0; i < arr.length; i++) { ret[i] = toSrc(arr[i]) || 'null'; }; return '[' + ret.join(',') + ']'; }, objToSrc = function (obj) { var val, ret = []; for (var prop in obj) { if (obj.hasOwnProperty(prop) && (val = toSrc(obj[prop]))) ret.push(strToSrc(prop) + ': ' + val); }; return '{' + ret.join(',') + '}'; }; switch (Object.prototype.toString.call(obj).slice(8, -1)) { case 'Array': return arrToSrc(obj); case 'Boolean': case 'Function': case 'RegExp': return obj.toString(); case 'Date': return 'new Date(' + obj.getTime() + ')'; case 'Math': return 'Math'; case 'Number': return isFinite(obj) ? String(obj) : 'null'; case 'Object': return objToSrc(obj); case 'String': return strToSrc(obj); default: return obj ? (obj.nodeType == 1 && obj.id ? 'document.getElementById(' + strToSrc(obj.id) + ')' : '{}') : 'null'; } }; var selWin = getSelWin(mainWin), win = selWin || mainWin, doc = win.document, loc = win.location; var ele, pEle, clone, reUrl = /(url\(\x22)(.+?)(\x22\))/g; if (selWin) { var rng = win.getSelection().getRangeAt(0); pEle = rng.commonAncestorContainer; ele = rng.cloneContents(); } else { pEle = doc.documentElement; ele = (doc.body || doc.getElementsByTagName('body')[0]).cloneNode(true); }; while (pEle) { if (pEle.nodeType == 1) { clone = pEle.cloneNode(false); clone.appendChild(ele); ele = clone; }; pEle = pEle.parentNode }; var sel = doc.createElement('div'); sel.appendChild(ele); for (var el, all = sel.getElementsByTagName('*'), i = all.length; i--;) { el = all[i]; if (el.style && el.style.backgroundImage) el.style.backgroundImage = el.style.backgroundImage.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, loc.href); return prev + encodeImg(url) + next; }); switch (el.nodeName.toLowerCase()) { case 'link': case 'style': case 'script': el.parentNode.removeChild(el); break; case 'a': case 'area': if (el.hasAttribute('href') && el.getAttribute('href').charAt(0) != '#') el.href = el.href; break; case 'img': case 'input': if (el.hasAttribute('src')) el.src = encodeImg(el.src, el); break; case 'audio': case 'video': case 'embed': case 'frame': case 'iframe': if (el.hasAttribute('src')) el.src = el.src; break; case 'object': if (el.hasAttribute('data')) el.data = el.data; break; case 'form': if (el.hasAttribute('action')) el.action = el.action; break; } }; var head = ele.insertBefore(doc.createElement('head'), ele.firstChild); var meta = doc.createElement('meta'); meta.httpEquiv = 'content-type'; meta.content = 'text/html; charset=utf-8'; head.appendChild(meta); var title = doc.getElementsByTagName('title')[0]; if (title) head.appendChild(title.cloneNode(true)); head.copyScript = function (unsafeWin) { if ('$' in unsafeWin) return; var f = doc.createElement('iframe'); f.src = 'about:blank'; f.setAttribute('style', 'position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;'); doc.documentElement.appendChild(f); var str, script = doc.createElement('script'); script.type = 'text/javascript'; for (var name in unsafeWin) { if (name in f.contentWindow || !/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) continue; try { str = toSrc(unsafeWin[name]); if (!/\{\s*\[native code\]\s*\}/.test(str)) { script.appendChild(doc.createTextNode('var ' + name + ' = ' + str.replace(/<\/(script>)/ig, '<\\/$1') + ';\n')); } } catch (e) {}; }; f.parentNode.removeChild(f); if (script.childNodes.length) this.nextSibling.appendChild(script); }; head.copyScript(win.wrappedJSObject || win); head.copyStyle = function (s) { if (!s) return; var style = doc.createElement('style'); style.type = 'text/css'; if (s.media && s.media.mediaText) style.media = s.media.mediaText; try { for (var i = 0, rule; rule = s.cssRules[i]; i++) { if (rule.type != 3) { if((!rule.selectorText || rule.selectorText.indexOf(':') != -1) || (!sel.querySelector || sel.querySelector(rule.selectorText))) { var css = !rule.cssText ? '' : rule.cssText.replace(reUrl, function (a, prev, url, next) { if (!/^[a-z]+:/.test(url)) url = resolveURL(url, s.href || loc.href); if(rule.type == 1 && rule.style && rule.style.backgroundImage) url = encodeImg(url); return prev + url + next; }); style.appendChild(doc.createTextNode(css + '\n')); } } else { this.copyStyle(rule.styleSheet); } } } catch(e) { if (s.ownerNode) style = s.ownerNode.cloneNode(false); }; this.appendChild(style); }; var sheets = doc.styleSheets; for (var j = 0; j < sheets.length; j++) head.copyStyle(sheets[j]); head.appendChild(doc.createTextNode('\n')); var doctype = '', dt = doc.doctype; if (dt && dt.name) { doctype += '<!DOCTYPE ' + dt.name; if (dt.publicId) doctype += ' PUBLIC \x22' + dt.publicId + '\x22'; if (dt.systemId) doctype += ' \x22' + dt.systemId + '\x22'; doctype += '>\n'; }; var fileName = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop()); fileName = fileName.replace(/[:\\\/<>?*|"]+/g, '').replace(/[\.]+/ig, ' ').replace(/[\,]+/ig, ' ').replace(/\s+/g, '_').slice(0, 100).replace(/^\s+|\s+$/g, ''); fileName += (function () { var d = new Date(), z = function(n){return (n < 10 ? '0' : '') + n}; return '_' + '[' + z(d.getFullYear()) + '_' + z(d.getMonth()+1) + '_' + z(d.getDate()) + '\u2014' + z(d.getHours()) + '_' + z(d.getMinutes()) + '_' + z(d.getSeconds()) + ']'; })(); if(!/\.html?$/.test(fileName))fileName += '.html'; return [doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->', fileName]; }
Отсутствует
Dumby
Всё отлично. Большое спасибо.
Отредактировано unter_officer (21-12-2021 00:31:11)
«The Truth Is Out There»
Отсутствует
Dumby
Помогите ещё вот с таким вопросом.
Я решил сам попробовать переделать простенькую СВ-кнопку под UCF. Для примера взял кнопку, которую когда-то делали вы:
// Перейти в начало/конец страницы - Центрирование страницы .......... // https://forum.mozilla-russia.org/viewtopic.php?pid=781993#p781993 ..... (u => { var id, lfs = url => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false); var max = () => { var url = u([ "var args = [scroller.scrollHeight, 0];", "scroller.scrollTop != 0 || args.reverse();", "content.scrollTo(...args);" ].join("\n\t")); (max = () => lfs(url))(); } var mid = () => { var url = u("content.scrollTo(0, (scroller.scrollHeight - scroller.clientHeight) / 2);"); (mid = () => id = lfs(url))(); } var obj = { mousedown: () => id = setTimeout(mid, 500), mouseup: () => id && max(id = clearTimeout(id)) }; this.onmousedown = this.onmouseup = e => e.button || obj[e.type](); this.tooltipText = "Л: Вверх/Вниз по странице \nдЛ: Центрирование страницы"; }) (code => "data:," + encodeURIComponent(`(doc => { var root = doc.documentElement; var body = doc.body || root; var scroller = body.scrollHeight > root.scrollHeight ? body : root; ${code} })(content.document)`));
try { CustomizableUI.createWidget({ id: "0123456789", label: "0123456789", // tooltiptext: "0123456789", img: "data:image/png;.....", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, get initCode() { delete this.initCode; return this.initCode = Cu.readUTF8URI(Services.io.newURI( "chrome://user_chrome_files/content/custom_scripts/ucf_user_script/cb_Button.js" )); }, onCreated(btn) { var win = btn.ownerGlobal; new win.Function(this.initCode).call(btn); btn.image = this.img; } }); } catch(ex) {Cu.reportError(ex);}
«The Truth Is Out There»
Отсутствует
Я решил сам попробовать переделать простенькую СВ-кнопку под UCF. Для примера взял кнопку
Похвально, но, мне кажется, выбор кнопки не совсем удачный.
То есть не то чтобы какая-то особая сложность,
надо просто окно пробросить, но сама цепочка длинновата.
И ещё, что-то мне исходник не слишком понятен.
Вобщем, переделал. Надо смотреть не испортил ли чего.
(async lfs => CustomizableUI.createWidget({ id: "0123456789", label: "0123456789", tooltiptext: "Л: Вверх/Вниз по странице \nдЛ: Центрирование страницы", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { var id, u = code => `data:,(se => se && content.scrollTo(0, ${code}))(content.document.scrollingElement);`; this.mousedown = w => { var url = u("(se.scrollHeight - se.clientHeight) / 2"); var mid = w => id = lfs(url, w); (this.mousedown = w => id = w.setTimeout(mid, 500, w))(w); } this.mouseup = w => { var max = lfs.bind(null, u("se.scrollTop == 0 && se.scrollHeight")); (this.mouseup = w => id && max(w, id = w.clearTimeout(id)))(w); } var mouse = e => e.button || this[e.type](e.view); (this.onCreated = btn => { btn.onmousedown = btn.onmouseup = mouse; btn.setAttribute("image", "resource://usercontext-content/fence.svg"); })(btn); } }))((url, w) => w.gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false));
Единственное, как мне удалось заставить эту кнопку работать, это подключить её из отдельного файла.
Содержимое файла можно было разместить там же, внутри кода.
Напрямую как `строку`, но там много экранировать нужно,
или как тело функции и дальше func.toString().slice(N, -M);
Отсутствует