Полезная информация

Будьте в курсе последних изменений в мире Mozilla, следя за нашим микроблогом в Twitter.

№1355129-07-2019 19:42:09

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 66.0

Re: Custom Buttons

psihkakihmalo
Нет смысла. Даже ru-tube можно сразу в potplayer... Скрипт  Inject2Download в violentmonkey и все дела.
uizvumxv.png

Отсутствует

 

№1355229-07-2019 23:26:07

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2249
UA: Firefox 52.0

Re: Custom Buttons

solombala пишет

а вернуть обратно можно? В смысле, снова адрес видно... в 68 - есть клавиша , в 66 - никак, код бы нужен...
Да, и Copy text не заработает в 66-68 ? Рихтовал, что знал, типа, mcurrent на selected , а все-одно не то...

Я не понимаю что ты говоришь.
Это код для очистки quantumbar'а в 68, что-то типа Ctrl+L, Ctrl+A, Del, Esc.
Вернуть, соответственно, Ctrl+Z, которого, если нет на 66, то ищи где потерял.
А кодом: goDoCommand("cmd_undo"); или gURLBar.inputField.editor.undo(1);

«Copy text» и «mcurrent» не смог найти нигде.

Отсутствует

 

№1355330-07-2019 08:24:46

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 66.0

Re: Custom Buttons

Dumby
На эти команды popup поиска выскакивает. В 68 на escape - только адрес,правда с выделением..По наитию  сделал

Выделить код

Код:

/*CODE*/

goDoCommand('cmd_undo');  
goDoCommand('cmd_switchTextDirection');
goDoCommand('cmd_switchTextDirection');
Сюда бы еще команду "снять выделенное в url"

.

Dumby пишет

«Copy text» и «mcurrent» не смог найти нигде.

Так поменял я сразу на selected, и до фени...Меню не показывается на ЛКМ

Отредактировано solombala (30-07-2019 09:52:54)

Отсутствует

 

№1355430-07-2019 09:57:10

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 68.0

Re: Custom Buttons

Dumby подскажи в папке Temp_ExternalEditor в профиле со временем накапливаются файлы. Может есть какие нибудь скрытые настройки у CB, чтобы они там не накапливались, или все время в ручную удалять?

Отсутствует

 

№1355530-07-2019 10:40:12

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 66.0

Re: Custom Buttons

Andrey_Krropotkin
Нет таких настроек. В BAt файл вставить , сам баткик в VBS или автоматом при выходе или принудительно.

скрытый текст

Выделить код

Код:

if exist Temp_ExternalEditor rmdir /s /q Temp_ExternalEditor


Принудительно - в код, авто - в INI
скрытый текст

Выделить код

Код:

/*CODE*/
var closer = {
    observe: function(subject, topic, data) {
       if ( data == "shutdown" ){
            var file = Services.dirsvc.get('ProfD', Ci.nsIFile); 
         
file.initWithPath("D:\\firefox\\profile\\sqlite.vbs");
file.launch(); 

}
}
};
Services.obs.addObserver(closer, "quit-application", false);


Services.obs.addObserver(closer, "quit-application", false);
alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
                      alertsService.showAlertNotification("chrome://global/skin/icons/???.png", "PrivateData", "Профиль будет Очищен при выходе");
                      setTimeout(()=> alertsService.closeAlert(), 1000);

Отредактировано solombala (30-07-2019 10:41:39)

Отсутствует

 

№1355630-07-2019 11:23:11

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 68.0

Re: Custom Buttons

solombala спасибо, подумаю как мне лучше

Отсутствует

 

№1355730-07-2019 12:13:13

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 66.0

Re: Custom Buttons

Andrey_Krropotkin
Подскажи код или команду "убрать фокус-выделение строки адреса?

Отсутствует

 

№1355830-07-2019 12:20:57

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 68.0

Re: Custom Buttons

solombala не сталкивался

Отсутствует

 

№1355930-07-2019 12:47:43

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 68.0

Re: Custom Buttons

Dumby
Andrey_Krropotkin
Всем спасибо , но я сделал

Выделить код

Код:

goDoCommand("cmd_undo");
goDoCommand("cmd_switchTextDirection")    
goDoCommand("cmd_switchTextDirection")
gURLBar.inputField.blur();

Отсутствует

 

№1356030-07-2019 13:02:19

Garalf
Участник
 
Группа: Members
Зарегистрирован: 19-09-2017
Сообщений: 316
UA: Firefox 66.0

Re: Custom Buttons

solombala

solombala пишет

Принудительно - в код, авто - в INI
скрытый текст

У меня в 69 этот код перестал работать

Отсутствует

 

№1356130-07-2019 13:13:53

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 68.0

Re: Custom Buttons

Garalf
Там много чего перестало...Это новоявленное "произведение" , тем более бэту трогать не будем. Нема смысла. Поздрав из Drage!

Отсутствует

 

№1356230-07-2019 14:53:24

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 68.0

Re: Custom Buttons

solombala тут у меня завалялся код, вот нашел (если я правильно тебя понял):

скрытый текст

Выделить код

Код:

//Объявляем 'urlbar' ...
var urlbar = document.getElementById("urlbar");

//Очистить поле адресной строки по правому клику на  historydropmarker ............................................................................................................
var clearUrl = function(event) {
        if (event.button != 2)
            return;
        //отключать реакцию по умолчанию
        event.preventDefault();
        event.stopPropagation();
        //очистить
        urlbar.value = "";
       };
// добавляем обработчик для кнопки поиска..........
document.getAnonymousElementByAttribute(urlbar,  "anonid", "historydropmarker")
    .addEventListener("click", clearUrl, false);
  
    
//вставить текущий адрес вкладки обратно по среднему клику на  historydropmarker .................................................................................................. 
 var clearUrl1 = function(event) {
        if (event.button != 1)
            return;
        //отключать реакцию по умолчанию
        event.preventDefault();
        event.stopPropagation();
        //очистить
        urlbar.value = (gBrowser.currentURI.spec);
  urlbar.blur();
       };
// добавляем обработчик для кнопки поиска..........
document.getAnonymousElementByAttribute(urlbar,  "anonid", "historydropmarker")
    .addEventListener("click", clearUrl1, false);

Отсутствует

 

№1356330-07-2019 15:59:44

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 68.0

Re: Custom Buttons

Dumby еще вот что подскажи, есть вот кнопка, вроде все работает, но почему-то ошибки в консоли выскакивают:

скрытый текст
TypeError: this.delayConnectedCallback is not a function
     connectedCallback chrome://global/content/elements/button.js:259
    handleEvent chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button82@init line 1 > Function:75
TypeError: this.delayConnectedCallback is not a function
connectedCallback chrome://global/content/elements/text.js:98
    handleEvent chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button82@init line 1 > Function:86

сама кнопка
скрытый текст

Выделить код

Код:

/*Initialization Code*/

// Редактировать сохранённые логини и пароли, от 16.12.2013. ................................
(function() {
  
   if ( document.getElementById("parolitem") ) return; 
   // добавить новый пункт "Показать пароли сайта" в меню "Инструменты" ....
   var parolicon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAALVWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNC4yLjItYzA2MyA1My4zNTI2MjQsIDIwMDgvMDcvMzAtMTg6MTI6MTggICAgICAgICI+CiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICB4bWxuczpwaG90b3Nob3A9Imh0dHA6Ly9ucy5hZG9iZS5jb20vcGhvdG9zaG9wLzEuMC8iCiAgICB4bWxuczpJcHRjNHhtcENvcmU9Imh0dHA6Ly9pcHRjLm9yZy9zdGQvSXB0YzR4bXBDb3JlLzEuMC94bWxucy8iCiAgICB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iCiAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIKICAgIHhtbG5zOnN0RXZ0PSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VFdmVudCMiCiAgICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgICB4bWxuczp4bXBSaWdodHM9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9yaWdodHMvIgogICBwaG90b3Nob3A6QXV0aG9yc1Bvc2l0aW9uPSJBcnQgRGlyZWN0b3IiCiAgIHBob3Rvc2hvcDpDcmVkaXQ9Ind3dy5nZW50bGVmYWNlLmNvbSIKICAgcGhvdG9zaG9wOkRhdGVDcmVhdGVkPSIyMDEwLTAxLTAxIgogICBJcHRjNHhtcENvcmU6SW50ZWxsZWN0dWFsR2VucmU9InBpY3RvZ3JhbSIKICAgeG1wOk1ldGFkYXRhRGF0ZT0iMjAxMC0wMS0wM1QyMTozMzoxMyswMTowMCIKICAgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ4bXAuZGlkOjNDOTBERTNDODFGN0RFMTE5RUFCOTBENzA3OEFGOTRBIgogICB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNDOTBERTNDODFGN0RFMTE5RUFCOTBENzA3OEFGOTRBIgogICB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkFDMUUxRTM3QTdGOERFMTE4MjFDRTRCMkM3RTM2RDcwIj4KICAgPElwdGM0eG1wQ29yZTpDcmVhdG9yQ29udGFjdEluZm8KICAgIElwdGM0eG1wQ29yZTpDaUFkckNpdHk9IlByYWd1ZSIKICAgIElwdGM0eG1wQ29yZTpDaUFkclBjb2RlPSIxNjAwMCIKICAgIElwdGM0eG1wQ29yZTpDaUFkckN0cnk9IkN6ZWNoIFJlcHVibGljIgogICAgSXB0YzR4bXBDb3JlOkNpRW1haWxXb3JrPSJrYUBnZW50bGVmYWNlLmNvbSIKICAgIElwdGM0eG1wQ29yZTpDaVVybFdvcms9Ind3dy5nZW50bGVmYWNlLmNvbSIvPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJzYXZlZCIKICAgICAgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDozQzkwREUzQzgxRjdERTExOUVBQjkwRDcwNzhBRjk0QSIKICAgICAgc3RFdnQ6d2hlbj0iMjAxMC0wMS0wMlQxMDoyODo1MSswMTowMCIKICAgICAgc3RFdnQ6Y2hhbmdlZD0iL21ldGFkYXRhIi8+CiAgICAgPHJkZjpsaQogICAgICBzdEV2dDphY3Rpb249InNhdmVkIgogICAgICBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOkM1RDdEQjAxREJGN0RFMTFBOTAwODNFMEExMjUzQkZEIgogICAgICBzdEV2dDp3aGVuPSIyMDEwLTAxLTAyVDIxOjExOjI2KzAxOjAwIgogICAgICBzdEV2dDpjaGFuZ2VkPSIvbWV0YWRhdGEiLz4KICAgICA8cmRmOmxpCiAgICAgIHN0RXZ0OmFjdGlvbj0ic2F2ZWQiCiAgICAgIHN0RXZ0Omluc3RhbmNlSUQ9InhtcC5paWQ6QUMxRTFFMzdBN0Y4REUxMTgyMUNFNEIyQzdFMzZENzAiCiAgICAgIHN0RXZ0OndoZW49IjIwMTAtMDEtMDNUMjE6MzM6MTMrMDE6MDAiCiAgICAgIHN0RXZ0OmNoYW5nZWQ9Ii9tZXRhZGF0YSIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgIDxkYzp0aXRsZT4KICAgIDxyZGY6QWx0PgogICAgIDxyZGY6bGkgeG1sOmxhbmc9IngtZGVmYXVsdCI+Z2VudGxlZmFjZS5jb20gZnJlZSBpY29uIHNldDwvcmRmOmxpPgogICAgPC9yZGY6QWx0PgogICA8L2RjOnRpdGxlPgogICA8ZGM6c3ViamVjdD4KICAgIDxyZGY6QmFnPgogICAgIDxyZGY6bGk+aWNvbjwvcmRmOmxpPgogICAgIDxyZGY6bGk+cGljdG9ncmFtPC9yZGY6bGk+CiAgICA8L3JkZjpCYWc+CiAgIDwvZGM6c3ViamVjdD4KICAgPGRjOmRlc2NyaXB0aW9uPgogICAgPHJkZjpBbHQ+CiAgICAgPHJkZjpsaSB4bWw6bGFuZz0ieC1kZWZhdWx0Ij5UaGlzIGlzIHRoZSBpY29uIGZyb20gR2VudGxlZmFjZS5jb20gZnJlZSBpY29ucyBzZXQuIDwvcmRmOmxpPgogICAgPC9yZGY6QWx0PgogICA8L2RjOmRlc2NyaXB0aW9uPgogICA8ZGM6Y3JlYXRvcj4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGk+QWxleGFuZGVyIEtpc2VsZXY8L3JkZjpsaT4KICAgIDwvcmRmOlNlcT4KICAgPC9kYzpjcmVhdG9yPgogICA8ZGM6cmlnaHRzPgogICAgPHJkZjpBbHQ+CiAgICAgPHJkZjpsaSB4bWw6bGFuZz0ieC1kZWZhdWx0Ij5DcmVhdGl2ZSBDb21tb25zIEF0dHJpYnV0aW9uIE5vbi1Db21tZXJjaWFsIE5vIERlcml2YXRpdmVzPC9yZGY6bGk+CiAgICA8L3JkZjpBbHQ+CiAgIDwvZGM6cmlnaHRzPgogICA8eG1wUmlnaHRzOlVzYWdlVGVybXM+CiAgICA8cmRmOkFsdD4KICAgICA8cmRmOmxpIHhtbDpsYW5nPSJ4LWRlZmF1bHQiPkNyZWF0aXZlIENvbW1vbnMgQXR0cmlidXRpb24gTm9uLUNvbW1lcmNpYWwgTm8gRGVyaXZhdGl2ZXM8L3JkZjpsaT4KICAgIDwvcmRmOkFsdD4KICAgPC94bXBSaWdodHM6VXNhZ2VUZXJtcz4KICA8L3JkZjpEZXNjcmlwdGlvbj4KIDwvcmRmOlJERj4KPC94OnhtcG1ldGE+Cjw/eHBhY2tldCBlbmQ9InIiPz40k4AAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAATZJREFUeNqUkUFugzAQRQ0tCASiQQKJXYXEgg0KnKDcIByhN8gR0iPkBvQI9AT0BtAdu6ZbFgR2XRDccWUil2JEvvQ00oznezwW0IKiKHqAcAQSYEPTLc0di6LoBF5zEASPgiCUTONUJcY4vuMZ2LadwQEfQCOgV4gvwzCQfAh8z07g+/6W3DDNV1Ul0PoOQkaeI84Z9H0fXy4XNMXzvC2tJzS3uZ8zIAXeu13Xbdk6z+B94XNY85Zn8IzWKfu3RMdxUgijAVlkyGlu4ZvDPxNYlpUyt5NnxJzmEzQndV1/XScwTTOF5LT5RP5+MknZNM3b2PdrYBgGO/b1ZjJi13Ufi1vQNO0AYEpO41nX9cOqNSqKkgOYiVhV1Se0VpIk5cAngAmyLO/QLRJFMQcwcAb26Eb9CDAA0PGLE+yv5DMAAAAASUVORK5CYII=";           
   var menuitem = document.createXULElement("menuitem"); 
   menuitem.setAttribute("Id", "parolitem");   
   menuitem.setAttribute("label", "Пароли сайта"); 
   menuitem.setAttribute("class", "menuitem-iconic"); 
   menuitem.setAttribute("image", parolicon);   
   //var devToolsSep = document.getElementById("devToolsSeparator"); 
   var devToolsSep = document.getElementById("menu_openAddons")
   devToolsSep.parentNode.insertBefore( menuitem, devToolsSep );   
   addDestructor(function() { devToolsSep.parentNode.removeChild( menuitem ) });
   
   addEventListener("click", function(e) {
      var loc = content.location;
      var str = !loc.protocol.indexOf("http") ? loc.host : '';
      var win = Services.wm.getMostRecentWindow("Toolkit:PasswordManager");
      if ( win ) win.setFilter(str), win.focus();
      else 
           openDialog("chrome://passwordmgr/content/passwordManager.xul", "Password", "centerscreen, resizable=1", { filterString: str } );    
   }, false, menuitem );
  
  // наблюдатель следит за открытием всех окон .... 
   var observer = {  
       observe: function(subject, topic, data) {
          subject.addEventListener("load", this, false);
          },
      
       handleEvent: function(e) {
          var doc = e.target;
          var win = doc.defaultView;
          var href = doc.location.href.slice(0,60);
          win.removeEventListener("load", this, false);
          
          // если открыт менеджер паролей и окошко редактирования пароля ....           
          if ( Services.wm.getMostRecentWindow("Toolkit:PasswordManager") && href == "chrome://global/content/commonDialog.xul") {
               
               // клик на чекбоксе показывает / скрывает пароль 
               addEventListener("click", function(e) { 
                  var pass = e.target.hasAttribute("checked") ? false : "password"; 
                  doc.getElementById('password1Textbox').setAttribute("type", pass );     
               }, false, doc.getElementById('checkbox') );
               
               }
               
          // если менеджер паролей добавить кнопку "Изменить" и обработчики ....          
          if ( href == "chrome://passwordmgr/content/passwordManager.xul") {

               // обработчик закрывает менеджер паролей по клику на странице .... 
               gBrowser.addEventListener("click", function f() {
                  this.removeEventListener("click", f ); 
                  try { win.close() } catch(e) {}; // закрыть окно 
               });              
              
               var buttons = doc.getElementsByTagName("button");

               // кнопка "Отобразить пароли" работает без запроса ....
               addEventListener("click", function(e) {
                  e.preventDefault();
                  doc.getElementById('passwordCol').hidden = !doc.getElementById('passwordCol').hidden;
               }, false, buttons[2] );               
               
               // добавить кнопку "Изменить" ....
               var changePassBut = document.createXULElement("button");
               //changePassBut.setAttribute("label", "Изменить");
               changePassBut.setAttribute("id", "changePassword");
               changePassBut.setAttribute("disabled", true );   
               buttons[0].parentNode.insertBefore( changePassBut, buttons[2] );               
               var changePasshbox = document.createXULElement("hbox");
               changePasshbox.setAttribute("class", "box-inherit button-box");
               changePasshbox.setAttribute("align", "center");
               changePasshbox.setAttribute("pack", "center");
               changePasshbox.setAttribute("flex", "1");
               changePassBut.appendChild( changePasshbox );

              var changePasslabel = document.createXULElement("label");
              changePasslabel.setAttribute("class", "button-text");
              changePasslabel.setAttribute("value", "Изменить");
               changePasshbox.appendChild( changePasslabel );
               // наблюдатель делает кнопку активной при выделении логина 
               var setHiddenMenu = new MutationObserver(function() {
                   changePassBut.setAttribute("disabled", buttons[0].disabled );          
               });
               setHiddenMenu.observe( buttons[0], { attributes: true, attributeFilter: ["disabled"] } ); 
               
               // клик на кнопке запускает редактирование
               addEventListener("click", function() {            
                  
                  // поличить выделений хост, логин и пароль
                  var tree = doc.getElementById('signonsTree');                     
                  function getSelectedItemFromTree(column) { return tree.view.getCellText( tree.currentIndex, tree.columns.getColumnAt(column) ) };                        
                  
                  var hostname = getSelectedItemFromTree(0);
                  var currUsername = getSelectedItemFromTree(1);
                  var currPassword = getSelectedItemFromTree(2);
             
                  // получить новый логин и пароль
                  var prompt = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService( Ci.nsIPromptService );   
                  var username = {value: currUsername};         
                  var password = {value: currPassword}; 
                  var result = prompt.promptUsernameAndPassword( null, "Изменить имя пользователя и пароль", hostname,
                                                                 username, password, "Показывать пароль", {value: false} );
                  if ( !result ) return;    
             
                  // найти нужный логин и переписать с измененными данными
                  var loginManager = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); 
                  var logins = loginManager.findLogins({}, hostname, "", "");                              
                  logins.forEach(function( login ) {      
                     if ( login.password !== currPassword ) return;               
                   
                     var nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo, "init");                    
                     var newLogin = new nsLoginInfo( hostname,
                                                     login.formSubmitURL,
                                                     !login.aHttpRealm ? null : login.aHttpRealm,
                                                     username.value,
                                                     password.value,
                                                     login.usernameField,
                                                     login.passwordField);                   
                     
                     loginManager.modifyLogin( login, newLogin );
                  });              

               }, false, changePassBut );
               }
       }
   };
   Services.obs.addObserver( observer, "domwindowopened", false);
   addDestructor(function() { Services.obs.removeObserver(observer, "domwindowopened", false) });

})();

Отредактировано Andrey_Krropotkin (30-07-2019 16:01:13)

Отсутствует

 

№1356430-07-2019 16:31:21

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 68.0

Re: Custom Buttons

очистить clipboard ? кода нет? Батник городить?

Отсутствует

 

№1356530-07-2019 16:57:42

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 68.0

Re: Custom Buttons

solombala
//Clear Clipboard......................................
function clearClipboard() {
gClipboard.clear();
var cbTitle = "Clear Clipboard";
var cbDesc = "Буфер обмена очищен";
custombuttons.alertSlide(cbTitle, cbDesc);
}

Отсутствует

 

№1356630-07-2019 18:07:07

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 66.0

Re: Custom Buttons

Andrey_Krropotkin
Понятно, а timeout  ?

Отсутствует

 

№1356731-07-2019 07:32:41

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 68.0

Re: Custom Buttons

egorsemenov06 я не стал все собирать вместе она у меня разбросана по нескольким местам, кто хочет собирайте, я привык к своему
1. кнопка - скриншоты, то что сделал Dumby( в принципе необязательная, т.к. есть штатная из контестного меню страницы)

скрытый текст

Выделить код

Код:

/*Initialization Code*/

