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

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

№1382625-10-2019 16:01:53

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

Re: Custom Buttons

Dumby

Dumby пишет

Так достаточно просто?

да все отлично, а можно еще условие туда засунуть item.hidden если аddon.homepageURL отсутствует (т.е. если нет домашней страницы - пункт не показывать.)

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

Выделить код

Код:

//Контекстного меню на странице  about:addons для addons..................................................................................................................
(lst => {
    addEventListener("shown", lst, true, gBrowser.tabpanels || 1);
    addDestructor(() => lst.item && lst.item.remove(lst.item = null));
})({
    //------------------------------------------------------------------
    "Копировать имя"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.name);
    },
    //------------------------------------------------------------------
    "Копировать ID"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.id);
    },
    //------------------------------------------------------------------
    "Копировать версию"(addon, hideOn) {
        if (hideOn) return ["custombuttons"];

        gClipboard.write(addon.version);
    },
    //------------------------------------------------------------------
        "Копировать имя и версию"(addon, hideOn) {
        if (hideOn) return ["custombuttons"];

        copyToClipboard(addon.name + " " + addon.version);
    },
    //------------------------------------------------------------------
        "Домашняя страница"(addon, hideOn) {
        if (hideOn) return ["custombuttons","theme"];

        var url = addon.homepageURL;
        if (!url) {
        if (addon.reviewURL) {
        url = addon.reviewURL.replace(/\/reviews\/.*$/, "/");
        } else {
        url = "https://addons.mozilla.org/search/?q="
            + encodeURIComponent(addon.name);
         }
        }
       openURL(url);
    },
    //------------------------------------------------------------------
        "Папка установки"(addon, hideOn) {
        if (hideOn) return ["custombuttons","theme","plugin"];

                    switch (addon.type) {
                    case "plugin":
                    var pathes = addon.pluginFullpath;
                    for (var i = 0; i < pathes.length; i++) {
                        this.revealPath(pathes[i]);
                    }
                    return;
                case "userchromejs":
                    var file = addon._script.file;
                    if (file.exists())
                        file.reveal();
                    return;
            }

            var gecko = parseInt(Services.appinfo.platformVersion);
            var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", (gecko >= 14) ? "nsIFile" : "nsILocalFile",
                "initWithPath");

            var dir = Services.dirsvc.get("ProfD", Ci.nsIFile);
            dir.append("extensions");
            dir.append(addon.id);
            var fileOrDir = dir.path + (dir.exists() ? "" : ".xpi");

            try {
                (new nsLocalFile(fileOrDir)).reveal();
            } catch (ex) {
                var addonDir = /.xpi$/.test(fileOrDir) ? dir.parent : dir;
                try {
                    if (addonDir.exists()) {
                        addonDir.launch();
                    }
                } catch (ex) {
                    var uri = Services.io.newFileURI(addonDir);
                    var protSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
                    getService(Ci.nsIExternalProtocolService);
                    protSvc.loadUrl(uri);
                }
            }
    },
    //------------------------------------------------------------------
        "Файл установки"(addon, hideOn) {
        if (hideOn) return ["custombuttons","theme","plugin"];

            var gecko = parseInt(Services.appinfo.platformVersion);
            var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", (gecko >= 14) ? "nsIFile" : "nsILocalFile",
                "initWithPath");
            var dir = Services.dirsvc.get("ProfD", Ci.nsIFile); 
                        dir.append('extensions');
                        dir.append(addon.id);
                            if ( dir.exists() ) dir.launch();
                            var file = Components.classes['@mozilla.org/file/directory_service;1']
                                      .getService(Components.interfaces.nsIProperties)
                                     .get('ProfD', Components.interfaces.nsIFile);
                            file.append('extensions');
                            file.append( addon.id + '.xpi' )
                            if ( file.exists() ) file.launch(); 
                            return;
    },
    //------------------------------------------------------------------
    url: "chrome://mozapps/content/extensions/aboutaddons.html",
    handleEvent(e) {
        if (e.target.baseURI != this.url) return;
        var item = this.getItem(e.target.ownerDocument);
        var type = e.target.closest("addon-list").getAttribute("type");

        for(var child of item.children) {
            var res = this[child.textContent](null, type);
            child.hidden = res && res.includes(type);
        }
        e.target.contains(item) || requestAnimationFrame(
            () => e.target.prepend(item)
        );
    },
    item: null,
    getItem(doc) {
        if (this.item) {
            if (this.item.ownerDocument == doc) return this.item;
            this.item.remove();
        }
        var item = doc.createElement("div");
        item.onclick = e => {
            e.stopPropagation();
            item.parentNode.hide();
            this[e.target.textContent](
                e.target.closest("addon-card").addon
            );
        }
        for(var lab of this.labels) item.appendChild(
            doc.createElement("panel-item")
        ).append(lab);
        return this.item = item;
    },
    get labels() {
        delete this.labels;
        return this.labels = Object.entries(this).map(
            ([key, val]) => String(val).startsWith('"') && key
        ).filter(Boolean);
    }
});


А по второму вопросу в том же посте не подскажите?
Или наверно повторюсь: вопрос по кнопке. Пункты списка 1,2 при на нажатии кнопку Add-on открываются нормально, а начиная с третьего и далее открывается как пункт 2
скрытый текст

Выделить код

Код:

/*CODE*/
var hid = false; //false - скрыть скрытые адоны, true - показать скрытые адоны

