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

Многие проблемы быстрее решаются поиском по форуму и чтением FAQ, чем созданием новой темы и томительным ожиданием ответа.

№1345106-07-2019 00:53:35

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 319
UA: Firefox 67.0

Re: Custom Buttons

anywho

Спасибо, работает в userChrome.css
А в CВ нет

Отсутствует

 

№1345206-07-2019 02:09:59

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

Re: Custom Buttons

leex пишет

А в CВ нет

И не должно.
В CB, если нужно именно сделать пункт collapsed, тогда так:
document.getElementById("context-searchselect").collapsed = true;

или с деструктором:
(ss => ss.collapsed = !addDestructor(() => ss.collapsed = false))(
    document.getElementById("context-searchselect")
);

Garalf пишет

Косяк всплыл. Контекстное меню страницы стало горизонтальным. Это лечится?

Расширение Custom Buttons никак не взаимодействует с контекстным меню страницы.

Искажение, скорей всего, связано с тем, что коды кнопок добавляют в контекстное меню
свои элементы, созданные документом браузера при помощи метода createElement(),
который больше для этого не подходит.

Не так давно это обсуждалось. Здесь, под спойлером, немного подробностей, и,
далее, следущим постом, Андрей приводит примеры необходимых исправлений.

Отсутствует

 

№1345306-07-2019 13:23:29

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 319
UA: Firefox 67.0

Re: Custom Buttons

Спасибо, Dumby! кнопка скрылась.

Еще вот такой вопрос.
Если на одной кнопке в инициализации несколько кодов , то эта кнопка иногда становится бледной.
Я вот думаю что коды возможно необходимо разделять между собой специальными знаками чтобы кнопка не становилась бледной?

Отредактировано leex (06-07-2019 13:23:48)

Отсутствует

 

№1345406-07-2019 15:46:43

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

Re: Custom Buttons

Andrey_Krropotkin
Правлю кнопки в 69 вашим методом (2-й вариант)
А с этой Перевод текста не могу справиться

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

Выделить код

Код:

/*Initialization Code*/

var btn = this;

btn.lastClick = {
    X: 0,
    Y: 0
};
addEventListener("mouseup", function(e) {
    if (e && e.button == 0 && e.view.top == content) {
        var lc = btn.lastClick;
        lc.X = e.clientX;
        lc.Y = e.clientY;
    }
}, false);

var createWindow = function(text, status, title, id, pos, size){
    var win = document.commandDispatcher.focusedWindow.top == content ? document.commandDispatcher.focusedWindow : content;
    var doc = win.document, wId = 'ujs_window'+(id || ''), w = doc.getElementById(wId);
    var keyDown = function(e){if(!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode == 27)doc.getElementById(wId).closeWin()};
    if(w)w.closeWin();
    w = doc.createElement('div');
    w.setAttribute('style', 'position:fixed;display:block;visibility:hidden;left:0;top:0;width:auto;height:auto;border:1px solid gray;padding:3px;margin:0;z-index:99999;overflow:hidden;cursor:move;'+(typeof w.style.borderRadius === 'string' ? 'background-color:#f3f5f7;padding-top:4px;border-radius:4px;box-shadow:0 0 15px rgba(0,0,0,.4);' : 'background:-o-skin("Window Skin");'));
    w.id = wId;
    w.closeWin = function(){
        doc.removeEventListener('keydown', keyDown, false);
        this.parentNode.removeChild(this);
    };
    w.addEle = function(str, style){
        var ele = doc.createElement('div');
        ele.setAttribute('style', style);
        if(str){
            ele.innerHTML = str;
            for(var el, all = ele.getElementsByTagName('*'), i = all.length; i--;){
                el = all[i];
                if(/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)){
                    el.parentNode.removeChild(el);
                }else{
                    for(var att = el.attributes, j = att.length; j--;){
                        if(/^on[a-z]+$/i.test(att[j].name))att[j].value = '';
                    }
                }
            }
        };
        return this.appendChild(ele);
    };
    var img = doc.createElement('div');
    img.setAttribute('style', 'display:block;float:right;width:18px;height:18px;padding:0;margin:0;border:none;cursor:pointer;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAAZElEQVR42mNgGNyAGQixsVGU/AdCXjCbHczmxKaMFywlAlWiw6DAwIZNmQhYGqJEDWoqFiAGVmKKTwk73CRJ/Ep0GIyhbsPpO4hbIG4TwKaMk0EZ7hYBBk1cvmNDEmbDrmSwAADE8h10+qICXwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=");background:-o-skin("Caption Close Button Skin");');
    img.title = (win.navigator.language.indexOf('ru') == 0) ? '\u0417\u0430\u043A\u0440\u044B\u0442\u044C' : 'Close';
    img.addEventListener('click', function(){this.parentNode.closeWin()}, false);
    w.appendChild(img);
    w.addEle(title, 'display:table;color:#000;font:17px Times New Roman;width:auto;height:auto;padding:0;margin:0 2px;cursor:text;');
    var cnt = w.addEle(text, 'display:block;border:1px solid #aaa;margin:2px 0 1px 0;padding:4px;background-color:#fafcfe;color:#000;font:17px Times New Roman;width:320px;height:160px;overflow:auto;cursor:text;');
    w.addEle(status, 'display:table;color:#555;font:13px Times New Roman;width:auto;height:auto;padding:0;margin:0 3px;cursor:text;');
    w.addEventListener('mousedown', function(e){
        if(e.target == w){
            e.preventDefault();
            var grabX = e.clientX, grabY = e.clientY, origX = parseInt(w.style.left), origY = parseInt(w.style.top);
            var mouseMove = function(ev){
                w.style.left = origX+ev.clientX-grabX+'px';
                w.style.top = origY+ev.clientY-grabY+'px';
            };
            doc.addEventListener('mousemove', mouseMove, false);
            doc.addEventListener('mouseup', function(){doc.removeEventListener('mousemove', mouseMove, false)}, false);
        }
    }, false);
    doc.documentElement.appendChild(w);

    if(size){
        cnt.style.height = size.height;
        cnt.style.width = size.width;
    }else{
        for(var i = 3; i < 10; i++){
            if(cnt.scrollHeight > cnt.offsetHeight || cnt.scrollWidth > cnt.offsetWidth){
                cnt.style.height = 80*i+'px';
                cnt.style.width = 180*i+'px';
            }else break;
        }
    };
    var docEle = doc.compatMode == 'CSS1Compat' ? doc.documentElement : doc.body;
    var mX = docEle.clientWidth-w.offsetWidth, mY = docEle.clientHeight-w.offsetHeight;
    if(mX < 0){cnt.style.width = parseInt(cnt.style.width)+mX+'px'; mX = 0};
    if(mY < 0){cnt.style.height = parseInt(cnt.style.height)+mY+'px'; mY =0};
    var hW = parseInt(w.offsetWidth/2);
    w.style.left = (pos && pos.X < mX+hW ? (pos.X > hW ? pos.X-hW : 0) : mX)+'px';
    w.style.top = (pos && pos.Y+10 < mY ? pos.Y+10 : mY)+'px';
    w.style.visibility = 'visible';
    doc.addEventListener('keydown', keyDown, false);
};

var getSel = function (w) {
    var s, d = w.document;
    if (d.selection) {
        var r = d.selection.createRange();
        s = r ? r.text : ''
    } else {
        s = d.getSelection().toString();
        if (!s) {
            var e, t = d.getElementsByTagName('textarea'), u = d.getElementsByTagName('input'), i = t.length;
            while(e = (i > 0) ? t[--i] : u[-i--])try{
                if (e.offsetHeight > 0 && (s = e.value.substring(e.selectionStart, e.selectionEnd))) break
            }catch(x){}
        }
    };
    if (!s) for (var j = 0, f; f = w.frames[j]; j++) {
        try {
            if (s = getSel(f)) break
        } catch(x) {}
    };
    return s
};

var getHash = function (txt) {
    TKK=eval('((function(){var a\x3d817046147;var b\x3d-335196159;return 410049+\x27.\x27+(a+b)})())');
    function sM(a) {
        var b;
        if (null !== yr)
            b = yr;
        else {
            b = wr(String.fromCharCode(84));
            var c = wr(String.fromCharCode(75));
            b = [b(), b()];
            b[1] = c();
            b = (yr = window[b.join(c())] || "") || ""
        }
        var d = wr(String.fromCharCode(116))
            , c = wr(String.fromCharCode(107))
            , d = [d(), d()];
        d[1] = c();
        c = "&" + d.join("") + "=";
        d = b.split(".");
        b = Number(d[0]) || 0;
        for (var e = [], f = 0, g = 0; g < a.length; g++) {
            var l = a.charCodeAt(g);
            128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023),
                e[f++] = l >> 18 | 240,
                e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224,
                e[f++] = l >> 6 & 63 | 128),
                e[f++] = l & 63 | 128)
        }
        a = b;
        for (f = 0; f < e.length; f++)
            a += e[f],
                a = xr(a, "+-a^+6");
        a = xr(a, "+-3^+b+-f");
        a ^= Number(d[1]) || 0;
        0 > a && (a = (a & 2147483647) + 2147483648);
        a %= 1E6;
        return c + (a.toString() + "." + (a ^ b))
    }

    var yr = null;
    var wr = function(a) {
        return function() {
            return a
        }
    }
        , xr = function(a, b) {
        for (var c = 0; c < b.length - 2; c += 3) {
            var d = b.charAt(c + 2)
                , d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d)
                , d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
            a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d
        }
        return a
    };

    return sM(txt);
};

var ujs_google_translate = function (dir){
    var win = content, lng = win.navigator.language.slice(0, 2), txt = getSel(win), l = dir.split('|');
    if (txt) {
        var xhr = new XMLHttpRequest();
        var url = 'https://translate.google.com/translate_a/single?client=t&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt);

        xhr.open('POST', url, true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
        xhr.onreadystatechange = function() {
            try{
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0'));
                    for(var i = 0, n; n = tmp[0][i]; i++){
                        if(n[0])result += n[0].toString();
                    };
                    result = '<span style="background-color:inherit;color:inherit;font-size:inherit;font-family:Times,serif;">' + result + '</span>';
                    status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase();

                    createWindow(result, status, '<a href="'+url.replace(/&/g,'&amp;')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:17px Times New Roman;">Google Translate</a>', '_gt', btn.lastClick);
                }
            } catch (x){LOG(x)};
        };
        xhr.send('q=' + encodeURIComponent(txt));
    } else {
        win.open('http://translate.google.com/translate?u='+escape(win.location.href)+'&hl='+lng+'&langpair='+dir+'&tbb=1');
    };
};


btn.onclick = function(e){if(e.button == 0)ujs_google_translate('auto|ru')};

var contextMenu = document.getElementById("contentAreaContextMenu");
var nextEleMenu = document.getElementById("context-inspect");

var menuId = "context-ext-google-translate";
var menuItem = document.getElementById(menuId);
if (menuItem) {
    contextMenu.removeChild(menuItem.nextElementSibling);
    contextMenu.removeChild(menuItem.nextElementSibling);
    contextMenu.removeChild(menuItem);
};

menuItem = document.createElementNS(xulns,"menuitem");
menuItem.setAttribute("id", menuId);
menuItem.setAttribute("label", "Перевести на русский");
menuItem.setAttribute("class", "menuitem-iconic");
menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABBUlEQVR4Ac2RMU4DMRREB2MqihQpAkUaqnAduuQw4Sx03CGcJYIiDYqQ0lCsZ77535ZFcgAkRuPvV7zd/dLiz3N1PFb8hmRckrfELZrF9ONQ1B6Yz0MyM7S0O6zGkVprh/3+Kw/JzkHSpRpJKZkpr9fYbOx0cjVsCbWG31oHBM9mtt0q73ZcrdLhAMlYQKkUI22aqsNo8HKZAMQhvVaKSHWj2Q2aPU3mJQFY7nuHyvYFduP83WF3AJRfcPNYnr/Lp1G1uK4m9sno1LaUbnX/htf8BNzoneUD5NhjvLCMhURQSQ93QCZwXYjFwg3I0NZKrvoknQPMIHkt/jRAQKMeG2yX89/mB4EJbKbZxIhFAAAAAElFTkSuQmCC");
menuItem.addEventListener("command", function(){ujs_google_translate('auto|ru')}, false);
contextMenu.insertBefore(menuItem, nextEleMenu);

menuItem = document.createElementNS(xulns,"menuitem");
menuItem.setAttribute("label", "Перевести на английский");
menuItem.setAttribute("class", "menuitem-iconic");
menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAAB5UlEQVR4AWOgPZg0c9+Oq2+qpx9LaQaiw4mNB27efbs2uXFNQh2Q4Zm9zSNth23MhqjGnXMC86vnHmUS4udxv7OvOd2yPE7PTlfCTk9GVVEoyJA7WI8dyPA0k3U1l+jJMV7CeThpTZeoKDdDUsvBPSff/V+6/P/Bvf///2+bdvU/EKRm/k9IBNIlfZe+LFrzvbsbyJ636pKkyQyQhoUb7tZNvPpw3/0/TfX/ISAm5n94BIiRm/n/xYsLd946ei4vajoiqDuRAejQf//+o4PQ0P9+fmhiQGVnrr1kXJNYG2zEzXDxDsPv3wy/fkFJoOTPn39+/fr/69e/37//AUX+/mXRkO458wWHDba2f8wswCyQ3N+/f//8/fP7z5+TV18w2Mdt6plzPiptx5Wr7/+/ffMzOR6kysjkt74hWMPfp06O+2dulZCeFZKwnkE4m8E8bN3i9aCQ+dxY96GrK6bkGJD9R1v3l6Y20NVW9kt+/v//ZdbcFwkxTVPPMQimM8XEqkb7a/zoqLxkH9v4zVyI5+///wyMmtKMmhJAnbLqQjHxaw5r2orOmZN5uj470Zahat6BKS7JzpmLBHXm8GhM5lCdcP7ai1ZpixZxk9NXXjKIFzOIFjAI54oY1vXuue5qmscw+AAAW0tKxtPoicEAAAAASUVORK5CYII=");
menuItem.addEventListener("command", function(){ujs_google_translate('auto|en')}, false);
contextMenu.insertBefore(menuItem, nextEleMenu);

contextMenu.insertBefore(document.createElement("menuseparator"), nextEleMenu);

addEventListener('keydown', function (e){
 if(e.shiftKey && !e.ctrlKey && e.altKey && e.keyCode == 84)ujs_google_translate('auto|ru');
}, false);


Посмотрите пожалуйста. Может получится.

Отредактировано Garalf (06-07-2019 15:48:02)

Отсутствует

 

№1345506-07-2019 16:58:46

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

Re: Custom Buttons

leex пишет

Если на одной кнопке в инициализации несколько кодов , то эта кнопка иногда становится бледной.
Я вот думаю что коды возможно необходимо разделять между собой специальными знаками чтобы кнопка не становилась бледной?

А мне кажется, что большинство нормальных кодов
можно вообще стыковать впритык.

Но надёжней и нагляднее понажимать Enter, то есть
разделять коды одной или несколькими пустыми строками.
Никаких специальных разделителей не требуется.

Если проверено, что каждый код успешно работает
в отдельной кнопке, но вместе в одной кнопке проблемы,
то разбираться в причине нужно конкретно по ситуации,
общего совета дать не готов.

Garalf пишет

Посмотрите пожалуйста.

Ну, чисто формально, createElement не исправлен в 288-й строке.
Это пятая строка снизу, там, где создаётся menuseparator.

Отсутствует

 

№1345606-07-2019 19:00:42

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

Re: Custom Buttons

Dumby подскажи, может знаешь в чем причина. На 69b1 в кнопках, которые выводят диалоговые окна, перестали выделятся пункты внутри окна:
1 кнопка

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

Выделить код

Код:

/*CODE*/
var btn = this, br = gBrowser;
var trigger, trigger1, dialog, drives, count;
function jarLoaded(e) {        var val = gURLBar.value;
    if(val.search(/(file|jar):/) == 0 && val.search(/\.(ja|jar|xpi|zip)$/i) > -1) loadURI("jar:" + val + "!/");
}
function jarClicked(e) {    if(e.button == 0) {
    var tabUrl = gURLBar.value;
    if(tabUrl.search(/(file|jar):/) == 0 && tabUrl.search(/\/$/) > -1 || tabUrl.search(/view-source:/) == 0) {
        var node = e.target.href;
        if(node && node.search(/\.(exe|dll|sqlite|sqlite-shm|sqlite-wal)$/i) == -1) {
            if(tabUrl.search(/view-source:/) == 0 &&
                 node.search(/view-source:/) == 0    || node.search(/\.(ja|jar|xpi|zip)$/i) > -1) {
                e.preventDefault();    e.stopPropagation();    br.selectedTab = br.addTab(node);
            } else if(node.search(/\/$/) == -1) {
                e.preventDefault();    e.stopPropagation();    br.selectedTab = br.addTab("view-source:" + un(node));
}}}}}

function intf(drives, count) {    
    var data = '<?xml version="1.0"?>';
    data += '<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>';
    data += '<window title="' + btn.label + '" onload="self.load()" xmlns="' + xulns + '">';
    data +=   '<keyset>';
    data +=     '<key keycode="VK_ESCAPE" oncommand="close()"/>';
    data +=   '</keyset>';
    data +=   '<vbox flex="1">';
    data +=     '<richlistbox id="listbox" flex="1" >';
    data +=       '<listcols>';
    data +=         '<listcol/>';
    data +=         '<listcol flex="1" />';
    data +=       '</listcols>';
    data +=     '</richlistbox>';
    data +=     '<hbox>';
    data +=       '<button label=" Add-on" oncommand="self.addon(event)" tooltiptext="Ctrl+ = Без закрытия диалога"/>';
    data +=       '<button label=" 1 omni.ja" oncommand="self.omni(event)" tooltiptext="Ctrl+ = Без закрытия диалога"/>';
    data +=       '<button label=" 2 omni.ja" oncommand="self.omni1(event)" tooltiptext="Ctrl+ = Без закрытия диалога"/>';
    data +=       '<button label=" Firefox" oncommand="self.folder(event,' + "'GreD'" + ')" tooltiptext="Ctrl+ = Без закрытия диалога"/>';
    data +=       '<button label="Профиль" oncommand="self.folder(event,' + "'ProfD'" + ')" tooltiptext="Ctrl+ = Без закрытия диалога"/>';
    data +=       '<button label="Закрыть" oncommand="self.close()"/>';
    data +=     '</hbox>';
    data +=     '<hbox>';
    for(i = 0; i < count; i++)    data += '<button label="   ' + drives[i] + '" oncommand="self.mydrives(event,' +
                        "'" + drives[i] + "'" + ')" tooltiptext="Ctrl+ = Без закрытия диалога"/>';
    data +=     '</hbox>';        
    data +=   '</vbox>';
    data += '</window>';
    return data.replace(/self/g, "opener.document.getElementById(&quot;" + self.id + "&quot;)");
}
this.load = function() {
    if(!("AddonManager" in window))
            Components.utils.import("resource://gre/modules/AddonManager.jsm");
            
    if(!("Services" in window))
            Components.utils.import("resource://gre/modules/Services.jsm");
        
    var then, promise = AddonManager.getAddonsByTypes(["extension"], then = function(addons) {
        var list = new Array();
        addons.forEach( function(addon) { list.push(addon); });
        var options = {
        addonTypes: ["extension"]
        };
        
        function key(addon) {
                return options.addonTypes.indexOf(["extension"])
                + "\n" + addon.name.toLowerCase();
            }    
        
        list.sort( function(a, b){
                        var ka = key(a);
                var kb = key(b);
                return ka == kb ? 0 : ka < kb ? -1 : 1;
                
            });
     
  for(var addon of list){
          var item = document.createXULElement("richlistitem");
          item.setAttribute("selected", "false");
          var cell1 = document.createXULElement("vbox");
          cell1.setAttribute("class", "icon-container");
          item.appendChild(cell1);
          var cell2 = document.createXULElement("image");
          cell2.setAttribute("anoid", "icon");
          cell2.setAttribute("class", "icon");
          cell2.setAttribute("src", addon.iconURL);
          if (addon.iconURL == null) cell2.setAttribute("src", icon5);
          cell2.style.height="16px";
          cell2.style.width="16px";
          cell1.appendChild(cell2);
          var cell = document.createXULElement("label");
          cell.setAttribute("value", addon.name);
          cell.style.height="16px";
          item.appendChild(cell);
          var cell = document.createXULElement("label");
          cell.setAttribute("value", addon.version);
          item.appendChild(cell);
          var box = dialog.document.getElementById("listbox");
          box.appendChild(item).addon = addon;
          box.focus();
           }    
            });
        promise && typeof promise.then == "function" && promise.then(then, Components.utils.reportError); // Firefox 61+    

}

this.addon = e => {
    var item1 = dialog.document.querySelector("richlistitem[selected]");
    var uri = item1.addon.getResourceURI();
    if (uri.schemeIs("jar"))
        uri = uri.spec
    else {
        var file = uri.QueryInterface(Ci.nsIFileURL).file;
        uri = file.isDirectory() ? uri.spec : "jar:" + uri.spec + "!/";
    }
    if (!e.ctrlKey) {
        dialog.close();
        dialog = null;
    }
    br.selectedTab = br.addTrustedTab(uri);
}

this.omni1 = function(e) {
    var profileDir = Components.classes["@mozilla.org/file/directory_service;1"]
    .getService(Components.interfaces.nsIProperties)
   .get("GreD", Components.interfaces.nsIFile)
    .path;
    var file = profileDir + "\\browser\\omni.ja";
    var vert="jar:" + "file:///" + file + "!/";
    br.selectedTab = br.addTrustedTab(vert);
    if(!e.ctrlKey) dialog.close();
}
this.omni = function(e) {
    var file = Services.dirsvc.get("GreD", Ci.nsIFile);
    file.append("omni.ja");
    var uri = Services.io.newFileURI(file);
    br.selectedTab = br.addTrustedTab("jar:" + uri.spec + "!/");
    if(!e.ctrlKey) dialog.close();
}
this.folder = function(e, shortcut) {
    var uri = Services.io.newFileURI(Services.dirsvc.get(shortcut, Ci.nsIFile));
    br.selectedTab = br.addTrustedTab(uri.spec);
    if(!e.ctrlKey) dialog.close();
}
this.mydrives = function(e, letter) {    
        br.selectedTab = br.addTrustedTab("file:///" + letter + "/");
    if(!e.ctrlKey) dialog.close();
}
this.close = function() {    dialog.close();
}

Cu.import("resource://gre/modules/FileUtils.jsm");    
var root = new FileUtils.File("\\\\.");
var drivesEnum = root.directoryEntries;            
drives = [];
while (drivesEnum.hasMoreElements()) { drives.push(drivesEnum.getNext().QueryInterface(Ci.nsIFile).path); }
count = drives.length;
var url = "data:application/vnd.mozilla.xul+xml;text/plain," + encodeURIComponent(intf(drives, count));
var feature = "chrome,centerscreen,width=580,height=410,alwaysRaised";
dialog = window.openDialog(url, "", feature);    

this.onDestroy = function(reason) {
    if(reason == "update" || reason == "delete") {
        br.removeEventListener("click", jarClicked, false);
        br.tabContainer.removeEventListener("TabSelect", jarLoaded, false);
        if(reason == "delete") try { this.PS.clearUserPref(unzp); } catch (e) {}
}}


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

Выделить код

Код:

/*CODE*/
var dialog;
var defaultFavicon = "http://forum.mozilla-russia.org/uploaded/custombuttons_button.png";
var checkFavicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAltJREFUOMtt0l9olXUcx/HX8zzThHh07cLQJSZoozXNONMonYxI6zhwhnVnGQldqASZKN50USgWE0ThgCEiZV2JyNDpEnXMLhbuNBC7SOnfVHQj5p/Hmmw+53hxzo7T9bv5Xfy+78/v8/1+P4EnT7NqvIOMVEYkRF6q16hjegxBsVgMgiAoBk/AWRyQminyf2cguzi7veOrjg+xBD8H4+Cd2A7xNJLZxDUkMISrTH8QO7e3R/3z9TCKVSWBJitEOsFC1BOXpZOyfhzFOptPeW3O6wqFgh9Of7/7/bc/2BJoVi11CbVewXziMhiX4SSkY/lx2VktYOOejXJHcwOmeKlKqkWk1jTiholNJ/iu6VAF/iL/uVx3jsiz7lsdlqdNLcaNdMxF2+Jd1s5bB/Zd2qOt70tmVcoyoUijiPq6F7SvPGNp7fLK69b5m322YBs4fOVbn/R8WppJTbkgkqmSKsD+1gOWzmwyMDzgp+unrZm71q5X28Dxv9tt6N70uLsUkUIo0iuiMFIADc80aH7uLd8sOygQ6L7RZf3ZVoqJeAweqmjlSynDyH+joK76RUdWtJsUTvLLP3nvda4ynD5aJ6VMPBL41wmp/puDN0FVWGVyONnlO79pPbXS8IOkYhuSX3EL3JA6Frrgrsj6vit9Fdlr967KnnzTnfuDkrEwFUgu4iJK/X/svFulxP/lj5qG6hkL5r7c2D/Yb82Od12+9runUkYS/MnIhbL1IkJf65Lz+ObR5A0cFJld/kXlhtR1fOS8H8eQYEL0FpnqaS3IoBGhVK9IHid0uT2+/CEAYcfQrHKJYQAAAABJRU5ErkJggg==";
var uncheckFavicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAeJJREFUOMudk81qU1EUhb+7krYZaIkUhQQcqLVG30BKCyoOOtFROgiJZuxTXF/CcaEhhtyROCoO/C19BNOgM0mgk6IpGNN713WQUKMVU1yjczjrfJyz914Bf6hef5wbDn/clFTAFJVVAPTiOO4lSdKJouj7tD+Y3lQqletID7DPAwjwyakAjjLi5XajsX8KUK1W7xmvYTD0wR2hHgjjonAJVJjY95rN5s4JYHNz81o2m60BiWO/Kd0q7YZh6OnXhWGobvfTbfBdICNlnjca2/tBvV7PjYajJ4hF269brdZb/qFqpbpqfB84GgwGzzQajVaQFiUOkiT5wAwtryzvjb/IuXw+XxJQmJRqP4qiZBYgDENjdwDSlIKMixIEQabHGSWpB2DSooRSm/+SHaca00SaJMWzX3RxPBnqyXYfjKUb5XI5M7MGT0MBpQmor8PDwy7wFfvS3Nzc+ixA52NnVVJB0sCJO8G4t5WrhkeSbPv98XH8Lorav3WkXC5nFhZya3ayBmQcu9lqt7q/RrlSuWNYBwKkAxx34thfEGSz85eBEvbFiX232Wy+OhWmWq12JU3Th7bz0xHyZGX7mx2/aLfbn/+aRoCNjY2FpQtLK4gCdjE2QVb0YtPP5ea7W1tbw2n/Tyf84OJw4lGJAAAAAElFTkSuQmCC";
var uncheckStyle = 'background:white url("' + uncheckFavicon + '") no-repeat left center;color:black;padding-left:24px';
var checkStyle = 'background:red url("' + checkFavicon + '") no-repeat left center;color:black;padding-left:24px';

var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
    createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
    converter.charset = "UTF-8";
var t=new Date();
var y=1900+t.getYear();
var min=t.getMinutes(); if (min<10){min="0"+min};
var h=t.getHours();
var m=t.getMonth();switch(m){case 0: m="Января";break;case 1: m="Февраля";break;case 2: m="Марта";break;case 3: m="Апреля";break;case 4: m="Мая";break;case 5: m="Июня";break;case 6: m="Июля";break;case 7: m="Августа";break;case 8: m="Сентября";break;case 9: m="Остября";break;case 10: m="Ноября";break;default: m="Декабря";}
var d=t.getDate();
var stream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
const text1 = "Активные кнопки";
const text2 = "Неактивные кнопки";
   
var saveToFile = function (fileContent, fileName) {
    var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
    uc.charset = 'utf-8';
    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 createURI(node) {
  var name = node.getAttribute("name") || node.getAttribute("label") || "";
  var image = node.getAttribute("image") || node.getAttribute("cb-stdicon") || "";
  var mode = node.getAttribute("cb-mode") || 0;
  var initcode = node.getAttribute("cb-init") || "";
  var code = node.getAttribute("cb-oncommand") || "";
  var accelkey = node.getAttribute("cb-accelkey") || "";
  var help = node.getAttribute("Help") || "";
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "chrome://custombuttons/content/nbftemplate.xml", false);
  xhr.send(null);
  var doc = xhr.responseXML;
  setText(doc, "name", name, 0);
  setText(doc, "image", image, 1);
  setText(doc, "mode", mode, 0);
  setText(doc, "initcode", initcode, 1);
  setText(doc, "code", code, 1);
  setText(doc, "accelkey", accelkey, 1);
  setText(doc, "help", help, 1);
  var ser = new XMLSerializer();
  var data = ser.serializeToString(doc);
  return "custombutton://" + escape(data);
}

function setText(doc, nodeName, text, make_CDATASection) {
  var node = doc.getElementsByTagName(nodeName)[0], cds;
  if (!node) return;
  if (make_CDATASection) {
    try {
      cds = doc.createCDATASection(text || "");
    } catch(e) {
      cds = doc.createTextNode(text || "");
    }
    node.appendChild(cds);
  } else {
    node.textContent = text;
  }
}

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

function bDate() {
var curdate=y+" "+"год"+" "+d+" "+m+" "+h+":"+min;
var myfilename=converter.ConvertFromUnicode(curdate);
return myfilename;
}

this.close = function() {
dialog.close();
}

var data = '<?xml version="1.0"?>';
 data += '<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>';
 data += '<window onload="self.load()" title="Инструменты CB" xmlns="' + xulns + '">';
 data += '<keyset>';
 data += '<key keycode="VK_ESCAPE" oncommand="this.close()"/>';
 data += '</keyset>';
 data += '<vbox flex="1">';
 data += '<richlistbox flex="1" id="listbox" height="555" width="600" context="menupopup" onclick = "self.handle(event)" tooltiptext = "L=Выбрать \nM=Выбрать все \nR=Копировать/Сохранить как… " > ';
 data += '  <listhead>';
 data +=          '<treecol label="Label"  width="342" tooltiptext = "Активные кнопки выделены жирным шрифтом"/>';
 data +=          '<treecol label="Id" width="300" ';
 data +=          'tooltiptext = "Активные кнопки выделены жирным шрифтом"/>';
 data +=    '</listhead>';
 data += '</richlistbox>';
 data += '<popupset>';
 data += '<menupopup id="menupopup">';
 data +=    '<menuitem label="Копировать изображение кнопки в base64" ';
 data +=      'oncommand = "self.copyIMG()"/>';  
 data +=   '<menuitem class ="menuitem-iconic" image="chrome://custombuttons/skin/copy.png" label="Копировать кнопку в буфер обмена" ';
 data +=      'oncommand = "self.copyURI()"/>';
 data +=   '<menuitem label="Копировать кнопку как BBcode ссылку" ';
 data +=      'oncommand="self.copyBBCode()"/>';
 data +=   '<menuitem label="Копировать кнопку как текст" '; 
 data +=      'oncommand="self.copyButtonsCodeText()"/>';
 data +=   '<menuitem label="Копировать кнопку как HTML ссылку" ';
 data +=       'oncommand="self.copyHTML()"/>';
 data +=   '<menuseparator id="separator"/>';
 data +=   '<menuitem label="Сохранить изображение кнопки" ';
 data +=      'oncommand="self.saveIMG()"/>';
 data +=   '<menuitem label="Сохранить кнопку как HTML файл" ';
 data +=      'oncommand="self.SaveButton()"/>';
 data +=   '<menuitem label="Сохранить кнопку как XML файл" ';      
 data +=      'oncommand="self.save1XML()"/>';
 data += '</menupopup>';  
 data += '</popupset>';
 data += '<hbox>';
 data +=  '<spacer flex="1"/>';
 data +=     '<button label="Сохранить избранное" oncommand="self.exportHTML()" ';
 data +=     'oncontextmenu="self.exportHTML(),self.close()" ';     
 data +=     'tooltiptext = "Left - Сохранить выбранные кнопки Right - Сохранить выбранные кнопки и закрыть окно"/>';
 data +=     '<button label="Сохранить все" oncommand="self.archiveall()" ';
 data +=     'oncontextmenu="self.archiveall(),self.close()" ';     
 data +=     'tooltiptext = "Left - Сохранить все кнопки Right - Сохранить все кнопки и закрыть окно"/>';
 data +=     '<button label="Выбрать все" oncommand="self.handle1()" ';
 data +=     'tooltiptext = "Выбрать все кнопки"/>';     
 data +=     '<button label="Считать кнопки" oncommand="self.setFolder1()" ';
 data +=     'tooltiptext = "Открыыть файл с кнопками из заданной папки"/>';
 data +=  '<spacer flex="1"/>';
 data +=  '</hbox>';
 data +=  '<hbox>';
 data +=  '<spacer flex="1"/>';
 data +=     '<button label="Новая кнопка" oncommand="self.newbutton()" ';
 data +=     'tooltiptext = "Создать новую кнопку рядом с выбранной"/>';
 data +=     '<button label="Считать кнопки" oncommand="self.delete()" ';
 data +=     'tooltiptext = "Удалить выбранную кнопку"/>';
 data +=     '<button label="Клонировать" oncommand="self.clone()" ';
 data +=     'tooltiptext = "Клонировать рядом с собой выбранную кнопку"/>';
 data +=     '<button label="Редактировать" oncommand="self.edit()" ';
 data +=     'tooltiptext = "Редактировать выбранную кнопку"/> ';
 data +=     '<button label="Просмотр" oncommand="self.view()" ';
 data +=     'oncontextmenu="self.view(),self.close()" ';     
 data +=     'tooltiptext = "Left - Просмотреть в новой вкладке код,свойтва, атрибуты Right - Просмотреть в новой вкладке код,свойтва,атрибуты и закрыть окно"/> ';
 data +=  '<spacer flex="1"/>';
 data +=  '</hbox>';
 data += '</vbox>';
 data += '</window>';

data = data.replace(/self/g, "opener.document.getElementById(&quot;" + self.id + "&quot;)");
var url = "data:application/vnd.mozilla.xul+xml;text/plain," + encodeURIComponent(data);
var feature = "chrome,centerscreen,alwaysRaised"; 
dialog = window.openDialog(url,  "_blank", "chrome,centerscreen,dialog=no,resizable=yes");

this.reopen = function() {
dialog.close();
  dialog = window.openDialog(url, "", feature);
}

this.load = function() {
var aList = [], node = /custombuttons-button\d+/;
var nodeList = document.getElementsByClassName("toolbarbutton-1 chromeclass-toolbar-additional");
for(var i = 0; i < nodeList.length; i++) if(nodeList[i].id.match(node)) aList.push(nodeList[i]);

aList.sort(function (a, b) {
a = a.getAttribute("label");
b = b.getAttribute("label");
if(a < b) return -1;
if(a > b) return 1;
return 0;
})
for(var i = 0; i < aList.length; i++) createItem(aList[i]);

var bList = [], node = /custombuttons-button\d+/;
var nodeList = custombuttons.palette.getElementsByClassName("toolbarbutton-1 chromeclass-toolbar-additional");
for(var i = 0; i < nodeList.length; i++) if(nodeList[i].id.match(node)) bList.push(nodeList[i]);
bList.sort(function (a, b) {
a = a.getAttribute("label");
b = b.getAttribute("label");
if(a < b) return -1;
if(a > b) return 1;
return 0;
})
for(var i = 0; i < bList.length; i++) createItem(bList[i]);

function createItem(button) {
   var item = document.createElement("richlistitem");
   
    item.checked = false;
    item.setAttribute("style", uncheckStyle);
    item.setAttribute("value", button.id);
    item.setAttribute("selected", "false");
    
    var cell = document.createElement("image"); 
    cell.setAttribute("src", button.getAttribute("image") || getImage(button.getAttribute("cb-stdicon")));
    item.appendChild(cell);
    var cell = document.createElement("label");
    cell.style.width = "300px";
    cell.setAttribute("value", button.getAttribute("name") || button.getAttribute("label") || "");
    if(button.getAttribute("initialized")) cell.style.fontWeight = "bold";
    if(button.getAttribute("initialized")) cell.style.fontSize = "12px";
    if(button.getAttribute("initialized")) cell.style.textShadow = "#999 2px 2px 2px";
    if(!button.getAttribute("initialized")) cell.style.color = "#666";
    if(!button.getAttribute("initialized")) item.setAttribute("initialized", true);
    item.appendChild(cell);
    
      var cell = document.createElement("label");
      cell.setAttribute("value", nodeList[i].id);
      item.appendChild(cell);
    dialog.document.getElementById("listbox").appendChild(item);
     
  }
  function getImage(s) {
    if (s == "custombuttons-stdicon-1") return "chrome://custombuttons/skin/button.png";
    if (s == "custombuttons-stdicon-2") return "chrome://custombuttons/skin/stdicons/rbutton.png";
    if (s == "custombuttons-stdicon-3") return "chrome://custombuttons/skin/stdicons/gbutton.png";
    if (s == "custombuttons-stdicon-4") return "chrome://custombuttons/skin/stdicons/bbutton.png";
    return defaultFavicon;
  }
  dialog.document.getElementById("listbox").focus();
  dialog.document.getElementById("listbox").selectAll();
 
}

function toggleChoice(item) {
    item.checked = !item.checked;
    if (item.checked) item.setAttribute("style", checkStyle);
    else item.setAttribute("style", uncheckStyle) ;
  }
  
this.handle = function(event) {
  var listbox = dialog.document.getElementById("listbox");
  if (event.button == 0)
    toggleChoice(listbox.selectedItem);
  if (event.button == 1)
    for (var i = 0; i < listbox.itemCount; i++)
      toggleChoice(listbox.getItemAtIndex(i));
}

this.handle1 = function(event) {
  var listbox = dialog.document.getElementById("listbox");
      for (var i = 0; i < listbox.itemCount; i++)
      toggleChoice(listbox.getItemAtIndex(i));
}

this.copyURI = function() {
  var listbox = dialog.document.getElementById("listbox");
  var button = document.getElementById(listbox.selectedItem.getAttribute("value"));
  var href, text;
  if (button) {
    href = button.URI;
    text = button.name;
  } else {
    var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
    for (var i = 0; i < nodeList.length; i++) {
      if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) {
        href = createURI(nodeList[i]);
        text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
        break;
      }
    }
  }
  custombuttons.cbService.writeToClipboard(href);
  custombuttons.alertSlide(text, "Код был скопирован в буфер обмена");
}