((main, parts) => this._handleClick = () => {
    var df = MozXULElement.parseXULToFragment(`
        <menupopup>
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить всю страницу как PNG"
                value="all"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить видимую часть страницы как PNG"
                value="page"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAIBkAAAEAIAAMDQAAFgAAACgAAAAgAAAAMgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29fT/2tra/8jIyP/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8jIyP/a2tr/9vX0/+zs7P/ak0b/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/9qTRv/s7Oz/7Ozs/+J9Dv/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+/6SdmP/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/+vn4//z7+v/6+fj/4n0O/+zs7P/s7Oz/4n0O//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/aFtT//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//j39v/ifQ7/7Ozs/+zs7P/ifQ7/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P9oW1P/7+zq/+/s6v/v7Or/8O3r//Dt6//w7ev/8O3r//Dt6//w7ev/8O3r/+/s6v/w7ev/9fTy/+J9Dv/s7Oz/7Ozs/+J9Dv/49/b/+Pf2//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4/2hbU//q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/y8O//4n0O/+zs7P/s7Oz/4n0O//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/aFtT/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe//Dt6//ifQ7/7Ozs/+zs7P/ifQ7/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P9oW1P/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/7uro/+J9Dv/s7Oz/7Ozs/+J9Dv/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx/2hbU//x7+3/8vDv//Hv7f/x7+3/8e/t//Lw7//x7+3/8e/t//Lw7//x7+3/8vDv//Hv7f/29fT/4n0O/+zs7P/s7Oz/4n0O//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//aFtT/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/8vGwf/ifQ7/7Ozs/+zs7P/ifQ7/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f9nWlL/aFtT/2hbU/9nWlL/Z1pS/2hbU/9oW1P/Z1pS/2daUv9oW1P/aFtT/2hbU/9nWlL/pJyX/+J9Dv/s7Oz/7Ozs/+J9Dv/w7ev/8O3r//Dt6//w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Hv7f/w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Dt6//w7ev/4n0O/+zs7P/s7Oz/4n0O/+/s6v/v7Or/7uro/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/u6uj/7+zq/+/s6v/ifQ7/7Ozs/+zs7P/ifQ7/7uro/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7Ojm/+J9Dv/s7Oz/7Ozs/+J9Dv/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/4n0O/+zs7P/s7Oz/4n0O/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/ifQ7/7Ozs/+zs7P/ifQ7/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+J9Dv/s7Oz/7Ozs/+J9Dv/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/4n0O/+zs7P/s7Oz/4n0O/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/ifQ7/7Ozs/+zs7P/ifQ7/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+J9Dv/s7Oz/7Ozs/+J9Dv/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/k39z/4n0O/+zs7P/s7Oz/4n0O/+Lc2f/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/ifQ7/7Ozs/+zs7P/ifQ7/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+J9Dv/s7Oz/9fTy/+J9Dv/8+/r/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/4n0O//X08v/8+/r/6KFU/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ooVT//Pv6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить выбранный элемент страницы как PNG"
                value="click"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAADDn2Hfz5pE/8eVQP7IlkH/yJZB/8iWQf/IlUH/yJVA/8iVQP/IlED/yJQ//8iUP//IlD//yJM+/8iTPv/Hkj3/nI1w//bDbP//8OH//+zW///s1///69b//+rV///p1P//59L//+XQ///izf//38n//9vG///ZxP//1b///dG////Prf/KlkX/88N4/v37///99Pj//fT6//vy9v/68fT/+u/y//rt8P/66u3/+ufq//rl6P/64eT/+93h//3a3//71d7//9LK/86XR//0xHb//vv////18///9fT///f5///4////9f7///P8///v+f//7Pb//+nz///m8f//4eb//9vZ//3Y2v//1Mb/zphH//TGd//+/////Pj1///7///Q58r/m9aV/6TZnv+i15r/otWY/6LTlv+j0pb/mc6M/9DXuf//3+P//Nnc///Wyf/OmUf/9MZ3//7////8+/j//////53WnP+Y5pn/rvGv/6PvpP+e7p//me6b/5nvm/95533/mM+L///j7f/629z//9jL/86ZR//0xnf//v////z9+v//////qtup/8Xzxf/a/tn/z/vO/8n7yf/D+sL/xPvD/6Hzo/+j05b//+Tu//re3///2cz/zplI//XGeP/+/////P36//////+n26f/uvC6/9T71P/K+Mr/xvjG/8D3wP+/+L//nfCf/6LTlf//5u//+t/g///cz//OmUj/9MZ3//7////8/fr//////6rcqv/G9MX/3//f/9n92f/V/NX/0PzQ/9H+0P+s9a7/pdSY///o8f/64OL//9zP/86aSP/0xnf//v////z9+f//////ndid/5TjlP+v7q//qeyp/6jsqf+k7KX/p+6n/4Tlh/+Z0Y7//+r0//rh4v//3tH/zppI//TGd//+/////v77///////Y8Nj/p9+n/6/jr/+t4a3/rd2p/67bpv+u2ab/p9Wc/9jgx///6Oz//OPl///e0f/Omkj/9MV1//7//////fr///78///+/f///////////////////P////j////0+///8fn//+vu///m4v/94+P//97P/86ZSP/zx3v//v/////+/f///////f////v////7////+/////v+///7+///+/f///vz/P/98Pr//+33//3p9///5OL/zppL//a1Sv/0xoL/9cR7//XEfP/1xHz/9cR8//XEfP/1xH3/9cR8//XCev/1wXr/9b94//W9d//1u3X/87l0//y6bP/Llj7/+pMA/vWBAP/1gwD/9YMA//WDAP/1gwD/9YMA//WDAP/1gwD/9YQA//WEAP/1hAD/9YQA//WEAP/zhAH//okA/8qLIv3xpzP/4ptV/+OdU//jnVP/451T/+OdU//jnVP/451T/+OdU//jnVL/451S/+OdUv/jnVL/451S/+GdVf/qnUf/2aRJ/9q0c9/8yn7/98V5/vjGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6/vrIe/+jj2y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить выбранную область страницы как PNG"
                value="clipping"/>
        </menupopup>
    `);
    var popup = df.firstChild;
    popup.setAttribute("context", "");
    popup.setAttribute("oncommand", "handleCommand(event);");
    popup.handleCommand = e => {
        var name = _id + ":DataURLReady";
        main = main.replace("%MESSAGE_NAME%", name);

        var urls = {}, configurable = true, enumerable = true;
        Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, {
            configurable, enumerable, get() {
                var value = `data:;charset=utf-8,({${
                    encodeURIComponent(main + part)
                }%0A}).init("${key}")`;
                Object.defineProperty(urls, key, {configurable, enumerable, value});
                return value;
        }}));
        var getTabLabel = () => {
            var label = gBrowser.selectedTab.label;      
            var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
            return label.substring(0, 50);
        }
        var listener = msg => {
            var fp = makeFilePicker();
            fp.init(window, "Сохранить как…", fp.modeSave);
            fp.appendFilter("", "*.png");
            fp.defaultString = getTabLabel() + ".png";   
            fp.open(res => res == fp.returnCancel || !fp.file || makeWebBrowserPersist().saveURI(
                Services.io.newURI(msg.data), document.nodePrincipal,
                null, null, null, null, null, fp.file, null
            ));
        }
        messageManager.addMessageListener(name, listener);
        addDestructor(() => messageManager.removeMessageListener(name, listener));

        (popup.handleCommand = e => gBrowser.selectedBrowser.messageManager
            .loadFrameScript(urls[e.target.value], false)
        )(e);
    }
    this.append(df);
    (this._handleClick = () => popup.openPopup(this, "after_start"))();
})(`
    init(cmd) {
        cmd.startsWith("c")
            ? this[cmd].init(this[cmd].parent = this)
            : this[cmd]();
    },
    capture(win, x, y, width, height) {
        var canvas = win.document.createElementNS("${xhtmlns}", "canvas");
        canvas.width = width;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        var tryDraw = ind => {
            try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")}
            catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);}
        }
        tryDraw(17);
        sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png"));
    },
    `, {

    all: `all() {
        var win = content;
        this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY);
    }`,
    page: `page() {
        var win = content, doc = win.document, body = doc.body, html = doc.documentElement;
        var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft;
        var scrY = (body.scrollTop || html.scrollTop) - html.clientTop;
        this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight);
    }`,
    clipping: `clipping: {
        handleEvent(e) {
            if (e.button) return false;
            e.preventDefault();
            e.stopPropagation();
            switch(e.type) {
                case "mousedown":
                    this.downX = e.pageX;
                    this.downY = e.pageY;
                    this.bs.left = this.downX + "px";
                    this.bs.top = this.downY + "px";
                    this.body.appendChild(this.box);
                    this.flag = true;
                    break;
                case "mousemove":
                    if (!this.flag) return;
                    this.moveX = e.pageX;
                    this.moveY = e.pageY;
                    if (this.downX > this.moveX) this.bs.left = this.moveX + "px";
                    if (this.downY > this.moveY) this.bs.top  = this.moveY + "px";
                    this.bs.width = Math.abs(this.moveX - this.downX) + "px";
                    this.bs.height = Math.abs(this.moveY - this.downY) + "px";
                    break;
                case "mouseup":
                    this.uninit();
                    break;
            }
        },
        init() {
            var win = {};
            Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
                .getFocusedElementForWindow(content, true, win);
            this.win = win.value;

            this.doc = this.win.document;
            this.body = this.doc.body;
            if (!HTMLBodyElement.isInstance(this.body)) {
                Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
                    .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!");
                return false;
            }
            this.flag = null;
            this.box = this.doc.createElement("div");
            this.bs = this.box.style;
            this.bs.border = "#0f0 dashed 2px";
            this.bs.position = "absolute";
            this.bs.zIndex = "2147483647";
            this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor;
            this.body.style.cursor = "crosshair";
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)];
            this.body.style.cursor = this.defaultCursor;
            this.body.removeChild(this.box);
            this.parent.capture.apply(this, pos);
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`,
    click: `click: {
        getPosition() {
            var html = this.doc.documentElement;
            var body = this.doc.body;
            var rect = this.target.getBoundingClientRect();
            return [
                this.win,
                Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft,
                Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop,
                parseInt(rect.width),
                parseInt(rect.height)
            ];
        },
        highlight() {
            this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false;
            this.target.style.cssText += "outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;";
        },
        lowlight() {
            if (this.orgStyle) this.target.style.cssText = this.orgStyle;
            else this.target.removeAttribute("style");
        },
        handleEvent(e) {
            switch(e.type){
                case "click":
                    if (e.button) return;
                    e.preventDefault();
                    e.stopPropagation();
                    this.lowlight();
                    this.parent.capture.apply(this, this.getPosition());
                    this.uninit();
                    break;
                case "mouseover":
                    if (this.target) this.lowlight();
                    this.target = e.target;
                    this.highlight();
                    break;
            }
        },
        init() {
            this.win = content;
            this.doc = content.document;
            ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            this.target = false;
            ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`
});


2 кнопка -остатки Save (пока руки не дошли, тоже раскидаю, т.к. у меня что касаеется контекстого меню (меню), вкладок, закладок  т.д.  складываются в отдельные кнопки)
скрытый текст

Выделить код

Код:

// Save, от 07.03.2017. .............

self.label = "Save";
self._handleClick =()=> menuPopup.openPopup(this, "after_start");
self.image = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";


var pref = "CB.Shortcuts.pathToSaveShortcuts";
var folderpath="C:\\Users\\vieva\\Desktop";         // папка для сохранения иконок для ярлыков и ярлыков сайтов
var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);


// Создать меню для кнопки .............
var array = [
   { label: "Сохранить значок веб-сайта", func: "saveFavicon()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACPVBMVEX09ff////C3L+Uq8+Vq8+Uqs+Zr9CZrtCZr9Gfu+ear8+mt9JRf8ORxl3t8vfF06+Twojs8/d9otl8o9s+aquZrs/X9KLp8Pft8fZhisf//+DBzN2hveihv+pii8hti9pgicl6oNlojs1zncNsi836/P2duebx8/eYyWqBp+Gn0IKBvlKHsm9qmaVuk8zt7/FEbauEv1Tp7/JdhL9oi9Pl8e2LwlmdsdD7/P76+/3H7ofo8+peh8eHwFaSteZ0pkp2gl7q8/Ohy5OApt2by2eZuOqbuOWaezWuvtd7nN2HvWxul9Ty9feQxV5ljcqBp+JEcLCVtOOo0nR7odx5n9suX6Z1mtBzmtSXyGPv9PewzfOzx+O6zu/s8fd9o95Xfrthi8lYhMN5oNnw9ffw9Pjw9Pf8/f6ewO/m8O9zmdE6aapsjdyUwouPxWPDzd6XteOSs9B5nNVpnpqHt7h/s6F6n9d7ntSTttGHwVh4qp+Ev1HH7ox6qk5wj+Hm8e3t9fOm0IKAtqOBpNrx+P9ljcyhs9FpkM2hv+/u8/fF0eOLu4N+vFKgzX3p9OSFqN13qExekIl4n9j7/P3x9PhxmNDm8e9Vg8Zfkozr8veq0YTX9qL//92AtamOwnHFz96Fot1diMh+pd13ntmatu+YyW/3+/+Tqs5UgcShzJNbhsdTf8GHs7bo8PaXtuqMr+Ty8/SZt+SUqs7r7Ox3ndb9/f7t8feZyXGYyWWCpNbz9PRuiteNtNDn7/V4ntjx8fGo3JqNAAAAv3RSTlP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AEVuhDkAAAD+SURBVBhXY5jHzcUMAqxAICq9bx8D96adDFAgaGQOFOBaH7h7zoqZDTlFyptncAAFWBjyi52CXCI0unRLxcECPhsatbbzmlXMnS60hg0kkOxW0uNrq93tNaFpD1ggUm21QK532ZQdSm1hmXKdDCwdnOWVOi1RjNGMQCCrwMDMJ8NZ4LAynVGPkXFp8zpJBubYmn579wXtqhZb0iwn9a1iWLaViYmJ3891obOwYtLEvcYMGyWAAkwJdv6accEhi8LjGVr11SenpC5f61g3NcO0vjCAIc+DjZ2dnWexddWSbYa9nlkM+8BgWsxsK7FZ1VLzRaACNokmtdnyu1QMQgF7Rlh4zWWTAwAAAABJRU5ErkJggg=="},
   { label: "Запомнить значок веб-сайта как base64", func: "copyFaviconData()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAI2bv/9RVpf/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAACIkvD/Jia6/ywpq/8AAAAAAAAAAAAAAAAAAAD/AAAA/wbwAf90qpv/Ymic/1RWqP9OUKr/W2Ch/2dumf9YYKT/Ly/B/xQP3/8MB9P/JCGb/wAAAAAAAAAAAAAAAAAAAP8G8AH/U5ea/ycr8f8VIP3/HiP4/ywo8v8sIvb/LCL2/ywi9v8KBOj/BQDe/wQAtv8tK4P/AAAAAAAAAAAAAAD/BvAB/3Sqm/9iaJz/Tim3/0UuuP9GPrT/R0ex/zk8uf8gIMz/FRDe/xEMzv8jIJz/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8AAAD/SqOR/yImvP8sLKj/AAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/BvAB/3Sqm/9KW5r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAABvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAG8AH/AAAAAAAAAP8G8AH/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BvAB/wbwAf8AAAAAAAAA/wAAAP8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAG8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOesQQBjrEGAAaxBwACsQcABrEHDg6xBwAesQcAPrEHAD6xBw8+sQcPprEHD8axBwAGsQQABrEGAAaxB//+sQQ=="},  
   { separator: ''},
   { label: "Сохранить ярлык страницы как…", func: "saveShortcuts()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP8E/yT/BP8k/5XLDv/zqgD/86oA//I1///yNf//86oA//OqAP/zqgD/86oA//OqAP+Vyw7/lcsO/wT/JP8E/yT/BP8k/5XLDv+Vyw7/86oA//OqAP/yNf//8jX///OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//02AP/9NgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/9NgD//TYA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA/wA31v8AN9b/86oA//9If///SH//86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP8AN9b/ADfW//OqAP//SH///0h///OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/5XLDv+Vyw7/86oA//OqAP/zqgD/86oA/0CA//9AgP//86oA/07+9f9O/vX/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP9AgP//QID///OqAP9O/vX/Tv71//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ=="},
   { separator: ''},
   { label: "Кодировать изображение или текстовой файл в base64", func: "copyFaviconbase()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACLElEQVR42pXTXUtUURTG8f/aZ58zppqjY4YhRgQBWRABRRgoEERlKNJlQn2ICOquIooi6Bt0FRDkOGlAUUBRQoEFmEYEZhSRYG/zojpzzl55cA6lUNFv89zszX5YN0tyIyNUDYdR1KfOoYCwQgSE1RQQMXiel7NhGFLVN9Dfz//I5nJ9VlX53buZ94BgDNT6HvuvjhNYQVAUcA4Obs9w7WQXqg7LGoHvIxIXCCk/HlM4e2w3Ym0yPOduPiMmgBERksRqampWkkoRBAFTF7q5MvSCcgQ3ns9SUYM1kLDW97POuf7IOW5ls6gqAlgDdRZOPwk43ruXu2/zNKfX87VsEH6x8eeu7h4iP8B5HjhFnCNllH0Xxxg4uofpwiKZpjTjj8dI204QIWEVMHX1iDV4bWnM1k14rS2kmjK8qUuz46HQe6iHe7dHeXnpCJ2nRgkjJaZJge8J5XqBnR3Ilja0JUPYkMEEjbxaesC2OxHXu8qAMHn5MGi1QMEAWMC0N2I60pjNzcvZgPpFFj9PsDAxxuvzByhWABUqIZQjqgWKVQUfWGptwGxshCCPzk3hiku42XmiyU9YoBIpiCBGiE/CoooPmMZadP4Dsj7EtK9Dfxi0FCL1Pj4xJWathYQIJnnQLx9hbga0gKldAClAOY+WF4gJwlpGBJtcp58W+RvfegwND+OcI2aMoVQqPZLlhcg71Qan/JERKBQK908MDp5hte8C7AI8/u0bMM0aPwHiYdBiB+lf7gAAAABJRU5ErkJggg=="},  
   { label: "Сохранить выделенный текст как txt файл", func: "saveSelectionToTxt()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAQE6AAAAZAAAAGgAAAJmAAACZgAAAGYAAABmAAAAZgAAAGYAAABmAAAAZgAAAGYAAABlAAAAaQABAmYAAQEjAAAAADlVkOdVcKHxVXKi8kdklPJLZpfyU3Cg8lJvn/JRbZ7yUW+g8lFun/JRbp/yUG6e8lVyofFVdKjzLkV45wAAAFABAQEAaIzF/3y34v9wsuL/cJe0/0lpgv9bjLP/dLLh/2+v3v9sq9v/cK3d/3Gv3v9sqtv/b7Df/4G77P9VcqT2AAAAVAMDAQBnir/+ZqfU/pDB4/7a3uD+j46N/kxYXv6To6/+1er4/tXp+P7J3/D+1ej4/svg8v6Gut/9aqzd/lhxnvAAAABSAwIBAGaIvv9pptX/ocfj//f4/P/P0tX/g4CA/1xZWf+Woqr/2uz8/9Hl+f/W5fT/2Of3/5fC4v5tq93/Vm+e8QAAAFIDAgEAaYm+/3mw2/+iyeX/9Pn8/+z0+//IzNL/d3h5/0tMTv+Mkpn/xdvs/9Hp/f/O4PL/msXk/nmz4/9XcJ/xAAAAUgMDAQBti7//k7/h/6fL5v/v9fn/4u73/9Dk9P+8wMT/YGpx/zJJWv94iJf/ztzo/9Pp/P+ZwuD+gLfk/1dwnvEAAABSAwMBAHOPwf+myub/sNHp//j7/P/6/P3/8fr///r39P+sxdP/IXWq/xJJcv+NjZD/0+Lu/6TN7f6Ft+L/WXGf8QAAAFIDAwEAd5LD/7PR6/+ZxOP/0ePx/97r9f/Y5/L/3e32/8Tc7f9gseT/CHK3/zBYdv+HiY7/lL/f/pLE7/9bcJ3xAAAAUgMDAQB4k8P/xNvx/5/F5f+kyOX/qMrn/6TH5f+kyOX/sM/q/5e51P9Mm83/GHm3/xxIav9fdYf+pMvs/1x1pfIAAABTAwMBAHmSxf/O4/T/y9/y/8Hb9P/C3PX/wNv0/7vW7/+93ff/utDm/42fsf9Gjbn/EXS2/ytSbv6Fj5r/WnGc8gAAAFICAwEBepPE/tHk9f/S5PX/vMjV/7fCzP+3w8//uMPP/7XBzP+6ytf/qa+4/3h/hv9Ghaz/JoO+/jNXdP82PVnyAAAAVgACAgCBmcb/2+r3/dHh8fyPkpX/kI6N/5yam/+dnJ3/paWk/6enpf+sr6//mpSR/3Bubf9SjbD8H4C+/QsrSvcCAAB/AAAAA3yVx//j8///3u/7/52gpf6pqKf+uLm5/rq7u/7Ly8v+ycnI/paWlf6LjY/+np2f/Xh+g/5gnL7/MX+y/xcgJ80BAgNNN1OUs6W84fDA1O73mJyj/ainpv+2trb/t7e4/8fHyP/Fxsb/kZGQ/4eGhP+vucT/j6G+/W53k/NlkbnwNoOv/AgiNb8CCBsQDRo/YwsaO3B0d33arKyp9q2trfWvr6/2u7u79ru7vPawr7H1sbCt9nJ2gOQIGD6bFCFEYB0qPE1Bf6SpEz9cggAAAAMCAQEBAQAAADIyMmlDQ0ONQUFBhUFBQYVCQkGFQkJBhUhISIRNTU2OKysrZAEAAAUBAQAAAgEAAAkEAAEDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
   { separator: ''},
   { label: "Сохранить выделенный текст в файл, в контекстном меню", value: "CB.Save.SelectionToFile" },
   { label: "Открыть выделенный текст в внешнем редакторе, в контекстном меню", value: "CB.Save.TextToEditor"},
];

var menuPopup = self.appendChild(document.createXULElement("menupopup"));
array.forEach((m,i)=> {
   if ("separator" in m) { menuPopup.appendChild(document.createXULElement("menuseparator")); return };
   var mItem = menuPopup.appendChild(document.createXULElement("menuitem"));
   mItem.setAttribute("label", m.label);
   mItem.setAttribute("class", "menuitem-iconic");
   if ("image" in m) mItem.setAttribute("image", m.image || array[i-1].image); 
   if ("value" in m) { 
       mItem.setAttribute('type', 'checkbox');
       mItem.setAttribute('checked', cbu.getPrefs(m.value) );
       mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value));
       }
   if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString()));
});
menuPopup.setAttribute("onclick", "event.stopPropagation()");


function aDate() {
 var t=new Date();
 var y=1900+t.getYear();
 var min=t.getMinutes(); if (min<10){min="0"+min};
 var h=t.getHours();
 var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";}
 var d=t.getDate();
 var curdate=d+" "+m+" "+y+" "+"г";
 var myfilename=curdate;
 return myfilename;
}



function WebScreenShotonImage(image) {
      var canvas = document.createElementNS(xhtmlns, 'canvas');
      canvas.width = image.naturalWidth;
      canvas.height = image.naturalHeight;
      var ctx = canvas.getContext('2d');
      ctx.drawImage(image, 0, 0);
      var base64 = canvas.toDataURL();
      gClipboard.write(base64);
   
      // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
      
     // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { 
     Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается
      }, "");
};



var saveToFile = function (fileContent, fileName) {
    var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
    uc.charset = 'utf-8';
    fileContent = uc.ConvertFromUnicode(fileContent);

    var nsIFilePicker = Components.interfaces.nsIFilePicker;
    var fp = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
    fp.init(window, '', fp.modeSave);
    fp.defaultString = fileName;
    fp.appendFilters(fp.filterHTML);
    fp.appendFilters(fp.filterAll);
    fp.open(function (rv) {
  if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
    var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream);
    stream.init(fp.file, 0x02|0x20|0x08, 0666, 0);
    stream.write(fileContent, fileContent.length);
    stream.close();
  }
});
};

// Сохранить ярлык страницы в указанную папку  ..............
function saveShortcuts() {
var file = Components.classes["@mozilla.org/file/local;1"].
           createInstance(Components.interfaces.nsIFile);
file.initWithPath(folderpath);

if( !file.exists() || !file.isDirectory() ) {   file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0x1B6);}

var savetodir=folderpath+"\\"; 
var urllink=gBrowser.currentURI.spec;
var out=getTabLabel();
var filename=savetodir+out+'.url';
var data="[InternetShortcut]\r\nURL="+urllink+"\r\n";

saveToFile(data, filename);
 
   // подсказка
   var notific = 'Сохранил в: ' + folderpath;
   var image = gBrowser.selectedBrowser.mIconURL;
   Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(image, filename, notific);
};


// Кодировать изображение или текстовой файл в base64 .............
function copyFaviconbase(){
var fp = window.makeFilePicker();
fp.init(window, "Открыть файл", fp.modeOpen);
fp.appendFilter("Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml; *.xhtml; *.jpe; *.jpg; *.jpeg;\
                                    *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw");
  fp.open(re=> { 
  if ( re != fp.returnOK ) return;
   var file = fp.file;
   var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
   inputStream.init(file, 0x01, 0600, 0);
   var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
   stream.setInputStream(inputStream);
   var encoded = btoa(stream.readBytes(stream.available()));
   var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file);
   var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded;
   gClipboard.write(dataURI);
   //Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Скопировал файл как base64");
    // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
      
     // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { 
     Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Запомнил изображение как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается
      }, "");
});
};