var br = gBrowser;
var img2 = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAABwWjpocFs8zHFbPP9xWzz/cVs8/3FbPP9xWzz/cVs8/3FbPP9xWzz/cVs8/3FbPP9xWzz/cVs8/3BbPMxwWjpodWBB4bWwqv/o6Oj/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+fn5//n5+f/5+fn/+rq6v+1sKr/dWBB4XtlR//f39//6Ojo/8e7q/+0oIf/po1t/6aNbf+mjW3/po1t/6aNbf+mjW3/po1t/+rq6v/s7Oz/39/f/3tlR/+Ba07/29vb/+fn5//f39//3Nzc/9nZ2f/Z2dn/2dnZ/9nZ2f/Z2dn/2dnZ/9nZ2f/l5eX/5+fn/9vb2/+Ba07/h3FV/9bW1v/k5OT/5OTk/+Dg4P+bhGb/k3hX/5N4WP+TeFf/m4Rm/+Dg4P+WfF3/rp2H/+Dg4P/U1NT/h3FV/454XP/Z2dn/5+fn/+Pj4//j4+P/ysK3/8nCtv/Jwrb/xr2w/8e9sP/d29j/2NjY/5d9Xv+vnon/1dXV/454XP+UgGP/3Nzc/+rq6v/m5ub/lHlY/5d8XP+dhmf/lXpa/5R5WP+dhmf/uqyb/+bm5v+UeVj/r56I/9jY2P+UgGP/m4dr/97e3v/t7e3/6enp/93d3f/d3d3/3t7e/yOC5P+AsOD/3t7e/+Pj4/+lkHX/rp6J/+Li4v/c3Nz/m4dr/6KNc//h4eH/8PDw//Dw8P/w8PD/7Ozs/zKK6f/h4eH/C3To/+zs7P/s7Oz/4+Pj/+bm5v/u7u7/4eHh/6KNc/+olHr/5OTk//Pz8//z8/P/8/Pz//Dw8P8Seen/8PDw/xJ56f8Seen/8PDw//Dw8P/z8/P/8/Pz/+Tk5P+olHr/r5uC/+fn5//29vb/9vb2//b29v/z8/P/lL3o/xl96f/n5+f/grTo/yWE6v/z8/P/9vb2//b29v/n5+f/r5uC/7Whif/p6en/+fn5//n5+f/5+fn/+fn5//Dw8P+JuOr/JYXr/+/v7/+60ev/9fX1//n5+f/5+fn/6enp/7Whif+6p5D/7Ozs//v7+//7+/v/+/v7//v7+//6+vr/8/Pz/4y77f83juz/9fX1//v7+//7+/v/+/v7/+zs7P+6p5D/v6yW/+3t7f/8/Pz//f39//39/f/9/f3//f39//z8/P/09PT/xNnw//r6+v/9/f3//f39//z8/P/t7e3/v6yW/8Owm8ze2tX/9fX1//f39//39/f/9/f3//f39//39/f/9/f3//T09P/39/f/9/f3//f39//19fX/3trV/8Owm8zGsp9oyLWezMi1n//ItZ//yLWf/8i1n//ItZ//yLWf/8i1n//ItZ//yLWf/8i1n//ItZ//yLWf/8i1nszGsp9oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="; 
var img1 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAmlJREFUeNpsU0toU0EUPfPysx/tTxuDH9SCWhUDooIbd7oRUUTMouqi2iIoCO6lceHWhegy4EJFinWjrlQUpVm0IIoFpVDEIthm0dpikpf3ZuZ6Z94nrXhhMjM3c8895977BBHB2PznK8WPtDgyWH5q77cPH8PpdXuhpQT4ifR9u5sfJb1bmw6VivahATDrxcRZ2njfoaMv+2j7mLDn93MPiNRMvGbL18L9IpF8h9/TN+EYkMffSiOXJ5+hkD+PdqcLpICWHOHc2CC+LEyA/K+cKQMnlQHJX8wqYG3MAJy88Wa4OLDvEqAEOpJd0LxHIMdHBziowSwVlF8D6QaicK01krw/JynwcKoEwZczewroTvZirlKJs5CqQ5CG8pb57FnJUA0LYCXMX5fibd+p8LWDDemcPZbzQyjvH+Ki1TlIciElA7ghwLKV4kRZstt2sANWRjYTAGzuP2hXZFpJ/GsxgGJ0ox1aoFWsDXyyxqCs26+ydmagFN/rRjymJ1898bzGzmQE0HCZpmk5A0RFIv8Pn0WYPsiu6t/Rsj6PauVTwffTSzGAGZhUG2F06hEc9ibS7OPMNp6ErYFlKavo7MkhmTqCxZ/jwzGA9Hx82H2BZSw1NTN9Gx8ycHkajU/7M+jInsDC7DiaEmo1bNl1AMr9ASFgqVu9MCTIzoGUimXVAnnaN0PdBBDCCYbEtMk6wkpQwIG0sn0PQIUF4GsTwLSIFKNqF6DVrQq+IWVrQDxAYQC/1SsYOI4pOxKZrfifiUSbDUisif7XlpGIPufXd/uvdvZm760M0no1FZcnrzUdjw7au3vu/BVgAFLXeuTxhTXVAAAAAElFTkSuQmCC";
var trigger, trigger1, dialog, drives, count;
var icon1 = "data:image/png;base64,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";
var icon2 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACa0lEQVR42oWTXUhTYRjH/+/50H1mZ/kRs5WstTKCcsFiTIVYUETUneAupEAqwSuD2obJokS78WawLrppu+uiSymCwFr2ceEcQoWM/MjK2odzNfd1ds7pbKCo2Py/HHh5nuf9v7/znOcQrKvP0sY1NPgMXJOdpiiRgCQAIsqZ2qxY4BZXlmdyyfR1+Kc+YpPIxu72mYtWm328y3IOGqpWzpCNgoV8AoHpF8XU1+/OnOvls50NZOked30622ZrtXBGoqBYSPLKCEWE5qbzodDEg+L9N8PYJrI9oAt0xy+1ddaf0BhQhIDX32YwEZp4wt99dQ07iGiGL3hMzS23GImUqQWVsYkz6wyMSdWIoiTg7coslheW0sKffOlHfDm46hof2GJwyO+MOh1XTJxCAwZU5SmKJZQksVKQD06hmoje1zVrs9nMsZ+/0cDppMONBqKU3z/B/0V07Rfs4wX09PTseDgYDILU3HP0quu0/alYclS9V9t92ma9rFGpEUnNI5ZJYTBytGJQLt6s9RiBy27B6GS4Eh3q9NWdaunnlRSy2SzAUvCGj1Un2BIZ7PDjYF0f9inl8WHAsCwG3xt3IXC390KSwhUKT/sjGPbchF4LSlkLDa3AQEi/C8GIY46oaiRpNbcENXsEzVo9WBpE/qw1NAP3jLk6ARk7/5k9vr+1lC1ALPCQaYD51HNk+AhoAi/jcFcloIc6MqL1gFqi5HbwAhCXmxdNXsXDd4FykdfrlaoSUHccomivJ2AZ+UIKdLYE/kvsqZRcu4GxD+l1g//3wNMZhYo2leeYVH4OApEX0ijwJzEyuVg2qDaJ/wCoeQGVklbGmAAAAABJRU5ErkJggg==";
var icon3 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAB3RJTUUH1wcREBAg9OD7NAAAAAlwSFlzAAAewQAAHsEBw2lUUwAAAARnQU1BAACxjwv8YQUAAAH6SURBVHjaxVNBaxNBFP4mGRNp06bSaGu9qXhRLOSQX6Dg0d48SMWC4Mmbv8AfYA7Sgp6UgteCF29CKahBsKKWglgam4rRxGxiks3u7Mz6zZIlSVHRk7N8vLcz7/vemzczwP8eorSCgtLJJeXpUGtMBQHgK5RptxbuYJUx5o8CL5bx+OzCkyuZ2cLIwtPihbVW9a1GiCyFQyusFD4S2zfv4x5DtI2TAphOZk8zbXFE4NKt5ctInDmY8OLd6zNrtI+IlhURG0Xs55dezZXXF9Gq7CA9NQvNbAH19W/wo+6gWXeaN1aQkybEXLv2Bb36Z+SvfUAynYLgB9Y+GLEv6Sl4HTdcvX0yy4kZqdkit1nFWC4Pme4ydvMXxNiOwwTfIVP5OCBlK0Cv8Y4C5xnXYM+bB0ixTwjWHwpUdzbh+ijZSWlYQefrcxwrLJJcIZxRAWM33qP1KTCOwJ9ErbyLno8trvqRgOrsITV5ik6pT2IXvbZdINmjVr8CmYMx09h7/8wKMBtUtIWgu4/DE8e5lxob4pLsDkhhvxJrjYfE2Am065/Et1ZUQRAJTBxJIDQJZrgKZDiRwYA03AlxCF1Ho92oYGM7ElCS5/qmVjXzLx+cg71tMex5D/8Pw+ng4etd2GYpER0ucJRI26v9l2/Ivg82CI2YIP+BPCyifwI91AzKs/qQkQAAAABJRU5ErkJggg==";
var icon4 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC5UlEQVR4AWIgFvxfaXzz/0tNC5wKbgpHCINoS9V+NW2TpVNlnPfc5Q0CsEkOwHItURRd3bfHeBh927Zt27Zt27Zt2/6xbdvJWFcnj8Xsqo1C42Ccw/mLnfNeeH2R5PcRWbG/J7+vcbC8GE3QAwPQP3L1DsnwlAcOWOv+waVg5F4dMdbu2Un8GlwX0nHO3vazHDoOGC07b/aHBEb8CLVj6MXw1HmvLVzvAJm89V7S/9B9ZdGV68gD11wtXLZcuNuW/kN2FckfIFI4usOPFn/5/iITEqcC6J+514St8oGpQIFNkovYIzORXNtinFqMtSOLwFJ8u+BQ8GaC73fQQ/lh3OSGnwDokGlc2GrVN7KUB6EOht0O+jyg3mHM2oegFTw1+UpmLbfBng6uB56L0SktY7IPGaPdcy3toZSA6WHQ46PQnlw//gH8lAtWis2//JvZh+9Btr0AZmPwBJHYZUZgNQEAXE8zc0GafrVdeWHFqdTDFqgKEKPhtXHmH0/z567nQ6YOwY1QEmyzzmLfO1LRZbF4sMw8FUJ8xZ+lrRhd3gwU4AtuE6RappavcdPun4LTBBtwLWVsLzSy6YYPdf0AKa9B3FR5eLtP2d8fQm7tEuGsx3V97qXvzDXZev3hEADyAAUQ3zXAwIqdOLTjEhJ2HQlAOZ9g69XmsrCU5LVhR7F0oZAsTOS+8z+CAlADxAWKX2vgg0K9zS3bCTw7gCobwhXNp/225+5PjqfvoAxru/34+pzn2CM1HfJAHSh7QrlxJQAdu/DIuNazpbje3iKbbS1y4PoiZ2dFboqJPKFFXkXk3Q6+38O3EP/JUAlAAwB3L6qs8cPyWoa6HYXFHVwQg/lxmJPoyGFYoiEPrFAdNL5fCJ4BoIDeX5hkuHD/2i0zb8vGFutIsAbpOrQ1oMWGmEPNMYgEh8WilUPVy8UVrAp9Q9dtOCNzwtPFdfee4G6yXVO23kLslbNU/v3cSvHRZVOdcnT1ADucXxaSvokQAAAAAElFTkSuQmCC";
var icon5 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAFBhaW50Lk5FVCB2My41LjenhJ3MAAACvklEQVQ4T2NgQAL///9nA2LpusbW2PDoxKYFi5baA/k8yGrwsoGKRexdvJbxiyv8F5XX+C8kLv/21avXyqQYIKmmbXRFxdD6v7aVy39+Udnvd+/e1wIazIjTEKAkBxBLAbEyEBv1TZzaIKGo+V9O0+h/YmrWbJAYEMsBsRJUHSeKYSA/axqYX1fTNbkHwkoaBs90gLYbOfr8B/Ed3Hz2mtu6HIPK3waql4EZAGSzMAAJDVll7a9mroH/QdjCI/i/nX80GIP4+jZu/w3tPcFsBXX990D1akgGcIAM0JZT0/1r4R7438Y77L9zSAJWbOcb+V/T0OIFyEKot7mBNBfIAAWgFz7auXhdMLZyeGBs5/7fIzIFAzsFxfw3NLd7BlTv0DNhSkxyRm77pStXdUAG8CxdsRoUUKpfv35zMrV1eeYRnvTfLy4LBfvGZv7XMrL8nZZTuFTbyPKnmaPXfzefoFMgA0BOkYWGtJm7f+g5j7CE/8HJeRjYLzbjv5138H8QHRCf9d/YxukjyAB5c3u3r3GpWdvTc4vWmtg4/41IL/ofkVGMgZ39w/+D5B19Qv57RyT9d3D3ewaOBVtX788+kcn/vcIT/kdmlPz3BtKeoXH/QQbF5FSAcVRW2X9rF6/vnz59jqxubJ3oFxZ9pXfStEyQAaqeQeHPorNK/ycWVP+3c/f9m1tSsb6kqn65q2/w2+jMEqB4zf/4vKr/Dp7+34HqDYBYEIjFgZgXZIBiWHzKFZDCSKCNUckZZ4BipkCs09DWNdc/JuV/SkkDGDv5BP9/8OixBVCOCZ4aQSYlZxccDI5P/x+WnPPfJyzm7eOnz0BxLRmekHodJA7CfpFAbwVH/Z+9YIkfOAUipSbOdZu22ta3dfWV1zevyiwsW/Hq9RtQ3uDrnTw9ASg+qbGjZ8rM+YsKt+7c4wx1PtwFACct2zZrCHmoAAAAAElFTkSuQmCC";

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="Firefox Explorer" 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 image="' + icon2 + '" label=" Add-on" oncommand="self.addon(event)" tooltiptext="Ctrl+ = Без закрытия диалога"/>';
    data +=       '<button image="' + img2 + '" label=" 1 omni.ja" oncommand="self.omni(event)" tooltiptext="Ctrl+ = Без закрытия диалога"/>';
    data +=       '<button image="' + img2 + '" label=" 2 omni.ja" oncommand="self.omni1(event)" tooltiptext="Ctrl+ = Без закрытия диалога"/>';
    data +=       '<button image="' + icon4 + '" label=" Firefox" oncommand="self.folder(event,' + "'GreD'" + ')" tooltiptext="Ctrl+ = Без закрытия диалога"/>';
    data +=       '<button image="' + icon3 + '" 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 image="' + icon1 + '" 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) { 
            if (addon.hidden == false || addon.hidden == hid) {
            list.push(addon);
                }
        });

        function key(addon) {
           return addon.name.toLowerCase();
            }

        list.sort( function( a, b){
                        var ka = key(a);
                var kb = key(b);
                return ka == kb ? 0 : ka < kb ? -1 : 1;
            });

    var {document} = dialog;
  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 url = "data:application/vnd.mozilla.xul+xml;text/plain," + encodeURIComponent(intf(drives, count));
