>Форум Mozilla Россия http://forum.mozilla-russia.org/index.php >Сustom Buttons http://forum.mozilla-russia.org/viewforum.php?id=34 >[CB]Attributes Inspector (для разработчиков) http://forum.mozilla-russia.org/viewtopic.php?id=56041 |
Infocatcher > 18-08-2012 00:03:21 |
Attributes Inspector 0.6.4 (2016-02-23) Установить: attrsInspector.html Выделить код Код:this.onmouseover = function(e) { this.focusedWindow = Components.classes["@mozilla.org/appshell/window-mediator;1"] .getService(Components.interfaces.nsIWindowMediator) .getMostRecentWindow(null); }; this.onmouseout = function(e) { this.focusedWindow = null; }; this.setAttribute("oncommand", "this.focusedWindow && this.focusedWindow.focus();"); Также код можно использовать из других расширений, позволяющих выполнять произвольный код в контексте главного окна приложения, например, из Mouse Gestures. Известные ограничения Проблемы с позиционированием всплывающей подсказки при перемещении по DOM-дереву в Firefox 3.0 и 3.5 В Firefox 3.0 и 3.5 невозможно перехватить клик по всплывающей подсказке В Firefox 1.5 и 2.0 при зажатом Shift всплывающие подсказки не показываются. В Firefox 1.5 нельзя загрузить полное дерево (ограничения соответствующей версии DOM Inspector'а) |
Infocatcher > 18-08-2012 00:08:55 |
Осторожно, это тестовая версия! |
Infocatcher > 18-10-2012 21:57:46 |
Attributes Inspector 0.6.0pre11 (2012-10-18) |
Infocatcher > 05-12-2012 12:59:38 |
Attributes Inspector 0.6.0pre12 (2012-12-05) |
Infocatcher > 20-12-2012 01:08:20 |
Исправление ошибки «TypeError: Value is not callable» в Nightly 20.0a1 (2012-12-19) (https://bugzilla.mozilla.org/show_bug.cgi?id=790978) |
Infocatcher > 13-01-2013 22:04:46 |
Attributes Inspector 0.6.0 (2012-12-20) 13-01-2013 22:06:26 0.6.0pre12 (2012-12-05) 0.6.0pre11 (2012-10-18) 0.6.0pre10 (2012-08-17) 0.6.0pre9 (2012-08-16) 0.6.0pre7 (2012-07-07) 0.6.0pre6 (2012-07-05) 0.6.0pre5 (2012-07-05) 0.6.0pre4 (2012-07-04) 0.6.0pre3 (2012-07-04) 0.6.0pre2 (2012-07-04) 0.6.0pre (2012-07-02) 0.5.2pre (2011-08-30) |
bunda1 > 11-05-2013 18:49:30 |
0.6.1pre3 - 2013-03-31 не открывает средней кнопкой полосу прокрутки (скролбар) на страницах в инспекторе. |
Infocatcher > 11-05-2013 18:56:19 |
bunda1 пишет
С этим ничего не сделать: событие клика или не генерируется вообще, или перехватывается где-то раньше. |
Infocatcher > 19-05-2013 18:49:36 |
Attributes Inspector 0.6.1 (2013-05-19) |
DAntES > 04-06-2013 11:09:11 |
После добавления работает нормально. Но через некоторое время кнопка перестаёт нажиматься. В меню добавления кнопок картинка становится растянутой. Mozilla v. 21 |
Infocatcher > 04-06-2013 11:27:35 |
DAntES |
voqabuhe > 06-08-2013 11:15:12 |
Infocatcher |
Infocatcher > 06-08-2013 11:31:45 |
voqabuhe |
voqabuhe > 06-08-2013 12:37:52 |
Infocatcher пишет
Спасибо, вроде всё работает. |
Infocatcher > 15-08-2013 17:33:40 |
Attributes Inspector 0.6.2 (2013-08-15) |
Dumby > 16-10-2013 20:34:16 |
Infocatcher Иногда случается, что хочется посмотреть в DOM Inspector'е Для себя, пока что, прицепился так, но ... скрытый текст Выделить код Код:else if( // Ctrl+W, Ctrl+Shift+W ctrlOrCtrlShift && ( e.keyCode == e.DOM_VK_W // keydown || keyup || e.keyCode == 0 && String.fromCharCode(e.charCode).toUpperCase() == "W" // keypress ) ) { this._checkPreventDefault(e); this.stopEvent(e); if(onlyStop) return; this.stopSingleEvent(top, "keyup"); var nodes = this._nodes; if(nodes.length) { var nWin = nodes[0].ownerDocument.defaultView; if(ctrlShift) nWin = nWin.top; var iWin = openDialog( "chrome://inspector/content/object.xul", "_blank", "chrome,all,dialog=no", nWin ); iWin.addEventListener("load", function load() { iWin.removeEventListener("load", load, false); var doc = iWin.document; doc.title = doc.title + " - window: " + nWin.location; }, false); context.stop(); } } |
Infocatcher > 21-10-2013 15:49:02 |
Dumby пишет
Хм, в принципе, можно и добавить. |
Dumby > 21-10-2013 18:11:49 |
Infocatcher О, круто. Большое спасибо ! Кстати, вспомнилось, что в более ранних версиях DOM Inspector'а |
Infocatcher > 21-10-2013 20:01:47 |
Dumby пишет
С этим, вроде, просто: |
MySh > 27-11-2013 20:33:12 |
voqabuhe
Та же проблема в Seamonkey 2.22.1. |
Infocatcher > 11-12-2013 00:26:37 |
MySh пишет
Ой, пока был в отъезде, накопилось порядочно всяких уведомлений на почте... видимо, пропустил. |
MySh > 11-12-2013 01:28:01 |
Infocatcher |
Dumby > 15-06-2014 10:47:15 |
Infocatcher |
Infocatcher > 15-06-2014 18:43:51 |
Dumby пишет
Какие молодцы, заодно легко можно пересчитать адекватных разработчиков. Подправил: https://github.com/Infocatcher/Custom_B … 58a4d952e9 (но принудительная перерисовка как была корявой, так и осталась). |
Infocatcher > 19-06-2014 13:32:42 |
Attributes Inspector 0.6.3 (2014-06-19) |
Dumby > 12-11-2014 13:53:23 |
Infocatcher Оказалось, что вместо removeEventListener там теперь ... какая-то. скрытый текст Выделить код Код:function rel(type, func, useCapture, target) { //return (target || window).removeEventListener(type, func, useCapture); return EventTarget.prototype.removeEventListener.call((target || window), type, func, useCapture); } |
Infocatcher > 12-11-2014 17:36:26 |
Dumby пишет
Угу, я уже видел, видимо, объe10s'или что-нибудь. Dumby пишет
О, спасибо! |
turbot > 25-05-2015 17:52:05 |
Infocatcher |
Infocatcher > 26-05-2015 20:16:38 |
turbot |
turbot > 26-05-2015 21:06:19 |
Infocatcher пишет
Обнаружил просто после обновления ночнушки, и сначала грешил на нее. Надо было переписать пост, но поленился. Виноват. |
villa7 > 01-08-2015 18:19:28 |
Infocatcher |
Infocatcher > 01-08-2015 19:35:02 |
Чтобы не потерялось: начало про копирование. villa7 пишет
ПКМ занимать нельзя, будет неудобно исследовать контекстные меню. |
z_mashine > 11-10-2015 15:42:09 |
а нет ли возможности сменить сочетание Ctrl+W на что-то другое? постоянно использовал для закрытия вкладки. а вчера дошли руки обновить кнопку и тут сюрприз. спасибо. |
Infocatcher > 12-10-2015 01:27:13 |
z_mashine пишет
Хм, ну там все равно одно и то же было для Ctrl+W и Ctrl+Shift+W... |
bunda1 > 02-02-2016 19:30:35 |
На FF45 после выключения кнопки в консоли ошибок бесконечно появляется сообщении о ошибке: Выделить код Код:Error: TypeError: tt.showPopup is not a function Source File: chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button4@code line 1 > Function Line: 1088 |
Infocatcher > 02-02-2016 20:08:44 |
bunda1 |
bunda1 > 02-02-2016 20:15:56 |
Спасибо, теперь вроде всё нормально. |
Infocatcher > 23-02-2016 21:58:32 |
Attributes Inspector 0.6.4 (2016-02-23) |
turbot > 11-05-2016 19:10:54 |
Infocatcher При уводе курсора с попапа, с активным Attributes Inspector, браузер падает. |
Infocatcher > 11-05-2016 22:34:56 |
turbot |
turbot > 11-05-2016 22:43:46 |
Infocatcher |
turbot > 12-05-2016 04:03:33 |
Не успел. Похоже, исправили в последней ночнушке. |
rgdru > 28-07-2017 12:19:18 |
А поправить кнопку для работы в Pale Moon 26.5.0,27.4.0 не работает Escape,Ctrl+Shift+C,Ctrl+Shift+W...? |
Infocatcher > 28-07-2017 13:11:10 |
rgdru пишет
Автор Pale Moon упоролся. |
rgdru > 28-07-2017 13:46:52 |
Спасибо! Сейчас нормально работает и в 26.5.0 тоже. |
Vitaliy V. > 28-07-2017 19:19:06 |
Infocatcher пишет
Может на 38, ну а то что возвращает "3.2.2" так это скорее всего Goanna 3.2.2 |
Infocatcher > 28-07-2017 20:03:08 |
Vitaliy V. пишет
Я поискал официальные упоминания, но каких-то особых привязок к версиям Firefox/Gecko не нашел, тут же функциональность важна, а не портированные исправления безопасности. Хорошо еще, что такая (не особо правильная) проверка только одна делается. |
69from > 24-11-2017 13:32:31 |
ДОбрый день! Как это сейчас установить? |
Infocatcher > 24-11-2017 17:21:13 |
69from пишет
С помощью распорок: https://forum.mozilla-russia.org/viewto … 48#p745048 Или можно запускать из встроенного редактора кода. |
69from > 28-11-2017 12:45:52 |
Infocatcher пишет
А можно как-то проще? Чтобы не копать что такое распорки, переходя из одной ветки в другую? Custom Buttons не нашел версию, которая может установиться... |
bunda1 > 28-11-2017 22:03:14 |
69from |
69from > 28-11-2017 22:58:59 |
bunda1 пишет
дык у меня мак |
Dumby > 13-01-2018 02:29:59 |
Infocatcher скрытый текст Выделить код Код:get dwu() { delete this.dwu; /* return this.dwu = Components.classes["@mozilla.org/inspector/dom-utils;1"] .getService(Components.interfaces.inIDOMUtils); */ return this.dwu = "inIDOMUtils" in Components.interfaces ? Components.classes["@mozilla.org/inspector/dom-utils;1"] .getService(Components.interfaces.inIDOMUtils) : InspectorUtils; }, |
Infocatcher > 13-01-2018 17:15:00 |
Dumby пишет О! Спасибо, обновил: https://github.com/Infocatcher/Custom_B … fa3c18c6a6 И бедный DOM Inspector ломается все больше. |
Ultima2m > 13-01-2018 18:34:12 |
Привет, Infocatcher |
Infocatcher > 13-01-2018 20:43:45 |
Ultima2m пишет
Так ведь должна по-прежнему работать предыдущая замена, код в этой части не менялся. |
Ultima2m > 14-01-2018 05:46:20 |
Infocatcher пишет
Да я сдуру весь код заменил, а про старые исправления и забыл совсем - думал кнопку с исправлениями целиком ставил. Склероз. |
Ultima2m > 24-01-2018 07:57:31 |
Привет, Infocatcher. |
Dumby > 26-07-2018 23:22:20 |
Infocatcher скрытый текст Выделить код Код:getScreenRect: function(node) { var win = node.ownerDocument.defaultView; var scale = 1; try { //var utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor) // .getInterface(Components.interfaces.nsIDOMWindowUtils); var utils = "windowUtils" in win && win.windowUtils instanceof Components.interfaces.nsIDOMWindowUtils ? win.windowUtils : win.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindowUtils); scale = utils.screenPixelsPerCSSPixel || 1; } |
Infocatcher > 27-07-2018 21:08:30 |
Dumby |
Andrey_Krropotkin > 11-12-2018 17:16:19 |
Скажите пожалуйста, а на 61и выше DOM Inspector работает? Я обновился с 59 на 61 и уменя стояла последняя версия Dom с сайта. В расширения он присутствует, а ваша кнопка (то же последняя версия с вашей странички) пишет, что он не найден. При попытке переустановить Dom пишем что в архиве ошибка, хотя это не так. Такая же ситуация и с консоль2 (с поддержкой до 63). Скачал на вашей страничке. В 59 все устанавливается и кнопка появляется, а на 61стала не активна и кнопка пропала. При переустановке пишет что тоже архив повреждён. Что можете подсказать. Custom Buttons работает без проблем. Паратры для установки старых приложений включены. |
Infocatcher > 11-12-2018 20:26:03 |
И DOM Inspector, и Console² точно ломались где-то в процессе обновления Nightly, но точных дат и версий я не помню. |
Karn > 12-12-2018 19:35:57 |
Infocatcher |
Infocatcher > 13-12-2018 19:31:55 |
Karn пишет
Есть встроенный Browser Toolbox, но он работает через удаленную отладку и, похоже, не позволяет задать узел для исследования внешним вызовом. |
Karn > 14-12-2018 02:52:28 |
Infocatcher |
Dumby > 28-01-2019 18:47:15 |
Infocatcher скрытый текст Выделить код Код:if(_nodePosition >= 0) { /* var tbo = viewer.mDOMTree.treeBoxObject; var cur = tbo.view.selection.currentIndex; var first = tbo.getFirstVisibleRow(); var visibleRows = tbo.height/tbo.rowHeight; */ if("nsITreeBoxObject" in Components.interfaces) { var tbo = viewer.mDOMTree.treeBoxObject; var visibleRows = tbo.height/tbo.rowHeight; } else { var tbo = viewer.mDOMTree; var visibleRows = tbo.getPageLength(); } var cur = tbo.view.selection.currentIndex; var first = tbo.getFirstVisibleRow(); ... _log('inspectWindow(): scroll to "defaultView" entry'); //var tbo = tree.treeBoxObject; var tbo = "nsITreeBoxObject" in Components.interfaces ? tree.treeBoxObject : tree; На всякий случай, чтоб проверить, мои останки DOMi dom_inspector-7.0.1-fx-paxmod.xpi dom_inspector-7.0.1-fx-bootstrap.xpi |
Infocatcher > 28-01-2019 19:52:05 |
Dumby |
Andrey_Krropotkin > 19-04-2019 23:19:48 |
Infocatcher пишу Вам здесь, так не нашел отдельной темы. Кнопка - New Button at Right from current работает и на 66.03, но в связи с их политикой, не запоминает настройки. Т.е. после перезагрузки или при новом включении постоянно приходится вручную нажимать на кнопку. Можно ли как нибудь это обойти, чтобы запоминались настройки? |
Dumby > 27-07-2019 16:50:35 |
Infocatcher Ссылки для .docShell и .domWindow, оба Firefox 63+ скрытый текст Выделить код Код:setClipboardData: function(dataObj, sourceWindow, clipId) { var ta = Components.classes["@mozilla.org/widget/transferable;1"] .createInstance(Components.interfaces.nsITransferable); if(sourceWindow && "init" in ta) { // The clipboard will be cleared when private browsing mode ends /* var privacyContext = sourceWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsILoadContext); */ var privacyContext = this.fxVersion >= 70 ? sourceWindow.docShell.QueryInterface(Ci.nsILoadContext) : sourceWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsILoadContext); Выделить код Код:getParentNode: function(node) { try { var pn = this.domUtils.getParentForNode(node, true); } catch(e) { if(("" + e).indexOf("NS_ERROR_XPC_CANT_PASS_CPOW_TO_NATIVE") == -1) Components.utils.reportError(e); pn = node.parentNode; } if(!pn && node.nodeType == Node.DOCUMENT_NODE) { // Firefox 1.5? /* pn = node.defaultView.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShell) .chromeEventHandler; */ pn = (this.fxVersion >= 70 ? node.ownerGlobal.docShell : node.defaultView.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShell) ) .chromeEventHandler; Выделить код Код:getTopWindow: function(node) { var win = node.ownerDocument && node.ownerDocument.defaultView || node.defaultView || node; //for(;;) { // var browser = this.domUtils.getParentForNode(win.document, true); // if(!browser) // break; // win = browser.ownerDocument.defaultView.top; //} try { /* return win.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShellTreeItem) .rootTreeItem .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindow); */ return this.fxVersion >= 70 ? window.docShell.rootTreeItem.domWindow : win.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShellTreeItem) .rootTreeItem .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindow); |
Infocatcher > 29-07-2019 20:32:53 |
Dumby Я правильно понимаю, что есть/будет DOM Inspector посвежее? Заодно стал проверять насчет nsITransferable.init()... похоже, фишку благополучно утопили:
Судя по https://bug1166840.bmoattachments.org/a … id=8609184, достаточно nsITransferable.init(null): скрытый текст Выделить код Код:// create a transferable for putting data on the clipboard nsCOMPtr<nsITransferable> trans(do_CreateInstance("@mozilla.org/widget/transferable;1", &rv)); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(trans, NS_ERROR_FAILURE); - nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument); - nsILoadContext* loadContext = doc ? doc->GetLoadContext() : nullptr; - trans->Init(loadContext); + trans->Init(nullptr); Хвост у .getParentNode() и правда наследный... можно не трогать. А вот window.docShell.rootTreeItem.domWindow вернет не то окно, если инспектор запустить из браузера, а кликнуть по какому-нибудь другому окну. Вроде как, вполне себе помогает window -> win Пока вот так: |
Dumby > 29-07-2019 23:23:08 |
Infocatcher ViewerRegistry.jsm — там rdf'ку читает fetch и отдаёт DOMParser'у, но грянул dom_inspector-7.0.4a1-fx-paxmod.xpi |
Infocatcher > 30-07-2019 19:28:25 |
Спасибо, DOM Inspector ожил.
Ну пожалуйста, работай!.. |
questman > 04-08-2019 20:07:10 |
Приветствую всех. |
questman > 05-08-2019 23:13:26 |
questman пишет
Скорее всего у вас стоит Attributes Inspector версии 0.6.4.1 05-08-2019 23:15:33 questman пишет
Спасибо, всё заработало! |
Andrey_Krropotkin > 21-08-2019 21:47:05 |
Infocatcher опять пишу здесь по поводуCustom Buttons: Source Editor, т.к. здесь до Вас легче достучаться. скрытый текст Выделить код Код:<menuitem id="menu_undo" label="&undoCmd.label;" accesskey="&undoCmd.accesskey;" oncommand="goDoCommand(\'cmd_undo\')" />\ <menuitem id="menu_redo" label="&redoCmd.label;" accesskey="&redoCmd.accesskey;" oncommand="goDoCommand(\'cmd_redo\')" />\ <menuseparator/>\ <menuitem id="menu_cut" label="&cutCmd.label;" accesskey="&cutCmd.accesskey;" oncommand="goDoCommand(\'cmd_cut\')" />\ <menuitem id="menu_copy" label="©Cmd.label;" accesskey="©Cmd.accesskey;" oncommand="goDoCommand(\'cmd_copy\')" />\ <menuitem id="menu_paste" label="&pasteCmd.label;" accesskey="&pasteCmd.accesskey;" oncommand="goDoCommand(\'cmd_paste\')" />\ <menuitem id="menu_delete" label="&deleteCmd.label;" accesskey="&deleteCmd.accesskey;" oncommand="goDoCommand(\'cmd_delete\')" />\ <menuseparator/>\ <menuitem id="menu_selectAll" label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;" oncommand="goDoCommand(\'cmd_selectAll\')" /> Не знаю правильно это или нет, но вроде работает. Не решенным осталось еще, что не работает кнопка "Внешний редактор", вообще не как не реагирует. Может Вы все таки посмотрите, ну просто без кнопки, такое чувство, что что-то не хватает. |
Infocatcher > 26-08-2019 20:23:23 |
Andrey_Krropotkin Andrey_Krropotkin пишет
На удивление не все еще отломали. У меня было опасение, что дублирование command/oncommand (от загружаемого оверлея в старых версиях и дописанное вручную) может привести к дублирующейся отработке команд, но, вроде (как минимум, в Firefox 52 и 56), работает нормально. Заодно оживил в новых версиях: https://github.com/Infocatcher/Custom_B … fd057a0614 Andrey_Krropotkin пишет
Я не пользуюсь... В самых новых – и вовсе редактирование поломало, я открытием во вкладке спасаюсь. Dumby, насколько я помню, тоже говорил, что не пользуется... |
Dumby > 26-08-2019 21:44:51 |
Да-да, не пользуюсь, и Source Editor'ом тоже. Открытие внешнего редактора показалось мне скрытый текст Выделить код Код:window.edit_button = function edit_button() { var panel = document.getElementById( "custombuttons-editbutton-tabbox" ).tabpanels.selectedPanel; if (/sourceEditor-(.+)/.test(panel.id)) panel = document.getElementById(RegExp.$1); if (panel.localName == "cbeditor") window.edittarget(panel); } И, ещё «See also» нарисовался: Bug 1566457 - Loaders summer cleanup То есть, предположительно, так скрытый текст Выделить код Код://var require = Components.utils.import(loader, {}).devtools.require; var g = Components.utils.import(loader, {}); var require = (g.devtools || g).require; |
Andrey_Krropotkin > 26-08-2019 22:00:21 |
Infocatcher и Dumby спасибо и вот еще по этому коду вопрос (может только у меня - не знаю): неправильно работает выделение в URL кнопки, Имя, Изображение. Текст мышкой не выделяется (или как у меня двойной дубль-клик), но если нажать в контекстном меню после этого копировать или выделить все и копировать, то текст нормально копируется (т.е. не видно полосы выделения текста). |
Dumby > 27-08-2019 18:44:46 |
Andrey_Krropotkin пишет
Подтвержаю, у меня на Win7 выделенное там тоже не подсвечивается фоном. Выделение можно стилем задать, а кодом — ничего лучше не придумал, скрытый текст Выделить код Код:if(this.platformVersion >= 68) (function(events, win) { var listener = function(e) { if(e.type == "unload") return destroy(); var sheets = win.document.styleSheets; for(var ind = sheets.length - 1; ind; ind--) { var sheet = sheets.item(ind); if(sheet.href != "resource://devtools/client/themes/common.css") continue; destroy(); for(let ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); if(rule.selectorText && rule.selectorText == "::selection") return sheet.deleteRule(ind); } } } var destroy = function() { events.forEach(function(type) { win.removeEventListener(type, listener, false); }); } events.forEach(function(type) { win.addEventListener(type, listener, false); }); })(["mousedown", "keydown", "unload"], window); |
Andrey_Krropotkin > 27-08-2019 20:44:40 |
Dumby спасибо, теперь вообще комфортнее стало. |
Andrey_Krropotkin > 13-09-2019 20:21:55 |
Dumby есть ещё маленький такой момент, у Infocatcher есть ещё кнопка редактировать во вкладке, при совместной работе с Source Editor-ом на 68 проблем не было, и в редакторе и во вкладке все было одинаково, на 69, Source Editor работает только в редакторе, а во вкладке как обычно, т. е. Source Editor не применяется, посмотри пожалуйста. В какой из этих двух кнопках где-то неисправность не знаю. |
Dumby > 14-09-2019 12:42:52 |
Andrey_Krropotkin пишет
В коде Source Editor'а поиск: Как только увидишь — всё сразу станет ясно. |
Andrey_Krropotkin > 14-09-2019 13:27:08 |
Dumby спасибо, слона и не заметил, заменил, все работает. |
Garalf > 30-11-2019 15:35:28 |
В 71 перестал работать, также как и dom inspector |
Infocatcher > 06-12-2019 20:37:57 |
Garalf пишет
DOM Inspector и правда снова отвалился... Что конкретно не работает и что пишет в консоль (Ctrl+Shift+J)? |
kokoss > 06-12-2019 21:08:09 |
Garalf пишет
В 71 работает! |
Dumby > 06-12-2019 22:24:58 |
Да и в 73, на данный момент, работает. А DOMi, ну давайте попробую скинуть. DOMi-7.0.{4a1-5}-fx.js Выделить код Код:// DOMi-7.0.{4a1-5}-fx.js (async re => { var gzip = "H4sIAAAAAAAACr19/XbbRpLv39I5eQcM955dKqEo4huQLXsS29nxrmPnxsns7PHxnYFISGJCEbwEZdnj0dPM2X0QP9ntql/1Bz5I0Zns9ZEJoNFdXd1dXV1dXVWYXq2r6/JkvqxX5XRTrU+m1XJTLjdOirl79a5cL4oP4/c3i0//9em/D83fIf/IvU71/d/2aiE3H5w7T/17WK8W882mXHvz2dlAPXyzrm7rcj3wpouirs8Gm/lmUc6OdbaBN+9J7KtSnvn279PP6LfxtK6dDjv8/fx6Va033s16MRwA0OmJU7D+Zb48AUavBSECMTh6cG/RDhbH5/PlbL68rDUEwj+hn0z9zw/v6DYI6CeUh4R+UjyEE/qhEQhD+onoJ6afRDLk6ieaqIdPfz+vqk29WRer8c9ue784fFesvT89e/nq6asnrx98oRJUEfU/ZlS+ODw4ODnxvrm59PwoSfN04h17Py3rmxW3dLqu6tqbVdN/XVc3K6+YVavNvFp6w2/n6/Kieu+l/ldHAuNqs1nVqj+uLsfX1V/ni0UxrtaXJ3J/PFU9sy4WJ+vy3ck0K4JpkBa+H2TTKJtMpv5FeTHNL4qL2SQJJlEZZeU0KAjy/MIbDjX+3pk3WBXruvxWdf7r4qJ8vVmr/lVktPSevvrue3q1Hq/W1abafFiVR4zbweZqXtO8MTkUmItiUZcP6HWpbjjbsC/fsry1kIdHR+OLaj0tny2L80X5p59e/OmbF8OjB1/waNKvP8Gk4XsaNJ/62qfO9mlo/ZR+aPR9GrtgcnhwpypX3fe0PFbA1D01uFit/liua+rqR6qPvb/9zRsyjs6LszN688//7A2W9fPXV8W6/H4+/YXn1NJ7MvecITm/uVSDMF4UJ37oB1EQKFjoG27yrFQ1/6FcrLjFT6ZvBr93R7CYzapljcvxdbEsLsv1cb0p1pub1QN/8HZ8WW5el+t382k5fDIfF9fPv6as3yHna2TESIzX5eW8VlPqCc+eoRSrx/NqrHr62/mi/OmH5zZ5Nl/X76ZUwXDw/bq6eDoYqaaNVYMp69HRyHvzhgEfDCrFH9fzWaly/Iq5qQrNik1xuinfb05UwmjAYN++pcG9w6wJaCiD2Jml6oeGMsgxWQ9oLNVdgEGlgfydptwjb1nNSiIodRlPF9WyfKnuhpv1TQkC0jNb/RDkMHMmOEMG9CjU+ESUN6K8EeWNcpWNJruarqoe1WdPq+nNtWr0UDGsESXz0xFTvSLjIWVmrKoL7814PFY5xtOr+WJGmNVvMWSML/28LK5LIrrB++uFGv4Pi7K+KsvNgEhQwx6r7i3Xm28Ub1iXoNgDM3cfo7LTdhfwVDyyCI4v1KhvnhAimFLUuph6J6YWx9TimNOodxKacQkxyYQYaUKTLqGRSpjDJXpUEiqRUImUSqRUIqUSKZVIqURKJVKqI6U60kyDyszYZoHu/YwyZ5Q5o8xZxqk5wc59nT0n2DmByCl7Ttlzyp5najhHaB6zjIlvE5hvTJhxTJhzTJh1TFLTG/4kZz4DbuPzb9BA1AfPAdNRXEcoaATk/YDL8NLjB1wfU7fP5O0zfftM4D5TuM8k7jONE13QfWAQDiMHWGrBKBLuyx4FNnvERaO4lVHNOVmq/JgxjTl3zJjGkbxhLBU5SIuZHHymB58Jwk/MaPkJWDAXSRhHJgifKcJnkvCZJnwmCp+pwmey8Jku/BT8m8syafgpl824bMZlMy6bhc5QHNzx7PYzcH7VJQ5L8XMuoMiEZ+66vFZs7OubTTWtrleLckMMw10LzrwkV/ONJpaT/NBLA5qFvxv2LwVH3Jfg9Q5boFXwZjmlBb3FIbyPeuU1/Ivgq0wEsIIkqsHU4BPrcnOz7r58owq91WPJpO/nzDOJJLkKyyE/gmFQT6hVWKHXC8wuhupff44z72W5+WkzX+hstPAUs+fL1c1GSQxlcf1jBclhWPPjyMN1XLwr5gta24ciOxyAXQKrlSsVGHZV3S7L9b8uqvNiMXZEBSmHMlvEBg0YLFuy9gg4Q9UfaolSY76YTwsasRPFhQdYOJjSWIzxLKxtHeOKN05N3Pohr3IT37CZgFlRwKwoYFYUMCsKmBUFkocFGWZFAbOiQLMiuuWizIsC5kUBS0ABi0ABZKDAWd/0UotlFussFlqstMyHAhaMA5aMgxDiMyOqGNEBkxHdc1leSgNeSwNeTIOIy0ZcljlREHFZ5kRBxPVGZtUIokzjRWu/j1VddVYNCezrp09fvfzz0+evv/7mxTOhYBqECyWeqN4mmYLWxE2xWHxfbK4emHlFGTTFU4Gb9VznX5d1daOoRUlCIBEqQO8Z0HJaquUaQtC/ff2DynQkhdXvWKWQZHRPOchZL440mlTyQhejkTh4oqbCbPaN3lOsypkS5+YXZb15UYEAh9yCB1osCWJIR7EZQl6iA2LK++zX3s3LW8XOTmbVNf1vbmIOWzvBbX+HjY0i09jOssjklPoo93eNJ51gAX50qumrpHnXgXYf8vu21fO2A6Xt+J36vRu1ugUvbfLn3js1SOKhiDdU55e2+i9PHBx7kcTqa+9tuwSybWBP0p5/6IjdKTv/wKwONb/6FX/BJGg8MsfZC+fejm/m/Nhf0iWUQMku+77oTQ3SfD+Y7kgHvDcR9qpWEp3bD5Otw4kVx953OgJy4x6UYOvtG4++1HatLRxDXjPCKNhabDcN6EHvb6I7mXZVGGowYZpvaclWtBoksqt1n51jy//uYLXHfY9h1VksizlpZutmsA1t5+1B4R+sKOJN3Za63A7v6/zfqipA3bcpv3HtcRL39GuUZls6vKdvtpFFszd1fs8jyYa3M9evy0XJWxjaoLSTlIA2vVmvlaRBioYjM2sSJUzqQUlYmExYmExCqBBYh8C72oS1MgkLkwkLkwkLk4kSJk2nJ2pONLosYdVMwvwviaBG4HpjrkuJkboXkziUNias4Uhiy1Vj1ActB9Qc0HOwoqPLOhK1rxVYWEsT3tAmadAGqTa0FnmoOdK8DS0zmLGqI2FdR8Lb2CRz+i+ftBrP+o5E7rkQ7/uSHBoYqGBYB8NbjXQSmO5IeauR8lYj5a1GyluNlLcaKW81Uh/6Gy7r666gey7Le42U9xop7zVSXr5TXrvTgMsGUP440j8g8K4j5V1HyruOlHcdKe86UiaUNLQ7hxS7DhcCE0rKvZwyoaS860h515Fi1wGWnfKGI+UNRxolBkSYQx/lcPeUtR9p3FxIOSk1fZ8mEz1e6DLWhKWsv0oTaLYYuQRvs9Z4gwOnKWpkCrHAEvR8ymSVsq4jZV1HmrWpMM00FaZZ3oaeA3quoadMGSlTRprnLTrNJthIQp0StSrKJplAyZgiMkURfOHsTAwZE0PGxJAxMWRMDBkTQ8bEkAW+qTZjVVgWRLaSQLcmYyLIwont/ozHPwud7KHJHuaHFqLDILJINz6LmnOpjTyPdxbjnhtimEOzW7MELU/0jM0SKCe53TzeGWu7Mpa3s9RtAyu6MlZ0ZazoylIoNbkYM4cszW0KD37Gg69TIgYEXagoQzPb3tzXWDFlZ8weMrAHh49kTAQZs4ec2UPO7CFnIshBBGlq5kk+SWwrcqbP3If2lYv5ba6XMzHkTAy5Iga+cDGmg9zQgeFmgR6pPEB2JoGc+UDOfCDnBSNnOsh5wch5wciZD+ShnZ55NGkBc7NHiZMx1xljv5Mxxq+THXplRolXh5xXh5xnf86zP09ivYZjGcqZGHImhpxVnzmvFDmrPnOmiJwpImeKyFPorbkXmSJypog8mxjOnTNF5Kz6zLNINyHj084840IZF2IVuYxhHjhjiKZARw4lOZNEziThT0RPLuoppgp1ga5clOWiLRd1+cQSC5iqPwGjMFRk6lZvUBT68gmO6SY4qJv4QCAAAlCdT6C/ngSW+asHAAkSNy1zqwlROETh0C0conCYdJGLWkusSkGDI3kC1hGwjoA10xEGx5/EehKq2xBAY5SFFn0So2yMslClT6BLn0CZPkma66WDHxTqE2jUJ1CpT6BTn0CpPoFWfQK1+gR69QkU65NUjjcAJbWaRz1smagkg27VGcpmcjYCDDJgkAODHKWhap8IyBwY5LHhEuoBQHI5YZEjFpyxgOx8kJ0/cQcOoHyXH/k4oElAEPqExg/cHHJA4yfymOGCWkFrckwjZyVyUCMnNXLGImc1cu4ipzVyXOOHgAKi80F0ftgdQD9E6RClQ5SOUDpqlI6AA7SlTSCgOz9C6RilcXwj5zdygOPHaAEoUM5xfFCgDwqUwxw5zcFxTqu6RA64UBokKIc6pEsywyrHOnKuIwc7crKDo50GscnZTm8LM+TIUDYDAqBAn8UeXSUI0M8nbmmBn0etyYwDEXVhkkH3iRYeiiNf0MBcJkW8zGXo4f1g4vIYKOF9aOHVBad7sEMQTXzc5TEBKC7QB4NBD2A5FpQjPijkHVCcGsqRImqVk0GwNqjkfejkfVHKR3L4iNpFLW9FbB96eVfq9qFX8oPIAmi0JUja7DKI5VQSZ5mgrQC0FWBPJd2eyNkr8idyGgq8E0kEEHC5AFwuAI0FqZyBolGgsQBcLkjlUDV1hhIniEFmZAMwsCBrDE0GzoIh5xwZSDAAhwty38kAKQtCmXpCWXmQU9wJLj4uAS4hLhEuOMDFShqCzEIcPYc4ew5bayknuUo+8LcQK2qIFTUElwvB5ULQXAiaC0FzIbhcCC4XBvFhd8XmFwABFheCxYWhy2FDRXa4om5wtxDcLQTFQanlQ6vlQ7mmLqgbq2uI1TUETYTgciHoJQSXC8HlQnC5EFwujDEEIfhbCBoMQYMhaDAEDYZYYcME5UGEYQIsQIRh0p2zIYgvTH23WCoXzb/4IZECqBxkF2aT3gJOBeBtIVbXEMQZgrmFoL0w990CHeYWgrmFIL0IpBeB9CKQXgQkI5BeBNKLQHrRxJkuESgv8vV0UbeAIKZWYHIRKC8C5UWgvAiUF/ntPakfBRCIoiCWa2rAg8giEFkEIotCu5lTD4YZRyCzKMw6NSjqwjUymUFUEYgqAlFFUY58IKcI5BTFVtiQNSpqMfB2fUlgByCy0j9Z+OGSOZ2a2t4E+4pS6RAwrgiMK4J4FsmOMEUWSGaR2Q7iCeWypJGIrswnbiI3J0wdXZpKS9vtiSe8EVJXvcFVtzEusAEBg4onTtfHvhF5Y5BHLLZ4II8Y5BGDPMxTrp8soMDWytwoxDoYYx2MIXLFIJUYpBLLeuWMnH6vBY7WXhM4gRvF4EZxJOYuQDuK7aDFkaHRGJwojtuLXgwpK47lKXGKx5kpDg4UgwPF4EBxYjltGIZtwFj64nTiQGQlIyBi2YtBPXEqVjqOeBSneRskJKuYN44aJC97AClyvdj/gPPEkOtjyPVxLu9Qed7sZk5yiCOZGOJIwH0So1/iB6zVHeWWEkQ7Bf1OQbutpf93D7gkrI2I15x8+SXuVfvQVNJHAybIB9poH+poH/poHwppHxppHyppP2EVwwmgYGVLsLIlESZNAipKQEVJFEsqbKDAeBJhPAkYTwLGk6C7E9AR9NO+VlAvyo0nFpTfF2tYE5HJbXUB8z42itHWJ2R19E0z85k30MZHAwbokQJ/j6JDynP0ALgAezH8EssvMf0CJSdYFBOspUkirRcLMDEBS6T1WEeTVO9z8dSmJGiT/ASLaIJFNMkc7REKKi6o7/TognATEG4Cwk1AuNCa+4khXH6ADq4j/KRMvoAOlbkPnbkPpbkPrblPanO++mLfBgM3LJopuCLU5j705n4KzofbzK2LbpWgRtQsBAx1uQ99uQ+FuQ+NuQ+VuQ+duQ/xXV0CTfGpIuaPuEFpdCp05iLAcwI4YgqOmIKhuq9RGifNTrrihjLvoDZXFzHliyUV9cXSQaooroGgBYKB4tyH5tyH6txPQTapmA6yECZrQirGg2mH8adpc8k2dJSCgKBU96FV91PwwxRifooFNYU0hkQhEejYW6wmzXXn5igBxQbU7H5Xz+5nE5dhcQImOyrJJpIr67DIDCSVOdpWP2OOaBmfL+QPfbufBWIqCVtJiPsZxP0saNQbpN0KQVEZKCoL+zhtmMoV8zoDDWUihWWR9E4G4oEaXl0y03pI9VnsG5CxLqPYn0mD+Wcy0dZBSSjXWK6pFAKlZBDXs9Q32MpMIpW7TAzSuPM1m8gV3ZQJbEUKgKntSTNcUAMYTAYGkzGD6Z8VpG1nOFC1+/mkg1SODs9JAgdupGXnK05a1DXEJZJHFPDTvVHMYVPfiyL07D4p2u/DFAsfq9gFUxnrPBLUMNR5lMojCqjKXExzsIocrEIwzbF9y+PtLAbKdp+07Q1MwS7yJOsgrPiDxjQFseQiEkOz7ucy/FCr+6RXb2CaJT2YoodFwd6PKRgCqdd392lAunSgGJAiHdccV1h5TvxAHsGP/AZlBqI8b6AYQHkeQHnei2IwgV5potjmR74JRfcXdFAMZWHMDKbRBDAiQU2UeLDqJDU5rqghyntGP5hsJ4IAWvIAWvIAWvItrUjEWjZxOzqAbjyYpJNOY1Lb36n0dyr9naEHRP0NTqCu1N+6ukz3Vo68mPpQdgfQUAcTkS1y6YZczHfFfhf2ulayCOCCEMAHIYATQgAvhEDsg6Hmln2OL9a/vj0nENnFFwNgX+8IrRpHixuBH2huG5CG+yNuUCcsgKHctnZn3V73w1gKgjT8sD31AlJgSz+T2wFyR+JwF5DWGtdAXsViwBw3gKiR10ASvwMkSeSaNYGkfgOIHXHyKkDOVDsFkisBriibaVwzsZ/OGrDywMDKow6sHIQEpXJASuWPuIl0z5EmWdKMW6IfmI1LQIpjXGGM7esNZADFcUCKYx4XMmbeFGsltqsdAax6x9dPX333R3U7rq+q26+X1fLDdXVTP4ERsEj/j73i2Ts2p1/PL+fLYvEjgPztb/qFQD1tPgv+QeKIAIFYiJOJeBfNRj60LsxNPiifxTRcKDuIrMgVBFHSkTmCIEaxODCA4qiZQYgh0PJCQMpmSYpNks6Vmlwp5brbz4r6dbm4gCMfGVHPV8WyXNTObdOsGn9fHLYSdibrN9pzYbO+VONcbhm50h0ouDuw9fuQijlm6c8WJTueaON9cbIzlTCAp+zYoEo2d4jsAyGHESjGTrPsUscCuOs22+dcp358XZDHW422mP/3udjxCx5u3ibzchFLCX4l/mna70z80/Qj25aZCnhjkaTmUfzT5LHhn8YJCS6wl4EfGttjsP4NpiaHfb5pZFlx+HnuaeJVZdzT6FeOrfnX+qflTfc0uJ9p1zTjjyYHhzZBu6bRr5yA0a8cRGkHNdOv1jdNQzCuaTpBTgHcQqFoz/lX1NgGZWhKsD2IYDZhYEWiPeVfqD6hpM1NcVHTQv8X2mTRkvFvqikL7xLroCcKCtHO2GTXRU3UAPTruKjJXhMbwMipgAGkWXvAOr5pcoLJZCKbI+2d5k4GpzegpICOAiq7PHE7E55DkHFExJO0ju8QJCntOsSZHLchWfGdUk1MYIOPEcFhpTMWQRA1R6HhOwSHoI7rkHXohW4WBhhOqhlwezBpvIO005BJgMl7ZilQVobYFjKeMp/08SmoJDaEGVgyCWB1kUDxgcGObb7U5mNJjKkEp5E4jEQ+UAlUWcJDgtTM8QC+Wpmv/bCOxGEvgOIBe3KmLU7kmkSg5yFBZkiZEDKdAYOYmcNHmnUlsOvyG0wWJ444cMR5I44bcdqIw8aQ6SRkOgmZn4RMKDhqxEkjDhpxzohjRpwy4pARZ4w4YqQTRpebh0FqRw3ninSsqJ26sZaEkU3g6sLUJnBtkfUDZ5ZCZ4omgfFEe5lSwsgMAo4S6STRJHCNscWSS8S2Qt5/hJZWcH5I54AmAcseV8gsJcct5h0ODsPU5Xxm2QlZdMeJYShrTcicJMwMYYWZ7Y8MCVheuRQTCp0T8nvekuAAK2RSCe2ig9mKs0JOwEEhnRMyhfCSgwPCyC45ABlNbCkfq7nPv/ySyQQHg5LdR05e1H0wPBYEmEyioIf7RcwNIggILpXgYDCyVBIxlUQsckTMTqLQMv8YCYafRMxPIiaTSCQPLsl0giNCnBDigDDitSdiQsEZIY4IcUIYMV+JUAnzlai1+kQsi0SsII+SwCZzQaaVKGmjy3wFyRHTC04JI15+ImYsOChsdxorMqRxTDeRpRuBnZmhjDIIWdzMzPYQb2cjDByTTsSkEzHpRJKHi2ra0ZOFmUzMC2DM5BMz+eDgEOeGdGyIvFRhzMQTM/HEfgtVHBo64JlycFwYM+XEYsVgiDEOILPFAZ5YLOSVCGeFOCq0oxMz7cRMOzgmdKoLMwuDpRYcFaJgBBHUMooIycidNdGS9sSmgTgnjCUZKal9yagy4eCMEEeEKB8z5cD/I06wrsRJu6rIdkkaWmbG71Iki0WReckLUsxUE2eBBPhYTqvr62I5o2Ad7Omx+iO2l9USNy/m9eYJ8gz32ZEcDb6QeqkaxoeZWJylFhNuPy92OHBEQ5gWcdhIZ406N5NibKVnzpYwKSZMitBsJ0yKCZMi9No6hV0kxJjZXY3vjtg5O2mFk0l8u3XwYXFoVoOE20Unjsa7+ujBZ/nizpfP9cb95/q6EVQI17vOJlEY4+HOnWTf1vKzSkkL3VQJLnHP7RedIhx856v/L/8Q54dDLcV5kk0o1NIPHPHBxhLoHJQqWm68NdoTjtFCoYm8r79/Xo+dkEwBh2TqhP9ZFI24TKSK+bN6M55ezh/PZ2eCkypZqCpqPmYdecviunTc2jmyktqEvzr/WZEK4fO9jrX06oI9so6Mi7ucBr/ksDfucS/HLJrXL4vN/F1p2sOxKiizE75J/OM5YTyvG22XUDre2SOcGncA0mxHpBlF4MV8qfr09VUxq25/qCpRRmjA7ZL3gYbKwQ/2Rq6hsPi8g+49EXViZ5yvKJZEH1ouSB2wQ+Wm0CHP9eynsBm1g8xPP7yoh+ero/GiXF5uriSiBhXR8URsr1I+QL8zkQRmJccxAT5MWpxDaufkN0Rlby1yNC8P5rUDl1+hjVJwuIMEx25Za5fgprn0yAg/dl6r8s9FNzUmG4ehfYWgIKdeQWqvR55E51BPRwzzTcVYObDeMvijVuOavea0jsavXuswUbXFWBNztSqXr9ZPFlVdzlrkLD2jimtXyEYf1usj7zG9PfWWN4uF09E9NNLoa4blcoVBq8zAHbYWje4Jr80NLMT/f+yZ9z4SHEp4GHqxp4OOiHRXtfeVGvXCzMcBc4atwaTgRwVntcOtWjsdasqEiNJaO/Id0kLFvlq7TlApk6CVdiZBh5TSCb74C9gEsbg/7OrtjErO1mjCSpkEGFVB1mtGlWLVKlR30NrB9DW2Iaa06g66uabeDmk6khS0djbUldjHwWYMJmPNYFJ9KjtxQ+gNKeVq7T45kaWgvtNRpSwCqWB4bzApztVS1iGNy+DMl2XTg+tqXK+/XRSXNNdv58sxQkfxwQiJwaVaWYYD8I+1mv3FZlNMr0qSnYmm1a+JO8cxqUDuCupVVW9qE4pJR4l7Q8kj73pTvaVgcTafShnP5rVaYpeK75mYRjrDeLooCxsLSdYC/dYsFYSENF/bBchTR+HohJCiYy1nqelTOpowODKR27yJk6l/XmJOO6vofKa4MPVsXW6eKwl5/a5YIL/qy/X8/GZT1lgdeM0ZecFkciSCwcS0S5SaPg5ItwdDctHsOyQzqBFGxWz2+QN90KCaM05vrdXMbq+UxLkAIQ0134ZfffHhvPx6NvvuZsMBgF6d16pTVO2l3k5plq01s/AiCQI5NuPfuFGNhlUPr282CtnrSp8ABdwnVPEb9WpMS/hbysR5nIqg8oeC1waBOpCR6A0CBQSWTVLgcIPUoaYSp+nTzkuzOnVfSQOiWIJGwkslN4dfmvqNGEg/P6r2kQTBCc9ePPvu2csf//zy1dNnZuDvn4sE3BV46yG9sFStxr9/tjrzFTMUBeVgLbJTzTnx40Fpn+t1hQ6VWSGAInRyR4CbAdXEdJRK0r6TtzXjC5pX+pEELX0/Xsp2ggA/aOrXm8r1AzORl7PyfbcKTlYSo07R0LQq/gsLoS4XuvxmXZbfVO9F+HzHZ9o63MQDp8htUSMMRUlsRGUZSyCK58DmDGi5RTjhxwrFPMmgtoi+m+njonxXLu7kaJ3wRmw/06Hr8l2nrW8aoN9qeDRilH/MML3fnXl849ALwsndLg02X1ls+OWyfN8dvTdUxNTC1XA+ond1lerOdHUmRl+7AwiMgcLh7QxiXPmUhGDe6pg2PATMBxYmnTZzRqdZLu09300dyGQnimLAasKXw+PjJraPXHC2Sc602DYa7e7wztdl8YtToW5mq3vO3Bpt9rtG0/tbLvyBIxnuRSkCzSHqIwtETfhXalPSiKnsdL7eJT4xgWW/VYzMlmZpWjaXbse58J84CLcqMe2909wKo+TMP0V3NAExT4eNFpqDrhj87aBnkq+r2yfVzVI1oFheljMAGHnHvohPeX7oWDb0N5e4lW6jrA/OiV5XkNlymGd5nXuaR7/poTOpt0oR/RtDXjNATE0xSLgfBXDef4ZQkXI50wVUV7wo6s3Tsp6q1GK5MUVGgNwsKZNBaFvmhst19Co45yqAG73nhIdnVDXff/XVUYtd2OWkh+jfNlmGM1/0wtOcphKEFf+6uhNocNTI84axsXiJREbsVhpJqQZYZ7J+1PR3J4g7EwzCSbVYFKsasZRbXSpZyvcrJW71Z2AeXy42he4XXZ9aevStkx1ZNR3tnilc1wjQOzg1i86XSryezwole7g5oTDYNdtxkP1JItTZk2z65WnC+2vJyfsocqc9QHEu6B5nw3oSxpNi8tCYmmZTR+6yuG4/ttaK0CYJHXm7pemlkUXo+BpC5u7MVnM0r2Ej1S9WPn315CcjVxo1bTPv73pEUNYPMugjzwyIrlLtR3SFThxcG+dUve8pVZeGo1TSFp43wy5pWIWyoPDRbOp+V+NM53cUvFzdvx3XFFT+uiKJUYm0jBtv4nQwX+zfejqS8oCdpzpWtsPP+3dkDnEatV2PTtTqXIHzuqc/CGXPtIKl375WWCi0z3DqlzSzK9dbDEQqpj3jd8VKZhZLUu5GZHxV1Fqp1cWM9f0GSrvfuL2tvZyzK0aNtO2QYR7W65H3sb45pzE+ZVY48sweSids25vh/Z1A1eirPhM9oqrI2Ru6Jh9QCcCpnHzKTah+nrK8fYSjjjX8oN9AWMBWyw8RMAlBxctliTc7OxtMvyng6PzmcwAmHyY+zBONPUkz9iKc1OGj7lqUdKQIsijRXcEiA1mU4IlLsborFKsSrtEYlNAv13ifRYmGzwIL+aPDrgQGJHDutf2WJiY/zEpg4cI82zUtCbPQxIDf68ASx78/8Lcl1h/MYaVzYrjXkWPrz57WpZMk89V6+GzJYby9r2v6ysEztWS9rDY/1XSy9KHelNffr+fL6XxVLLxqqUZ2efy0PFcAvrlRw1t3Ppry+Sd0jMcXiEFNod6fz0qststyoWO9ex+3fPkjjpMoy9tYfHK/MsOdv8NmVpt2GJtZUb7CagUKj6a1bNdYVpJgMnDIVk368Pyw72sO+jQ7lmxsxvQZH3MwRk2iezffcWDVu37bMJaVs3ttKytZGhp3HRP87xLce7yeXfQGrD44eFhen75DpP5H6Xgyjh+eOClO7q2EiAvrDc0fQhEffvpvcZHvvAuy+9/y39/lUy59Z/y0AvB3X8xHZ7wBt2HwoHWY3plV7euu1P3mY/MvjLYDY+ku7y/ABG3+mFrNe7dAnyXDr/gTTeS2v7yNJZfp2lXch9nd57oH0Iduzqv3+oqvZMkDi1jHihUd39T0qR/eKqu1V72l1ZWux9A407dclqKC4gIUKr5Y08kp8l/My8WMCk1v1nW1tkDOi+kvl2u1W5gdqw0MveHy35r87cQfUVA1XqO8WhSK5X3sq5qwUjIrf66rEBcB0rKvFDErbn3qTVbvm++VjL2+nC/73pxX61m57gPaQeaRN5aE4zl9bIKx216pjGSCPqWedwDQVW0QC+gL2IaKWjHRvOfeIvd+eopNd5lH9JEPfwiNP9s2nzrJ3U+j7Q7Ur8MS5+bO3rj3fYlbHDb4tfbUwIO76NzRZ9b2mQ43vF3f70sD970nrOFjGep89zMHe+FVt/dPrIDpoT/gOd4gPoUGE2qOrz2ylIjP304jNl5vWFbQVkUPdiPJgQ12xd5HNNh0Cw6tIqnmt85F4/mxCbIJHU84du7kM+8bnXHP347w8Wm6/Uk3dltn7WhDt5CT0qqlTUyf2h+Q6PUI4zl7rTYS6+WvmrJ64qX98/LTlvn66d4py/IipqrIiniQKUs2uPvPW/ttx+7HMHF5+2jnTOZF9/j4UYP86N9cVXY2UDtdo9L7TrF1+iBl47tvPGz6q28t4ZnfadEZD9IRh1ZoZvaFfjhscS/uCn0nMvMhC8yHfd8+O3S+e7ZP38FAactXRPt7jv8/VJ2iFnz+rmenf/TXPXnRPp7Ni0V1OdijU7sLEf1G7e7+1PzMXqvDD9tUx53e2KOA7A7havIPCkrvr1XPHe8FRZUolyQ2171TcD8g2hhX1f2dmtgLc7PPwtX+301tfvGmN9F+FcC9iVzWtGuyaUZrCvdwZydbz5vPfWisV+3Fi5/RlNbHBhotctrYyNypZ+vbRtP2+ngNDI1c+Pofm3XSMeVHJ9Hz3p9670feh1Pvw8i7nc82V6e4jLyrcn55pWR2XEeNUvV0XZbLP53qm5Hc/KdO+U8n+x1HWnK/j5c44e9MmPj9v4vn+h5ak6ZP4nzoZ43vECCoaG4CsOWxrcW1BIJi3/gfNoN22YCp9rtl5p2J59Vvo2Pz5c18LdMWk88ED5R8LX9Dk8/EDez/RJnJF3HbtdHr4SfnE2WfHHdDmJgQ35zYFHZGP4RRhFSmI4dLumlU4rvpicmfaDdD+oUXpT6aFOf2z+WntOlbEUPVN30+6d2/fjUC/mS/LInc1eZlpNVGos9eFOdaTf9/b8r1B5wDV+vh4LSeVqtSbadUlhLf1js4oOz6sKsuN19r06/hALlGlJv3X/pYQBQjEgf30NWl+WISJFu4o33Vm3oJ+LnGkYi5Ef+Xz/lWmnM51JqhQ83km/zeXpiIuwz3nm/6bHtuwej9sljrqy/dDB2QneQ9me5OoDpOid3cTGxdOxvbyWigba1QPowauRFYo2QLcpznf1JBrSv4NSpqLrtdSV1dr6olfZRyPCfDyotiWtafp7emrvlHvtCK/Jlo/PzMCfeZaZ5oTVEPu5aoh64Rql56JBrORIeptyk2ynz705mtpcrXSx0tQTY1a5BI4HyyJAhseE4EQUH8EMQ14drNEsQXbSNpAPyKD2Ua+gwiu+8PYh1IVgxUYgez2GCGiHsIvo3Y29tc3GXxkSgAzuJjurMx2QJE0kKAba6qZRJgWsxhPU24ONgEAKscAcFcCwBya+cLI5MjNFMu2iwKns0X5vENWwCkMFjyXv/I16bnugRYlbBp8GS3Ifas3/qBiSoZmgC0JiF34gBZJ3X65azmrHL3sSKCB4UcGk9Ne0AzLuqexGS1PurySTjjom6QNoeKNoWDvT7ANk2Hx0Fw665/esjjbI8TP4mTOqhAjhRd6Cl2ftpX3aS3DhUNBpkbyMl6qNMv5zWBlKyPOuPL0maIGLK8WWCnTkSwbrunmyyZ0Jj1SLewIt9mVKOOmwDBpCKWKyPeCbedz+mXVQU8uaNQRx+jsNRSm0TBQkDqiEcdXucRdsWIDLu/xzlo03qcN3kZeZy7AbkizPCus3nEM7zrbY6o1FFi+3annzniUUfQ+ZGXuR3PiHcYEfN1OJcjCDVG2PUupzjUGGfrXM59lrv0EeWWPqxDOcpZd/KPh3Alp19WzTBb55aQH7nDZmJ87COWiJjWcVxn5xFHlGnrNi6hOo3TuA7dyayH/MX5AhdyxgLO4jzicTRxeF0soS9BgQgijYp5Ysc4qIXWCXGNYs2lYhP4klzCGXvjDq6BGD9w+uUa3K+MQX/FsNWYCizj/23R8v2wOcliHk/roG2Cl/J4xo0IqI0+j/PEba7FlHyxkSWZxP1VU6BnycJbwkTCGyZ+2hziJMBpddAqH+j+SiSSYeK3qwh1hGD2A4eGkMI2c+4IgaIkiBheZZ+927K3reNd2TkdHCTZqTewEcIGIzZRSX2Vqk+YmsqrAbZTpCRWHSH3Eu5JP0E0awMyJfV5lK6+WorOsFu5KYOwUJF+sjUkqeSmky+bPf38KniXHt0DOEy670Zyvuhiqp84/Mu+OFD6ACOshODuGLe/kv3+ZjE4FYu4hMD9Un54Wbwb6B3vPrCmShxXO9rZ682HRdl8+k3gd3atO6BaI0vRincV3i3zEA6mBvOQHvsQAYX1pKlgbxiliEkKVATVElaUM/rVntX4RvsCyWN9dtb6RPuCtjdi3rk6arrQXZebq2pGHjs6wxtV4C3MQd/g7duhAgzFA5txiXmdmr/GaFnsMB6qbZD3WFA97aJ6vhZMW0qO83V1q7aGot2A9dq5sUgEPItE10QJO7KMIqx27Jla+A54K/pDuSrULo83fgqpLSgftDp1zDYp9X/MN1fDfWhscGS0NKvisnRacNBu0t2RfvjEPqCaRPby1JXM3fh6fZ66Ok3shvQjYs7oj9rx767getZR99N/I+oqfAb6HHU/cYC9T01PXZR3IuyhvPbUJV90T7jQ07KYDcXCVnw1YZBrX7ue5u13bSJ9RET6t7+JOX3j1dkZvaNAEMv6+esrxUW/n09/UYQJK7YtqgC1gYqC4AtMYWCveTAPKjAfGrzYFuKsi6eC7tAuY/e4kUsTP7QrvtpRhTZYh4Es3z/gGB3rcrUopqV3Uyv6q71bRbmqBdeLU5PbTJckleny+doVxoTLmgnEaC+qYvb6qiw39ZBnUnlR3CxYPThylym4HlB5MwmMc3bTIRtO1/gcUbgjkmKfOzZ0WJ/YJRvvnaiKNoZiv0u2xqfrkS2fetnlkW0cskEbhhWALsx4Zmo/nNrxVMvRKWVtjKPiMLXiRmsZSsojJ6Adtvf5w8gIaAtrrrq5rEg4VGPaTVnYRv9lcc02+gNKGXRM0AVDAJuqId+Uf/rphUAbDvBaeL9elz5S8I2R965Y3JR3tDxxZdbH+UigNtXfTiGAg1scl72Yr2v4P5myZJu1nHVec0nCVXqdU4coM2JEGiQaHjYnZRA3JyXJqnpO/gajxDU0HQEcJoIp3MMJDcNpSM06dVlVqwdNLoUyw4+O/wSd4y3vjuwC2Z7l6vXICo+ytNlM0/V8tenJ5MyxgyZ+zjxpg6EBcnAjkFz0uNY7AusODUmuOeleVp7q15H380298a6rdeldrOeKHBYfPJXduyrezS/Zc0CT8eaa5IePd4auP74u1+/m07ImH6gnN2PY0A0H67KubpSQocb0cl2S4cvNoqxPdG7a8hDTu14dOR4Nb8j14K1MErX4yfSov/nwY3FJE2w4oBzSqVQCjSIk2XlMvRz/2UkbbyqJA+M4aLjvXWHmYnB01AJoItF4A+8r952D9Hp1RU2fvhn83iXaZbm5rda/nHAYnWm1eOA/ppl5pjtm8JYJgz1S0CnDJ/OxWnJ/KOvvpcwf2HtjbZtb35zX5J4zMPLWsULqeGnG6Vj16HHNxDGAPLC6IvbwmgrONzeUZ8hQRp4Zi3k1Xpa3SraDNDCYFZvidEQtLpdTxdrUG3MwMPwL06DTFWf/S7vFuR0rbGM4oK8DU1i4xrAoCab4MMA8vfsLlj20Esd5CxD5zbnQuUtOhJe0QMhHKNGpgB3yrlf39QAF23HpT3VctVg8LdjjjsSfH113JxGAtEyiXrWiO6m5rImw4Scl4q4wpDcq24jyjmEBcEK3Svb/Az+9ZVbAQYcPTk0lPDFGAM0+jJflC/ZaGR69NR2wquoHzZYINs39B+p/N6/n54vyB7XnoAlnWz6kEsK12CP5hhmkwrHpUt/wmrfZeQmRAgrTb+nxj6auoQNYkdy3kpnqOCb8v3TQsr6lBAsIfvPhxXxZ1sPvis3VmE2UhwbMMeo+cjZpUs2/M2GQg7KezS4xIh7hkdNDithUZpdep8UCEUZGiFIozeCMZ94xi9JwmbPMmIjux/l1Wd1shsB+5E0Q+sMUZ4JYl3UT5Y+XHNfke7VKEiGbebpSCYj/RbbUimNZazuLLA2NMMihM1Xbm2bV2SrJVjQcqJQ5B90aeWF8dKLmLbDszNtWOczlkVr3EWVFtoy72PebydsGm4YbG4bJWQq1m9F1sZxflPVGLRrV8tN/sQX14cFANiyDU+34YAIKdswQtqdpZRvsFH6VrT4J8Cef/uurzzOQPBZxqIbF2e/rmxWtnLW3rDbecErOumzgv4F1O+iTlIHH0AaWsGCHgb3AOiU9yM5duWOfeb34Jw1JpARmhLaK3wi+Aa7+mC8eL+b1hm3j6UEtczfXy1o906N6sm4DplbxZGAATfmmJ/N9KG43/SOUWwrVo45XgGCgETjmOA5K8N5Uyx2Y/2q60jdCJSRC1CvezVIzSWxWjby9vW0IzGpqXRf1hkx61Oz6pSwZ5FW5poCJ42q5+MCKPhoYByLtiTtgb0OG6Od5fvKecgywYIro+uZabWbnC8WUzwa0gx28/RUjsrPdPCh6m3yEMbCTBRVV1eJ4xcxIsSLFb6mzxqVCTbVecrw/ps3i8cWiVOI240iN+duXvQ4aSjb+0vum9M4X1fSXY/YNH3l1pXh3sfEMQILlTQu1xSh+Kb3y4kK1auTdXpVL71btWNe0a/Xmm/KaAJLVxdIrTGnvvKS9kCA5884/KPl7Nr+Yq3tYiXsEf+x9ecI7sbkiuOLDKVCyE2pXI3pdbxr+NG0XmgcNlxjPX73v9wfaKIA1QiQ4DkHzpaKwedcPyUknHOv5Xxk+Kqa+eGAoRnr1lFf+uz1tsLZbBB+TY3THfUo3P1i99yI00TSa0uh/2Eg/ni+JxI95t3AqhYgOr8vZvPCGjDz2xvWxaHiO1XyjAK2kuUCGqj6WJevU05nVNQU59vgMsZ/S6SkL0lfVYibs7uBCdYHC5cNCjel8UyzmU00Qn91fTW669yq2A0TrmS3gpmp7WV1rcYB0YKo3h5296gjG6h5z6FntfVf91epIuOmk+lFshhXmIrEpVlDqMHZQ31PIG47tZOLRkGRVkwv8lCQXTZDlzChN6mEzDObHQZvN05iQpMF6lTNYGN5p2BK1q5w9UXIiTZehu18XDUujNRTUpSYN0I/Vt+vikpVAf2HZ6eE7ogKx2m+vNTrYzoCZw9nAHzzC3uIhs/D1lnIzVcV5sR6c6Nzbq+BH0kmYGrxqSZ7+JcV8OhsgSLcazpXapK4KCJzDI40HQCuSvFR5pyXJMObVwUPutm0VUwefGDBkS28epHEaI5tL1t0tvWVX5kELJU8B/MU8afyq5VTNJZUupxU67M6WW4avKM9p4PyaNIY70OEMjWYyfnpcbKsfnrzT939xt8bzpRLSVWP+WhrifQ5yJh4/1LIWHx0g+lM5axG3O0vc7DpaTTl04pboRCeAhmNpq9/KhkMqsGXULvq8vKjW5cATLT5FBJsrcnqttnm0AJ6K7k2NviRplCicbh8mBhWTYFQ7JuXI1c0h/qaLNYfobajmunkElMlmYO+Rt8WHbDxH7BGXaJrZ9DELATH9Bs1t2kJLW0kzSOKZi2DdO5SdvLbhexbYxoV3NV8noiFWq3v9akmA3N35z3U/LQKEe3z6c60Pc1xYEjPlW9EFUK4G3jqTURYQVlB43lnni+58QrnHjUdV1AnprBbokfdRVje1lpiF727P6P87JB01c256XMV/K1nnH0XvuphW9Q782rhNfn21ne3Dp/96+FhdPBG+1AoyngweP6JdzEO9CWfnOUFMoqvXA0+VWipGvmWX9f58QUsHZzolQfxs98bJ5FV7r61A99y6WVjn22ERgtzMA91O00zeTWlB68xuzi5ZdWU6WXeP62L3T/rUghenh5JVVi06jCNZl0VX3udQBG6qtZHqSBcKyVMRyNhNcUngR2psF4vpVTn9xUg4zSNbvca2Nj4DUx/XpZf2ZiX0RAXOWJgbqb1Vca5W6tGmOEcEQbLEGCn+Vo8UyBl1+uh2XaxGjiQ+Uu0pmD9czZcNfFHlo4c6ktDJo4cnDdz1At/pK3ToidOjD/UIgFrNeDz6h7dGLJcPER5qrdWC7IVT133HGer+5Oea9OaskT8m/Xy5fuDjGKN1iqEyP/+310Z9/4LzHjV1+jTdVV3DrbSHx1dq1qqNr0J3MJJdE7PrzfoD3BLePH78+K05Pc4T8rX4rlwrMUztzTbflcsbC0JJ/pvKawMe9RvSECxq204ku3U00bzzpsVmejUs39MiwnOxGyL6Zkk9owoO7bGiPgPWzLK6aHxrpE+1qg8TsejpcbZBhd3tCU4FvY8VwoHo0F0kiGzZqwn0+/dofZu0xi5NFtrnRPYcP0Sv59fPVG9W/IkFWTJN3sulEiKfkHRuMiPtW9UpdY+UMVW7E50VUrkRo/grRPqxmE7Luv73krTag4HVw++3XTT7RUz6QXPrbvaLI4qRPbou3iPUmOU4tZLjLY9x2YvhRUBQLQujZSXC/wW1WSwVnToNDxTbxf9B9ma/IbJ166u3K2aQTYBTkySSdIMs9t0so/E9YqBRSA7w3Q+WTGUZeOz9y69bRk4e/YuAONUgEESmVR65txQ+ctu5xz7O6ZQOyxAS8ISBN2LJbylyvrhZf14Js+23xXYX4O1zM7MR2xVL0HPuz1OOg28ZwB+JUK3crrKaWKttkmGa5vCyazlWda3hdkG+s5j/We1kXpa3RCV8xG4NBGyQ3quidqiqvF5tPrCKohGv0lXN9W5KnHKWt/SzZGeLc+FyRdt4i+GFnlEXtlNcvPr7gdikzb+VFwvzbW+OP5cCe0vdR4S9he6hw94yPaQo34Y8gG7EtHjYiFva7g+3V3uWrJYN7xuZ+Qz9rd6LNvaJz5vDeacR4jFpryu91O8sUqac+t2nKAWnlxCwpmJtkbhP/W7eJhoNKPdj42bvQ4o1hb3YXPa4eh+Z83dnQjbxA0AHsR1+45Trgba77qDmVHFfd23FxoVxf2c1uUwHIeYxFIOtF52tONhiWzC4p1qSafYYIcrmMr9aF3Vq5VDMhY6/XHfLy5hwZg6S26+0k7q2Dp2SwLTZzO4eNxmbeNvy9w+ayds750Qmu3e+Sb7WXNOl2+TcU9KpfWc36/xtZd6O3jZFdvS4kjnZQKjdUJboni8lqnSLYkROHRy1yUYD29FunWffdpvK9iUxg9z2RpNUf9/IUp5m67jU/XRF2fpIikT5V0qUv69ina9ZuSm9o2t1nn27Vm8uPoOkTJEdvcsrO5bc+uvFPotEq4S7MWj2Qhv0niyqDX//9nYw297skvfGfcIKds0NQcVspNtjCCg9Yskz+0KkpHVJ0bsbxKBlCH7oyALQyThooLIxWwtgM/ldsVRb8XXr22MaEfvZK2hNPP7K1Z2LrN3my6Dxh0O2Uax+3Rjln+pyzULYEGLz1rKdnG0ZkpRAZNdXrjsKgTY0J2uLQaoFeL81yeZscRttkfmaNPb38p1G7hYHakLawQqaOYUhbOeHOvez5b0rnpt3C3YEZR/cni1n2zETqK915h/ouxjD4nWjYSPPJihousaTE+/r6bRas0Z9Uxn1IekFxqR6Hd9eFZvbS1ac/tOsOl5WGzLEWXwY6fLdqo+8ee0R7/OKd8V8QSsrRYIpvMX8mpRP/GGG6gIbF5ag6rHhBB1akY9LDLD1dOZkk8I/r/l2PHo30M4G1tnsN1nxEoVq95iOMmvlEFiG2f2zKtFb1s+/pxi+1BjD2WAs30oXhnKhcrD29D0ZXXWz2S+5UP0n/6eUttQnapbVm+F790M7GkXVnT+Ul8/er8ZrMtR+gpOK8aZ6Ud2W6ycFHd+6n4hxWeD/pm3icx1RZ9iDkSl2MF42O5Z25J38b947n8VpfpZKf4hFrrhYhd2f+YslGFd3+bTf1tF7YEfnqoentV6ZT+0Y1TSxebUXF3XwWWcBMiXu4yjdpcud1wzDJWvp59o2y53orKvYukrIW0vdpKTYmhsvTWb9CXjKvO37jG9KfCQRZuT6m4ywH1HUZjX3I8/5EDHQco3Tt+imOCOJ4a1vhNS3cyyibLIjH4KUVk0LkUlO0Ynkdlmtb4v1zGNwxNbUWN4UC+8PP373Alynf+Tc7uvdVmv8WmKRS7YGHQewYGYa7Sr89XS55yTAflClj3rtZHUEF1eyAlHxZ2xcIiM//IoCd9lJu4sGrTzjiDN6dv667hLRy47dKzohvp3XpWLZi0V161WU4JmPmSiiuxx7P/3wwjsnD3S2OaqPaJBpfeYa25WYr466s6FfijUEKISnEFJS/L+oVUpxyku2SmuyDbaRBXmyk65aGudTtiTThpGa3Bkr7Tt5pn0WN9VKMxJJmddP+ITuP5BVXu7Nlij3kZ3uLYrSgik++KSVkY2pufWYastUlZ5yVY62bIP1bMHFkk5rDZ+MvImzuMo8cFiAbr6i6+0vG+onY/LWYbs7uCg+wUrNaRBPZ/nhjpWQi/8PImJY9nXNAAA="; var sel = "Select"; try {sel = Services.strings.createBundle("chrome://global/locale/commonDialogs.properties") .GetStringFromName(sel);} catch(ex) {} var picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); picker.init(window, sel + " DOMi 7.0.4a1", picker.modeOpen); picker.appendFilter(null, "dom_inspector-7.0.4a1-fx-*.xpi"); await new Promise(resolve => picker.open(resolve)); var {file} = picker; if (!file) return; var ln = file.leafName; if (!re.test(ln)) return alert("???\n" + ln); var {fileURL} = picker; var xpi = file.parent.clone(); xpi.append(ln = ln.replace("4a1-", "5-")); file.copyTo(file.parent, ln); var obs = {}, data; var td = new TextDecoder(), te = new TextEncoder(); var scs = Cc["@mozilla.org/streamConverters;1"].getService(Ci.nsIStreamConverterService); var sis = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream); var sl = Cc["@mozilla.org/network/stream-loader;1"].createInstance(Ci.nsIStreamLoader); sis.data = atob(gzip); obs.onStreamComplete = (a, b, c, d, result) => data = td.decode(new Uint8Array(result)); sl.init(obs); var converter = scs.asyncConvertData("gzip", "uncompressed", sl, null); converter.onStartRequest(null, null); var args = [null, null, sis, 0, sis.data.length]; if (converter.onDataAvailable.length == 4) args.shift(); converter.onDataAvailable(...args); converter.onStopRequest(null, null, null); var zw = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter); var mt = Date.now() * 1000, cp = zw.COMPRESSION_DEFAULT; var bootstrap = ln.includes("bootstrap"); var prefix = "jar:" + fileURL.spec + "!/"; var lr = /^¦(?:\d+)?$/, sep1 = "£", sep2 = "¥"; zw.open(xpi, 0x04); // PR_RDWR for(var item of data.split(sep1)) { var [entry, val] = item.split(sep2); if (bootstrap && (entry == "manifest.json" || entry == "startup.jsm")) continue; if (val == "+") { zw.addEntryDirectory(entry, mt, false); continue; } if (zw.hasEntry(entry)) { if (val.includes("¦")) { var lines = val.split("\n"); var oldLines = (await (await fetch(prefix + entry)).text()).split("\n"); lines.forEach((line, ind) => { if (lr.test(line)) lines[ind] = oldLines[ line.length == 1 ? ind : +line.slice(1) ]; }); val = lines.join("\n"); } zw.removeEntry(entry, false); if (val == "-") continue; } var stream = Cc["@mozilla.org/io/string-input-stream;1"] .createInstance(Ci.nsISupportsCString); stream.data = String.fromCharCode(...new Uint8Array(te.encode(val))); zw.addEntryStream(entry, mt, cp, stream, false); stream.close(); } zw.close(); xpi.reveal(); })( /^dom_inspector-7\.0\.4a1-fx-(?:paxmod|bootstrap)\.xpi$/ ); |
Andrey_Krropotkin > 16-12-2019 11:59:38 |
Infocatcher, Dumby в кнопке для 71 версии скрытый текст Выделить код Код:// https://github.com/Infocatcher/Custom_Buttons/tree/master/CB_Editor_Toggle_on_Top // (c) Infocatcher 2012-2015 // version 0.1.11 - 2015-06-04 // Hotkey: Ctrl+T const watcherId = "customButtonsToggleOnTop_" + this.id; var {Components} = window; // Prevent garbage collection in Firefox 3.6 and older var storage = (function() { if(!("Services" in window)) // Firefox 3.6 and older return Application.storage; var global = Components.utils.import("resource://gre/modules/Services.jsm", {}); var ns = "_cbEditorToggleOnTopStorage"; var storage = global[ns] || (global[ns] = Components.utils.getGlobalForObject(global).Object.create(null)); return { get: function(key, defaultVal) { if(key in storage) return storage[key]; return defaultVal; }, set: function(key, val) { if(key === null) delete storage[key]; else storage[key] = val; } }; })(); var watcher = storage.get(watcherId, null); if(!watcher) { watcher = { btnPos: 0, // 0 - at top right window corner, 1 - at end of tabs, 2 - before dialog buttons spacer btnStyle: "toolbarbutton", // "button" or "toolbarbutton" btnChecked: true, // use "checked" style: true or false // http://www.iconfinder.com/icondetails/12276/16/gps_location_pin_icon icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AgNBjAx4SevkwAAAjxJREFUKM+FUk1oE0EU/mZnRU0U6cFLIT1KKkkNpIcSWwUvVty2l142hZpDoQcPgYQKQkUEz6V6sHgR/KGQQwleQg/xEKRRsIEmga4NoZa2oRGKpJaWmp2Z52UX12Dxg4838+D73ps3jzUYQycIgDc7l0oNAkgqpZ4n5uc/NgHsEEHDKZB/X5OJRGJcSplemJ6+6SZPFStvJ0Ta4eEhTNMcE0I8fDsxcQsAdPwHc6nUoBRCOz4+Rr1eR39//+18Pn/h/cjIGea+eS6VegLgKoBfRPRdKbXGOf8GIBmPx8cty0Kz2YTf74ff70cmkynpNSIAwP7+/t2ZmZnowcGBPDo6+rm1tdWo1Wo7pmnesSwLtm2jWCx+EkJwKSUnoln2wWnv9eTkMBE9TafT0b29PbTbbXDO0Wq1YNs2lpaWVpVSj8ZyuWXhaPg953CtXK6v9fVtr6ys9A4NDXU3Gg24JoVC4fPJycnjsVxu2TtMzgCUAVQAUKVSrwDtzc3NQCQS6d7d3XU7EK1W62twY+ML84i1N4zB5TvgYrVaPTs1NRXNZDKlrq4u+Hw+BAKBy1LK6zYA2xE+6/gqzhgbXl9fnw+FQrPBYPCHlBKjo6NRIjpPRD3kEdbcJWGMgTF2Y3Fx8UE4HE4yxl70WtYCEc1ms9kS51wDcM4r/FOS87BhGK90XTc0TeNuPgggFosNG4axOjAw8PJKxwIxAD26rt9XShWVUtvOWosO2h1RAJAMwCUAPseInGG6UTlm6l/8DZ+nFuAjSdH0AAAAAElFTkSuQmCC", iconPinned: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AgNBjIpwH1VRwAAAgdJREFUKM+FkkFoU0EQhr/dtxFSquLBS8CAICISQci1oBWLKaaINL300psXDxH0ItSD4L21UKgUxV4aWnKyiIGaQwio2IQ0PQQpBaEhoaEk0dSQNsnb9WAepg+LPwz/7DD/7O7MiJIQuGEAV3QIiNowV4f0HlA0BskJsI8fo75YLHIEjw3ccIInivVxX1IqcXFu7l4Lnhq4BaD4P4Y6INsHB+zlcpwfH7+zG48PavCIvj8/B64CRxoqXdg8Bd+BqG9xMVJNpaiUy5zxehkcGCC2uppV28Y44rs3V1aCFIt2p15v/MzlSj/S6eKlmZnRairFoW2zmUx+boHVBsvAtEj+fV5Iw4vbS0tBe2uLw04H2+ulUy5zaNu8X17OdOGZgkTX3TADCRumP0xNZY3fz6/9fSr5PNVGg6/x+BfdE/Y3wxJAHtj6wzt5aHsSiQv+4WFfbWcHu9VCeDzdRq32DdgQfZMQom9JjDGngcn19fWF2shI9vrYWNBqNjFCND8mk+8MTDq5s65RWUKIUKFQmA0EAtP3pawdra0xGokE0dqrwe8kvgS2e1cjpURKORyLxTaUUg+UUuciUvIWQq8hU5uYMPOQmQcuu7fAsqxr4XD4jVIqLKW0nPgV4AmEFiDzCF65hQLwK6Ueaq0/aa13e2vddVnHxV3AFsBZYKBXyPSa6bDuFdP/st/BfOD54p3eIQAAAABJRU5ErkJggg==", boxId: "cbToggleOnTopBox", btnId: "cbToggleOnTopButton", onTopAttr: "cbOnTop", naAttr: "cbOnTopNA", styleId: "cbToggleOnTopStyle", get btnTip() { var locale = (function() { if("Services" in window && "locale" in Services) { var locales = Services.locale.requestedLocales // Firefox 64+ || Services.locale.getRequestedLocales && Services.locale.getRequestedLocales(); if(locales) return locales[0]; } var prefs = "Services" in window && Services.prefs || Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefBranch); function pref(name, type) { return prefs.getPrefType(name) != prefs.PREF_INVALID ? prefs["get" + type + "Pref"](name) : undefined; } if(!pref("intl.locale.matchOS", "Bool")) { // Also see https://bugzilla.mozilla.org/show_bug.cgi?id=1414390 var locale = pref("general.useragent.locale", "Char"); if(locale && locale.substr(0, 9) != "chrome://") return locale; } return Components.classes["@mozilla.org/chrome/chrome-registry;1"] .getService(Components.interfaces.nsIXULChromeRegistry) .getSelectedLocale("global"); })().match(/^[a-z]*/)[0]; if(locale == "ru") return "Поверх всех окон (Ctrl+T)"; return "Always on top (Ctrl+T)"; }, REASON_STARTUP: 1, REASON_SHUTDOWN: 2, REASON_WINDOW_LOADED: 3, REASON_WINDOW_CLOSED: 4, get obs() { delete this.obs; return this.obs = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); }, get ww() { delete this.ww; return this.ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] .getService(Components.interfaces.nsIWindowWatcher); }, get wm() { delete this.wm; return this.wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] .getService(Components.interfaces.nsIWindowMediator); }, init: function(reason) { this.obs.addObserver(this, "quit-application-granted", false); var ws = this.wm.getEnumerator(null); while(ws.hasMoreElements()) this.initWindow(ws.getNext(), reason); this.ww.registerNotification(this); }, destroy: function(reason) { this.obs.removeObserver(this, "quit-application-granted"); var ws = this.wm.getEnumerator(null); while(ws.hasMoreElements()) this.destroyWindow(ws.getNext(), reason); this.ww.unregisterNotification(this); }, initWindow: function(window, reason) { if(!this.isTargetWindow(window)) return; window.addEventListener("keypress", this, true); if(this.hasSizeModeChangeEvent) window.addEventListener("sizemodechange", this, false); else { window.addEventListener("resize", this, false); // Can detect only maximize/restore this.legacySizeModeChange(window); } var document = window.document; this.removeStyle(document); this.addStyle(document); var box = document.getElementById(this.boxId); box && box.parentNode.removeChild(box); box = document.createXULElement("hbox"); box.id = this.boxId; var btn = document.createXULElement(this.btnStyle); btn.id = this.btnId; if(this.btnChecked) { btn.setAttribute("type", "checkbox"); btn.setAttribute("autoCheck", "false"); } btn.tooltipText = this.btnTip; btn.addEventListener("command", this, false); box.appendChild(btn); switch(this.btnPos) { default: box.setAttribute("cbOnTopFloat", "true"); document.documentElement.appendChild(box); break; case 1: box.setAttribute("align", "right"); let tabbox = document.getElementById("custombuttons-editbutton-tabbox"); let tabs = tabbox.getElementsByTagName("tabs")[0]; tabs.parentNode.insertBefore(box, tabs); box.style.marginBottom = -btn.boxObject.height + "px"; break; case 2: box.setAttribute("align", "center"); let btnBox = document.documentElement.getButton("accept").parentNode; let insPos = btnBox.firstChild; for(let node = insPos; node; node = node.nextSibling) { if(node.localName == "spacer") { insPos = node; break; } } btnBox.insertBefore(box, insPos); } this.checkWindowStatus(window, box); }, destroyWindow: function(window, reason) { if(reason == this.REASON_WINDOW_CLOSED) window.removeEventListener("DOMContentLoaded", this, false); // Window can be closed before DOMContentLoaded if(!this.isTargetWindow(window)) return; window.removeEventListener("keypress", this, true); if(this.hasSizeModeChangeEvent) window.removeEventListener("sizemodechange", this, false); else window.removeEventListener("resize", this, false); var document = window.document; var btn = document.getElementById(this.btnId); btn.removeEventListener("command", this, false); if(reason == this.REASON_SHUTDOWN) { let box = btn.parentNode; box.parentNode.removeChild(box); this.removeStyle(document); let xulWin = this.getXulWin(window); xulWin.zLevel = xulWin.normalZ; } }, isTargetWindow: function(window) { return window.location.href.substr(0, 41) == "chrome://custombuttons/content/editor.xul"; }, observe: function(subject, topic, data) { if(topic == "quit-application-granted") this.destroy(); else if(topic == "domwindowopened") subject.addEventListener("DOMContentLoaded", this, false); else if(topic == "domwindowclosed") this.destroyWindow(subject, this.REASON_WINDOW_CLOSED); }, handleEvent: function(e) { var trg = e.originalTarget || e.target; var window; switch(e.type) { case "DOMContentLoaded": window = trg.defaultView; window.removeEventListener("DOMContentLoaded", this, false); this.initWindow(window, this.REASON_WINDOW_LOADED); break; case "keypress": if( !( (e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && String.fromCharCode(e.charCode).toLowerCase() == "t" ) ) break; e.preventDefault(); e.stopPropagation(); case "command": window = trg.ownerDocument.defaultView.top; this.toggleOnTop(window); break; case "sizemodechange": case "resize": window = trg; this.checkWindowStatus(window); } }, get hasSizeModeChangeEvent() { var appinfo = "Services" in window && Services.appinfo; delete this.hasSizeModeChangeEvent; return this.hasSizeModeChangeEvent = appinfo && ( appinfo.name == "Pale Moon" || parseFloat(appinfo.platformVersion) >= 8 ); }, legacySizeModeChange: function(window) { var lastState = window.windowState; window.setInterval(function(window, _this) { var state = window.windowState; if(state != lastState) _this.checkWindowStatus(window); lastState = state; }, 150, window, this); }, checkWindowStatus: function(window, box) { if(!box) box = window.document.getElementById(this.boxId); var na = String(window.windowState != window.STATE_NORMAL); if(box.getAttribute(this.naAttr) == na) return; box.setAttribute(this.naAttr, na); //LOG("Set n/a: " + na); this.setOnTop(box.firstChild); }, addStyle: function(document) { var style = '\ %box%[cbOnTopFloat] {\n\ position: fixed !important;\n\ top: 0 !important;\n\ right: 0 !important;\n\ }\n\ %btn%, %btn% * {\n\ margin: 0 !important;\n\ padding: 0 !important;\n\ }\n\ %btn% > .button-box > .button-icon {\n\ margin: -3px -1px !important;\n\ }\n\ toolbarbutton%btn% {\n\ padding: 0 2px !important;\n\ }\n\ %btn% {\n\ position: relative !important;\n\ z-index: 2147483647 !important;\n\ list-style-image: url("%icon%") !important;\n\ -moz-user-focus: ignore !important;\n\ min-height: 0 !important;\n\ min-width: 0 !important;\n\ }\n\ %btn%[%onTopAttr%="true"] {\n\ list-style-image: url("%iconPinned%") !important;\n\ }\n\ %box%[%naAttr%="true"] image {\n\ opacity: 0.75 !important;\n\ }' .replace(/%box%/g, "#" + this.boxId) .replace(/%btn%/g, "#" + this.btnId) .replace(/%onTopAttr%/g, this.onTopAttr) .replace(/%icon%/g, this.icon) .replace(/%iconPinned%/g, this.iconPinned) .replace(/%naAttr%/g, this.naAttr); document.insertBefore(document.createProcessingInstruction( "xml-stylesheet", 'id="' + this.styleId + '" href="' + "data:text/css," + encodeURIComponent(style) + '" type="text/css"' ), document.documentElement); }, removeStyle: function(document) { var mark = 'id="' + this.styleId + '"'; for(var child = document.documentElement; child = child.previousSibling; ) { if( child.nodeType == child.PROCESSING_INSTRUCTION_NODE && child.data.substr(0, mark.length) == mark ) { document.removeChild(child); break; } } }, getXulWin: function(window) { return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShellTreeItem) .treeOwner .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIXULWindow); }, setOnTop: function(btn, toggle) { var document = btn.ownerDocument; var root = document.documentElement; var onTop = root.getAttribute(this.onTopAttr) == "true"; var xs = Components. classes ["@mozilla.org/xul/xulstore;1"]. getService (Components. interfaces. nsIXULStore); if(toggle) { onTop = !onTop; root.setAttribute(this.onTopAttr, onTop); if(root.id) { if (!("persist" in document)) { if (!("persist" in xs)) xs = ChromeUtils. import ("resource://gre/modules/Services.jsm"). Services. xulStore; document.persist = function (id, attrr){ var node = document. getElementById (root.id); if (node) xs. persist (root.id, this.onTopAttr); } } } } else if(!onTop) // Just opened or restored window always have zLevel == normalZ return; var window = document.defaultView; var state = window.windowState; var restore = onTop && state == window.STATE_MINIMIZED; if(restore || state == window.STATE_NORMAL) { if(restore) onTop = false; let xulWin = this.getXulWin(window); xulWin.zLevel = onTop ? xulWin.raisedZ : xulWin.normalZ; } this.checkButton(btn, onTop); }, toggleOnTop: function(window) { this.setOnTop(window.document.getElementById(this.btnId), true); }, checkButton: function(btn, onTop) { btn.setAttribute(this.onTopAttr, onTop); this.btnChecked && btn.setAttribute("checked", onTop); } }; storage.set(watcherId, watcher); watcher.init(watcher.REASON_STARTUP); } function destructor(reason) { if(reason == "update" || reason == "delete") { watcher.destroy(watcher.REASON_SHUTDOWN); storage.set(watcherId, null); } } if( typeof addDestructor == "function" // Custom Buttons 0.0.5.6pre4+ && addDestructor != ("addDestructor" in window && window.addDestructor) ) addDestructor(destructor, this); else this.onDestroy = destructor; Выдает скрытый текст TypeError: btn is null button.js:187:4 destroyWindow chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button58@init line 1 > Function:187 observe chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button58@init line 1 > Function:205 В кнопке скрытый текст Выделить код Код:// https://github.com/Infocatcher/Custom_Buttons/tree/master/CB_Source_Editor // http://infocatcher.ucoz.net/js/cb/cbSourceEditor.js // (c) Infocatcher 2012-2019 // version 0.1.0a9 - 2019-03-01 var options = { cssInHelp: true, codeMirror: { lineNumbers: true, enableCodeFolding: true, showTrailingSpace: true, lineWrapping: false, autocomplete: true, fontSize: 14 }, orion: { lineNumbers: true } }; const watcherId = "customButtonsSourceEditor_" + this.id; var {Components} = window; // Prevent garbage collection in Firefox 3.6 and older var storage = (function() { if(!("Services" in window)) // Firefox 3.6 and older return Application.storage; var global = Components.utils.import("resource://gre/modules/Services.jsm", {}); var ns = "_cbSourceEditorStorage"; var storage = global[ns] || (global[ns] = Components.utils.getGlobalForObject(global).Object.create(null)); return { get: function(key, defaultVal) { if(key in storage) return storage[key]; return defaultVal; }, set: function(key, val) { if(key === null) delete storage[key]; else storage[key] = val; } }; })(); var watcher = storage.get(watcherId, null); if(!watcher) { watcher = { REASON_STARTUP: 1, REASON_SHUTDOWN: 2, REASON_WINDOW_LOADED: 3, REASON_WINDOW_CLOSED: 4, get obs() { delete this.obs; return this.obs = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); }, get ww() { delete this.ww; return this.ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] .getService(Components.interfaces.nsIWindowWatcher); }, get wm() { delete this.wm; return this.wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] .getService(Components.interfaces.nsIWindowMediator); }, get platformVersion() { delete this.platformVersion; return this.platformVersion = parseFloat(Services.appinfo.platformVersion); }, get hasCodeMirror() { delete this.hasCodeMirror; return this.hasCodeMirror = Services.appinfo.name == "Pale Moon" //~ todo: test || this.platformVersion >= 27; }, init: function(reason) { if(!this.hasCodeMirror) { this.isBrowserWindow = function() { return false; }; } this.obs.addObserver(this, "quit-application-granted", false); var ws = this.wm.getEnumerator(null); while(ws.hasMoreElements()) this.initWindow(ws.getNext(), reason); this.ww.registerNotification(this); }, destroy: function(reason) { this.obs.removeObserver(this, "quit-application-granted"); var ws = this.wm.getEnumerator(null); while(ws.hasMoreElements()) this.destroyWindow(ws.getNext(), reason); this.ww.unregisterNotification(this); }, initWindow: function(window, reason, isFrame) { if(this.isBrowserWindow(window)) { this.initBrowserWindow(window, reason); return; } if(!this.isEditorWindow(window)) return; _log("initWindow(): isFrame: " + isFrame); var document = window.document; if(isFrame) window.addEventListener("unload", this, false); Components.classes["@mozilla.org/moz/jssubscript-loader;1"] .getService(Components.interfaces.mozIJSSubScriptLoader) .loadSubScript("chrome://global/content/globalOverlay.js", window); var isCodeMirror = false; try { // See chrome://browser/content/devtools/scratchpad.js Components.utils.import("resource:///modules/source-editor.jsm", window); } catch(e) { var loader = this.platformVersion >= 44 // See https://bugzilla.mozilla.org/show_bug.cgi?id=912121 ? "resource://devtools/shared/Loader.jsm" : "resource://gre/modules/devtools/Loader.jsm"; var g = Components.utils.import(loader, {}); var require = (g.devtools || g).require; [ "devtools/sourceeditor/editor", "devtools/client/sourceeditor/editor", // Firefox 44+ "devtools/client/shared/sourceeditor/editor" // Firefox 68+ ].some(function(path) { try { return window.SourceEditor = require(path); } catch(e) { } return null; }); isCodeMirror = true; } var SourceEditor = window.SourceEditor; // See view-source:chrome://browser/content/devtools/scratchpad.xul // + view-source:chrome://browser/content/devtools/source-editor-overlay.xul var psXUL = (isCodeMirror ? '<!DOCTYPE popupset [\ <!ENTITY % editMenuStrings SYSTEM "chrome://global/locale/editMenuOverlay.dtd">\ %editMenuStrings;\ <!ENTITY % sourceEditorStrings SYSTEM "' + ( Services.appinfo.name == "Pale Moon" || Services.appinfo.name == "Basilisk" ? this.platformVersion >= 4.1 ? "chrome://devtools/locale/sourceeditor.dtd" : "chrome://global/locale/devtools/sourceeditor.dtd" : this.platformVersion >= 45 ? "chrome://devtools/locale/sourceeditor.dtd" : "chrome://browser/locale/devtools/sourceeditor.dtd" ) + '">\ %sourceEditorStrings;\ ]>\ <popupset id="sourceEditorPopupset"\ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">\ <menupopup id="sourceEditorContext"\ onpopupshowing="goUpdateSourceEditorMenuItems()">\ <menuitem id="menu_undo" label="&undoCmd.label;" accesskey="&undoCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_undo\')" />\ <menuitem id="menu_redo" label="&redoCmd.label;" accesskey="&redoCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_redo\')" />\ <menuseparator/>\ <menuitem id="menu_cut" label="&cutCmd.label;" accesskey="&cutCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_cut\')" />\ <menuitem id="menu_copy" label="©Cmd.label;" accesskey="©Cmd.accesskey;"\ oncommand="goDoCommand(\'cmd_copy\')" />\ <menuitem id="menu_paste" label="&pasteCmd.label;" accesskey="&pasteCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_paste\')" />\ <menuitem id="menu_delete" label="&deleteCmd.label;" accesskey="&deleteCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_delete\')" />\ <menuseparator/>\ <menuitem id="menu_selectAll" label="&selectAllCmd.label;" accesskey="&selectAllCmd.accesskey;"\ oncommand="goDoCommand(\'cmd_selectAll\')" />\ <menuseparator/>\ <menuitem id="menu_find" label="&findCmd.label;" accesskey="&findCmd.accesskey;" />\ <menuitem id="menu_findAgain" label="&findAgainCmd.label;" accesskey="&findAgainCmd.accesskey;" />\ <menuseparator/>\ <menuitem id="se-menu-gotoLine"\ label="&gotoLineCmd.label;"\ accesskey="&gotoLineCmd.accesskey;"\ key="key_gotoLine"\ oncommand="goDoCommand(\'cmd_gotoLine\')"/>\ </menupopup>\ </popupset>' : '<popupset id="sourceEditorPopupset"\ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">\ <menupopup id="sourceEditorContext"\ onpopupshowing="goUpdateSourceEditorMenuItems()">\ <menuitem id="se-menu-undo"/>\ <menuitem id="se-menu-redo"/>\ <menuseparator/>\ <menuitem id="se-menu-cut"/>\ <menuitem id="se-menu-copy"/>\ <menuitem id="se-menu-paste"/>\ <menuitem id="se-menu-delete"/>\ <menuseparator/>\ <menuitem id="se-menu-selectAll"/>\ <menuseparator/>\ <menuitem id="se-menu-find"/>\ <menuitem id="se-menu-findAgain"/>\ <menuseparator/>\ <menuitem id="se-menu-gotoLine"/>\ </menupopup>\ </popupset>' ).replace(/>\s+</g, "><"); var ps = this.parseXULFromString(psXUL); document.documentElement.appendChild(ps); window.setTimeout(function() { function appendNode(nodeName, id) { var node = document.createElementNS(xulns, nodeName); node.id = id; document.documentElement.appendChild(node); } appendNode("commandset", "editMenuCommands"); appendNode("commandset", "sourceEditorCommands"); appendNode("keyset", "sourceEditorKeys"); appendNode("keyset", "editMenuKeys"); this.loadOverlays( window, function done() { window.setTimeout(function() { var mp = document.getElementById("sourceEditorContext"); if(mp.state == "closed") return; Array.prototype.forEach.call( mp.getElementsByAttribute("command", "*"), function(mi) { var cmd = mi.getAttribute("command"); var controller = document.commandDispatcher .getControllerForCommand(cmd); if(controller && !controller.isCommandEnabled(cmd)) mi.setAttribute("disabled", "true"); } ); }, 0); if(!isCodeMirror) return; // See view-source:chrome://browser/content/devtools/scratchpad.xul in Firefox 27.0a1 window.goUpdateSourceEditorMenuItems = function() { goUpdateGlobalEditMenuItems(); var commands = ["cmd_undo", "cmd_redo", "cmd_cut", "cmd_paste", "cmd_delete"]; commands.forEach(goUpdateCommand); }; var cmdsMap = { "se-menu-undo": "cmd_undo", "se-menu-redo": "cmd_redo", "se-menu-cut": "cmd_cut", "se-menu-copy": "cmd_copy", "se-menu-paste": "cmd_paste", "se-menu-delete": "cmd_delete", __proto__: null }; for(var id in cmdsMap) { var mi = document.getElementById(id); mi && mi.setAttribute("command", cmdsMap[id]); } // We can't use command="cmd_selectAll", menuitem will be wrongly disabled sometimes var enabledCmdsMap = { "se-menu-selectAll": "cmd_selectAll", "se-menu-findAgain": "cmd_findAgain", __proto__: null }; for(var id in enabledCmdsMap) { var mi = document.getElementById(id); if(mi) { mi.removeAttribute("command"); mi.removeAttribute("disabled"); mi.setAttribute("oncommand", "goDoCommand('" + enabledCmdsMap[id] + "');"); } } // Workaround: emulate keyboard shortcut var keyCmdsMap = { "menu_find": { keyCode: KeyboardEvent.DOM_VK_F, charCode: "f".charCodeAt(0), ctrlKey: true }, "menu_findAgain": { keyCode: KeyboardEvent.DOM_VK_G, charCode: "g".charCodeAt(0), ctrlKey: true }, __proto__: null }; var _key = function() { var e = this._keyData; var evt = document.createEvent("KeyboardEvent"); evt.initKeyEvent( "keydown", true /*bubbles*/, true /*cancelable*/, window, e.ctrlKey || false, e.altKey || false, e.shiftKey || false, e.metaKey || false, e.keyCode || 0, e.charCode || 0 ); document.commandDispatcher.focusedElement.dispatchEvent(evt); }; for(var id in keyCmdsMap) { var mi = document.getElementById(id); if(mi) { mi.removeAttribute("command"); mi.removeAttribute("disabled"); mi.setAttribute("oncommand", "this._key();"); mi._keyData = keyCmdsMap[id]; mi._key = _key; } } // Fix styles for autocomplete tooltip function css(uri) { document.insertBefore(document.createProcessingInstruction( "xml-stylesheet", 'href="' + uri + '" type="text/css"' ), document.documentElement); } css("resource://devtools/client/themes/variables.css"); css("resource://devtools/client/themes/common.css"); css("chrome://devtools/skin/tooltips.css"); }, ["chrome://global/content/editMenuOverlay.xul", function check(window) { return window.document.getElementById("editMenuCommands").hasChildNodes(); }], ["chrome://browser/content/devtools/source-editor-overlay.xul", function check(window) { return window.document.getElementById("sourceEditorCommands").hasChildNodes(); }] ); }.bind(this), 500); // We should wait to not break other extensions with document.loadOverlay() var tabs = document.getElementById("custombuttons-editbutton-tabbox"); var selectedPanel = tabs.selectedPanel; Array.prototype.slice.call(document.getElementsByTagName("cbeditor")).forEach(function(cbEditor) { if("__sourceEditor" in cbEditor) return; var code = cbEditor.value; var isCSS = options.cssInHelp && cbEditor.id == "help"; if(isCodeMirror) { var opts = { mode: isCSS ? SourceEditor.modes.css : SourceEditor.modes.js, value: code, lineNumbers: true, enableCodeFolding: true, showTrailingSpace: true, autocomplete: true, contextMenu: "sourceEditorContext" }; var optsOvr = options.codeMirror; for(var opt in optsOvr) if(optsOvr.hasOwnProperty(opt)) opts[opt] = optsOvr[opt]; var se = new SourceEditor(opts); if("codeMirror" in se) window.setTimeout(function() { if("insertCommandsController" in se) se.insertCommandsController(); // Pale Moon and Basilisk else this.insertCommandsController(se); }.bind(this), 200); } else { var se = new SourceEditor(); } se.__isCodeMirror = isCodeMirror; var seElt = document.createElementNS(xulns, "hbox"); if(cbEditor.id) seElt.id = "sourceEditor-" + cbEditor.id; seElt.className = "sourceEditor"; seElt.setAttribute("flex", 1); seElt.__sourceEditor = se; cbEditor.parentNode.insertBefore(seElt, cbEditor); //cbEditor.setAttribute("hidden", "true"); cbEditor.setAttribute("collapsed", "true"); cbEditor.parentNode.appendChild(cbEditor); cbEditor.__sourceEditor = se; cbEditor.__sourceEditorElt = seElt; cbEditor.__defineGetter__("value", function() { if("__sourceEditor" in this) { var se = this.__sourceEditor; if(!se.__initialized) return se.__value; return se.getText().replace(/\r\n?|\n\r?/g, "\n"); } return this.textbox.value; }); cbEditor.__defineSetter__("value", function(v) { if("__sourceEditor" in this) { var se = this.__sourceEditor; if(!se.__initialized) { var _this = this; se.__onLoadCallbacks.push(function() { _this.value = v; }); return se.__value = v; } return se.setText(v.replace(/\r\n?|\n\r?/g, "\n")); } return this.textbox.value = v; }); cbEditor.selectLine = function(lineNumber) { if("__sourceEditor" in this) { var se = this.__sourceEditor; if(!se.__initialized) { var _this = this, args = arguments; se.__onLoadCallbacks.push(function() { _this.selectLine.apply(_this, args); }); return undefined; } if(se.__isCodeMirror) { //se.focus(); //se.setCursor({ line: lineNumber - 1, ch: 0 }); //~ todo: optimize var val = this.value; var lines = val.split("\n"); var line = Math.min(lineNumber - 1, lines.length); var ch = lines[line].length; se.focus(); return se.setSelection({ line: line, ch: 0 }, { line: line, ch: ch }); } else { var selStart = se.getLineStart(lineNumber - 1); var selEnd = se.getLineEnd(lineNumber - 1, false); se.focus(); return se.setSelection(selStart, selEnd); } } return this.__proto__.selectLine.apply(this, arguments); }; // For edit_button() from chrome://custombuttons/content/editExternal.js seElt.__cbEditor = cbEditor; seElt.__defineGetter__("localName", function() { return "cbeditor"; }); seElt.__defineGetter__("value", function() { return this.__cbEditor.value; }); seElt.__defineSetter__("value", function(val) { this.__cbEditor.value = val; }); se.__initialized = false; se.__onLoadCallbacks = []; se.__value = code; var onTextChanged = se.__onTextChanged = function() { window.editor.changed = true; }; var isLoaded = reason == this.REASON_WINDOW_LOADED; function done() { se.__initialized = true; se.__onLoadCallbacks.forEach(function(fn) { try { fn(); } catch(e) { Components.utils.reportError(e); } }); delete se.__onLoadCallbacks; delete se.__value; } if(isCodeMirror) { se.appendTo(seElt).then(function() { try { se.setupAutoCompletion(); } catch(e) { Components.utils.reportError(e); } if("setFontSize" in se) try { se.setFontSize(options.codeMirror.fontSize); } catch(e) { Components.utils.reportError(e); } window.setTimeout(function() { window.editor.changed = false; // Strange... window.setTimeout(function() { // Workaround for unexpected onTextChanged() calls if(window.editor.changed && cbEditor.value == code) window.editor.changed = false; }, 100); se.on("change", onTextChanged); if(isLoaded) { if("clearHistory" in se) se.clearHistory(); else { var seGlobal = Components.utils.getGlobalForObject(SourceEditor.prototype); // Note: this is resource://app/modules/devtools/gDevTools.jsm scope in Firefox 34+ var cm = seGlobal.editors.get(se); cm.clearHistory(); } } }, isFrame ? 50 : 15); // Oh, magic delays... done(); // See resource:///modules/devtools/sourceeditor/editor.js // doc.defaultView.controllers.insertControllerAt(0, controller(this, doc.defaultView)); var controllers = window.controllers; // nsIControllers var controller = se.__cmdController = controllers.getControllerAt(0); if("__cmdControllers" in tabs) tabs.__cmdControllers.push(controller); else { tabs.__cmdControllers = [controller]; var onSelect = tabs.__onSelect = function() { var seElt = tabs.selectedPanel; if(!seElt || !("__sourceEditor" in seElt)) return; var se = seElt.__sourceEditor; var curController = se.__cmdController; tabs.__cmdControllers.forEach(function(controller) { try { if(controller == curController) controllers.insertControllerAt(0, controller); else controllers.removeController(controller); } catch(e) { } }); }; tabs.addEventListener("select", onSelect, false); window.setTimeout(onSelect, 0); // Activate controller from selected tab } }); } else { var opts = { mode: isCSS ? SourceEditor.MODES.CSS : SourceEditor.MODES.JAVASCRIPT, showLineNumbers: true, initialText: code, placeholderText: code, // For backward compatibility contextMenu: "sourceEditorContext" }; var optsOvr = options.orion; for(var opt in optsOvr) if(optsOvr.hasOwnProperty(opt)) opts[opt] = optsOvr[opt]; se.init(seElt, opts, function callback() { done(); isLoaded && se.resetUndo && se.resetUndo(); se.addEventListener(SourceEditor.EVENTS.TEXT_CHANGED, onTextChanged); // Hack to use selected editor var controller = se.ui._controller; controller.__defineGetter__("_editor", function() { var seElt = tabs.selectedPanel; var se = seElt && seElt.__sourceEditor || document.getElementsByTagName("cbeditor")[0].__sourceEditor; return se; }); controller.__defineSetter__("_editor", function() {}); }); } }, this); // Force select correct panel (prevent bugs, if selected "Button settings" tab) tabs.selectedPanel = selectedPanel.__sourceEditorElt || selectedPanel; var origExecCmd = window.editor.execute_oncommand_code; window.editor.execute_oncommand_code = function() { var cd = document.commandDispatcher; var cdFake = { __proto__: cd, get focusedElement() { var selectedTab = tabs.selectedTab; if(selectedTab && selectedTab.id == "code-tab") return document.getElementById("code").textbox.inputField; return cd.focusedElement; } }; document.__defineGetter__("commandDispatcher", function() { return cdFake; }); try { var ret = origExecCmd.apply(this, arguments); } catch(e) { Components.utils.reportError(e); } // document.hasOwnProperty("commandDispatcher") == false, so we cat just delete our fake property delete document.commandDispatcher; return ret; }; window.addEventListener("load", function ensureObserversAdded() { window.removeEventListener("load", ensureObserversAdded, false); window.setTimeout(function() { window.editor.removeObservers(); }, 0); window.setTimeout(function() { window.editor.addObservers(); }, 0); }, false); // Fix for Ctrl+S hotkey (catched by CodeMirror) var hke = this.handleKeyEvent; window.addEventListener("keydown", hke, true); window.addEventListener("keypress", hke, true); window.addEventListener("keyup", hke, true); if(this.platformVersion >= 68) (function(events, win) { var listener = function(e) { if(e.type == "unload") return destroy(); var sheets = win.document.styleSheets; for(var ind = sheets.length - 1; ind; ind--) { var sheet = sheets.item(ind); if(sheet.href != "resource://devtools/client/themes/common.css") continue; destroy(); for(let ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); if(rule.selectorText && rule.selectorText == "::selection") return sheet.deleteRule(ind); } } } var destroy = function() { events.forEach(function(type) { win.removeEventListener(type, listener, false); }); } events.forEach(function(type) { win.addEventListener(type, listener, false); }); })(["mousedown", "keydown", "unload"], window); }, insertCommandsController: function(se) { this.insertCommandsController = insertCommandsController; return insertCommandsController(se); // devtools/client/sourceeditor/editor-commands-controller in Pale Moon/Basilisk function createController(ed) { return { supportsCommand: function (cmd) { switch (cmd) { case "cmd_find": case "cmd_findAgain": case "cmd_gotoLine": case "cmd_undo": case "cmd_redo": case "cmd_delete": case "cmd_selectAll": return true; } return false; }, isCommandEnabled: function (cmd) { let cm = ed.codeMirror; switch (cmd) { case "cmd_find": case "cmd_gotoLine": case "cmd_selectAll": return true; case "cmd_findAgain": return cm.state.search != null && cm.state.search.query != null; case "cmd_undo": return ed.canUndo(); case "cmd_redo": return ed.canRedo(); case "cmd_delete": return ed.somethingSelected(); } return false; }, doCommand: function (cmd) { let cm = ed.codeMirror; let map = { "cmd_selectAll": "selectAll", "cmd_find": "find", "cmd_undo": "undo", "cmd_redo": "redo", "cmd_delete": "delCharAfter", "cmd_findAgain": "findNext" }; if (map[cmd]) { cm.execCommand(map[cmd]); return; } if (cmd == "cmd_gotoLine") { ed.jumpToLine(); } }, onEvent: function () {} }; } function insertCommandsController(sourceEditor) { let input = sourceEditor.codeMirror.getInputField(); let controller = createController(sourceEditor); input.controllers.insertControllerAt(0, controller); } }, destroyWindow: function(window, reason, isFrame) { if(reason == this.REASON_WINDOW_CLOSED) window.removeEventListener("DOMContentLoaded", this, false); // Window can be closed before DOMContentLoaded if(this.isBrowserWindow(window)) { this.destroyBrowserWindow(window, reason); return; } if(!this.isEditorWindow(window) || !("SourceEditor" in window)) return; _log("destroyWindow(): isFrame: " + isFrame); var document = window.document; if(isFrame) window.removeEventListener("unload", this, false); var tabs = document.getElementById("custombuttons-editbutton-tabbox"); if("__onSelect" in tabs) { tabs.removeEventListener("select", tabs.__onSelect, false); delete tabs.__onSelect; delete tabs.__cmdControllers; } Array.prototype.slice.call(document.getElementsByTagName("cbeditor")).forEach(function(cbEditor) { if(!("__sourceEditor" in cbEditor)) return; var se = cbEditor.__sourceEditor; var isCodeMirror = se.__isCodeMirror; if(isCodeMirror) se.off("change", se.__onTextChanged); else se.removeEventListener(window.SourceEditor.EVENTS.TEXT_CHANGED, se.__onTextChanged); delete se.__onTextChanged; if(reason == this.REASON_SHUTDOWN) { var val = cbEditor.value; delete cbEditor.value; delete cbEditor.selectLine; var seElt = cbEditor.__sourceEditorElt; seElt.parentNode.insertBefore(cbEditor, seElt); seElt.parentNode.removeChild(seElt); delete cbEditor.__sourceEditorElt; delete cbEditor.__sourceEditor; delete seElt.__sourceEditor; delete seElt.__cbEditor; cbEditor.value = val; window.setTimeout(function() { cbEditor.removeAttribute("collapsed"); }, 0); } se.destroy(); if("__cmdController" in se) { try { window.controllers.removeController(se.__cmdController); } catch(e) { } delete se.__cmdController; } }, this); if(reason == this.REASON_SHUTDOWN) { delete window.editor.execute_oncommand_code; [ "sourceEditorPopupset", "editMenuCommands", "sourceEditorCommands", "sourceEditorKeys", "editMenuKeys" ].forEach(function(id) { var node = document.getElementById(id); node && node.parentNode.removeChild(node); }); [ "closeWindow", "canQuitApplication", "goQuitApplication", "goUpdateCommand", "goDoCommand", "goSetCommandEnabled", "goSetMenuValue", "goSetAccessKey", "goOnEvent", "visitLink", "setTooltipText", "NS_ASSERT", "goUpdateGlobalEditMenuItems", "goUpdateUndoEditMenuItems", "goUpdatePasteMenuItems" ].forEach(function(p) { delete window[p]; }); for(var child = document.documentElement; child = child.previousSibling; ) { if( child.nodeType == child.PROCESSING_INSTRUCTION_NODE && child.data.indexOf("://devtools/") != -1 ) { setTimeout(function(child) { child.parentNode.removeChild(child); }, 0, child); } } delete window.SourceEditor; } var hke = this.handleKeyEvent; window.removeEventListener("keydown", hke, true); window.removeEventListener("keypress", hke, true); window.removeEventListener("keyup", hke, true); //~ todo: we have one not removed controller! //LOG("getControllerCount(): " + window.controllers.getControllerCount()); }, initBrowserWindow: function(window, reason) { _log("initBrowserWindow()"); window.addEventListener("DOMContentLoaded", this, false); Array.prototype.forEach.call(window.frames, function(frame) { this.initWindow(frame, reason, true); }, this); }, destroyBrowserWindow: function(window, reason) { _log("destroyBrowserWindow()"); window.removeEventListener("DOMContentLoaded", this, false); Array.prototype.forEach.call(window.frames, function(frame) { this.destroyWindow(frame, reason, true); }, this); }, isEditorWindow: function(window) { return window.location.href.substr(0, 41) == "chrome://custombuttons/content/editor.xul"; }, isBrowserWindow: function(window) { var loc = window.location.href; return loc == "chrome://browser/content/browser.xhtml" || loc == "chrome://navigator/content/navigator.xul"; }, observe: function(subject, topic, data) { if(topic == "quit-application-granted") this.destroy(); else if(topic == "domwindowopened") subject.addEventListener("DOMContentLoaded", this, false); else if(topic == "domwindowclosed") this.destroyWindow(subject, this.REASON_WINDOW_CLOSED); }, handleEvent: function(e) { switch(e.type) { case "DOMContentLoaded": var window = e.target.defaultView || e.target; window.removeEventListener(e.type, this, false); var isFrame = window != e.currentTarget; this.initWindow(window, this.REASON_WINDOW_LOADED, isFrame); break; case "unload": //var window = e.currentTarget; var window = e.target.defaultView || e.target; window.removeEventListener(e.type, this, false); this.destroyWindow(window, this.REASON_WINDOW_CLOSED, true); } }, handleKeyEvent: function(e) { if( (e.keyCode == e.DOM_VK_S || String.fromCharCode(e.charCode).toUpperCase() == "S") && e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey ) { e.preventDefault(); e.stopPropagation(); if(e.type == "keydown") { var window = e.currentTarget; window.editor.updateButton(); } } }, loadOverlays: function() { this.runGenerator(this.loadOverlaysGen, this, arguments); }, get loadOverlaysGen() { var fn = this._loadOverlaysGen.toString() .replace(/__yield/g, "yield"); try { new Function("function test() { yield 0; }"); } catch(e) { // Firefox 58+: SyntaxError: yield expression is only valid in generators fn = fn.replace("function", "function*"); // Firefox 26+ } delete this.loadOverlaysGen; return this.loadOverlaysGen = eval("(" + fn + ")"); }, _loadOverlaysGen: function loadOverlaysGen(window, callback/*, overlayData1, ...*/) { var gen = loadOverlaysGen.__generator; for(var i = 2, l = arguments.length; i < l; ++i) { var overlayData = arguments[i]; this.loadOverlay(window, overlayData[0], overlayData[1], function() { gen.next(); }); __yield(0); } callback(); __yield(0); }, loadOverlay: function(window, uri, check, callback) { var document = window.document; var stopWait = Date.now() + 4500; window.setTimeout(function load() { _log("loadOverlay(): " + uri); var tryAgain = Date.now() + 800; try { document.loadOverlay(uri, null); } catch(e) { window.setTimeout(callback, 0); return; } window.setTimeout(function ensureLoaded() { if(check(window)) window.setTimeout(callback, 0); else if(Date.now() > stopWait) return; else if(Date.now() > tryAgain) window.setTimeout(load, 0); else window.setTimeout(ensureLoaded, 50); }, 50); }, 0); }, runGenerator: function(genFunc, context, args) { var gen = genFunc.apply(context, args); genFunc.__generator = gen; gen.next(); }, parseXULFromString: function(xul) { xul = xul.replace(/>\s+</g, "><"); try { return new DOMParser().parseFromString(xul, "application/xml").documentElement; } catch(e) { var dummy = document.createElement("dummy"); dummy.innerHTML = xul.trimLeft(); return dummy.firstChild; } } }; storage.set(watcherId, watcher); setTimeout(function() { watcher.init(watcher.REASON_STARTUP); }, 50); } function destructor(reason) { if(reason == "update" || reason == "delete") { watcher.destroy(watcher.REASON_SHUTDOWN); storage.set(watcherId, null); } } if( typeof addDestructor == "function" // Custom Buttons 0.0.5.6pre4+ && addDestructor != ("addDestructor" in window && window.addDestructor) ) addDestructor(destructor, this); else this.onDestroy = destructor; function ts() { var d = new Date(); var ms = d.getMilliseconds(); return d.toTimeString().replace(/^.*\d+:(\d+:\d+).*$/, "$1") + ":" + "000".substr(("" + ms).length) + ms + " "; } function _log(s) { Services.console.logStringMessage("[Custom Buttons :: Source Editor] " + ts() + s); } при редактировании во вкладке выдает скрытый текст ecurityError: The operation is insecure. button.js:219 initWindow chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button57@init line 1 > Function:219 handleEvent chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button57@init line 1 > Function:835 Просто при редактировании работает, но выдает SecurityError: The operation is insecure. button.js:219 initWindow chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button57@init line 1 > Function:219 handleEvent chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button57@init line 1 > Function:835 И последннее в кнопке скрытый текст Выделить код Код:// https://github.com/Infocatcher/Custom_Buttons/tree/master/Add_New_Buttons_After_This_Button // Add New Buttons After This Button button for Custom Buttons // (c) Infocatcher 2012, 2014 // version 0.1.2 - 2014-01-25 var cbs = custombuttons.cbService; var windowId = cbs.getWindowId(document.documentURI); var notificationPrefix = cbs.getNotificationPrefix(windowId); this.toggleEnabled = function() { this.checked = !this.checked; if("persist" in document) document.persist(this.id, "checked"); else // Firefox 63+ Services.xulStore.persist(this, "checked"); }; this.setAttribute("oncommand", "this.toggleEnabled();"); var observer = { button: this, observe: function(button, topic, data) { if(topic != notificationPrefix + "installButton") return; if(!this.button.checked) return; var toolbar = this.button.parentNode; toolbar.insertBefore(button, this.button.nextSibling); custombuttons.persistCurrentSets(toolbar.id, this.button.id, button.id || button.getAttribute("id")); } }; var os = Components.classes["@mozilla.org/observer-service;1"] .getService (Components.interfaces.nsIObserverService); os.addObserver(observer, notificationPrefix + "installButton", false); var hasObserver = true; this.onDestroy = function(reason) { if(hasObserver) { hasObserver = false; os.removeObserver(observer, notificationPrefix + "installButton"); } if(reason == "delete" && this.checked) this.toggleEnabled(); }; не создается кнопка рядом с текущей Не могли бы Вы глянуть? |
Dumby > 17-12-2019 19:46:20 |
Andrey_Krropotkin пишет
Эта та кнопка, которой я пользуюсь сам, и там много чего уже накопилось. скрытый текст Выделить код Код:// https://forum.mozilla-russia.org/viewtopic.php?id=56040 // http://infocatcher.ucoz.net/js/cb/cbEditorToggleOnTop.js // https://github.com/Infocatcher/Custom_Buttons/tree/master/CB_Editor_Toggle_on_Top // Custom Buttons Editor: Toggle on Top button for Custom Buttons // (code for "initialization" section) // (c) Infocatcher 2012-2015 // version 0.1.11 - 2015-06-04 // Hotkey: Ctrl+T const watcherId = "customButtonsToggleOnTop_" + this.id; var {Components} = window; // Prevent garbage collection in Firefox 3.6 and older var storage = (function() { if(!("Services" in window)) // Firefox 3.6 and older return Application.storage; // Simple replacement for Application.storage // See https://bugzilla.mozilla.org/show_bug.cgi?id=1090880 //var global = Components.utils.getGlobalForObject(Services); // Ensure, that we have global object (because window.Services may be overwritten) var global = Components.utils.import("resource://gre/modules/Services.jsm", {}); var ns = "_cbEditorToggleOnTopStorage"; // Note: Firefox 57+ returns NonSyntacticVariablesObject w/o .Object property var storage = global[ns] || (global[ns] = Components.utils.getGlobalForObject(global).Object.create(null)); return { get: function(key, defaultVal) { if(key in storage) return storage[key]; return defaultVal; }, set: function(key, val) { if(key === null) delete storage[key]; else storage[key] = val; } }; })(); var watcher = storage.get(watcherId, null); if(!watcher) { watcher = { btnPos: 0, // 0 - at top right window corner, 1 - at end of tabs, 2 - before dialog buttons spacer btnStyle: "button", // "button" or "toolbarbutton" btnChecked: true, // use "checked" style: true or false // Fogue icons, http://p.yusukekamiyamane.com/ // http://www.iconfinder.com/icondetails/12276/16/gps_location_pin_icon icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AgNBjAx4SevkwAAAjxJREFUKM+FUk1oE0EU/mZnRU0U6cFLIT1KKkkNpIcSWwUvVty2l142hZpDoQcPgYQKQkUEz6V6sHgR/KGQQwleQg/xEKRRsIEmga4NoZa2oRGKpJaWmp2Z52UX12Dxg4838+D73ps3jzUYQycIgDc7l0oNAkgqpZ4n5uc/NgHsEEHDKZB/X5OJRGJcSplemJ6+6SZPFStvJ0Ta4eEhTNMcE0I8fDsxcQsAdPwHc6nUoBRCOz4+Rr1eR39//+18Pn/h/cjIGea+eS6VegLgKoBfRPRdKbXGOf8GIBmPx8cty0Kz2YTf74ff70cmkynpNSIAwP7+/t2ZmZnowcGBPDo6+rm1tdWo1Wo7pmnesSwLtm2jWCx+EkJwKSUnoln2wWnv9eTkMBE9TafT0b29PbTbbXDO0Wq1YNs2lpaWVpVSj8ZyuWXhaPg953CtXK6v9fVtr6ys9A4NDXU3Gg24JoVC4fPJycnjsVxu2TtMzgCUAVQAUKVSrwDtzc3NQCQS6d7d3XU7EK1W62twY+ML84i1N4zB5TvgYrVaPTs1NRXNZDKlrq4u+Hw+BAKBy1LK6zYA2xE+6/gqzhgbXl9fnw+FQrPBYPCHlBKjo6NRIjpPRD3kEdbcJWGMgTF2Y3Fx8UE4HE4yxl70WtYCEc1ms9kS51wDcM4r/FOS87BhGK90XTc0TeNuPgggFosNG4axOjAw8PJKxwIxAD26rt9XShWVUtvOWosO2h1RAJAMwCUAPseInGG6UTlm6l/8DZ+nFuAjSdH0AAAAAElFTkSuQmCC", iconPinned: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAPCAYAAAA71pVKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3AgNBjIpwH1VRwAAAgdJREFUKM+FkkFoU0EQhr/dtxFSquLBS8CAICISQci1oBWLKaaINL300psXDxH0ItSD4L21UKgUxV4aWnKyiIGaQwio2IQ0PQQpBaEhoaEk0dSQNsnb9WAepg+LPwz/7DD/7O7MiJIQuGEAV3QIiNowV4f0HlA0BskJsI8fo75YLHIEjw3ccIInivVxX1IqcXFu7l4Lnhq4BaD4P4Y6INsHB+zlcpwfH7+zG48PavCIvj8/B64CRxoqXdg8Bd+BqG9xMVJNpaiUy5zxehkcGCC2uppV28Y44rs3V1aCFIt2p15v/MzlSj/S6eKlmZnRairFoW2zmUx+boHVBsvAtEj+fV5Iw4vbS0tBe2uLw04H2+ulUy5zaNu8X17OdOGZgkTX3TADCRumP0xNZY3fz6/9fSr5PNVGg6/x+BfdE/Y3wxJAHtj6wzt5aHsSiQv+4WFfbWcHu9VCeDzdRq32DdgQfZMQom9JjDGngcn19fWF2shI9vrYWNBqNjFCND8mk+8MTDq5s65RWUKIUKFQmA0EAtP3pawdra0xGokE0dqrwe8kvgS2e1cjpURKORyLxTaUUg+UUuciUvIWQq8hU5uYMPOQmQcuu7fAsqxr4XD4jVIqLKW0nPgV4AmEFiDzCF65hQLwK6Ueaq0/aa13e2vddVnHxV3AFsBZYKBXyPSa6bDuFdP/st/BfOD54p3eIQAAAABJRU5ErkJggg==", boxId: "cbToggleOnTopBox", btnId: "cbToggleOnTopButton", onTopAttr: "cbOnTop", naAttr: "cbOnTopNA", styleId: "cbToggleOnTopStyle", get btnTip() { var locale = (function() { if("Services" in window && "locale" in Services) { var locales = Services.locale.requestedLocales // Firefox 64+ || Services.locale.getRequestedLocales && Services.locale.getRequestedLocales(); if(locales) return locales[0]; } var prefs = "Services" in window && Services.prefs || Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefBranch); function pref(name, type) { return prefs.getPrefType(name) != prefs.PREF_INVALID ? prefs["get" + type + "Pref"](name) : undefined; } if(!pref("intl.locale.matchOS", "Bool")) { // Also see https://bugzilla.mozilla.org/show_bug.cgi?id=1414390 var locale = pref("general.useragent.locale", "Char"); if(locale && locale.substr(0, 9) != "chrome://") return locale; } return Components.classes["@mozilla.org/chrome/chrome-registry;1"] .getService(Components.interfaces.nsIXULChromeRegistry) .getSelectedLocale("global"); })().match(/^[a-z]*/)[0]; if(locale == "ru") return "Поверх всех окон (Ctrl+T)"; return "Always on top (Ctrl+T)"; }, REASON_STARTUP: 1, REASON_SHUTDOWN: 2, REASON_WINDOW_LOADED: 3, REASON_WINDOW_CLOSED: 4, get obs() { delete this.obs; return this.obs = Components.classes["@mozilla.org/observer-service;1"] .getService(Components.interfaces.nsIObserverService); }, get ww() { delete this.ww; return this.ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] .getService(Components.interfaces.nsIWindowWatcher); }, get wm() { delete this.wm; return this.wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] .getService(Components.interfaces.nsIWindowMediator); }, init: function(reason) { this.obs.addObserver(this, "quit-application-granted", false); var ws = this.wm.getEnumerator(null); while(ws.hasMoreElements()) this.initWindow(ws.getNext(), reason); this.ww.registerNotification(this); }, destroy: function(reason) { this.obs.removeObserver(this, "quit-application-granted"); var ws = this.wm.getEnumerator(null); while(ws.hasMoreElements()) this.destroyWindow(ws.getNext(), reason); this.ww.unregisterNotification(this); }, checkOnTopAttr: function(window) { if(this.version < 71) return this.checkOnTopAttr = function() {} var attr = this.onTopAttr; var id = window.document.documentElement.id; var xs = Cu.import("resource://gre/modules/Services.jsm", {}) .Services.xulStore; (this.checkOnTopAttr = function(window) { var de = window.document.documentElement; if(de.hasAttribute(attr)) return; var url = window.location.href; if(xs.hasValue(url, id, attr)) de.setAttribute(attr, xs.getValue(url, id, attr)); })(window); }, initWindow: function(window, reason) { if(!this.isTargetWindow(window)) return; window.addEventListener("keypress", this, true); if(this.hasSizeModeChangeEvent) window.addEventListener("sizemodechange", this, false); else { window.addEventListener("resize", this, false); // Can detect only maximize/restore this.legacySizeModeChange(window); } this.checkOnTopAttr(window); var document = window.document; this.removeStyle(document); this.addStyle(document); var box = document.getElementById(this.boxId); box && box.parentNode.removeChild(box); box = document.createElementNS(xulns, "hbox"); box.id = this.boxId; var btn = document.createElementNS(xulns, this.btnStyle); btn.id = this.btnId; if(this.btnChecked) { btn.setAttribute("type", "checkbox"); btn.setAttribute("autoCheck", "false"); } btn.tooltipText = this.btnTip; btn.addEventListener("command", this, false); box.appendChild(btn); switch(this.btnPos) { default: box.setAttribute("cbOnTopFloat", "true"); document.documentElement.appendChild(box); break; case 1: box.setAttribute("align", "right"); let tabbox = document.getElementById("custombuttons-editbutton-tabbox"); let tabs = tabbox.getElementsByTagName("tabs")[0]; tabs.parentNode.insertBefore(box, tabs); box.style.marginBottom = -(btn.boxObject || btn.getBoundingClientRect()).height + "px"; break; case 2: box.setAttribute("align", "center"); let btnBox = document.documentElement.getButton("accept").parentNode; let insPos = btnBox.firstChild; for(let node = insPos; node; node = node.nextSibling) { if(node.localName == "spacer") { insPos = node; break; } } btnBox.insertBefore(box, insPos); } this.checkWindowStatus(window, box); //this.setOnTop(btn); }, destroyWindow: function(window, reason) { if(reason == this.REASON_WINDOW_CLOSED) window.removeEventListener("DOMContentLoaded", this, false); // Window can be closed before DOMContentLoaded if(!this.isTargetWindow(window)) return; window.removeEventListener("keypress", this, true); if(this.hasSizeModeChangeEvent) window.removeEventListener("sizemodechange", this, false); else window.removeEventListener("resize", this, false); var document = window.document; var btn = this.shadow(document).getElementById(this.btnId); btn.removeEventListener("command", this, false); if(reason == this.REASON_SHUTDOWN) { let box = btn.parentNode; box.parentNode.removeChild(box); this.removeStyle(document); let xulWin = this.getXulWin(window); xulWin.zLevel = xulWin.normalZ; } }, isTargetWindow: function(window) { return window.location.href.substr(0, 41) == "chrome://custombuttons/content/editor.xul"; }, observe: function(subject, topic, data) { if(topic == "quit-application-granted") this.destroy(); else if(topic == "domwindowopened") subject.addEventListener("DOMContentLoaded", this, false); else if(topic == "domwindowclosed") this.destroyWindow(subject, this.REASON_WINDOW_CLOSED); }, handleEvent: function(e) { var trg = e.originalTarget || e.target; var window; switch(e.type) { case "DOMContentLoaded": window = trg.defaultView; window.removeEventListener("DOMContentLoaded", this, false); this.initWindow(window, this.REASON_WINDOW_LOADED); break; case "keypress": if( !( (e.ctrlKey || e.metaKey) && !e.altKey && !e.shiftKey && String.fromCharCode(e.charCode).toLowerCase() == "t" ) ) break; e.preventDefault(); e.stopPropagation(); case "command": window = trg.ownerDocument.defaultView.top; this.toggleOnTop(window); break; case "sizemodechange": case "resize": window = trg; this.checkWindowStatus(window); } }, version: 0, get hasSizeModeChangeEvent() { var appinfo = "Services" in window && Services.appinfo; delete this.hasSizeModeChangeEvent; return this.hasSizeModeChangeEvent = appinfo && ( appinfo.name == "Pale Moon" || (this.version = parseFloat(appinfo.platformVersion)) >= 8 ); }, legacySizeModeChange: function(window) { var lastState = window.windowState; window.setInterval(function(window, _this) { var state = window.windowState; if(state != lastState) _this.checkWindowStatus(window); lastState = state; }, 150, window, this); }, checkWindowStatus: function(window, box) { if(!box) box = this.shadow(window.document).getElementById(this.boxId); var na = String(window.windowState != window.STATE_NORMAL); if(box.getAttribute(this.naAttr) == na) return; box.setAttribute(this.naAttr, na); //LOG("Set n/a: " + na); this.setOnTop(box.firstChild); }, addStyle: function(document) { var style = '\ %box%[cbOnTopFloat] {\n\ display: block !important;\n\ position: fixed !important;\n\ top: 0 !important;\n\ right: 0 !important;\n\ }\n\ %btn%, %btn% * {\n\ margin: 0 !important;\n\ padding: 0 !important;\n\ }\n\ %btn% > .button-box > .button-icon {\n\ margin: -3px -1px !important;\n\ }\n\ toolbarbutton%btn% {\n\ padding: 0 2px !important;\n\ }\n\ %btn% {\n\ position: relative !important;\n\ z-index: 2147483647 !important;\n\ list-style-image: url("%icon%") !important;\n\ -moz-user-focus: ignore !important;\n\ min-height: 0 !important;\n\ min-width: 0 !important;\n\ }\n\ %btn%[%onTopAttr%="true"] {\n\ list-style-image: url("%iconPinned%") !important;\n\ }\n\ %box%[%naAttr%="true"] image {\n\ opacity: 0.75 !important;\n\ }' .replace(/%box%/g, "#" + this.boxId) .replace(/%btn%/g, "#" + this.btnId) .replace(/%onTopAttr%/g, this.onTopAttr) .replace(/%icon%/g, this.icon) .replace(/%iconPinned%/g, this.iconPinned) .replace(/%naAttr%/g, this.naAttr); if(this.shadow(document, style)) return; document.insertBefore(document.createProcessingInstruction( "xml-stylesheet", 'id="' + this.styleId + '" href="' + "data:text/css," + encodeURIComponent(style) + '" type="text/css"' ), document.documentElement); }, removeStyle: function(document) { if(this.shadow(document, false)) return; var mark = 'id="' + this.styleId + '"'; for(var child = document.documentElement; child = child.previousSibling; ) { if( child.nodeType == child.PROCESSING_INSTRUCTION_NODE && child.data.substr(0, mark.length) == mark ) { document.removeChild(child); break; } } }, shadow: function(document, arg) { var sr = document.documentElement.shadowRoot; if(this.btnPos != 2 || !sr) return (this.shadow = function(document, arg) { return arg === undefined ? document : false; })(document, arg); if(arg === undefined) return sr; var st = sr.querySelector("style"), id = this.styleId; if(arg) { st.append(arg); st.lastChild[id] = true; } else { var tn = Array.from(st.childNodes).find(function(node) { return id in node; }); tn && tn.remove(); } return true; }, getXulWin: function(window) { return ( window.docShell && window.docShell instanceof Components.interfaces.nsIDocShell ? window.docShell : window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShellTreeItem) ) .treeOwner .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIXULWindow || Ci.nsIAppWindow); }, setOnTop: function(btn, toggle) { var document = btn.ownerDocument; var root = document.documentElement; var onTop = root.getAttribute(this.onTopAttr) == "true"; if(toggle) { onTop = !onTop; root.setAttribute(this.onTopAttr, onTop); if(root.id) { if("persist" in document) document.persist(root.id, this.onTopAttr); else // Firefox 63+ Services.xulStore.persist(root, this.onTopAttr); } } else if(!onTop) // Just opened or restored window always have zLevel == normalZ return; var window = document.defaultView; var state = window.windowState; // Strange glitches with minimized "raisedZ" window... var restore = onTop && state == window.STATE_MINIMIZED; if(restore || state == window.STATE_NORMAL) { if(restore) onTop = false; let xulWin = this.getXulWin(window); xulWin.zLevel = onTop ? xulWin.raisedZ : xulWin.normalZ; //LOG("Set on top: " + onTop); } this.checkButton(btn, onTop); }, toggleOnTop: function(window) { this.setOnTop(this.shadow(window.document).getElementById(this.btnId), true); }, checkButton: function(btn, onTop) { btn.setAttribute(this.onTopAttr, onTop); this.btnChecked && btn.setAttribute("checked", onTop); } }; storage.set(watcherId, watcher); watcher.init(watcher.REASON_STARTUP); } function destructor(reason) { if(reason == "update" || reason == "delete") { watcher.destroy(watcher.REASON_SHUTDOWN); storage.set(watcherId, null); } } if( typeof addDestructor == "function" // Custom Buttons 0.0.5.6pre4+ && addDestructor != ("addDestructor" in window && window.addDestructor) ) addDestructor(destructor, this); else this.onDestroy = destructor; Остальными двумя не пользуюсь, но, похоже, здесь это пресловутое западло. Задело многое, в своё время даже их дражайший Firefox Screenshots под раздачу угодил. Вобщем, парочка не слишком оптимальных фиксов, чтоб проверить для CB_Source_Editor Выделить код Код:var ps = this.parseXULFromString(psXUL); if(isFrame && "parseFromSafeString" in window.DOMParser.prototype) ps = window.MozXULElement.parseXULToFragment(ps.outerHTML); document.documentElement.appendChild(ps); для Add_New_Buttons_After_This_Button Выделить код Код://toolbar.insertBefore(button, this.button.nextSibling); toolbar.insertBefore( custombuttons.cbCloneNode(button), this.button.nextSibling ); |
Andrey_Krropotkin > 17-12-2019 20:01:12 |
Dumby да все работает, спасибо. |
Infocatcher > 19-12-2019 00:10:15 |
Dumby 19-12-2019 00:11:24 |
Dumby > 06-01-2020 16:28:39 |
Infocatcher По всему коду лазать не стал, записал всё про контекстное меню скрытый текст Выделить код Код:var SourceEditor = window.SourceEditor; if(this.platformVersion >= 73) { var psXUL = '<popupset id="sourceEditorPopupset">\ <linkset>\ <html:link rel="localization" href="toolkit/global/textActions.ftl" />\ </linkset>\ <menupopup id="sourceEditorContext"\ onpopupshowing="popupHandler(event.target)"\ oncommand="popupHandler(event.target)">\ \ <menuitem id="menu_undo" data-l10n-id="text-action-undo" />\ <menuitem id="menu_redo" data-l10n-id="text-action-redo" />\ <menuseparator/>\ <menuitem id="menu_cut" data-l10n-id="text-action-cut" />\ <menuitem id="menu_copy" data-l10n-id="text-action-copy" />\ <menuitem id="menu_paste" data-l10n-id="text-action-paste" />\ <menuitem id="menu_delete" data-l10n-id="text-action-delete" />\ <menuseparator/>\ <menuitem id="menu_selectAll" data-l10n-id="text-action-select-all" />\ <menuseparator/>\ <menuitem id="menu_find" label="&findCmd.label;" accesskey="&findCmd.accesskey;" />\ <menuitem id="menu_findAgain" label="&findAgainCmd.label;" accesskey="&findAgainCmd.accesskey;" />\ <menuseparator/>\ <menuitem id="se-menu-gotoLine" label="&gotoLineCmd.label;"\ accesskey="&gotoLineCmd.accesskey;" key="key_gotoLine" />\ </menupopup>\ </popupset>'; var ps = window.MozXULElement.parseXULToFragment(psXUL, [ "chrome://global/locale/editMenuOverlay.dtd", "chrome://devtools/locale/sourceeditor.dtd" ]); if(!this.popupHandler) { var commands = {module: {}}; ps.querySelectorAll("menuitem").forEach(function(menuitem) { commands[menuitem.id] = menuitem.id.replace(/^(se-)?menu./, "cmd_"); }); Services.scriptloader.loadSubScript( "resource://devtools/client/shared/sourceeditor/editor-commands-controller.js", commands ); var createController = function(editor) { var res = editor.popupCmdController = commands.createController(editor); res.docShell = editor.container.contentWindow.docShell; return res; } var getObj = function(cmd, controller) { return controller.supportsCommand(cmd) ? controller: controller.docShell; } var setDisabled = function(menuitem) { var cmd = commands[menuitem.id]; menuitem.disabled = !getObj(cmd, this).isCommandEnabled(cmd); } this.popupHandler = function(node) { var ed = node.ownerDocument.activeElement.contentWindow.editor; var controller = ed.popupCmdController || createController(ed); var cmd = commands[node.id]; if(cmd) getObj(cmd, controller).doCommand(cmd); else node.menuitems.forEach(setDisabled, controller); } } var popup = ps.querySelector("menupopup"); popup.menuitems = popup.querySelectorAll("menuitem"); popup.popupHandler = this.popupHandler; } else { // See view-source:chrome://browser/content/devtools/scratchpad.xul // + view-source:chrome://browser/content/devtools/source-editor-overlay.xul var psXUL = (isCodeMirror // ....... } document.documentElement.appendChild(ps); Но я не об этом. Лисе сделали XUL content type лоботомию, и теперь И вот здесь нарисовалась какая-то нестыковка. Так вот, если воспроизводится, хотел попросить добавить скрытый текст Выделить код Код://initWindow: function(window, reason, isFrame) { initWindow: function(window, reason, isFrame, again) { if(this.isBrowserWindow(window)) { this.initBrowserWindow(window, reason); return; } if(!this.isEditorWindow(window)) return; if(!again && !isFrame && window.document.contentType == "text/xml") { window.setTimeout(function(_this) { _this.initWindow(window, reason, isFrame, true); }, 0, this); return; } _log("initWindow(): isFrame: " + isFrame); P.S. Да, DOMi тоже ведь .xul dom_inspector-7.0.6-fx-paxmod.xpi dom_inspector-7.0.6-fx-bootstrap.xpi |
Infocatcher > 07-01-2020 23:08:25 |
Dumby пишет
Упс. Выделить код Код:if(!again && !isFrame && window.document.contentType == "text/xml") { // Firefox 73+ //window.setTimeout(function(_this) { // _this.initWindow(window, reason, isFrame, true); //}, 0, this); Services.tm.mainThread.dispatch(function() { this.initWindow(window, reason, isFrame, true); }.bind(this), Components.interfaces.nsIThread.DISPATCH_NORMAL); return; } Но на глаз все равно есть задержка (хотя она и от самого CodeMirror'а). А с меню надо бы еще посмотреть, куда и как доотламывать будут. Хотя, наверное, это еще локализации не обновились. |
Andrey_Krropotkin > 08-01-2020 19:03:39 |
Infocatcher на 72 обновил кнопки с вашей страницы: |
Dumby > 08-01-2020 23:20:00 |
Andrey_Krropotkin пишет
Там таймаут надо поднимать. скрытый текст Выделить код Код:css("resource://devtools/client/themes/variables.css"); css("resource://devtools/client/themes/common.css"); css("chrome://devtools/skin/tooltips.css"); if(this.platformVersion >= 68) { var eKey = "styleSheetChangeEventsEnabled"; var notVal = !document[eKey]; if(notVal) document[eKey] = true; document.addEventListener("StyleSheetApplicableStateChanged", function change(e) { var sheet = e.stylesheet; if(sheet.href != "resource://devtools/client/themes/common.css") return; document.removeEventListener(e.type, change); if(notVal && document[eKey]) document[eKey] = false; for(var i = 0, len = sheet.cssRules.length; i < len; ++i) if(sheet.cssRules[i].selectorText == "::selection") { sheet.deleteRule(i); break; } }); } |
Dumby > 09-01-2020 00:08:58 |
Andrey_Krropotkin пишет
Решаемая в этом месте кода проблема с тултипом, Может так скрытый текст |
Infocatcher > 09-01-2020 00:14:38 |
Andrey_Krropotkin пишет
(Долго я писал, да...) Andrey_Krropotkin пишет
Там все печально, в браузере браузер (вкладочный) с браузером (с содержимым). Я начал делать, но все ссылки на элементы управления в менеджере дополнений отломались: Какой-то неработающий черновик Выделить код Код:--- a/checkForAddonsUpdates.js +++ b/checkForAddonsUpdates.js @@ -169,8 +169,6 @@ } progressIcon.loading(); - var inProgress = $("updates-progress"); - btn.tooltipText = inProgress.getAttribute("value"); var origIcon = tab.image; tab.image = image; @@ -180,12 +178,36 @@ if(!updEnabled) Services.prefs.setBoolPref(updEnabledPref, true); - var notFound = $("updates-noneFound"); - var updated = $("updates-installed"); + var fu = $("cmd_findAllUpdates"); + if(!fu) { // Firefox 72+ + var win = doc.defaultView; + var vb = doc.getElementById("html-view-browser"); + if(!vb) { + win.setTimeout(processAddonsTab, 20, win); + return; + } + var vbDoc = vb.contentDocument; + fu = vbDoc.querySelector('[action="check-for-updates"]'); + } + + var notFound = $("updates-noneFound"); //~fixme + var updated = $("updates-installed"); //~fixme // Avoid getting false results from the past update check (may not be required for "noneFound") - notFound.hidden = updated.hidden = true; + //~fixme notFound.hidden = updated.hidden = true; - $("cmd_findAllUpdates").doCommand(); + //fu.doCommand(); + fu.click(); + + var inProgress = $("updates-progress"); + if(!inProgress) { // Firefox 72+ + var um = vbDoc.getElementById("updates-message"); + inProgress = um.shadowRoot.querySelector('[data-l10n-id="addon-updates-updating"]'); + if(!inProgress) { + win.setTimeout(processAddonsTab, 5, win); + return; + } + } + btn.tooltipText = inProgress.getAttribute("value") || inProgress.textContent; var waitTimer = setInterval(function() { if(!doc.defaultView || doc.defaultView.closed) { |
Andrey_Krropotkin > 09-01-2020 13:44:59 |
Dumby пишет
работает без ошибок Infocatcher пишет
работает без ошибок Infocatcher пишет
если сначала нажимаю на кнопку выдает ошибки Если сначала открываю вкладку Управление дополнениями и затем нажимаю на кнопку, то находит обновления, но все равно кнопка и вкладка зацикливаются и выдают только вторую ошибку, если после этого закрываю вкладку, то выскакивает сообщение "Tab with addon-manager was closed" и тогда кнопка перестает работать Не знаю поможет Вам или нет - вот на www.camp-firefox.de нашел работающий кусок кода скрытый текст Выделить код Код:let frameScript = function() { addEventListener('pageshow', function onPageshow(event) { let document = event.target; if (document.URL != 'about:addons') return; removeEventListener('pageshow', onPageshow); content.setTimeout(function() { content.getHtmlBrowser().contentDocument.querySelector('[action="check-for-updates"]').click(); let item = document.getElementById('category-availableUpdates'); item.click(); let categories = item.parentNode; categories.addEventListener('mousedown', function onMousedown(event) { if (event.target != item && event.target.parentNode != item) { item.hidden = true; categories.removeEventListener('mousedown', onMousedown); }; }); }, 0); }); }; let frameScriptURI = 'data:,(' + frameScript.toString() + ')()'; let window = event.target.ownerGlobal; window.openTrustedLinkIn('about:addons', 'tab'); window.gBrowser.selectedBrowser.messageManager.loadFrameScript(frameScriptURI, true); |
Dumby > 09-01-2020 14:35:52 |
Хочу добавить про Toggle on Top, раз обсуждалось. В Firefox 72 переписали использование [align="right"], Причём, переписали неправильно, затем исправили, Таким образом, наверно так скрытый текст Выделить код Код:case 1: //box.setAttribute("align", "right"); if(this.platformVersion >= 72) box.setAttribute("pack", "end"); else box.setAttribute("align", "right"); |
Infocatcher > 12-01-2020 23:24:54 |
Dumby пишет
Спасибо! Обновил. Dumby пишет
Чик-чик – и в продакшн! © 12-01-2020 23:35:00 Выделить код Код:tabs.parentNode.insertBefore(box, tabs); LOG("xxx " + window.getComputedStyle(btn, null).height); LOG("xxx " + btn.getBoundingClientRect().height); setTimeout(function() { LOG("xxx " + window.getComputedStyle(btn, null).height); LOG("xxx " + btn.getBoundingClientRect().height); }, 5); box.style.marginBottom = -(btn.boxObject || btn.getBoundingClientRect()).height + "px"; |
Infocatcher > 24-01-2020 20:48:58 |
Какой-то обложенный распорками Check for Addons Updates: |
voqabuhe > 24-01-2020 22:05:56 |
Infocatcher пишет
А почему в этой теме, а не в [CB]Check for Addons Updates | Форум Mozilla Россия ? |
Infocatcher > 24-01-2020 22:09:24 |
voqabuhe |
Andrey_Krropotkin > 20-03-2020 23:30:52 |
Infocatcher что то я не нашел тему про "Edit_Custom_Button_in_Tab" у меня на 74 она до сих пор работает. Поэтому задам здесь. Если есть отдельная тема - то покажите. Вопрос в следующем. Код работает нормально, но выскивает ошибка в консоли не на что не влияющая - скрытый текст Выделить код Код:// http://infocatcher.ucoz.net/js/cb/editCustomButtonInTab.js // https://github.com/Infocatcher/Custom_Buttons/tree/master/Edit_Custom_Button_in_Tab // Edit Custom Button in Tab button for Custom Buttons // (code for "initialization" section) // (c) Infocatcher 2012-2014 // version 0.1.8.3 - 2014-01-12 // Note: // In Firefox 3.6 and older: // - Force enables "Save size and position of editor windows separately for each custom button" // option for editor in tab (because doesn't work without this) // - tab with editor can't be closed sometimes using OK/Cancel buttons var editInTabLabel = (function() { var locale = (function() { if("Services" in window && "locale" in Services) { var locales = Services.locale.requestedLocales // Firefox 64+ || Services.locale.getRequestedLocales && Services.locale.getRequestedLocales(); if(locales) return locales[0]; } var prefs = "Services" in window && Services.prefs || Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefBranch); function pref(name, type) { return prefs.getPrefType(name) != prefs.PREF_INVALID ? prefs["get" + type + "Pref"](name) : undefined; } if(!pref("intl.locale.matchOS", "Bool")) { // Also see https://bugzilla.mozilla.org/show_bug.cgi?id=1414390 var locale = pref("general.useragent.locale", "Char"); if(locale && locale.substr(0, 9) != "chrome://") return locale; } return Components.classes["@mozilla.org/chrome/chrome-registry;1"] .getService(Components.interfaces.nsIXULChromeRegistry) .getSelectedLocale("global"); })().match(/^[a-z]*/)[0]; if(locale == "ru") return "Редактировать во вкладке…"; return "Edit button in tab…"; })(); const editorBaseUri = "chrome://custombuttons/content/editor.xul"; const cbIdTabAttr = "custombuttons-editInTab-id"; const editId = "custombuttons-contextpopup-edit"; const editInTabId = editId + "InTab"; var editInTab = document.getElementById(editInTabId); if(editInTab) editInTab.parentNode.removeChild(editInTab); var editItem = document.getElementById(editId); editInTab = editItem.cloneNode(true); editInTab.id = editInTabId; editInTab.setAttribute("cb_id", editInTabId); editInTab.setAttribute("label", editInTabLabel); editInTab.setAttribute("oncommand", "editCustomButtonInTab();"); if(!Object.create) // Firefox 3.6 and older editInTab.removeAttribute("observes"); editInTab.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAitJREFUeNrEk0tIVVEUhr99zrnHc1+SkYQVFWo20G6SgkFRDorEILFJDoogkoLoXfOopEZCYIFlIITlRIUiC5UmFZVk1igwCAozfD9uat17z97tc5XK0pGDFiz289/rXz//FkopFhMGiwyr5GoHHgkpZUnCde9LqXwwHyuR3HVNIzZpGrubbLtjfHwYyzvywIYpHp0o386ajAAD3/R1MRfugZeFoGcgbm9pedo+7VVVCMvTwKt8tGwrfXGb5mfRJFj8VV0Ki7hpk9t5gW35lYx9GcSZGFOGSjJQvuXpYd4PTLPUYU6m+Q1SgzbBkEPey0tUHjlJfU8j0c8j+Aa/ahFn2x2cdknVgLBfpx5DyTQIBGx8+oHjras4vX8DtfWNFG0q4gmPyas9VqgZqEbNAEvPUnW1sCMI+QVBPXc02Ar5ONiURW55NsHus1TkjNDW2srHdYcormo/Z2kG+0p35BPTfaaHrVnBBAmt75QwKK3LYuPetdDbDxMTdHc2ELn4gfWj32l+MFQhdla1KVdKpCvxBPXAcWUSlQEaYgeIlK2GvmENHuHOmxVcW3mLoDuqn09gGjNiF8xnEPWw+DUFpTA0BS+uc/tdDodrnhf+445dV9p/LaQw+SH8nBfVRBMpKi0zm5LIEupq7lF541Vhy6lIV3XGTRw5qdWXM078bRSBK3zs6b3MWxEgplxSPnWS2e8kwXfPbO4SanIefy4cf7bWtdAl8d9/408BBgBVmNFVzOyEfgAAAABJRU5ErkJggg=="); editItem.parentNode.insertBefore(editInTab, editItem.nextSibling); Array.prototype.filter.call( // Process already cloned menu items document.getElementsByAttribute("observes", editItem.getAttribute("observes")), function(mi) { var id = mi.id || ""; return mi != editItem && id.substr(0, editId.length) == editId && id.substr(0, editInTabId.length) != editInTabId; } ).forEach(function(editItem, i) { var clone = editInTab.cloneNode(true); clone.id += "-cloned-" + i; editItem.parentNode.insertBefore(clone, editItem.nextSibling); }); // Process #custombuttons-contextpopup-sub const editIdSub = editId + "-sub"; var editItemSub = document.getElementById(editIdSub); if(editItemSub) { var clone = editInTab.cloneNode(true); if(editItemSub.hasAttribute("observes")) clone.setAttribute("observes", editItemSub.getAttribute("observes")); else clone.removeAttribute("observes"); clone.id += "-sub"; editItemSub.parentNode.insertBefore(clone, editItemSub.nextSibling); } window.editCustomButtonInTab = function(btn, newTab) { // Should be global to work in cloned menus if(!btn) btn = custombuttons.popupNode; if(!btn) return; var btnId = btn.id; var link = custombuttons.makeButtonLink("edit", btnId); var cbService = "cbICustomButtonsService" in Components.interfaces ? Components.classes["@xsms.nm.ru/custombuttons/cbservice;1"] .getService(Components.interfaces.cbICustomButtonsService) : Components.classes["@xsms.nm.ru/custombuttons/cbservice;1"] // Custom Buttons 0.0.5.9+ .getService(Components.interfaces.nsISupports) .wrappedJSObject; var param = cbService.getButtonParameters(link); var editorUriFull = editorBaseUri + "?window=" + cbService.getWindowId(document.documentURI) + "&id=" + btnId; var editorUri = cbService.mode & 64 /*CB_MODE_SAVE_EDITOR_SIZE_SEPARATELY*/ || !Object.create // Firefox 3.6 and older ? editorUriFull : editorBaseUri; // Search for already opened tab var rawParam = unwrap(param); var isSeaMonkey = "Services" in window && Services.appinfo.name == "SeaMonkey"; var ws = Components.classes["@mozilla.org/appshell/window-mediator;1"] .getService(Components.interfaces.nsIWindowMediator) .getEnumerator(isSeaMonkey ? null : "navigator:browser"); while(ws.hasMoreElements()) { let win = ws.getNext(); if(isSeaMonkey && win.location.href != "chrome://navigator/content/navigator.xul") continue; let gBrowser = win.gBrowser; let tabs = gBrowser.tabs || gBrowser.tabContainer.childNodes; for(let i = 0, l = tabs.length; i < l; ++i) { let tab = tabs[i]; if(tab == newTab) continue; let browser = tab.linkedBrowser; if(!browser) continue; let loc = browser.currentURI.spec; if(loc.substr(0, editorBaseUriLength) != editorBaseUri) continue; let isSameEditor = loc == editorUriFull || tab.getAttribute(cbIdTabAttr) == btnId; let win = browser.contentWindow; // Will be null for unloaded tab if(!isSameEditor && win) { let rawWin = unwrap(win); let winParam = "arguments" in rawWin && rawWin.arguments.length ? unwrap(rawWin.arguments[0]) : rawWin.editor && rawWin.editor.param; isSameEditor = winParam && winParam.buttonLink == link; } if(isSameEditor) { gBrowser.selectedTab = tab; win && win.focus(); newTab && setTimeout(function() { gBrowser.removeTab(newTab); }, 0); return; } } } // Or open new tab var tab = newTab; if(!tab) { tab = gBrowser.selectedTab = gBrowser.addTab(editorUri, { triggeringPrincipal: "Services" in window // Firefox 63+ && Services.scriptSecurityManager && Services.scriptSecurityManager.getSystemPrincipal() }); initSessionStore(); tab.setAttribute(cbIdTabAttr, btn.id); } var browser = tab.linkedBrowser; browser.addEventListener("DOMContentLoaded", function load(e) { var doc = e.target; if(doc.location != editorUri) return; browser.removeEventListener(e.type, load, false); var win = doc.defaultView; win.arguments = [param]; var iconLink = doc.createElementNS("http://www.w3.org/1999/xhtml", "link"); iconLink.rel = "shortcut icon"; //iconLink.href = "chrome://custombuttons-context/content/icons/default/custombuttonsEditor.ico"; iconLink.href = getStdImage(rawParam.image); iconLink.style.display = "none"; doc.documentElement.insertBefore(iconLink, doc.documentElement.firstChild); var alreadyAsked = false; function checkUnsaved(e) { if(alreadyAsked) return; var dlg = unwrap(doc).documentElement; if( "_fireButtonEvent" in dlg ? !dlg._fireButtonEvent("cancel") : !dlg.cancelDialog() ) e.preventDefault(); } function onDialogCancel(e) { alreadyAsked = true; // win.setTimeout shouldn't fire while confirmation dialog from the same window are opened win.setTimeout(function() { alreadyAsked = false; }, 100); } function destroy(e) { win.removeEventListener("dialogcancel", onDialogCancel, false); win.removeEventListener("beforeunload", checkUnsaved, false); win.removeEventListener("unload", destroy, false); } win.addEventListener("dialogcancel", onDialogCancel, false); win.addEventListener("beforeunload", checkUnsaved, false); win.addEventListener("unload", destroy, false); }, false); }; function unwrap(o) { return o.wrappedJSObject || o; // Firefox 3.6 and older } function getStdImage(iid) { if(/^custombuttons-stdicon-(\d)$/.test(iid)) switch(+RegExp.$1) { // chrome://custombuttons/skin/custombuttons.css // toolbarbutton[cb-stdicon="custombuttons-stdicon-*"] { ... } case 1: return "chrome://custombuttons/skin/button.png"; case 2: return "chrome://custombuttons/skin/stdicons/rbutton.png"; case 3: return "chrome://custombuttons/skin/stdicons/gbutton.png"; case 4: return "chrome://custombuttons/skin/stdicons/bbutton.png"; } return iid || "chrome://custombuttons/skin/button.png"; } function initSessionStore() { initSessionStore = function() {}; var ss = "nsISessionStore" in Components.interfaces ? ( Components.classes["@mozilla.org/browser/sessionstore;1"] || Components.classes["@mozilla.org/suite/sessionstore;1"] ).getService(Components.interfaces.nsISessionStore) : SessionStore; // Firefox 61+ https://bugzilla.mozilla.org/show_bug.cgi?id=1450559 ss.persistTabAttribute(cbIdTabAttr); } function checkTab(tab) { var cbId = tab.getAttribute(cbIdTabAttr); if(!cbId) return; initSessionStore(); let btn = document.getElementById(cbId); if(btn) editCustomButtonInTab(btn, tab); } const editorBaseUriLength = editorBaseUri.length; // We can't use only SSTabRestoring: user can reload tab with editor addEventListener("DOMContentLoaded", function(e) { var doc = e.target; if(doc.location.href.substr(0, editorBaseUriLength) != editorBaseUri) return; var tabs = gBrowser.tabs || gBrowser.tabContainer.childNodes; for(var i = 0, l = tabs.length; i < l; ++i) { let tab = tabs[i]; let browser = tab.linkedBrowser; if(browser && browser.contentDocument == doc) { checkTab(tab); break; } } }, true, document.getElementById("appcontent")); // Firefox 60+, gBrowser isn't a DOM node anymore checkTab(gBrowser.selectedTab); function destructor(reason) { if(reason == "update" || reason == "delete") { Array.prototype.slice.call(document.getElementsByAttribute("cb_id", editInTabId)).forEach(function(btn) { btn.parentNode.removeChild(btn); }); delete window.editCustomButtonInTab; } } if( typeof addDestructor == "function" // Custom Buttons 0.0.5.6pre4+ && addDestructor != ("addDestructor" in window && window.addDestructor) ) addDestructor(destructor, this); else this.onDestroy = destructor; |
Dumby > 21-03-2020 14:07:22 |
Andrey_Krropotkin Это из-за Custom Buttons в моём исполнении. С превеликим трудом и приключениями поставил в виртуалку Поэтому было принято решение делать так: Таким образом, данная ошибка это побочный эффект. |
Dumby > 28-04-2022 08:20:18 |
Infocatcher STR: AR: Это в лучшем случае. Похоже, себе и нам, навязана необходимость некого перерасчёта. скрытый текст Выделить код Код:… mousemoveHandler: function(e) { var tt = this.context.tt; if(!this._hasData) { this.mouseoverHandler(e); return; } var x, y; if(e) { x = e.screenX; y = e.screenY; // ▼▼▼▼▼ if(this.fxVersion >= 99) { var k = e.view.devicePixelRatio / tt.ownerGlobal.devicePixelRatio; x *= k; y *= k; } |
Infocatcher > 03-05-2022 00:06:17 |
Dumby |
Dumby > 10-01-2023 00:19:02 |
Infocatcher Проявляется в том, что Attributes Inspector больше не показывает margin, border, padding, Такое происходит во всех окнах, кроме того, в котором запущен код, Насколько я вижу, Element и XULElement используются только для оператора instanceof, скрытый текст Выделить код Код://... var omit = this.eventHandler.fxVersion < 106; var defElm = function(name) { var elm = window[name]; if(omit) return elm; var res = {}; res[Symbol.hasInstance] = elm.isInstance.bind(elm); return res; } var Element = defElm("Element"); var XULElement = defElm("XULElement"); this.setAllListeners(ael); Метод isInstance() довольно старый, Firefox 59+ |
Dumby > 12-01-2023 12:31:05 |
Infocatcher |
Dumby > 04-02-2023 08:35:59 |
Infocatcher скрытый текст Выделить код Код:/* this.setClipboardData({ "text/unicode": text.replace(/\r\n?|\n/g, this.lineBreak), "text/html": html.replace(/\r\n?|\n/g, this.lineBreak) }, sourceWindow); */ var data = { "text/html": html.replace(/\r\n?|\n/g, this.lineBreak) }; data["text/" + (this.fxVersion >= 111 ? "plain" : "unicode")] = text.replace(/\r\n?|\n/g, this.lineBreak); this.setClipboardData(data, sourceWindow); |