// Сохранить иконку текущего сайта с диалогом сохранения .............
function saveFavicon() {
       var uri = gBrowser.currentURI;
       function getSiteName() {
                  try { var domain = uri.host.split('.') } catch(e) { return "" };
                   domain = (domain.length == 2) ? domain[0] : domain[1]
                   return domain.charAt(0).toUpperCase() + domain.slice(1).split('.')[0] + " ";  
            };
      saveImageURL(gBrowser.selectedTab.image, getSiteName(), null, false, false, null, window.document);
};


// Скопировать иконку текущего сайта как base64 код .............
function copyFaviconData() {
   var img = new Image();
   img.src = gBrowser.selectedTab.image;
   WebScreenShotonImage(img);
};


// Сохранить выделенный текст или весь текст на странице как txt файл .............
function saveSelectionToTxt() {

let browserMM = gBrowser.selectedBrowser.messageManager;
        browserMM.addMessageListener('getSelection', function listener(message) {
        var sel = message.data;
       !sel && document.getElementById("cmd_selectAll").doCommand(); 
     
   // создать название файла из заголовка страницы и текущего времени и сохранить текст ....
   var fileTitle = getTabLabel() + '  ' + aDate().replace(/:/g, ".");
   saveURL("data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + ("\r\n\r\n" + sel)), 
                                fileTitle + ".txt", null, false, false, null, window.document);
   !sel && goDoCommand("cmd_selectNone"); 
 browserMM.removeMessageListener('getSelection', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelection", content.document.getSelection().toString())', false);
};

 
// Добавляем в контекстного меню страницы новые пункты .............
((contextMenu, el)=> {

   // в контекстного меню выделенного текста ....
   var saveItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el);
   saveItem.id = "content-saveItem";
   saveItem.setAttribute("label", "Сохранить выделенный текст в файл");
   saveItem.onclick =()=> saveSelectionToFile();

   var editorItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el);
   editorItem.id = "content-editorItem";
   editorItem.setAttribute("label", "Открыть выделенный текст в внешнем редакторе");
   editorItem.onclick =()=> textToEditor();


   // устанавливаем где и при каких настройках показывать новые пункты ....
   addEventListener('popupshowing', e=> {
      if (e.target != e.currentTarget) return;
      var sel = gContextMenu.isTextSelected;
      saveItem.hidden = !sel || !cbu.getPrefs("CB.Save.SelectionToFile");
      editorItem.hidden = !sel || !cbu.getPrefs("CB.Save.TextToEditor"); 
   }, false, contextMenu);

   // удалять новые пункти при изминениях ....
   addDestructor(()=> {
     saveItem.remove(); editorItem.remove();
   });   
})(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open"));


// Сохранить выделенный текст в файл на рабочем столе .............
function saveSelectionToFile() {
   // создать текст для записи
   var url = gBrowser.currentURI.spec;
   if (/\.рф/.test(url.host)) url = convertFromUnicode("UTF-8", url);
   
   var time = convertFromUnicode("UTF-8", aDate().replace(/:/g, "."));
   var text = convertFromUnicode("UTF-8", gContextMenuContentData.selectionInfo.fullText); 
   var title = convertFromUnicode("UTF-8", getTabLabel());
   
   var text = "..............................................................\n"
            + title + " - " + time + "\n" + url + "\n\n" + text + "\n\n\n";
   var text = text.replace(/\u000A/g, "\u000D\u000A").replace(/\u000D\u000D\u000A/g, "\u000D\u000A");

   // путь к файлу и название файла
   var file = Services.dirsvc.get("Desk", Ci.nsIFile); 
   file.append("Save - " + (aDate().replace(/:/g, ".")) + ".txt");
          
   // создать файл с текстом или добавлять текст в файл
   var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
   file.exists() ? foStream.init(file, 0x02 | 0x10, 0664, 0) : foStream.init(file, 0x02|0x08|0x20, 0666, 0);
   foStream.write(text, text.length);
   foStream.close();

   // всплывающая подсказка дает возможность открыть файл если кликнуть на подсказке
   var notificat = 'Сохранил выделенный текст в файл на рабочий стол'; 
   var image = gBrowser.selectedTab.image || self.image;
   Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
    .showAlertNotification(image, notificat, "Кликни чтобы открыть файл", true, "", (s, t)=> { 
      if (t == 'alertclickcallback') file.launch();
   }, "");
};


// Создать текстовой файл с выделенным текстом в папке профиля и открыть в редакторе .............
function textToEditor() {
   var text = convertFromUnicode("UTF-8", gContextMenuContentData.selectionInfo.fullText); 
   var file = Services.dirsvc.get('ProfD', Ci.nsIFile);
   file.append("TextToEditor.txt");
   custombuttonsUtils.writeFile(file.path, text);
   file.launch(); 
};


// Конвертировать текст в юникод .............
function convertFromUnicode(charset, str) {
     var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
     converter.charset = charset;
     str = converter.ConvertFromUnicode(str);
     return str + converter.Finish();
 
};

// Получить название вкладки без не сохраняемых символов и лишних пробелов ..............
function getTabLabel() { 
   var label = gBrowser.selectedTab.label;      
   var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
   return label.substring(0, 50);
};


3. В контестном меню страницы
скрытый текст

Выделить код

Код:

//Добавить в контекстное меню страницы пункт "Запомнить изображение как base64"..........................................................................................
(popup => addEventListener("popupshowing", {
    handleEvent(e) {
        if (this.shouldHide) return;

        var menuitem = document.createXULElement("menuitem");
        menuitem.id = "content-baseItem";
        menuitem.className = "menuitem-iconic";
        menuitem.setAttribute("oncommand", "copyImageAsBase64()");
        menuitem.setAttribute("label", "Запомнить изображение как base64");
        menuitem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AIAQ/wCAEf8AgA//AIAR/wCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AgBX/AIAVAAAAAAAAAAD/AIAo/wCA//8AgP//AID//wCA//8AgP//AIAoAAAAAAAAAAAAAAAAAAAAAP8AgBL/AID//wCA//8AgA3/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgBAAAAAAAAAAAAAAAAD/AIAR/wCA//8AgP//AIAK/wCACv8AgP//AID//wCAIf8AgAX/AIAh/wCA//8AgP//AIAQAAAAAAAAAAAAAAAA/wCACv8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAUAAAAA/wCABf8AgP//AID//wCACgAAAAD/AIAQ/wCADP8AgCH/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCABf8AgCH/AID//wCA//8AgAv/AIAh/wCA//8AgP//AID//wCA//8AgP//AIAH/wCAB/8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AIAg/wCA//8AgP//AID//wCA//8AgP//AID//wCAB/8AgAf/AID//wCA//8AgP//AID//wCA//8AgP//AIAh/wCAC/8AgP//AID//wCAHP8AgBz/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCACf8AgA7/AIAMAAAAAP8AgAj/AID//wCA//8AgAP/AIAD/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCABQAAAAAAAAAA/wCADf8AgAr/AIAL/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCAB/8AgAr/AID//wCA//8AgCH/AIAH/wCAJf8AgP//AID//wCAI/8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAf/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgCT/AID//wCA//8AgAr/AIAK/wCA//8AgP//AIAKAAAAAP8AgCj/AID//wCA//8AgP//AID//wCA//8AgCP/AIAM/wCA//8AgP//AIAN/wCADf8AgP//AID//wCADQAAAAAAAAAA/wCAEP8AgBH/AIAP/wCAEf8AgBAAAAAAAAAAAP8AgBT/AIAVAAAAAAAAAAD/AIAV/wCAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQcH5rEGA8KxBAHCsQQBwrEEIQKxBAACsQQAArEEAAKxBAQCsQQwArEEAAKxBAACsQYAArEHBmaxB//+sQQ==");
        popup.append(menuitem);
        addDestructor(() => menuitem.remove());

        menuitem.copyImageAsBase64 = () => gBrowser.selectedBrowser.messageManager
            .loadFrameScript("data:;charset=utf-8," + encodeURIComponent(this.code()), false);

        this.handleEvent = () => menuitem.hidden = this.shouldHide;
    },
    get shouldHide() {
        return !gContextMenu.onImage;
    },
    code: () => `(selectors => {

        var getImage = doc => {
            var elm = doc.querySelector(selectors.shift());
            if (selectors.length) elm = getImage(elm.contentDocument);
            return elm;
        }
        var image = getImage(content.document);

        var canvas = image.ownerDocument.createElementNS("${xhtmlns}", "canvas");
        canvas.width = image.naturalWidth;
        canvas.height = image.naturalHeight;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(image, 0, 0);
        var base64 = canvas.toDataURL();

        Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
            .copyStringToClipboard(base64, Ci.nsIClipboard.kGlobalClipboard);

        Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
            .showAlertNotification(base64, "${self.label}", "Запомнил изображение как base64");
    })(${
        JSON.stringify(gContextMenu.targetSelectors)
    })`
}, false, popup || 1))(document.getElementById("contentAreaContextMenu"));


4. В главном меню (т.е. в appmenu)
скрытый текст

Выделить код

Код:

// Добавить новый пункт "Сохранить страницу или выбранное как  PDF" в главном меню .....................................................
(function() {
    // блокировать дублирование пункта при открытии настройки панелей
  if ( document.getElementById("savePageToPDF") ) return;

function savePageToPDF() {
   // сохранить если это веб страница ....     
   //var loc = content.document.location;
   var loc = gBrowser.currentURI.spec;
   var vert = "http://pdfmyurl.com?url=" + loc;
  
   gBrowser. loadURI(vert, {
   triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
   });
   
}; 
    
    var menuItem = document.createXULElement("toolbarbutton");
    menuItem.id = "savePageToPDF";               
    menuItem.setAttribute("label", "Сохранить страницу как PDF");
    menuItem.setAttribute("class", "subviewbutton subviewbutton-iconic");
    menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAAmlJREFUeJx9krtrVEEUh7953OzjmvjAIiqxEqxkkRVchAWtUghWQtJpkUrBFCks/AcEQQVLsUkgnaCgYrU2YdkgEmNpICQQNmDhajbJ3b3zOBaJulvogR8zHOZ8Z878Bv4TNTjXg48VuPqvMxbg89xcWrHW0ulApwPAp/V1llZXrxe8v1SDm5dh5SFw/LDwMeRzkCmALzduvLtw9uyVoBTKOYgRDdBuj8jbt6VvtVp+8vTpzHgPzkG3y4ulpVczIrcBWKnXW359XXpZJvn+vrheT4L3It2uhGpVdl+/lqFYW5PnxeIb4KCRCsHHkRGCtURrEWuJxhCOHEErhZ6fxw8OrhSBg5QGIM8J3hMHJIBqt8lHRzHLy7hW6y8gRuLhdggQQiCEQIyRAEizSVavw6NHmAcPyPP8oCpNkUFAdA7vPf4QEkMgihCbTWK1ip6eZiTL4NYt4sICvHxJGLSRPMd5T3AOlIJSiWR7m7i8jD1zBrl7l91r1yg2GsjsLDI+Tt+YYYB3DhcCUiphtrawT5+SA15r9mZmKFy8CD9/Et+/R9IUPT09AOj36XuPV4p0cREaDbLNTbrz8xw9fx4bAibPkdFR9NQUZmMDQhi+QS7C2LNnuK9foVymd+cO5YkJ4s4OUWswBi0ChQKm1xt+RHGOfpYRv39H//jBbqVCnJxE9vbwzuEH3BEAkT8ACxBE2A+BnXv3KCtFMjZGWWv6xpAkCVgL1qKsRQEUi3/+gQVIQ0iPffiAP3GCQpKQWIv9rSRBa40xBmUMFAqwtYWNsQQcAG/D/VNQCRAjIEA81G+/B1cDegU+tuDJL/RmVAGj5AsYAAAAAElFTkSuQmCC");
    menuItem.addEventListener("command", savePageToPDF, false);  
   var it = document.getElementById("appMenu-print-button");
    it.parentNode.insertBefore(menuItem, it); 
  
 })();
 
 
 
 // Добавить новый пункт "Сохранить страницу или выбранное как  HTML" в главном меню .....................................................
(function() {
    // блокировать дублирование пункта при открытии настройки панелей
  if ( document.getElementById("SavHTML") ) return;

function SaveHTML() {
var vert=`javascript:(function(){var getSelWin=function(w){if(w.getSelection().toString())return w;for(var i=0,f,r;f=w.frames[i];i++){try{if(r=getSelWin(f))return r}catch(e){}}};var selWin=getSelWin(window),win=selWin||window,doc=win.document,loc=win.location;var qualifyURL=function(url,base){if(!url||/^([a-z]+:|%23)/.test(url))return url;var a=doc.createElement('a');if(base){a.href=base;a.href=a.protocol+(url.charAt(0)=='/'%3F(url.charAt(1)=='/'%3F'':'//'+a.host):'//'+a.host+a.pathname.slice(0,(url.charAt(0)!='%3F'&&a.pathname.lastIndexOf('/')+1)||a.pathname.length))+url}else{a.href=url};return a.href};var encodeImg=function(src,obj){var canvas,img,ret=src;if(/^https%3F:%5C/%5C//.test(src)){canvas=doc.createElement('canvas');if(!obj||obj.nodeName.toLowerCase()!='img'){img=doc.createElement('img');img.src=src}else{img=obj};if(img.complete)try{canvas.width=img.width;canvas.height=img.height;canvas.getContext('2d').drawImage(img,0,0);ret=canvas.toDataURL((/%5C.jpe%3Fg/i.test(src)%3F'image/jpeg':'image/png'))}catch(e){};if(img!=obj)img.src='about:blank'};return ret};var toSrc=function(obj){var strToSrc=function(str){var chr,ret='',i=0,meta={'%5Cb':'%5C%5Cb','%5Ct':'%5C%5Ct','%5Cn':'%5C%5Cn','%5Cf':'%5C%5Cf','%5Cr':'%5C%5Cr','%5Cx22':'%5C%5C%5Cx22','%5C%5C':'%5C%5C%5C%5C'};while(chr=str.charAt(i++)){ret+=meta[chr]||chr};return'%5Cx22'+ret+'%5Cx22'},arrToSrc=function(arr){var ret=[];for(var i=0;i<arr.length;i++){ret[i]=toSrc(arr[i])||'null'};return'['+ret.join(',')+']'},objToSrc=function(obj){var val,ret=[];for(var prop in obj){if(Object.prototype.hasOwnProperty.call(obj,prop)&&(val=toSrc(obj[prop])))ret.push(strToSrc(prop)+': '+val)};return'{'+ret.join(',')+'}'};switch(Object.prototype.toString.call(obj).slice(8,-1)){case'Array':return arrToSrc(obj);case'Boolean':case'Function':case'RegExp':return obj.toString();case'Date':return'new Date('+obj.getTime()+')';case'Math':return'Math';case'Number':return isFinite(obj)%3FString(obj):'null';case'Object':return objToSrc(obj);case'String':return strToSrc(obj);default:return obj%3F(obj.nodeType==1&&obj.id%3F'document.getElementById('+strToSrc(obj.id)+')':'{}'):'null'}};var ele,pEle,clone,reUrl=/(url%5C(%5Cx22%3F)(.+%3F)(%5Cx22%3F%5C))/g;if(selWin){var rng=win.getSelection().getRangeAt(0);pEle=rng.commonAncestorContainer;ele=rng.cloneContents()}else{pEle=doc.documentElement;ele=(doc.body||doc.getElementsByTagName('body')[0]).cloneNode(true)};while(pEle){if(pEle.nodeType==1){clone=pEle.cloneNode(false);clone.appendChild(ele);ele=clone};pEle=pEle.parentNode};var sel=doc.createElement('div');sel.appendChild(ele);for(var el,all=sel.getElementsByTagName('*'),i=all.length;i--;){el=all[i];if(el.style&&el.style.backgroundImage)el.style.backgroundImage=el.style.backgroundImage.replace(reUrl,function(a,b,c,d){return b+encodeImg(qualifyURL(c))+d});switch(el.nodeName.toLowerCase()){case'link':case'style':case'script':el.parentNode.removeChild(el);break;case'a':case'area':if(el.hasAttribute('href')&&el.getAttribute('href').charAt(0)!='%23')el.href=el.href;break;case'img':case'input':if(el.hasAttribute('src'))el.src=encodeImg(el.src,el);break;case'audio':case'video':case'embed':case'frame':case'iframe':if(el.hasAttribute('src'))el.src=el.src;break;case'object':if(el.hasAttribute('data'))el.data=el.data;break;case'form':if(el.hasAttribute('action'))el.action=el.action;break}};var head=ele.insertBefore(doc.createElement('head'),ele.firstChild);var meta=doc.createElement('meta');meta.httpEquiv='content-type';meta.content='text/html; charset=utf-8';head.appendChild(meta);var title=doc.getElementsByTagName('title')[0];if(title)head.appendChild(title.cloneNode(true));head.copyScript=function(){if('$'in win)return;var f=doc.createElement('iframe');f.src='about:blank';f.setAttribute('style','position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;');doc.documentElement.appendChild(f);var str,script=doc.createElement('script');script.type='text/javascript';for(var name in win){if(name in f.contentWindow||!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name))continue;try{str=toSrc(win[name]);if(!/%5C{%5Cs*%5C[native code%5C]%5Cs*%5C}/.test(str)){script.appendChild(doc.createTextNode('var '+name+' = '+str.replace(/<%5C/(script>)/ig,'<%5C%5C/$1')+';%5Cn'))}}catch(e){}};f.parentNode.removeChild(f);if(script.childNodes.length)this.nextSibling.appendChild(script)};head.copyScript();head.copyStyle=function(s){if(!s)return;var style=doc.createElement('style');style.type='text/css';if(s.media&&s.media.mediaText)style.media=s.media.mediaText;try{for(var i=0,rule;rule=s.cssRules[i];i++){if(rule.type!=3){if((!rule.selectorText||rule.selectorText.indexOf(':')!=-1)||(!sel.querySelector||sel.querySelector(rule.selectorText))){style.appendChild(doc.createTextNode(rule.cssText.replace(reUrl,function(a,b,c,d){var url=qualifyURL(c,s.href);if(rule.type==1&&rule.style&&rule.style.backgroundImage)url=encodeImg(url);return b+url+d})+'%5Cn'))}}else{this.copyStyle(rule.styleSheet)}}}catch(e){if(s.ownerNode)style=s.ownerNode.cloneNode(false)};this.appendChild(style)};var sheets=doc.styleSheets;for(var j=0;j<sheets.length;j++)head.copyStyle(sheets[j]);head.appendChild(doc.createTextNode('%5Cn'));var doctype='',dt=doc.doctype;if(dt&&dt.name){doctype+='<!DOCTYPE '+dt.name;if(dt.publicId)doctype+=' PUBLIC %5Cx22'+dt.publicId+'%5Cx22';if(dt.systemId)doctype+=' %5Cx22'+dt.systemId+'%5Cx22';doctype+='>%5Cn'};var href = 'data:text/html;charset=utf-8,' + encodeURIComponent(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->');var a = document.documentElement.appendChild(document.createElement("a"));a.setAttribute("href", href);var name = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());name=name.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');name += (function () {var d = new Date(), z=function(n){return '_' + (n < 10 ? '0' : '') + n};return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());})();a.setAttribute("download", name + ".html");a.click();a.remove();})();`;
gBrowser. loadURI(vert, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});
}; 
    var menuItem = document.createXULElement("toolbarbutton");
    menuItem.id = "SavHTML";               
    menuItem.setAttribute("label", "Сохранить страницу или выбранное как HTML");
    menuItem.setAttribute("class", "subviewbutton subviewbutton-iconic");
    menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzElEQVQ4jV2STW8bZRDHf/Psrr11nZhgVKcKaSmUiArRKBRVIMgH4BKJ7xAp5MSFiA+Rc28ckBAoipC4koJQLyAaVFChIlQllDRWmjRev8Qvu14/+wwHx6ZlpNFcZn7zn79GVJW1tbXc6urqijHGqKoAPF3TgcVaq8owXJbphx99fOOnWzcHoqqsr68/t7y83BARVBXnHHraXo3a3HoUU8gFAHRTS2Bg/7C2Zx7vXPIBwjA0p3BU9Zns9i3vvVrhr6MWzlpee+EsRqAbHc3+/Pee7wPkcrkx4P+g0IMvb/5Iv5/iXEaWZQS+By578MaVy9YH8H3fE5FnANZajqMmgcAnH7yN73mICMYMd21sbLy7srKiPkA+n3/qBLhzv8p+EuOfTUjShPbODvOVWa5fnRsvKBaLAcAIMFbw+bc/EBVn8At7SPcQ60LSiVm++P0fGu0e7y++yalvHoABCILAiAj7hzU+vfcVT6zPVGmR3x4/xJoLSH6BVu4cN777nnQwQETI5XL/AYwxRkS4ff8BEk6Q2pBfq3dxUuHMmWt0kgFGStTDY/7YrTLybQwYPU2cpgzsCd1OgmSzWHeOR7VjWicxaT9lxn+HfjoYmWnGHgAiIsydf5HKnUXiThehQDG4Tr3e5KR7hN8XilnGKxfOoyrDgZECwIgIb125xIxxTGVdgjRG4pR2+zbG/sIkD7l2cYJyaYLMOZxzjBV4nueLCI1GnaWFab65t4OXt4gUuFqYJ8gGuPYBCxdLHNciys9PkaapjAHGGM8YQ7lcZv71OaYmC/xZPaJHTN4cUgpDXrr8MtOVaUqTRXzfY3t7u7O0tDR82a2trfkkSTSOY+31etrpdLTZbGoURRpFkdbrTY3qTW00mhrHse7u7t4tl8uhqg4VxHHcPDg4+ExVHeBU1YmIU1WnisucZtamLszn01ar9WRzc/PrWq2WAPwLJ7l2ULfXOAMAAAAASUVORK5CYII=");
    menuItem.addEventListener("command", function(e) {SaveHTML()  }, false);  
    var it = document.getElementById("appMenu-print-button");
    it.parentNode.insertBefore(menuItem, it); 
  
 })();

Отредактировано Andrey_Krropotkin (31-07-2019 07:55:04)

Отсутствует

 

№1356831-07-2019 08:06:38

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2249
UA: Firefox 52.0

Re: Custom Buttons

Andrey_Krropotkin пишет

в папке Temp_ExternalEditor в профиле со временем накапливаются файлы

Ой, я внешним редактором не пользуюсь совсем.
Но, судя по коду, такого быть не должно, однозначно.
И вообще, вся идея сломана аж с FF63 из-за удаления nsIUTF8ConverterService

скрытый текст
Собрал бы новую версию, но у меня там ещё кот не валялся.
Давай пока попробую предложить патч, оформленный как код
для Инициализации CB кнопки.

Нужен рестарт, код вообще не restartless.

Если всё работает, тогда оставлю это изменение в CB,
и тут главное не забудь удалить код патча из Инициализации,
если случится обновление расширения.

Выделить код

Код:

(async (sg, key, repl) => {
    if (key in sg) return;

    var url = "chrome://custombuttons/content/editExternal.js";
    var code = await (await fetch(url)).text();
    var newCode = code.replace(/function checkfocus_window[\s\S]+?^}/m, repl.trim());

    var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
    sg[key] = ams.registerChrome(
        Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)),
        [["override", url, "data:," + encodeURIComponent(newCode)]]
    );
})(Cu.getGlobalForObject(Cu), "TempCBeditExternalPatchHelper", `

function checkfocus_window() {
    for(var cbeditor of _target)
        cbeditor.hasAttribute("filename") && checkfocus_cbeditor(cbeditor);
}

function checkfocus_cbeditor(cbeditor) {
    var readFile = Components.utils.readUTF8File || function(file) {

        var istream = Cc['@mozilla.org/network/file-input-stream;1']
            .createInstance(Ci.nsIFileInputStream);
        // FileInputStream's read is [noscript].
        var sstream = Cc["@mozilla.org/scriptableinputstream;1"]
            .createInstance(Ci.nsIScriptableInputStream);
        var converter = Cc['@mozilla.org/intl/utf8converterservice;1']
            .createInstance(Ci.nsIUTF8ConverterService);

        return (readFile = function(file) {
            istream.init(file, 1, 0x400, false);
            sstream.init(istream);
            var res = sstream.read(sstream.available());
            sstream.close(); istream.close();
            if (res.length) converter.convertStringToUTF8(res, _encode, true, false);
            return res;
        })(file);
    }
    var file = Cc["@mozilla.org/file/local;1"]
        .createInstance(Ci.nsILocalFile || Ci.nsIFile);

    (checkfocus_cbeditor = function(cbeditor) {
        file.initWithPath(cbeditor.getAttribute("filename"));
        if (
            file.exists() && file.isReadable() &&
            file.lastModifiedTime > cbeditor.getAttribute("timestamp")
        ) {
            cbeditor.setAttribute("timestamp", file.lastModifiedTime);
            cbeditor.value = readFile(file);
            try {
                file.remove(false);
            } catch(ex) {
                Components.utils.reportError(ex);
            }
        }
    })(cbeditor);
}

`);