if (parseInt(Services.appinfo.platformVersion) >= 69 && Services.appinfo.browserTabsRemoteAutostart) {
    var chromeURL = `chrome://custombuttons/content/cbdialog${Date.now()}.xul`;
    Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup).registerChrome(
        Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)), [["override", chromeURL, url]]
    );
    url = chromeURL;
}
var feature = "chrome,centerscreen,width=580,height=410,alwaysRaised";
dialog = window.openDialog(url, "", feature);

Отредактировано Andrey_Krropotkin (25-10-2019 16:33:40)

Отсутствует

 

№1382725-10-2019 16:56:08

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

Re: Custom Buttons

Dumby
Так в 71b CB работает или нет?

Отсутствует

 

№1382825-10-2019 19:34:52

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

Re: Custom Buttons

Andrey_Krropotkin пишет

а можно еще условие туда засунуть item.hidden если аddon.homepageURL отсутствует (т.е. если нет домашней страницы - пункт не показывать.)

Можно, наверно

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

Выделить код

Код:

(lst => {
    addEventListener("shown", lst, true, gBrowser.tabpanels || 1);
    addDestructor(() => lst.item && lst.item.remove(lst.item = null));
})({
    //------------------------------------------------------------------
    "Копировать имя"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.name);
    },
    //------------------------------------------------------------------
    "Копировать ID"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.id);
    },
    //------------------------------------------------------------------
    "Копировать версию"(addon, hideOn) {
        if (hideOn) return ["custombuttons"];

        gClipboard.write(addon.version);
    },
    //------------------------------------------------------------------
    "Домашняя страница"(addon, hideOn) {
        if (hideOn) return !addon.homepageURL;

        alert(addon.homepageURL);
    },
    //------------------------------------------------------------------
    url: "chrome://mozapps/content/extensions/aboutaddons.html",
    handleEvent(e) {
        if (e.target.baseURI != this.url) return;
        var item = this.getItem(e.target.ownerDocument);
        var addon = e.target.closest("addon-card").addon;
        
        for(var child of item.children) {
            var res = this[child.textContent](child.addon = addon, true);
            child.hidden = Array.isArray(res)
                ? res.includes(addon.type) : res;
        }
        e.target.contains(item) || requestAnimationFrame(
            () => e.target.prepend(item)
        );
    },
    item: null,
    getItem(doc) {
        if (this.item) {
            if (this.item.ownerDocument == doc) return this.item;
            this.item.remove();
        }
        var item = doc.createElement("div");
        item.onclick = e => {
            e.stopPropagation();
            item.parentNode.hide();
            this[e.target.textContent](e.target.addon);
        }
        for(var lab of this.labels) item.appendChild(
            doc.createElement("panel-item")
        ).append(lab);
        return this.item = item;
    },
    get labels() {
        delete this.labels;
        return this.labels = Object.keys(this).filter(
            key => String(this[key]).startsWith('"')
        );
    }
});