this.copyBBCode = function() {
  var listbox = dialog.document.getElementById("listbox");
  }
  custombuttons.cbService.writeToClipboard("Install [url=" + href + "][img]" + defaultFavicon + "[/img][B] " + text + "[/B][/url]");
  custombuttons.alertSlide(text, "BBCode был скопирован в буфер обмена");
}

this.copyButtonsCodeText = function copyButtonsCodeText() {
   var listbox = dialog.document.getElementById("listbox");

}

this.copyHTML = function() {
  var listbox = dialog.document.getElementById("listbox");
}

this.copyIMG = function() {
  var listbox = dialog.document.getElementById("listbox");

}

this.saveIMG = function() {
  var listbox = dialog.document.getElementById("listbox");

}

this.SaveButton = function() {
  var listbox = dialog.document.getElementById("listbox");

}

this.newbutton = function() {
  var out = new Array();
  var listbox = dialog.document.getElementById("listbox");
  for (var i = 0; i < listbox.itemCount; i++) {
    if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
       custombuttons. cloneButton(document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")));
        var newButtonLink = custombuttons. makeButtonLink ("update",  document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")).nextSibling. id );
        var params = custombuttons. cbService. getButtonParameters (newButtonLink). wrappedJSObject;
        params. image = "";
        params. name = ""
        params. code = "";
        params. initCode = "";
        params. wrappedJSObject = params;
         custombuttons. cbService. installButton (params);
         this.reopen();
    }
  }
}
this.edit = function() {
  var out = new Array();
  var listbox = dialog.document.getElementById("listbox");
  for (var i = 0; i < listbox.itemCount; i++) {
    if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
       custombuttons.editButton(document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")));
       
    }
  }
}

this.save1XML = function() {
 var btn = null; 
  var btns = document.querySelectorAll("toolbarbutton[cb-init]");
  for (var i = 0; i < btns.length; i++) {
    if ("saveXML" in  btns[i]) {
      btn = btns[i];
      break;
    }
  }
  if (!btn) {
    custombuttons.alertBox(this.label, "Кнопка XML Exporter/Importer не установлена");
    return;
  }
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
btn.saveXML(document.getElementById(id).URI);
} 

this.clone = function() {
  var out = new Array();
  var listbox = dialog.document.getElementById("listbox");
  for (var i = 0; i < listbox.itemCount; i++) {
    if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
       custombuttons.cloneButton(document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")));
       this.reopen();
    }
  }
}

this.delete = function() {
  var out = new Array();
  var listbox = dialog.document.getElementById("listbox");
  for (var i = 0; i < listbox.itemCount; i++) {
    if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
      var id = listbox.getItemAtIndex(i).getAttribute("value");
      var oRemovedButton = document.getElementById(id);
      var sParentToolbarId = oRemovedButton.parentNode.id;
      var sRemovedButtonId = oRemovedButton.getAttribute("id");
      var cButtonsToRemove = document.getElementsByAttribute("id", sRemovedButtonId);
      var bRemoveFromOverlay = cButtonsToRemove.length == 1;
       custombuttons.cbService.removeButton(oRemovedButton, bRemoveFromOverlay);
        custombuttons.persistCurrentSets(sParentToolbarId, sRemovedButtonId, null);
        this.reopen();
    }
  }  
}
this.view = function() {
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
   var box = custombuttons.confirmBox3("CB TOOLS", "Просмотр в новой вкладке:", "Код", "Свойства", "Атрибуты");
    if (box == 0)  this.link();
    if (box == 2)  this.attr();
    if (box == 1)  this.prop();
  this.reopen();
}

var br = getBrowser();