есть вот кнопка, вроде все работает, но почему-то ошибки в консоли выскакивают

Я говорил кто воротит нос от элемента, созданного другим документом?

скрытый текст

Выделить код

Код:

/*
               // добавить кнопку "Изменить" ....
               var changePassBut = document.createXULElement("button");
               //changePassBut.setAttribute("label", "Изменить");
               changePassBut.setAttribute("id", "changePassword");
               changePassBut.setAttribute("disabled", true );   
               buttons[0].parentNode.insertBefore( changePassBut, buttons[2] );               
               var changePasshbox = document.createXULElement("hbox");
               changePasshbox.setAttribute("class", "box-inherit button-box");
               changePasshbox.setAttribute("align", "center");
               changePasshbox.setAttribute("pack", "center");
               changePasshbox.setAttribute("flex", "1");
               changePassBut.appendChild( changePasshbox );

              var changePasslabel = document.createXULElement("label");
              changePasslabel.setAttribute("class", "button-text");
              changePasslabel.setAttribute("value", "Изменить");
               changePasshbox.appendChild( changePasslabel );
*/
               // добавить кнопку "Изменить" ....
               var changePassBut = doc.createXULElement("button");
               changePassBut.setAttribute("label", "Изменить");
               changePassBut.setAttribute("id", "changePassword");
               changePassBut.setAttribute("disabled", true);
               buttons[2].before(changePassBut);

Отредактировано Dumby (31-07-2019 08:08:59)

Отсутствует

 

№1356931-07-2019 08:20:20

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 68.0

Re: Custom Buttons

Dumby вроде патч работает, а там еще понаблюдаю. Я пользуюсь внешним когда код большой, вроде как бекапа, т.е. открыл во внешнем, сам редактирую обычным, если надо откатиться из внешнего возвращаю. Ошибки в консоли исчезли, спасибо.

Отредактировано Andrey_Krropotkin (31-07-2019 08:28:05)

Отсутствует

 

№1357031-07-2019 14:03:50

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 68.0

Re: Custom Buttons

Кнопка СВ -"убрать/вернуть адрес (в адрес.строке)

Выделить код

Код:

custombutton://%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22UTF-8%22%3F%3E%0D%0A%3Ccustombutton%20xmlns%3Acb%3D%22http%3A//xsms.nm.ru/custombuttons/%22%3E%0A%20%20%3Cname/%3E%0A%20%20%3Cimage%3E%3C%21%5BCDATA%5Bdata%3Aimage/png%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAYAAAAmlE46AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAE6AAABOgBdZN6YAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAHjSURBVCiRhVK/a1NhFD33vu/5MG+IQxBSkBCHRLLEltQEJIt2FRQn3URwKRIQQTJoZ8V/QJRKoeDklkAXF4lYAhEcfBniUysK0jcksVr68r4fLu0jaRI8070HznfOd7hkjME42u32DSHEvdFotF2pVO5iDmjt4sm3w9AsQ2sQNBZvPrBPZYsc7u/h44v7odr/bZgIhq0vS7kzl65v9HYBgGpXK2r1yQYrpRBFEf7u/YGUEaSUgDFgMpBSovH6Feyd93ceb/WeA4A4IQTOZrPzEsXwPmxj5+s7OtoZbP1XBABG64ldMDONE0EQYH39JSzLAhGBiMDM+NT9jJ8Hp28XCgXyPO+ZIOKJl3zfx+WVFZTL5SnXVqt1odFolKrV6jUGTwqNMSCiKREA5HI5pNNpzmQyy4KP/VFrDSKC53no9/sx7zgOSqUSarUa6vX6UPAxR31YQj6fj+epoozRAjQ7qu/7GAwGE47FYhEAQERa0AxHIoKUElEUxfx4MmbGVKtHt+u6Lsbv2LbteLYsy8x0NMYglUohmUzOd/z1rffj4a0raTCDifF9d0ira08tx3Hguu5UMWEYwrZtEgcLS+fedLvnlVIAgCAIFpObm4+azaaSUpowDPVhOVYikVBCCNHpdNQ/dx7FVwUNykQAAAAASUVORK5CYII%3D%5D%5D%3E%3C/image%3E%0A%20%20%3Cmode%3E0%3C/mode%3E%0A%20%20%3Cinitcode%3E%3C%21%5BCDATA%5B/*Initialization%20Code*/%0Avar%20urlbar%20%3D%20document.getElementById%28%22page-action-buttons%22%29%3B%0Avar%20button2%20%3D%20document.getElementById%28_id%29%3B%0Aurlbar.insertBefore%28button2%2C%20urlbar.Child%29%3B%0A%0Athis.onclick%20%3D%20this.oncontextmenu%20%3D%20function%28event%29%20%7B%0Aif%20%28event.button%20%3D%3D%200%29%20%7B%0AgURLBar.inputField.focus%28%29%3B%0AgURLBar.inputField.editor.selectAll%28%29%3B%0AgoDoCommand%28%22cmd_delete%22%29%3B%0AgURLBar.view.close%28%29%3B%0A%7D%0Aif%28event.button%20%3D%3D%202%20%26%26%20%21event.ctrlKey%20%26%26%20%21event.shiftKey%20%26%26%20%21event.altKey%20%26%26%20%21event.metaKey%29%7B%0AgoDoCommand%28%22cmd_undo%22%29%3B%0AgoDoCommand%28%22cmd_switchTextDirection%22%29%20%20%20%20%0AgoDoCommand%28%22cmd_switchTextDirection%22%29%0AgURLBar.inputField.blur%28%29%3B%20%20%0A%7D%0A%7D%3B%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0Athis.oncontextmenu%20%3De%3D%3E%20%7B%20e.button%20%26%26%20%21e.ctrlKey%20%26%26%20e.preventDefault%28%29%20%7D%3B%0Athis.tooltipText%20%3D%20%22%u041B%3A%20%u0421%u0431%u0440%u043E%u0441%u0438%u0442%u044C%20%u0430%u0434%u0440%u0435%u0441%5Cn%u041F%3A%20%u041E%u0431%u0440%u0430%u0442%u043D%u043E%20%u0430%u0434%u0440%u0435%u0441%22%3B%20%0Avar%20style%20%3D%20custombutton.buttonGetHelp%28self%29.replace%28/id/g%2C%20_id%29%3B%0Avar%20uri%20%3D%20makeURI%28%27data%3Atext/css%2C%27+%20encodeURIComponent%28style%29%29%3B%0Avar%20sss%20%3D%20Cc%5B%22@mozilla.org/content/style-sheet-service%3B1%22%5D.getService%28Ci.nsIStyleSheetService%29%3B%0Asss.loadAndRegisterSheet%28uri%2C%200%29%3B%20%5D%5D%3E%3C/initcode%3E%0A%20%20%3Ccode%3E%3C%21%5BCDATA%5B/*CODE*/%5D%5D%3E%3C/code%3E%0A%20%20%3Caccelkey%3E%3C%21%5BCDATA%5B%5D%5D%3E%3C/accelkey%3E%0A%20%20%3Chelp%3E%3C%21%5BCDATA%5B%23id%20%7B%0Amargin-top%3A%20-1px%20%21important%3B%0Amargin-right%3A%201px%20%21important%3B%0Amargin-left%3A%20-3px%20%21important%3B%0A%7D%20%5D%5D%3E%3C/help%3E%0A%20%20%3Cattributes/%3E%0A%3C/custombutton%3E

Отсутствует

 

№1357131-07-2019 17:08:59

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 68.0

Re: Custom Buttons

egorsemenov06 одну пока еще не получилось сделать, пока две кнопки, думаю иконки под кнопки подберете
1 кнопка скриншоты

скрытый текст

Выделить код

Код:

/*Initialization Code*/

((main, parts) => this._handleClick = () => {
    var df = MozXULElement.parseXULToFragment(`
        <menupopup>
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить всю страницу как PNG"
                value="all"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить видимую часть страницы как PNG"
                value="page"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAIBkAAAEAIAAMDQAAFgAAACgAAAAgAAAAMgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29fT/2tra/8jIyP/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8jIyP/a2tr/9vX0/+zs7P/ak0b/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/9qTRv/s7Oz/7Ozs/+J9Dv/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+/6SdmP/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/+vn4//z7+v/6+fj/4n0O/+zs7P/s7Oz/4n0O//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/aFtT//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//j39v/ifQ7/7Ozs/+zs7P/ifQ7/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P9oW1P/7+zq/+/s6v/v7Or/8O3r//Dt6//w7ev/8O3r//Dt6//w7ev/8O3r/+/s6v/w7ev/9fTy/+J9Dv/s7Oz/7Ozs/+J9Dv/49/b/+Pf2//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4/2hbU//q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/y8O//4n0O/+zs7P/s7Oz/4n0O//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/aFtT/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe//Dt6//ifQ7/7Ozs/+zs7P/ifQ7/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P9oW1P/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/7uro/+J9Dv/s7Oz/7Ozs/+J9Dv/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx/2hbU//x7+3/8vDv//Hv7f/x7+3/8e/t//Lw7//x7+3/8e/t//Lw7//x7+3/8vDv//Hv7f/29fT/4n0O/+zs7P/s7Oz/4n0O//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//aFtT/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/8vGwf/ifQ7/7Ozs/+zs7P/ifQ7/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f9nWlL/aFtT/2hbU/9nWlL/Z1pS/2hbU/9oW1P/Z1pS/2daUv9oW1P/aFtT/2hbU/9nWlL/pJyX/+J9Dv/s7Oz/7Ozs/+J9Dv/w7ev/8O3r//Dt6//w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Hv7f/w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Dt6//w7ev/4n0O/+zs7P/s7Oz/4n0O/+/s6v/v7Or/7uro/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/u6uj/7+zq/+/s6v/ifQ7/7Ozs/+zs7P/ifQ7/7uro/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7Ojm/+J9Dv/s7Oz/7Ozs/+J9Dv/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/4n0O/+zs7P/s7Oz/4n0O/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/ifQ7/7Ozs/+zs7P/ifQ7/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+J9Dv/s7Oz/7Ozs/+J9Dv/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/4n0O/+zs7P/s7Oz/4n0O/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/ifQ7/7Ozs/+zs7P/ifQ7/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+J9Dv/s7Oz/7Ozs/+J9Dv/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/k39z/4n0O/+zs7P/s7Oz/4n0O/+Lc2f/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/ifQ7/7Ozs/+zs7P/ifQ7/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+J9Dv/s7Oz/9fTy/+J9Dv/8+/r/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/4n0O//X08v/8+/r/6KFU/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ooVT//Pv6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить выбранный элемент страницы как PNG"
                value="click"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAADDn2Hfz5pE/8eVQP7IlkH/yJZB/8iWQf/IlUH/yJVA/8iVQP/IlED/yJQ//8iUP//IlD//yJM+/8iTPv/Hkj3/nI1w//bDbP//8OH//+zW///s1///69b//+rV///p1P//59L//+XQ///izf//38n//9vG///ZxP//1b///dG////Prf/KlkX/88N4/v37///99Pj//fT6//vy9v/68fT/+u/y//rt8P/66u3/+ufq//rl6P/64eT/+93h//3a3//71d7//9LK/86XR//0xHb//vv////18///9fT///f5///4////9f7///P8///v+f//7Pb//+nz///m8f//4eb//9vZ//3Y2v//1Mb/zphH//TGd//+/////Pj1///7///Q58r/m9aV/6TZnv+i15r/otWY/6LTlv+j0pb/mc6M/9DXuf//3+P//Nnc///Wyf/OmUf/9MZ3//7////8+/j//////53WnP+Y5pn/rvGv/6PvpP+e7p//me6b/5nvm/95533/mM+L///j7f/629z//9jL/86ZR//0xnf//v////z9+v//////qtup/8Xzxf/a/tn/z/vO/8n7yf/D+sL/xPvD/6Hzo/+j05b//+Tu//re3///2cz/zplI//XGeP/+/////P36//////+n26f/uvC6/9T71P/K+Mr/xvjG/8D3wP+/+L//nfCf/6LTlf//5u//+t/g///cz//OmUj/9MZ3//7////8/fr//////6rcqv/G9MX/3//f/9n92f/V/NX/0PzQ/9H+0P+s9a7/pdSY///o8f/64OL//9zP/86aSP/0xnf//v////z9+f//////ndid/5TjlP+v7q//qeyp/6jsqf+k7KX/p+6n/4Tlh/+Z0Y7//+r0//rh4v//3tH/zppI//TGd//+/////v77///////Y8Nj/p9+n/6/jr/+t4a3/rd2p/67bpv+u2ab/p9Wc/9jgx///6Oz//OPl///e0f/Omkj/9MV1//7//////fr///78///+/f///////////////////P////j////0+///8fn//+vu///m4v/94+P//97P/86ZSP/zx3v//v/////+/f///////f////v////7////+/////v+///7+///+/f///vz/P/98Pr//+33//3p9///5OL/zppL//a1Sv/0xoL/9cR7//XEfP/1xHz/9cR8//XEfP/1xH3/9cR8//XCev/1wXr/9b94//W9d//1u3X/87l0//y6bP/Llj7/+pMA/vWBAP/1gwD/9YMA//WDAP/1gwD/9YMA//WDAP/1gwD/9YQA//WEAP/1hAD/9YQA//WEAP/zhAH//okA/8qLIv3xpzP/4ptV/+OdU//jnVP/451T/+OdU//jnVP/451T/+OdU//jnVL/451S/+OdUv/jnVL/451S/+GdVf/qnUf/2aRJ/9q0c9/8yn7/98V5/vjGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6/vrIe/+jj2y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить выбранную область страницы как PNG"
                value="clipping"/>
        </menupopup>
    `);
    var popup = df.firstChild;
    popup.setAttribute("context", "");
    popup.setAttribute("oncommand", "handleCommand(event);");
    popup.handleCommand = e => {
        var name = _id + ":DataURLReady";
        main = main.replace("%MESSAGE_NAME%", name);

        var urls = {}, configurable = true, enumerable = true;
        Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, {
            configurable, enumerable, get() {
                var value = `data:;charset=utf-8,({${
                    encodeURIComponent(main + part)
                }%0A}).init("${key}")`;
                Object.defineProperty(urls, key, {configurable, enumerable, value});
                return value;
        }}));
        var getTabLabel = () => {
            var label = gBrowser.selectedTab.label;      
            var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
            return label.substring(0, 50);
        }
        var listener = msg => {
            var fp = makeFilePicker();
            fp.init(window, "Сохранить как…", fp.modeSave);
            fp.appendFilter("", "*.png");
            fp.defaultString = getTabLabel() + ".png";   
            fp.open(res => res == fp.returnCancel || !fp.file || makeWebBrowserPersist().saveURI(
                Services.io.newURI(msg.data), document.nodePrincipal,
                null, null, null, null, null, fp.file, null
            ));
        }
        messageManager.addMessageListener(name, listener);
        addDestructor(() => messageManager.removeMessageListener(name, listener));

        (popup.handleCommand = e => gBrowser.selectedBrowser.messageManager
            .loadFrameScript(urls[e.target.value], false)
        )(e);
    }
    this.append(df);
    (this._handleClick = () => popup.openPopup(this, "after_start"))();
})(`
    init(cmd) {
        cmd.startsWith("c")
            ? this[cmd].init(this[cmd].parent = this)
            : this[cmd]();
    },
    capture(win, x, y, width, height) {
        var canvas = win.document.createElementNS("${xhtmlns}", "canvas");
        canvas.width = width;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        var tryDraw = ind => {
            try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")}
            catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);}
        }
        tryDraw(17);
        sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png"));
    },
    `, {

    all: `all() {
        var win = content;
        this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY);
    }`,
    page: `page() {
        var win = content, doc = win.document, body = doc.body, html = doc.documentElement;
        var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft;
        var scrY = (body.scrollTop || html.scrollTop) - html.clientTop;
        this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight);
    }`,
    clipping: `clipping: {
        handleEvent(e) {
            if (e.button) return false;
            e.preventDefault();
            e.stopPropagation();
            switch(e.type) {
                case "mousedown":
                    this.downX = e.pageX;
                    this.downY = e.pageY;
                    this.bs.left = this.downX + "px";
                    this.bs.top = this.downY + "px";
                    this.body.appendChild(this.box);
                    this.flag = true;
                    break;
                case "mousemove":
                    if (!this.flag) return;
                    this.moveX = e.pageX;
                    this.moveY = e.pageY;
                    if (this.downX > this.moveX) this.bs.left = this.moveX + "px";
                    if (this.downY > this.moveY) this.bs.top  = this.moveY + "px";
                    this.bs.width = Math.abs(this.moveX - this.downX) + "px";
                    this.bs.height = Math.abs(this.moveY - this.downY) + "px";
                    break;
                case "mouseup":
                    this.uninit();
                    break;
            }
        },
        init() {
            var win = {};
            Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
                .getFocusedElementForWindow(content, true, win);
            this.win = win.value;

            this.doc = this.win.document;
            this.body = this.doc.body;
            if (!HTMLBodyElement.isInstance(this.body)) {
                Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
                    .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!");
                return false;
            }
            this.flag = null;
            this.box = this.doc.createElement("div");
            this.bs = this.box.style;
            this.bs.border = "#0f0 dashed 2px";
            this.bs.position = "absolute";
            this.bs.zIndex = "2147483647";
            this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor;
            this.body.style.cursor = "crosshair";
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)];
            this.body.style.cursor = this.defaultCursor;
            this.body.removeChild(this.box);
            this.parent.capture.apply(this, pos);
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`,
    click: `click: {
        getPosition() {
            var html = this.doc.documentElement;
            var body = this.doc.body;
            var rect = this.target.getBoundingClientRect();
            return [
                this.win,
                Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft,
                Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop,
                parseInt(rect.width),
                parseInt(rect.height)
            ];
        },
        highlight() {
            this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false;
            this.target.style.cssText += "outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;";
        },
        lowlight() {
            if (this.orgStyle) this.target.style.cssText = this.orgStyle;
            else this.target.removeAttribute("style");
        },
        handleEvent(e) {
            switch(e.type){
                case "click":
                    if (e.button) return;
                    e.preventDefault();
                    e.stopPropagation();
                    this.lowlight();
                    this.parent.capture.apply(this, this.getPosition());
                    this.uninit();
                    break;
                case "mouseover":
                    if (this.target) this.lowlight();
                    this.target = e.target;
                    this.highlight();
                    break;
            }
        },
        init() {
            this.win = content;
            this.doc = content.document;
            ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            this.target = false;
            ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`
});


2 кнопка все что у меня есть для Save, не забудть вставить свое место сохранения  в строке "folderpath"
скрытый текст

Выделить код

Код:

// Save, от 07.03.2017. .............

self.label = "Save";
self._handleClick =()=> menuPopup.openPopup(this, "after_start");
self.image = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";



var folderpath="C:\\Users\\_________\\Desktop";         // папка для сохранения иконок для ярлыков и ярлыков сайтов