Andrey_Krropotkin пишет

начиная с третьего и далее открывается как пункт 2

Вот так, вроде, помогает

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

Выделить код

Код:

box.appendChild(item).addon = addon;
          //box.focus();
           }
          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 item1 = dialog.document.querySelector("richlistitem[current]");

Garalf пишет

Так в 71b CB работает или нет?

Разумеется нет. Интересно, в эти последние времена,
такое вообще бывало, чтобы после прохождения Nightly-цикла,
CB, без обновления, продолжал бы работать на новорожденной бете?

Как обычно, в Merge Date, подготовил новую версию.
Открываю anonfile.com и вижу, что он переметнулся.
Другой сервис, подобный такому, как этот (был), мне не известен.
Таким образом, я иду лесом, выложить некуда.

Отредактировано Dumby (25-10-2019 19:39:24)

Отсутствует

 

№1382925-10-2019 19:42:36

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

Re: Custom Buttons

Dumby
А, это?https://www.upload.ee/
Хотя, смысл? Судя по 70, эта такая же лажа будет...

Отсутствует

 

№1383025-10-2019 20:12:26

bunda1
Moderator
 
Группа: Moderators
Откуда: Латвия
Зарегистрирован: 09-02-2010
Сообщений: 4811
UA: Firefox 60.0

Re: Custom Buttons

Dumby пишет

Другой сервис, подобный такому, как этот (был), мне не известен.
Таким образом, я иду лесом, выложить некуда.

Может выложи без трекера на torrent тут, а народ будет сидировать.

Отсутствует

 

№1383125-10-2019 22:21:17

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

Re: Custom Buttons

Dumby спасибо.
Дополнительные пункты контекстного меню на странице  about:addons для аддонов, плагинов, тем, CB

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

Выделить код

Код:

/*Initialization Code*/ 
//Дополнительные пункты контекстного меню на странице about:addons для аддонов, плагинов, тем, CB..................................................................................................................
(lst => {
    addEventListener("shown", lst, true, gBrowser.tabpanels || 1);
    addDestructor(() => lst.item && lst.item.remove(lst.item = null));
})({
    //------------------------------------------------------------------
    "Копировать имя"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.name);
    },
    //------------------------------------------------------------------
    "Копировать ID"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.id);
    },
    //------------------------------------------------------------------
    "Копировать версию"(addon, hideOn) {
        if (hideOn) return ["custombuttons"];

        gClipboard.write(addon.version);
    },
    //------------------------------------------------------------------
        "Копировать имя и версию"(addon, hideOn) {
        if (hideOn) return ["custombuttons"];

        copyToClipboard(addon.name + " " + addon.version);
    },
    //------------------------------------------------------------------
        "Домашняя страница"(addon, hideOn) {
        if (hideOn) return !addon.homepageURL;

        var url = addon.homepageURL;
        if (!url) {
        if (addon.reviewURL) {
        url = addon.reviewURL.replace(/\/reviews\/.*$/, "/");
        }
        }
       openURL(url);
    },
    //------------------------------------------------------------------
        "Поиск на АМО"(addon, hideOn) {
        if (hideOn) return ["custombuttons","theme","plugin"];

        var url = addon.homepageURL;
        if (!url) {
        url = "https://addons.mozilla.org/search/?q="
            + encodeURIComponent(addon.name);
        }
       openURL(url);
    },
    //------------------------------------------------------------------
        "Папка установки"(addon, hideOn) {
        if (hideOn) return ["custombuttons","theme","plugin"];

                    switch (addon.type) {
                    case "plugin":
                    var pathes = addon.pluginFullpath;
                    for (var i = 0; i < pathes.length; i++) {
                        this.revealPath(pathes[i]);
                    }
                    return;
                case "userchromejs":
                    var file = addon._script.file;
                    if (file.exists())
                        file.reveal();
                    return;
            }

            var gecko = parseInt(Services.appinfo.platformVersion);
            var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", (gecko >= 14) ? "nsIFile" : "nsILocalFile",
                "initWithPath");

            var dir = Services.dirsvc.get("ProfD", Ci.nsIFile);
            dir.append("extensions");
            dir.append(addon.id);
            var fileOrDir = dir.path + (dir.exists() ? "" : ".xpi");

            try {
                (new nsLocalFile(fileOrDir)).reveal();
            } catch (ex) {
                var addonDir = /.xpi$/.test(fileOrDir) ? dir.parent : dir;
                try {
                    if (addonDir.exists()) {
                        addonDir.launch();
                    }
                } catch (ex) {
                    var uri = Services.io.newFileURI(addonDir);
                    var protSvc = Cc["@mozilla.org/uriloader/external-protocol-service;1"].
                    getService(Ci.nsIExternalProtocolService);
                    protSvc.loadUrl(uri);
                }
            }
    },
    //------------------------------------------------------------------
        "Файл установки"(addon, hideOn) {
        if (hideOn) return ["custombuttons","theme","plugin"];

            var gecko = parseInt(Services.appinfo.platformVersion);
            var nsLocalFile = Components.Constructor("@mozilla.org/file/local;1", (gecko >= 14) ? "nsIFile" : "nsILocalFile",
                "initWithPath");
            var dir = Services.dirsvc.get("ProfD", Ci.nsIFile); 
                        dir.append('extensions');
                        dir.append(addon.id);
                            if ( dir.exists() ) dir.launch();
                            var file = Components.classes['@mozilla.org/file/directory_service;1']
                                      .getService(Components.interfaces.nsIProperties)
                                     .get('ProfD', Components.interfaces.nsIFile);
                            file.append('extensions');
                            file.append( addon.id + '.xpi' )
                            if ( file.exists() ) file.launch(); 
                            return;
    },
    //------------------------------------------------------------------
    url: "chrome://mozapps/content/extensions/aboutaddons.html",
    handleEvent(e) {
        if (e.target.baseURI != this.url) return;
        var item = this.getItem(e.target.ownerDocument);
        var addon = e.target.closest("addon-card").addon;
        for(var child of item.children) {
            var res = this[child.textContent](child.addon = addon, true);
            child.hidden = Array.isArray(res)
                ? res.includes(addon.type) : res;
        }
        e.target.contains(item) || requestAnimationFrame(
            () => e.target.prepend(item)
        );
    },
    item: null,
    getItem(doc) {
        if (this.item) {
            if (this.item.ownerDocument == doc) return this.item;
            this.item.remove();
        }
        var item = doc.createElement("div");
        item.onclick = e => {
            e.stopPropagation();
            item.parentNode.hide();
            this[e.target.textContent](e.target.addon);
        }
        for(var lab of this.labels) item.appendChild(
            doc.createElement("panel-item")
        ).append(lab);
        return this.item = item;
    },
    get labels() {
        delete this.labels;
        return this.labels = Object.keys(this).filter(
            key => String(this[key]).startsWith('"')
        );
    }
});