function openTab(arr) {
  for (var i = 0; i < arr.length; i++) {
    arr[i] = converter.ConvertFromUnicode(arr[i]);
    arr[i] = arr[i].replace(/&/g, "&amp;");
    arr[i] = arr[i].replace(/>/g, "&gt;");
    arr[i] = arr[i].replace(/</g, "&lt;");
    arr[i] = arr[i].replace(/"/g, "&quot;");
    arr[i] = arr[i].replace(/'/g, "&apos;");
  }
  var data = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//En">';
  data += "<html><head><title>" + arr[1] + "</title>";
  data += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
  data += "</head><body><pre>" + arr.join("\n\n") + "</pre></body></html>";
  var info = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULAppInfo);
  if (info.name == "Firefox" || info.name == "SeaMonkey") {
  var tret = "data:text/html;charset=utf-8;base64," + btoa(data);
    br.selectedTab = br.addTab(tret, {
    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
  }
  if (info.name == "Thunderbird") {
    openContentTab("data:text/html;charset=utf-8;base64," + btoa(data));
  }
}

this.attr = function() {
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
   var node = document.getElementById(id);
  var out = new Array();
  out.push('windowtype="' + document.documentElement.getAttribute("windowtype") + '" id="' + id + '"');
  out.push("Атрибуты");
  for (var i = 0; i < node.attributes.length; i++) {
    if (node.attributes[i].nodeName == "cb-oncommand" ||
        node.attributes[i].nodeName == "cb-init"      ||
        node.attributes[i].nodeName == "Help") {
      out.push(node.attributes[i].nodeName + " " + typeof node.attributes[i].nodeValue + "\n" + "[omitted]");
    } else {
      out.push(node.attributes[i].nodeName + " " + typeof node.attributes[i].nodeValue + "\n" + node.attributes[i].nodeValue);
    }
  }
  openTab(out);
}

this.prop = function() {
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
   var node = document.getElementById(id);
  var out = new Array();
  out.push('windowtype="' + document.documentElement.getAttribute("windowtype") + '" id="' + id + '"');
  out.push("Свойства");
  for (var i in node) {
    if (i == "cbCommand"  ||
        i == "cbInitCode" ||
        i == "Help"       ||
        i == "URI") {
      out.push(i + " " + typeof node[i] + "\n" + "[omitted]");
    } else {
      out.push(i + " " + typeof node[i] + "\n" + node[i]);
    }
  }
  openTab(out);
}

this.link = function() {
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
  var out = new Array();
  out.push('windowtype="' + document.documentElement.getAttribute("windowtype") + '" id="' + id + '"');
  out.push("Код");
  out.push(unescape(document.getElementById(id).URI));
  openTab(out);
}

this.inspect = function() {
  if (typeof(inspectDOMDocument) == "undefined") {
    custombuttons.alertBox(this.label, "DOM Инспектор не установлен.");
    return;
  }
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
inspectDOMNode(document.getElementById(id));
}

this.setFolder1 = function(){
BrowserOpenFileWindow();
}

this.exportHTML = function () {
  var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
    createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  converter.charset = "UTF-8";
  var out = new Array();
  var listbox = dialog.document.getElementById("listbox");
  for (var i = 0; i < listbox.itemCount; i++) {
    if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
      var href = button.URI;
      var src = button.image;
      var text = button.name;
      if (!src) src = defaultFavicon;
      out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>');
      }
  }
  var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
  for (var i = 0; i < nodeList.length; i++) {
    if (nodeList[i].id.search("custombuttons-button") == 0 && document.getElementById(nodeList[i].id) == null) {
      for (var j = 0; j < listbox.itemCount; j++) {
        if (listbox.getItemAtIndex(j).checked && nodeList[i].id == listbox.getItemAtIndex(j).getAttribute("value")) {
          var href = createURI(nodeList[i]);
          var src = nodeList[i].getAttribute("image");
          var text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
          if (!src) src = defaultFavicon;
         out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>');
         
        }
      }
    }
  }
     var data = document.getElementById(this.id).getAttribute("Help").
    replace("<ol>", bDate() + "\n" + "<ol>" + "\n" + out.join("\n"));
  name = "CB buttons " + aDate().replace(/:/g, ".") + ".html"
  saveToFile(data, name);

  custombuttons.alertSlide("Кнопки", "сохранены");
}

this.archiveall = function() {
   var out = new Array();
      out.push('<a><hr><strong>' + converter.ConvertFromUnicode(text1) + '</strong><hr></a>');
  var listbox = dialog.document.getElementById("listbox");
    for (var i = 0; i < listbox.itemCount; i++) {
   if (document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
      var href = button.URI;
      var src = button.image;
      var text = button.name;
      if (!src) src = defaultFavicon;
      out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>');
   }
  }
 
     var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
      out.push('<a><hr><strong>' + converter.ConvertFromUnicode(text2) + '</strong><hr></a>');
  for (var i = 0; i < nodeList.length; i++) {
    if (nodeList[i].id.search("custombuttons-button") == 0 && document.getElementById(nodeList[i].id) == null) {
      var href = createURI(nodeList[i]);
      var src = nodeList[i].getAttribute("image");
      var text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
      if (!src) src = defaultFavicon;
      out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>');
    }
  }
var data = document.getElementById(this.id).getAttribute("Help").
    replace("<ol>", bDate() + "\n" + "<ol>" + "\n" + out.join("\n"));
  name = "CB buttons " + aDate().replace(/:/g, ".") + ".html"
  saveToFile(data, name);
}

function readFile(file) {
  var data = "";
  var fstream = Cc["@mozilla.org/network/file-input-stream;1"].
                createInstance(Ci.nsIFileInputStream);
  fstream.init(file, -1, 0, 0);
  var charset = "UTF-8";
  const replacementChar = Ci.nsIConverterInputStream
                            .DEFAULT_REPLACEMENT_CHARACTER;
  var is = Cc["@mozilla.org/intl/converter-input-stream;1"].
           createInstance(Ci.nsIConverterInputStream);
  is.init(fstream, charset, 1024, replacementChar);
  var str = {};
  while (is.readString(4096, str) != 0) {
    data += str.value;
  }
  is.close();
  return data;
}

function stringToDOM(aString) {
  var parser = new DOMParser();
  var dom = parser.parseFromString(aString, "text/xml");
  if (dom.documentElement.nodeName == "parsererror") {
    return null;
  } else {
    return dom;
  }
}

function getCBOverlay() {
  var dirsvc = Cc["@mozilla.org/file/directory_service;1"].
               getService(Ci.nsIProperties);
  var file = dirsvc.get("ProfD", Ci.nsIFile);
  file.append("custombuttons");
  file.append("backup");
  file.append("buttonsoverlay.xul.bak");
  return file;
}
this.viewCBOverlay = function viewCBOverlay() {
  var fileURL = Cc["@mozilla.org/network/io-service;1"].
                getService(Ci.nsIIOService).getProtocolHandler("file").
                QueryInterface(Ci.nsIFileProtocolHandler).
                getURLSpecFromFile(getCBOverlay());
  gBrowser.selectedTab = gBrowser.addTab("view-source:" + fileURL);
}

function importXMLtoButton(aStrXMLData) { loadURI("custombutton://" + escape(aStrXMLData));  }

this.importFromCBOverlay = function importFromCBOverlay(aTitle) {
  var id = custombuttons.promptBox(aTitle, "Введитете номер id кнопки:");
  if (!id[1] || id[1] == "") return;
  id = "custombuttons-button" + id[1];
  var dom = stringToDOM(readFile(getCBOverlay()));
  var button = dom.getElementById(id);
  if (!button) {
    custombuttons.alertBox(aTitle, "Копка Id " + id + " не найдена!");
    return;
  }
  var cbName = button.getAttribute("cb-name") ||
               button.getAttribute("label");
  var cbImage = button.getAttribute("image") ||
                button.getAttribute("cb-stdicon") || "";
  var cbMode = button.getAttribute("mode") || "";
  var cbInitCode = button.getAttribute("cb-init");
  var cbCode = button.getAttribute("cb-oncommand");
  var cbKey = button.getAttribute("accelkey") || "";
  var cbHelp = button.getAttribute("Help") || "";
  var cbAttr = button.getAttribute("attributes");
  
  var cbXML = '<custombutton xmlns:cb="' + e4xConv_encodeHTML(cbNamespace, true) + '">\n\
                <name>' + e4xConv_encodeHTML(cbName) + '</name>\n\
                <image>' + e4xConv_encodeHTML(cbImage) + '</image>\n\
                <mode>' + e4xConv_encodeHTML(cbMode) + '</mode>\n\
                <initcode>' + e4xConv_encodeHTML(cbInitCode) + '</initcode>\n\
                <code>' + e4xConv_encodeHTML(cbCode) + '</code>\n\
                <accelkey>' + e4xConv_encodeHTML(cbKey) + '</accelkey>\n\
                <help>' + e4xConv_encodeHTML(cbHelp) + '</help>\n\
                <attributes>' + e4xConv_encodeHTML(cbAttr) + '</attributes>\n\
              </custombutton>';
  var xml = "<?xml version='1.0' encoding='UTF-8'?>" + cbXML.toString(); 
  importXMLtoButton(xml);
  
}

function e4xConv_encodeHTML(s, isAttr) {
    s = String(s)
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;");
    if(isAttr) {
        s = s
            .replace(/\t/g, "&#x9;")
            .replace(/\n/g, "&#xA;")
            .replace(/\r/g, "&#xD;");
    }
    return s;
}


3 кнопка - не реагируют кнопки внутри окна, а также на горячие клавиши
скрытый текст

Выделить код

Код:

/*Initialization Code*/
gCBClipboardViewer = this; // global obj
var dataURL = "data:application/vnd.mozilla.xul+xml," + encodeURIComponent(self.Help);

((g, name, id) => {
    var obj = g[name] || (g[name] = ({
        topic: "quit-application-granted",
        init() {
            this.url = `chrome://custombuttons/content/${name}.xul`;
            this.helper = Cc["@mozilla.org/addons/addon-manager-startup;1"]
                .getService(Ci.amIAddonManagerStartup).registerChrome(
                    Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)),
                    [["override", this.url, dataURL]]
                );
            (this.obs = Services.obs).addObserver(this, this.topic, false);
            return this;
        },
        observe() {
            delete g[name];
            this.obs.removeObserver(this, this.topic);
            this.helper.destruct();
        }
    }).init());

 var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
                   .getService(Components.interfaces.nsIWindowWatcher);
 var em = ww.getWindowEnumerator();
 var winName = "clipview";
 var index = 1;
 while (em.hasMoreElements()) {
  let win = em.getNext();
  if(win.name == winName) {
    win.focus();
    return;
  }
  index++
 }

    this.onclick = e => {
       if (e.button == 0 && e.ctrlKey) return this.togglePanel();     // открыть в bottom panel
       if (e.button == 0  ) return openDialog(dataURL, winName, "chrome, dialog=no, centerscreen, minimizable, resizable");
       if (e.button == 1 && e.ctrlKey)  return gBrowser.selectedTab = gBrowser.addTrustedTab(obj.url); 
       if (e.button == 1) SidebarUI.toggle(id);
          } 

    addDestructor(reason => reason[5] == "e" && name in g && g[name].observe());
    for(var tab of gBrowser.tabs) {
        if (!tab.linkedPanel || tab.closing) continue;
        var br = tab.linkedBrowser;
        !br.isRemoteBrowser && br.currentURI.spec == obj.url &&
        br.contentDocument.documentURI.startsWith("about:neterror?e=fileNotFound") && br.reload();
    }
    
function $(aId) {
  return document.getElementById(aId);
}

this.togglePanel = function() {
  this.panel = !this.panel;
  $("SClipboard-splitter").hidden = !this.panel;
  $("SClipboard-panel").hidden = !this.panel;
  $("SClipboard-iframe").setAttribute("src", this.panel ? dataURL : "");
}

this.checkForCBWindow = function() {
  var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
                     .getService(Components.interfaces.nsIWindowWatcher);
  var em = ww.getWindowEnumerator();
  var winName = "clipview";
  var index = 1;
  while (em.hasMoreElements()) {
    let win = em.getNext();
    if(win.name == winName) {
      win.focus();
      return true;
    }
    index++
  }
  return false;
}

function makeXML(aXMLString) {
  return (new DOMParser).parseFromString(aXMLString, "application/xml")
                        .documentElement;
}

function $xml(aNode, aId, aXML) {
  var node = $(aId);
  node && node.parentNode.removeChild(node);
  aNode && aNode.appendChild(makeXML(aXML))
}

$xml($("appcontent"),
     "SClipboard-splitter",
     '<splitter xmlns="' + xulns + '" id="SClipboard-splitter"'
   + ' orient="vertical" hidden="true">'
   + '<grippy oncommand="this.parentNode.nextSibling.collapsed ='
   + ' !this.parentNode.nextSibling.collapsed;"/></splitter>');

$xml($("appcontent"),
     "SClipboard-panel",
     '<vbox xmlns="' + xulns + '" id="SClipboard-panel"'
   + ' height="300" hidden="true">'
   + '<toolbox><toolbar align="center">'
   + '<label value="' + this.label + '" flex="1" crop="end"/>'
   + '<toolbarbutton class="tabs-closebutton"'
   + ' image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACt0lEQVQ4jaWSzUtUYRTGn/fcGZ25H+m9Iyne8fpFq4lGCsFFIW21NiKKuHIn4qpazDraabnMTVEh+Af0B0QIIohBowhlkM1MMTre+VLngzv3PW1SKWvVWR0eOL/zcM4jmBn/U4G/iTuzsyK7unoLUl4HABDtdExNbV1fXr60Tfzp4J1h3Dd1/ak1OHhN7+kBiHCaTsPd2NgrlMsP7x4fv/0nYE3XH9ix2GLbzIwQmvYbmCsVHL16xd+3tx/dOTl5dqbTWfPeMIavOs6COT0tmBmyWAS1toJaWyGLRbCUMKemxFXHWXhvGMOXACrw2BwdJYUITX190MbG4O/twf/yBdrYGJr6+6EQwbx3j1QhHv8GWDfNNjUavR3u6ACyWQRjMQRsG+rkJNSJCQRsG8FYDDKbRbi9Harj3F43zbYLB41Gr2bbRIUCFACnS0vwMhkEbBsB24aXyaCcSEDJZiFyOWidnYRGo/f8jQpQp9NTiFwOACCJACEuDsgMeXAAuC7YMECeBwWonwOaLOtT/evXMhTlSs00oS8vI2jbqGcyADOau7pgvHiB8vg4tMND1F233GRZn87pzIwtXX9eiEb5uLubC2/ecC2V4qOhIT4aGuJqKsX516/52HG4EI3ylq4/P5s7z8FHy2qXnvehOxTqDBGhFongiusCAMqWhVA+j5qU+Far/RDB4M2BfP7gUpCSLS03qr7/NiyEExEC6i+9AsBlRpU5FVaU+zdKpeSlHCSTSazOzW0XNW2gCjzZ9/3Pu77Pu77P+77/uQo8cTVt4OXMzM7a2tpFlBOJhFhZWWkulUphz/NUKWWYmUPM3GwCKgBRAKoA6kRUI6JKIBCo6rpeGRkZqQlmRjqdxuLiIm1ublIul6NKpaI0Gg3yfV8AABFxMBiUoVBIRiIRPx6Py/n5eRmPx/ETBvM/dPD/rBwAAAAASUVORK5CYII="'
   + ' oncommand="gCBClipboardViewer.togglePanel();"/>'
   + '</toolbar></toolbox>'
   + '<iframe id="SClipboard-iframe" src="" flex="1"/>'
   + '</vbox>');
   
    var label = "Clipboard Viewer";
    var url = "chrome://browser/content/webext-panels.xul?" + id;
    var icon  ="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAArdJREFUeNpsU11IU2EYfs/Zt+Vy7sfKEZEp2pxmF2uKUVhq2VKwTB0FmT8FCUbgpTddBWFBICJRgVleRC5GUeRNpPZj+bfMrJZhajeWRTPa2mTnr/c77Iyj9cLD2fd97/PsOc/7HQawytMQW0AuhoF49a+rzmQYZp+yliTpSclP74yybh6QgHTuhdV1DeGkP6zPvNAyNONUDtp3Z/pgW7zPh2hiRQlADUEE5373SafVnu888eCtUxBYMBiMQJ90TffpOe2jKoQX/nEAtuYumOjthZHRp2A0GsGQmAgcx0EwGIQNpa1gq6qCR7dvyL1E+I9AKBKBEpcLvi0sANFoQMOywCJopaWno1MJFB6J8iu4DA3x+9ISrDebIctmkzcpQRRFWYRHJouinCLA8Wo2FG+0O/TJJhPf4/WOdns8U5i8VFdTk9vgdheggpbFJoLgYzyCYajrWPHZtk2evr6Rx2P+F1cvX8+gmxeudL7UaO+LtZWVeyLoQK9ywFIHKmRt3r7T8LC/f+xIZUPq5x98AkXt0VMZjwYHx3FIEF5eBh5fR3G+OgOgTSaLhUvS60hOqnkN3fsaCILRYokKSPyDAScmJYHCW+1gen5iOOQuK8t///GVP4FI4lotML6pockql2tHMByGZRyngKHGHYTCqIIT0hI5xPEv/g+HDzSeKdTqXgudd3ue0xALHY5d+dnZJfM41hSrFTSEwK9gTIDePpaRBSoKqutbXadbUu51tC+mZufkna+rK6JN/pHh0MXy0k+zkxMR5VXxT32ygDxnERodh+rPHb90M72rpWGur/tWW+A35OFRVqx/GnFHw8IAQooTaeXqAWpMME6tdjTVzxYZoMKuwxsHK2FWBZ2MjrcS+esE8g5D1fHgPahjYBHA84aDOeyxI6IILvaMqtZ8AC9mIBbiXwEGADy0Lb/f2n5rAAAAAElFTkSuQmCC";
    var defaultURL = obj.url; 
 
    var e = (name, attrs, node, append) => {
        var elm = document.createElement(name);
        for(var a in attrs) elm.setAttribute(a, attrs[a]);
        append ? node.append(elm) : node.before(elm);
        return elm;
    }
    var menuitem = e("menuitem", {
        label,
        type: "checkbox",
        id: "menu_CBClipboardLoader",
        oncommand: `SidebarUI.toggle("${id}");`,
    }, document.getElementById("viewSidebarMenu"), true);

    var btn = e("toolbarbutton", {
        label,
        type: "checkbox",
        oncommand: "handleCommand();",
        id: "sidebar-switcher-CBClipboardLoader",
        class: "subviewbutton subviewbutton-iconic"
    }, document.querySelector('toolbarbutton[id^="sidebar-switcher-"] + toolbarseparator'));

    SidebarUI.sidebars.set(id, {
        url,
        title: label,
        buttonId: btn.id,
        menuId: menuitem.id,
    });
    var css = `\
        #${btn.id} > .toolbarbutton-icon,
        #sidebar-box[sidebarcommand="${id}"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon {
            width: 16px;
            height: 16px;
            opacity: 0.8;
            fill: currentColor;
            -moz-context-properties: fill;
            list-style-image: url(${icon});
        }`;
    var str = "data:text/css," + encodeURIComponent(css), type = windowUtils.USER_SHEET;
    windowUtils.loadSheetUsingURIString(str, type);

    addDestructor(() => {
        btn.remove(); menuitem.remove();
        SidebarUI.sidebars.delete(id);
        windowUtils.removeSheetUsingURIString(str, type);
    });
    var isActive = () => SidebarUI.isOpen && SidebarUI.currentID == id;

    if (isActive()) {
        SidebarUI.selectMenuItem(id);
        var doc = SidebarUI.browser.contentDocument;
        if (doc.readyState != "complete") return;
        var br = doc.getElementById("webext-panels-browser");
        if (br) defaultURL = br.currentURI.spec;
    }
    btn.handleCommand = () => {
        if (!btn.hasAttribute("checked")) {
            SidebarUI._switcherPanel.hidePopup();
            btn.setAttribute("checked", true);
        }
        loadURL(gBrowser.currentURI.spec);
    }

gBrowser.tabContainer.addEventListener("TabAttrModified", function(event) {
         if ( gBrowser.currentURI.spec == defaultURL) gURLBar.value = "";
}, true);
    
    addEventListener("load", e =>
        e.target.documentURI == url && load(defaultURL)
    , true, SidebarUI.browser);
    
    var loadURL = url => {
        defaultURL = defaultURL;
        isActive() ? load(url) : SidebarUI.show(id);    
    }
    var principal = {triggeringPrincipal: document.nodePrincipal};
    var config = {browserStyle: false, extension: {remote: false}};
    var load = async url => {
        var win = SidebarUI.browser.contentWindow;
        var br = win.document.getElementById("webext-panels-browser");
        if (br) {
            if (br.currentURI.spec === url) return;
            br.parentNode.remove();
        }
        var br = await win.getBrowser(config);
        win.onunload = () => defaultURL = br.currentURI.spec;
        br.loadURI(url, principal);
    }
 
})(Cu.import("resource://gre/modules/Services.jsm", {}), "some-unique-name", "viewCBClipboardLoader");

this.info = "\n\
ЛКМ: открыть в окне\n\n\
СКМ: открыть в Sidebar\n\n\
Ctrl+СКМ: открыть в новой вкладке\n\n\
Ctrl+ЛКМ: открыть в нижней панели\n\n";

this.showTooltip = function(aNode) {
  var win = this.checkForCBWindow();
  if (win || this.opened) {
    aNode.label = this.info;
    return;
  }
  aNode.label = readFromClipboard() ? readFromClipboard() : this.info;
}
var tooltip = this.appendChild(document.createElement("tooltip"));
tooltip.style.MozAppearance = "none";
tooltip.style.background = "menu";
tooltip.style.color = "menutext";
tooltip.style.opacity = ".9";
tooltip.style.border = "1px solid menutext";
tooltip.style.borderRadius = "5px";
tooltip.style.MozBorderRadius = "5px";
tooltip.style.fontFamily = "monospace";
tooltip.style.fontSize = "medium";
tooltip.style.maxWidth = (screen.width / 2) + "px";
tooltip.style.maxHeight = (screen.height / 2) + "px"; // not working
tooltip.style.padding = "1em";
tooltip.setAttribute("onpopupshowing", "this.parentNode.showTooltip(this);");

this.removeAttribute("tooltiptext");
this.tooltip = "_child";


вкладка справка для этой же кнопки
скрытый текст

Выделить код

Код:

<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="chrome://global/skin/"?>
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
        xmlns:html="http://www.w3.org/1999/xhtml"
        id="clipboard-viewer"
        width="800" height="600"
        title="Clipboard viewer"
        buttons="extra1, extra2, cancel"
        buttonlabelextra1="Правка"
        buttonlabelextra2="Очистить"
        buttonlabelcancel="Закрыть"
        buttonaccesskeyextra1="E"
        buttonaccesskeyextra2="r"
        buttonaccesskeycancel="C"
        ondialogextra1="edit();"
        ondialogextra2="clearClipboard();"
        ondialogcancel="closeDialog();"
        onfocus="loadFromClipboard();">

  <html:head>
     <html:style type="text/css">
    <![CDATA[#textbox {
      font-family: monospace; font-size: medium; white-space: pre-wrap;   
    }]]>
    </html:style>
  </html:head>

  <keyset><key keycode="VK_F5" oncommand="loadFromClipboard();" /></keyset>

  <popupset>
    <menupopup id="contextmenu"
               onpopupshowing="popupShowing(event);"
               onpopuphiding="loadFromClipboard();"
               oncommand="var cmd = event.originalTarget.getAttribute('cmd');
 if (cmd) document.popupNode.parentNode.doCommand(cmd);">
      <menuitem id="edit-copy" label="Копировать" accesskey="c" cmd="cmd_copy" />
      <!--menuitem id="edit-delete" label="Удалить" accesskey="d" cmd="cmd_delete" /-->
      <menuseparator />
      <menuitem id="edit-selectAll" label="Выбрать все" accesskey="a" cmd="cmd_selectAll" />
    </menupopup>
  </popupset>

  <html:textarea  id="textbox" onclick="gmon_edit_mouseclick(event);"  context="contextmenu" readonly="" style="height: 600pt; "/>


  <script type="application/x-javascript"><![CDATA[
const Cc = Components.classes;
const Ci = Components.interfaces;

const gTextbox = document.getElementById("textbox");

function getMainwin() {
  if (window.frameElement) {
    return window.frameElement.ownerDocument.defaultView;
  } else if (window.opener) {
    return window.opener;
  } else {
    return Cc["@mozilla.org/appshell/window-mediator;1"].
           getService().QueryInterface(Ci.nsIWindowMediator).
           getMostRecentWindow("navigator:browser")
  }
}

function readFromClipboard() {
  var string;
  try {
      var clipboard = Cc["@mozilla.org/widget/clipboard;1"].
                      getService(Ci.nsIClipboard);
      var trans = Cc["@mozilla.org/widget/transferable;1"].
                  createInstance(Ci.nsITransferable);
      trans.addDataFlavor("text/unicode");
      if (clipboard.supportsSelectionClipboard()) {
        clipboard.getData(trans, clipboard.kSelectionClipboard);
      } else {
        clipboard.getData(trans, clipboard.kGlobalClipboard);
      }
      var data = {};
      var dataLen = {};
      trans.getTransferData("text/unicode", data, dataLen);
      if (data) {
        data = data.value.QueryInterface(Ci.nsISupportsString);
        string = trans.getTransferData.length == 2
          ? data.data : data.data.substring(0, dataLen.value / 2);
      }
  } catch (ex) {
  }
  return string;
}

function loadFromClipboard() {
  var string = readFromClipboard();
  if (gTextbox.value != string) {
    if (!string) {
      gTextbox.value = "";
    } else {
      gTextbox.value = string;
    }
  }
  gTextbox.selectionStart = 0;
  gTextbox.selectionEnd = 0;
}

function copyToClipboard(aString) {
  let clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].
                        getService(Ci.nsIClipboardHelper);
  clipboardHelper.copyString(aString);
}

function clearClipboard() {
  copyToClipboard("");
  gTextbox.value = "";
}

function edit() {
  edittarget(gTextbox);
}

function closeDialog() {
  getMainwin().gCBClipboardViewer.opened = false;
  if (window.frameElement) {
    switch (window.frameElement.id) {
    case "sidebar":
      getMainwin().gCBClipboardViewer.toggleSidebar();
      break;
    default:
      getMainwin().gCBClipboardViewer.togglePanel();
    }
  } else {
    window.close();
  }
}

function popupShowing(aEvent) {
  var children = aEvent.target.childNodes;
  for (var i = 0; i < children.length; i++) {
    var command = children[i].getAttribute("cmd");
    if (command) {
      var controller = document.commandDispatcher
                               .getControllerForCommand(command);
      var enabled = controller.isCommandEnabled(command);
      if (enabled) {
        children[i].removeAttribute("disabled");
      } else {
        children[i].setAttribute("disabled", "true");
      }
    }
  }
}

var _tmpdir=null,_dir_separator,_os;
var _ext,_encode,_target=[];

function editinit() {
  if (window.navigator.platform.toLowerCase().indexOf("win") != -1) {
    _dir_separator = "\\";
    _os = "win";
  } else {
    _dir_separator = "/";
    _os = "unix";
  }
  _ext = "txt";
  _encode = "UTF-8";
  _target = [];

  window.addEventListener("unload", edituninit, false);
  window.addEventListener("unload", function() {
    document.removeEventListener("focus", checkfocus_window, true);
  }, false);
}

function getEditor() {
  let pref = Cc["@mozilla.org/preferences-service;1"].
             getService(Ci.nsIPrefService).
             getBranch("custombuttons.ClipboardViewer.");
  let editor = null;
  try {
    editor = pref.getCharPref("external_editor");
  } catch(ex) {
    let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
                  getService(Ci.nsIPromptService);

    let ask = prompts.confirm(null, "Clipboard Viewer",
                              "Вы должны сначала выбрать текстовый редактор.\nНажмите OK для продолжения.");
    if (!ask) return false;

    let nsIFilePicker = Ci.nsIFilePicker;
    let filePicker = Cc["@mozilla.org/filepicker;1"].
                     createInstance(nsIFilePicker);
    filePicker.init(window, "Select editor", nsIFilePicker.modeOpen);
    filePicker.appendFilters(nsIFilePicker.filterApplication);
    filePicker.appendFilters(nsIFilePicker.filterAll);
    filePicker.open(res => {
                   if (res == nsIFilePicker.returnOK) 
      if (filePicker.file.exists() && filePicker.file.isExecutable()) {
        pref.setCharPref("external_editor", filePicker.file.path);
        editor = filePicker.file.path;
      }
      });
    }
  return editor;
}

function edituninit() {
  if (_tmpdir == null) return;
  var windowType = "navigator:browser";
  var windowManager = Cc["@mozilla.org/appshell/window-mediator;1"].
                      getService();
  var windowManagerInterface = windowManager.
                               QueryInterface(Ci.nsIWindowMediator);
  var enumerator = windowManagerInterface.getEnumerator(windowType);
  if (enumerator.hasMoreElements()) {
    return;
  }

  var file = Cc["@mozilla.org/file/local;1"].
             createInstance(Ci.nsIFile);
  file.initWithPath(_tmpdir);
  var entries = file.directoryEntries;
  while (entries.hasMoreElements()) {
    var entry = entries.getNext().QueryInterface(Ci.nsIFile);
    if (/^custombuttons\./i.test(entry.leafName)) {
      try {
        entry.remove(false);
      } catch(e) {
      }
    }
  }

  try {
    if (file.exists() == true ) {
      file.remove(false);
    }
  } catch(e) {
  }

  _tmpdir = null;
}

function gmon_edit_mouseclick(e) {
  if (e.button != 1) return;
  var target = e.target;
  edittarget(target);
}

function checkfocus_window() {
  var target, filename, timestamp, encode,
      file, inst, sstream, utf, textBoxText;

  if (_target.length<=0) return;

  file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
  istr = Cc["@mozilla.org/network/file-input-stream;1"].
         createInstance(Ci.nsIFileInputStream);

  sstream = Cc["@mozilla.org/scriptableinputstream;1"].
            createInstance(Ci.nsIScriptableInputStream);
  utf = Cc["@mozilla.org/intl/utf8converterservice;1"].
        createInstance(Ci.nsIUTF8ConverterService);

  for (var i=0; i < _target.length;i++) {
    target = _target[i];
    if (!target.hasAttribute("filename")) continue;
    filename = target.getAttribute("filename");
    timestamp = target.getAttribute("timestamp");
    file.initWithPath(filename);
    if (!file.exists() || !file.isReadable()) continue;
    if (file.lastModifiedTime <= timestamp) continue;

    target.setAttribute("timestamp", file.lastModifiedTime);

    istr.init(file, 1, 0x400, false);
    sstream.init(istr);

    textBoxText  = sstream.read(sstream.available());
    encode = target.getAttribute("encode");
    if (textBoxText.length) {
      copyToClipboard(utf.convertStringToUTF8(textBoxText, encode, true, false));
      target.value = utf.convertStringToUTF8(textBoxText, encode, true, false);
    } else {
      clearClipboard();
      target.value = "";
    }
    sstream.close();
    istr.close();
    try {
      file.remove(false);
    } catch(e) {
    }
  }
}

function editfile(target,filename) {
 //  var editor = getEditor();
 var editor = "C:\\AkelPad\\AkelPad.exe";
  if (!editor) return false;

  var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
  file.initWithPath(editor);
  if (!file.exists()) {
    alert("Error_invalid_Editor_file");
    return false;
  }
  if (!file.isExecutable()) {
    alert("Error_Editor_not_executable");
    return false;
  }
  target.setAttribute("filename", filename);
  target.setAttribute("timestamp", file.lastModifiedTime);

  var process = Cc["@mozilla.org/process/util;1"].
                createInstance(Ci.nsIProcess);
  process.init(file);
  var args = [filename];
  process.run(false, args, args.length);  // don't block
  document.addEventListener("focus", checkfocus_window, true);
  return true;
}

function edittarget(target) {
  var textBoxText = target.value;
  var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
  if (target.hasAttribute("filename")) {
    var filename = target.getAttribute("filename");
    file.initWithPath(filename);
    try {
      if(file.exists()) file.remove(false);
    } catch(e) {
    }
  } else {
    var filename = TmpFilenameTextarea();
  }
  file.initWithPath(filename);    
  file.create(file.NORMAL_FILE_TYPE, 0x180);
  var ostr = Cc["@mozilla.org/network/file-output-stream;1"].
             createInstance(Ci.nsIFileOutputStream);
  ostr.init(file, 2, 0x200, false);

  if(navigator.platform == "Win32") {
    textBoxText = textBoxText.replace(/\n/g, "\r\n");
  }
  var conv = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  try {
        conv.charset = 'utf-8';
    textBoxText = conv.ConvertFromUnicode(textBoxText);
    
  } catch(e) {
    textBoxText = "";
  }
  ostr.write(textBoxText, textBoxText.length);

  ostr.flush();
  ostr.close();
  target.setAttribute("encode", _encode);
  if (editfile(target,file.path)) {
    _target.push(target);  // Editting target array
  }
}

function TmpFilenameTextarea() {
  var TmpFilename;
  _tmpdir = gettmpDir();
  do {
    TmpFilename = _tmpdir + _dir_separator + "clipboard." +
                  Math.floor(Math.random() * 100000) + "." + _ext;
  } while (!ExistsFile(TmpFilename))
    return TmpFilename;
}

function ExistsFile(filename) {
  try {
    var file = Cc["@mozilla.org/file/local;1"].
               createInstance(Ci.nsIFile);
    file.initWithPath(filename);
    return true;
  } catch(e) {
    return false;
  }
}

function gettmpDir() {
  var fobj = Cc["@mozilla.org/file/directory_service;1"].
             getService(Ci.nsIProperties).get("TmpD", Ci.nsIFile);
  fobj.append("Clipboard_Viewer");
  if (!fobj.exists()) {
    fobj.create(Ci.nsIFile.DIRECTORY_TYPE, parseInt("0700", 8));
  }
  if (!fobj.isDirectory()) {
    alert("Having a problem finding or creating directory: "+ fobj.path);
  }
  return fobj.path;
}

function onLoad() {
  getMainwin().gCBClipboardViewer.opened = true;
  editinit();
}

window.addEventListener("load", onLoad, false);
window.removeEventListener("unload", onLoad, false);

  ]]></script>

</dialog>

Отредактировано Andrey_Krropotkin (06-07-2019 19:24:53)

Отсутствует

 

№1345706-07-2019 23:31:01

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

Re: Custom Buttons

Andrey_Krropotkin пишет

подскажи, может знаешь в чем причина. На 69b1 в кнопках, которые выводят диалоговые окна, перестали выделятся пункты внутри окна

Причина всё та же, De-XBL и browser.xhtml
Если нет какого-то сугубого резона, то пусть лучше
элементы создаются тем документом, в который затем будут добавлены.

скрытый текст
Чтобы проверить будут ли выделяться пункты, добавь по одной строке

1 кнопка
В функции this.load перед for(var addon of list) вот так:

Выделить код

Код:

var {document} = dialog;
  for(var addon of list){

2 кнопка
(Преподготовка: выброси мусорную скобку } из this.copyBBCode, её сразу видно.)
В функции createItem первой строкой вот так:

Выделить код

Код:

function createItem(button) {
   var document = {createElement: (dialog.document.createXULElement || dialog.document.createElement).bind(dialog.document)};

Затем, если работает, можешь переписать
соответствующие функции более осмысленно.

Andrey_Krropotkin пишет

3 кнопка - не реагируют кнопки внутри окна, а также на горячие клавиши

Это Bug 1498566 - Remove new Function from dialog.xml
Атрибуты ondialog{bla-bla} больше не исполняются, предлагается использовать листенеры.

скрытый текст
Можно на вкладке Справка, для элемента <dialog>, удалить или переименовать
атрибуты ondialogextra1, ondialogextra2 и ondialogcancel

и в элемент <script> дописать что-то типа

Выделить код

Код:

var dialogEvents = Object.entries({dialogextra1: edit, dialogextra2: clearClipboard, dialogcancel: closeDialog});
for(let args of dialogEvents) document.addEventListener(...args);
addEventListener("unload", () => dialogEvents.forEach(args => document.removeEventListener(...args)), {once: true});

Удаление листенеров, наверно, не столь обязательно,
сами они нынче лепят без удаления.

Отсутствует

 

№1345807-07-2019 00:15:26

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

Re: Custom Buttons

Dumby спасибо, по первой кнопке без проблем, во второй кнопке Ваш вариант не прошел, но прошел вариант из первой кнопки, в третьей без проблем (удалил и дописал скрипт).
И еше вопрос по третьей кнопке, как Вы видите я из нее сделал такую солянку из всех ваших кодов, чтобы она открывалась везде. Самое интересное, что это пока работает, но как то интересно. Если в окне - то все нормально, если  первый раз открываю допустим сайдбар, то пока не щелкну по текстовому полю, текст не не появляется. Если второй раз открываю, то уже все нормально. Перезагружаю браузер, тоже все нормально. То же самое с tooltip. Пока в первый раз не открою окно, tooltip не появляется. Видать наверно я не правильно объединил функции для сайдбара и xml из вкладки "Справка", где-то какая то мелочь мешает. Но это не критично.
И еще один интересный момент про нижнюю панель (этот код, что в кнопке 3) у меня он везде работает и на других кнопках в 69b1 за исключением одной кнопки - почему-то браузер после применения кнопки вылетает. 

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

Выделить код

Код:

/*Initialization Code*/
(function () {
    gCBNote = this; // global obj
    var label = "Сайт";
    var icon  ="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAABKUlEQVQ4T6WS24qDMBRF/f9fHCi1ijHkQi7kRqJ7jpYZYSxMi8J6CezlyT7p6MNFXh5+wsvDT+hQ2opcn6TyJG7kJ4HwcYXxDcoWCJXhXD4E67r+y7IsKKUipYwQElpO7wtaW5BzRYwF3idYG5FCfE9w/PknHKC1R3D+EEi6j3LlhLQZs04YRcBjdrhPFrdB46tXuI/qEFykg0vUbqi/SF8hqG1utgkyJhUxyogHD+hnjzvz0MoegtPdqbRaGhKVFjytzG4BB8EtZqYx0fh8kmfBsqyote2Nh1CosARjAqR04BSeJoNhUOh7iWkQZ0Gtx7q2h2JMhFJ+DzO2hfUevt0Ehp7/FSxEo/ELVnokNSYkWlWwDk4ZaKEhGY0+crCBQ7H5EFwCuAK6b7kpsLGbUcTpAAAAAElFTkSuQmCC";
    var defaultURL = gBrowser.currentURI.spec;
 
    function $(aId) {
  return document.getElementById(aId);
}

this.togglePanel = function() {
  this.panel = !this.panel;
  $("SNote-splitter").hidden = !this.panel;
  $("SNote-panel").hidden = !this.panel;
  $("SNote-iframe").setAttribute("src", gBrowser.currentURI.spec);
}
 
function makeXML(aXMLString) {
  return (new DOMParser).parseFromString(aXMLString, "application/xml")
                        .documentElement;
}

function $xml(aNode, aId, aXML) {
  var node = $(aId);
  
 node && node.parentNode.removeChild(node);
 aNode && aNode.appendChild(makeXML(aXML))
 
}

$xml($("appcontent"),
     "SNote-splitter",
     '<splitter xmlns="' + xulns + '" id="SNote-splitter"'
   + ' orient="vertical" hidden="true">'
   + '<grippy oncommand="this.parentNode.nextSibling.collapsed ='
   + ' !this.parentNode.nextSibling.collapsed;"/></splitter>');

$xml($("appcontent"),
     "SNote-panel",
     '<vbox xmlns="' + xulns + '" id="SNote-panel"'
   + ' height="300" hidden="true">'
   + '<toolbox><toolbar align="center">'
   + '<label value=" " flex="1" crop="end"/>'
   + '<toolbarbutton class="tabs-closebutton"'
   + ' image="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACt0lEQVQ4jaWSzUtUYRTGn/fcGZ25H+m9Iyne8fpFq4lGCsFFIW21NiKKuHIn4qpazDraabnMTVEh+Af0B0QIIohBowhlkM1MMTre+VLngzv3PW1SKWvVWR0eOL/zcM4jmBn/U4G/iTuzsyK7unoLUl4HABDtdExNbV1fXr60Tfzp4J1h3Dd1/ak1OHhN7+kBiHCaTsPd2NgrlMsP7x4fv/0nYE3XH9ix2GLbzIwQmvYbmCsVHL16xd+3tx/dOTl5dqbTWfPeMIavOs6COT0tmBmyWAS1toJaWyGLRbCUMKemxFXHWXhvGMOXACrw2BwdJYUITX190MbG4O/twf/yBdrYGJr6+6EQwbx3j1QhHv8GWDfNNjUavR3u6ACyWQRjMQRsG+rkJNSJCQRsG8FYDDKbRbi9Harj3F43zbYLB41Gr2bbRIUCFACnS0vwMhkEbBsB24aXyaCcSEDJZiFyOWidnYRGo/f8jQpQp9NTiFwOACCJACEuDsgMeXAAuC7YMECeBwWonwOaLOtT/evXMhTlSs00oS8vI2jbqGcyADOau7pgvHiB8vg4tMND1F233GRZn87pzIwtXX9eiEb5uLubC2/ecC2V4qOhIT4aGuJqKsX516/52HG4EI3ylq4/P5s7z8FHy2qXnvehOxTqDBGhFongiusCAMqWhVA+j5qU+Far/RDB4M2BfP7gUpCSLS03qr7/NiyEExEC6i+9AsBlRpU5FVaU+zdKpeSlHCSTSazOzW0XNW2gCjzZ9/3Pu77Pu77P+77/uQo8cTVt4OXMzM7a2tpFlBOJhFhZWWkulUphz/NUKWWYmUPM3GwCKgBRAKoA6kRUI6JKIBCo6rpeGRkZqQlmRjqdxuLiIm1ublIul6NKpaI0Gg3yfV8AABFxMBiUoVBIRiIRPx6Py/n5eRmPx/ETBvM/dPD/rBwAAAAASUVORK5CYII="'   
   + ' oncommand="gCBNote.togglePanel();"/>'
   + '</toolbar></toolbox>'
   + '<iframe id="SNote-iframe" src="" flex="1"/>'
   + '</vbox>');

    this.onclick = e => {
        if (e.button == 0) return this.togglePanel();     // открыть в bottom panel
     }
    
   if ( document.getElementById("TabSNote") ) return;
 
   var tabContext = document.getElementById("tabContextMenu");
   var menuItem = document.createXULElement("menuitem");                 
   menuItem.setAttribute("id", "TabSNote");
   menuItem.setAttribute("label", "Открыть в нижней панели");
   menuItem.setAttribute("class", "menuitem-iconic");
   menuItem.setAttribute("image", icon);
   menuItem.setAttribute("oncommand", "gCBNote.togglePanel();" );
   tabContext.insertBefore( menuItem, tabContext.firstChild.nextSibling ); // как первый пункт 
   
})();

Отсутствует

 

№1345907-07-2019 08:31:44

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

Re: Custom Buttons

Andrey_Krropotkin пишет

пока не щелкну по текстовому полю, текст не не появляется

Ну, как-бы напрашивается в function onLoad()
попробовать добавить gTextbox.focus();

Andrey_Krropotkin пишет

в 69b1 за исключением одной кнопки - почему-то браузер после применения кнопки вылетает

Mozilla Crash Reporter пишет

MozCrashReason: MOZ_RELEASE_ASSERT(false) (SystemPrincipal must not load remote documents.)

Видимо bug 1552477. Может и правильно, каким-то там сайтам
в привилегированном XUL <iframe>'е делать нечего.

И ещё, вот как можно код с this.onclick завернуть в (function () {…})();
Это всё равно что написать window.onclick, не слишком остроумно.

Отсутствует

 

№1346007-07-2019 11:31:16

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

Re: Custom Buttons

Dumby спасибо, исправил в onLoad(), в принципе ответ лежал на поверхности. Про bug 1552477, вроде пишут только в ночнушках и бетах, завернул this.onclick - не помогло. На 67 то работает. А в принципе эта кнопка и ненужна. Есть другой вариант - разделения на два окна. Просто когда делал для себя кнопку для вкладок открыть в боковой панели, паровозом и эту кнопку сделал. Еще раз спасибо.
А DOM Inspector У Вас есть для 69b1?

Отсутствует

 

№1346107-07-2019 13:08:31

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

Re: Custom Buttons

Dumby
Еще раз по поводу кнопки Перевод

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

Выделить код

Код:

/*Initialization Code*/

var btn = this;

btn.lastClick = {
    X: 0,
    Y: 0
};
addEventListener("mouseup", function(e) {
    if (e && e.button == 0 && e.view.top == content) {
        var lc = btn.lastClick;
        lc.X = e.clientX;
        lc.Y = e.clientY;
    }
}, false);

var createWindow = function(text, status, title, id, pos, size){
    var win = document.commandDispatcher.focusedWindow.top == content ? document.commandDispatcher.focusedWindow : content;
    var doc = win.document, wId = 'ujs_window'+(id || ''), w = doc.getElementById(wId);
    var keyDown = function(e){if(!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode == 27)doc.getElementById(wId).closeWin()};
    if(w)w.closeWin();
    w = doc.createElementNS(xulns,'div');
    w.setAttribute('style', 'position:fixed;display:block;visibility:hidden;left:0;top:0;width:auto;height:auto;border:1px solid gray;padding:3px;margin:0;z-index:99999;overflow:hidden;cursor:move;'+(typeof w.style.borderRadius === 'string' ? 'background-color:#f3f5f7;padding-top:4px;border-radius:4px;box-shadow:0 0 15px rgba(0,0,0,.4);' : 'background:-o-skin("Window Skin");'));
    w.id = wId;
    w.closeWin = function(){
        doc.removeEventListener('keydown', keyDown, false);
        this.parentNode.removeChild(this);
    };
    w.addEle = function(str, style){
        var ele = doc.createElementNS(xulns,"div");
        ele.setAttribute('style', style);
        if(str){
            ele.innerHTML = str;
            for(var el, all = ele.getElementsByTagName('*'), i = all.length; i--;){
                el = all[i];
                if(/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)){
                    el.parentNode.removeChild(el);
                }else{
                    for(var att = el.attributes, j = att.length; j--;){
                        if(/^on[a-z]+$/i.test(att[j].name))att[j].value = '';
                    }
                }
            }
        };
        return this.appendChild(ele);
    };
    var img = doc.createElementNS(xulns,"div");
    img.setAttribute('style', 'display:block;float:right;width:18px;height:18px;padding:0;margin:0;border:none;cursor:pointer;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAAZElEQVR42mNgGNyAGQixsVGU/AdCXjCbHczmxKaMFywlAlWiw6DAwIZNmQhYGqJEDWoqFiAGVmKKTwk73CRJ/Ep0GIyhbsPpO4hbIG4TwKaMk0EZ7hYBBk1cvmNDEmbDrmSwAADE8h10+qICXwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=");background:-o-skin("Caption Close Button Skin");');
    img.title = (win.navigator.language.indexOf('ru') == 0) ? '\u0417\u0430\u043A\u0440\u044B\u0442\u044C' : 'Close';
    img.addEventListener('click', function(){this.parentNode.closeWin()}, false);
    w.appendChild(img);
    w.addEle(title, 'display:table;color:#000;font:17px Times New Roman;width:auto;height:auto;padding:0;margin:0 2px;cursor:text;');
    var cnt = w.addEle(text, 'display:block;border:1px solid #aaa;margin:2px 0 1px 0;padding:4px;background-color:#fafcfe;color:#000;font:17px Times New Roman;width:320px;height:160px;overflow:auto;cursor:text;');
    w.addEle(status, 'display:table;color:#555;font:13px Times New Roman;width:auto;height:auto;padding:0;margin:0 3px;cursor:text;');
    w.addEventListener('mousedown', function(e){
        if(e.target == w){
            e.preventDefault();
            var grabX = e.clientX, grabY = e.clientY, origX = parseInt(w.style.left), origY = parseInt(w.style.top);
            var mouseMove = function(ev){
                w.style.left = origX+ev.clientX-grabX+'px';
                w.style.top = origY+ev.clientY-grabY+'px';
            };
            doc.addEventListener('mousemove', mouseMove, false);
            doc.addEventListener('mouseup', function(){doc.removeEventListener('mousemove', mouseMove, false)}, false);
        }
    }, false);
    doc.documentElement.appendChild(w);

    if(size){
        cnt.style.height = size.height;
        cnt.style.width = size.width;
    }else{
        for(var i = 3; i < 10; i++){
            if(cnt.scrollHeight > cnt.offsetHeight || cnt.scrollWidth > cnt.offsetWidth){
                cnt.style.height = 80*i+'px';
                cnt.style.width = 180*i+'px';
            }else break;
        }
    };
    var docEle = doc.compatMode == 'CSS1Compat' ? doc.documentElement : doc.body;
    var mX = docEle.clientWidth-w.offsetWidth, mY = docEle.clientHeight-w.offsetHeight;
    if(mX < 0){cnt.style.width = parseInt(cnt.style.width)+mX+'px'; mX = 0};
    if(mY < 0){cnt.style.height = parseInt(cnt.style.height)+mY+'px'; mY =0};
    var hW = parseInt(w.offsetWidth/2);
    w.style.left = (pos && pos.X < mX+hW ? (pos.X > hW ? pos.X-hW : 0) : mX)+'px';
    w.style.top = (pos && pos.Y+10 < mY ? pos.Y+10 : mY)+'px';
    w.style.visibility = 'visible';
    doc.addEventListener('keydown', keyDown, false);
};

var getSel = function (w) {
    var s, d = w.document;
    if (d.selection) {
        var r = d.selection.createRange();
        s = r ? r.text : ''
    } else {
        s = d.getSelection().toString();
        if (!s) {
            var e, t = d.getElementsByTagName('textarea'), u = d.getElementsByTagName('input'), i = t.length;
            while(e = (i > 0) ? t[--i] : u[-i--])try{
                if (e.offsetHeight > 0 && (s = e.value.substring(e.selectionStart, e.selectionEnd))) break
            }catch(x){}
        }
    };
    if (!s) for (var j = 0, f; f = w.frames[j]; j++) {
        try {
            if (s = getSel(f)) break
        } catch(x) {}
    };
    return s
};

var getHash = function (txt) {
    TKK=eval('((function(){var a\x3d817046147;var b\x3d-335196159;return 410049+\x27.\x27+(a+b)})())');
    function sM(a) {
        var b;
        if (null !== yr)
            b = yr;
        else {
            b = wr(String.fromCharCode(84));
            var c = wr(String.fromCharCode(75));
            b = [b(), b()];
            b[1] = c();
            b = (yr = window[b.join(c())] || "") || ""
        }
        var d = wr(String.fromCharCode(116))
            , c = wr(String.fromCharCode(107))
            , d = [d(), d()];
        d[1] = c();
        c = "&" + d.join("") + "=";
        d = b.split(".");
        b = Number(d[0]) || 0;
        for (var e = [], f = 0, g = 0; g < a.length; g++) {
            var l = a.charCodeAt(g);
            128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023),
                e[f++] = l >> 18 | 240,
                e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224,
                e[f++] = l >> 6 & 63 | 128),
                e[f++] = l & 63 | 128)
        }
        a = b;
        for (f = 0; f < e.length; f++)
            a += e[f],
                a = xr(a, "+-a^+6");
        a = xr(a, "+-3^+b+-f");
        a ^= Number(d[1]) || 0;
        0 > a && (a = (a & 2147483647) + 2147483648);
        a %= 1E6;
        return c + (a.toString() + "." + (a ^ b))
    }

    var yr = null;
    var wr = function(a) {
        return function() {
            return a
        }
    }
        , xr = function(a, b) {
        for (var c = 0; c < b.length - 2; c += 3) {
            var d = b.charAt(c + 2)
                , d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d)
                , d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
            a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d
        }
        return a
    };

    return sM(txt);
};