// Создать меню для кнопки .............
var array = [
   { label: "Сохранить значок веб-сайта", func: "saveFavicon()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACPVBMVEX09ff////C3L+Uq8+Vq8+Uqs+Zr9CZrtCZr9Gfu+ear8+mt9JRf8ORxl3t8vfF06+Twojs8/d9otl8o9s+aquZrs/X9KLp8Pft8fZhisf//+DBzN2hveihv+pii8hti9pgicl6oNlojs1zncNsi836/P2duebx8/eYyWqBp+Gn0IKBvlKHsm9qmaVuk8zt7/FEbauEv1Tp7/JdhL9oi9Pl8e2LwlmdsdD7/P76+/3H7ofo8+peh8eHwFaSteZ0pkp2gl7q8/Ohy5OApt2by2eZuOqbuOWaezWuvtd7nN2HvWxul9Ty9feQxV5ljcqBp+JEcLCVtOOo0nR7odx5n9suX6Z1mtBzmtSXyGPv9PewzfOzx+O6zu/s8fd9o95Xfrthi8lYhMN5oNnw9ffw9Pjw9Pf8/f6ewO/m8O9zmdE6aapsjdyUwouPxWPDzd6XteOSs9B5nNVpnpqHt7h/s6F6n9d7ntSTttGHwVh4qp+Ev1HH7ox6qk5wj+Hm8e3t9fOm0IKAtqOBpNrx+P9ljcyhs9FpkM2hv+/u8/fF0eOLu4N+vFKgzX3p9OSFqN13qExekIl4n9j7/P3x9PhxmNDm8e9Vg8Zfkozr8veq0YTX9qL//92AtamOwnHFz96Fot1diMh+pd13ntmatu+YyW/3+/+Tqs5UgcShzJNbhsdTf8GHs7bo8PaXtuqMr+Ty8/SZt+SUqs7r7Ox3ndb9/f7t8feZyXGYyWWCpNbz9PRuiteNtNDn7/V4ntjx8fGo3JqNAAAAv3RSTlP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AEVuhDkAAAD+SURBVBhXY5jHzcUMAqxAICq9bx8D96adDFAgaGQOFOBaH7h7zoqZDTlFyptncAAFWBjyi52CXCI0unRLxcECPhsatbbzmlXMnS60hg0kkOxW0uNrq93tNaFpD1ggUm21QK532ZQdSm1hmXKdDCwdnOWVOi1RjNGMQCCrwMDMJ8NZ4LAynVGPkXFp8zpJBubYmn579wXtqhZb0iwn9a1iWLaViYmJ3891obOwYtLEvcYMGyWAAkwJdv6accEhi8LjGVr11SenpC5f61g3NcO0vjCAIc+DjZ2dnWexddWSbYa9nlkM+8BgWsxsK7FZ1VLzRaACNokmtdnyu1QMQgF7Rlh4zWWTAwAAAABJRU5ErkJggg=="},
   { label: "Запомнить значок веб-сайта как base64", func: "copyFaviconData()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAI2bv/9RVpf/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAACIkvD/Jia6/ywpq/8AAAAAAAAAAAAAAAAAAAD/AAAA/wbwAf90qpv/Ymic/1RWqP9OUKr/W2Ch/2dumf9YYKT/Ly/B/xQP3/8MB9P/JCGb/wAAAAAAAAAAAAAAAAAAAP8G8AH/U5ea/ycr8f8VIP3/HiP4/ywo8v8sIvb/LCL2/ywi9v8KBOj/BQDe/wQAtv8tK4P/AAAAAAAAAAAAAAD/BvAB/3Sqm/9iaJz/Tim3/0UuuP9GPrT/R0ex/zk8uf8gIMz/FRDe/xEMzv8jIJz/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8AAAD/SqOR/yImvP8sLKj/AAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/BvAB/3Sqm/9KW5r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAABvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAG8AH/AAAAAAAAAP8G8AH/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BvAB/wbwAf8AAAAAAAAA/wAAAP8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAG8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOesQQBjrEGAAaxBwACsQcABrEHDg6xBwAesQcAPrEHAD6xBw8+sQcPprEHD8axBwAGsQQABrEGAAaxB//+sQQ=="},  
   { separator: ''},
   { label: "Сохранить ярлык страницы как…", func: "saveShortcuts()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP8E/yT/BP8k/5XLDv/zqgD/86oA//I1///yNf//86oA//OqAP/zqgD/86oA//OqAP+Vyw7/lcsO/wT/JP8E/yT/BP8k/5XLDv+Vyw7/86oA//OqAP/yNf//8jX///OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//02AP/9NgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/9NgD//TYA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA/wA31v8AN9b/86oA//9If///SH//86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP8AN9b/ADfW//OqAP//SH///0h///OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/5XLDv+Vyw7/86oA//OqAP/zqgD/86oA/0CA//9AgP//86oA/07+9f9O/vX/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP9AgP//QID///OqAP9O/vX/Tv71//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ=="},
   { separator: ''},  
   { label: "Кодировать изображение(текст.файл) в base64", func: "copyFaviconbase()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AIAQ/wCAEf8AgA//AIAR/wCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AgBX/AIAVAAAAAAAAAAD/AIAo/wCA//8AgP//AID//wCA//8AgP//AIAoAAAAAAAAAAAAAAAAAAAAAP8AgBL/AID//wCA//8AgA3/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgBAAAAAAAAAAAAAAAAD/AIAR/wCA//8AgP//AIAK/wCACv8AgP//AID//wCAIf8AgAX/AIAh/wCA//8AgP//AIAQAAAAAAAAAAAAAAAA/wCACv8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAUAAAAA/wCABf8AgP//AID//wCACgAAAAD/AIAQ/wCADP8AgCH/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCABf8AgCH/AID//wCA//8AgAv/AIAh/wCA//8AgP//AID//wCA//8AgP//AIAH/wCAB/8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AIAg/wCA//8AgP//AID//wCA//8AgP//AID//wCAB/8AgAf/AID//wCA//8AgP//AID//wCA//8AgP//AIAh/wCAC/8AgP//AID//wCAHP8AgBz/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCACf8AgA7/AIAMAAAAAP8AgAj/AID//wCA//8AgAP/AIAD/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCABQAAAAAAAAAA/wCADf8AgAr/AIAL/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCAB/8AgAr/AID//wCA//8AgCH/AIAH/wCAJf8AgP//AID//wCAI/8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAf/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgCT/AID//wCA//8AgAr/AIAK/wCA//8AgP//AIAKAAAAAP8AgCj/AID//wCA//8AgP//AID//wCA//8AgCP/AIAM/wCA//8AgP//AIAN/wCADf8AgP//AID//wCADQAAAAAAAAAA/wCAEP8AgBH/AIAP/wCAEf8AgBAAAAAAAAAAAP8AgBT/AIAVAAAAAAAAAAD/AIAV/wCAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQcH5rEGA8KxBAHCsQQBwrEEIQKxBAACsQQAArEEAAKxBAQCsQQwArEEAAKxBAACsQYAArEHBmaxB//+sQQ=="},
   { separator: ''},
   { label: "Сохранить всю страницу как PDF", func: "savePageToPDF()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYUw4pJt3V/+Rb1D8lnFP/55zTf+VcVH/lXJS/5VyUv+VclL/lXJS/5VyUv+VclL/k3BR/J56Wv9cRzSkAAAAAJNvUKTto2L/4ppe/uehZf/Pmmr/noZv/9Scav/Wl17/1plh/9eZYf/XmWH/15lh/9eZYf/WmGD/2Jlg/suRXP9mRiuk8rWA/397dP1akKn/rqqi/3LF3f8Mntj/4dLJ///+9f/48u3/9e7n//bt5v/47+f/+O/n//jv5//rvZP/1ZJX/a9/VP9+lrD8AIvz/xOt+f8Douv/ALb6/wC28/9tmar/z8jJ//Lq5/////7//v////n9///6/P3//////+Ta0P/PjVP/pnpT/IWds/+aiXj/5efl/8Px//951/3/LMz//wCx8/8GltL/NIu3/4ycqf/l29L////+//n6+//8/v//3tXM/8+OVP+oe1P/6K57/86QWP/r6Ob////////++v/r9/z/oOb9/zDL//8Arf//AI/r/ydysv+hpqr//PTr///////d1Mz/0I5U/6h7U//osH//wo5g/+fm5P/7/f//9vf5//z7+////vv/9/r8/5Dc/P8Oqv7/AJf//wF02v9ffZ7/8Ojh/+Ha1P/NjFL/qHtT/+ewf//Ej1//7O3r///////+/v7//v7+//f5+v/6+vv////8/8Tq/f8hp/7/AJH//wB18/8/bqj/1MGu/9mXXv+leVH/569+/8iSYv+/tKn/wLew/8O5sf/P0M////////7+/v/3+fv////7/9Hv/v8hoP3/AIn//wB4/v84ZqL/w4NH/619VP/nsYD/x45c/9W5of/bv6j/0Jxt/6J/YP+spqD/2N3i//7////6+/3///76/8vr/v8Slv7/AIb+/wBz//83VH7/nW1B/+ewfv/Fjl7/7Ozr///////9+/r/9d7K/9Ghdv+jd1D/pJ6Y/+jt8f/9///////7/6fb/v8Ahv7/AYD//wRp6f95YlT/57B//8SOXv/n5uT//v7///r7/P/8/v////////XRsv/DhEv/loBu/9DX3P/9/v/////7/2O6/f8Afv//FnTU/5JtTf/nsH//xY9e/+jn5f/+/f//+fj5//n4+P/5+Pn/+/////Xbxf/Wj1D/nX1h/+Ll6P////7/3+/3/w+V//8tcbP/qHJB/+WuffzCjV7/5efn///////+/v7//////////////v7///////XRsP/TnW3/8fT3//////////z/ddD//0Nxl/+zdkH88LmH/9CRWP2+qJT/0M7N/8/Jxv/Pysf/z8rH/8/Kxv/Py8n/zsO6/7+pmP/PzMv/zsnG/9bNyP+nsK7/h4R3/b2BT/+Sb1Ck7qxw/9GSW/69hlb/wYhX/8CIV//AiFf/wIhX/8CIVv/BiVj/xI1d/8CIVv/BiFf/vYZW/9STW/7ppmv/bE80pAAAAACUd16k+sui/+7AmPzwwpr/8MKa//DCmv/wwpr/8MKa//DCmf/vwZj/8MKa//DCmv/uwJj8+cui/5N3XaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
   { label: "Сохранить всю страницу или выбранное как HTML", func: "savePageToHTML()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzElEQVQ4jV2STW8bZRDHf/Psrr11nZhgVKcKaSmUiArRKBRVIMgH4BKJ7xAp5MSFiA+Rc28ckBAoipC4koJQLyAaVFChIlQllDRWmjRev8Qvu14/+wwHx6ZlpNFcZn7zn79GVJW1tbXc6urqijHGqKoAPF3TgcVaq8owXJbphx99fOOnWzcHoqqsr68/t7y83BARVBXnHHraXo3a3HoUU8gFAHRTS2Bg/7C2Zx7vXPIBwjA0p3BU9Zns9i3vvVrhr6MWzlpee+EsRqAbHc3+/Pee7wPkcrkx4P+g0IMvb/5Iv5/iXEaWZQS+By578MaVy9YH8H3fE5FnANZajqMmgcAnH7yN73mICMYMd21sbLy7srKiPkA+n3/qBLhzv8p+EuOfTUjShPbODvOVWa5fnRsvKBaLAcAIMFbw+bc/EBVn8At7SPcQ60LSiVm++P0fGu0e7y++yalvHoABCILAiAj7hzU+vfcVT6zPVGmR3x4/xJoLSH6BVu4cN777nnQwQETI5XL/AYwxRkS4ff8BEk6Q2pBfq3dxUuHMmWt0kgFGStTDY/7YrTLybQwYPU2cpgzsCd1OgmSzWHeOR7VjWicxaT9lxn+HfjoYmWnGHgAiIsydf5HKnUXiThehQDG4Tr3e5KR7hN8XilnGKxfOoyrDgZECwIgIb125xIxxTGVdgjRG4pR2+zbG/sIkD7l2cYJyaYLMOZxzjBV4nueLCI1GnaWFab65t4OXt4gUuFqYJ8gGuPYBCxdLHNciys9PkaapjAHGGM8YQ7lcZv71OaYmC/xZPaJHTN4cUgpDXrr8MtOVaUqTRXzfY3t7u7O0tDR82a2trfkkSTSOY+31etrpdLTZbGoURRpFkdbrTY3qTW00mhrHse7u7t4tl8uhqg4VxHHcPDg4+ExVHeBU1YmIU1WnisucZtamLszn01ar9WRzc/PrWq2WAPwLJ7l2ULfXOAMAAAAASUVORK5CYII="},
   { label: "Сохранить выделенный текст как txt файл", func: "saveSelectionToTxt()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAQE6AAAAZAAAAGgAAAJmAAACZgAAAGYAAABmAAAAZgAAAGYAAABmAAAAZgAAAGYAAABlAAAAaQABAmYAAQEjAAAAADlVkOdVcKHxVXKi8kdklPJLZpfyU3Cg8lJvn/JRbZ7yUW+g8lFun/JRbp/yUG6e8lVyofFVdKjzLkV45wAAAFABAQEAaIzF/3y34v9wsuL/cJe0/0lpgv9bjLP/dLLh/2+v3v9sq9v/cK3d/3Gv3v9sqtv/b7Df/4G77P9VcqT2AAAAVAMDAQBnir/+ZqfU/pDB4/7a3uD+j46N/kxYXv6To6/+1er4/tXp+P7J3/D+1ej4/svg8v6Gut/9aqzd/lhxnvAAAABSAwIBAGaIvv9pptX/ocfj//f4/P/P0tX/g4CA/1xZWf+Woqr/2uz8/9Hl+f/W5fT/2Of3/5fC4v5tq93/Vm+e8QAAAFIDAgEAaYm+/3mw2/+iyeX/9Pn8/+z0+//IzNL/d3h5/0tMTv+Mkpn/xdvs/9Hp/f/O4PL/msXk/nmz4/9XcJ/xAAAAUgMDAQBti7//k7/h/6fL5v/v9fn/4u73/9Dk9P+8wMT/YGpx/zJJWv94iJf/ztzo/9Pp/P+ZwuD+gLfk/1dwnvEAAABSAwMBAHOPwf+myub/sNHp//j7/P/6/P3/8fr///r39P+sxdP/IXWq/xJJcv+NjZD/0+Lu/6TN7f6Ft+L/WXGf8QAAAFIDAwEAd5LD/7PR6/+ZxOP/0ePx/97r9f/Y5/L/3e32/8Tc7f9gseT/CHK3/zBYdv+HiY7/lL/f/pLE7/9bcJ3xAAAAUgMDAQB4k8P/xNvx/5/F5f+kyOX/qMrn/6TH5f+kyOX/sM/q/5e51P9Mm83/GHm3/xxIav9fdYf+pMvs/1x1pfIAAABTAwMBAHmSxf/O4/T/y9/y/8Hb9P/C3PX/wNv0/7vW7/+93ff/utDm/42fsf9Gjbn/EXS2/ytSbv6Fj5r/WnGc8gAAAFICAwEBepPE/tHk9f/S5PX/vMjV/7fCzP+3w8//uMPP/7XBzP+6ytf/qa+4/3h/hv9Ghaz/JoO+/jNXdP82PVnyAAAAVgACAgCBmcb/2+r3/dHh8fyPkpX/kI6N/5yam/+dnJ3/paWk/6enpf+sr6//mpSR/3Bubf9SjbD8H4C+/QsrSvcCAAB/AAAAA3yVx//j8///3u/7/52gpf6pqKf+uLm5/rq7u/7Ly8v+ycnI/paWlf6LjY/+np2f/Xh+g/5gnL7/MX+y/xcgJ80BAgNNN1OUs6W84fDA1O73mJyj/ainpv+2trb/t7e4/8fHyP/Fxsb/kZGQ/4eGhP+vucT/j6G+/W53k/NlkbnwNoOv/AgiNb8CCBsQDRo/YwsaO3B0d33arKyp9q2trfWvr6/2u7u79ru7vPawr7H1sbCt9nJ2gOQIGD6bFCFEYB0qPE1Bf6SpEz9cggAAAAMCAQEBAQAAADIyMmlDQ0ONQUFBhUFBQYVCQkGFQkJBhUhISIRNTU2OKysrZAEAAAUBAQAAAgEAAAkEAAEDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
   { separator: ''},
   { label: "Запомнить изображение как base64, в контекстном меню", value: "CB.Save.WebScreenShotOnImage"},
   { label: "Сохранить выделенный текст в файл, в контекстном меню", value: "CB.Save.SelectionToFile" },
   { label: "Открыть выделенный текст в внешнем редакторе, в контекстном меню", value: "CB.Save.TextToEditor"},
];

var menuPopup = self.appendChild(document.createXULElement("menupopup"));
array.forEach((m,i)=> {
   if ("separator" in m) { menuPopup.appendChild(document.createXULElement("menuseparator")); return };
   var mItem = menuPopup.appendChild(document.createXULElement("menuitem"));
   mItem.setAttribute("label", m.label);
   mItem.setAttribute("class", "menuitem-iconic");
   if ("image" in m) mItem.setAttribute("image", m.image || array[i-1].image); 
   if ("value" in m) { 
       mItem.setAttribute('type', 'checkbox');
       mItem.setAttribute('checked', cbu.getPrefs(m.value) );
       mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value));
       }
   if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString()));
});
menuPopup.setAttribute("onclick", "event.stopPropagation()");


function aDate() {
 var t=new Date();
 var y=1900+t.getYear();
 var min=t.getMinutes(); if (min<10){min="0"+min};
 var h=t.getHours();
 var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";}
 var d=t.getDate();
 var curdate=d+" "+m+" "+y+" "+"г";
 var myfilename=curdate;
 return myfilename;
}
 

function WebScreenShotonImage(image) {
      var canvas = document.createElementNS(xhtmlns, 'canvas');
      canvas.width = image.naturalWidth;
      canvas.height = image.naturalHeight;
      var ctx = canvas.getContext('2d');
      ctx.drawImage(image, 0, 0);
      var base64 = canvas.toDataURL();
      gClipboard.write(base64);
   
      // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
      
     // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { 
     Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается
      }, "");
};



var saveToFile = function (fileContent, fileName) {
    var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
    uc.charset = 'utf-8';
    fileContent = uc.ConvertFromUnicode(fileContent);

    var nsIFilePicker = Components.interfaces.nsIFilePicker;
    var fp = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
    fp.init(window, '', fp.modeSave);
    fp.defaultString = fileName;
    fp.appendFilters(fp.filterHTML);
    fp.appendFilters(fp.filterAll);
    fp.open(function (rv) {
  if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
    var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream);
    stream.init(fp.file, 0x02|0x20|0x08, 0666, 0);
    stream.write(fileContent, fileContent.length);
    stream.close();
  }
});
};


function savePageToHTML() {
var vert=`javascript:(function(){var getSelWin=function(w){if(w.getSelection().toString())return w;for(var i=0,f,r;f=w.frames[i];i++){try{if(r=getSelWin(f))return r}catch(e){}}};var selWin=getSelWin(window),win=selWin||window,doc=win.document,loc=win.location;var qualifyURL=function(url,base){if(!url||/^([a-z]+:|%23)/.test(url))return url;var a=doc.createElement('a');if(base){a.href=base;a.href=a.protocol+(url.charAt(0)=='/'%3F(url.charAt(1)=='/'%3F'':'//'+a.host):'//'+a.host+a.pathname.slice(0,(url.charAt(0)!='%3F'&&a.pathname.lastIndexOf('/')+1)||a.pathname.length))+url}else{a.href=url};return a.href};var encodeImg=function(src,obj){var canvas,img,ret=src;if(/^https%3F:%5C/%5C//.test(src)){canvas=doc.createElement('canvas');if(!obj||obj.nodeName.toLowerCase()!='img'){img=doc.createElement('img');img.src=src}else{img=obj};if(img.complete)try{canvas.width=img.width;canvas.height=img.height;canvas.getContext('2d').drawImage(img,0,0);ret=canvas.toDataURL((/%5C.jpe%3Fg/i.test(src)%3F'image/jpeg':'image/png'))}catch(e){};if(img!=obj)img.src='about:blank'};return ret};var toSrc=function(obj){var strToSrc=function(str){var chr,ret='',i=0,meta={'%5Cb':'%5C%5Cb','%5Ct':'%5C%5Ct','%5Cn':'%5C%5Cn','%5Cf':'%5C%5Cf','%5Cr':'%5C%5Cr','%5Cx22':'%5C%5C%5Cx22','%5C%5C':'%5C%5C%5C%5C'};while(chr=str.charAt(i++)){ret+=meta[chr]||chr};return'%5Cx22'+ret+'%5Cx22'},arrToSrc=function(arr){var ret=[];for(var i=0;i<arr.length;i++){ret[i]=toSrc(arr[i])||'null'};return'['+ret.join(',')+']'},objToSrc=function(obj){var val,ret=[];for(var prop in obj){if(Object.prototype.hasOwnProperty.call(obj,prop)&&(val=toSrc(obj[prop])))ret.push(strToSrc(prop)+': '+val)};return'{'+ret.join(',')+'}'};switch(Object.prototype.toString.call(obj).slice(8,-1)){case'Array':return arrToSrc(obj);case'Boolean':case'Function':case'RegExp':return obj.toString();case'Date':return'new Date('+obj.getTime()+')';case'Math':return'Math';case'Number':return isFinite(obj)%3FString(obj):'null';case'Object':return objToSrc(obj);case'String':return strToSrc(obj);default:return obj%3F(obj.nodeType==1&&obj.id%3F'document.getElementById('+strToSrc(obj.id)+')':'{}'):'null'}};var ele,pEle,clone,reUrl=/(url%5C(%5Cx22%3F)(.+%3F)(%5Cx22%3F%5C))/g;if(selWin){var rng=win.getSelection().getRangeAt(0);pEle=rng.commonAncestorContainer;ele=rng.cloneContents()}else{pEle=doc.documentElement;ele=(doc.body||doc.getElementsByTagName('body')[0]).cloneNode(true)};while(pEle){if(pEle.nodeType==1){clone=pEle.cloneNode(false);clone.appendChild(ele);ele=clone};pEle=pEle.parentNode};var sel=doc.createElement('div');sel.appendChild(ele);for(var el,all=sel.getElementsByTagName('*'),i=all.length;i--;){el=all[i];if(el.style&&el.style.backgroundImage)el.style.backgroundImage=el.style.backgroundImage.replace(reUrl,function(a,b,c,d){return b+encodeImg(qualifyURL(c))+d});switch(el.nodeName.toLowerCase()){case'link':case'style':case'script':el.parentNode.removeChild(el);break;case'a':case'area':if(el.hasAttribute('href')&&el.getAttribute('href').charAt(0)!='%23')el.href=el.href;break;case'img':case'input':if(el.hasAttribute('src'))el.src=encodeImg(el.src,el);break;case'audio':case'video':case'embed':case'frame':case'iframe':if(el.hasAttribute('src'))el.src=el.src;break;case'object':if(el.hasAttribute('data'))el.data=el.data;break;case'form':if(el.hasAttribute('action'))el.action=el.action;break}};var head=ele.insertBefore(doc.createElement('head'),ele.firstChild);var meta=doc.createElement('meta');meta.httpEquiv='content-type';meta.content='text/html; charset=utf-8';head.appendChild(meta);var title=doc.getElementsByTagName('title')[0];if(title)head.appendChild(title.cloneNode(true));head.copyScript=function(){if('$'in win)return;var f=doc.createElement('iframe');f.src='about:blank';f.setAttribute('style','position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;');doc.documentElement.appendChild(f);var str,script=doc.createElement('script');script.type='text/javascript';for(var name in win){if(name in f.contentWindow||!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name))continue;try{str=toSrc(win[name]);if(!/%5C{%5Cs*%5C[native code%5C]%5Cs*%5C}/.test(str)){script.appendChild(doc.createTextNode('var '+name+' = '+str.replace(/<%5C/(script>)/ig,'<%5C%5C/$1')+';%5Cn'))}}catch(e){}};f.parentNode.removeChild(f);if(script.childNodes.length)this.nextSibling.appendChild(script)};head.copyScript();head.copyStyle=function(s){if(!s)return;var style=doc.createElement('style');style.type='text/css';if(s.media&&s.media.mediaText)style.media=s.media.mediaText;try{for(var i=0,rule;rule=s.cssRules[i];i++){if(rule.type!=3){if((!rule.selectorText||rule.selectorText.indexOf(':')!=-1)||(!sel.querySelector||sel.querySelector(rule.selectorText))){style.appendChild(doc.createTextNode(rule.cssText.replace(reUrl,function(a,b,c,d){var url=qualifyURL(c,s.href);if(rule.type==1&&rule.style&&rule.style.backgroundImage)url=encodeImg(url);return b+url+d})+'%5Cn'))}}else{this.copyStyle(rule.styleSheet)}}}catch(e){if(s.ownerNode)style=s.ownerNode.cloneNode(false)};this.appendChild(style)};var sheets=doc.styleSheets;for(var j=0;j<sheets.length;j++)head.copyStyle(sheets[j]);head.appendChild(doc.createTextNode('%5Cn'));var doctype='',dt=doc.doctype;if(dt&&dt.name){doctype+='<!DOCTYPE '+dt.name;if(dt.publicId)doctype+=' PUBLIC %5Cx22'+dt.publicId+'%5Cx22';if(dt.systemId)doctype+=' %5Cx22'+dt.systemId+'%5Cx22';doctype+='>%5Cn'};var href = 'data:text/html;charset=utf-8,' + encodeURIComponent(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->');var a = document.documentElement.appendChild(document.createElement("a"));a.setAttribute("href", href);var name = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());name=name.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');name += (function () {var d = new Date(), z=function(n){return '_' + (n < 10 ? '0' : '') + n};return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());})();a.setAttribute("download", name + ".html");a.click();a.remove();})();`;
gBrowser. loadURI(vert, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});
};


function saveShortcuts() {
var file = Components.classes["@mozilla.org/file/local;1"].
           createInstance(Components.interfaces.nsIFile);
file.initWithPath(folderpath);

if( !file.exists() || !file.isDirectory() ) {   file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0x1B6);}

var savetodir=folderpath+"\\"; 
var urllink=gBrowser.currentURI.spec;
var out=getTabLabel();
var filename=savetodir+out+'.url';
var data="[InternetShortcut]\r\nURL="+urllink+"\r\n";

saveToFile(data, filename);
 // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
   // подсказка
   var notific = 'Сохранил в: ' + folderpath;
   var image = gBrowser.selectedBrowser.mIconURL;
   Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(image, filename, notific);
};