Отсутствует

 

№1383226-10-2019 14:33:05

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

Re: Custom Buttons

solombala пишет

А, это?https://www.upload.ee/

upload.ee пишет

ERROR: Javascript must be allowed.

bunda1 пишет

Может выложи без трекера на torrent

Да, звучит логично, но полностью противоречит моей вздорной позиции.


Вобщем, решил выложить кодом.
Требуется: наличие на диске xpi-файла CB 0.0.7.0.0.6
(в смысле один из этих).
xpi должен быть расположен в хорошей папке, такой,
где лисе будут позволительны файловые операции.

Как задумано: запускаем код, откроется диалог выбора файла,
выбираем xpi, и код запишет рядом новую версию CB 0.0.7.0.0.7
Ну, надеюсь, запишет.

CB-0.0.7.0.0.{6-7}-fx.js

Выделить код

Код:

(async re => {
    var gzip = "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";

    var s = (path, name, def) => {try {
        return Services.strings.createBundle(`chrome://${path}.properties`)
            .GetStringFromName(name);
    } catch(ex) {return def;}}
    var picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
    var title = s("global/locale/commonDialogs", "Select", "Select") + " CB 0.0.7.0.0.6";
    picker.init(window, title, picker.modeOpen);
    var filter = s("mozapps/locale/extensions/extensions", "installFromFile.filterName", "Add-ons");
    picker.appendFilter(filter, "*.xpi");
    await new Promise(resolve => picker.open(resolve));
    var {file} = picker; if (!file) return;
    var ln = file.leafName;
    if (!re.test(ln)) return alert("???\n" + ln);
    var {fileURL} = picker;

    var xpi = file.parent.clone();
    xpi.append(ln = ln.replace("6-", "7-"));
    file.copyTo(file.parent, ln);

    var obs = {}, data;
    var td = new TextDecoder(), te = new TextEncoder();
    var scs = Cc["@mozilla.org/streamConverters;1"].getService(Ci.nsIStreamConverterService);
    var sis = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
    var sl =  Cc["@mozilla.org/network/stream-loader;1"].createInstance(Ci.nsIStreamLoader);

    sis.data = atob(gzip);
    obs.onStreamComplete = (a, b, c, d, result) => data = td.decode(new Uint8Array(result));
    sl.init(obs);
    var converter = scs.asyncConvertData("gzip", "uncompressed", sl, null);

    converter.onStartRequest(null, null);
    var args = [null, null, sis, 0, sis.data.length];
    if (converter.onDataAvailable.length == 4) args.shift();
    converter.onDataAvailable(...args);
    converter.onStopRequest(null, null, null);

    var zw = Cc['@mozilla.org/zipwriter;1'].createInstance(Ci.nsIZipWriter);
    var mt = Date.now() * 1000, cp = zw.COMPRESSION_DEFAULT;
    var bootstrap = ln.includes("bootstrap");
    var prefix = "jar:" + fileURL.spec + "!/";
    var lr = /^¦(?:\d+)?$/, sep1 = "£", sep2 = "¥";

    zw.open(xpi, 0x04); // PR_RDWR
    for(var item of data.split(sep1)) {
        var [entry, val] = item.split(sep2);
        if (bootstrap && (entry == "manifest.json" || entry == "startup.jsm")) continue;
        if (val == "+") {
            zw.addEntryDirectory(entry, mt, false); continue;
        }
        if (zw.hasEntry(entry)) {
            if (val.includes("¦")) {
                var lines = val.split("\n");
                var oldLines = (await (await fetch(prefix + entry)).text()).split("\n");
    
                lines.forEach((line, ind) => {
                    if (lr.test(line)) lines[ind] = oldLines[
                        line.length == 1 ? ind : +line.slice(1)
                    ];
                });
                val = lines.join("\n");
            }
            zw.removeEntry(entry, false);
        }
        var stream = Cc["@mozilla.org/io/string-input-stream;1"]
            .createInstance(Ci.nsISupportsCString);
        stream.data = String.fromCharCode(...new Uint8Array(te.encode(val)));
        zw.addEntryStream(entry, mt, cp, stream, false);
        stream.close();
    };
    zw.close(); xpi.reveal();
})(
    /^custom_buttons-0\.0\.7\.0\.0\.6-fx-(?:paxmod|bootstrap)\.xpi$/
);


И, немного банальностей про запуск кода
скрытый текст
Можно запустить из JS-терминала Консоли браузера
( devtools.chrome.enabled=true, Ctrl+Shift+J ).

Можно из Вэб-консоли на странице about:addons ( Ctrl+Shift+K ).

Можно из CB-кнопки ( вкладка Код ).

Можно, пока ещё не выпилили, запустить со Scratchpad'а
( devtools.chrome.enabled=true, Shift+F4, Окружение > Браузер
  или, лучше, открыть во вкладке:
  chrome://devtools/content/scratchpad/index.xul
)

Отсутствует

 

№1383326-10-2019 15:00:12

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

Re: Custom Buttons

Dumby
Спасибо! Записал с помощью кнопки.

Отсутствует

 

№1383426-10-2019 16:49:20

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

Re: Custom Buttons

Dumby
https://www.upload.ee/files/10644103/cu … p.rar.html
Хорошая вещь , но 71 кое-какие кнопки отвалились , там много чего отвалилось .... Зато 69 перестала падать...
Нужен код " Переключиться на последнюю использованную вкладку" Этот код не то...

скрытый текст
gBrowser.tabContainer.advanceSelectedTab(-1, true);

А нет возможности стилем заделать на кнопку: Hover и Active?

Отредактировано solombala (27-10-2019 11:33:26)

Отсутствует

 

№1383527-10-2019 13:25:38

Dook
Участник
 
Группа: Members
Зарегистрирован: 05-06-2016
Сообщений: 19
UA: Firefox 71.0

Re: Custom Buttons

Dumby
А есть способ на FF70 отключить подпись, но чтоб при этом устанавливались расширения без ID?

Отсутствует

 

№1383627-10-2019 15:08:36

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

Re: Custom Buttons

Dook пишет

А есть способ на FF70 отключить подпись, но чтоб при этом устанавливались расширения без ID?

Во-первых, расширений без ID в манфесте не бывает, только WebExtensions.

Если WebExtensions неподписан, то что мешает указать ID?
Ведь это всё равно значит либо писал сам,
либо изменил существующий подписанный.
То есть ответ будет в стиле «Совсем обленились!».

Правда есть вариант, что кто-то написал WebExtensions,
не указал в манфесте ID, не подписал, и предлагает к установке.
Это значит, что автор алень и не заботится о пользователях.
Следует, по возможности, указать ему на это.
Или, опять же, дописать ID в манифест самостоятельно,
это вовсе не сложная процедура.

А если WebExtensions подписан и не устанавливается,
то тогда совсем другое дело.
В этом случае, просьба предоставить примеры
(ссылки на такие WebExtensions).

Отсутствует

 

№1383727-10-2019 15:49:22

Dook
Участник
 
Группа: Members
Зарегистрирован: 05-06-2016
Сообщений: 19
UA: Firefox 71.0