var ujs_google_translate = function (dir){
    var win = content, lng = win.navigator.language.slice(0, 2), txt = getSel(win), l = dir.split('|');
    if (txt) {
        var xhr = new XMLHttpRequest();
        var url = 'https://translate.google.com/translate_a/single?client=t&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt);

        xhr.open('POST', url, true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
        xhr.onreadystatechange = function() {
            try{
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0'));
                    for(var i = 0, n; n = tmp[0][i]; i++){
                        if(n[0])result += n[0].toString();
                    };
                    result = '<span style="background-color:inherit;color:inherit;font-size:inherit;font-family:Times,serif;">' + result + '</span>';
                    status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase();

                    createWindow(result, status, '<a href="'+url.replace(/&/g,'&amp;')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:17px Times New Roman;">Google Translate</a>', '_gt', btn.lastClick);
                }
            } catch (x){LOG(x)};
        };
        xhr.send('q=' + encodeURIComponent(txt));
    } else {
        win.open('http://translate.google.com/translate?u='+escape(win.location.href)+'&hl='+lng+'&langpair='+dir+'&tbb=1');
    };
};


btn.onclick = function(e){if(e.button == 0)ujs_google_translate('auto|ru')};

var contextMenu = document.getElementById("contentAreaContextMenu");
var nextEleMenu = document.getElementById("context-inspect");

var menuId = "context-ext-google-translate";
var menuItem = document.getElementById(menuId);
if (menuItem) {
    contextMenu.removeChild(menuItem.nextElementSibling);
    contextMenu.removeChild(menuItem.nextElementSibling);
    contextMenu.removeChild(menuItem);
};

menuItem = document.createElementNS(xulns,"menuitem");
menuItem.setAttribute("id", menuId);
menuItem.setAttribute("label", "Перевести на русский");
menuItem.setAttribute("class", "menuitem-iconic");
menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABBUlEQVR4Ac2RMU4DMRREB2MqihQpAkUaqnAduuQw4Sx03CGcJYIiDYqQ0lCsZ77535ZFcgAkRuPvV7zd/dLiz3N1PFb8hmRckrfELZrF9ONQ1B6Yz0MyM7S0O6zGkVprh/3+Kw/JzkHSpRpJKZkpr9fYbOx0cjVsCbWG31oHBM9mtt0q73ZcrdLhAMlYQKkUI22aqsNo8HKZAMQhvVaKSHWj2Q2aPU3mJQFY7nuHyvYFduP83WF3AJRfcPNYnr/Lp1G1uK4m9sno1LaUbnX/htf8BNzoneUD5NhjvLCMhURQSQ93QCZwXYjFwg3I0NZKrvoknQPMIHkt/jRAQKMeG2yX89/mB4EJbKbZxIhFAAAAAElFTkSuQmCC");
menuItem.addEventListener("command", function(){ujs_google_translate('auto|ru')}, false);
contextMenu.insertBefore(menuItem, nextEleMenu);

menuItem = document.createElementNS(xulns,"menuitem");
menuItem.setAttribute("label", "Перевести на английский");
menuItem.setAttribute("class", "menuitem-iconic");
menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAAB5UlEQVR4AWOgPZg0c9+Oq2+qpx9LaQaiw4mNB27efbs2uXFNQh2Q4Zm9zSNth23MhqjGnXMC86vnHmUS4udxv7OvOd2yPE7PTlfCTk9GVVEoyJA7WI8dyPA0k3U1l+jJMV7CeThpTZeoKDdDUsvBPSff/V+6/P/Bvf///2+bdvU/EKRm/k9IBNIlfZe+LFrzvbsbyJ636pKkyQyQhoUb7tZNvPpw3/0/TfX/ISAm5n94BIiRm/n/xYsLd946ei4vajoiqDuRAejQf//+o4PQ0P9+fmhiQGVnrr1kXJNYG2zEzXDxDsPv3wy/fkFJoOTPn39+/fr/69e/37//AUX+/mXRkO458wWHDba2f8wswCyQ3N+/f//8/fP7z5+TV18w2Mdt6plzPiptx5Wr7/+/ffMzOR6kysjkt74hWMPfp06O+2dulZCeFZKwnkE4m8E8bN3i9aCQ+dxY96GrK6bkGJD9R1v3l6Y20NVW9kt+/v//ZdbcFwkxTVPPMQimM8XEqkb7a/zoqLxkH9v4zVyI5+///wyMmtKMmhJAnbLqQjHxaw5r2orOmZN5uj470Zahat6BKS7JzpmLBHXm8GhM5lCdcP7ai1ZpixZxk9NXXjKIFzOIFjAI54oY1vXuue5qmscw+AAAW0tKxtPoicEAAAAASUVORK5CYII=");
menuItem.addEventListener("command", function(){ujs_google_translate('auto|en')}, false);
contextMenu.insertBefore(menuItem, nextEleMenu);

contextMenu.insertBefore(document.createElementNS(xulns,"menuseparator"), nextEleMenu);

addEventListener('keydown', function (e){
 if(e.shiftKey && !e.ctrlKey && e.altKey && e.keyCode == 84)ujs_google_translate('auto|ru');
}, false);


Пункты в контекстном меню создаются. Перевод всей страницы в новой вкладке выполняется нормально, но при переводе выделенного текста окно перевода не появляется. Посмотрите пожалуйста в чем здесь проблема.

Отсутствует

 

№1346207-07-2019 13:18:46

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

Re: Custom Buttons

Garalf однопроцессорный включен? Что в консоли пишет?

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

Отсутствует

 

№1346307-07-2019 13:24:05

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

Re: Custom Buttons

Andrey_Krropotkin
Включен. Вроде ничего не пишет.

Отредактировано Garalf (07-07-2019 13:42:46)

Отсутствует

 

№1346407-07-2019 13:44:13

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

Re: Custom Buttons

Garalf посмотри мой комбайн перевода, у меня так работает на 69b1 и исправь свой (однопроцессорный прописывается сначала config.js, потом переключается в about:config)

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

Выделить код

Код:

/*Initialization Code*/ 
//--------------------------------Перевод---------------------------------------- 
//Здесь можно изменять парамеры:

//Ключи
//Яндекс
var keyuser = "____Ваш ключ______";
//Microsoft
var keyus = "____Ваш ключ______"; 


//Варианты выбора языка переводчика для перевода текста в окне. Нужное разкоментировать. Остальное закоментировать.
//Google,
var langFrom_google_text = "auto";//авто
var langTo_google_text = "ru"; 
//Microsoft 
var langFrom_Microsoft_text = "";//авто 
var langTo_Microsoft_text = "ru"; 
//Promt 
var langFrom_PROMT_text = "a";//авто
var langTo_PROMT_text = "r"; 
//Яндекс 
var langFrom_yandex_text = ""; //авто
//var langFrom_yandex_text = "en-"; //английский и так же другие языки, тире обязательно
var langTo_yandex_text = "ru";
      
//Назначаем иконки
var mainicon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAIAAAD5gJpuAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQtJREFUKM9VkSFOhFEQg799/CjEihWAwKDgIFwAyWHgLDjuAGfZgMCQDQkG8abtQ/z8u9A0k4rOTCez2u0GB0gCsLELbCuxLduJy0zAZgOQBBqQALEbtOQoyRgjSZLt9nOaJyf5K2zPjr01SWst8ermZtzd5euLhCQ2Y9iOHXssIvZYr1f39x/T87Ourtr7O3ZUyK6KlN5HVRaOqlxcNGACJKRItigdHFXpFdXoPVWRGmSac0suRYWUWhz7zt5/BXh65Pi6Hr7rI/IopZyqpSqldLsq9onPX3iabuHYr6o3pCVHP2Sa11nIzZdnMAmOSpyejiocVEhtjrwc15L5l4HVDgReCGTR+V9n/AAByma0J+vVwwAAAABJRU5ErkJggg==";
var gticon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADPElEQVR4nGWTTWhjZRSG3/uTNr39mTqTn1KacagTqyKIlYJ2ExQCUhiprgpduRVFpLvZjOCsXEgWFqRk0RZcWLopmOnCQcPUsVBiTEZbalrGTJOZJm2aNGm++92b737fcdGZTfvAuznwnMV7OBouEI/HdSHEyNzcXCwajb7r8/n6T09P99bW1u4PDw8/SiQSbHd396IGBINBJJPJQDqdvssYK0kpO0SkiIiUUlII0SqVSr8lk8n3JycnjUsLZmdnb5bL5T+klPK5RNzp0BlzyHEFKXU+cxynubKy8tXExIQJABoAzM/PB6amptYikch70DRtv3iMh5kClPQglcKzozMMXhnAh7E3EL0RhCcEX19f/6xSqSxhdHRUT6VS39i2LYUQtJ7epm9/uEdHtSZJKUkpRa0zm75fvE+f3/mRmM3JcRyqVqulmZmZl7G6uhopl8sHtm3TduEpffH1T1Srn9FFavUmnTRaJKUkx3Go0WiojY2N22aj0Yj5fL6wJyVS6R289koYVwd7L3V07aUBAICUEkopSCk1v99/Sw+Hw5NSyi7OXZQrTQwFBy6f6DlKKSil4HkeOp0ODMO4btq23S+EgFQaAAKzO1BKQdd1AICmaSAiEBGUlBBCwHVduK4LzrlpHh4e7nHOVW+vofdbPmxkHuPWB6/D6vFD13UoRfj38TPsP6mBOxJjN64gdNUC5xz1er2l5/P5XxqNBvNEByPBLmS2n+LXzQK4zcH5ebp9GkAeEksPwJgNxhhs20axWMzo7Xb7US6Xyx7Xanh7LIhXRywklh7i9z/30Wy1YNsMfT0mrG4DGoCO64Ixhlqt5uTz+UVjZ2dHDA0NFYPB4Cd9fVb3W2MhnDZb+DldwD+FCk5OWvivVEX27ycY7APevHkNouNSNpu9l8vlvtMAIBQKGfF4/Mvp6em7oVCoxzAMOB0PjAsQEfxdPvi7DBgG4Dgu5fP5vxYWFj4uFAoHBgAwxmhvby8jpTywLOsdy7IGfKah9XSb56IOeJ7A0dGxs7m5mVpeXv60Xq8fcM7Pf+EFsVhMq1Qq18fHx2ej0ehHgUAgYpqm2W63W6VSKVMsFhe3trYeVKtV/sL5HwhICaDODiyAAAAAAElFTkSuQmCC";
var promticon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADQ0lEQVQ4jX2TX2xTdRTHT7O4GWL0gSwKmphoi3SsdFXHZiRjDExGSIxGHoTgwzDAUoM4skgEE6ckmiiEB2D8GYqbo2LLrmxZ51rWlob+W1e2ua2z2tp1ZVzrunZr161r7/3drw9TCLr4Sc7b+Zycc3IO0QNkY4M333LrD19zGbSc64aWc/VoOZepnnOZD3KuHi3nNB9rCQQcW2kl7CPjH3tPF7OUjpAxEbKDhNwEQUgSxBRBiD8GYWY/UlONzHO76YJery+4LwcmJmrHZtL5tlOVmGsjzPcQFgcIuRBBmCaIaYKYJIip18HyHiylv2Ae5wUtERGFef5ZZzQWS4sSmjgO060yzBsJi/2E3G8E4Y/lDpajDJIwDEkMwW2rHvf5fI/QlZHQFc+CBO8CQ9efOVw8s225gIewFCDkeRnEuSKwzGqw7PuQWAySlMFcrJ4NeIyv0SFv+N5nvIjdgSx2+NLYZ/Sio7nW4uTqdE7jIZ3TfFzntH6u03ON9g/aq9DQvgkftlfg5A+1aGk50EG77MHEK3cyKLHPQm6aRrkljqYu+/V/L/mNjroual0HuqwAnVeAzsix9og6Rg23xjmlLQm5OQ65OQ7FzRlstUyJtoHB7f/Ivf6+2kdNKpFMSlC3EvTjepDhBexo3tNLY+Ep9YaeyaX1tiSU9llscKSw0TOPPTecQ8FgsCgYDBZtt789Sv6NoGEVaKAU5C5F4fWSrHPIW05ERMetQxfV/fPQ+Bbw8nAWFaM5vDq6iK9tt9+77Pnu8NOz20AJDSimAd0tA4XVOGhovHR/vkgksqbqVjC5+VcBVSGGLb8zbAkxVHe642+OvpuQiSqQoAblNaClF1Hs2jQdjUbXPrSks1bHR5UjWZQPZqDxpKFyzEJ17VNckr5HIZOD2HMgUQHKrsOpn84e+c8p8zy/6qVzvZFnDJN46moYxedM+HKyGUPSCOpZI9awUjzBFCjr2+zneX7Viv/Q2tm3t+CEixWccKC68ygmhCj8wi8wCr04JnyCkruqfHd/984V5b+RnbxqbNj11VHLzrZ9kRr9O9ka614orTXseUPZvW8s39b9n/wQfr+/MBwOP+n+2V3huOOoTCQSj6+U9xeWlBixn0UlkAAAAABJRU5ErkJggg==";
var yndicon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC8UlEQVQ4jY2TTWgcZQCGv1OLgkX0UlChaC8iEUo1kNJV0UiTNl1SFasYk2pELeohVkOgWkILDSTR2tWGjRILhigVoxIbf1oaWkJtIokmYWOa3253t2T/Z2dnZmfnm5nv8RZIhdIXnst7eE7vK+oH5JvPfSe5HfZ963SImxPsL9E45PD6r/KWvDYsCfaXnN2nzYp1gt2nDZqGbJqGbJrP2ixrPpZU+AoMR5GxFCNRj6Yhmxe/t6j9uji6TvDsV3kaBk1az5XQy4q0pbia8WgYNMmVFA2DJhdWXCypaPrJJPhNgere/ME1wZM9aQ78oOMrGItJlIJIyiVf8rFdxWLW4+UzBfSyImv5vDCg8URPKlf1afw+IYQQO07eIGv5jMcc+v+2OPhjnqThkbV89g9kee9njZzlM5Fw+GXOpueKwa4vU1R9dmNACCHEY91RMqbH5Ws2ZVcR01ySRY/OCwXq+5LU9yWJaS5ayeeV/hQ5y6e+L8nOkzG2dy3vEYETK8Q0l7pwgpThURdOUBdOkLc89vYmiGkug9MGe3sTRHMSWyrqwgme+fw6FccXF0XFsTl026cmFGUx7VATilITihK+lKfsKjr/yKx1CymHklTUhKIEupd4uH32H/HQRzMYZZ94XlJ2FasFyWpBcmneIFN0CYZWqO5e4vlT15CeQrM8qruXeKQ9woOHp3aKB1onieccaj9ZIKW7PNVxdY1dXfOkiy77Ty2TNVzmV21az8R59MgM93842SuEEGJzyxjVx/9Fs1xe+mKB85ECgaMRAkcj1HbOYTk+17Nl9nTNkdIljx+ZZnPLldym5j/vEUIIce+7o1R9PEWwaxbD9nA9RVqXzMRMpqImTx+bwSx7pHVJoH2aLe+Pcfc7o6+uDWnT2yNUtk1Q2TbBjsOTXJzVsKVPseRxcVYjrUtOnI1T2TbB1pbL3PXWyPop3/nGebYdGmf7B3/dkm2Hxrmj+Zyzsfn3resEGxqHOzYc+I3bonH4f3f+Dz63ssfSaOz4AAAAAElFTkSuQmCC";
var bingicon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABMUlEQVQ4jY2SsU7DMBCG/TJYYqpEPDojcbq0NGM7sXdnggnigYFOyVDqLLBAkRJLTIwJSwdYw8gj8AQ/Q0kaO6HNSZbPp/P332+ZkJ7hSo2uvNdFV2rwMEOVGw28UVjl5bZZaqi8hA3aqzB/KOBKDVWUrcZ6ir/dgLlSY/HxAx5mmD++d15u7jzMjDNxpcbZyzeE+mz563o4bteaY9nj2bktwP97F7upS72yUgdLfNDIA428g9SD/6APZG84SoDGwoDQeFurly3CEh+OEmBKIFgPcWwBCCHkKPJwt7nA+dvIFBg/C9wUV3VhsbnF4L4NmKYT0Fjg9HVoApgSSL/WBuBkZQKm6QQ08jDLgraF8ZPAdX6JJnCw3AFo5IHGArMs2NVsi44SYIkPlviozraFrvgFK3TyTsPvtF8AAAAASUVORK5CYII=";
var lmricon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADQ0lEQVQ4jX2TX2xTdRTHT7O4GWL0gSwKmphoi3SsdFXHZiRjDExGSIxGHoTgwzDAUoM4skgEE6ckmiiEB2D8GYqbo2LLrmxZ51rWlob+W1e2ua2z2tp1ZVzrunZr161r7/3drw9TCLr4Sc7b+Zycc3IO0QNkY4M333LrD19zGbSc64aWc/VoOZepnnOZD3KuHi3nNB9rCQQcW2kl7CPjH3tPF7OUjpAxEbKDhNwEQUgSxBRBiD8GYWY/UlONzHO76YJery+4LwcmJmrHZtL5tlOVmGsjzPcQFgcIuRBBmCaIaYKYJIip18HyHiylv2Ae5wUtERGFef5ZZzQWS4sSmjgO060yzBsJi/2E3G8E4Y/lDpajDJIwDEkMwW2rHvf5fI/QlZHQFc+CBO8CQ9efOVw8s225gIewFCDkeRnEuSKwzGqw7PuQWAySlMFcrJ4NeIyv0SFv+N5nvIjdgSx2+NLYZ/Sio7nW4uTqdE7jIZ3TfFzntH6u03ON9g/aq9DQvgkftlfg5A+1aGk50EG77MHEK3cyKLHPQm6aRrkljqYu+/V/L/mNjroual0HuqwAnVeAzsix9og6Rg23xjmlLQm5OQ65OQ7FzRlstUyJtoHB7f/Ivf6+2kdNKpFMSlC3EvTjepDhBexo3tNLY+Ep9YaeyaX1tiSU9llscKSw0TOPPTecQ8FgsCgYDBZtt789Sv6NoGEVaKAU5C5F4fWSrHPIW05ERMetQxfV/fPQ+Bbw8nAWFaM5vDq6iK9tt9+77Pnu8NOz20AJDSimAd0tA4XVOGhovHR/vkgksqbqVjC5+VcBVSGGLb8zbAkxVHe642+OvpuQiSqQoAblNaClF1Hs2jQdjUbXPrSks1bHR5UjWZQPZqDxpKFyzEJ17VNckr5HIZOD2HMgUQHKrsOpn84e+c8p8zy/6qVzvZFnDJN46moYxedM+HKyGUPSCOpZI9awUjzBFCjr2+zneX7Viv/Q2tm3t+CEixWccKC68ygmhCj8wi8wCr04JnyCkruqfHd/984V5b+RnbxqbNj11VHLzrZ9kRr9O9ka614orTXseUPZvW8s39b9n/wQfr+/MBwOP+n+2V3huOOoTCQSj6+U9xeWlBixn0UlkAAAAABJRU5ErkJggg==";
var maillicon="data:image/gif;base64,R0lGODlhEAAQAPeSAPt3d+9fX8kTE39xVP+wsCFiAP/hpv/Sd4NYAf/Rdf/Whf/Ufebe3v/Teo+Caf/Xh//hpEAYAHZWF/+3JtfSyf7s7P/cl//p6WolJakZD//Naf/19WJMIPBnZ/jOzoMkJPrY2P/GU+xxcU87FH9TEO+kDvv6+f+yGf39/NmzaJQyIKJMPO3554lXPm3OPP38/KSYImLKLehYWPeysvFubv+8NUa2C1a6H31EKox2SJSaOPaBgfbRhvbYnPt8fFpmFbN+FrCXY3UHB//HVjlTCf/BRf/pvG5SMq6Tk/F0dDOSAf/MZzGSAGhTKP/LZKx7Gv/dmT+JCPO3t8m3t4xhCf/x8ZsVFYEZBPyVleuWlvzd3fSSkko0DZVyK7ctJf/blJFsbIt9Ff++Pf/lsPOrq/LPiMctLfJ4eP/lsubk3v/YirOqmfauHGJQLd9CQlECAf7U1P/MzNnVzPnFV0AnAP23t//7+8leXkq8EJGFbPnBwfS3Pv+zG2NPKNSbKP+uDf+4K9K0d/yZmWFPK3o9FnRSJXZISG1dPPrS0rmyoreSR8MUEtytP+dQUNAhIfVsbN9AQNcwMP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAJIALAAAAAAQABAAAAjbACUJFHghDgECdgYOrAKnjiAfACICwLJBoaQzjzJq1LijgsI7AUIm2TIDkZ4OAWhoGfihUSMQZES4nNlIhgeBGCDp3MlTpxspkgyZiUS0qNGiWcBYccS0aVMvK1ocGYFEiICrizKowFFIQhdFKcpQmPLmCiESVID42RPCSQIFX3pIYhABwZ8TE2oUGbLkwAMLEMageEGnBJ8wRH7M0dBADRQDaIwkksSFDSAYBQroWMAjUJAcTQblkTTgiRhGSphE4XDIwRo5JgamadNngI0beCzqFuiCRYzdkgICADs=";



function GetXmlHttpObject(){
         if (window.XMLHttpRequest){ return new XMLHttpRequest();}
         if (window.ActiveXObject) { return new ActiveXObject("Microsoft.XMLHTTP");}
        return null;
        };

var btn = this;

btn.lastClick = {
    X: 0,
    Y: 0
};
addEventListener("mouseup", function(e) {
    if (e && e.button == 0 && e.view.top == content) {
        var lc = btn.lastClick;
        lc.X = e.clientX;
        lc.Y = e.clientY;
    }
}, false);

var createWindow = function(text, status, title, id, pos, size){
    var win = content;
    var focusedWindow = document.commandDispatcher.focusedWindow;
            if (focusedWindow.top == content)
                win = focusedWindow;
    var doc = win.document, wId = 'ujs_window'+(id || ''), w = doc.getElementById(wId);
    var keyDown = function(e){if(!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode == 27)doc.getElementById(wId).closeWin()};
    if(w)w.closeWin();
    w = doc.createElement('div');
    w.setAttribute('style', 'position:fixed;display:block;visibility:hidden;left:0;top:0;width:auto;height:auto;border:1px solid gray;padding:3px;margin:0;z-index:99999;overflow:hidden;cursor:move;'+(typeof w.style.borderRadius === 'string' ? 'background-color:#f3f5f7;padding-top:4px;border-radius:4px;box-shadow:0 0 12px rgba(0,0,0,.4);' : 'background:-o-skin("Window Skin");'));
    w.id = wId;
    w.closeWin = function(){
        doc.removeEventListener('keydown', keyDown, false);
        this.parentNode.removeChild(this);
    };
    w.addEle = function(str, style){
        var ele = doc.createElement('div');
        ele.setAttribute('style', style);
        if(str){
            ele.innerHTML = str;
            for(var el, all = ele.getElementsByTagName('*'), i = all.length; i--;){
                el = all[i];
                if(/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)){
                    el.parentNode.removeChild(el);
                }else{
                    for(var att = el.attributes, j = att.length; j--;){
                        if(/^on[a-z]+$/i.test(att[j].name))att[j].value = '';
                    }
                }
            }
        };
        return this.appendChild(ele);
    };
    var img = doc.createElement('div');
    img.setAttribute('style', 'display:block;float:right;width:18px;height:18px;padding:0;margin:0;border:none;cursor:pointer;background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAQAAAD8x0bcAAAAZElEQVR42mNgGNyAGQixsVGU/AdCXjCbHczmxKaMFywlAlWiw6DAwIZNmQhYGqJEDWoqFiAGVmKKTwk73CRJ/Ep0GIyhbsPpO4hbIG4TwKaMk0EZ7hYBBk1cvmNDEmbDrmSwAADE8h10+qICXwAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAAASUVORK5CYII=");background:-o-skin("Caption Close Button Skin");');
    img.title = (win.navigator.language.indexOf('ru') == 0) ? '\u0417\u0430\u043A\u0440\u044B\u0442\u044C' : 'Close';
    img.addEventListener('click', function(){this.parentNode.closeWin()}, false);
    w.appendChild(img);
    w.addEle(title, 'display:table;color:#000;font:16px Times New Roman;width:auto;height:auto;padding:0;margin:0 2px;cursor:text;');
    var cnt = w.addEle(text, 'display:block;border:1px solid #aaa;margin:2px 0 1px 0;padding:4px;background-color:#fafcfe;color:#000;font:14px Times New Roman;width:240px;height:120px;overflow:auto;cursor:text;');
    w.addEle(status, 'display:table;color:#555;font:10px Times New Roman;width:auto;height:auto;padding:0;margin:0 2px;cursor:text;');
    w.addEventListener('mousedown', function(e){
        if(e.target == w){
            e.preventDefault();
            var grabX = e.clientX, grabY = e.clientY, origX = parseInt(w.style.left), origY = parseInt(w.style.top);
            var mouseMove = function(ev){
                w.style.left = origX+ev.clientX-grabX+'px';
                w.style.top = origY+ev.clientY-grabY+'px';
            };
            doc.addEventListener('mousemove', mouseMove, false);
            doc.addEventListener('mouseup', function(){doc.removeEventListener('mousemove', mouseMove, false)}, false);
        }
    }, false);
    doc.documentElement.appendChild(w);

    if(size){
        cnt.style.height = size.height;
        cnt.style.width = size.width;
    }else{
        for(var i = 3; i < 10; i++){
            if(cnt.scrollHeight > cnt.offsetHeight || cnt.scrollWidth > cnt.offsetWidth){
                cnt.style.height = 50*i+'px';
                cnt.style.width = 100*i+'px';
            }else break;
        }
    };
    var docEle = doc.compatMode == 'CSS1Compat' ? doc.documentElement : doc.body;
    var mX = docEle.clientWidth-w.offsetWidth, mY = docEle.clientHeight-w.offsetHeight;
    if(mX < 0){cnt.style.width = parseInt(cnt.style.width)+mX+'px'; mX = 0};
    if(mY < 0){cnt.style.height = parseInt(cnt.style.height)+mY+'px'; mY =0};
    var hW = parseInt(w.offsetWidth/2);
    w.style.left = (pos && pos.X < mX+hW ? (pos.X > hW ? pos.X-hW : 0) : mX)+'px';
    w.style.top = (pos && pos.Y+10 < mY ? pos.Y+10 : mY)+'px';
    w.style.visibility = 'visible';
    doc.addEventListener('keydown', keyDown, false);
};

var getSel = function (w) {
    var s,d = w.document;
    if (d.selection) {
        var r = d.selection.createRange();
        s = r ? r.text : ''
    } else {
        s = d.getSelection().toString();
        if (!s) {
            var e, t = d.getElementsByTagName('textarea'), u = d.getElementsByTagName('input'), i = t.length;
            while(e = (i > 0) ? t[--i] : u[-i--])try{
                if (e.offsetHeight > 0 && (s = e.value.substring(e.selectionStart, e.selectionEnd))) break
            }catch(x){}
        }
    };
    if (!s) for (var j = 0, f; f = w.frames[j]; j++) {
        try {
            if (s = getSel(f)) break
        } catch(x) {}
    };
    return s
};

var getHash = function (txt) {
    TKK=eval('((function(){var a\x3d817046147;var b\x3d-335196159;return 410049+\x27.\x27+(a+b)})())');
    function sM(a) {
        var b;
        if (null !== yr)
            b = yr;
        else {
            b = wr(String.fromCharCode(84));
            var c = wr(String.fromCharCode(75));
            b = [b(), b()];
            b[1] = c();
            b = (yr = window[b.join(c())] || "") || ""
        }
        var d = wr(String.fromCharCode(116))
            , c = wr(String.fromCharCode(107))
            , d = [d(), d()];
        d[1] = c();
        c = "&" + d.join("") + "=";
        d = b.split(".");
        b = Number(d[0]) || 0;
        for (var e = [], f = 0, g = 0; g < a.length; g++) {
            var l = a.charCodeAt(g);
            128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023),
                e[f++] = l >> 18 | 240,
                e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224,
                e[f++] = l >> 6 & 63 | 128),
                e[f++] = l & 63 | 128)
        }
        a = b;
        for (f = 0; f < e.length; f++)
            a += e[f],
                a = xr(a, "+-a^+6");
        a = xr(a, "+-3^+b+-f");
        a ^= Number(d[1]) || 0;
        0 > a && (a = (a & 2147483647) + 2147483648);
        a %= 1E6;
        return c + (a.toString() + "." + (a ^ b))
    }

    var yr = null;
    var wr = function(a) {
        return function() {
            return a
        }
    }
        , xr = function(a, b) {
        for (var c = 0; c < b.length - 2; c += 3) {
            var d = b.charAt(c + 2)
                , d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d)
                , d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
            a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d
        }
        return a
    };

    return sM(txt);
};