// Кодировать изображение или текстовой файл в base64 .............
function copyFaviconbase(){
var fp = window.makeFilePicker();
fp.init(window, "Открыть файл", fp.modeOpen);
fp.appendFilter("Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml; *.xhtml; *.jpe; *.jpg; *.jpeg;\
                                    *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw");
  fp.open(re=> { 
  if ( re != fp.returnOK ) return;
   var file = fp.file;
   var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
   inputStream.init(file, 0x01, 0600, 0);
   var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
   stream.setInputStream(inputStream);
   var encoded = btoa(stream.readBytes(stream.available()));
   var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file);
   var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded;
   gClipboard.write(dataURI);
   //Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Скопировал файл как base64");
    // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
      
     // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { 
     Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Запомнил изображение как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается
      }, "");
});
};

// Сохранить страницу как PDF файл через сервис 'pdfmyurl.com' .............
function savePageToPDF() {
      var loc = gBrowser.currentURI.spec;
   var vert = "http://pdfmyurl.com?url=" + loc;
  
   gBrowser. loadURI(vert, {
   triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
   });
}; 

// Сохранить иконку текущего сайта с диалогом сохранения .............
function saveFavicon() {
       var uri = gBrowser.currentURI;
       function getSiteName() {
                  try { var domain = uri.host.split('.') } catch(e) { return "" };
                   domain = (domain.length == 2) ? domain[0] : domain[1]
                   return domain.charAt(0).toUpperCase() + domain.slice(1).split('.')[0] + " ";  
            };
      saveImageURL(gBrowser.selectedTab.image, getSiteName(), null, false, false, null, window.document);
};


// Скопировать иконку текущего сайта как base64 код .............
function copyFaviconData() {
   var img = new Image();
   img.src = gBrowser.selectedTab.image;
   WebScreenShotonImage(img);
};


// Сохранить выделенный текст или весь текст на странице как txt файл .............
function saveSelectionToTxt() {

let browserMM = gBrowser.selectedBrowser.messageManager;
        browserMM.addMessageListener('getSelection', function listener(message) {
        var sel = message.data;
       !sel && document.getElementById("cmd_selectAll").doCommand(); 
     
   // создать название файла из заголовка страницы и текущего времени и сохранить текст ....
   var fileTitle = getTabLabel() + '  ' + aDate().replace(/:/g, ".");
   saveURL("data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + ("\r\n\r\n" + sel)), 
                                fileTitle + ".txt", null, false, false, null, window.document);
   !sel && goDoCommand("cmd_selectNone"); 
 browserMM.removeMessageListener('getSelection', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelection", content.document.getSelection().toString())', false);
};

(popup => addEventListener("popupshowing", {
    handleEvent(e) {
        if (this.shouldHide) return;

        var menuitem = document.createXULElement("menuitem");
        menuitem.id = "content-baseItem";
        menuitem.className = "menuitem-iconic";
        menuitem.setAttribute("oncommand", "copyImageAsBase64()");
        menuitem.setAttribute("label", "Запомнить изображение как base64");
        menuitem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AIAQ/wCAEf8AgA//AIAR/wCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AgBX/AIAVAAAAAAAAAAD/AIAo/wCA//8AgP//AID//wCA//8AgP//AIAoAAAAAAAAAAAAAAAAAAAAAP8AgBL/AID//wCA//8AgA3/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgBAAAAAAAAAAAAAAAAD/AIAR/wCA//8AgP//AIAK/wCACv8AgP//AID//wCAIf8AgAX/AIAh/wCA//8AgP//AIAQAAAAAAAAAAAAAAAA/wCACv8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAUAAAAA/wCABf8AgP//AID//wCACgAAAAD/AIAQ/wCADP8AgCH/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCABf8AgCH/AID//wCA//8AgAv/AIAh/wCA//8AgP//AID//wCA//8AgP//AIAH/wCAB/8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AIAg/wCA//8AgP//AID//wCA//8AgP//AID//wCAB/8AgAf/AID//wCA//8AgP//AID//wCA//8AgP//AIAh/wCAC/8AgP//AID//wCAHP8AgBz/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCACf8AgA7/AIAMAAAAAP8AgAj/AID//wCA//8AgAP/AIAD/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCABQAAAAAAAAAA/wCADf8AgAr/AIAL/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCAB/8AgAr/AID//wCA//8AgCH/AIAH/wCAJf8AgP//AID//wCAI/8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAf/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgCT/AID//wCA//8AgAr/AIAK/wCA//8AgP//AIAKAAAAAP8AgCj/AID//wCA//8AgP//AID//wCA//8AgCP/AIAM/wCA//8AgP//AIAN/wCADf8AgP//AID//wCADQAAAAAAAAAA/wCAEP8AgBH/AIAP/wCAEf8AgBAAAAAAAAAAAP8AgBT/AIAVAAAAAAAAAAD/AIAV/wCAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQcH5rEGA8KxBAHCsQQBwrEEIQKxBAACsQQAArEEAAKxBAQCsQQwArEEAAKxBAACsQYAArEHBmaxB//+sQQ==");
        popup.append(menuitem);
        addDestructor(() => menuitem.remove());

        menuitem.copyImageAsBase64 = () => gBrowser.selectedBrowser.messageManager
            .loadFrameScript("data:;charset=utf-8," + encodeURIComponent(this.code()), false);

        this.handleEvent = () => menuitem.hidden = this.shouldHide;
    },
    get shouldHide() {
        return !gContextMenu.onImage || !cbu.getPrefs("CB.Save.WebScreenShotOnImage");
    },
    code: () => `(selectors => {

        var getImage = doc => {
            var elm = doc.querySelector(selectors.shift());
            if (selectors.length) elm = getImage(elm.contentDocument);
            return elm;
        }
        var image = getImage(content.document);

        var canvas = image.ownerDocument.createElementNS("${xhtmlns}", "canvas");
        canvas.width = image.naturalWidth;
        canvas.height = image.naturalHeight;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(image, 0, 0);
        var base64 = canvas.toDataURL();

        Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
            .copyStringToClipboard(base64, Ci.nsIClipboard.kGlobalClipboard);

        Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
            .showAlertNotification(base64, "${self.label}", "Запомнил изображение как base64");
    })(${
        JSON.stringify(gContextMenu.targetSelectors)
    })`
}, false, popup || 1))(document.getElementById("contentAreaContextMenu"));


// Добавляем в контекстного меню страницы новые пункты .............
((contextMenu, el)=> {

   // в контекстного меню выделенного текста ....
   var saveItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el);
   saveItem.id = "content-saveItem";
   saveItem.setAttribute("label", "Сохранить выделенный текст в файл");
   saveItem.onclick =()=> saveSelectionToFile();

   var editorItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el);
   editorItem.id = "content-editorItem";
   editorItem.setAttribute("label", "Открыть выделенный текст в внешнем редакторе");
   editorItem.onclick =()=> textToEditor();


    // устанавливаем где и при каких настройках показывать новые пункты ....
   addEventListener('popupshowing', e=> {
      if (e.target != e.currentTarget) return;
      var sel = gContextMenu.isTextSelected;
      saveItem.hidden = !sel || !cbu.getPrefs("CB.Save.SelectionToFile");
      editorItem.hidden = !sel || !cbu.getPrefs("CB.Save.TextToEditor"); 
      }, false, contextMenu);

   // удалять новые пункти при изминениях ....
   addDestructor(()=> {
      saveItem.remove(); editorItem.remove();
   });   
})(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open"));


// Сохранить выделенный текст в файл на рабочем столе .............
function saveSelectionToFile() {

 let browserMM = gBrowser.selectedBrowser.messageManager;
 browserMM.addMessageListener('getSelect', function listener(message) {
   // создать текст для записи
   var url = gBrowser.currentURI.spec;
   if (/\.рф/.test(url.host)) url = convertFromUnicode("UTF-8", url);
   
   var time = convertFromUnicode("UTF-8", aDate().replace(/:/g, "."));
   var text = convertFromUnicode("UTF-8", message.data); 
   var title = convertFromUnicode("UTF-8", getTabLabel());
   
   var text = "..............................................................\n"
            + title + " - " + time + "\n" + url + "\n\n" + text + "\n\n\n";
   var text = text.replace(/\u000A/g, "\u000D\u000A").replace(/\u000D\u000D\u000A/g, "\u000D\u000A");

   // путь к файлу и название файла
   var file = Services.dirsvc.get("Desk", Ci.nsIFile); 
   file.append("Save - " + (aDate().replace(/:/g, ".")) + ".txt");
          
   // создать файл с текстом или добавлять текст в файл
   var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
   file.exists() ? foStream.init(file, 0x02 | 0x10, 0664, 0) : foStream.init(file, 0x02|0x08|0x20, 0666, 0);
   foStream.write(text, text.length);
   foStream.close();
    // всплывающая подсказка дает возможность открыть файл если кликнуть на подсказке
       var notificat = 'Сохранил выделенный текст в файл на рабочий стол'; 
   var image = gBrowser.selectedTab.image || self.image;
   Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
    .showAlertNotification(image, notificat, "Кликни чтобы открыть файл", true, "", (s, t)=> { 
      if (t == 'alertclickcallback') file.launch();
   }, "");
 browserMM.removeMessageListener('getSelect', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false);

};


// Создать текстовой файл с выделенным текстом в папке профиля и открыть в редакторе .............
function textToEditor() {


 let browserMM = gBrowser.selectedBrowser.messageManager;
 browserMM.addMessageListener('getSelect', function listener(message) {
   // создать текст для записи
    var text = convertFromUnicode("UTF-8", message.data); 
    var file = Services.dirsvc.get('ProfD', Ci.nsIFile);
   file.append("TextToEditor.txt");
   custombuttonsUtils.writeFile(file.path, text);
   file.launch(); 
          

 browserMM.removeMessageListener('getSelect', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false);
};


// Конвертировать текст в юникод .............
function convertFromUnicode(charset, str) {
     var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
     converter.charset = charset;
     str = converter.ConvertFromUnicode(str);
     return str + converter.Finish();
 
};

// Получить название вкладки без не сохраняемых символов и лишних пробелов ..............
function getTabLabel() { 
   var label = gBrowser.selectedTab.label;      
   var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
   return label.substring(0, 50);
};

Отсутствует

 

№1357231-07-2019 20:46:42

Dumby
Участник
 
Группа: Members
Зарегистрирован: 12-08-2012
Сообщений: 2249
UA: Firefox 52.0

Re: Custom Buttons

Andrey_Krropotkin пишет

одну пока еще не получилось сделать, пока две кнопки

Мне кажется их объеденить довольно легко. Я сейчас чуть-чуть
модифицировал первую и просто добавил в конец второй. Вроде встала.
Смысл в том, что вместо menupopup будет menugroup. Попробуй.

скрытый текст

Выделить код

Код:

((main, parts) => this.onmousedown = e => {
    if (e.button) return;
    this.onmousedown = null;

    var df = MozXULElement.parseXULToFragment(`
        <menugroup orient="vertical">
            <menuseparator/>
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить всю страницу как PNG"
                value="all"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить видимую часть страницы как PNG"
                value="page"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAIBkAAAEAIAAMDQAAFgAAACgAAAAgAAAAMgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29fT/2tra/8jIyP/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8jIyP/a2tr/9vX0/+zs7P/ak0b/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/9qTRv/s7Oz/7Ozs/+J9Dv/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+/6SdmP/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/+vn4//z7+v/6+fj/4n0O/+zs7P/s7Oz/4n0O//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/aFtT//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//j39v/ifQ7/7Ozs/+zs7P/ifQ7/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P9oW1P/7+zq/+/s6v/v7Or/8O3r//Dt6//w7ev/8O3r//Dt6//w7ev/8O3r/+/s6v/w7ev/9fTy/+J9Dv/s7Oz/7Ozs/+J9Dv/49/b/+Pf2//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4/2hbU//q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/y8O//4n0O/+zs7P/s7Oz/4n0O//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/aFtT/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe//Dt6//ifQ7/7Ozs/+zs7P/ifQ7/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P9oW1P/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/7uro/+J9Dv/s7Oz/7Ozs/+J9Dv/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx/2hbU//x7+3/8vDv//Hv7f/x7+3/8e/t//Lw7//x7+3/8e/t//Lw7//x7+3/8vDv//Hv7f/29fT/4n0O/+zs7P/s7Oz/4n0O//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//aFtT/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/8vGwf/ifQ7/7Ozs/+zs7P/ifQ7/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f9nWlL/aFtT/2hbU/9nWlL/Z1pS/2hbU/9oW1P/Z1pS/2daUv9oW1P/aFtT/2hbU/9nWlL/pJyX/+J9Dv/s7Oz/7Ozs/+J9Dv/w7ev/8O3r//Dt6//w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Hv7f/w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Dt6//w7ev/4n0O/+zs7P/s7Oz/4n0O/+/s6v/v7Or/7uro/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/u6uj/7+zq/+/s6v/ifQ7/7Ozs/+zs7P/ifQ7/7uro/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7Ojm/+J9Dv/s7Oz/7Ozs/+J9Dv/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/4n0O/+zs7P/s7Oz/4n0O/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/ifQ7/7Ozs/+zs7P/ifQ7/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+J9Dv/s7Oz/7Ozs/+J9Dv/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/4n0O/+zs7P/s7Oz/4n0O/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/ifQ7/7Ozs/+zs7P/ifQ7/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+J9Dv/s7Oz/7Ozs/+J9Dv/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/k39z/4n0O/+zs7P/s7Oz/4n0O/+Lc2f/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/ifQ7/7Ozs/+zs7P/ifQ7/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+J9Dv/s7Oz/9fTy/+J9Dv/8+/r/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/4n0O//X08v/8+/r/6KFU/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ooVT//Pv6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить выбранный элемент страницы как PNG"
                value="click"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAADDn2Hfz5pE/8eVQP7IlkH/yJZB/8iWQf/IlUH/yJVA/8iVQP/IlED/yJQ//8iUP//IlD//yJM+/8iTPv/Hkj3/nI1w//bDbP//8OH//+zW///s1///69b//+rV///p1P//59L//+XQ///izf//38n//9vG///ZxP//1b///dG////Prf/KlkX/88N4/v37///99Pj//fT6//vy9v/68fT/+u/y//rt8P/66u3/+ufq//rl6P/64eT/+93h//3a3//71d7//9LK/86XR//0xHb//vv////18///9fT///f5///4////9f7///P8///v+f//7Pb//+nz///m8f//4eb//9vZ//3Y2v//1Mb/zphH//TGd//+/////Pj1///7///Q58r/m9aV/6TZnv+i15r/otWY/6LTlv+j0pb/mc6M/9DXuf//3+P//Nnc///Wyf/OmUf/9MZ3//7////8+/j//////53WnP+Y5pn/rvGv/6PvpP+e7p//me6b/5nvm/95533/mM+L///j7f/629z//9jL/86ZR//0xnf//v////z9+v//////qtup/8Xzxf/a/tn/z/vO/8n7yf/D+sL/xPvD/6Hzo/+j05b//+Tu//re3///2cz/zplI//XGeP/+/////P36//////+n26f/uvC6/9T71P/K+Mr/xvjG/8D3wP+/+L//nfCf/6LTlf//5u//+t/g///cz//OmUj/9MZ3//7////8/fr//////6rcqv/G9MX/3//f/9n92f/V/NX/0PzQ/9H+0P+s9a7/pdSY///o8f/64OL//9zP/86aSP/0xnf//v////z9+f//////ndid/5TjlP+v7q//qeyp/6jsqf+k7KX/p+6n/4Tlh/+Z0Y7//+r0//rh4v//3tH/zppI//TGd//+/////v77///////Y8Nj/p9+n/6/jr/+t4a3/rd2p/67bpv+u2ab/p9Wc/9jgx///6Oz//OPl///e0f/Omkj/9MV1//7//////fr///78///+/f///////////////////P////j////0+///8fn//+vu///m4v/94+P//97P/86ZSP/zx3v//v/////+/f///////f////v////7////+/////v+///7+///+/f///vz/P/98Pr//+33//3p9///5OL/zppL//a1Sv/0xoL/9cR7//XEfP/1xHz/9cR8//XEfP/1xH3/9cR8//XCev/1wXr/9b94//W9d//1u3X/87l0//y6bP/Llj7/+pMA/vWBAP/1gwD/9YMA//WDAP/1gwD/9YMA//WDAP/1gwD/9YQA//WEAP/1hAD/9YQA//WEAP/zhAH//okA/8qLIv3xpzP/4ptV/+OdU//jnVP/451T/+OdU//jnVP/451T/+OdU//jnVL/451S/+OdUv/jnVL/451S/+GdVf/qnUf/2aRJ/9q0c9/8yn7/98V5/vjGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6/vrIe/+jj2y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить выбранную область страницы как PNG"
                value="clipping"/>
        </menugroup>
    `);
    var menugroup = df.firstChild;
    menugroup.setAttribute("context", "");
    menugroup.setAttribute("oncommand", "handleCommand(event);");
    menugroup.handleCommand = e => {
        var name = _id + ":DataURLReady";
        main = main.replace("%MESSAGE_NAME%", name);

        var urls = {}, configurable = true, enumerable = true;
        Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, {
            configurable, enumerable, get() {
                var value = `data:;charset=utf-8,({${
                    encodeURIComponent(main + part)
                }%0A}).init("${key}")`;
                Object.defineProperty(urls, key, {configurable, enumerable, value});
                return value;
        }}));
        var getTabLabel = () => {
            var label = gBrowser.selectedTab.label;      
            var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
            return label.substring(0, 50);
        }
        var listener = msg => {
            var fp = makeFilePicker();
            fp.init(window, "Сохранить как…", fp.modeSave);
            fp.appendFilter("", "*.png");
            fp.defaultString = getTabLabel() + ".png";   
            fp.open(res => res == fp.returnCancel || !fp.file || makeWebBrowserPersist().saveURI(
                Services.io.newURI(msg.data), document.nodePrincipal,
                null, null, null, null, null, fp.file, null
            ));
        }
        messageManager.addMessageListener(name, listener);
        addDestructor(() => messageManager.removeMessageListener(name, listener));

        (menugroup.handleCommand = e => gBrowser.selectedBrowser.messageManager
            .loadFrameScript(urls[e.target.value], false)
        )(e);
    }
    menuPopup.querySelector('menuitem[label*="ярлык"]').after(df);
})(`
    init(cmd) {
        cmd.startsWith("c")
            ? this[cmd].init(this[cmd].parent = this)
            : this[cmd]();
    },
    capture(win, x, y, width, height) {
        var canvas = win.document.createElementNS("${xhtmlns}", "canvas");
        canvas.width = width;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        var tryDraw = ind => {
            try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")}
            catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);}
        }
        tryDraw(17);
        sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png"));
    },
    `, {

    all: `all() {
        var win = content;
        this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY);
    }`,
    page: `page() {
        var win = content, doc = win.document, body = doc.body, html = doc.documentElement;
        var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft;
        var scrY = (body.scrollTop || html.scrollTop) - html.clientTop;
        this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight);
    }`,
    clipping: `clipping: {
        handleEvent(e) {
            if (e.button) return false;
            e.preventDefault();
            e.stopPropagation();
            switch(e.type) {
                case "mousedown":
                    this.downX = e.pageX;
                    this.downY = e.pageY;
                    this.bs.left = this.downX + "px";
                    this.bs.top = this.downY + "px";
                    this.body.appendChild(this.box);
                    this.flag = true;
                    break;
                case "mousemove":
                    if (!this.flag) return;
                    this.moveX = e.pageX;
                    this.moveY = e.pageY;
                    if (this.downX > this.moveX) this.bs.left = this.moveX + "px";
                    if (this.downY > this.moveY) this.bs.top  = this.moveY + "px";
                    this.bs.width = Math.abs(this.moveX - this.downX) + "px";
                    this.bs.height = Math.abs(this.moveY - this.downY) + "px";
                    break;
                case "mouseup":
                    this.uninit();
                    break;
            }
        },
        init() {
            var win = {};
            Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
                .getFocusedElementForWindow(content, true, win);
            this.win = win.value;

            this.doc = this.win.document;
            this.body = this.doc.body;
            if (!HTMLBodyElement.isInstance(this.body)) {
                Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
                    .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!");
                return false;
            }
            this.flag = null;
            this.box = this.doc.createElement("div");
            this.bs = this.box.style;
            this.bs.border = "#0f0 dashed 2px";
            this.bs.position = "absolute";
            this.bs.zIndex = "2147483647";
            this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor;
            this.body.style.cursor = "crosshair";
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)];
            this.body.style.cursor = this.defaultCursor;
            this.body.removeChild(this.box);
            this.parent.capture.apply(this, pos);
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`,
    click: `click: {
        getPosition() {
            var html = this.doc.documentElement;
            var body = this.doc.body;
            var rect = this.target.getBoundingClientRect();
            return [
                this.win,
                Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft,
                Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop,
                parseInt(rect.width),
                parseInt(rect.height)
            ];
        },
        highlight() {
            this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false;
            this.target.style.cssText += "outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;";
        },
        lowlight() {
            if (this.orgStyle) this.target.style.cssText = this.orgStyle;
            else this.target.removeAttribute("style");
        },
        handleEvent(e) {
            switch(e.type){
                case "click":
                    if (e.button) return;
                    e.preventDefault();
                    e.stopPropagation();
                    this.lowlight();
                    this.parent.capture.apply(this, this.getPosition());
                    this.uninit();
                    break;
                case "mouseover":
                    if (this.target) this.lowlight();
                    this.target = e.target;
                    this.highlight();
                    break;
            }
        },
        init() {
            this.win = content;
            this.doc = content.document;
            ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            this.target = false;
            ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`
});

Отсутствует

 

№1357331-07-2019 21:17:20

Andrey_Krropotkin
Участник
 
Группа: Members
Зарегистрирован: 11-11-2011
Сообщений: 484
UA: Firefox 68.0

Re: Custom Buttons

Dumby да все четко встало, такого сочетания я еще не встречал, круто.
Исправленная для многопроцессорного режима кнопка Save, от 07.03.2017. .............

скрытый текст

Выделить код

Код:

// Save, от 07.03.2017. .............

self.label = "Save";
self._handleClick =()=> menuPopup.openPopup(this, "after_start");
self.image = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";


var folderpath="C:\\Users\\________\\Desktop";         // папка для сохранения иконок для ярлыков и ярлыков сайтов(Ставьте свое)



// Создать меню для кнопки .............
var array = [
   { label: "Сохранить значок веб-сайта", func: "saveFavicon()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACPVBMVEX09ff////C3L+Uq8+Vq8+Uqs+Zr9CZrtCZr9Gfu+ear8+mt9JRf8ORxl3t8vfF06+Twojs8/d9otl8o9s+aquZrs/X9KLp8Pft8fZhisf//+DBzN2hveihv+pii8hti9pgicl6oNlojs1zncNsi836/P2duebx8/eYyWqBp+Gn0IKBvlKHsm9qmaVuk8zt7/FEbauEv1Tp7/JdhL9oi9Pl8e2LwlmdsdD7/P76+/3H7ofo8+peh8eHwFaSteZ0pkp2gl7q8/Ohy5OApt2by2eZuOqbuOWaezWuvtd7nN2HvWxul9Ty9feQxV5ljcqBp+JEcLCVtOOo0nR7odx5n9suX6Z1mtBzmtSXyGPv9PewzfOzx+O6zu/s8fd9o95Xfrthi8lYhMN5oNnw9ffw9Pjw9Pf8/f6ewO/m8O9zmdE6aapsjdyUwouPxWPDzd6XteOSs9B5nNVpnpqHt7h/s6F6n9d7ntSTttGHwVh4qp+Ev1HH7ox6qk5wj+Hm8e3t9fOm0IKAtqOBpNrx+P9ljcyhs9FpkM2hv+/u8/fF0eOLu4N+vFKgzX3p9OSFqN13qExekIl4n9j7/P3x9PhxmNDm8e9Vg8Zfkozr8veq0YTX9qL//92AtamOwnHFz96Fot1diMh+pd13ntmatu+YyW/3+/+Tqs5UgcShzJNbhsdTf8GHs7bo8PaXtuqMr+Ty8/SZt+SUqs7r7Ox3ndb9/f7t8feZyXGYyWWCpNbz9PRuiteNtNDn7/V4ntjx8fGo3JqNAAAAv3RSTlP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AEVuhDkAAAD+SURBVBhXY5jHzcUMAqxAICq9bx8D96adDFAgaGQOFOBaH7h7zoqZDTlFyptncAAFWBjyi52CXCI0unRLxcECPhsatbbzmlXMnS60hg0kkOxW0uNrq93tNaFpD1ggUm21QK532ZQdSm1hmXKdDCwdnOWVOi1RjNGMQCCrwMDMJ8NZ4LAynVGPkXFp8zpJBubYmn579wXtqhZb0iwn9a1iWLaViYmJ3891obOwYtLEvcYMGyWAAkwJdv6accEhi8LjGVr11SenpC5f61g3NcO0vjCAIc+DjZ2dnWexddWSbYa9nlkM+8BgWsxsK7FZ1VLzRaACNokmtdnyu1QMQgF7Rlh4zWWTAwAAAABJRU5ErkJggg=="},
   { label: "Запомнить значок веб-сайта как base64", func: "copyFaviconData()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAI2bv/9RVpf/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAACIkvD/Jia6/ywpq/8AAAAAAAAAAAAAAAAAAAD/AAAA/wbwAf90qpv/Ymic/1RWqP9OUKr/W2Ch/2dumf9YYKT/Ly/B/xQP3/8MB9P/JCGb/wAAAAAAAAAAAAAAAAAAAP8G8AH/U5ea/ycr8f8VIP3/HiP4/ywo8v8sIvb/LCL2/ywi9v8KBOj/BQDe/wQAtv8tK4P/AAAAAAAAAAAAAAD/BvAB/3Sqm/9iaJz/Tim3/0UuuP9GPrT/R0ex/zk8uf8gIMz/FRDe/xEMzv8jIJz/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8AAAD/SqOR/yImvP8sLKj/AAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/BvAB/3Sqm/9KW5r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAABvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAG8AH/AAAAAAAAAP8G8AH/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BvAB/wbwAf8AAAAAAAAA/wAAAP8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAG8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOesQQBjrEGAAaxBwACsQcABrEHDg6xBwAesQcAPrEHAD6xBw8+sQcPprEHD8axBwAGsQQABrEGAAaxB//+sQQ=="},  
   { separator: ''},
   { label: "Сохранить ярлык страницы как…", func: "saveShortcuts()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP8E/yT/BP8k/5XLDv/zqgD/86oA//I1///yNf//86oA//OqAP/zqgD/86oA//OqAP+Vyw7/lcsO/wT/JP8E/yT/BP8k/5XLDv+Vyw7/86oA//OqAP/yNf//8jX///OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//02AP/9NgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/9NgD//TYA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA/wA31v8AN9b/86oA//9If///SH//86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP8AN9b/ADfW//OqAP//SH///0h///OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/5XLDv+Vyw7/86oA//OqAP/zqgD/86oA/0CA//9AgP//86oA/07+9f9O/vX/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP9AgP//QID///OqAP9O/vX/Tv71//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ=="},
   { separator: ''},  
   { label: "Кодировать изображение(текст.файл) в base64", func: "copyFaviconbase()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AIAQ/wCAEf8AgA//AIAR/wCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AgBX/AIAVAAAAAAAAAAD/AIAo/wCA//8AgP//AID//wCA//8AgP//AIAoAAAAAAAAAAAAAAAAAAAAAP8AgBL/AID//wCA//8AgA3/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgBAAAAAAAAAAAAAAAAD/AIAR/wCA//8AgP//AIAK/wCACv8AgP//AID//wCAIf8AgAX/AIAh/wCA//8AgP//AIAQAAAAAAAAAAAAAAAA/wCACv8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAUAAAAA/wCABf8AgP//AID//wCACgAAAAD/AIAQ/wCADP8AgCH/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCABf8AgCH/AID//wCA//8AgAv/AIAh/wCA//8AgP//AID//wCA//8AgP//AIAH/wCAB/8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AIAg/wCA//8AgP//AID//wCA//8AgP//AID//wCAB/8AgAf/AID//wCA//8AgP//AID//wCA//8AgP//AIAh/wCAC/8AgP//AID//wCAHP8AgBz/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCACf8AgA7/AIAMAAAAAP8AgAj/AID//wCA//8AgAP/AIAD/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCABQAAAAAAAAAA/wCADf8AgAr/AIAL/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCAB/8AgAr/AID//wCA//8AgCH/AIAH/wCAJf8AgP//AID//wCAI/8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAf/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgCT/AID//wCA//8AgAr/AIAK/wCA//8AgP//AIAKAAAAAP8AgCj/AID//wCA//8AgP//AID//wCA//8AgCP/AIAM/wCA//8AgP//AIAN/wCADf8AgP//AID//wCADQAAAAAAAAAA/wCAEP8AgBH/AIAP/wCAEf8AgBAAAAAAAAAAAP8AgBT/AIAVAAAAAAAAAAD/AIAV/wCAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQcH5rEGA8KxBAHCsQQBwrEEIQKxBAACsQQAArEEAAKxBAQCsQQwArEEAAKxBAACsQYAArEHBmaxB//+sQQ=="},
   { separator: ''},
   { label: "Сохранить всю страницу как PDF", func: "savePageToPDF()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYUw4pJt3V/+Rb1D8lnFP/55zTf+VcVH/lXJS/5VyUv+VclL/lXJS/5VyUv+VclL/k3BR/J56Wv9cRzSkAAAAAJNvUKTto2L/4ppe/uehZf/Pmmr/noZv/9Scav/Wl17/1plh/9eZYf/XmWH/15lh/9eZYf/WmGD/2Jlg/suRXP9mRiuk8rWA/397dP1akKn/rqqi/3LF3f8Mntj/4dLJ///+9f/48u3/9e7n//bt5v/47+f/+O/n//jv5//rvZP/1ZJX/a9/VP9+lrD8AIvz/xOt+f8Douv/ALb6/wC28/9tmar/z8jJ//Lq5/////7//v////n9///6/P3//////+Ta0P/PjVP/pnpT/IWds/+aiXj/5efl/8Px//951/3/LMz//wCx8/8GltL/NIu3/4ycqf/l29L////+//n6+//8/v//3tXM/8+OVP+oe1P/6K57/86QWP/r6Ob////////++v/r9/z/oOb9/zDL//8Arf//AI/r/ydysv+hpqr//PTr///////d1Mz/0I5U/6h7U//osH//wo5g/+fm5P/7/f//9vf5//z7+////vv/9/r8/5Dc/P8Oqv7/AJf//wF02v9ffZ7/8Ojh/+Ha1P/NjFL/qHtT/+ewf//Ej1//7O3r///////+/v7//v7+//f5+v/6+vv////8/8Tq/f8hp/7/AJH//wB18/8/bqj/1MGu/9mXXv+leVH/569+/8iSYv+/tKn/wLew/8O5sf/P0M////////7+/v/3+fv////7/9Hv/v8hoP3/AIn//wB4/v84ZqL/w4NH/619VP/nsYD/x45c/9W5of/bv6j/0Jxt/6J/YP+spqD/2N3i//7////6+/3///76/8vr/v8Slv7/AIb+/wBz//83VH7/nW1B/+ewfv/Fjl7/7Ozr///////9+/r/9d7K/9Ghdv+jd1D/pJ6Y/+jt8f/9///////7/6fb/v8Ahv7/AYD//wRp6f95YlT/57B//8SOXv/n5uT//v7///r7/P/8/v////////XRsv/DhEv/loBu/9DX3P/9/v/////7/2O6/f8Afv//FnTU/5JtTf/nsH//xY9e/+jn5f/+/f//+fj5//n4+P/5+Pn/+/////Xbxf/Wj1D/nX1h/+Ll6P////7/3+/3/w+V//8tcbP/qHJB/+WuffzCjV7/5efn///////+/v7//////////////v7///////XRsP/TnW3/8fT3//////////z/ddD//0Nxl/+zdkH88LmH/9CRWP2+qJT/0M7N/8/Jxv/Pysf/z8rH/8/Kxv/Py8n/zsO6/7+pmP/PzMv/zsnG/9bNyP+nsK7/h4R3/b2BT/+Sb1Ck7qxw/9GSW/69hlb/wYhX/8CIV//AiFf/wIhX/8CIVv/BiVj/xI1d/8CIVv/BiFf/vYZW/9STW/7ppmv/bE80pAAAAACUd16k+sui/+7AmPzwwpr/8MKa//DCmv/wwpr/8MKa//DCmf/vwZj/8MKa//DCmv/uwJj8+cui/5N3XaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
   { label: "Сохранить всю страницу или выбранное как HTML", func: "savePageToHTML()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzElEQVQ4jV2STW8bZRDHf/Psrr11nZhgVKcKaSmUiArRKBRVIMgH4BKJ7xAp5MSFiA+Rc28ckBAoipC4koJQLyAaVFChIlQllDRWmjRev8Qvu14/+wwHx6ZlpNFcZn7zn79GVJW1tbXc6urqijHGqKoAPF3TgcVaq8owXJbphx99fOOnWzcHoqqsr68/t7y83BARVBXnHHraXo3a3HoUU8gFAHRTS2Bg/7C2Zx7vXPIBwjA0p3BU9Zns9i3vvVrhr6MWzlpee+EsRqAbHc3+/Pee7wPkcrkx4P+g0IMvb/5Iv5/iXEaWZQS+By578MaVy9YH8H3fE5FnANZajqMmgcAnH7yN73mICMYMd21sbLy7srKiPkA+n3/qBLhzv8p+EuOfTUjShPbODvOVWa5fnRsvKBaLAcAIMFbw+bc/EBVn8At7SPcQ60LSiVm++P0fGu0e7y++yalvHoABCILAiAj7hzU+vfcVT6zPVGmR3x4/xJoLSH6BVu4cN777nnQwQETI5XL/AYwxRkS4ff8BEk6Q2pBfq3dxUuHMmWt0kgFGStTDY/7YrTLybQwYPU2cpgzsCd1OgmSzWHeOR7VjWicxaT9lxn+HfjoYmWnGHgAiIsydf5HKnUXiThehQDG4Tr3e5KR7hN8XilnGKxfOoyrDgZECwIgIb125xIxxTGVdgjRG4pR2+zbG/sIkD7l2cYJyaYLMOZxzjBV4nueLCI1GnaWFab65t4OXt4gUuFqYJ8gGuPYBCxdLHNciys9PkaapjAHGGM8YQ7lcZv71OaYmC/xZPaJHTN4cUgpDXrr8MtOVaUqTRXzfY3t7u7O0tDR82a2trfkkSTSOY+31etrpdLTZbGoURRpFkdbrTY3qTW00mhrHse7u7t4tl8uhqg4VxHHcPDg4+ExVHeBU1YmIU1WnisucZtamLszn01ar9WRzc/PrWq2WAPwLJ7l2ULfXOAMAAAAASUVORK5CYII="},
   { label: "Сохранить выделенный текст как txt файл", func: "saveSelectionToTxt()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAQE6AAAAZAAAAGgAAAJmAAACZgAAAGYAAABmAAAAZgAAAGYAAABmAAAAZgAAAGYAAABlAAAAaQABAmYAAQEjAAAAADlVkOdVcKHxVXKi8kdklPJLZpfyU3Cg8lJvn/JRbZ7yUW+g8lFun/JRbp/yUG6e8lVyofFVdKjzLkV45wAAAFABAQEAaIzF/3y34v9wsuL/cJe0/0lpgv9bjLP/dLLh/2+v3v9sq9v/cK3d/3Gv3v9sqtv/b7Df/4G77P9VcqT2AAAAVAMDAQBnir/+ZqfU/pDB4/7a3uD+j46N/kxYXv6To6/+1er4/tXp+P7J3/D+1ej4/svg8v6Gut/9aqzd/lhxnvAAAABSAwIBAGaIvv9pptX/ocfj//f4/P/P0tX/g4CA/1xZWf+Woqr/2uz8/9Hl+f/W5fT/2Of3/5fC4v5tq93/Vm+e8QAAAFIDAgEAaYm+/3mw2/+iyeX/9Pn8/+z0+//IzNL/d3h5/0tMTv+Mkpn/xdvs/9Hp/f/O4PL/msXk/nmz4/9XcJ/xAAAAUgMDAQBti7//k7/h/6fL5v/v9fn/4u73/9Dk9P+8wMT/YGpx/zJJWv94iJf/ztzo/9Pp/P+ZwuD+gLfk/1dwnvEAAABSAwMBAHOPwf+myub/sNHp//j7/P/6/P3/8fr///r39P+sxdP/IXWq/xJJcv+NjZD/0+Lu/6TN7f6Ft+L/WXGf8QAAAFIDAwEAd5LD/7PR6/+ZxOP/0ePx/97r9f/Y5/L/3e32/8Tc7f9gseT/CHK3/zBYdv+HiY7/lL/f/pLE7/9bcJ3xAAAAUgMDAQB4k8P/xNvx/5/F5f+kyOX/qMrn/6TH5f+kyOX/sM/q/5e51P9Mm83/GHm3/xxIav9fdYf+pMvs/1x1pfIAAABTAwMBAHmSxf/O4/T/y9/y/8Hb9P/C3PX/wNv0/7vW7/+93ff/utDm/42fsf9Gjbn/EXS2/ytSbv6Fj5r/WnGc8gAAAFICAwEBepPE/tHk9f/S5PX/vMjV/7fCzP+3w8//uMPP/7XBzP+6ytf/qa+4/3h/hv9Ghaz/JoO+/jNXdP82PVnyAAAAVgACAgCBmcb/2+r3/dHh8fyPkpX/kI6N/5yam/+dnJ3/paWk/6enpf+sr6//mpSR/3Bubf9SjbD8H4C+/QsrSvcCAAB/AAAAA3yVx//j8///3u/7/52gpf6pqKf+uLm5/rq7u/7Ly8v+ycnI/paWlf6LjY/+np2f/Xh+g/5gnL7/MX+y/xcgJ80BAgNNN1OUs6W84fDA1O73mJyj/ainpv+2trb/t7e4/8fHyP/Fxsb/kZGQ/4eGhP+vucT/j6G+/W53k/NlkbnwNoOv/AgiNb8CCBsQDRo/YwsaO3B0d33arKyp9q2trfWvr6/2u7u79ru7vPawr7H1sbCt9nJ2gOQIGD6bFCFEYB0qPE1Bf6SpEz9cggAAAAMCAQEBAQAAADIyMmlDQ0ONQUFBhUFBQYVCQkGFQkJBhUhISIRNTU2OKysrZAEAAAUBAQAAAgEAAAkEAAEDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
   { separator: ''},
   { label: "Запомнить изображение как base64, в контекстном меню", value: "CB.Save.WebScreenShotOnImage"},
   { label: "Сохранить выделенный текст в файл, в контекстном меню", value: "CB.Save.SelectionToFile" },
   { label: "Открыть выделенный текст в внешнем редакторе, в контекстном меню", value: "CB.Save.TextToEditor"},
];

var menuPopup = self.appendChild(document.createXULElement("menupopup"));
array.forEach((m,i)=> {
   if ("separator" in m) { menuPopup.appendChild(document.createXULElement("menuseparator")); return };
   var mItem = menuPopup.appendChild(document.createXULElement("menuitem"));
   mItem.setAttribute("label", m.label);
   mItem.setAttribute("class", "menuitem-iconic");
   if ("image" in m) mItem.setAttribute("image", m.image || array[i-1].image); 
   if ("value" in m) { 
       mItem.setAttribute('type', 'checkbox');
       mItem.setAttribute('checked', cbu.getPrefs(m.value) );
       mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value));
       }
   if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString()));
});
menuPopup.setAttribute("onclick", "event.stopPropagation()");


function aDate() {
 var t=new Date();
 var y=1900+t.getYear();
 var min=t.getMinutes(); if (min<10){min="0"+min};
 var h=t.getHours();
 var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";}
 var d=t.getDate();
 var curdate=d+" "+m+" "+y+" "+"г";
 var myfilename=curdate;
 return myfilename;
}
 

function WebScreenShotonImage(image) {
      var canvas = document.createElementNS(xhtmlns, 'canvas');
      canvas.width = image.naturalWidth;
      canvas.height = image.naturalHeight;
      var ctx = canvas.getContext('2d');
      ctx.drawImage(image, 0, 0);
      var base64 = canvas.toDataURL();
      gClipboard.write(base64);
   
      // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
      
     // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { 
     Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается
      }, "");
};