Re: Custom Buttons

Dumby пишет

Правда есть вариант, что кто-то написал WebExtensions,
не указал в манфесте ID, не подписал, и предлагает к установке

именно этот вариант. И таких расширений в репозитарии куча. Первые попавшиеся:
https://addons.mozilla.org/ru/firefox/a … bextension
https://addons.mozilla.org/ru/firefox/a … che-button
https://addons.mozilla.org/ru/firefox/a … leaner-pro
Просто не удобно каждый раз для установки таких расширений переименовывать config.js и перезагружаться, а потом назад.

Отсутствует

 

№1383827-10-2019 17:50:31

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

Re: Custom Buttons

Dook пишет

именно этот вариант. И таких расширений в репозитарии куча.

Какой ещё репозитарий? Если имеется в виду AMO,
то там не может быть неподписанных WebExtensions,
а значит это никакой не «именно этот вариант».

Все трое, Cache Cleaner 0.1.1, Empty Cache Button 3.4 и Browser Cleaner Pro 0.1.0,
установились в релизный Firefox 70.0 сразу сходу и без проблем.
«RESOLVED WORKSFORME»

P.S.
Конфиг этот.
Но, так ли это всё важно, ведь приговор лисе
находится уже в стадии рассмотрения.
Это чисто формальная процедура, не знаю чего Крис
тянет резину за хвост, наверно занят чем-то.

Отсутствует

 

№1383927-10-2019 19:08:49

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

Re: Custom Buttons

Dumby
Можно эту кнопку заставить работать в многопроцессорном режиме?

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

Выделить код

Код:

// Двойным левым кликом на папке закладок добавлять закладку в папку закладок, от 09.05.2014
addEventListener("dblclick", function(e) {
    var target = e.originalTarget;
    if ( e.button !== 0 || !target._placesNode || !PlacesUtils.nodeIsFolder( target._placesNode ) ) return;
    var Host = window.gBrowser.selectedBrowser.contentWindow.location.hostname; Host = '[url]'+ Host +'[url]'; // выделение адреса
    var docTitle = ( content.document.title || gBrowser.mCurrentTab.label).substr(0, 60);    // ограничить длину имени закладки
    var folderId = PlacesUtils.getConcreteItemId( target._placesNode );
    var dirTitle = PlacesUtils.bookmarks.getItemTitle( folderId );
// не добавлять имя папки
        dirTitle = '';
    if (dirTitle.length > 0 ) { dirTitle = ' ['+ dirTitle +']' } else dirTitle = '';
    var parentFolderTitle = PlacesUtils.bookmarks.getItemTitle( folderId );
    var currentURI = Services.io.newURI( content.location, null, null );
    var selTxt = ''; var getSel = document.commandDispatcher.focusedWindow.content.document.getSelection().toString();
    if (getSel) selTxt = '[txt]:: ' + getSel + ' ::[txt]';
    Host = '';    // отключить жирный адрес справа от имени закладки
    PlacesUtils.bookmarks.insertBookmark( folderId, currentURI, 0, Host + docTitle + selTxt + dirTitle);
    var favicon = ( !!gBrowser.mCurrentTab.image ) ? gBrowser.mCurrentTab.image : "chrome://global/skin/icons/Portrait.png";
    window.show_tooltip(favicon, "Добавил в папку "+ dirTitle +":", docTitle, 7000);
});

Отсутствует

 

№1384028-10-2019 00:09:59

Dook
Участник
 
Группа: Members
Зарегистрирован: 05-06-2016
Сообщений: 19
UA: Firefox 71.0

Re: Custom Buttons

Dumby
Всё, спасибо, нашел у себя ошибку. sandbox_enabled не был прописан. Сорри

Отсутствует

 

№1384128-10-2019 10:15:47

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

Re: Custom Buttons

Garalf пишет

Можно эту кнопку заставить работать в многопроцессорном режиме?

Не, вот прям именно эту неохота, тем более описания нет.
Но могу попробовать набросать что-нибудь приблизительно аналогичное.

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

Выделить код

Код:

addEventListener("dblclick", {
    handleEvent(e) {
        if (this.skip(e)) return;

        var name = _id + ":SelectionForDblclickFolderBkm";
        messageManager.addMessageListener(name, this);
        addDestructor(() => messageManager.removeMessageListener(name, this));

        var url = "data:," + encodeURIComponent(`(fw => {
            Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
                .getFocusedElementForWindow(content, true, fw);
            sendAsyncMessage("${name}", fw.value.document.getSelection().toString());
        })({});`);

        var lfs = () => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false);
        this.handleEvent = e => this.skip(e) || lfs();
        lfs();
    },
    skip(e) {
        if (e.button) return true;
        var trg = e.target;
        var pn = trg._placesNode || (trg._placesView && trg._placesView.result.root);
        if (!pn) return true;
        var res = PlacesUtils.nodeIsFolder(pn);
        if (res) this.guid = PlacesUtils.getConcreteItemGuid(pn);
        return !res;
    },
    receiveMessage(msg) {
        var title = (gBrowser.contentTitle || gBrowser.selectedTab.label).slice(0, 60);
        if (msg.data) title += `[txt]:: ${msg.data} ::[txt]`;
        var url = gBrowser.currentURI.spec, index = 0;
        PlacesUtils.bookmarks.insert({url, title, index, parentGuid: this.guid});
    }
});

solombala пишет

Нужен код " Переключиться на последнюю использованную вкладку"

Я так понимаю, что это связано с «FlipClosetab приказал долго жить».
Если да, то лучше подправить расширение. Я скачал Flip Close Tab 1.2.0
и вижу, что там, вроде, ничего особо непоправимого быть не должно.
Вот, подпаял чуть-чуть bootstrap.js, можешь попробовать. Надеюсь Автор не будет против.

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

Выделить код

Код:

var {interfaces: Ci, utils: Cu} = Components;
Cu.import("resource://gre/modules/Services.jsm");