//----------Перевести  текст  из буфера в окне Google------------
var ujs_google_translat = function (dir){
   var win = content; 
   var lng = 'ru';
   var txt = gClipboard.read(), l = dir.split('|');
    if (txt) {
        var xhr = new XMLHttpRequest();
        var url = 'https://translate.google.com/translate_a/single?client=t&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt);
        xhr.open('POST', url, true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
        xhr.onreadystatechange = function() {
            try{
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />"));
                    for(var i = 0, n; n = tmp[0][i]; i++){
                        if(n[0])result += n[0].toString();
                    };
                    result = '<span style="background-color:inherit;color:inherit;font-size:inherit;font-family:Times,serif;">' + result + '</span>';
                    status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase();

                    createWindow(result, status, '<a href="'+url.replace(/&/g,'&amp;')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Google Translate</a>', '_gt', btn.lastClick);
                }
            } catch (x){LOG(x)};
        };
        xhr.send('q=' + encodeURIComponent(txt));
    };
};



//----------Перевести выделенный текст в окне Google------------
function ujs_google_translate (){
    var win = content, lng = win.navigator.language.slice(0, 2), txt = getSel(win);
    if (txt) {
        var xhr = new XMLHttpRequest();
         var url = 'https://translate.google.com/translate_a/single?client=t&sl=' + langFrom_google_text + '&tl=' + langTo_google_text + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt);
      
        xhr.open('POST', url, true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
        xhr.onreadystatechange = function() {
            try{
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />"));
                    for(var i = 0, n; n = tmp[0][i]; i++){
                        if(n[0])result += n[0].toString();
                    };
                    result = '<span style="background-color:inherit;color:inherit;font-size:inherit;font-family:Times,serif;">' + result + '</span>';
                   status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + langTo_google_text.toUpperCase();
                   createWindow(result, status, '<a href="'+url.replace(/&/g,'&amp;')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Google Translate</a>', '_gt', btn.lastClick);
                   
                }
            } catch (x){LOG(x)};
        };
        xhr.send('q=' + encodeURIComponent(txt));
     };
};

//----------Перевести текст в окне Яндекс------------
function ujs_yandex_translate() {
       var win = content, txt = getSel(win);
     // var txt = gClipboard.read();
       var encTxt = encodeURIComponent(txt);
     if (txt) { 
        var xhr = new XMLHttpRequest();
        var encTxt = encodeURIComponent(txt);
        var url ="https://translate.yandex.net/api/v1.5/tr.json/translate?key="+keyuser+"&lang="+langFrom_yandex_text+langTo_yandex_text+"&text=" + encTxt;

        function gettransdata(){
           xmlhttp=GetXmlHttpObject();
           xmlhttp.onreadystatechange=stateChanged;
           xmlhttp.open('GET', url, true);
           xmlhttp.send(null);
        }
        function stateChanged(){
          if (xmlhttp.readyState==4)
           {
           var tryain=xmlhttp.responseText;
           tryain=tryain.replace(/\\n/g, "<br />");
           var data = JSON.parse( tryain );
           var result,status;
           if (data.code == "401") {result = "Неправильный ключ API"; status = "";} 
           if (data.code == "402") {result = "Ключ API заблокирован"; status = "";} 
           if (data.code == "403") {result = "Превышено суточное ограничение на количество запросов"; status = "";} 
           if (data.code == "404") {result = "Превышено суточное ограничение на объем переведенного текста"; status = "";} 
           if (data.code == "413") {result = "Превышен максимально допустимый размер текста"; status = "";} 
           if (data.code == "422") {result = "Текст не может быть переведен"; status = "";} 
           if (data.code == "501") {result = "Заданное направление перевода не поддерживается"; status = "";} 
           if (data.code == "200") {result = data.text; var status1 = data.lang; status =(status1.replace(/\-/g, "-\u203A")).toUpperCase();}
           var urlt = 'http://translate.yandex.ru/?text=' + encTxt + '&lang=' + status1;
           createWindow(result, status, '<a href="'+urlt.replace(/&/g,'&amp;')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Яндекс</a>', '_gt', btn.lastClick);
           }
        }  
        gettransdata();
    } 
};
//----------Перевести выделенный текст в окне Microsoft------------
function ujs_Microsoft_translate (){
    var win = content, txt = getSel(win);
    var encTxt = encodeURIComponent(txt);
    if (txt) { 
        var xhr = new XMLHttpRequest();
        var encTxt = encodeURIComponent(txt), post = encTxt.length > 1024;
        var urlt = 'http://www.bing.com/translator/?from='+langFrom_Microsoft_text+'&to='+langTo_Microsoft_text+'&SourceText=' + encTxt;       
        var uridetect = "http://api.microsofttranslator.com/V2/Ajax.svc/Detect?appId="+keyus+"&text="+ encTxt;
        var url="http://api.microsofttranslator.com/V2/Ajax.svc/Translate?appId="+keyus+"&from="+langFrom_Microsoft_text+"&to="+langTo_Microsoft_text+"&text="+ encTxt;
 
        if (txt && location. hostname != 'http://api.microsofttranslator.com/')
         { var result="Подождите идет перевод", status="";
            createWindow(result, status,'<a href="'+url.replace(/&/g,'&amp;')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Bing</a>', '_gt', btn.lastClick);
         }
        function gettransdata(){
           xmlhttp=GetXmlHttpObject();
           xmlhttp.onreadystatechange=stateChanged;
           xmlhttp.open(post ? 'POST' : 'GET', url, true);
           if(post)xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
           xmlhttp.send(post ? encTxt : null);
           xmlhttp1=GetXmlHttpObject();
           xmlhttp1.onreadystatechange=stateChanged;
           xmlhttp1.open('GET', uridetect, true);
           xmlhttp1.send(null);
        }
       function stateChanged(){
         if (xmlhttp.readyState==4 && xmlhttp1.readyState==4)
         {
           var tryain=xmlhttp.responseText;
           tryain=tryain.replace(/\"/g, '').replace(/\\u000d/g, " ").replace(/\\u000a/g, "<br />").replace(/\//g, '').replace(/\\n/g, "<br/>").replace(/\\r/g, "");
           var tryain1=xmlhttp1.responseText;
           tryain1=tryain1.replace(/\"/g, '');
           var result = tryain;
          var status =(tryain1 +' -\u203A '+ "ru").toUpperCase();
          createWindow(result, status, '<a href="'+urlt.replace(/&/g,'&amp;')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Bing</a>', '_gt', btn.lastClick);
         }
       }  
      gettransdata();
   } 
};

//----------Заменить текст переводом Microsoft------------
function ujs_Microsoft_TexReplace (){
      var win = content, txt = getSel(win);
    var encTxt = encodeURIComponent(txt);
    if (txt) { 
        var xhr = new XMLHttpRequest();
        var encTxt = encodeURIComponent(txt), post = encTxt.length > 1024;
        var urlt = 'http://www.bing.com/translator/?from='+langFrom_Microsoft_text+'&to='+langTo_Microsoft_text+'&SourceText=' + encTxt;       
        var uridetect = "http://api.microsofttranslator.com/V2/Ajax.svc/Detect?appId="+keyus+"&text="+ encTxt;
        var url="http://api.microsofttranslator.com/V2/Ajax.svc/Translate?appId="+keyus+"&from="+langFrom_Microsoft_text+"&to="+langTo_Microsoft_text+"&text="+ encTxt;
 
        function gettransdata(){
           xmlhttp=GetXmlHttpObject();
           xmlhttp.onreadystatechange=stateChanged;
           xmlhttp.open(post ? 'POST' : 'GET', url, true);
           if(post)xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
           xmlhttp.send(post ? encTxt : null);
           xmlhttp1=GetXmlHttpObject();
           xmlhttp1.onreadystatechange=stateChanged;
           xmlhttp1.open('GET', uridetect, true);
           xmlhttp1.send(null);
        }
       function stateChanged(){
         if (xmlhttp.readyState==4 && xmlhttp1.readyState==4)
         {
           var tryain=xmlhttp.responseText;
           tryain=tryain.replace(/\"/g, '').replace(/\\u000d/g, " ").replace(/\\u000a/g, "<br />").replace(/\//g, '').replace(/\\n/g, "<br/>").replace(/\\r/g, "");
           var tryain1=xmlhttp1.responseText;
           tryain1=tryain1.replace(/\"/g, '');
           var result = tryain;
            var range = content.getSelection().getRangeAt(0);
              range.deleteContents();
              range.insertNode(range. createContextualFragment(result));
         }
       }  
      gettransdata();
   } 
};
//----------Заменить текст переводом Яндекс------------ 
function ujs_TexReplace_translate() {
       var win = content, txt = getSel(win);
       var encTxt = encodeURIComponent(txt);
       if (txt) { 
         var xhr = new XMLHttpRequest();
         var encTxt = encodeURIComponent(txt);
         var url ="https://translate.yandex.net/api/v1.5/tr.json/translate?key="+keyuser+"&lang="+langFrom_yandex_text+langTo_yandex_text+"&text=" + encTxt;

        function gettransdata(){
           xmlhttp=GetXmlHttpObject();
           xmlhttp.onreadystatechange=stateChanged;
           xmlhttp.open('GET', url, true);
           xmlhttp.send(null);
        }
        function stateChanged(){
          if (xmlhttp.readyState==4)
           {
           var tryain=xmlhttp.responseText;
           tryain=tryain.replace(/\\n/g, "<br />");
           var data = JSON.parse( tryain );
           var result = data.text;
     
          var range = content.getSelection().getRangeAt(0);
              range.deleteContents();
              range.insertNode(range. createContextualFragment(result));
           }
        }  
        gettransdata();
      } 
    
};  
//----------Заменить текст переводом Google------------
function ujs_google_TexReplace() {
    var win = content, lng = win.navigator.language.slice(0, 2), txt = getSel(win);
    if (txt) {
        var xhr = new XMLHttpRequest();
        var url = 'https://translate.google.com/translate_a/single?client=t&sl=' + langFrom_google_text + '&tl=' + langTo_google_text + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt);
       
           function gettransdata(){
           xmlhttp=GetXmlHttpObject();
           xmlhttp.onreadystatechange=stateChanged;
           xmlhttp.open('POST', url, true);
           xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
           xmlhttp.send('q=' + encodeURIComponent(txt));
        }
        function stateChanged() {
            
                if (xmlhttp.readyState == 4 ) {
           var result = '';
           var data = JSON.parse(xmlhttp.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />"));
           for(var i = 0, n; n = data[0][i]; i++){
                        if(n[0])result += n[0].toString();
                    };
           
              var range = content.getSelection().getRangeAt(0);
              range.deleteContents();
              range.insertNode(range. createContextualFragment(result));
                                     
                }
        }  
        gettransdata();
    } 
};

//--------Перевести текст в Google в новой вкладке--------------
function ujs_GoogleTextPageNew_translate() { 
   var win = content, txt = getSel(win);
   var encTxt = encodeURIComponent(txt);
   var ctabpos = gBrowser.selectedTab._tPos +1;
   var url="http://translate.google.com/translate_t?text="+encTxt+"&sl=auto&tl=ru&hl=ru&eotf=0&ujs=gtt";
   gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos);
};
//--------Перевести текст в Яндексе в новой вкладке--------------
function ujs_yandexTextPageNew_translate() { 
       var win = content, txt = getSel(win);
       var encTxt = encodeURIComponent(txt), post = encTxt.length > 1024;
       var ctabpos = gBrowser.selectedTab._tPos +1;
       if (txt) { 
          var xhr = new XMLHttpRequest();
          var url ="https://translate.yandex.net/api/v1.5/tr.json/detect?key="+keyuser+"&lang=ru&text=" + (post ? '' : encTxt);

       function gettransdata(){
           xmlhttp=GetXmlHttpObject();
           xmlhttp.onreadystatechange=stateChanged;
           xmlhttp.open(post ? 'POST' : 'GET', url, true);
           if(post)xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
           xmlhttp.send(post ? encTxt : null);
        }
       function stateChanged(){
          if (xmlhttp.readyState==4)
           {
           var tryain=xmlhttp.responseText;
           var data = JSON.parse( tryain );
           var status1 = data.lang;
           var urlt="http://translate.yandex.ru/?text=" + encTxt + "&lang=" + status1 + "-ru";
           gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(urlt), ctabpos);
           }
        }  
        gettransdata();
       } 
};
//---------Перевести текст в PROMT в новой вкладке---------------
function ujs_PROMTTextPageNew_translate(){ 
   var win = content, txt = getSel(win);
   var encTxt = encodeURIComponent(txt); 
   var ctabpos = gBrowser.selectedTab._tPos +1;
   var url="http://www.translate.ru/?External=IE8Accelerator&formEncoding=utf-8&direction=ar&prmtlang=ru&status=translate&template=General&source="+encTxt;
   gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos);
};
//---------Перевести текст в Microsoft в новой вкладке---------------
function ujs_MicrosoftTextPageNew_translate(){
   var ctabpos = gBrowser.selectedTab._tPos +1;
   var win = content, txt = getSel(win);
   var encTxt = encodeURIComponent(txt);
   var url="http://www.bing.com/translator/?to=ru&Text="+encTxt;
   gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos);
};


//--------Перевести страницу с Google--------------
function ujs_googlePage_translate() {
   var urlt = content.document.location.href;  
   var url = "http://translate.google.com/translate?hl=ru&sl=auto&tl=ru&u="+ encodeURIComponent(urlt) + "&sandbox=1";
   getBrowser (). loadURI(url, {
   triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
};

//---------Перевести страницу с Promt---------------
function ujs_PromtPage_translate() {
   var urlt = content.document.location.href;
   var url = "http://www.translate.ru/siteTranslation/autolink/?direction=ar&template=General&sourceURL="+encodeURIComponent(urlt);
   getBrowser (). loadURI(url, {
   triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
};

//---------Перевести страницу с Yandex---------------
function ujs_YandexPage_translate() {
   var urlt = content.document.location.href;
   var url = "https://translate.yandex.com/translate?url=" + encodeURIComponent(urlt) + "&dir=&ui=ru&lang=auto-ru" ;
   getBrowser (). loadURI(url, {
   triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
};
//---------Перевести страницу с Microsoft---------------
function ujs_MicrosoftPage_translate() {
   var urlt = content.document.location.href;
   var url = "http://www.microsofttranslator.com/bv.aspx?from=&to=ru&a="+encodeURIComponent(urlt);
   getBrowser (). loadURI(url, {
   triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
};

//---------Перевести страницу с Yandex в новой вкладке --------------
function ujs_yandexPageNew_translate() {
   var urlt = content.document.location.href;
   var url = "https://translate.yandex.com/translate?url=" + encodeURIComponent(urlt) + "&dir=&ui=ru&lang=auto-ru" ;
   var ctabpos = gBrowser.selectedTab._tPos +1;
   gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos);
};

//---------Перевести страницу с Microsoft в новой вкладке ---------------
function ujs_MicrosoftPageNew_translate() {   
   var urlt = content.document.location.href;  
   var url = "http://www.microsofttranslator.com/bv.aspx?from=&to=ru&a="+encodeURIComponent(urlt);
   var ctabpos = gBrowser.selectedTab._tPos +1;
   gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos);
};
//---------Перевести страницу с Promt в новой вкладке ---------------
function ujs_PromtPageNew_translate() {                 
   var urlt = content.document.location.href;  
   var url = "http://www.translate.ru/site/General/au-ru/?url="+ encodeURIComponent(urlt) + "";
   var ctabpos = gBrowser.selectedTab._tPos +1;
   gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos);
};
//--------Перевести страницу с Google в новой вкладке --------------
  
function ujs_GooglePageNew_translate() {
   var urlt = content.document.location.href;  
   var url = "http://translate.google.com/translate?hl=ru&sl=auto&tl=ru&u="+ encodeURIComponent(urlt) + "&sandbox=1";
   var ctabpos = gBrowser.selectedTab._tPos +1;
     
   var css = '@-moz-document domain("translate.google.com") {\
   #gb, #gt-c:not([class="g-section"]) { display: none !important; }\
   #contentframe { top: 0 !important; }\
   }';
   var uri = makeURI("data:text/css," + encodeURIComponent(css));
   var sss = Cc["@mozilla.org/content/style-sheet-service;1"]. getService(Ci.nsIStyleSheetService);
   try { sss.unregisterSheet(uri, sss.AGENT_SHEET) }
   catch(e) { sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET) } 

   gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos);
 };


//Контекстное меню для перевода из буфера-------------------------------------------  

(function () {
 if ( document.getElementById("TranslateBufer") ) return; 
 var contextMenu = document.getElementById("contentAreaContextMenu");  
 var Item = document.createXULElement("menuitem");
       Item.setAttribute("Id", "TranslateBufer");
       Item.setAttribute("label", "Перевод из буфера");
       Item.setAttribute("class", "menuitem-iconic");
       Item.setAttribute("image", mainicon);
       Item.addEventListener("command", function(){ujs_google_translat('auto|ru')}, false);

    contextMenu.insertBefore(Item, document.getElementById("context-viewpartialsource-selection") ); 
    addDestructor(function() { contextMenu.removeChild( Item ) });
 })();

 //Контекстное меню для перевода страниц-------------------------------------------  

(function () {
 if ( document.getElementById("TranslatePage") ) return; 
  
  var menu = document.createXULElement("menu");  
  var menuPopup = document.createXULElement("menupopup");
  var contextMenu = document.getElementById("contentAreaContextMenu");  
  
    menu.id = "TranslatePage";
    menu.setAttribute("label", "Перевести страницу");
    menu.setAttribute("class", "menu-iconic");
    menu.setAttribute("image", mainicon);
   
  contextMenu.insertBefore(menu, document.getElementById("context-viewsource") ); 
  menu.appendChild( menuPopup );
  addDestructor(function() { contextMenu.removeChild( menu ) }); 

    var array = [
        {label:"Google", func: ujs_googlePage_translate, image:gticon},
        {label:"Promt ", func: ujs_PromtPageNew_translate, image:promticon},
        {label:"Yandex ", func: ujs_YandexPage_translate, image:yndicon},
        {label:"Microsoft", func: ujs_MicrosoftPage_translate, image:bingicon},
        { separator: '' },
        {label:"Google в новой вкладке", func: ujs_GooglePageNew_translate, image:gticon},
        {label:"Promt в новой вкладке", func: ujs_PromtPageNew_translate, image:promticon},
        {label:"Yandex в новой вкладке", func: ujs_yandexPageNew_translate, image:yndicon},
        {label:"Microsoft в новой вкладке", func: ujs_MicrosoftPageNew_translate, image:bingicon}
        ];
        
   array.forEach(function( m ) {  
       if ( "separator" in m ) { menuPopup.appendChild( document.createXULElement("menuseparator") ); return };
       var mItem = document.createXULElement("menuitem");
       mItem.setAttribute("label", m.label);
       mItem.setAttribute("class", "menuitem-iconic");
       mItem.setAttribute("image", m.image);
       mItem.addEventListener("command", m.func, false);
       menuPopup.appendChild( mItem );

       });
   
     addEventListener("popupshowing", function() {
     menu.hidden = gContextMenu.isTextSelected || gContextMenu.onImage || gContextMenu.onTextInput ; 
  }, true, contextMenu );
})();

 //Контекстное меню для перевода текста-------------------------------------------  
(function () {
 if ( document.getElementById("TranslateSelected") ) return; 
  
  var menu = document.createXULElement("menu");  
  var menuPopup = document.createXULElement("menupopup");
  var contextMenu = document.getElementById("contentAreaContextMenu");  
      
    menu.id = "TranslateSelected";
    menu.setAttribute("label", "Перевести выделенный текст");
    menu.setAttribute("class", "menu-iconic");
    menu.setAttribute("image", mainicon);

  contextMenu.insertBefore(menu, document.getElementById("context-viewpartialsource-selection") ); 
  menu.appendChild( menuPopup );
  addDestructor(function() { contextMenu.removeChild( menu ) });
     
    
  var array = [
        {label:"В окне Google", func: ujs_google_translate, image:gticon},
        {label:"В окне Яндекс", func: ujs_yandex_translate, image:yndicon},
        {label:"В окне Microsoft", func: ujs_Microsoft_translate, image:bingicon},
        { separator: ''},
        {label:"Заменить текст переводом Яндекс", func: ujs_TexReplace_translate, image:yndicon},
        {label:"Заменить текст переводом Microsoft", func: ujs_Microsoft_TexReplace, image:bingicon},
        {label:"Заменить текст переводом Google", func: ujs_google_TexReplace, image:gticon},
        { separator: ''},
        {label:"В Google в новой вкладке", func: ujs_GoogleTextPageNew_translate, image:gticon},
        {label:"В Яндексе в новой вкладке", func: ujs_yandexTextPageNew_translate, image:yndicon},
        {label:"В PROMT в новой вкладке", func: ujs_PROMTTextPageNew_translate, image:promticon},
        {label:"В Microsoft в новой вкладке", func: ujs_MicrosoftTextPageNew_translate, image:bingicon}
              ];
  array.forEach(function( m ) {  
        if ( "separator" in m ) { menuPopup.appendChild( document.createXULElement("menuseparator") ); return };
       var mItem = document.createXULElement("menuitem");
       mItem.setAttribute("label", m.label);
       mItem.setAttribute("class", "menuitem-iconic");
       mItem.setAttribute("image", m.image);
       mItem.addEventListener("command", m.func, false);
       menuPopup.appendChild( mItem );
       });
 
     addEventListener("popupshowing", function() {
     menu.hidden = !gContextMenu.isTextSelected; 
  }, false, contextMenu ); 
 })();

Отсутствует

 

№1346507-07-2019 16:28:22

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 319
UA: Firefox 67.0

Re: Custom Buttons

Garalf пишет

Перевод всей страницы в новой вкладке выполняется нормально,

А у меня ваш код не работает совсем. Хотя кнопки а контекстном меню появились

Andrey_Krropotkin пишет

Garalf посмотри мой комбайн перевода, у меня так работает на 69b1 и исправь свой (однопроцессорный прописывается сначала config.js, потом переключается в about:config)

Ваш код тоже не работает

FF 67.04 (32 bit)

Andrey_Krropotkin пишет

(однопроцессорный прописывается сначала config.js, потом переключается в about:config)

Можете ли подробнее описать как прописать однопроцессорный?

Отсутствует

 

№1346607-07-2019 18:50:31

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

Re: Custom Buttons

Andrey_Krropotkin пишет

А DOM Inspector У Вас есть для 69b1?

Да почти тот же
dom_inspector-7.0.3-fx-paxmod.xpi
dom_inspector-7.0.3-fx-bootstrap.xpi

Garalf пишет

Посмотрите пожалуйста

Не-не, в строках 22, 30 и 47 менять createElement не нужно было.
Там же создаются <div>'ы и создаются документом контента.

Отсутствует

 

№1346707-07-2019 21:08:56

fokanik
Участник
 
Группа: Members
Зарегистрирован: 05-02-2014
Сообщений: 268
UA: Seamonkey 2.49

Re: Custom Buttons

Rag пишет

Помести youtube-dl.exe в папку PotPlayer/Module
Проверь если играет, то всё OK если нет тогда не знаю.

Quartz1t пишет

Есть инструкция как подключить youtube-dl ?

func4ptch4 пишет

А что он дает? скачивает к примеру 720-1080 с тюба

Реально работает, проверял на сайте ivi.ru из бесплатных фильмов:
377f2e6dfe0e.jpg

Выбор качества имеется, значит видео после просмотра можно вытащить из временной папки...
Но ютуб, вроде, открывается встроенными средствами.

Если просто скачать, то dоwnload master могЁт:
2887a2e73e75.jpg

Отредактировано fokanik (07-07-2019 21:15:14)

Отсутствует

 

№1346807-07-2019 22:28:56

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

Re: Custom Buttons

leex это для для 69, на 67 не будет работать, я не стал делать совместимым с 67. Все дело в createXULElement для пунктов контекстного меню (для 67 - createElement)
Garalf несколько страниц назад пост Dumby в config.js добавить

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

Выделить код

Код:

//
try {
    Components.interfaces.nsIUDPSocketChild ||
    Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment).set(
        "MOZ_FORCE_DISABLE_E10S",
        Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
            .getBoolPref("browser.tabs.remote.autostart", true) ? "" : "1"
    );
} catch(ex) {}


затем в about:config - browser.tabs.remote.autostart = false

Отредактировано Andrey_Krropotkin (07-07-2019 23:18:14)

Отсутствует

 

№1346907-07-2019 23:35:27

leex
Участник
 
Группа: Members
Зарегистрирован: 24-03-2011
Сообщений: 319
UA: Firefox 67.0

Re: Custom Buttons

Кстати, на счет переводчика в браузере FF
Почему-то не все страницы переводятся, но в Хроме без проблем
Например, макниловский фрорум никак https://discourse.mcneel.com/

Я в поддержку гугл транслит писал, они ответили - скорей всего этот сайт "кривой"
Хотя этот же сайт легко переводился пару лет назад в FF

Ни гугл, ни майктософт, ни промт,
Этот форум не берет.

Я думаю что это связано с FF, с его кардинальными переменами за последние пару лет.
Кто-нибудь знает как обратиться к Моззиловцам c этим вопросом?

Отредактировано leex (08-07-2019 01:04:44)

Отсутствует

 

№1347008-07-2019 06:14:28

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

Re: Custom Buttons

Andrey_Krropotkin
Dumby

Спасибо! Поставил обе кнопки.
Но есть один неприятный момент.
После перезапуска браузера текст в пунктах контекстного меню, создаваемых кнопками
становится невидимым, что очень неудобно.
Чтобы снова увидеть текст нужно в Персонализации перетащить кнопку, а потом обратно на панель.
В чем м. б. причина?
Пункты меню, создаваемые расширениями выглядят нормально


Andrey_Krropotkin
Как получить ключ API для перевода в окне Яндекса?

Отредактировано Garalf (08-07-2019 09:32:16)

Отсутствует

 

№1347108-07-2019 09:31:40

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

Re: Custom Buttons

Garalf пишет

Как получить ключ API для перевода в окне Яндекса?

зарегистрироваться на Яндексе и бесплатно получить на yandex в течении нескольких минут, также и для  microsoft. Если не понятно, в инете полно инструкций.

Garalf пишет

Но есть один неприятный момент.

У себя не наблюдаю, попробуй отключать по очереди кнопки.

Garalf пишет

Можно ее починить?

ее по моему делал bunda1
В качестве альтернативы дополнительное меню для кнопок для 67. Там один из пунктов - Сохранить все кнопки HTML файл

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

Выделить код

Код:

/*Initialization Code*/ 

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Создание меню ///////////////////////////////
/////////////////////////////////////////////////////////////////////////////

function $(aId) {
  return document.getElementById(aId);
};

function addMenuItem(aNewIDs, aNodeIDs, aLabel, aIcon, aCommand) {
  for (var i = 0; i < aNewIDs.length; i++) {
    
    if ($(aNewIDs[i])) $(aNewIDs[i]).parentNode.removeChild($(aNewIDs[i]));

  var mi = document.createElement("menuitem");
           mi.setAttribute("id", aNewIDs[i]);
           mi.setAttribute("class", "menuitem-iconic");
           mi.setAttribute("image", aIcon);
           mi.setAttribute("label", aLabel);
           mi.setAttribute("oncommand", aCommand);
        
    if (i == 0)
      mi.setAttribute("observes", "custombuttons-contextbroadcaster-primary");

    if ($(aNodeIDs[i])) {
      if ($(aNodeIDs[i]).nextSibling) {
        $(aNodeIDs[i]).parentNode.insertBefore(mi, $(aNodeIDs[i]).nextSibling);
      } else {
        $(aNodeIDs[i]).parentNode.appendChild(mi);
      }
    }
  }
};

var saveImg1 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAnUlEQVQ4jc3RPQ4BURTF8Z+PgrAPtUJnIxZgBZagkolVqDWWIliARCFR6GSq0Twyw2SemcpJTnPzzv/edy//ohOymj7mARl6NRoOQ6YAiGmNFAm6TQBpePdAJwYYYIF+rpaE8CoGaGEbarsw7qfaVYCl4rY3mOOGaQwwU326O8Zhyi/AJPwxdv8rRmWAyw/hl89lgCZ+69AgvPcXegKfOWlGgoA/rgAAAABJRU5ErkJggg==";
var saveImg2 = "data:application/file;base64,AAABAAEAEBACAAEAAQCwAAAAFgAAACgAAAAQAAAAIAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAADbAAADpcAAA//AAANVwAAD/8AAAKsAAAD/AAAP//AAAP8AAAD/AAAD/8AAAwDAAAP/wAAA/wAAAP8AAA";
var saveImg3 = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQf//rEH4j6xB8IesQeHDrEHD4axBh/CsQYf4rEGH8KxBw+GsQeHDrEHwh6xB+I+sQf//rEH//6xB//+sQQ==";
var saveImg4 = "data:application/file;base64,AAABAAEAEBACAAEAAQCwAAAAFgAAACgAAAAQAAAAIAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAA/wAAAP8AAA";
var saveImg5 = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAU1FQr1FRT7BRUU+wUVFPsFFRT7BRUU+wUVFPsFFRT7BRUU+wUVFPsFFRT7BRUU+wU1FQrwAAAAAAAAAAAAAAAHd0cpz//////////////////////////////////////////////////////////3d0cpwAAAAAAAAAAAAAAAB4d3Sc/////+Dg4P/g4OD/4ODg/+Dg4P/g4OD/4ODg/+Dg4P/g4OD/4ODg//////94d3ScAAAAAAAAAAAAAAAAenh3nP/////i4uL/4uLi/5yiz/9HYcT/PWrR/1qQ3P+nuNr/4uLi/+Li4v//////enh3nAAAAAAAAAAAAAAAAH18eJz/////5OTk/2FluP8IJ6r/D1TU/wli4v8FZeb/D3He/4y+5f/k5OT/+/v7/318eJwAAAAAAAAAAAAAAACBfXyc/////5Wc0v8JKq//E2Pd/yFTrv9EKTn/LjVZ/xaF2/8OdNP/zNnm//z8/P+BfXycAAAAAAAAAAAAAAAAhIGBnP////89Xc7/Dk7N/wpQ0/8zVp//TGCK/4U2Cf9DW2b/Eqj7/5C+5//8/Pz/hIGBnAAAAAAAAAAAAAAAAIaEgZz/////Kmnf/wlFzf8gPZ7/uXcl/8OAK/+UTBL/b1Az/zfG9f9srdX/+fn5/4aEgZwAAAAAAAAAAAAAAACJhoac/////0iN6P8HQtH/EVzd/2mCqf/dqkz/0pY6/6FnKv9Nvt7/kMfs//X19f+JhoacAAAAAAAAAAAAAAAAiomJnP////+Mr+r/FFnU/xVRyv+LorL/8Oqh//nXbP+5omH/Urvf/8bj7v/s7Oz/iomJnAAAAAAAAAAAAAAAAI6Kipz/////2+n3/5aSm/+hcEn/4uXC////2P/25KD/rqSD/7HR5//o6Oj/4eHh/46KipwAAAAAAAAAAAAAAACPjo6c//////j4+P/4+Pj/3s/F/9i/n//p27n/5NG0/+7r6f/r6+v/3t7e/9LS0v+Pjo6cAAAAAAAAAAAAAAAAk4+PnP/////6+vr/+vr6//r6+v/6+vr/+vr6//j4+P/19fX/r66t/62sq/ObmprrkI2NpgAAAAAAAAAAAAAAAJOTk5z//////Pz8//z8/P/8/Pz/+/v7//r6+v/4+Pj/9fX1/66trfHs7Ozrp6emp4aGhhMAAAAAAAAAAAAAAACWlpOc/////////////////v7+//39/f/6+vr/9/f3//Pz8/+bmprrp6enp3NzcxYAAAAAAAAAAAAAAAAAAAAAmJiWnJiYlpyYmJacmJiWnJeTk52SkZGemJiWnJeTk52SkZGej4+LpIaGhhMAAAAAAAAAAAAAAAAAAAAAgAMAAIADAACAAwAAgAMAAIADAACAAwAAgAMAAIADAACAAwAAgAMAAIADAACAAwAAgAMAAIADAACABwAAgA8AAA==";
var saveImg6 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABKklEQVR42mNkQAMNDAxCQMoTiB2BWAEq/ACI9wPxdqD8O2T1jGiao4HUEgb8IAaobimGAUDBGiDVzEAcqAWqb4EbQKTNWF3CCPXzW5ho/f//YDqHkZFhCpQNA7lAMV4gzY4QEmZEtx1mgCtQ8W4o2xLIPg5lJwDZUghDYkAGzAEyktENMAQqPA9l6wDZEkB6D6Yhc0EG7AGynfEZYAxkawHpxVC+A5CvC6RFGBj2Em2AIZCeg8Q3BtLSUAMIegGkwQBIz8U0YC7OQEQ2wAjIPoekGRQTUC/E4IxGkMKzaNEI8jso4chDbGdgA0UjekJ6A8S3gRikFWQyKOF/higGR50UFLPBEhLM9AZoUv4F1cAA1QTi/2SAJFkQnxdCoyZlJEPIz0xIhpCUnQFx83abgfUZOQAAAABJRU5ErkJggg==";
var saveImg7 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAASUlEQVR42mNkoBAw0s6ABob/aHxGkg1I8zEGM2dtOTskDED3MxCgGIBpASOGATANhACyi6hrAGVeoDgQB6UB2PxMvAFEAooNAAC7izYR2pQ0nAAAAABJRU5ErkJggg==";
var saveImg8 = "data:application/file;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///8A////AESqAABHpgAASKAAAEukAQxMpQMYR6MAAEepAQ9MpgOLRKgACUenAABHpgAARKoAAP///wD///8A////AP///wBEqgAARaIAAFS2FVBj0jS3Y9AzyVG0EUROrwt8TKcDs0ikAANInwAAR6YAAESqAAD///8A////AP///wD///8ARKQAAVvJKJtj0jX/SaAJ/0abCv9UtSH/U7QX8lW5IMddwyfQW8Iii0mqBQ1DqQAA////AP///wD///8A////AEWlAAFYwB6YXsYc5F7GFt9bwA+vVbgWvU6rAKBRrgf0RZgA/02oDP9ezCzJR6UBA////wD///8A////AP///wBFrAAASKIAADiGNQAeYIIpF1iJHVa4GKEve0tFLHl1Pla7J51exRnUWL8VjEetAAP///8A////AP///wD///8AC0WuAAk/tAAANdpIAFD6/wA+7f8gd6jqBlPX+QBE9PIGS8uDLnZLADqNJwAzjDMA////AP///wD///8A////AAAw0QAALc0AAEPdegBI4f8AK8P/ADHX/wAwzf8AL8b/AEno/gAz2zYALtEQAC3VAP///wD///8A////AP///wAAMssAADjSMwBA2pIATen/ADG9/wBe1v8ATcz/ADHK/wBN5/4ASeH/AEvl6wA10DP///8A////AP///wD///8AADnTSQBO5/8ANc7/ADnR/xC+9/8C0f//AMj//wCP8P8ALcX/ACrC/wBE3f8ASeOf////AP///wD///8A////AABI4Z4ARN3/ACvG/wJAxP8Z5v//AMT//wDE//8Axv7/AETM/wA51P8AUervADjSPP///wD///8A////AP///wAAOdRiAFry+QBS6/QATOP/H+P8/xDe//8J1///E9H4/wFE2f8AReC6ADTOEwAyywD///8A////AP///wD///8AADDNAAAyzCcARN7WACvG/wVfzf8d0vf/HM30/whf0/8AI7n/ADzV+AA40kUAMswA////AP///wD///8A////AAAwywAAPNdTAEfg/wAsw/8AOdb/ADLP/wAswv8AReP/AC7H/wA40f8AR+GfADDKAP///wD///8A////AP///wAAMswAADfRQgBY8f8AT+j/AE7o7AA+1/8AK8T/AE7o/wBN5f8AVe7/AD/ZbAAwywD///8A////AP///wD///8AADPMAAAyywAANM4vADjSUQA0zikAU+z3AEff/wBJ4sMAN9EtADjROQAyywAAM8wA////AP///wD///8A////AAAzzAAAM8wAADHLAAAwywAAMcsAAD/YXQBK4pYAN9AxAC/KAAAwygAAM8wAADPMAP///wD///8A+R8AAPAfAADABwAAwAMAAPgDAADwHwAA8AcAAOADAADAAwAAwAMAAMAHAADgBwAA4AcAAOAHAADwDwAA/j8AAA==";
var saveImg9 = "data:application/file;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAD///8BAAAAFwAAAGkAAABzAAAAdQAAAHUAAAB1AAAAdQAAAHUAAAB1AAAAdQAAAHUAAAB1AAAAdQAAADkAAAAP////AQAAAIdgZmj/YWlt/2FobP9haGz/YGhr/2Boa/9fZ2v/X2dr/15mav9dZWn/XGRo/0ZNUP8AAACdAAAAFf///wEAAACr2tzc/9ve4P/a3t//1dnZ/7S2tf+foJz/m5ya/6apqP/O0tP/09fZ/9DV1v+hqq//AAAAuQAAABX///8BAAAAq+3u7//e4eL/ub29/2hnXv9oVUX/U0As/zgxGf83Lx3/YWBX/7a5uv/S1tj/o6yx/wAAALkAAAAV////AQAAAKv29/f/19na/1dUQf9jXDv/dmtJ/4FoSP9VQiL/V0Ek/008Iv9HQTP/yc3P/6Wus/8AAAC5AAAAFf///wEAAACr+Pj4/5uamP9tY0L/g31b/6GLa/+McVH/eFY5/4xwUv9yXkD/RTki/4uMiv+nsLT/AAAAuQAAABX///8BAAAAq/n6+v+FfXL/waSM/8qznf/DrZP/ooFi/7WfhP+qh2//blk9/1A+Iv9aWlH/pK2x/wAAALkAAAAV////AQAAAKv6+/v/d3Rr/9zCsP/RxbH/z8Wu/9fJt//Qvab/qItv/5iOb/9tYUH/VVJK/6Wtsf8AAAC5AAAAFf///wEAAACr+/z8/4mHff+3pI//3NK//+HXxf/m3Mz/5trJ/9rMuf+bgWT/d14//2hnYP+osbX/AAAAuQAAABX///8BAAAAq/z9/f/FxL7/j4l+//Xw5f/29ez/8/Dl/+DMuv/VuaP/poZn/2dFKv+srav/oamt/wAAALkAAAAV////AQAAAKv+/v7/+/z8/5iZjf+5uqr/6+PW/+3i1P/kzL3/vZR+/4NhSf+Qh3z/z9HS/4qQkv8AAAC1AAAAFf///wEAAACr/v7+//7+/v/u7u3/tbiv/5WSgP+DfGj/e25Z/29gTv+sppz/vr6+/5aYmP90eHr/AAAApwAAABP///8BAAAAq/////////////////7+/v/9/f3//f39//v8/P/5+fn/1dXV/2pqav9TU1P/QUFB/wEBAYkAAAAJ////AQAAAKv7+/v//////////////////v7+//7+/v/+/v7/+vr6/9fY2P/V1tb/7Ozs/4KCgv8EBAQrAAAAA////wEAAACFlJSU/6ioqP+qqqr/qqqq/6qqqv+qqqr/qKio/6anp/2kpaX9o6Oj/4qKitUZGRk9////Af///wH///8BAAAAFQAAAFUAAABVAAAAVQAAAFUAAABVAAAAVQAAAFUAAABTBAQEUx8fH1dfX18z////Af///wH///8BAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//w==";
var loadImg = "data:image/x-icon;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAD///8B////Af///wH///8B////AQAAAB+yg2l71ZRt+daTa//Wk2v/1pNr/9aTa//Wk2v/v4NlywYEAycAAAAX////Af///wH///8B////Af///wHdo4M53Zx3/+Sgef/innb/4p52/+Kedv/lo3r/5aR6/+mqgfvPj27N////Af///wH///8B////Af///wH///8B4KSD8+mmff/opH3/56N6/+Whef/no3r/66qB/8KBXf/Fg1//0Y5s78+Pbqn///8B////Af///wH///8B////AeGlg//trIX/7ayE/+6thP/urIX/9bWL/8eFYf/GhF//yYZh/9SPa/nkn3j/////Af///wH///8B////Af///wHkn3j/76+G/+6uh//vrob/76+G//W3jP/GhF//y4di/9ONZ//XkWr/5J94/////wH///8B////Af///wH///8B5J94/++wif/wsIj/8LGJ//CxiP/0toz/y4di/8+KZf/vroP/766D/+SfeP////8B////Af///wH///8B////AeSfeP/xs4v/8bOL//Cziv/ws4v/87WL/9CNa+3QjWvt3p96/96fev/en3r/////Af///wH///8B////Af///wHkn3j/8rWN//K2jf/ytY3/8rWN//O2jvfdo4Lj0I5sJdCObCXQjmwl0I5sJf///wH///8B////Af///wH///8B5J94//O3j//zuI//87iP//O4j//zuZDx3aOD7////wH///8B////Af///wHdo4M/5J94/+SfeP/kn3j/5J94/++2j//zupH/9LqR//O6kv/0upL/87qR/+SfeP/kn3j/5J94/+SfeP////8B////Af///wHkoXr/9cCY//W8k//0vJT/9L2T//S8lP/0vZT/9LyU//S8lP/1vJT/9cCY/+Shev////8B////Af///wH///8B9b+WC+SjfP/2yqP/9b+W//a/lf/2v5X/9b6V//W+lv/1vpX/9sqj/+SjfP////8B////Af///wH///8B////Af///wH2wZgX5aZ+//fTrP/2wJj/9sCY//bAmP/2wZj/99Os/+Smf/////8B////Af///wH///8B////Af///wH///8B////Af///wHkqYH/99ax//fCmv/3wpn/99aw/+Sogf////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////AeWrhP/317L/99ey/+WrhP////8B////Af///wH///8B////Af///wH///8B////Af///wH///8B////Af///wH///8B5a2F/+Wthf////8B////Af///wH///8B////Af///wH///8BAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//w==";
var moveToMenu = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABKElEQVR42o3TMUvDQBQH8P+7tLlEwaW4ugl+iU6CCA4i0tbdqavgZ/ErCE79DsVBkYpKLR2kuApOatG297zLJWkqXnIPwrsk937cveQIJXHZBZt8cgFyzaEqYGuTvl7feM2FVAIHR8Bj341UAu1T4PPdjXgBJgzyPKDFy4SDIkJZo1yRASZ+FDB5Itzfct7YBGjuBBBh6oT6ed2OazGjsV3wQ2Cu64bXUKM7FgZJgPaufinTSVFhrDPFheVIe01nwLgfq9HNVCRAaw8Q6USWS4B05mgVIH2/qG+ABh+46im7heP9EELOLRDZpVqAQev8ZwUS/DBLivMtlDWxc7Ycs6yBhyov9vqMGcBBDB5/rxT7/Qfntjn/FXsDrmIvoHUonMVegMllx/kXlvSRMQ0GPE4AAAAASUVORK5CYII=";
var removeFromToolbar = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACMElEQVR42p3Sz2/SUBwA8G9pgQJd6QYZQQkOjUFdXMCLMn9B4l3myRgXhydPZgcTY2KyLfGiF/wT9GTmhfIXjMQ4NP5YD5qZTGdVdEx+9FVKSwttrTV4QD3AN3mH9837fr7v+/Kww1e4ic2HiSYMRGxufcHjxs87nQ5GN0zodnXQNLVomvCAL6ZR/xxmAS9VsX1umz1pJ/dfKGeD4+58OERNYQQO7Y4BWs8E3XCAqvRAEkWkdpTcNptm+4DpMVUOtboZl4tY2reXWmTGvbDTVKFnALicTrvYsFqbpgEOBw6tpgiigOb4Yoa1gTMzY1B+XUexKM1gLid8a3QgQHtBklQQBJm3RuAxDBiPl0z4aMq+eu1rFYmiFLOBowd8QJEEiLIBlbpV7PdArdZCApJX3j9O3e/Pe/Di0zTpJgvB8CSjSG1o7O7mbCA04QIHjoGsGuAfI6FRk0D8ISe3VlPc4OPGL61nab+/QDE0VD9/+T1CKOCCtqoDQRBAe0n4yH/nZUVLVtjTCP4R8cvPN8LRSKL6qVKygUjIC0rXAAMw6+EI6GkmoGaDM0DP8KuzfyHx+WfLe6KRpdpOlbMB+E9oWof78OhEcjB/5OqLbHAyUEB1oYTBCDFz7VWaYZg11BTYkYBj17lFyu3Lo5aYGwk4fuNNHgd8QVHk2EjA7K3NDVM3iuV708tDA2dXtqb0rr5mrWT57jQaGjh1+13eKio+uXOo9Gs/NJC6+TZhdf7zQ38Ceg0HgF1MCP0AAAAASUVORK5CYII=";
var iconADD = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACDUlEQVR42nWT30sUURTHz91Zd9FkVBRrX0oScTMI8weSIYSU/QMFbb5oGAn+AQo9B/UH9BAF+lIr+OLrSETQQ4GhEVRrUFkP/SLRNcvUnXv8nrmz7XVcB86cy7nn+5kz556ryHrueKxIYcFkPMmbxXHgzA6NDyguatQewBzHkKMMQDnWPgDsIwYh8/hATP8HQCRJEFIc5iA1DpljZIGogJU/9WXp39DR1pj99QBwe45dZb6UhCXE2Hx6m4xtQZQ/8SDni+DdSNopVYtysUiFpVbDqp4vPL4uCWc6zt+H+wvbAOBrCBCRFgh0AtIA6BboBVADc6eeZLMCGOq/kkF8Hcs8AO8tgDwav5M0AI/bw87Xw9dml+bvSUamtfsGYmuIrQDwKgIoQirkF3pR9uCbz28vx+tTMWo6VRdsL79eLax80yePtc3MTlwYKwMIT8HTvYufFkc+bq4NOjWN9Kf6cIVsHNr4sePnf9LxytqH06Od1w6oICGA9uZGOnvEpb7tgkrefLl8UXZvdTV5CYe3vv9Wzy6dVnfL9KAKfkcALeihaSKT+yj3Imji1XRPBvFyTTSn4LHMi5Y5SCnrGFc3c5MCqKtMD5c5RnsOisfILlmD1NxA5yThwy96GhkkRtlxrP3oIO0d5ZKXfSSbUYaJ1/tGef9lovAyUeQyAaKCO4nLpPRBABWJlwCWt6vYBccZ9A793wmLAAAAAElFTkSuQmCC";
var customBtn = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAjVJREFUeNqcUkuIUmEUPl4fML6bBsFRacRF2EaCcRO48bFLEIJcBIJLxb2b2UWLkIEgQQjauVFaKmgYuclUTMUHKoaKE4GPxnxh5r3ezh0QHJFmmA/OPZfDfx7fdw7AfojQ7qGx4QawdgMymeyRyWR6IZVKucFg8N10Ov0Ot4VGozmNRCLx5XL5F/HHbrefYZh7m1yWWq0+TafTn2kEdqXr9TrtcDje3JR4xRHH1QYCgXOz2Wzs9/sQj8dBIpEATtGrVqu9yWSywmdLNGq3AAeNsFgsz202mxk7QzKZBK1WCzqdjtHjKUmSx41Go4L+slQqpYvF4keKoibXpnA6nWfY+VehUKBSqRTJ0Oh2u3Qul6MHgwE9Ho9pLMD4H16v95zD4RxuU6BbrdYlPh5g8tfFYvET9XiIiRylUsnQgPl8DtgVhsOheL1eS6LRaGy1Wg02FAA5VmKxWB1/yUQioWOxWHKXy2XEYsDQEggEgKJCJpOBcrnMbOliW4MNSOaDCbVKpVISCoVGHBnQQygUgnK1AkeH9z+Ew+HX2xoQezZDjUaj3ygDiMViaLfbV8kK+TGw2WysJzzafry3QK1W+9Lr9RpIDbLZLEhE4vedTsdvMBieuN3ulwRBPLh2B7uYzWYXzWZzjBoc5PP5MJ70K1xfEsVc4cpNeDcnuLFvzM3978gILpcrRy/w+XybGE+v1z/z+/2frFarG9d5AHeBSqUyeDyetwqF4jHcFXw+/4TH44n+CTAA3Ccog288LRAAAAAASUVORK5CYII=";
var saveAll = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACOElEQVR42mNkwAJ+7xf7//3tKwZeIUELRqf3JxnwAEZkzrtlwnv/MzE6/WfkWCwS/iTu7RLO/wzMPAwc/z4Lc0f/eIfTgP/7BM0PXDY5ofB9N8M/EB8k+BcoyQw1mEWd4SurLIO97lkUFzX9b/oPNmBznc7/////MbAzfIdoBoI/P77Abfnzn4XhH9A0kOLA7icQV88HKn0EdcH6Ss3/yM76/f0jg2vTXYZ/f39j9fdUgQkMdTp1DNFXoiEGrCzFNMCj6SrD/79/MDQzsbAzCEfyMTBwADkbGBjBBiwrRDXgF9AAz6ZLWF1QIlHCsFRnKdj2pYxLIQYsytPAMMC75SLYBVMkpzDkPM+By0lFSTEwCDAwvJ79eouoqKgv2IB5WWgGfPvI4N95kUEyQQwcJVXbq8CGeEp6MlzUuQi2fcKbCQgDZqWhG/CJIaDrLIPMf0kGBjeggAoDw5YNWxh8rHwYGMQZGB5PfszAysq6RUJCAmLAtCR1DAMCu08zzJSZxtDm0cbA8AQoyAxJGyDbWx+2MrCwsGyRkZGBGDApDpsBx8FhME95HkObfhtYM4MqA8OdnjtgNSAXyMvLQwzoi8JmwGF4NGoc12Bg6IHYXnuzFm6AsrIyxIAJ+UHXfj27oomIhc9AA/ajpAOdPToMV1yuwPnMzMxbNDU14QaEAqnGH28fqYGywt/fP5i8q5czYUtIMABygY6ODsSAJUuWOKMrUFHT2PPvzy90YZhX/79//36dt7d3KACPfPJHOU7GxAAAAABJRU5ErkJggg==";

let cIDs = ["custombuttons-contextpopup-exportXML",
            "custombuttons-contextpopup-exportXML-sub"];
let bIDs = ["custombuttons-contextpopup-bookmarkButton",
            "custombuttons-contextpopup-bookmarkButton-sub"];
addMenuItem(cIDs, bIDs, "Сохранить код кнопки в XML файл", saveImg9,
            "document.getElementById('" + this.id
          + "').saveXML(('triggerNode' in this.parentNode) "
          + "? this.parentNode.triggerNode.URI "
          + ": document.popupNode.URI);", "X");
let xIDs = ["custombuttons-contextpopup-importnewbutton",
            "custombuttons-contextpopup-importnewbutton-sub"];
let aIDs = ["custombuttons-contextpopup-addnewbutton",
            "custombuttons-contextpopup-addnewbutton-sub"];
addMenuItem(xIDs, aIDs, "Добавить кнопку из XML файла\u2026", loadImg,
            "document.getElementById('" + this.id +
            "').loadXML();");          
let fIDs = ["custombuttons-contextpopup-copyImageURI",
            "custombuttons-contextpopup-copyImageURI-sub"];
let b2IDs = ["custombuttons-contextpopup-copyURI",
            "custombuttons-contextpopup-copyURI-sub"];            
addMenuItem(fIDs, b2IDs, "Копировать изображение кнопки в формате base64", saveImg1,
            "document.getElementById('" + this.id
          + "').copyImageURI();");
let f1IDs = ["custombuttons-contextpopup-saveButtonImage",
            "custombuttons-contextpopup-saveButtonImage-sub"];
addMenuItem(f1IDs, cIDs, "Сохранить изображение кнопки", saveImg8,
            "document.getElementById('" + this.id
          + "').saveImageURI();");  
let f2IDs = ["custombuttons-contextpopup-copyButtonsCodeText",
            "custombuttons-contextpopup-copyButtonsCodeText-sub"];
addMenuItem(f2IDs, b2IDs, "Копировать код кнопки как текст", saveImg2,
            "document.getElementById('" + this.id
          + "').copyButtonsCodeText();");                    
let f3IDs = ["custombuttons-contextpopup-copyAsHTML",
            "custombuttons-contextpopup-copyAsHTML-sub"];
addMenuItem(f3IDs, b2IDs, "Копировать код кнопки как HTML ссылку", saveImg3,
            "document.getElementById('" + this.id
          + "').copyToHTMLCode();");
let f4Ds = ["custombuttons-contextpopup-copyToBBCode",
            "custombuttons-contextpopup-copyToBBCode-sub"];
addMenuItem(f4Ds, b2IDs, "Копировать код кнопки как BBcode сылку", saveImg4,
            "document.getElementById('" + this.id
          + "').copyToBBCode();");          
let f5Ds = ["custombuttons-contextpopup-saveAsHTML",
            "custombuttons-contextpopup-saveAsHTML-sub"];
addMenuItem(f5Ds, bIDs, "Сохранить код кнопки в HTML файл", saveImg5,
            "document.getElementById('" + this.id
          + "').saveToHTMLCode();");
let f8Ds = ["custombuttons-contextpopup-saveAsHTMLAll",
            "custombuttons-contextpopup-AsHTMLAll-sub"];
addMenuItem(f8Ds, f5Ds, "Сохранить все кнопки в HTML файл", saveAll,
            "document.getElementById('" + this.id
          + "').saveToHTMLALLCode()");          
let f6Ds = ["custombuttons-contextpopup-getButtonId",
            "custombuttons-contextpopup-getButtonId-sub"];
let b1IDs = ["custombuttons-contextpopup-remove",
            "custombuttons-contextpopup-remove-sub"];            
addMenuItem(f6Ds, b1IDs, "Показать Id кнопки", saveImg6,
            "document.getElementById('" + this.id
          + "').idMIonclick(content.document);");
let f7Ds = ["custombuttons-contextpopup-addNextButton",
             "custombuttons-contextpopup-addNextButton-sub"];
   
                                        
var addMI = document.getElementById('custombuttons-contextpopup-addnewbutton');
addMI.setAttribute('image', iconADD);
var addMI1 = document.getElementById('custombuttons-contextpopup-addnewbutton-sub');
addMI1.setAttribute('image', iconADD);
var addMI2 = document.getElementById('custombuttons-contextpopup-move-moveToPanel');
addMI2.setAttribute('image', moveToMenu);
var addMI3 = document.getElementById('custombuttons-contextpopup-move-removeFromToolbar');
addMI3.setAttribute('image', removeFromToolbar);
var addMI4 = document.getElementById('custombuttons-contextpopup-customize');
addMI4.setAttribute('image', customBtn);

/////////////////////////////////////////////////////////////////////////////
/////////////////////////////// Общие функци ////////////////////////////////
/////////////////////////////////////////////////////////////////////////////

var options1 = {year: "numeric"};
var options2 = {day: "numeric", month: "long"};
var cDate = new Date().toLocaleDateString("ru-RU", options1);
var dDate = new Date().toLocaleDateString("ru-RU", options2);
var aDate = cDate + "г" + " " + dDate;

var options3 = {weekday: "long", year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "numeric", second: "numeric", hour12: false};
var bDate = new Date().toLocaleDateString("ru-RU", options3);

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();
             }
         });
};

/////////////////////////////////////////////////////////////////////////////
////////////////////////////Остальные функци ////////////////////////////////
/////////////////////////////////////////////////////////////////////////////


/////////////////////////////// Показать Id кнопки ///////////////////////////////

this.idMIonclick = function idMIonclick() {
  var btn = document.popupNode.id;
  var box = custombuttons.confirmBox("Копировать в буфер", btn, "Да", "Нет");
  if (box) {
    custombuttons.cbService.writeToClipboard(btn);
    custombuttons.alertSlide(btn, "Скопирована в буфер");
} }
function  mostRecentWindow(windowType) {
  return Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow(windowType);
}

/////////////////////////////// Копировать изображение кнопки в формате base64 ///////////////////////////////

this.copyImageURI = function copyImageURI() {
    var btn = document.popupNode;
    if (!btn) return;
    cbu.gClipboard.write(btn.image);
  var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService);
  as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "Изображение кнопки скопировано в буфер", false, "", null);
}