var saveToFile = function (fileContent, fileName) {
    var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
    uc.charset = 'utf-8';
    fileContent = uc.ConvertFromUnicode(fileContent);

    var nsIFilePicker = Components.interfaces.nsIFilePicker;
    var fp = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
    fp.init(window, '', fp.modeSave);
    fp.defaultString = fileName;
    fp.appendFilters(fp.filterHTML);
    fp.appendFilters(fp.filterAll);
    fp.open(function (rv) {
  if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
    var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream);
    stream.init(fp.file, 0x02|0x20|0x08, 0666, 0);
    stream.write(fileContent, fileContent.length);
    stream.close();
  }
});
};

function savePageToHTML() {
var vert=`javascript:(function(){var getSelWin=function(w){if(w.getSelection().toString())return w;for(var i=0,f,r;f=w.frames[i];i++){try{if(r=getSelWin(f))return r}catch(e){}}};var selWin=getSelWin(window),win=selWin||window,doc=win.document,loc=win.location;var qualifyURL=function(url,base){if(!url||/^([a-z]+:|%23)/.test(url))return url;var a=doc.createElement('a');if(base){a.href=base;a.href=a.protocol+(url.charAt(0)=='/'%3F(url.charAt(1)=='/'%3F'':'//'+a.host):'//'+a.host+a.pathname.slice(0,(url.charAt(0)!='%3F'&&a.pathname.lastIndexOf('/')+1)||a.pathname.length))+url}else{a.href=url};return a.href};var encodeImg=function(src,obj){var canvas,img,ret=src;if(/^https%3F:%5C/%5C//.test(src)){canvas=doc.createElement('canvas');if(!obj||obj.nodeName.toLowerCase()!='img'){img=doc.createElement('img');img.src=src}else{img=obj};if(img.complete)try{canvas.width=img.width;canvas.height=img.height;canvas.getContext('2d').drawImage(img,0,0);ret=canvas.toDataURL((/%5C.jpe%3Fg/i.test(src)%3F'image/jpeg':'image/png'))}catch(e){};if(img!=obj)img.src='about:blank'};return ret};var toSrc=function(obj){var strToSrc=function(str){var chr,ret='',i=0,meta={'%5Cb':'%5C%5Cb','%5Ct':'%5C%5Ct','%5Cn':'%5C%5Cn','%5Cf':'%5C%5Cf','%5Cr':'%5C%5Cr','%5Cx22':'%5C%5C%5Cx22','%5C%5C':'%5C%5C%5C%5C'};while(chr=str.charAt(i++)){ret+=meta[chr]||chr};return'%5Cx22'+ret+'%5Cx22'},arrToSrc=function(arr){var ret=[];for(var i=0;i<arr.length;i++){ret[i]=toSrc(arr[i])||'null'};return'['+ret.join(',')+']'},objToSrc=function(obj){var val,ret=[];for(var prop in obj){if(Object.prototype.hasOwnProperty.call(obj,prop)&&(val=toSrc(obj[prop])))ret.push(strToSrc(prop)+': '+val)};return'{'+ret.join(',')+'}'};switch(Object.prototype.toString.call(obj).slice(8,-1)){case'Array':return arrToSrc(obj);case'Boolean':case'Function':case'RegExp':return obj.toString();case'Date':return'new Date('+obj.getTime()+')';case'Math':return'Math';case'Number':return isFinite(obj)%3FString(obj):'null';case'Object':return objToSrc(obj);case'String':return strToSrc(obj);default:return obj%3F(obj.nodeType==1&&obj.id%3F'document.getElementById('+strToSrc(obj.id)+')':'{}'):'null'}};var ele,pEle,clone,reUrl=/(url%5C(%5Cx22%3F)(.+%3F)(%5Cx22%3F%5C))/g;if(selWin){var rng=win.getSelection().getRangeAt(0);pEle=rng.commonAncestorContainer;ele=rng.cloneContents()}else{pEle=doc.documentElement;ele=(doc.body||doc.getElementsByTagName('body')[0]).cloneNode(true)};while(pEle){if(pEle.nodeType==1){clone=pEle.cloneNode(false);clone.appendChild(ele);ele=clone};pEle=pEle.parentNode};var sel=doc.createElement('div');sel.appendChild(ele);for(var el,all=sel.getElementsByTagName('*'),i=all.length;i--;){el=all[i];if(el.style&&el.style.backgroundImage)el.style.backgroundImage=el.style.backgroundImage.replace(reUrl,function(a,b,c,d){return b+encodeImg(qualifyURL(c))+d});switch(el.nodeName.toLowerCase()){case'link':case'style':case'script':el.parentNode.removeChild(el);break;case'a':case'area':if(el.hasAttribute('href')&&el.getAttribute('href').charAt(0)!='%23')el.href=el.href;break;case'img':case'input':if(el.hasAttribute('src'))el.src=encodeImg(el.src,el);break;case'audio':case'video':case'embed':case'frame':case'iframe':if(el.hasAttribute('src'))el.src=el.src;break;case'object':if(el.hasAttribute('data'))el.data=el.data;break;case'form':if(el.hasAttribute('action'))el.action=el.action;break}};var head=ele.insertBefore(doc.createElement('head'),ele.firstChild);var meta=doc.createElement('meta');meta.httpEquiv='content-type';meta.content='text/html; charset=utf-8';head.appendChild(meta);var title=doc.getElementsByTagName('title')[0];if(title)head.appendChild(title.cloneNode(true));head.copyScript=function(){if('$'in win)return;var f=doc.createElement('iframe');f.src='about:blank';f.setAttribute('style','position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;');doc.documentElement.appendChild(f);var str,script=doc.createElement('script');script.type='text/javascript';for(var name in win){if(name in f.contentWindow||!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name))continue;try{str=toSrc(win[name]);if(!/%5C{%5Cs*%5C[native code%5C]%5Cs*%5C}/.test(str)){script.appendChild(doc.createTextNode('var '+name+' = '+str.replace(/<%5C/(script>)/ig,'<%5C%5C/$1')+';%5Cn'))}}catch(e){}};f.parentNode.removeChild(f);if(script.childNodes.length)this.nextSibling.appendChild(script)};head.copyScript();head.copyStyle=function(s){if(!s)return;var style=doc.createElement('style');style.type='text/css';if(s.media&&s.media.mediaText)style.media=s.media.mediaText;try{for(var i=0,rule;rule=s.cssRules[i];i++){if(rule.type!=3){if((!rule.selectorText||rule.selectorText.indexOf(':')!=-1)||(!sel.querySelector||sel.querySelector(rule.selectorText))){style.appendChild(doc.createTextNode(rule.cssText.replace(reUrl,function(a,b,c,d){var url=qualifyURL(c,s.href);if(rule.type==1&&rule.style&&rule.style.backgroundImage)url=encodeImg(url);return b+url+d})+'%5Cn'))}}else{this.copyStyle(rule.styleSheet)}}}catch(e){if(s.ownerNode)style=s.ownerNode.cloneNode(false)};this.appendChild(style)};var sheets=doc.styleSheets;for(var j=0;j<sheets.length;j++)head.copyStyle(sheets[j]);head.appendChild(doc.createTextNode('%5Cn'));var doctype='',dt=doc.doctype;if(dt&&dt.name){doctype+='<!DOCTYPE '+dt.name;if(dt.publicId)doctype+=' PUBLIC %5Cx22'+dt.publicId+'%5Cx22';if(dt.systemId)doctype+=' %5Cx22'+dt.systemId+'%5Cx22';doctype+='>%5Cn'};var href = 'data:text/html;charset=utf-8,' + encodeURIComponent(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->');var a = document.documentElement.appendChild(document.createElement("a"));a.setAttribute("href", href);var name = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());name=name.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');name += (function () {var d = new Date(), z=function(n){return '_' + (n < 10 ? '0' : '') + n};return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());})();a.setAttribute("download", name + ".html");a.click();a.remove();})();`;
gBrowser. loadURI(vert, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});
};