var flipclosetabStatic = {
    customjsm: false,
    initialized: false,
    get styleURI() {
        delete this.styleURI;
        return this.styleURI = Services.io.newURI("chrome://flip_close_tab/content/button.css", null, null);
    },
    get buttonStrings() {
        delete this.buttonStrings;
        return this.buttonStrings = Services.strings.createBundle("chrome://flip_close_tab/locale/button.properties");
    },
    get CustomizableUI() {
        delete this.CustomizableUI;
        var _CustomizableUI = null;
        try {
            _CustomizableUI = Cu.import("resource:///modules/CustomizableUI.jsm", {}).CustomizableUI;
        } catch(e) {
            try {
                _CustomizableUI = Cu.import("chrome://flip_close_tab/content/customizable.jsm", {}).CustomizableUI;
                this.customjsm = true;
            } catch(e) {}
        }
        return this.CustomizableUI = _CustomizableUI;
    },
    start: function(win) {
        var onLoad = () => {
            win.removeEventListener("load", onLoad);
            this.loadIntoWindow(win);
        };
        win.addEventListener("load", onLoad);
    },
    get loadIntoWindow() {
        delete this.loadIntoWindow;
        this.init();
        return this.loadIntoWindow = function(win) {
            var obj = new FlipCloseTab();
            obj.load(win);
            Object.defineProperty(win, "_Flip_Close_Tab_Prototype", {
                value: obj,
                writable: false,
                configurable: true,
                enumerable: false
            });
        };
    },
    init: function() {
        if (this.initialized || !this.CustomizableUI) return;
        this.initialized = true;
        var cWidget = {
            id: "f-flip-tabs",
            type: "custom",
            label: flipclosetabStatic.buttonStrings.GetStringFromName("f-flip-tabs.label"),
            tooltiptext: flipclosetabStatic.buttonStrings.GetStringFromName("f-flip-tabs.tooltip"),
            defaultArea: this.CustomizableUI.AREA_NAVBAR,
            onBuild: function(document) {
                var window = document.defaultView;
                flipclosetabStatic.stylifyButton(window, true);
                var toolbarbutton_0 = (document.createXULElement || document.createElement).call(document, "toolbarbutton");
                toolbarbutton_0.id = "f-flip-tabs";
                toolbarbutton_0.setAttribute("label", flipclosetabStatic.buttonStrings.GetStringFromName("f-flip-tabs.label"));
                toolbarbutton_0.setAttribute("tooltiptext", flipclosetabStatic.buttonStrings.GetStringFromName("f-flip-tabs.tooltip"));
                toolbarbutton_0.setAttribute("context", false);
                toolbarbutton_0.classList.add("toolbarbutton-1");
                toolbarbutton_0.classList.add("chromeclass-toolbar-additional");
                toolbarbutton_0.addEventListener("click", function(event) {
                    var gtBrowser = window.gBrowser;
                    if (event.button == 0) {
                        var old = gtBrowser.selectedTab;
                        var tabs = filterTabs(old.parentNode);
                        var last  = 0;
                        var prevTab = null;
                        tabs.forEach((tab)=> {
                            let s = +tab.getAttribute("flipselectedID");
                            if (s && s > last && old != tab) {
                                prevTab = tab;
                                last = s;
                            }
                        });
                        if (prevTab !== null) 
                        gtBrowser.selectedTab = prevTab;
                    } else if (event.button == 1) {
                        gtBrowser.removeAllTabsBut(gtBrowser.selectedTab);
                    } else if (event.button == 2) {
                        event.preventDefault();
                        event.stopPropagation();
                        gtBrowser.removeTab(gtBrowser.selectedTab);
                    }
                }, false);
                return toolbarbutton_0;
            }
        };
        if (this.customjsm) {
            this.CustomizableUI.addListener();
            cWidget.onloadStylePalette = function(window) {
                flipclosetabStatic.stylifyButton(window, true);
            };
        }
        try {
            this.CustomizableUI.createWidget(cWidget);
        } catch(e) {}
    },
    getWindowUtils: function(window) {
        var has = "windowUtils" in window &&
            window.windowUtils instanceof Ci.nsIDOMWindowUtils;
        return (this.getWindowUtils = has
            ? window => window.windowUtils
            : window => window.QueryInterface(Ci.nsIInterfaceRequestor)
                .getInterface(Ci.nsIDOMWindowUtils)
        )(window);
    },
    stylifyButton: function(window, stylify) {
        var method = stylify ? "loadSheet" : "removeSheet";
        try {
            this.getWindowUtils(window)[method](
                this.styleURI, Ci.nsIDOMWindowUtils.USER_SHEET
            );
        } catch(ex) {
            Cu.reportError(ex);
        }
    },
    uninit: function() {
        if (!this.initialized) return;
        try {
            this.CustomizableUI.destroyWidget("f-flip-tabs");
        } catch(e) {}
        if (this.customjsm) {
            this.CustomizableUI.removeListener();
            Cu.unload("chrome://flip_close_tab/content/customizable.jsm");
        }
        var windows = Services.wm.getEnumerator("navigator:browser");
        while (windows.hasMoreElements()) {
            var win = windows.getNext();
            if (win.QueryInterface) win = win.QueryInterface(Ci.nsIDOMWindow);
            try {
                if ("_Flip_Close_Tab_Prototype" in win) {
                    win._Flip_Close_Tab_Prototype.unload(true);
                    delete win._Flip_Close_Tab_Prototype;
                }
                this.stylifyButton(win);
            } catch(e) {}
        }
    }
};

var filterTabs = node => {
    var func = tab => !tab.hidden && !tab.closing;
    return (filterTabs = "from" in Array
        ? node => Array.from(node.getElementsByAttribute("flipselectedID", "*")).filter(func)
        : node => Array.filter(node.getElementsByAttribute("flipselectedID", "*"), func)
    )(node);
}

function FlipCloseTab() {
    this.gtBrowser = null;
    this.removeListeners = null;
    this.blurTab = null;
    this.eventTabClose = false;
}

FlipCloseTab.prototype = {
    load: function(win) {
        var gtBrowser = this.gtBrowser = win.gBrowser || win.getBrowser();
        var tabid = 1;
        var TabSelect = (event) => {
            var tab = event.target;
            tab.setAttribute("flipselectedID", tabid++);
        };
        var TabClose = (event) => {
            var old = event.target;
            if (!old.selected) return;
            var tabs = filterTabs(old.parentNode);
            var last  = 0;
            var prevTab = null;
            tabs.forEach((tab) => {
                var s = +tab.getAttribute("flipselectedID");
                if (s && s > last && old != tab) {
                    prevTab = tab;
                    last = s;
                }
            });
            if (prevTab !== null && !prevTab.closing)
                gtBrowser.selectedTab = prevTab;
        };
        gtBrowser.tabContainer.addEventListener("TabSelect", TabSelect, false);
        if ("_blurTab" in gtBrowser) {
            var blurTab = this.blurTab = gtBrowser._blurTab;
            gtBrowser._blurTab = function _blurTab() {
                var old = arguments[0];
                if (!old.selected) return;
                var tabs = filterTabs(old.parentNode);
                var last  = 0;
                var prevTab = null;
                tabs.forEach((tab) => {
                    var s = +tab.getAttribute("flipselectedID");
                    if (s && s > last && old != tab) {
                        prevTab = tab;
                        last = s;
                    }
                });
                if (prevTab !== null && !prevTab.closing) {
                    this.selectedTab = prevTab;
                    return;
                }
                return blurTab.apply(this, arguments);
            };
        } else {
            gtBrowser.tabContainer.addEventListener("TabClose", TabClose, true);
            this.eventTabClose = true;
        }
        this.removeListeners = function() {
            gtBrowser.tabContainer.removeEventListener("TabSelect", TabSelect, false);
            if (this.eventTabClose)
                gtBrowser.tabContainer.removeEventListener("TabClose", TabClose, true);
        };
        var sel = gtBrowser.selectedTab;
        if (sel && !sel.hidden)
            sel.setAttribute("flipselectedID", tabid++);
    },
    unload: function(shutdown = false) {
        this.removeListeners();
        if (shutdown) {
            if (this.blurTab !== null)
                this.gtBrowser._blurTab = this.blurTab;
            var tabs = filterTabs(this.gtBrowser.tabContainer);
            tabs.forEach((tab) => {
                tab.removeAttribute("flipselectedID");
            });
        }
    }
};

var WindowListener = {
    onOpenWindow: function(aWindow) {
        var win = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
        function onWindowLoad() {
            win.removeEventListener("load", onWindowLoad);
            if (win.document.documentElement.getAttribute("windowtype") == "navigator:browser")
                flipclosetabStatic.loadIntoWindow(win);
        }
        win.addEventListener("load", onWindowLoad);
    },
    onCloseWindow: function(aWindow) {
        var win = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
        if (win.document.documentElement.getAttribute("windowtype") == "navigator:browser" && "_Flip_Close_Tab_Prototype" in win)
            win._Flip_Close_Tab_Prototype.unload();
    },
    onWindowTitleChange: function(aWindow, newTitle) { }
};