/////////////////////////////// Копировать код кнопки как текст ///////////////////////////////

this.copyButtonsCodeText = function copyButtonsCodeText() {
  var btn = document.popupNode;
  if (!btn) return;
  var code = ((btn.cbCommand == "") || (btn.Command == "/*CODE*/"))
              ? ""
              : ("\n/*CODE*/\n" + btn.cbCommand + "\n");
    var init = ((btn.cbInitCode == "") || (btn.cbInitCode == "/*Initialization Code*/"))
              ? ""
              : ("\n/*Initialization Code*/\n" + btn.cbInitCode);
    cbu.gClipboard.write(code + init);
    //custombuttons.alertSlide(btn.name, "Код скопирван в буфер");
    var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService);
        as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "Код скопирван в буфер", false, "", null);

}

/////////////////////////////// Копировать код кнопки как HTML ссылку ///////////////////////////////

this.copyToHTMLCode = function copyToHTMLCode() {
  var btn = document.popupNode;
  if (!btn) return;
  var code = "<p><div id=\"install\" style=\"background: transparent -moz-linear-gradient(center top , rgb(224, 102, 255) 30%, rgb(125, 38, 205) 55%); text-shadow: 0pt -1px 0pt rgb(122, 55, 139); border: 1px outset rgb(85, 26, 139); border-radius: 1em; padding: 0; width: 240px; text-align: center;\"><a href=\"" + btn.URI + "\" style=\"display: block; padding: 1em; color: #ffffff; text-decoration: none;\" title=\"Click here to install " + btn.name + "\" rel=\"nofollow\"><img src=\"" + btn.image + "\" alt=\"" + btn.name + "\" style=\"vertical-align: middle; float: left;\"/>" + btn.name + "</a></div></p>";
  cbu.gClipboard.write(code);
  var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService);
  as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "HTML кнопки скопирован в буфер", false, "", null);

}

/////////////////////////////// Копировать код кнопки как BBcode сылку ///////////////////////////////

this.copyToBBCode = function copyToBBCode() {
  var btn = document.popupNode;
  if (!btn) return;
  var code = "[url=" + btn.URI + "][B]" + btn.name + "[/B][/url]";
  cbu.gClipboard.write(code); //.toXMLString());
  var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService);
  as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "BBCode кнопки скопирован в буфер", false, "", null);
}

/////////////////////////////// Сохранить изображение кнопки ///////////////////////////////

this.saveImageURI = function saveImageURI(btn) {
 
  var remove = gBrowser.removeCurrentTab.bind(gBrowser);
    var promiseTargetFile = async (...args) => {
        var res = await window.promiseTargetFile(...args);
        setTimeout(remove, 0);
        return res;
    }
    var internalSave = eval(`(${window.internalSave})`);
    var save = eval(`(${window.saveDocument})`);
     
     var btn = document.popupNode;
  if (!btn) return;
  
  (saveButtonImage = btn => {
        if (btn.image != "") {
            var tab = gBrowser.selectedTab;
            gBrowser.selectedTab = gBrowser.addTab(btn.image, {
                triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
            });
            setTimeout(function() {
                window.content.document.title = btn.name;
                save(window.content.document);
            }, 2000);
        } else
            custombuttons.alertBox("Эта кнопка не имееет изображения!");
    })(btn);
 
}



