Dumby
Откровенно говоря и не надеялся на положительный ответ. Слишком сложная и действительно великолепная кнопка. Но что интересно, работает в предложенном варианте. Только со строкой меню "Восстановить последнюю сессию" проблема - пропадает после очистки списка закрытых вкладок. И после очистки по ПКМ в кнопке классическое меню CB. В общем, раз "малой кровью" не получается, буду использовать вариант CB. Спасибо за предложенный вариант, взял на заметку.
egorsemenov06
Эта у меня тоже есть из поста https://forum.mozilla-russia.org/viewtopic.php?pid=784332#p784332
Отсутствует
Раньше в СВ были две удобные фичи. Первая: можно было открыть окно и запретить в нем загрузку нежелательного контента.
let win = open('','',param); docShell = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell); docShell.allowImages = false; docShell.allowJavascript = false; docShell.allowPlugins = false;
И вторая, можно было открыть закладку по ее ключевому слову.
Есть сейчас замена этим двум фичам?
Отсутствует
Есть сейчас замена этим двум фичам?
Первая, как-то так, наверно.
Плюс, приглядывать за багами, типа такого.
OpenBrowserWindow().addEventListener("XULFrameLoaderCreated", { async handleEvent(e) { if (!e.target.matches("[id^=panel-].browserSidebarContainer :scope")) return; await Promise.resolve(); var func = type => { var restrict = () => { destroy(); docShell.allowImages = docShell.allowJavascript = docShell.allowPlugins = false; } var destroy = () => { removeEventListener(type, restrict); removeEventListener("unload", destroy); } addEventListener(type, restrict); addEventListener("unload", destroy); } var url = "data:charset=utf-8," + encodeURIComponent( `(${func})("DOMDocElementInserted");` ); var {type} = e, stack = e.target.parentNode; var unload = () => { stack.removeEventListener(type, this); tab.removeEventListener("TabClose", tabClose); } var win = e.target.ownerGlobal; win.addEventListener("unload", unload, {once: true}); var tabClose = () => { stack.removeEventListener(type, this); win.removeEventListener("unload", unload); } var tab = win.gBrowser.getTabForBrowser(e.target); tab.addEventListener("TabClose", tabClose, {once: true}); win.removeEventListener(type, this); (this.handleEvent = e => e.target.messageManager.loadFrameScript(url, false))(e); stack.addEventListener(type, this); } });
PlacesUtils.keywords.fetch("keyword").then(res => res && openLinkIn(res.url.href, "current", { postData: res.postData, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }));
Отредактировано Dumby (18-02-2021 00:52:22)
Отсутствует
hartumov пишетЕсть сейчас замена этим двум фичам?
Первая, как-то так, наверно.
Плюс, приглядывать за багами, типа такого.скрытый текстВыделить кодКод:
OpenBrowserWindow().addEventListener("XULFrameLoaderCreated", { async handleEvent(e) { if (!e.target.matches("[id^=panel-].browserSidebarContainer :scope")) return; await Promise.resolve(); var func = type => { var restrict = () => { destroy(); docShell.allowImages = docShell.allowJavascript = docShell.allowPlugins = false; } var destroy = () => { removeEventListener(type, restrict); removeEventListener("unload", destroy); } addEventListener(type, restrict); addEventListener("unload", destroy); } var url = "data:charset=utf-8," + encodeURIComponent( `(${func})("DOMDocElementInserted");` ); var {type} = e, stack = e.target.parentNode; var unload = () => { stack.removeEventListener(type, this); tab.removeEventListener("TabClose", tabClose); } var win = e.target.ownerGlobal; win.addEventListener("unload", unload, {once: true}); var tabClose = () => { stack.removeEventListener(type, this); win.removeEventListener("unload", unload); } var tab = win.gBrowser.getTabForBrowser(e.target); tab.addEventListener("TabClose", tabClose, {once: true}); win.removeEventListener(type, this); (this.handleEvent = e => e.target.messageManager.loadFrameScript(url, false))(e); stack.addEventListener(type, this); } });
Втораяскрытый текстВыделить кодКод:
PlacesUtils.keywords.fetch("keyword").then(res => res && openLinkIn(res.url, "current", { postData: res.postData, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }));
Dumby
Первый код открывает новое окно, у меня это настроено на домашнюю страницу. А как сделать, чтобы в этом окне сразу открылся нужный адрес?
А со вторым кодом ничего не получается. В эту строчку PlacesUtils.keywords.fetch("keyword") вместо keyword я вставляю краткое имя закладки или просто веб адрес. Не происходит ничего, только в консоли пишет Promise { <state>: "pending" }
Отсутствует
А как сделать, чтобы в этом окне сразу открылся нужный адрес?
Можно заменить первую строку на
openDialog( AppConstants.BROWSER_CHROME_URL, "_blank", "chrome,all,dialog=no", "нужный_адрес" ).addEventListener("XULFrameLoaderCreated", {
вместо keyword я вставляю краткое имя закладки или просто веб адрес. Не происходит ничего, только в консоли пишет Promise { <state>: "pending" }
Интересно, откуда может взяться запись в консоли?
Разве что запускать, собственно, с консоли.
И что значит «или просто веб адрес»? Написано было чётко:
И вторая, можно было открыть закладку по ее ключевому слову.
При чём тут «веб адрес»? Если приведённому тобой коду, на Firefox 56,
скормить вместо keyword «просто веб адрес», то он тоже ничего не откроет.
А по краткому имени — должен открывать. Может в keyword'е опечатка.
Отсутствует
hartumov пишетвместо keyword я вставляю краткое имя закладки или просто веб адрес. Не происходит ничего, только в консоли пишет Promise { <state>: "pending" }
Интересно, откуда может взяться запись в консоли?
Разве что запускать, собственно, с консоли.И что значит «или просто веб адрес»? Написано было чётко:
И вторая, можно было открыть закладку по ее ключевому слову.
При чём тут «веб адрес»? Если приведённому тобой коду, на Firefox 56,
скормить вместо keyword «просто веб адрес», то он тоже ничего не откроет.
А по краткому имени — должен открывать. Может в keyword'е опечатка.
С веб адресом это я просто оговорился.
У меня не получалось запустить этот код из кнопки, потому я попробовал с консоли.
А не получалось потому, что я вставлял краткое имя букмарклета. Букмарклет не вызывается, хотя старый код
прекрасно с этим справлялся.
А если закладка с обычным адресом - то да, новый код работает. А букмарклет загрузить никак нельзя?
И еще вопрос, вот в этой строчке
я меняю current на window - закладка открывается в новом окне. А если меняю на tab, не работает. Почему?
Отсутствует
А не получалось потому, что я вставлял краткое имя букмарклета.
Да, вижу, интересный кейс.
Порылся немного, вот так, вроде, работает.
PlacesUtils.keywords.fetch("keyword").then(res => { if (!res) return; var {url: {href}, postData} = res; var allowPopups = href.startsWith("javascript:"); openLinkIn(href, "current", { postData, allowPopups, allowInheritPrincipal: allowPopups, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }); });
А если меняю на tab, не работает. Почему?
Потому, что res.url это объект, инстанция URL.
Легко превращается в строку, поэтому так и оставил.
А когда res.url отправляется открываться как tab, то, в цепочке вызовов,
на нём вызывается метод replace(), которого нет. Ошибка останавливает дальнейшее исполнение.
Код был расчитан на "current", но да, надо было, всё таки, передать строку, то есть res.url.href
Отсутствует
Как показать список закрытых вкладок т. е. вот это menupop#historyUndoPopup
Чтобы не лазить через меню Журнал и т. д... а сразу и отдельно посередине экрана?
Отсутствует
Как показать список закрытых вкладок т. е. вот это menupop#historyUndoPopup
Чтобы не лазить через меню Журнал и т. д... а сразу и отдельно посередине экрана?
SessionStore.getClosedTabCount(window) && (this.hpopup || (this.hpopup = (() => { var popup = document.createXULElement("menupopup", {is: "places-popup"}); for(var args of Object.entries({ context: "", placespopup: true, tooltip: "bhTooltip", onpopupshowing: "fill()", id: _id + "-historyUndoPopup" })) popup.setAttribute(...args); popup.fill = () => { popup.textContent = ""; popup.append(RecentlyClosedTabsAndWindowsMenuUtils.getTabsFragment(window, "menuitem")); var {width, height} = popup.getBoundingClientRect(); popup.moveTo((screen.availWidth - width)/2, (screen.availHeight - height)/2); } return this.appendChild(popup); })())) .openPopupAtScreen();
Dumby
network
Может лучше пойди подрядить «агента Шифт»,
чтобы подвинуть урлбарский плейсхолдер,
вместо того, чтобы вопрошать про «network» не по адресу.
Отредактировано Dumby (20-02-2021 22:12:57)
Отсутствует
Не понял...Куда код вставлять? Явно не в userchrome.
Да, не userchrome.
Попробовал (по всякому) куда-то в omni.ja, и не получилось, видимо, руки кривые.
А вот в ucf custom_style_agent.css — работает. Ну и такие варианты, конечно, тоже.
(css => { var type = windowUtils.AGENT_SHEET; var url = "data:text/css;charset=utf-8," + encodeURIComponent(css); windowUtils.loadSheetUsingURIString(url, type); addDestructor(() => windowUtils.removeSheetUsingURIString(url, type)); })(` #urlbar #urlbar-input::placeholder { text-indent: 22px !important; } `);
(async css => Cc["@mozilla.org/content/style-sheet-service;1"] .getService(Ci.nsIStyleSheetService).loadAndRegisterSheet( Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService).newURI( "data:text/css;charset=utf-8," + encodeURIComponent(css) ), Ci.nsIStyleSheetService.AGENT_SHEET ) )(` @-moz-document url(chrome://browser/content/browser.xhtml) { #urlbar #urlbar-input::placeholder { text-indent: 22px !important; } } `);
Отсутствует
https://github.com/xiaoxiaoflood/firefox-scripts/issues/64
как-то все молчат, а уже "security engineering team", аккуратно назвав тему "Compatability with Future Versions of Firefox", интересуются использованием autoconfig
пока к конкретному случаю привязано (load scripts off-the-main thread), но известно ж как мацарелла похерить все может
неужели 1% юзеров тоже выкинут? кто ж останется..
Отсутствует
Dumby
Тонкий ход! Config.js не понадобился. Тоже omni.ja весь перелопатил...Ну, ты , мастер...
А нельзя это же в польз.скрипт это запихать? Не надо. Вставил в custom_style_agent.css
Отредактировано solombala (21-02-2021 13:32:29)
Отсутствует
Dumby
Список закрытых вкладок - класс, спасибо!!
Отсутствует
Dumby объясни почему var nodeList = custombuttons.palette.getElementsByClassName("toolbarbutton-1 chromeclass-toolbar-additional"); выдает ошибку (в коде 204 строка)
var dialog; var defaultFavicon = "http://forum.mozilla-russia.org/uploaded/custombuttons_button.png"; var checkFavicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAltJREFUOMtt0l9olXUcx/HX8zzThHh07cLQJSZoozXNONMonYxI6zhwhnVnGQldqASZKN50USgWE0ThgCEiZV2JyNDpEnXMLhbuNBC7SOnfVHQj5p/Hmmw+53hxzo7T9bv5Xfy+78/v8/1+P4EnT7NqvIOMVEYkRF6q16hjegxBsVgMgiAoBk/AWRyQminyf2cguzi7veOrjg+xBD8H4+Cd2A7xNJLZxDUkMISrTH8QO7e3R/3z9TCKVSWBJitEOsFC1BOXpZOyfhzFOptPeW3O6wqFgh9Of7/7/bc/2BJoVi11CbVewXziMhiX4SSkY/lx2VktYOOejXJHcwOmeKlKqkWk1jTiholNJ/iu6VAF/iL/uVx3jsiz7lsdlqdNLcaNdMxF2+Jd1s5bB/Zd2qOt70tmVcoyoUijiPq6F7SvPGNp7fLK69b5m322YBs4fOVbn/R8WppJTbkgkqmSKsD+1gOWzmwyMDzgp+unrZm71q5X28Dxv9tt6N70uLsUkUIo0iuiMFIADc80aH7uLd8sOygQ6L7RZf3ZVoqJeAweqmjlSynDyH+joK76RUdWtJsUTvLLP3nvda4ynD5aJ6VMPBL41wmp/puDN0FVWGVyONnlO79pPbXS8IOkYhuSX3EL3JA6Frrgrsj6vit9Fdlr967KnnzTnfuDkrEwFUgu4iJK/X/svFulxP/lj5qG6hkL5r7c2D/Yb82Od12+9runUkYS/MnIhbL1IkJf65Lz+ObR5A0cFJld/kXlhtR1fOS8H8eQYEL0FpnqaS3IoBGhVK9IHid0uT2+/CEAYcfQrHKJYQAAAABJRU5ErkJggg=="; var uncheckFavicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAeJJREFUOMudk81qU1EUhb+7krYZaIkUhQQcqLVG30BKCyoOOtFROgiJZuxTXF/CcaEhhtyROCoO/C19BNOgM0mgk6IpGNN713WQUKMVU1yjczjrfJyz914Bf6hef5wbDn/clFTAFJVVAPTiOO4lSdKJouj7tD+Y3lQqletID7DPAwjwyakAjjLi5XajsX8KUK1W7xmvYTD0wR2hHgjjonAJVJjY95rN5s4JYHNz81o2m60BiWO/Kd0q7YZh6OnXhWGobvfTbfBdICNlnjca2/tBvV7PjYajJ4hF269brdZb/qFqpbpqfB84GgwGzzQajVaQFiUOkiT5wAwtryzvjb/IuXw+XxJQmJRqP4qiZBYgDENjdwDSlIKMixIEQabHGSWpB2DSooRSm/+SHaca00SaJMWzX3RxPBnqyXYfjKUb5XI5M7MGT0MBpQmor8PDwy7wFfvS3Nzc+ixA52NnVVJB0sCJO8G4t5WrhkeSbPv98XH8Lorav3WkXC5nFhZya3ayBmQcu9lqt7q/RrlSuWNYBwKkAxx34thfEGSz85eBEvbFiX232Wy+OhWmWq12JU3Th7bz0xHyZGX7mx2/aLfbn/+aRoCNjY2FpQtLK4gCdjE2QVb0YtPP5ea7W1tbw2n/Tyf84OJw4lGJAAAAAElFTkSuQmCC"; var uncheckStyle = 'background:white url("' + uncheckFavicon + '") no-repeat left center;color:black;padding-left:24px'; var checkStyle = 'background:red url("' + checkFavicon + '") no-repeat left center;color:black;padding-left:24px'; var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]. createInstance(Components.interfaces.nsIScriptableUnicodeConverter); converter.charset = "UTF-8"; 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 stream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream); var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker); const text1 = "Активные кнопки"; const text2 = "Неактивные кнопки"; 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, 0o666, 0); stream.write(fileContent, fileContent.length); stream.close(); } }); }; function createURI(node) { var name = node.getAttribute("name") || node.getAttribute("label") || ""; var image = node.getAttribute("image") || node.getAttribute("cb-stdicon") || ""; var mode = node.getAttribute("cb-mode") || 0; var initcode = node.getAttribute("cb-init") || ""; var code = node.getAttribute("cb-oncommand") || ""; var accelkey = node.getAttribute("cb-accelkey") || ""; var help = node.getAttribute("Help") || ""; var xhr = new XMLHttpRequest(); xhr.open("GET", "chrome://custombuttons/content/nbftemplate.xml", false); xhr.send(null); var doc = xhr.responseXML; setText(doc, "name", name, 0); setText(doc, "image", image, 1); setText(doc, "mode", mode, 0); setText(doc, "initcode", initcode, 1); setText(doc, "code", code, 1); setText(doc, "accelkey", accelkey, 1); setText(doc, "help", help, 1); var ser = new XMLSerializer(); var data = ser.serializeToString(doc); return "custombutton://" + escape(data); } function setText(doc, nodeName, text, make_CDATASection) { var node = doc.getElementsByTagName(nodeName)[0], cds; if (!node) return; if (make_CDATASection) { try { cds = doc.createCDATASection(text || ""); } catch(e) { cds = doc.createTextNode(text || ""); } node.appendChild(cds); } else { node.textContent = text; } } 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=y+"г."+" "+d+" "+m+" "+h+":"+min; var myfilename=curdate; return myfilename; } function bDate() { var curdate=y+" "+"год"+" "+d+" "+m+" "+h+":"+min; var myfilename=converter.ConvertFromUnicode(curdate); return myfilename; } this.close = function() { dialog.close(); } var data = '<?xml version="1.0"?>'; data += '<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>'; data += '<window title="' + this.label + '" onload="self.load()" xmlns="' + xulns + '">'; data += '<keyset>'; data += '<key keycode="VK_ESCAPE" oncommand="close()"/>'; data += '</keyset>'; data += '<vbox flex="1">'; data += '<richlistbox flex="1" id="listbox" height="555" width="600" context="menupopup" onclick = "self.handle(event)" tooltiptext = "L=Выбрать \nM=Выбрать все \nR=Копировать/Сохранить как… " > '; data += ' <listhead>'; data += '<treecol label="Label" width="342" tooltiptext = "Активные кнопки выделены жирным шрифтом"/>'; data += '<treecol label="Id" width="300" '; data += 'tooltiptext = "Активные кнопки выделены жирным шрифтом"/>'; data += '</listhead>'; data += '</richlistbox>'; data += '<popupset>'; data += '<menupopup id="menupopup">'; data += '<menuitem class="menuitem-iconic" image="data:application/file;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///8A////AESqAABHpgAASKAAAEukAQxMpQMYR6MAAEepAQ9MpgOLRKgACUenAABHpgAARKoAAP///wD///8A////AP///wBEqgAARaIAAFS2FVBj0jS3Y9AzyVG0EUROrwt8TKcDs0ikAANInwAAR6YAAESqAAD///8A////AP///wD///8ARKQAAVvJKJtj0jX/SaAJ/0abCv9UtSH/U7QX8lW5IMddwyfQW8Iii0mqBQ1DqQAA////AP///wD///8A////AEWlAAFYwB6YXsYc5F7GFt9bwA+vVbgWvU6rAKBRrgf0RZgA/02oDP9ezCzJR6UBA////wD///8A////AP///wBFrAAASKIAADiGNQAeYIIpF1iJHVa4GKEve0tFLHl1Pla7J51exRnUWL8VjEetAAP///8A////AP///wD///8AC0WuAAk/tAAANdpIAFD6/wA+7f8gd6jqBlPX+QBE9PIGS8uDLnZLADqNJwAzjDMA////AP///wD///8A////AAAw0QAALc0AAEPdegBI4f8AK8P/ADHX/wAwzf8AL8b/AEno/gAz2zYALtEQAC3VAP///wD///8A////AP///wAAMssAADjSMwBA2pIATen/ADG9/wBe1v8ATcz/ADHK/wBN5/4ASeH/AEvl6wA10DP///8A////AP///wD///8AADnTSQBO5/8ANc7/ADnR/xC+9/8C0f//AMj//wCP8P8ALcX/ACrC/wBE3f8ASeOf////AP///wD///8A////AABI4Z4ARN3/ACvG/wJAxP8Z5v//AMT//wDE//8Axv7/AETM/wA51P8AUervADjSPP///wD///8A////AP///wAAOdRiAFry+QBS6/QATOP/H+P8/xDe//8J1///E9H4/wFE2f8AReC6ADTOEwAyywD///8A////AP///wD///8AADDNAAAyzCcARN7WACvG/wVfzf8d0vf/HM30/whf0/8AI7n/ADzV+AA40kUAMswA////AP///wD///8A////AAAwywAAPNdTAEfg/wAsw/8AOdb/ADLP/wAswv8AReP/AC7H/wA40f8AR+GfADDKAP///wD///8A////AP///wAAMswAADfRQgBY8f8AT+j/AE7o7AA+1/8AK8T/AE7o/wBN5f8AVe7/AD/ZbAAwywD///8A////AP///wD///8AADPMAAAyywAANM4vADjSUQA0zikAU+z3AEff/wBJ4sMAN9EtADjROQAyywAAM8wA////AP///wD///8A////AAAzzAAAM8wAADHLAAAwywAAMcsAAD/YXQBK4pYAN9AxAC/KAAAwygAAM8wAADPMAP///wD///8A+R8AAPAfAADABwAAwAMAAPgDAADwHwAA8AcAAOADAADAAwAAwAMAAMAHAADgBwAA4AcAAOAHAADwDwAA/j8AAA==" label="Копировать изображение кнопки в base64" '; data += 'oncommand = "self.copyIMG()"/>'; data += '<menuitem class ="menuitem-iconic" image="chrome://custombuttons/skin/copy.png" label="Копировать кнопку в буфер обмена" '; data += 'oncommand = "self.copyURI()"/>'; data += '<menuitem class="menuitem-iconic" image="data:application/file;base64,AAABAAEAEBACAAEAAQCwAAAAFgAAACgAAAAQAAAAIAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAA/wAAAP8AAA" label="Копировать кнопку как BBcode ссылку" '; data += 'oncommand="self.copyBBCode()"/>'; data += '<menuitem class="menuitem-iconic" image="data:application/file;base64,AAABAAEAEBACAAEAAQCwAAAAFgAAACgAAAAQAAAAIAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAADbAAADpcAAA//AAANVwAAD/8AAAKsAAAD/AAAP//AAAP8AAAD/AAAD/8AAAwDAAAP/wAAA/wAAAP8AAA" label="Копировать кнопку как текст" '; data += 'oncommand="self.copyButtonsCodeText()"/>'; data += '<menuitem class="menuitem-iconic" image="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQf//rEH4j6xB8IesQeHDrEHD4axBh/CsQYf4rEGH8KxBw+GsQeHDrEHwh6xB+I+sQf//rEH//6xB//+sQQ==" label="Копировать кнопку как HTML ссылку" '; data += 'oncommand="self.copyHTML()"/>'; data += '<menuseparator id="separator"/>'; data += '<menuitem class="menuitem-iconic" image="data:application/file;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///8A////AESqAABHpgAASKAAAEukAQxMpQMYR6MAAEepAQ9MpgOLRKgACUenAABHpgAARKoAAP///wD///8A////AP///wBEqgAARaIAAFS2FVBj0jS3Y9AzyVG0EUROrwt8TKcDs0ikAANInwAAR6YAAESqAAD///8A////AP///wD///8ARKQAAVvJKJtj0jX/SaAJ/0abCv9UtSH/U7QX8lW5IMddwyfQW8Iii0mqBQ1DqQAA////AP///wD///8A////AEWlAAFYwB6YXsYc5F7GFt9bwA+vVbgWvU6rAKBRrgf0RZgA/02oDP9ezCzJR6UBA////wD///8A////AP///wBFrAAASKIAADiGNQAeYIIpF1iJHVa4GKEve0tFLHl1Pla7J51exRnUWL8VjEetAAP///8A////AP///wD///8AC0WuAAk/tAAANdpIAFD6/wA+7f8gd6jqBlPX+QBE9PIGS8uDLnZLADqNJwAzjDMA////AP///wD///8A////AAAw0QAALc0AAEPdegBI4f8AK8P/ADHX/wAwzf8AL8b/AEno/gAz2zYALtEQAC3VAP///wD///8A////AP///wAAMssAADjSMwBA2pIATen/ADG9/wBe1v8ATcz/ADHK/wBN5/4ASeH/AEvl6wA10DP///8A////AP///wD///8AADnTSQBO5/8ANc7/ADnR/xC+9/8C0f//AMj//wCP8P8ALcX/ACrC/wBE3f8ASeOf////AP///wD///8A////AABI4Z4ARN3/ACvG/wJAxP8Z5v//AMT//wDE//8Axv7/AETM/wA51P8AUervADjSPP///wD///8A////AP///wAAOdRiAFry+QBS6/QATOP/H+P8/xDe//8J1///E9H4/wFE2f8AReC6ADTOEwAyywD///8A////AP///wD///8AADDNAAAyzCcARN7WACvG/wVfzf8d0vf/HM30/whf0/8AI7n/ADzV+AA40kUAMswA////AP///wD///8A////AAAwywAAPNdTAEfg/wAsw/8AOdb/ADLP/wAswv8AReP/AC7H/wA40f8AR+GfADDKAP///wD///8A////AP///wAAMswAADfRQgBY8f8AT+j/AE7o7AA+1/8AK8T/AE7o/wBN5f8AVe7/AD/ZbAAwywD///8A////AP///wD///8AADPMAAAyywAANM4vADjSUQA0zikAU+z3AEff/wBJ4sMAN9EtADjROQAyywAAM8wA////AP///wD///8A////AAAzzAAAM8wAADHLAAAwywAAMcsAAD/YXQBK4pYAN9AxAC/KAAAwygAAM8wAADPMAP///wD///8A+R8AAPAfAADABwAAwAMAAPgDAADwHwAA8AcAAOADAADAAwAAwAMAAMAHAADgBwAA4AcAAOAHAADwDwAA/j8AAA==" label="Сохранить изображение кнопки" '; data += 'oncommand="self.saveIMG()"/>'; data += '<menuitem class="menuitem-iconic" image="data:application/file;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAD///8BAAAAFwAAAGkAAABzAAAAdQAAAHUAAAB1AAAAdQAAAHUAAAB1AAAAdQAAAHUAAAB1AAAAdQAAADkAAAAP////AQAAAIdgZmj/YWlt/2FobP9haGz/YGhr/2Boa/9fZ2v/X2dr/15mav9dZWn/XGRo/0ZNUP8AAACdAAAAFf///wEAAACr2tzc/9ve4P/a3t//1dnZ/7S2tf+foJz/m5ya/6apqP/O0tP/09fZ/9DV1v+hqq//AAAAuQAAABX///8BAAAAq+3u7//e4eL/ub29/2hnXv9oVUX/U0As/zgxGf83Lx3/YWBX/7a5uv/S1tj/o6yx/wAAALkAAAAV////AQAAAKv29/f/19na/1dUQf9jXDv/dmtJ/4FoSP9VQiL/V0Ek/008Iv9HQTP/yc3P/6Wus/8AAAC5AAAAFf///wEAAACr+Pj4/5uamP9tY0L/g31b/6GLa/+McVH/eFY5/4xwUv9yXkD/RTki/4uMiv+nsLT/AAAAuQAAABX///8BAAAAq/n6+v+FfXL/waSM/8qznf/DrZP/ooFi/7WfhP+qh2//blk9/1A+Iv9aWlH/pK2x/wAAALkAAAAV////AQAAAKv6+/v/d3Rr/9zCsP/RxbH/z8Wu/9fJt//Qvab/qItv/5iOb/9tYUH/VVJK/6Wtsf8AAAC5AAAAFf///wEAAACr+/z8/4mHff+3pI//3NK//+HXxf/m3Mz/5trJ/9rMuf+bgWT/d14//2hnYP+osbX/AAAAuQAAABX///8BAAAAq/z9/f/FxL7/j4l+//Xw5f/29ez/8/Dl/+DMuv/VuaP/poZn/2dFKv+srav/oamt/wAAALkAAAAV////AQAAAKv+/v7/+/z8/5iZjf+5uqr/6+PW/+3i1P/kzL3/vZR+/4NhSf+Qh3z/z9HS/4qQkv8AAAC1AAAAFf///wEAAACr/v7+//7+/v/u7u3/tbiv/5WSgP+DfGj/e25Z/29gTv+sppz/vr6+/5aYmP90eHr/AAAApwAAABP///8BAAAAq/////////////////7+/v/9/f3//f39//v8/P/5+fn/1dXV/2pqav9TU1P/QUFB/wEBAYkAAAAJ////AQAAAKv7+/v//////////////////v7+//7+/v/+/v7/+vr6/9fY2P/V1tb/7Ozs/4KCgv8EBAQrAAAAA////wEAAACFlJSU/6ioqP+qqqr/qqqq/6qqqv+qqqr/qKio/6anp/2kpaX9o6Oj/4qKitUZGRk9////Af///wH///8BAAAAFQAAAFUAAABVAAAAVQAAAFUAAABVAAAAVQAAAFUAAABTBAQEUx8fH1dfX18z////Af///wH///8BAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//w==" label="Сохранить кнопку как HTML файл" '; data += 'oncommand="self.SaveButton()"/>'; data += '<menuitem class="menuitem-iconic" image="data:image/gif;base64,R0lGODlhGAAQALMAAH9AAP+AAP/AgP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAQAAAEUFDISaudIevNu/9gKH5SVmIBVnLDILVBO2RyPHOAPAC2K9SwTm5H0wFvnJ+raJwFN8qWwDYc2lZFgBXGddY02kx4zCOHR+i0eg3Wut/wuDsCADs=" label="Сохранить кнопку как XML файл" '; data += 'oncommand="self.save1XML()"/>'; data += '</menupopup>'; data += '</popupset>'; data += '<hbox>'; data += '<spacer flex="1"/>'; data += '<button label="Сохранить избранное" oncommand="self.exportHTML()" '; data += 'oncontextmenu="self.exportHTML(),self.close()" '; data += 'tooltiptext = "Left - Сохранить выбранные кнопки Right - Сохранить выбранные кнопки и закрыть окно"/>'; data += '<button label="Сохранить все" oncommand="self.archiveall()" '; data += 'oncontextmenu="self.archiveall(),self.close()" '; data += 'tooltiptext = "Left - Сохранить все кнопки '; data += ' Right - Сохранить все кнопки и закрыть окно"/>'; data += '<button label="Выбрать все" oncommand="self.handle1()" '; data += 'tooltiptext = "Выбрать все кнопки"/>'; data += '<spacer flex="1"/>'; data += '</hbox>'; data += '<hbox>'; data += '<spacer flex="1"/>'; data += '<button label="Удалить" oncommand="self.delete()" '; data += 'tooltiptext = "Удалить выбранную кнопку"/>'; data += '<button label="Клонировать" oncommand="self.clone()" '; data += 'tooltiptext = "Клонировать рядом с собой выбранную кнопку"/>'; data += '<button label="Редактировать" oncommand="self.edit()" '; data += 'tooltiptext = "Редактировать выбранную кнопку"/> '; data += '<button label="Просмотр" oncommand="self.view()" '; data += 'oncontextmenu="self.view(),self.close()" '; data += 'tooltiptext = "Left - Просмотреть в новой вкладке код,свойтва, атрибуты'; data += 'Right - Просмотреть в новой вкладке код,свойтва,атрибуты и закрыть окно"/>'; data += '<spacer flex="1"/>'; data += '</hbox>'; data += '</vbox>'; data += '</window>'; data = data.replace(/self/g, "opener.document.getElementById("" + self.id + "")"); var pv = parseInt(Services.appinfo.platformVersion); var url = `data:application/${pv >= 73 ? "xhtm" : "vnd.mozilla.xu"}l+xml,${encodeURIComponent(data)}`; if (pv >= 69 && Services.appinfo.browserTabsRemoteAutostart) { var chromeURL = `chrome://custombuttons/content/cbdialog${Date.now()}.xul`; Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup).registerChrome( Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)), [["override", chromeURL, url]] ); url = chromeURL; } dialog = window.openDialog(url, "_blank", "chrome,centerscreen,resizable=yes"); this.reopen = function() { dialog.close(); dialog = window.openDialog(url, "_blank", "chrome,centerscreen,resizable=yes"); } this.load = function() { var aList = [], node = /custombuttons-button\d+/; var nodeList = document.getElementsByClassName("toolbarbutton-1 chromeclass-toolbar-additional"); for(var i = 0; i < nodeList.length; i++) if(nodeList[i].id.match(node)) aList.push(nodeList[i]); aList.sort(function (a, b) { a = a.getAttribute("label"); b = b.getAttribute("label"); if(a < b) return -1; if(a > b) return 1; return 0; }) for(var i = 0; i < aList.length; i++) createItem(aList[i]); var bList = [], node = /custombuttons-button\d+/; var nodeList = custombuttons.palette.getElementsByClassName("toolbarbutton-1 chromeclass-toolbar-additional"); for(var i = 0; i < nodeList.length; i++) if(nodeList[i].id.match(node)) bList.push(nodeList[i]); bList.sort(function (a, b) { a = a.getAttribute("label"); b = b.getAttribute("label"); if(a < b) return -1; if(a > b) return 1; return 0; }) for(var i = 0; i < bList.length; i++) createItem(bList[i]); function createItem(button) { var {document} = dialog; var item = document.createXULElement("richlistitem"); item.checked = false; item.setAttribute("style", uncheckStyle); item.setAttribute("value", button.id); item.setAttribute("selected", "false"); var cell = document.createXULElement("image"); cell.setAttribute("src", button.getAttribute("image") || getImage(button.getAttribute("cb-stdicon"))); item.appendChild(cell); var cell = document.createXULElement("label"); cell.style.width = "300px"; cell.setAttribute("value", button.getAttribute("name") || button.getAttribute("label") || ""); // Style these three if(button.getAttribute("initialized")) cell.style.fontWeight = "bold"; if(button.getAttribute("initialized")) cell.style.fontSize = "12px"; if(button.getAttribute("initialized")) cell.style.textShadow = "#999 2px 2px 2px"; if(!button.getAttribute("initialized")) cell.style.color = "#666"; if(!button.getAttribute("initialized")) item.setAttribute("initialized", true); item.appendChild(cell); var cell = document.createXULElement("label"); cell.setAttribute("value", nodeList[i].id); item.appendChild(cell); dialog.document.getElementById("listbox").appendChild(item); } function getImage(s) { if (s == "custombuttons-stdicon-1") return "chrome://custombuttons/skin/button.png"; if (s == "custombuttons-stdicon-2") return "chrome://custombuttons/skin/stdicons/rbutton.png"; if (s == "custombuttons-stdicon-3") return "chrome://custombuttons/skin/stdicons/gbutton.png"; if (s == "custombuttons-stdicon-4") return "chrome://custombuttons/skin/stdicons/bbutton.png"; return defaultFavicon; } dialog.document.getElementById("listbox").focus(); dialog.document.getElementById("listbox").selectAll(); } function toggleChoice(item) { item.checked = !item.checked; if (item.checked) item.setAttribute("style", checkStyle); else item.setAttribute("style", uncheckStyle) ; } this.handle = function(event) { var listbox = dialog.document.getElementById("listbox"); if (event.button == 0) toggleChoice(listbox.selectedItem); if (event.button == 1) for (var i = 0; i < listbox.itemCount; i++) toggleChoice(listbox.getItemAtIndex(i)); } this.handle1 = function(event) { var listbox = dialog.document.getElementById("listbox"); for (var i = 0; i < listbox.itemCount; i++) toggleChoice(listbox.getItemAtIndex(i)); } this.copyURI = function() { var listbox = dialog.document.getElementById("listbox"); var button = document.getElementById(listbox.selectedItem.getAttribute("value")); var href, text; if (button) { href = button.URI; text = button.name; } else { var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton"); for (var i = 0; i < nodeList.length; i++) { if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) { href = createURI(nodeList[i]); text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || ""; break; } } } custombuttons.cbService.writeToClipboard(href); custombuttons.alertSlide(text, "Код был скопирован в буфер обмена"); } this.copyBBCode = function() { var listbox = dialog.document.getElementById("listbox"); var button = document.getElementById(listbox.selectedItem.getAttribute("value")); var href, text; if (button) { href = button.URI; text = button.name; } else { var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton"); for (var i = 0; i < nodeList.length; i++) { if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) { href = createURI(nodeList[i]); text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || ""; break; } } } custombuttons.cbService.writeToClipboard("Install [url=" + href + "][img]" + defaultFavicon + "[/img][B] " + text + "[/B][/url]"); custombuttons.alertSlide(text, "BBCode был скопирован в буфер обмена"); } this.copyButtonsCodeText = function copyButtonsCodeText() { var listbox = dialog.document.getElementById("listbox"); var btn = document.getElementById(listbox.selectedItem.getAttribute("value")); if (!btn) return; var code = ((btn.cbCommand == "") || (btn.Command == "/*CODE*/")) ? "" : ("\n/*CODE*/\n" + btn.cbCommand + "\n"); var init = ((btn.cbInitCode == "") || (btn.cbInitCode == "/*Initialization Code*/")) ? "" : ("\n/*Initialization Code*/\n" + btn.cbInitCode); cbu.gClipboard.write(code + init); custombuttons.alertSlide(btn.name, "Code + INIT Code скопированы в буфер обмена"); } this.copyHTML = function() { var listbox = dialog.document.getElementById("listbox"); var button = document.getElementById(listbox.selectedItem.getAttribute("value")); var href, src, text; if (button) { href = button.URI; src = button.image; text = button.name; } else { var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton"); for (var i = 0; i < nodeList.length; i++) { if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) { href = createURI(nodeList[i]); src = nodeList[i].getAttribute("image"); text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || ""; break; } } } if (!src) src = defaultFavicon; custombuttons.cbService.writeToClipboard('<a href="' + href + '"><img alt="" src="' + src + '">' + " " + text + "</a>"); custombuttons.alertSlide(text, "HTML был скопирован в буфер обмена"); } this.copyIMG = function() { var listbox = dialog.document.getElementById("listbox"); var button = document.getElementById(listbox.selectedItem.getAttribute("value")); var href, src, text; if (button) { src = button.image; text = button.name; } else { var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton"); for (var i = 0; i < nodeList.length; i++) { if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) { src = nodeList[i].getAttribute("image"); text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || ""; break; } } } if (!src) custombuttons.alertBox(text + "\n" + "Эта кнопка не имеет изображения!"); else {custombuttons.cbService.writeToClipboard(src); custombuttons.alertSlide(text, "Изображение кнопки было скопировано в буфер обмена"); } } this.saveIMG = function() { var listbox = dialog.document.getElementById("listbox"); var button = document.getElementById(listbox.selectedItem.getAttribute("value")); var href, src, text; if (button) { src = button.image; text = button.name; } else { var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton"); for (var i = 0; i < nodeList.length; i++) { if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) { src = nodeList[i].getAttribute("image"); text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || ""; break; } } } if (!src) custombuttons.alertBox(text + "\n" + "Эта кнопка не имеет изображения!"); else if(button.image != "") { var br = gBrowser; var tab = br.selectedTab; gBrowser.selectedTab = gBrowser.addTab(button.image, { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }); setTimeout( function() { window.content.document.title = button.name; saveDocument(window.content.document); // br.removeCurrentTab(); br.selectedTab = tab; }, 200); } } this.SaveButton = function() { var listbox = dialog.document.getElementById("listbox"); var id = listbox.selectedItem.getAttribute("value"); var btn = document.getElementById(id); var btnname, btnimage, btnURI, btncbInitCode, btncbCommand, btnHelp; if (btn) { btnname = btn.name; btnimage = btn.image; btnURI = btn.URI; btncbInitCode = btn.cbInitCode; btncbCommand = btn.cbCommand; btnHelp = btn.Help; } else { var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton"); for (var i = 0; i < nodeList.length; i++) { if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) { btnimage = nodeList[i].getAttribute("image"); btnname = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || ""; btnURI = createURI(nodeList[i]); btncbInitCode = nodeList[i].getAttribute("cb-init"); btncbCommand = nodeList[i].getAttribute("cb-oncommand"); btnHelp = nodeList[i].getAttribute("Help"); break; } } } if (!btnimage) btnimage = defaultFavicon; var xml = '<html xmlns="' + e4xConv_encodeHTML(xhtmlns, true) + '">\n\ <head>\n\ <meta http-equiv=\'Content-Type\' content=\'text/html; charset=utf-8\'/>\n\ <title>' + e4xConv_encodeHTML(btn.name + ' for Custom Buttons') + '</title>\n\ <link rel=\'icon\' type=\'image/vnd.microsoft.icon\' href="' + e4xConv_encodeHTML(btn.image, true) + '"/>\n\ <style type="text/css">\n\ .button a{\n\ background-color: rgb(85, 168, 2);\n\ background-image: linear-gradient(to bottom, rgb(147, 200, 94), rgb(85, 168, 2));\n\ background-image: -moz-linear-gradient(top, rgb(147, 200, 94), rgb(85, 168, 2));\n\ border: 1px solid rgb(58, 116, 4);\n\ border-radius: .5em;\n\ -webkit-border-radius: .5em;\n\ padding: 0;\n\ margin-bottom: 1em;\n\ box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\ -o-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\ -webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\ color: #000;\n\ text-shadow: -1pt -1px 0pt rgba(255, 255, 255, .5);\n\ padding: 0.5em;\n\ text-decoration: none;\n\ }\n\ pre { border: 1px inset rgb(170, 170, 170); \n\ background-color: rgb(255, 255, 255);}\n\ body { background-color: rgb(245, 245, 220);} \n\ </style> \n\ </head>\n\ <body>\n\ <section id=\'install\'><h1>' + e4xConv_encodeHTML(btn.name) + '</h1>\n\ </section>\n\ <div class="button"><a href="' + e4xConv_encodeHTML(btn.URI, true) + '">Установить кнопку</a></div>\n\ <section id=\'init\'><h2>Инициализация</h2><pre>' + e4xConv_encodeHTML(btn.cbInitCode) + '</pre></section>\n\ <section id=\'code\'><h2>Код</h2><pre>' + e4xConv_encodeHTML(btn.cbCommand) + '</pre></section>\n\ <section id=\'help\'><h2>Справка</h2><pre>' + e4xConv_encodeHTML(btn.Help) + '</pre></section>\n\ </body>\n\ </html>'; var html1 = '<!DOCTYPE html>\n' + xml; name = btn.name + ".HTML"; var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]. createInstance(Components.interfaces.nsIScriptableUnicodeConverter); converter.charset = "UTF-8"; var html = converter.ConvertFromUnicode(html1); saveToFile(html, name); custombuttons.alertSlide("Кнопка: " + btn.name, "сохранена"); } this.edit = function() { var out = new Array(); var listbox = dialog.document.getElementById("listbox"); for (var i = 0; i < listbox.itemCount; i++) { if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) { var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")); custombuttons.editButton(document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"))); } } } this.save1XML = function() { var btn = null; var btns = document.querySelectorAll("toolbarbutton[cb-init]"); for (var i = 0; i < btns.length; i++) { if ("saveXML" in btns[i]) { btn = btns[i]; break; } } if (!btn) { custombuttons.alertBox(this.label, "Кнопка XML Exporter/Importer не установлена"); return; } var listbox = dialog.document.getElementById("listbox"); var id = listbox.selectedItem.getAttribute("value"); btn.saveXML(document.getElementById(id).URI); } this.clone = function() { var out = new Array(); var listbox = dialog.document.getElementById("listbox"); for (var i = 0; i < listbox.itemCount; i++) { if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) { var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")); custombuttons.cloneButton(document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"))); this.reopen(); } } } this.delete = function() { var out = new Array(); var listbox = dialog.document.getElementById("listbox"); for (var i = 0; i < listbox.itemCount; i++) { if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) { var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")); var id = listbox.getItemAtIndex(i).getAttribute("value"); var oRemovedButton = document.getElementById(id); var sParentToolbarId = oRemovedButton.parentNode.id; var sRemovedButtonId = oRemovedButton.getAttribute("id"); var cButtonsToRemove = document.getElementsByAttribute("id", sRemovedButtonId); var bRemoveFromOverlay = cButtonsToRemove.length == 1; custombuttons.cbService.removeButton(oRemovedButton, bRemoveFromOverlay); custombuttons.persistCurrentSets(sParentToolbarId, sRemovedButtonId, null); this.reopen(); } } } this.view = function() { var listbox = dialog.document.getElementById("listbox"); var id = listbox.selectedItem.getAttribute("value"); var box = custombuttons.confirmBox3("CB TOOLS", "Просмотр в новой вкладке:", "Код", "Свойства", "Атрибуты"); if (box == 0) this.link(); if (box == 2) this.attr(); if (box == 1) this.prop(); this.reopen(); } var br = gBrowser; function openTab(arr) { for (var i = 0; i < arr.length; i++) { arr[i] = converter.ConvertFromUnicode(arr[i]); arr[i] = arr[i].replace(/&/g, "&"); arr[i] = arr[i].replace(/>/g, ">"); arr[i] = arr[i].replace(/</g, "<"); arr[i] = arr[i].replace(/"/g, """); arr[i] = arr[i].replace(/'/g, "'"); } var data = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//En">'; data += "<html><head><title>" + arr[1] + "</title>"; data += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">'; data += "</head><body><pre>" + arr.join("\n\n") + "</pre></body></html>"; var info = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULAppInfo); if (info.name == "Firefox" || info.name == "SeaMonkey") { var tret = "data:text/html;charset=utf-8;base64," + btoa(data); br.selectedTab = br.addTab(tret, { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() }); } if (info.name == "Thunderbird") { openContentTab("data:text/html;charset=utf-8;base64," + btoa(data)); } } this.attr = function() { var listbox = dialog.document.getElementById("listbox"); var id = listbox.selectedItem.getAttribute("value"); var node = document.getElementById(id); var out = new Array(); out.push('windowtype="' + document.documentElement.getAttribute("windowtype") + '" id="' + id + '"'); out.push("Атрибуты"); for (var i = 0; i < node.attributes.length; i++) { if (node.attributes[i].nodeName == "cb-oncommand" || node.attributes[i].nodeName == "cb-init" || node.attributes[i].nodeName == "Help") { out.push(node.attributes[i].nodeName + " " + typeof node.attributes[i].nodeValue + "\n" + "[omitted]"); } else { out.push(node.attributes[i].nodeName + " " + typeof node.attributes[i].nodeValue + "\n" + node.attributes[i].nodeValue); } } openTab(out); } this.prop = function() { var listbox = dialog.document.getElementById("listbox"); var id = listbox.selectedItem.getAttribute("value"); var node = document.getElementById(id); var out = new Array(); out.push('windowtype="' + document.documentElement.getAttribute("windowtype") + '" id="' + id + '"'); out.push("Свойства"); for (var i in node) { if (i == "cbCommand" || i == "cbInitCode" || i == "Help" || i == "URI") { out.push(i + " " + typeof node[i] + "\n" + "[omitted]"); } else { out.push(i + " " + typeof node[i] + "\n" + node[i]); } } openTab(out); } this.link = function() { var listbox = dialog.document.getElementById("listbox"); var id = listbox.selectedItem.getAttribute("value"); var out = new Array(); out.push('windowtype="' + document.documentElement.getAttribute("windowtype") + '" id="' + id + '"'); out.push("Код"); out.push(unescape(document.getElementById(id).URI)); openTab(out); } this.inspect = function() { if (typeof(inspectDOMDocument) == "undefined") { custombuttons.alertBox(this.label, "DOM Инспектор не установлен."); return; } var listbox = dialog.document.getElementById("listbox"); var id = listbox.selectedItem.getAttribute("value"); inspectDOMNode(document.getElementById(id)); } this.setFolder1 = function(){ BrowserOpenFileWindow(); } this.exportHTML = function () { var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]. createInstance(Components.interfaces.nsIScriptableUnicodeConverter); converter.charset = "UTF-8"; var out = new Array(); var listbox = dialog.document.getElementById("listbox"); for (var i = 0; i < listbox.itemCount; i++) { if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) { var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")); var href = button.URI; var src = button.image; var text = button.name; if (!src) src = defaultFavicon; out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>'); } } var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton"); for (var i = 0; i < nodeList.length; i++) { if (nodeList[i].id.search("custombuttons-button") == 0 && document.getElementById(nodeList[i].id) == null) { for (var j = 0; j < listbox.itemCount; j++) { if (listbox.getItemAtIndex(j).checked && nodeList[i].id == listbox.getItemAtIndex(j).getAttribute("value")) { var href = createURI(nodeList[i]); var src = nodeList[i].getAttribute("image"); var text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || ""; if (!src) src = defaultFavicon; out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>'); } } } } var data = document.getElementById(this.id).getAttribute("Help"). replace("<ol>", bDate() + "\n" + "<ol>" + "\n" + out.join("\n")); name = "CB buttons " + aDate().replace(/:/g, ".") + ".html" // name = "CB buttons " + new Date().toLocaleFormat("%d.%m.%Y. %H·%M·%S") + ".html" saveToFile(data, name); custombuttons.alertSlide("Кнопки", "сохранены"); } this.archiveall = function() { var out = new Array(); out.push('<a><hr><strong>' + converter.ConvertFromUnicode(text1) + '</strong><hr></a>'); var listbox = dialog.document.getElementById("listbox"); for (var i = 0; i < listbox.itemCount; i++) { if (document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) { var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")); var href = button.URI; var src = button.image; var text = button.name; if (!src) src = defaultFavicon; out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>'); } } var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton"); out.push('<a><hr><strong>' + converter.ConvertFromUnicode(text2) + '</strong><hr></a>'); for (var i = 0; i < nodeList.length; i++) { if (nodeList[i].id.search("custombuttons-button") == 0 && document.getElementById(nodeList[i].id) == null) { var href = createURI(nodeList[i]); var src = nodeList[i].getAttribute("image"); var text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || ""; if (!src) src = defaultFavicon; out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>'); } } var data = document.getElementById(this.id).getAttribute("Help"). replace("<ol>", bDate() + "\n" + "<ol>" + "\n" + out.join("\n")); name = "CB buttons " + aDate().replace(/:/g, ".") + ".html" saveToFile(data, name); } function readFile(file) { var data = ""; var fstream = Cc["@mozilla.org/network/file-input-stream;1"]. createInstance(Ci.nsIFileInputStream); fstream.init(file, -1, 0, 0); var charset = "UTF-8"; const replacementChar = Ci.nsIConverterInputStream .DEFAULT_REPLACEMENT_CHARACTER; var is = Cc["@mozilla.org/intl/converter-input-stream;1"]. createInstance(Ci.nsIConverterInputStream); is.init(fstream, charset, 1024, replacementChar); var str = {}; while (is.readString(4096, str) != 0) { data += str.value; } is.close(); return data; } function stringToDOM(aString) { var parser = new DOMParser(); var dom = parser.parseFromString(aString, "text/xml"); if (dom.documentElement.nodeName == "parsererror") { return null; } else { return dom; } } function e4xConv_encodeHTML(s, isAttr) { s = String(s) .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """); if(isAttr) { s = s .replace(/\t/g, "	") .replace(/\n/g, "
") .replace(/\r/g, "
"); } return s; };
На форуме
Andrey_Krropotkin
Ну как почему, потому что образуется ошибка.
В данном выражении, скобки — это оператор вызова функции.
Если идёт попытка вызова этого оператора на чём-то, не являющимся функцией,
то будет ошибка «TypeError: ... is not a function».
getElementsByClassName() — это метод Element'а или Document'а.
А custombuttons.palette, он же gNavToolbox.palette, ни тем, ни другим не является,
соответственно, метода getElementsByClassName() не имеет. Вот и ошибка.
Раньше был элементом, но затем, в Firefox 78+, превратили в HTMLTemplateElement.content,
то есть в DocumentFragment. Таким образом, можно записать
var nodeList = custombuttons.palette.querySelectorAll(".toolbarbutton-1.chromeclass-toolbar-additional");
Отсутствует
А вот этот код, копирующий адрес табов, можно приспособить под современные реалии?
(function() { // выходим, если функция уже выполнялась if (document.getElementById("copyTabInfo")) return; var htmlEscape = function(s) { s = s.replace(/&/g, "&"); s = s.replace(/>/g, ">"); s = s.replace(/</g, "<"); s = s.replace(/"/g, """); return s; }; var copyTabInfo = function (event) { var tab = document.popupNode; var url = gBrowser.getBrowserForTab(tab).contentWindow.location.href; Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper).copyString(url); }; var copyTabBBC = function (aAsBBC) { var tab = document.popupNode; var title = tab.label; var url = gBrowser.getBrowserForTab(tab).contentWindow.location.href; var txt = aAsBBC ? '[url=' + htmlEscape(url) + ']' + htmlEscape(title) + '[/url]' : title + "\n" + url; Cc["@mozilla.org/widget/clipboardhelper;1"] .getService(Ci.nsIClipboardHelper) .copyString(title); }; var menuitem1 = document.createElement("menuitem"); menuitem1.setAttribute("label", "Копировать адрес"); menuitem1.setAttribute("id", "copyTabInfo"); menuitem1.addEventListener("command", function() { copyTabInfo(event); }, false); var menuitem2 = document.createElement("menuitem"); menuitem2.setAttribute("label", "Копировать Title"); menuitem2.addEventListener("command", function() { copyTabBBC(true); }, false); setTimeout(function() { gBrowser.mStrip.childNodes[1].appendChild(document.createElement("menuseparator")); gBrowser.mStrip.childNodes[1].appendChild(menuitem1); gBrowser.mStrip.childNodes[1].appendChild(menuitem2); }, 0); })();
Отсутствует
Dumby
Я в шоке , опять проблема с поисковиками... Правил SearchService.jsm , теперь и это не помогает...Или помогает, так в настойках поиск отсутствует...
Откуда теперь тянет поисковики? main из default убрал ...прет ozon, price.ru, mail.ru и т.д. Откуда? Из локали? не вижу. В SearchService.jsm вставлять lisr.json ?
Еще и яндекс по умолчанию...На черта он нужен?
Как это и куда вставить?
{ "default": { "searchDefault": "Startpage", "searchOrder": ["Startpage", "Google", "Bing", "Yandex-Ua", "Yandex", "Yahoo", "Teoma"], "visibleDefaultEngines": [ "google", "bing", "yandex", "ask", "aol", "Bigcinema", "boardreader", "mailru", "Dogpile", "Teoma", "hotline-ua", "Seasonvar", "Rambler", "firefox", "youtube", "yahoo", "wikipedia", "Startpage", "ecosta", "hdrezka"] } }
Services.search.addPolicyEngine({ iconURL: "data:image/x-icon;charset=utf-8;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdK7CwSU+x9B0rslQhL7bAHSuy2B0rstgdK7LAGSeusBknrewZJ6z0HSuyQBknrGgAAAAAAAAAAAAAAAAdK7CcHSuzIAADeYgZJ63IHSuz/CEvt/wdK7P8IS+3/B0rsyAZJ6xMHSuyfBknrfgVI6gEAAAAAAAAAAAAAAAAGSetgB0rsngAAAAAGSeujCEvt/ghL7fcIS+35B0rs/QdK7OQGSes2B0rssAZJ6w4AAAAAAAAAAAAAAAAAAAAABknrNQdK7I6GqPgVB0rs3QdK7P8IS+39Ck3v+whL7f8HSuzXBUjqmgZJ67YGSesFAAAAAAAAAAAAAAAAAAAAAAdK7AQGSet2ACvmKQdK7d0IS+3/Ck3t/AhL7fwIS+3+CEvt5wdK7PIGSeuQAAAAAAdK7AEAAAAAAAAAAAdK7AIAAAAABknrRg1P7FsHSuzQCEvt/ghL7fwIS+3+Ck3v/QdK7P0IS+3/B0rsfAAAAAAIS+0CAAAAAAAAAAAAAAAAAAAAAAZJ6yEFSOpaB0rrkwhL7P8KTe/4B0rs/gpN7/4IS+36Ck3v/gdK7KUAAAAAAAAAAAAAAAAAAAAAAAAAAAVI6gkAAAAABEfqUwVJ60oHSuvuCEvt/whL7fcIS+38B0rs/AhL7f4GSevwx9j+JgAAAAAAAAAAAAAAAAAAAAAFSOpzBknrdgVI6l0LSuwSB0rsVQZJ6+8HSuz/CEvt/QhL7f0IS+37B0rs/wAw54EAAAAABknrBAAAAAAAAAAABUjqJwZK7HsITe8zC0rsAQAAAAAFSOo9BknrvwhL7fUIS+39Ck3v+ghL7f8KTeyJAAAAAAdK7AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaXf8DAAAAAAVI6gwFSOqOB0rs/wpN7/sHSuz4B0rsNgAAAAAIS+0BAAAAAAAAAAAAQ+UBAUrsAgAAAAEAAAAAAAAAAAdK7AQAAAAACEvtPwZJ6/MIS+36Bknr+QVI6qQFSOo0AAAAAAVI6gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkXnAQRH6QQGSeumB0rs/whL7fUHSuz/BknrtgRH6QQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARH6QIAAAAABUjqWQdK7PEIS+34B0rs5QZJ61AAAAAAB0rsAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0rsAgAAAAAGSeuYBknr/whL7TkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZJ6wEAAAAABUjqJAZJ634AAAAAB0rsAQAAAAAAAAAAwAMAAIADAACQBwAAgAcAAIALAABACwAAwA8AAKAHAACABQAAhAUAAPoFAACNAgAA/gEAAP6CAAD/RwAA/0sAAA==", chrome_settings_overrides: { search_provider: { name: "Seasonvar.Ru", search_url: "http://seasonvar.ru/search", search_form: "http://seasonvar.ru/", search_url_get_params: "q={searchTerms}" } } });
Так делал:
// try { Services.search.init().then(() => { if (!Services.search.getEngineByName("Seasonvar.ru")) { //Services.search.addEngine("data:text/xml," + encodeURIComponent(` (Services.search.addOpenSearchEngine || Services.search.addEngine)("data:text/xml," + encodeURIComponent(` <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> <ShortName>Seasonvar.ru</ShortName> <Description>Сериалы ТУТ! Сериалы онлайн смотреть бесплатно. Смотреть онлайн.</Description> <InputEncoding>UTF-8</InputEncoding> <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADvklEQVRYhb1XTYgcRRR+JtNVr0ail0gUPLkehBwEVwgakMHNdr1XKwQ8RFQwF39uOXnxtkIwieAhetWLeoh7VVBE3IPgYY1gCIFA0OzOdL0aMYoH4y5xZsrDdjUzk91sz8BsQTFU09Pfz3uvXhXAjEax2FjoWP34MsCBWWHsDm7VKWGMwrh+7SiofScQnAlC+j9xeHvfwQvSbwnpO4FxIKTveKs+2TcXCsKF4EwMjINqOhODM1Fs9tRMwX9fgCPCGIX0oLvUjNV0ZhCciZ7wh5stwJkR6OTq1aR+hMBSs3LEW/3tzAh4q04OExj+DYwDYYxi8fWZgLcXG7kwbg6rT2S2y1H3hPRXMwEHABBnLgeH/cA46DozSLEvc+LrmQGn4UlfGY99cuD6cTg0U/B23nhOGO9OvtKB4PD7iT/qc/PsXu8I45vC2E3gaQ470HVmIKT/XgE4WAt4I89OF6S2PKnPA+ON3xbgyPg7geGhwPidMMauM4NU5+Oll1zwpLc6z4Cpp5zwlif9MwDAagsaweEXI6pz9YQn1R9Rm5Juh7ldBbp3JYf7axEorLoa2HwEALACcLCwahMA7gMA2DiBjw3bvRvoeAg84a3aIbg8D9ly2b9XW9DwrP8FAFi38Ig47EsqtaGNZjflVRISnq4FPj6uH4dDnvESAIA4c7FUFMO9Yj629QpjmAocAKCTq/eFtF0GODCJ9SkptxuQvjg1AWGMNxgeEMazeyneKfbBmbg+bQsubPakt7oLACCEa7XVjzlwswUPT6ee8LOCcAEAILCRWolXKq+2YWeitODw5ODz0PSkN9M6LDX/qhuC6gRUdsGC4dEp1OszwmatWrP5sxaBdPKx+K6w7gVnYnsxe3oKAihC+oO09ozFXvYPh6G92MiFUIQxetZvTwTeZj3nScci1y8MEVqrcuAeTlSll6uXOqReFMZYkFqZiMC2fRglz+bTs8KqT9PH99r3gzOxsOoUAIA4vO1J/zIZAdIfCmP0uV5Mzzp5dqzqfLspT1sv6UEnz44BAHjGS5701kQEpLTO8+jptTxY9HcsvSo/TN9b9U/6T5vUy9v3AfXKZC6w/rK81/306wl4sHTm4+FsHwF3JnaXTF8YY/t5mFttQWO5bGjCGAurrso8NKHsqjWd0Gc84x/pRBsc9kZuPCknqqOX7gVnup5xQxi3POGPJfFvSjEjeVVrXDsKqs16zlt1smOzN4TUO8J41hOe86wveNYXvFXnPalzBeF7aXqL54s8q1qwkLaFzV5Lbo6P/wEF7JeDr5SEggAAAABJRU5ErkJggg==</Image> <Url type="text/html" method="GET" template="http://seasonvar.ru/search"> <Param name="q" value="{searchTerms}"/> </Url> <SearchForm>http://seasonvar.ru/</SearchForm> </SearchPlugin> `), null, null); } }); } catch(e) {}
Отредактировано solombala (25-02-2021 16:23:38)
Отсутствует
код, копирующий адрес табов, можно приспособить под современные реалии?
Никакой адрес табов код не копирует.
Код добавляет в контекстное меню табов свои пункты, вернее, добавлял бы,
если бы в бесполезной функции htmlEscape не было бы синтаксической ошибки.
Если есть сомнение, возможно ли в «современных реалиях» добавление,
тогда пишем что-нибудь, и смотрим, добавляется или нет.
(popup => { var prfx = `cb${_id.slice(20)}-tabCopy-`; var menuitem = popup.appendChild(document.createXULElement("menuitem")); menuitem.id = prfx + "url"; addDestructor(() => popup.querySelectorAll(`[id^="${prfx}"]`) .forEach(n => n.remove()) ); menuitem.render = () => { var node = document.createXULElement("menuseparator"); node.id = prfx + "sep"; menuitem.before(node); menuitem.setAttribute("oncommand", "tcopy(this.id)"); node = menuitem.cloneNode(false); node.id = prfx + "bbc"; node.setAttribute("label", "2"); menuitem.after(node); menuitem.setAttribute("label", "1"); menuitem.tcopy = node.tcopy = id => { var tab = TabContextMenu.contextTab; var uri = gBrowser.getBrowserForTab(tab).currentURI; var url = gURLBar.makeURIReadable(uri).displaySpec; gClipboard.write(id.endsWith("l") ? url : `[url=${url}]${tab.label}[/url]`); } delete menuitem.render; menuitem.render(); } })(document.getElementById("tabContextMenu"));
опять проблема с поисковиками... Правил SearchService.jsm
Я так понимаю, что смысл твоих усилий не в том, чтобы просто добавить поисковики,
но в том, чтобы браузер воспринимал их как свои собственные (встроенные).
Я тут попробовал организовать такое на 86, но как-бы снаружи, без правки omni.ja
2. Чтобы поисковики брались из этой папки, добавляем код в config.js
(будет перечислено всё, поэтому держим в папке только нужные).
В коде можно указать дефолтный поисковик.
Также, включён и http-патч (правка omni.ja на предмет этого тоже не требуется).
// (async cso => { var defaultEngine = "google"; var rph = Cc["@mozilla.org/network/protocol;1?name=resource"].getService(Ci.nsIResProtocolHandler); var uri = rph.getSubstitution("gre").QueryInterface(Ci.nsIJARURI).JARFile.QueryInterface(Ci.nsIFileURL); var se, dir = uri.file.parent; dir.append(se = "search-extensions"); if (!dir.exists() || !dir.isDirectory()) return; var u = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService).newURI; var json = Cu.readUTF8URI(u(cso)).replace(/https(?!\?)/g, "$&?"); var jsonURL = "data:application/json;charset=utf-8," + encodeURIComponent(json); var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup); globalThis[Symbol("http mod")] = ams.registerChrome(uri, [["override", cso, jsonURL]]); rph.setSubstitution(se, u(uri.spec.replace(/omni\.ja$/, se))); var sel = {engines: []}; for(var {leafName} of dir.directoryEntries) sel.engines[ leafName == defaultEngine ? "unshift" : "push" ]({webExtension: {id: leafName + "@search.mozilla.org", locale: "default"}}); Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsISearchService) .wrappedJSObject._fetchEngineSelectorEngines = async () => sel; })("chrome://browser/content/schemas/chrome_settings_overrides.json");
3. Запускаем код, который должен очистить базы профиля от налипших
предыдущих встроенных поисковиков, и сам перезапустить браузер.
Запустить только один раз, из консоли, или по нажатию на кнопку.
(async () => { var ss = Services.search.wrappedJSObject; var engines = Array.from(ss._sortedEngines); for(var engine of engines) { if (!engine._isAppProvided) continue; engine._isAppProvided = false; var addon = await AddonManager.getAddonByID(engine._extensionID); await addon.uninstall(); } Object.defineProperty(ss._settings, "_currentSettings", { configurable: true, enumerable: true, set(val) { val.engines.length || Object.defineProperty(val, "engines", { configurable: true, enumerable: true, get(val) { delete this.engines; this.engines = []; return " "; } }); delete this._currentSettings; this._currentSettings = val; } }); Services.obs.addObserver(function obs(s, topic, data) { if (data != "write-settings-to-disk-complete") return; Services.obs.removeObserver(obs, topic); Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart); }, "browser-search-service"); })();
Всё. Если перезапустилось, поисковики должны подхватиться из этой папки search-extensions.
Разумеется, если экспериментировать, то только на отдельной чистой сборке,
и не только потому, что возможны конфликты с (неизвестно как) «правленным SearchService.jsm»,
но и просто из осторожности, а то мало ли, что у меня работает, ещё испортится что-нибудь.
Отсутствует
Dumby
Тонкий ход...Нет слов...Осталось допилить , все остальные по алфавиту ...
var defaultEngine = "Startpage"; Как бы другие выставить , как мне надо? Типа, как в list.json было:
"searchOrder": ["Startpage", "Google", "Bing", "Yandex-Ua", "Yandex", "Yahoo", "Teoma"],
Добавлять , в принципе, итак получалось, но таскать после очистки профиля неохота...Лезут вверх всякие AOl , Ask ..алфавит ...
Отредактировано solombala (25-02-2021 20:59:39)
Отсутствует