function saveShortcuts() {
var file = Components.classes["@mozilla.org/file/local;1"].
           createInstance(Components.interfaces.nsIFile);
file.initWithPath(folderpath);

if( !file.exists() || !file.isDirectory() ) {   file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0x1B6);}

var savetodir=folderpath+"\\"; 
var urllink=gBrowser.currentURI.spec;
var out=getTabLabel();
var filename=savetodir+out+'.url';
var data="[InternetShortcut]\r\nURL="+urllink+"\r\n";

saveToFile(data, filename);
 // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
   // подсказка
   var notific = 'Сохранил в: ' + folderpath;
   var image = gBrowser.selectedBrowser.mIconURL;
   Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(image, filename, notific);
};

// Кодировать изображение или текстовой файл в base64 .............
function copyFaviconbase(){
var fp = window.makeFilePicker();
fp.init(window, "Открыть файл", fp.modeOpen);
fp.appendFilter("Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml; *.xhtml; *.jpe; *.jpg; *.jpeg;\
                                    *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw");
  fp.open(re=> { 
  if ( re != fp.returnOK ) return;
   var file = fp.file;
   var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
   inputStream.init(file, 0x01, 0600, 0);
   var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
   stream.setInputStream(inputStream);
   var encoded = btoa(stream.readBytes(stream.available()));
   var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file);
   var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded;
   gClipboard.write(dataURI);
   //Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Скопировал файл как base64");
    // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
      
     // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { 
     Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Запомнил изображение как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается
      }, "");
});
};

// Сохранить страницу как PDF файл через сервис 'pdfmyurl.com' .............
function savePageToPDF() {
      var loc = gBrowser.currentURI.spec;
   var vert = "http://pdfmyurl.com?url=" + loc;
  
   gBrowser. loadURI(vert, {
   triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
   });
}; 

// Сохранить иконку текущего сайта с диалогом сохранения .............
function saveFavicon() {
       var uri = gBrowser.currentURI;
       function getSiteName() {
                  try { var domain = uri.host.split('.') } catch(e) { return "" };
                   domain = (domain.length == 2) ? domain[0] : domain[1]
                   return domain.charAt(0).toUpperCase() + domain.slice(1).split('.')[0] + " ";  
            };
      saveImageURL(gBrowser.selectedTab.image, getSiteName(), null, false, false, null, window.document);
};


// Скопировать иконку текущего сайта как base64 код .............
function copyFaviconData() {
   var img = new Image();
   img.src = gBrowser.selectedTab.image;
   WebScreenShotonImage(img);
};


// Сохранить выделенный текст или весь текст на странице как txt файл .............
function saveSelectionToTxt() {

let browserMM = gBrowser.selectedBrowser.messageManager;
        browserMM.addMessageListener('getSelection', function listener(message) {
        var sel = message.data;
       !sel && document.getElementById("cmd_selectAll").doCommand(); 
     
   // создать название файла из заголовка страницы и текущего времени и сохранить текст ....
   var fileTitle = getTabLabel() + '  ' + aDate().replace(/:/g, ".");
   saveURL("data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + ("\r\n\r\n" + sel)), 
                                fileTitle + ".txt", null, false, false, null, window.document);
   !sel && goDoCommand("cmd_selectNone"); 
 browserMM.removeMessageListener('getSelection', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelection", content.document.getSelection().toString())', false);
};

(popup => addEventListener("popupshowing", {
    handleEvent(e) {
        if (this.shouldHide) return;

        var menuitem = document.createXULElement("menuitem");
        menuitem.id = "content-baseItem";
        menuitem.className = "menuitem-iconic";
        menuitem.setAttribute("oncommand", "copyImageAsBase64()");
        menuitem.setAttribute("label", "Запомнить изображение как base64");
        menuitem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AIAQ/wCAEf8AgA//AIAR/wCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AgBX/AIAVAAAAAAAAAAD/AIAo/wCA//8AgP//AID//wCA//8AgP//AIAoAAAAAAAAAAAAAAAAAAAAAP8AgBL/AID//wCA//8AgA3/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgBAAAAAAAAAAAAAAAAD/AIAR/wCA//8AgP//AIAK/wCACv8AgP//AID//wCAIf8AgAX/AIAh/wCA//8AgP//AIAQAAAAAAAAAAAAAAAA/wCACv8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAUAAAAA/wCABf8AgP//AID//wCACgAAAAD/AIAQ/wCADP8AgCH/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCABf8AgCH/AID//wCA//8AgAv/AIAh/wCA//8AgP//AID//wCA//8AgP//AIAH/wCAB/8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AIAg/wCA//8AgP//AID//wCA//8AgP//AID//wCAB/8AgAf/AID//wCA//8AgP//AID//wCA//8AgP//AIAh/wCAC/8AgP//AID//wCAHP8AgBz/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCACf8AgA7/AIAMAAAAAP8AgAj/AID//wCA//8AgAP/AIAD/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCABQAAAAAAAAAA/wCADf8AgAr/AIAL/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCAB/8AgAr/AID//wCA//8AgCH/AIAH/wCAJf8AgP//AID//wCAI/8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAf/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgCT/AID//wCA//8AgAr/AIAK/wCA//8AgP//AIAKAAAAAP8AgCj/AID//wCA//8AgP//AID//wCA//8AgCP/AIAM/wCA//8AgP//AIAN/wCADf8AgP//AID//wCADQAAAAAAAAAA/wCAEP8AgBH/AIAP/wCAEf8AgBAAAAAAAAAAAP8AgBT/AIAVAAAAAAAAAAD/AIAV/wCAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQcH5rEGA8KxBAHCsQQBwrEEIQKxBAACsQQAArEEAAKxBAQCsQQwArEEAAKxBAACsQYAArEHBmaxB//+sQQ==");
        popup.append(menuitem);
        addDestructor(() => menuitem.remove());

        menuitem.copyImageAsBase64 = () => gBrowser.selectedBrowser.messageManager
            .loadFrameScript("data:;charset=utf-8," + encodeURIComponent(this.code()), false);

        this.handleEvent = () => menuitem.hidden = this.shouldHide;
    },
    get shouldHide() {
        return !gContextMenu.onImage || !cbu.getPrefs("CB.Save.WebScreenShotOnImage");
    },
    code: () => `(selectors => {

        var getImage = doc => {
            var elm = doc.querySelector(selectors.shift());
            if (selectors.length) elm = getImage(elm.contentDocument);
            return elm;
        }
        var image = getImage(content.document);

        var canvas = image.ownerDocument.createElementNS("${xhtmlns}", "canvas");
        canvas.width = image.naturalWidth;
        canvas.height = image.naturalHeight;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(image, 0, 0);
        var base64 = canvas.toDataURL();

        Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
            .copyStringToClipboard(base64, Ci.nsIClipboard.kGlobalClipboard);

        Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
            .showAlertNotification(base64, "${self.label}", "Запомнил изображение как base64");
    })(${
        JSON.stringify(gContextMenu.targetSelectors)
    })`
}, false, popup || 1))(document.getElementById("contentAreaContextMenu"));


// Добавляем в контекстного меню страницы новые пункты .............
((contextMenu, el)=> {

   // в контекстного меню выделенного текста ....
   var saveItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el);
   saveItem.id = "content-saveItem";
   saveItem.setAttribute("label", "Сохранить выделенный текст в файл");
   saveItem.onclick =()=> saveSelectionToFile();

   var editorItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el);
   editorItem.id = "content-editorItem";
   editorItem.setAttribute("label", "Открыть выделенный текст в внешнем редакторе");
   editorItem.onclick =()=> textToEditor();


    // устанавливаем где и при каких настройках показывать новые пункты ....
   addEventListener('popupshowing', e=> {
      if (e.target != e.currentTarget) return;
      var sel = gContextMenu.isTextSelected;
      saveItem.hidden = !sel || !cbu.getPrefs("CB.Save.SelectionToFile");
      editorItem.hidden = !sel || !cbu.getPrefs("CB.Save.TextToEditor"); 
      }, false, contextMenu);

   // удалять новые пункти при изминениях ....
   addDestructor(()=> {
      saveItem.remove(); editorItem.remove();
   });   
})(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open"));


// Сохранить выделенный текст в файл на рабочем столе .............
function saveSelectionToFile() {

 let browserMM = gBrowser.selectedBrowser.messageManager;
 browserMM.addMessageListener('getSelect', function listener(message) {
   // создать текст для записи
   var url = gBrowser.currentURI.spec;
   if (/\.рф/.test(url.host)) url = convertFromUnicode("UTF-8", url);
   
   var time = convertFromUnicode("UTF-8", aDate().replace(/:/g, "."));
   var text = convertFromUnicode("UTF-8", message.data); 
   var title = convertFromUnicode("UTF-8", getTabLabel());
   
   var text = "..............................................................\n"
            + title + " - " + time + "\n" + url + "\n\n" + text + "\n\n\n";
   var text = text.replace(/\u000A/g, "\u000D\u000A").replace(/\u000D\u000D\u000A/g, "\u000D\u000A");

   // путь к файлу и название файла
   var file = Services.dirsvc.get("Desk", Ci.nsIFile); 
   file.append("Save - " + (aDate().replace(/:/g, ".")) + ".txt");
          
   // создать файл с текстом или добавлять текст в файл
   var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
   file.exists() ? foStream.init(file, 0x02 | 0x10, 0664, 0) : foStream.init(file, 0x02|0x08|0x20, 0666, 0);
   foStream.write(text, text.length);
   foStream.close();
    // всплывающая подсказка дает возможность открыть файл если кликнуть на подсказке
       var notificat = 'Сохранил выделенный текст в файл на рабочий стол'; 
   var image = gBrowser.selectedTab.image || self.image;
   Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
    .showAlertNotification(image, notificat, "Кликни чтобы открыть файл", true, "", (s, t)=> { 
      if (t == 'alertclickcallback') file.launch();
   }, "");
 browserMM.removeMessageListener('getSelect', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false);

};


// Создать текстовой файл с выделенным текстом в папке профиля и открыть в редакторе .............
function textToEditor() {


 let browserMM = gBrowser.selectedBrowser.messageManager;
 browserMM.addMessageListener('getSelect', function listener(message) {
   // создать текст для записи
    var text = convertFromUnicode("UTF-8", message.data); 
    var file = Services.dirsvc.get('ProfD', Ci.nsIFile);
   file.append("TextToEditor.txt");
   custombuttonsUtils.writeFile(file.path, text);
   file.launch(); 
          

 browserMM.removeMessageListener('getSelect', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false);
};


// Конвертировать текст в юникод .............
function convertFromUnicode(charset, str) {
     var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
     converter.charset = charset;
     str = converter.ConvertFromUnicode(str);
     return str + converter.Finish();
 
};

// Получить название вкладки без не сохраняемых символов и лишних пробелов ..............
function getTabLabel() { 
   var label = gBrowser.selectedTab.label;      
   var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
   return label.substring(0, 50);
};
 
 
 ((main, parts) => this.onmousedown = e => {
    if (e.button) return;
    this.onmousedown = null;

    var df = MozXULElement.parseXULToFragment(`
        <menugroup orient="vertical">
            <menuseparator/>
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить всю страницу как PNG"
                value="all"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить видимую часть страницы как PNG"
                value="page"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAIBkAAAEAIAAMDQAAFgAAACgAAAAgAAAAMgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29fT/2tra/8jIyP/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8jIyP/a2tr/9vX0/+zs7P/ak0b/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/9qTRv/s7Oz/7Ozs/+J9Dv/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+/6SdmP/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/+vn4//z7+v/6+fj/4n0O/+zs7P/s7Oz/4n0O//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/aFtT//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//j39v/ifQ7/7Ozs/+zs7P/ifQ7/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P9oW1P/7+zq/+/s6v/v7Or/8O3r//Dt6//w7ev/8O3r//Dt6//w7ev/8O3r/+/s6v/w7ev/9fTy/+J9Dv/s7Oz/7Ozs/+J9Dv/49/b/+Pf2//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4/2hbU//q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/y8O//4n0O/+zs7P/s7Oz/4n0O//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/aFtT/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe//Dt6//ifQ7/7Ozs/+zs7P/ifQ7/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P9oW1P/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/7uro/+J9Dv/s7Oz/7Ozs/+J9Dv/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx/2hbU//x7+3/8vDv//Hv7f/x7+3/8e/t//Lw7//x7+3/8e/t//Lw7//x7+3/8vDv//Hv7f/29fT/4n0O/+zs7P/s7Oz/4n0O//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//aFtT/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/8vGwf/ifQ7/7Ozs/+zs7P/ifQ7/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f9nWlL/aFtT/2hbU/9nWlL/Z1pS/2hbU/9oW1P/Z1pS/2daUv9oW1P/aFtT/2hbU/9nWlL/pJyX/+J9Dv/s7Oz/7Ozs/+J9Dv/w7ev/8O3r//Dt6//w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Hv7f/w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Dt6//w7ev/4n0O/+zs7P/s7Oz/4n0O/+/s6v/v7Or/7uro/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/u6uj/7+zq/+/s6v/ifQ7/7Ozs/+zs7P/ifQ7/7uro/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7Ojm/+J9Dv/s7Oz/7Ozs/+J9Dv/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/4n0O/+zs7P/s7Oz/4n0O/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/ifQ7/7Ozs/+zs7P/ifQ7/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+J9Dv/s7Oz/7Ozs/+J9Dv/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/4n0O/+zs7P/s7Oz/4n0O/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/ifQ7/7Ozs/+zs7P/ifQ7/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+J9Dv/s7Oz/7Ozs/+J9Dv/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/k39z/4n0O/+zs7P/s7Oz/4n0O/+Lc2f/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/ifQ7/7Ozs/+zs7P/ifQ7/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+J9Dv/s7Oz/9fTy/+J9Dv/8+/r/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/4n0O//X08v/8+/r/6KFU/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ooVT//Pv6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить выбранный элемент страницы как PNG"
                value="click"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAADDn2Hfz5pE/8eVQP7IlkH/yJZB/8iWQf/IlUH/yJVA/8iVQP/IlED/yJQ//8iUP//IlD//yJM+/8iTPv/Hkj3/nI1w//bDbP//8OH//+zW///s1///69b//+rV///p1P//59L//+XQ///izf//38n//9vG///ZxP//1b///dG////Prf/KlkX/88N4/v37///99Pj//fT6//vy9v/68fT/+u/y//rt8P/66u3/+ufq//rl6P/64eT/+93h//3a3//71d7//9LK/86XR//0xHb//vv////18///9fT///f5///4////9f7///P8///v+f//7Pb//+nz///m8f//4eb//9vZ//3Y2v//1Mb/zphH//TGd//+/////Pj1///7///Q58r/m9aV/6TZnv+i15r/otWY/6LTlv+j0pb/mc6M/9DXuf//3+P//Nnc///Wyf/OmUf/9MZ3//7////8+/j//////53WnP+Y5pn/rvGv/6PvpP+e7p//me6b/5nvm/95533/mM+L///j7f/629z//9jL/86ZR//0xnf//v////z9+v//////qtup/8Xzxf/a/tn/z/vO/8n7yf/D+sL/xPvD/6Hzo/+j05b//+Tu//re3///2cz/zplI//XGeP/+/////P36//////+n26f/uvC6/9T71P/K+Mr/xvjG/8D3wP+/+L//nfCf/6LTlf//5u//+t/g///cz//OmUj/9MZ3//7////8/fr//////6rcqv/G9MX/3//f/9n92f/V/NX/0PzQ/9H+0P+s9a7/pdSY///o8f/64OL//9zP/86aSP/0xnf//v////z9+f//////ndid/5TjlP+v7q//qeyp/6jsqf+k7KX/p+6n/4Tlh/+Z0Y7//+r0//rh4v//3tH/zppI//TGd//+/////v77///////Y8Nj/p9+n/6/jr/+t4a3/rd2p/67bpv+u2ab/p9Wc/9jgx///6Oz//OPl///e0f/Omkj/9MV1//7//////fr///78///+/f///////////////////P////j////0+///8fn//+vu///m4v/94+P//97P/86ZSP/zx3v//v/////+/f///////f////v////7////+/////v+///7+///+/f///vz/P/98Pr//+33//3p9///5OL/zppL//a1Sv/0xoL/9cR7//XEfP/1xHz/9cR8//XEfP/1xH3/9cR8//XCev/1wXr/9b94//W9d//1u3X/87l0//y6bP/Llj7/+pMA/vWBAP/1gwD/9YMA//WDAP/1gwD/9YMA//WDAP/1gwD/9YQA//WEAP/1hAD/9YQA//WEAP/zhAH//okA/8qLIv3xpzP/4ptV/+OdU//jnVP/451T/+OdU//jnVP/451T/+OdU//jnVL/451S/+OdUv/jnVL/451S/+GdVf/qnUf/2aRJ/9q0c9/8yn7/98V5/vjGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6/vrIe/+jj2y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить выбранную область страницы как PNG"
                value="clipping"/>
        </menugroup>
    `);
    var menugroup = df.firstChild;
    menugroup.setAttribute("context", "");
    menugroup.setAttribute("oncommand", "handleCommand(event);");
    menugroup.handleCommand = e => {
        var name = _id + ":DataURLReady";
        main = main.replace("%MESSAGE_NAME%", name);

        var urls = {}, configurable = true, enumerable = true;
        Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, {
            configurable, enumerable, get() {
                var value = `data:;charset=utf-8,({${
                    encodeURIComponent(main + part)
                }%0A}).init("${key}")`;
                Object.defineProperty(urls, key, {configurable, enumerable, value});
                return value;
        }}));
        var getTabLabel = () => {
            var label = gBrowser.selectedTab.label;      
            var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
            return label.substring(0, 50);
        }
        var listener = msg => {
            var fp = makeFilePicker();
            fp.init(window, "Сохранить как…", fp.modeSave);
            fp.appendFilter("", "*.png");
            fp.defaultString = getTabLabel() + ".png";   
            fp.open(res => res == fp.returnCancel || !fp.file || makeWebBrowserPersist().saveURI(
                Services.io.newURI(msg.data), document.nodePrincipal,
                null, null, null, null, null, fp.file, null
            ));
        }
        messageManager.addMessageListener(name, listener);
        addDestructor(() => messageManager.removeMessageListener(name, listener));

        (menugroup.handleCommand = e => gBrowser.selectedBrowser.messageManager
            .loadFrameScript(urls[e.target.value], false)
        )(e);
    }
    menuPopup.querySelector('menuitem[label*="ярлык"]').after(df);
})(`
    init(cmd) {
        cmd.startsWith("c")
            ? this[cmd].init(this[cmd].parent = this)
            : this[cmd]();
    },
    capture(win, x, y, width, height) {
        var canvas = win.document.createElementNS("${xhtmlns}", "canvas");
        canvas.width = width;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        var tryDraw = ind => {
            try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")}
            catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);}
        }
        tryDraw(17);
        sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png"));
    },
    `, {

    all: `all() {
        var win = content;
        this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY);
    }`,
    page: `page() {
        var win = content, doc = win.document, body = doc.body, html = doc.documentElement;
        var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft;
        var scrY = (body.scrollTop || html.scrollTop) - html.clientTop;
        this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight);
    }`,
    clipping: `clipping: {
        handleEvent(e) {
            if (e.button) return false;
            e.preventDefault();
            e.stopPropagation();
            switch(e.type) {
                case "mousedown":
                    this.downX = e.pageX;
                    this.downY = e.pageY;
                    this.bs.left = this.downX + "px";
                    this.bs.top = this.downY + "px";
                    this.body.appendChild(this.box);
                    this.flag = true;
                    break;
                case "mousemove":
                    if (!this.flag) return;
                    this.moveX = e.pageX;
                    this.moveY = e.pageY;
                    if (this.downX > this.moveX) this.bs.left = this.moveX + "px";
                    if (this.downY > this.moveY) this.bs.top  = this.moveY + "px";
                    this.bs.width = Math.abs(this.moveX - this.downX) + "px";
                    this.bs.height = Math.abs(this.moveY - this.downY) + "px";
                    break;
                case "mouseup":
                    this.uninit();
                    break;
            }
        },
        init() {
            var win = {};
            Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
                .getFocusedElementForWindow(content, true, win);
            this.win = win.value;

            this.doc = this.win.document;
            this.body = this.doc.body;
            if (!HTMLBodyElement.isInstance(this.body)) {
                Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
                    .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!");
                return false;
            }
            this.flag = null;
            this.box = this.doc.createElement("div");
            this.bs = this.box.style;
            this.bs.border = "#0f0 dashed 2px";
            this.bs.position = "absolute";
            this.bs.zIndex = "2147483647";
            this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor;
            this.body.style.cursor = "crosshair";
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)];
            this.body.style.cursor = this.defaultCursor;
            this.body.removeChild(this.box);
            this.parent.capture.apply(this, pos);
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`,
    click: `click: {
        getPosition() {
            var html = this.doc.documentElement;
            var body = this.doc.body;
            var rect = this.target.getBoundingClientRect();
            return [
                this.win,
                Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft,
                Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop,
                parseInt(rect.width),
                parseInt(rect.height)
            ];
        },
        highlight() {
            this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false;
            this.target.style.cssText += "outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;";
        },
        lowlight() {
            if (this.orgStyle) this.target.style.cssText = this.orgStyle;
            else this.target.removeAttribute("style");
        },
        handleEvent(e) {
            switch(e.type){
                case "click":
                    if (e.button) return;
                    e.preventDefault();
                    e.stopPropagation();
                    this.lowlight();
                    this.parent.capture.apply(this, this.getPosition());
                    this.uninit();
                    break;
                case "mouseover":
                    if (this.target) this.lowlight();
                    this.target = e.target;
                    this.highlight();
                    break;
            }
        },
        init() {
            this.win = content;
            this.doc = content.document;
            ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            this.target = false;
            ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`
});

Отредактировано Andrey_Krropotkin (31-07-2019 21:21:55)

Отсутствует

 

№1357401-08-2019 15:12:03

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 66.0

Re: Custom Buttons

Кнопка "Перейти обновить" . Как бы ее подрихтовать, хотя бы "обновить вкладку" , в смысле , команду не из адреса, а как в контексте вкладки.
К, примеру, в адресе - пусто, а обновить надо кнопкой, неохота в контекст вкладки лезть...

Выделить код

Код:

/*Initialization Code*/
this.onclick = this.oncontextmenu = function(event) {
if (event.button == 0) {
if (gURLBar.focused) {

  
gURLBar.handleCommand(event);

}
else {

BrowserReload();
}
}

Отредактировано solombala (01-08-2019 15:44:01)

Отсутствует

 

№1357502-08-2019 08:22:10

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 66.0

Re: Custom Buttons

egorsemenov06
А, она чистит? До боли знакомая кнопочка. В нормальных сборках thumbnails быть не должно...

Отсутствует

 

Board footer

Powered by PunBB
Modified by Mozilla Russia
Copyright © 2004–2020 Mozilla Russia GitHub mark
Язык отображения форума: [Русский] [English]