/////////////////////////////// Сохранить кнопку в XML файл ///////////////////////////////

this.saveXML = function saveXML(aStrURI) {
  var cbURI = (aStrURI != undefined) ? aStrURI : readFromClipboard();
  if (!cbURI || !/^custombutton\:\/\//.test(cbURI)) {
    custombuttons.uChelpButton(this);
    return;
  }
var topicURL = "http://forum.mozilla-russia.org/viewforum.php?id=34"
  var cbXML = cbURI.replace(/^custombutton\:\/\//, "");
  var decodeXML = unescape(cbXML);
  var btnName = decodeXML.match(/\<name\/?.+/).toString();
  var name = "untitled";
  if (!/\<name\/\>/.test(btnName)) {
    name = btnName.replace(/\<\/?\w+\>/g, "").toString();
  }
  var image = decodeXML.match(/\<image\/?.+/).toString();
  var icon = "";
  if (!/\<\image.*\[\].*\>$/.test(image)) {
    icon = image.match(/[^\[\]]+/g)[2].toString()
                .replace(/custombuttons\-stdicon\-\d/, "").toString();
  }

  function htmlEntities(str) {
      return str.replace(/&/g, "&amp;").replace(/</g, "&lt;")
                .replace(/>/g, "&gt;").replace(/"/g, "&quot;");
  }

  var xmlTemplate = "custombuttons/\"\n\
              xmlns:html=\"http://www.w3.org/1999/xhtml\">\n\
  <html:head>\n\
    <html:title><![CDATA[" + name + "]]></html:title>\n\
    <html:link rel=\"shortcut icon\" href=\"" + icon + "\"/>\n\
    <html:style type=\"text/css\"><![CDATA[\n\
body { font-size: medium; margin: 0; }\n\
body, code:before, help:before, initcode:before {\n\
  font-family: \"Verdana\", sans-serif;\n\
}\n\
#wrapper { position: fixed; top: 1em; right: 1em; text-align: center; }\n\
p { font-size: small; text-align: center; }\n\
#button {\n\
  background-color: rgb(85, 168, 2);\n\
  background-image: linear-gradient(to bottom, rgb(147, 200, 94),\
 rgb(85, 168, 2));\n\
  background-image: -moz-linear-gradient(top, rgb(147, 200, 94),\
 rgb(85, 168, 2));\n\
  background-image: -o-linear-gradient(top, rgb(147, 200, 94),\
 rgb(85, 168, 2));\n\
  background-image: -webkit-linear-gradient(top, rgb(147, 200, 94),\
 rgb(85, 168, 2));\n\
  border: 1px solid rgb(58, 116, 4);\n\
  border-radius: .5em;\n\
  -moz-border-radius: .5em;\n\
  -webkit-border-radius: .5em;\n\
  padding: 0;\n\
  margin-bottom: 1em;\n\
  box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\
  -moz-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\
  -o-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\
  -webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\
}\n\
#button a {\n\
  color: #000;\n\
  text-shadow: -1pt -1px 0pt rgba(255, 255, 255, .5);\n\
  padding: 1em;\n\
  text-decoration: none;\n\
}\n\
:-moz-any-link:focus {\n\
  color: white;\n\
  outline-color: transparent;\n\
  text-decoration: none;\n\
}\n\
#button a, code, code:before, initcode, initcode:before, help, help:before {\
\n  display: block;\n\
}\n\
#credits { position: fixed; bottom: 1em; right: 1em; font-size: small; }\n\
custombutton { background-color: rgb(171, 171, 171); margin: 1em; }\n\
date, image, mode, accelkey { display: none; }\n\
name { font-weight: bold; font-size: x-large; }\n\
code:before, help:before, initcode:before {\n\
  font-weight: bold;\n\
  font-size: large;\n\
  margin: 0 0 1em;\n\
  padding: .5em;\n\
}\n\
code:before { content: \"Код\"; }\n\
help:before { content: \"Справка\"; }\n\
initcode:before { content: \"Инициализация\"; }\n\
code, initcode, help {\n\
  background-color: rgb(255, 255, 255);\n\
  border: 1px inset rgb(170, 170, 170);\n\
  font: medium monospace;\n\
  margin: 1em 1em 2em 0;\n\
  padding: 1em;\n\
  text-align: left;\n\
  width: 840px;\n\
  white-space: pre-wrap;\n\
  word-wrap: break-word;\n\
}\n\
.clear { clear: both; }\n\
]]></html:style>\n\
  </html:head>\n\
  <html:body>\n\
    <html:div id=\"wrapper\">\n\
      <html:div id=\"button\">\n\
        <html:a href=\"" + cbURI + "\" rel=\"nofollow\" title=\"Установить " +
        htmlEntities(name, "ENT_COMPAT") +"\">\n\
        <![CDATA[Установить кнопку]]>\n\
        </html:a>\n\
      </html:div>\n\
      <html:div id=\"credits\">\n\
        <html:a href=\"" + topicURL +"\">\n\
          <![CDATA[Другие кнопки]]><html:br/>\
<![CDATA[на форуме Mozilla Россия]]>\n\
        </html:a>\n\
      </html:div>\n\
    </html:div>\n\
  </html:body>";

  decodeXML = decodeXML.replace(/custombuttons\/\"\>/, xmlTemplate);

  name += ".xml";
  saveToFile(decodeXML, name);
 var btn = document.popupNode;
 var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService);
 as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "сохранена в XML файл", false, "", null);
}
var mrw = mostRecentWindow('navigator:browser');
var css = '@-moz-document url("chrome://browser/content/browser.xul"){' + this.Help + '}';
var uri = makeURI('data:text/css,' + encodeURIComponent(css));
var sss = Components.classes['@mozilla.org/content/style-sheet-service;1'].getService(Components.interfaces.nsIStyleSheetService);
if (!sss.sheetRegistered(uri, sss.USER_SHEET)) sss.loadAndRegisterSheet(uri, sss.USER_SHEET);

/////////////////////////////// Добавить кнопку из XML файл ///////////////////////////////

this.loadXML = function loadXML() {
  var nsIFilePicker = Ci.nsIFilePicker;
  var fp = window.makeFilePicker();
  fp.init(window, "Установить кнопку из XML файла",
          nsIFilePicker.modeOpen);
  fp.appendFilters(fp.filterXML);
  fp.appendFilter("Все файлы", "*.*");
  fp.open(re=> { 
      if ( re == fp.returnOK ) gBrowser.selectedTab = gBrowser.addTrustedTab(fp.file.path);
   })

}


/////////////////////////////// Сохранить все кнопки в HTML файл ///////////////////////////////

this.saveToHTMLALLCode = function saveToHTMLALLCode() {
 var visibleCBbuttons = [...document.querySelectorAll('[cb-mode]')];
   var paletteCBbuttons = [...custombuttons.palette.querySelectorAll('[cb-mode]')];
   var allCBbuttons = visibleCBbuttons.concat(paletteCBbuttons);

var gn = btn => btn.getAttribute("label") || "Без названия";
allCBbuttons.sort((a, b) => gn(a).localeCompare(gn(b)));

var array = [];
   allCBbuttons.forEach(but=> {
      var uri = but.URI ? but.URI : getPaleteButtonsURI(but);
      var name1 = but.getAttribute("label") || "Без названия";
      var image = but.getAttribute("image") || "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACNFBMVEXDRgDweQDnbwC0NgDCRQC7PQDtpTu+QQD78q3PUwDCRAD//8vbYQDLTgDocAD0iQX1jQbGSgD7iAD4gwDVaw7vdwDyegD+igDweQDlawDyhAXveADmZwDzmBbtcwDwkhHveADmhBTkgxbweADkfRH+igD7hADXZQX0gADyjA/tfgvveQDiawDQVADRXgfnbwD1jAb9iQD9z0PVZAbxpinykRHtdgD5mRbERQDDRgDOYArCRAD9iQD3ewDxegD3dwDFRgDAQAD+hgD4fQDucgDtgQftfwTISQDCRQDvdgD5lxb1kRb2qh7wnynkagD766LDRQDDRwDDRQDspjbtpzbuqDbvqzv//8DUZAbCRQD//83pjhvveQbvggW+QQDfcxLlmUb//8veYADMTwDHSADVVwC8PgDwixb78q3oZgDUWADRVADCRQD9iQDERwDBQQDYVQC+PgC0NgDbYQDWWgDUWADSVQDFSAC+QAC7PAC0NgD+wRL+/kD+/zb+7i3+8Cv+/DX+wBL/+DD/rwz+qgz+rwz/tAz+sQzfbAT+3iP/+jD//Dz1jwP+nwf5iwf7pBz2tRr4lwb/ogfsdQT+2R7/9ET+2iT8yyLmgBL5iQL2egLokhP7zzT60zv1zUr0gAL1ewP50yn9+UL++EXooyngaAH41EPzowzyySj+xxzlhhHvvyruwjXxvTnUag3+zxrwigP+swz86U/ZXwD75lHqegD6xzb//kn+uhPTXAG3OAD/+UC2vFeJAAAAe3RSTlMAAAAAAAAAAAAAAAAAAAAAAAAAAACfnwAIaelpAAA2+wD7UQAAa3oArKzRzMysnwgAvPQA/gAAw3prw0oALr16vS4AACnF6bspAAAA/mIAADQAAAAAAI8AAEwA0vv7kd2yAuuvr+vKABL23U+8Sk/d9vUDIIAQAAAQgCAfvupHAAABB0lEQVR4Xi3IU3fDABgA0C+u26FdZ9u2bdu2vZSzbds2/tyac3IfLxjpGyA6MimqY6gHTNgiiNwkwRM1E7EhTrYyTfMzzsh0ZEPiH+D6+u5mV1jEhpe5haVCYW1T4suEvUOkk7PLpVJ5WFnl7hEUDN5LPvsHJ6cazdn13f3DYxu0B35+/Y2qVSr17NzGeUgohIVHLK/PMDa39qKieRATGxd/9cS4uU1MwnmQktqY/qGlaVr7/ZOVDTmQm5df8PwyNj4xOTVdjOM4kCRZOr+wWFa+srpWQVEU8PnV2zu7NbV19UfHDQRBAIfTdNHc0soVdnR2dfdgGAgEvW99/QNc4eDQ8O8Ihv0D77NPgbVLZ6kAAAAASUVORK5CYII=";
      
      array.push("<li>\n<img src=" + image + ">&nbsp\<a href=" + uri + ">" + name1 +"</a><br>\n");
   });
   
   var before = "<html>\n<head>\n<title>Custom Buttons</title>\n<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>\n";
   var before1 = "<style type='text/css'>\nbody {background: beige;} a:link {color: black; text-decoration: none;} img {border: 0; margin: 0px 10px;}\n</style>\n";
   var before2 = "</head>\n<body>\nCustom Buttons\n<p>\n";
   var info = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
   var before3 = info.vendor + " " + info.name + " " + info.version + " (build " + info.appBuildID + ")\n";
   var after = "\n</ol>\n</body>\n</html>";
    
   var text = before + before1 + before2 + before3 + "<p>\n" + bDate + "<p>\n" + "<ol>" + array.join("") + after;
   var name = "CB buttons " + aDate + ".html"
   saveToFile(text, name);

   var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
   alertsService.showAlertNotification(saveImg5, "Экспорт в HTML", "Экспортировал все CB кнопки как HTML");
   setTimeout(()=> alertsService.closeAlert(), 4000);
};


function getPaleteButtonsURI(but) {
   var doc = document.implementation.createDocument("", "", null);
   doc.async = false;
   doc.load("chrome://custombuttons/content/nbftemplate.xml");

   ["help,Help", "name,label", "image,image", "mode,cb-mode", "initcode,cb-init", "accelkey,cb-accelkey", "code,cb-oncommand"]
   .forEach(str=> {
      var arr = str.split(',');
      var value = but.getAttribute(arr[1]), name = arr[0];
      custombutton.buttonSetText(doc, name, value, true);
   });

   var ser = new XMLSerializer();
   return "custombutton://" + escape(ser.serializeToString(doc));
};


/////////////////////////////// Сохранить кнопку в HTML файл ///////////////////////////////

this.saveToHTMLCode = function saveToHTMLCode() {
  var btn = document.popupNode;
  var xml = '<html xmlns="' + xhtmlns + '">\n';
      xml += '<head>\n';
      xml += '<meta http-equiv = "Content-Type" content = "text/html; charset=utf-8"/>\n';
      xml += '<title>  ' + btn.name + ' для Custom Buttons </title>\n';
      xml += '<link rel="icon" type="image/vnd.microsoft.icon" href = "'+ btn.image +'" />\n';
      xml += '<style type="text/css">\n';
      xml += '.button a{ \n';
      xml += 'background-color: rgb(85, 168, 2); \n';
      xml += 'background-image: linear-gradient(to bottom, rgb(147, 200, 94), rgb(85, 168, 2)); \n';
      xml += 'background-image: -moz-linear-gradient(top, rgb(147, 200, 94), rgb(85, 168, 2)); \n';
      xml += 'border: 1px solid rgb(58, 116, 4); \n';
      xml += 'border-radius: .5em; \n';
      xml += ' -webkit-border-radius: .5em; \n';
      xml += 'padding: 0; \n';
      xml += 'margin-bottom: 1em; \n';
      xml += 'box-shadow: 1px 2px 3px rgba(0, 0, 0, .25); \n';
      xml += ' -o-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25); \n';
      xml += ' -webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25); \n';
      xml += ' color: #000; \n';
      xml += ' text-shadow: -1pt -1px 0pt rgba(255, 255, 255, .5); \n';
      xml += ' padding: 0.5em; \n';
      xml += ' text-decoration: none; \n';
      xml += '} ';
      xml += 'pre { border: 1px inset rgb(170, 170, 170); \n';
      xml += 'background-color: rgb(255, 255, 255);} \n';
      xml += 'body { background-color: rgb(245, 245, 220);} \n';
      xml += '</style> \n';
      xml += '</head>\n';
      xml += '<body>\n';
      xml += '<section id="install"><h1> ' + btn.name + ' </h1> \n';
      xml += '</section>\n';
      xml += '<div class="button"><a href = "' + btn.URI + '">Установить кнопку</a></div> \n';
      xml += '<section id="init"><h2>Инициализация</h2><pre>' + e4xConv_encodeHTML(btn.cbInitCode) + '</pre></section>\n';
      xml += '<section id="code"><h2>Код</h2><pre>' + e4xConv_encodeHTML(btn.cbCommand) + '</pre></section> \n';
      xml += '<section id="help"><h2>Справка</h2><pre>' + e4xConv_encodeHTML(btn.Help) + '</pre></section> \n';
      xml += '</body> \n';
      xml += '</html> ';
  var html = '<!DOCTYPE html>\n' + xml;
  var name = btn.name + ".HTML";
  saveToFile(html, name);
  var as = Cc['@mozilla.org/alerts-service;1'].getService(Ci.nsIAlertsService);
  as.showAlertNotification(btn.image, "Кнопка: " + btn.name, "сохранена в HTML файл", false, "", null);
}

function e4xConv_encodeHTML(s, isAttr) {
    s = String(s)
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;");
    if(isAttr) {
        s = s
            .replace(/\t/g, "&#x9;")
            .replace(/\n/g, "&#xA;")
            .replace(/\r/g, "&#xD;");
    }
    return s;
};


/////////////////////////////// Переместить кнопку ///////////////////////////////

this.MoveToolbarButtons = MTB = {
    // Start editable preferences
    MoveButtonMICBContext: true, // Add "Move button" menu item to Custom Buttons context menu?
    MoveButtonMITBarContext: false, // Add "Move button" menu item to toolbars context menu?
    ShowMoveAlert: false, // Show the alert with instructions when moving buttons?
    MoveBtnImage: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAYklEQVQ4jWNgGJTgaAXHf2LEcGrGZQBBQ45WcPz/fZ0XpwG45FAUEDIAqzyyJLIiZIxNHqdmYvHRCo7/DLhsIEYziivQDcHnBawxgqyQUCzgjQlC6YCotEB2QkJWTIzY4AAAezv/caeCLKcAAAAASUVORK5CYII=",
    // End editable preferences

    _UID: "__cb_move_toolbar_buttons_" + custombuttons.getNumber(self.id),
    WindowIDs: ["main-window", "messengerWindow", "msgcomposeWindow"],
    ToolbarContexIDs: ["toolbar-context-menu", "aios-toolbar-contextmenu", "aios-sbhtoolbar-contextmenu"],
    Pref: "extensions.custombuttons.MoveToolbarButtons.Id" + custombuttons.getNumber(self.id) + ".MoveButtonID",
    SP: Services.prefs,

    Init: function() {
        if (!(MTB._UID in window)) {
            window[MTB._UID] = {
                Initialized: false
            };
        }

        if (!window[MTB._UID]["Initialized"]) {
            window[MTB._UID]["Initialized"] = true;
            custombuttons.isPref(MTB.Pref, "");

            if ("CustomizableUI" in window) {
                var originalFunction = custombuttons.persistCurrentSets.toString();
                eval("custombuttons.persistCurrentSets=" + originalFunction
                    .replace(", newButtonId)", ", newButtonId, aToRight)")
                    .replace("pos + 1", "aToRight ? pos : pos + 1"));
            }

            if (MTB.MoveButtonMICBContext) {
                var contextPops = document.getElementsByTagName("menupopup");
                let p = 0,
                    pLen = contextPops.length;
                for (; p < pLen; p++) {
                    var cPopID = contextPops[p].id;
                    if (cPopID.substr(0, 26) === "custombuttons-contextpopup") {
                        var cPopEl = document.getElementById(cPopID);
                        var moveMIID = "custombuttons-contextpopup-moveButton" + cPopID.slice(26);
                        var moveMIEl = document.getElementById(moveMIID);
                        if (!moveMIEl)
                            MTB.CreateMoveMI(moveMIID, cPopEl);
                    }
                }
            }

            if (MTB.MoveButtonMITBarContext) {
                Array.prototype.slice.call(MTB.ToolbarContexIDs).forEach(function(aTBCtxID, aIndex) {
                    let Ctx = document.getElementById(aTBCtxID);
                    let tBarCtxMIID = MTB._UID + "moveButton" + aIndex;
                    if (!document.getElementById(tBarCtxMIID)) {
                        if (Ctx) {
                            MTB.CreateMoveMI(tBarCtxMIID, Ctx);
                            Ctx.addEventListener("popupshowing", function(aE) {
                                document.getElementById(tBarCtxMIID).hidden = (document.popupNode.tagName !== "toolbarbutton");
                            }, false);
                        }
                    }
                });
            }

            addDestructor(function(aReason) {
                if (aReason === "delete") {
                    SP.resetUserPrefs(MTB.Pref);
                    delete window[_UID];
                }
                if (aReason === "delete" || aReason === "update") {
                    window[MTB._UID]["Initialized"] = false;
                }
            });
        }
    },

    getPopupNode: function(aEl) {
        if (custombuttons.popupNode)
            return custombuttons.popupNode;
        var popupNode = aEl;
        while (popupNode.tagName.toLowerCase() !== "toolbarbutton") {
            popupNode = popupNode.parentNode;
        }
        return popupNode;
    },

    CreateMoveMI: function(aMItemID, aPopupEl) {
        let moveMIEl = aPopupEl.appendChild(document.createElementNS(xulns, "menuitem"));
        moveMIEl.setAttribute("id", aMItemID);
        moveMIEl.setAttribute("label", "Переместить кнопку...");
        moveMIEl.setAttribute("class", "menuitem-iconic");
        moveMIEl.setAttribute("image", MTB.MoveBtnImage);
        moveMIEl.setAttribute("tooltip", MTB._UID + "moveButtonMI_tooltip");
        moveMIEl.setAttribute("onclick", "document.getElementById(\"" +
            self.id + "\").MoveToolbarButtons.MoveOnClick(event);");
    },

    MoveOnClick: function(aE) {
        var popupNode = MTB.getPopupNode(aE.target);
        if (!popupNode)
            return;
        aE.stopPropagation();
        aE.preventDefault();
        if (aE.button === 0 && !aE.shiftKey && !aE.ctrlKey && !aE.altKey) {
            MTB.SP.setCharPref(MTB.Pref, popupNode.id);
            window.addEventListener('click', MTB.MoveListener, true);
            window.addEventListener('mouseup', MTB.DefaultPrevention, true);
            window.addEventListener('mousedown', MTB.DefaultPrevention, true);
            window.addEventListener('contextmenu', MTB.DefaultPrevention, true);
            MTB.HidePopup(aE.target);
            MTB.ShowMoveAlert && Services.prompt.alert(null, self.name,
                "Now click ANY toolbarbutton element inside ANY toolbar.\n" +
                "Left click will position the button to the left of the target.\n" +
                "Right click will position the button to the right of the target.\n\n" +
                "To cancel the movement, just click ANY element inside the browser that IS NOT a toolbarbutton.\n");
        }
    },

    MoveListener: function(aE) {
        MTB.DefaultPrevention(aE);
        window.removeEventListener('click', MTB.MoveListener, true);
        window.removeEventListener('mouseup', MTB.DefaultPrevention, true);
        window.removeEventListener('mousedown', MTB.DefaultPrevention, true);
        window.removeEventListener('contextmenu', MTB.DefaultPrevention, true);
        var anchor = aE.target;
        if (anchor.tagName !== "toolbarbutton")
            return;
        var toolbar = anchor.parentNode;
        var BtnToMove = document.getElementById(MTB.SP.getCharPref(MTB.Pref));
        if (aE.button === 0 && !aE.shiftKey && !aE.ctrlKey && !aE.altKey)
            toolbar.insertBefore(BtnToMove, anchor);
        else if (aE.button === 2 && !aE.shiftKey && !aE.ctrlKey && !aE.altKey)
            toolbar.insertBefore(BtnToMove, anchor.nextSibling);
        if ("CustomizableUI" in window)
            custombuttons.persistCurrentSets(toolbar.id, anchor.id,
                BtnToMove.id || BtnToMove.getAttribute("id"), !(aE.button === 2));
        else {
            toolbar.setAttribute("currentset", toolbar.currentSet);
            document.persist(toolbar.id, "currentset");
        }
        MTB.SP.setCharPref(MTB.Pref, "");
    },

    DefaultPrevention: function(aE) {
        aE.preventDefault();
        aE.stopImmediatePropagation && aE.stopImmediatePropagation();
        aE.stopPropagation();
    },

    Tooltips: function(aRem) {
        var popSetID = MTB._UID + "popupset";
        var popSetEl = document.getElementById(popSetID);
        if (popSetEl)
            popSetEl.parentNode.removeChild(popSetEl);

        if (aRem)
            return;

        if (!popSetEl) {
            popSetEl = document.createElementNS(xulns, "popupset");
            popSetEl.setAttribute("id", popSetID);
        }

        popSetEl.appendChild(MTB.parseXML("<tooltip xmlns=\"" + xulns + "\" xmlns:html=\"" + xhtmlns +
            "\" id=\"" + MTB._UID + "moveButtonMI_tooltip" + "\">" +
            "<description><html:b>Instructions</html:b> : After clicking this menu item, you can " +
            "click ANY toolbarbutton element inside the application to place the currently " +
            "selected button to the left (with Left click) or to the right (with Right click) " +
            "of the targeted toolbarbutton.</description>" +
            "<separator/>" +
            "<description><html:b>Note</html:b> : It can be ANY toolbarbutton, not just " +
            "other Custom Buttons.</description>" +
            "</tooltip>"));

        setTimeout(function() {
            Array.prototype.slice.call(MTB.WindowIDs).forEach(function(aWinID) {
                let win = document.getElementById(aWinID);
                if (win)
                    !document.getElementById(popSetID) && win.appendChild(popSetEl);
            });
        }, 100);
    },

    parseXML: function(aXML) { // Return parsed XML
        aXML = aXML.replace(/>\s+</g, "><"); // Linearize XML
        return (new DOMParser).parseFromString(aXML, "application/xml").documentElement;
    },

    HidePopup: function(aEl) {
        try {
            aEl.hidePopup();
        } catch (aError) {
            try {
                aEl.parentNode.hidePopup();
            } catch (aError) {
                try {
                    aEl.parentNode.parentNode.hidePopup();
                } catch (aError) {
                    try {
                        aEl.parentNode.parentNode.parentNode.hidePopup();
                    } catch (aError) {}
                }
            }
        }
    }
};

this.MoveToolbarButtons.Init();

Отредактировано Andrey_Krropotkin (08-07-2019 09:34:09)

Отсутствует

 

№1347208-07-2019 10:41:09

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

Re: Custom Buttons

Andrey_Krropotkin
Спасибо, помогло отключение кнопок. Причиной была "неисправленная" кнопка, в коде которой было создание пункта контекстного меню.

Отсутствует

 

№1347308-07-2019 17:38:52

xrun1
Участник
 
Группа: Members
Зарегистрирован: 12-12-2013
Сообщений: 1160
UA: Firefox 67.0

Re: Custom Buttons

Andrey_Krropotkin
А в мультипроцессорном режиме кнопку, которую выкладывал Garalf, запустить нельзя? Я пробовал, не запускается. Или это потребует слишком кардинальных изменений в коде?

Отсутствует

 

№1347408-07-2019 19:16:40

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

Re: Custom Buttons

xrun1 а у нас тут даже почти примеров нет, как делать такие кнопки, поэтому даже не знаю, как править.

Отсутствует

 

№1347509-07-2019 00:27:31

xrun1
Участник
 
Группа: Members
Зарегистрирован: 12-12-2013
Сообщений: 1160
UA: Firefox 67.0

Re: Custom Buttons

Andrey_Krropotkin
Google Translate когда-то сделал Lex1, он же Алексей Рузанов, который перешёл на Firefox, когда умерла Opera Presto. Давно не видел его постов ни здесь, ни на руборде, но остался сайт как память с некоторыми кнопками. ;)

Отсутствует

 

Board footer

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