function startup(data, reason) {
    var wm = Services.wm;
    var windows = wm.getEnumerator(null);
    while (windows.hasMoreElements()) {
        var win = windows.getNext();
        if (win.QueryInterface) win = win.QueryInterface(Ci.nsIDOMWindow);
        try {
            var type = win.document.documentElement.getAttribute("windowtype");
            if (type == "navigator:browser")
                flipclosetabStatic.loadIntoWindow(win);
            else if (type == "navigator:blank")
                flipclosetabStatic.start(win);
        } catch(e) {}
    }
    wm.addListener(WindowListener);
}

function shutdown(data, reason) {
    if (reason == APP_SHUTDOWN)
        return;
    flipclosetabStatic.uninit();
    Services.wm.removeListener(WindowListener);
}

function install(data, reason) { }

function uninstall(data, reason) { }

Отсутствует

 

№1384228-10-2019 11:20:52

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

Re: Custom Buttons

Dumby
Все ОК! Спасибо! Код работает

Отредактировано Garalf (28-10-2019 11:25:27)

Отсутствует

 

№1384328-10-2019 15:34:14

Vitaliy V.
Участник
 
Группа: Members
Зарегистрирован: 19-09-2014
Сообщений: 2074
UA: Firefox 71.0

Re: Custom Buttons

Dumby пишет

Надеюсь Автор не будет против.

Конечно не против, я к сожалению забросил старые расширения когда удалили поддержку bootstrapped extensions

Отредактировано Vitaliy V. (28-10-2019 15:34:36)

Отсутствует

 

№1384428-10-2019 15:47:35

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

Re: Custom Buttons

Dumby
Благодарочка! За FlipCloseTab
Такое дело, не ли возможности кнопкой сделать однооконный режим? Для 70 ...

Отредактировано solombala (29-10-2019 19:37:17)

Отсутствует

 

№1384529-10-2019 23:40:52

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

Re: Custom Buttons

Dumby в этой кнопке возможно ли добавить иконки для пунктов или какие нибудь атрибуты задать, чтобы бы через CSS  добавить иконки можно было.

Отсутствует

 

№1384631-10-2019 16:06:37

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

Re: Custom Buttons

Andrey_Krropotkin пишет

Dumby в этой кнопке возможно ли добавить иконки для пунктов

Вариант

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

Выделить код

Код:

((id, g, iconizer) => addDestructor(r => r[5] == "e" && id in g && g[id].destroy()) + addEventListener("shown", {
    //------------------------------------------------------------------
    "Копировать имя_i": "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ==",
    "Копировать имя"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.name);
    },
    //------------------------------------------------------------------
    "Копировать ID_i": "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AMgA/wDIAP8AyAD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ==",
    "Копировать ID"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.id);
    },
    //------------------------------------------------------------------
    "Копировать версию_i": "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ==",
    "Копировать версию"(addon, hideOn) {
        if (hideOn) return ["custombuttons"];

        gClipboard.write(addon.version);
    },
    //------------------------------------------------------------------
    "Домашняя страница"(addon, hideOn) {
        if (hideOn) return !addon.homepageURL;

        alert(addon.homepageURL);
    },
    //------------------------------------------------------------------
    url: "chrome://mozapps/content/extensions/aboutaddons.html",
    handleEvent(e) {
        if (e.target.baseURI != this.url) return;
        var item = this.getItem(e.target.ownerDocument);
        var addon = item.addon = e.target.closest("addon-card").addon;
        
        for(var child of item.children) {
            var res = this[child.textContent](addon, true);
            child.hidden = Array.isArray(res)
                ? res.includes(addon.type) : res;
        }
        e.target.contains(item) || requestAnimationFrame(
            () => e.target.prepend(item)
        );
    },
    click(e) {
        e.stopPropagation();
        iconizer.item.parentNode.hide();
        this[e.target.textContent](iconizer.item.addon);
    },
    getItem(doc) {
        if (iconizer.item) {
            if (iconizer.item.ownerDocument == doc) return iconizer.item;
            iconizer.handleEvent();
        }
        var item = doc.createElement("div");
        item.id = id;
        for(var lab of this.labels) item.appendChild(
            doc.createElement("panel-item")
        ).append(lab);
        
        item.onclick = this.click;
        doc.ownerGlobal.addEventListener("unload", iconizer);
        return iconizer.item = item;
    },
    get labels() {
        delete this.labels;
        this.click = this.click.bind(this);
        if (id in g) return this.labels = (iconizer = g[id]).labs;

        g[id] = iconizer;
        var css = "", ind = 0, arr = [];
        var push = (ind, icon) => {
            var chromeImg = `chrome://custombuttons/content/${id + ind}`;
            arr.push(["override", chromeImg, icon]);
            return chromeImg;
        }
        var labs = iconizer.labs = Object.keys(this).filter(key => {
            var res = String(this[key]).startsWith('"');
            if (!res) return false;
            ind++;
            var icon = this[key + "_i"];
            if (icon) css += `\n\t#${
                id
            } > panel-item:nth-child(${ind}) {\n\t\t--icon: url(${
                push(ind, icon)
            }) !important;\n\t}`;
            return true;
        });
        var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
        var mUri = Services.io.getProtocolHandler("resource").getSubstitution("custombuttons-modules");
        iconizer.iconHelper = ams.registerChrome(mUri, arr);

        var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
        var md = "@-moz-document url(chrome://mozapps/content/extensions/aboutaddons.html) {";
        var uri = Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(md + css + "\n}"));
        var args = [uri, sss.USER_SHEET];
        sss.loadAndRegisterSheet(...args);

        iconizer.handleEvent = function() {
            if (!this.item) return;
            this.item.ownerGlobal.removeEventListener("unload", this);
            this.item.remove();
            this.item = null;
        }
        iconizer.destroy = function() {
            delete g[id];
            this.handleEvent();
            sss.unregisterSheet(...args);
            this.iconHelper.destruct();
        }
        return this.labels = labs;
    }
}, true, gBrowser.tabpanels || 1))("CBAddonsMenuExt", Cu.import("resource://gre/modules/Services.jsm", {}), {});

Отсутствует

 

№1384731-10-2019 18:28:47

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

Re: Custom Buttons

Dumby спасибо, без замечаний.

Отсутствует

 

№1384801-11-2019 21:34:54

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

Re: Custom Buttons

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

Отсутствует

 

№1384901-11-2019 23:53:34

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

Re: Custom Buttons

Нет не в курсе

Отсутствует

 

№1385002-11-2019 00:36:34

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

Re: Custom Buttons

solombala пишет

стоит одну открыть и autopopup работает на все остальные

Думаю, за это отвечает PlacesToolbar.prototype._onMouseMove()

Открой: chrome://browser/content/places/browserPlacesViews.js
(%Install_Folder%\browser\omni.ja\chrome\browser\content\browser\places\browserPlacesViews.js)

Поиск: PT__onMouseMove

Можно проверить кодом для Инициализации

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

Выделить код

Код:

(node => addEventListener("mousedown", function md() {
    removeEventListener("mousedown", md, false, node);

    var res = Services.els.getListenerInfoFor(node)
        .find(inf => inf.listenerObject instanceof PlacesToolbar);

    var obj = res.listenerObject, key = "_openedMenuButton", n = () => null;
    Object.defineProperty(obj, key, {
        configurable: true, enumerable: true, get: n, set: n
    });
    addDestructor(() => obj[key] = delete obj[key] && null);

}, false, node || 1))(document.getElementById("PlacesToolbarItems"));

Отсутствует

 

Board footer

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