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

Mozilla Россия — свежие версии программ Mozilla, а также масса полезной информации по каждому продукту.

№1392604-12-2019 16:04:48

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

Re: Custom Buttons

Dumby
Спасибо, дошло... Разобрался, все работает.

Отредактировано Garalf (04-12-2019 16:05:33)

Отсутствует

 

№1392704-12-2019 16:18:58

solombala
Участник
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 280
UA: Firefox 71.0

Re: Custom Buttons

Dumby
Круто...А, кто это писал? Тоже того...Доп пункты в about;addons

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

Выделить код

Код:

//Добавление на вкладке дополнения в меню расширений дополнительных пунктов
(function(){

        var iconURL = "";  

 

    if (window.AM_Helper) { 
        window.AM_Helper.uninit();
        delete window.AM_Helper;
    }
    

    Cu.import("resource://gre/modules/Services.jsm");
    Cu.import("resource://gre/modules/AddonManager.jsm");

   
    window.AM_Helper = {
        init: function() {
            document.addEventListener("DOMContentLoaded", this, false);
            this.platformVersion = parseFloat(Services.appinfo.platformVersion);
        },
        uninit: function() {
            document.removeEventListener("DOMContentLoaded", this, false);
        },
          handleEvent: function(event){
            switch(event.type){
                    case "DOMContentLoaded":
                    var doc = event.target;
                    var win = doc.defaultView;
                    
                    if (["about:addons","chrome://mozapps/content/extensions/extensions.xul"].indexOf(doc.URL) == -1)
                        return;
                    this.addPopupMenu(doc);

                    win.AM_Helper = AM_Helper;
                    this.win = win;

                    var observer = new MutationObserver(function(e) {
                        e = e[e.length-1];
                        if(e.attributeName == "loading") {
                            var doc = e.target.ownerDocument;
                        }
                    });
                    observer.observe(doc.getElementById("detail-view"), {attributes: true});
                    break;
                    case "popupshowing":
                    this.getAddon(this.win.document.popupNode.value,
                                  this.setItemsAttributes,
                                  event);
                    break;
            }
        },
        
        
        //Создаем меню
        addPopupMenu: function(doc) {
        
         var mainicon2="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAwAAAP8AAAD/AAAA/wAAAPAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAAAAAAD/AAAA/wAAAP8AAADwAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAA/wAAAP8AAAD/AAAA8AAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAAAAAP8AAAD/AAAA/wAAAPAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAAAAAAD/AAAA/wAAAP8AAADwAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAA8wAAAP8AAAD/AAAA8AAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAAAAAPAAAAD/AAAA/wAAAPAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAPAAAAAAAAAAAAAAAHsAAAD/AAAAkAAAAAAAAADwAAAA/wAAAP8AAADwAAAA/wAAAP8AAAD/AAAA/wAAAP8AAADwAAAAAAAAAIQAAAD/AAAAjQAAAAAAAAB1AAAA/wAAAP8AAAD/AAAA8AAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA8AAAAIoAAAD/AAAAigAAAAAAAABpAAAAAAAAAAAAAAB7AAAA/wAAAIcAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAigAAAAAAAAB7AAAA8AAAAAAAAACEAAAA/wAAAIcAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAAhwAAAAAAAACBAAAA/wAAAPAAAACKAAAA/wAAAIcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEAAAA/wAAAP8AAAD/AAAA/wAAAIcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAIQAAAAAAAAAAAAAAAAAAAAAAB8AAAAfAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAxAAAAIgAAAAWAAAAJEAAAEDAAD+BwAA+A8AAA==";
        
        
            var ins = doc.getElementById("menuitem_uninstallItem");
            if (!ins) return;

            ins = ins.nextSibling;
            var popup = ins.parentNode;

            var menuitem = $C("menuseparator", {
                id: "AM-separator-1"
            });
            popup.insertBefore(menuitem, ins);


             menuitem = $C("menuitem", {
                id: "AM-browse-dir",
                label: "Папка установки",
                oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.browseDir);"
            });
            popup.insertBefore(menuitem, ins);
            
            menuitem = $C("menuitem", {
                id: "AM-browse-Folder",
                label: "Файл установки",
                oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.Folder);"
            });
            popup.insertBefore(menuitem, ins);

            menuitem = $C("menuitem", {
                id: "AM-open-url",
                label: "Страница на AMO",
                tooltiptext: null,
                oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.goAMO);"
            });
            popup.insertBefore(menuitem, ins);
            
            menuitem = $C("menuitem", {
                id: "AM-browse-support",
                label: "Страница поддержки",
                oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.support);"
            });    
           popup.insertBefore(menuitem, ins);   
           
           menuitem = $C("menuitem", {
                id: "AM-browse-goHome",
                label: "Домашняя страница",
                oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.goHome);"
            });
           popup.insertBefore(menuitem, ins);         

           var menu = $C("menu", {
                id: "AM-menu",
                class: "menu-iconic",
                image: mainicon2,
                label: "Копировать",
            });
            popup.insertBefore(menu, ins);
            var menuPopup = $C("menupopup", {
                id: "AM-menupopup",
            });
            menu.appendChild(menuPopup);

            menuitem = $C("menuitem", {
                id: "AM-copy-name",
                label: "Копировать имя",
                oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyName);"
            });
            menuPopup.appendChild(menuitem);
            
             menuitem = $C("menuitem", {
                id: "AM-copy-version",
                label: "Копировать версию",
                oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyVersion);"
            });
            menuPopup.appendChild(menuitem);
 
            menuitem = $C("menuitem", {
                id: "AM-copy-NameVersion",
                label: "Копировать имя и версию",
                oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyNameVersion);"
            });
            menuPopup.appendChild(menuitem);
           
            menuitem = $C("menuitem", {
                id: "AM-copy-id",
                label: "Копировать id",
                oncommand: "AM_Helper.getAddon(AM_Helper.getPopupNode(this).value, AM_Helper.copyID);"
            });
            menuPopup.appendChild(menuitem);

            popup.addEventListener("popupshowing", this, true);
        },
        
        
        //Указываем где и когда показывать элементы меню
        setItemsAttributes: function(aAddon, event) {
            var popup = event.target;
            var doc = popup.ownerDocument;

            var
                isExtension = (aAddon.type == "extension"),
                isTheme = (aAddon.type == "theme"),
                isPlugin = (aAddon.type == "plugin"),
                isService = (aAddon.type == "service"),
                isCustomButton = (aAddon.type == "custombuttons"),
                menuitem
            ;

            menuitem = doc.getElementById("AM-browse-dir");
            menuitem.hidden = isService || isTheme || isCustomButton;
                        
            menuitem = doc.getElementById("AM-browse-Folder");
            menuitem.hidden = isService || isTheme || isCustomButton || isPlugin;

            menuitem = doc.getElementById("AM-copy-name");
            menuitem.tooltipText = aAddon.name;
            
            
            menuitem = doc.getElementById("AM-copy-version");
            menuitem.tooltipText = aAddon.version;
            menuitem.hidden = isCustomButton || isTheme;
            
            menuitem = doc.getElementById("AM-copy-NameVersion");
            menuitem.tooltipText = aAddon.name + " " + aAddon.version;
            menuitem.hidden = isCustomButton || isTheme;
            
            menuitem = doc.getElementById("AM-copy-id");
            menuitem.tooltipText = "ID: " + aAddon.id;
            

            menuitem = doc.getElementById("AM-open-url");
            var amoURL = aAddon.reviewURL
                 ? aAddon.reviewURL.replace(/\/reviews\//, "/")
                 : null;
            menuitem.tooltipText = amoURL;
            menuitem.hidden = !amoURL || /addons.mozilla.org/.test(aAddon.homepageURL);
            
            menuitem = doc.getElementById("AM-browse-support");
            menuitem.tooltipText = aAddon.supportURL;
            menuitem.hidden = !aAddon.supportURL;
            
            menuitem = doc.getElementById("AM-browse-goHome");
            menuitem.tooltipText = aAddon.homepageURL;
            menuitem.hidden = !aAddon.homepageURL;
           
        },

        getPopupNode: function (aNode) {
            var doc = aNode.ownerDocument;
            return "triggerNode" in aNode.parentNode ? aNode.parentNode.triggerNode : doc.popupNode;
        },
        getAddon: function (aId, aCallback, aEvent) {
            var self = this;
            if (this.win.gDetailView._addon) {
                aCallback.apply(this, [this.win.gDetailView._addon, aEvent]);
                return;
            }

            (self.platformVersion < 61.0?
                new Promise((resolve, reject) => AddonManager.getAllAddons(addons => resolve(addons))):
                AddonManager.getAllAddons()
            ).then(addons => {
                for (var i = 0; i < addons.length; i++) {
                    if (addons[i].id == aId) {
                        aCallback.apply(self, [addons[i], aEvent]);
                        return;
                    }
                }
            });
        },


     //Открыть папку установки
        browseDir: function (aAddon) {
            switch (aAddon.type) {
                case "plugin":
                    var pathes = aAddon.pluginFullpath;
                    for (var i = 0; i < pathes.length; i++) {
                        this.revealPath(pathes[i]);
                    }
                    return;
                case "userchromejs":
                    var file = aAddon._script.file;
                    if (file.exists())
                        file.reveal();
                    return;
            }

            // addon
            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(aAddon.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);
                }
            }
        },



        //Копировать имя  
        copyName: function (aAddon) {
            this.copyToClipboard(aAddon.name);
        },
         //Копировать ID 
    copyID: function (aAddon) {
            this.copyToClipboard("ID: " + aAddon.id);
        },
    //Копировать версию 
    copyVersion: function (aAddon) {
            this.copyToClipboard(aAddon.version);
        },
    //Копировать имя и версию
    copyNameVersion: function (aAddon) {
           this.copyToClipboard(aAddon.name + " " + aAddon.version);
        },
       //Открыть файл установки    
    Folder: function (aAddon) {
            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(aAddon.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( aAddon.id + '.xpi' )             
                            if ( file.exists() ) file.launch(); 
                            return; 
          },     
         //Страница на АМО
       goAMO: function (aAddon) {
        var sourceTracker = "/?src=external-Add-ons_Manager_Context_Menu-extension";
    if (aAddon.reviewURL) {
      var amoURL = aAddon.reviewURL.replace(/\/reviews\//, "/")
                             .replace(/\/(firefox|seamonkey|thunderbird|android)/, "")
                             .replace(/\/\?src\=api/, sourceTracker);
    }
    if (/personas.mozilla.org$/.test(aAddon.id)) {
      amoURL = "https://addons.mozilla.org/addon/" + aAddon.id.match(/\d+/) + sourceTracker;
      }
       openURL(amoURL);
       },
       
        //Домашняя страница
     goHome: function (aAddon) {
        var url = aAddon.homepageURL;
        if (!url) {
        if (aAddon.reviewURL) {
        url = aAddon.reviewURL.replace(/\/reviews\/.*$/, "/");
        } else {
        url = "https://addons.mozilla.org/search/?q="
            + encodeURIComponent(aAddon.name);
         }
        }
       openURL(url);
       },
       
       //Страница поддержки
       support: function(aAddon) {
        openURL(aAddon.supportURL);
       },
       //Вспомогательные функции
        get getPath() {
            var url = this.win.gViewController.viewObjects.detail._addon;
            if (!url) return false;
            return url.pluginFullpath || false;
        },
       revealPath: function(path){
            var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
            file.initWithPath(path);
            if(file.exists())
                file.reveal();
        },
        copyToClipboard: function (aString) {
            Cc["@mozilla.org/widget/clipboardhelper;1"].
                getService(Ci.nsIClipboardHelper).copyString(aString);
        }
    };

 
    AM_Helper.init();

 
    function $C(name, attr) {
        var el = document.createXULElement(name);
        if (attr) Object.keys(attr).forEach(function(n){ el.setAttribute(n, attr[n])});
        return el;
    }
})();
((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", {}), {});


впрочем, нуее , прокси не пашут..SSL - отрихтовали...

Отредактировано solombala (04-12-2019 17:04:39)

Отсутствует

 

№1392804-12-2019 18:39:32

kokoss
Участник
 
Группа: Members
Зарегистрирован: 15-02-2018
Сообщений: 651
UA: Firefox 52.0

Re: Custom Buttons

Dumby пишет:

У вас не работает. У меня работает.

Взял эту кнопку: https://forum.mozilla-russia.org/viewto … 10#p775310, затем заменил этот код:

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

Выделить код

Код:

this.handleClick = function(evt) {

    var node = evt.target;
    if (node.nodeName != &quot;button&quot; || node.parentNode == hbox) return;

    var v1 = node.getAttribute(&quot;value1&quot;);
    var v2 = node.getAttribute(&quot;value2&quot;);
    if (v2) v2 = &quot;=&quot; + v2.replace(&quot;%clipboard%&quot;, gClipboard.read());

    var bb1 = &quot;[&quot; + v1 + (v2 || &quot;&quot;) + &quot;]&quot;;
    var bb2 = &quot;[/&quot; + v1 + &quot;]&quot;;

    var box = content.document.activeElement;
    var txt = box.value;

    var s = box.selectionStart;
    var e = box.selectionEnd;

    var bef = txt.substring(0, s);
    var mid = txt.substring(s, e);
    var aft = txt.substring(e);

    var ins = bb1.replace(/%copy%|%move%/, mid) + (v2 == &quot;=%move%&quot; ? &quot;&quot; : mid) + bb2;
    var val = bef + ins + aft;

    box.value = val;
    box.selectionStart = s;
    box.selectionEnd = s + ins.length;
//    box.focus();
}


на ваш. Вроде сделал как вы подсказали ?

Отредактировано kokoss (04-12-2019 18:42:38)

Отсутствует

 

№1392904-12-2019 21:57:38

Eugene20212021
Участник
 
Группа: Members
Зарегистрирован: 04-12-2019
Сообщений: 1
UA: Firefox 71.0

Re: Custom Buttons

Зашел по ссылке http://custombuttons.mozdev.org/installation.html
Последняя версия от 2011 на мой свежий Firefox не ставится.
А тут люди вроде используют, обсуждают.
Люди добрые! Как мне получить работающую версию этого замечательного плагина?

Отредактировано Eugene20212021 (04-12-2019 21:57:53)

Отсутствует

 

№1393004-12-2019 22:39:29

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

Re: Custom Buttons

kokoss пишет:

Вроде сделал как вы подсказали ?

Ну, почти что.
Не упомянуто, что была произведена замена slice на from
Array generics удалили в Firefox 71

Отсутствует

 

№1393105-12-2019 12:07:30

solombala
Участник
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 280
UA: Firefox 71.0

Re: Custom Buttons

Dumby
Нельзя глянуть? FindBar в 71 блекнет в ini , приходится в код вставлять и жмакать пару раз , что ни есть гуд.

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

Выделить код

Код:

/*Initialization Code*/

((bar, button = true, insertAtTop = true, ctrlFcloseFinbar = false) => ({
    init(parent) {
        var has = bar = parent.querySelector("#appcontent > findbar");
        has || this.initFinbar(parent);
        var lo = bar.linkedObject;
        lo.listenCtrlF = ctrlFcloseFinbar
            ? listen => listen
                ? addEventListener("keydown", lo, true)
                : removeEventListener("keydown", lo, true)
            : () => {};
        has && !bar.hidden && lo.listenCtrlF(true);
        if (button) self._handleClick = () => bar.hidden
            ? bar.startFind(bar.FIND_NORMAL)
            : bar.collapsed || bar.close();
        addDestructor(lo.destroy, lo);
    },
    destroy(reason) {
        if (reason[5] != "e") return;
        bar.close();
        bar._browser = {};
        bar.remove();
        this.setProgressListener(false);
        for(var key of ["gFindBar", "gFindBarInitialized"])
            Object.defineProperty(window, key, this[key]);
        gBrowser[this.gBrKey] = this[this.gBrKey];
        Services.ppmm.removeDelayedProcessScript(this.url);
        Services.ppmm.loadProcessScript("data:," + encodeURIComponent(`
            Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT
            && Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_CONTENT
            || (nsvo => {
                var proto = nsvo.Finder.prototype;
                if ("_requestMatchesCount" in proto) {
                    proto.requestMatchesCount = proto._requestMatchesCount;
                    delete proto._requestMatchesCount;
                }
            })(Cu.import("resource://gre/modules/Finder.jsm", {}));`
        ) , false);
    },
    initFinbar(parent) {
        for(var tab of gBrowser.tabs) {
            if (!tab._findBar) continue;
            tab._findBar.browser = null;
            tab._findBar._browser = {};
            tab._findBar.remove();
            delete tab._findBar;
        }
        bar = document.createXULElement("findbar");
        var p = new Proxy({}, {get: () => () => {}});
        bar._browser = {finder: p, messageManager: p};
        parent.insertBefore(bar, insertAtTop ? parent.firstChild : null);
        bar.linkedObject = this;

        ["gFindBar", "gFindBarInitialized"].forEach((key, ind) => {
            this[key] = Object.getOwnPropertyDescriptor(window, key);
            delete window[key];
            window[key] = ind ? true : bar;
        });
        var key = "getCachedFindBar" in gBrowser ? "getCachedFindBar" : "getFindBar";
        this[this.gBrKey = key] = gBrowser[key];
        gBrowser[key] = () => bar;
        [
            "close", "startFind", "onMatchesCountResult",
            "_updateMatchesCount", "_onBrowserKeypress", "receiveMessage"

        ].forEach((key, ind) => {
            var func = bar[key].bind(bar);
            bar[key] = ind
                ? (...args) => this[key](...args) || func(...args)
                : (...args) => func(...args) || this[key](...args);
        });
        this.url = "data:," + encodeURIComponent(`
            Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT
            && Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_CONTENT
            || (nsvo => {
                var proto = nsvo.Finder.prototype;
                if ("_requestMatchesCount" in proto) return;
                proto._requestMatchesCount = proto.requestMatchesCount;
                proto.requestMatchesCount = ${
                    this.newRequestMatchesCount
                }
            })(Cu.import("resource://gre/modules/Finder.jsm", {}));`
        );
        delete this.newRequestMatchesCount;
        Services.ppmm.loadProcessScript(this.url, true);
    },
    newRequestMatchesCount: async function requestMatchesCount(aWord, aLinksOnly) {
        if (typeof aLinksOnly != "boolean") {

            var {linksOnly, data} = aLinksOnly;
            aLinksOnly = linksOnly;

            this.entireWord = data.entireWord;
            this.caseSensitive = data.caseSensitive;
            this.onModalHighlightChange(data.useModalHighlight);
            this.onHighlightAllChange(data.highlightAll);
            data.highlightAll && await this.highlighter.highlight(true, aWord, linksOnly);
            this._iterator && this._iterator.reset();
            var obj;
            Object.defineProperty(this, "_currentMatchesCountResult", {
                configurable: true, enumerable: true,
                get: (val = obj) => {
                    if (val) {
                        if (!val.total) val.total = new Number(0);
                        val.currentFound = val._currentFound;
                    }
                    return obj = val;
                },
                set: val => {
                    if (val) return obj = val;
                    delete this._currentMatchesCountResult;
                    return obj = this._currentMatchesCountResult = val;
                }
            });
            var lfr = this._lastFindResult;
            lfr !== null && lfr != Ci.nsITypeAheadFind.FIND_NOTFOUND
            || Object.defineProperty(this, "_lastFindResult", {
                configurable: true, enumerable: true, get: () => null,
                set: val => {
                    if (val == Ci.nsITypeAheadFind.FIND_WRAPPED)
                        val = Ci.nsITypeAheadFind.FIND_FOUND;
                    delete this._lastFindResult;
                    return this._lastFindResult = val;
                }
            });
        }
        this._requestMatchesCount(aWord, aLinksOnly);
    },

    close() {
        bar.collaped = false;
        this.setProgressListener(false);
        this.setBrowser(null, null);
    },
    startFind() {
        if (this.maybeCollapse(gBrowser.selectedBrowser))
            return true;
        if (bar.hidden)
            this.setBrowser(300),
            this.setProgressListener(true);
        else if (!ctrlFcloseFinbar)
            setTimeout(() => this.updateMatchesCount(), 100);
    },
    onMatchesCountResult(res) {
        if (!("currentFound" in res) || res.total == -1 || res.currentFound)
            return;

        bar._foundMatches.value = `${+res.total || "Нет"} совпадени${
            bar.pluralForm.get(res.total, "е;я;й")
        }.`;
        bar._foundMatches.hidden = false;
        return true;
    },
    _updateMatchesCount() {
        return true;
    },
    _onBrowserKeypress(e) {
        if (!bar.hidden) return;
        if (!e.charCode) return true;
        this.setBrowser(300);
        this.setProgressListener(true);
    },
    receiveMessage(msg) {
        msg.target = bar._browser;
    },

    progressListenerAdded: false,
    setProgressListener(add) {
        if (add) {
            if (this.progressListenerAdded) return;
            this.progressListenerAdded = true;
            gBrowser.addProgressListener(this);
            this.listenCtrlF(true);
        } else {
            if (!this.progressListenerAdded) return;
            this.progressListenerAdded = false;
            gBrowser.removeProgressListener(this);
            this.listenCtrlF(false);
        }
    },
    handleEvent(e) {
        if (
            e.ctrlKey && e.code == "KeyF"
            && !e.shiftKey && !e.altKey && !bar.collapsed
        )
            e.preventDefault(),
            e.stopPropagation(),
            bar.close();
    },
    updateMatchesCount() {
        var str = bar._findField.value;
        if (!str) return;
        var data = {
            entireWord: bar._entireWord,
            caseSensitive: bar._typeAheadCaseSensitive,
            highlightAll: bar._highlightAll,
            useModalHighlight: bar._useModalHighlight
        };
        bar.browser.finder.requestMatchesCount(
            bar._findField.value,
            {linksOnly: bar._findMode == bar.FIND_LINKS, data}
                );
    },
    maybeCollapse(br) {
        return br.isSyntheticDocument ||
            br.documentContentType == "application/vnd.mozilla.xul+xml";
    },
    setBrowser(updateDelay, br = gBrowser.selectedBrowser) {
        if (bar._browser != br) {
            var b = bar._browser;
            if (b) {
                b.messageManager.removeMessageListener("Findbar:Mouseup", bar);
                b.finder.removeResultListener(bar);
                bar._highlightAll && b.finder.highlight(false);
            }
            if (br) {
                br.messageManager.addMessageListener("Findbar:Mouseup", bar);
                bar._updateBrowserWithState();
            }
            bar._browser = br;
        }
        if (!br) return;
        bar._updateStatusUI();
        bar._foundMatches.value = "";
        br.finder.addResultListener(bar);
        if (
            !(bar.collapsed = this.maybeCollapse(br))
            && br.currentURI.spec != "about:blank"
            && updateDelay !== null
        )
            updateDelay
                ? setTimeout(this.updateMatchesCount, updateDelay)
                : this.updateMatchesCount();
    },
    onStateChange(wpr, req, state) {
        state & Ci.nsIWebProgressListener.STATE_STOP && this.setBrowser();
        },
    onLocationChange(wpr, req) {
        req || Components.stack.formattedStack.includes("SessionStore.jsm")
        || this.setBrowser();
    }
}).init(document.getElementById("appcontent")))();

Отсутствует

 

№1393205-12-2019 22:13:15

func4ptch4
Участник
 
Группа: Members
Зарегистрирован: 03-05-2018
Сообщений: 177
UA: Firefox 71.0

Re: Custom Buttons

Что делает эта кнопка? // Дв.клик по панели вкладок........... ||| Понять не могу, какая панель?
Насчет BBCode, тоже все сделал как надо заменил и подставил в конец, не пашет.

Отредактировано func4ptch4 (05-12-2019 22:17:26)

Отсутствует

 

№1393305-12-2019 22:47:36

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

Re: Custom Buttons

func4ptch4
Здесь обе эти кнопки. Работают даже в 73.
Дв.клик по вкладке&Дв. клик по панели вкладок - двойной клик по панели вкладок закрывает все вкладки, а двойной клик по вкладке закрывает другие открытые вкладки. Проверь у себя - у меня все работает, как в однопроцессорном режиме, так и многопроцессорном.

Отредактировано Garalf (05-12-2019 22:49:33)

Отсутствует

 

№1393405-12-2019 23:01:38

solombala
Участник
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 280
UA: Firefox 71.0

Re: Custom Buttons

Dumby
Больше не знаю к кому обратиться. В 71 прокси frigate https приказали долго жить.(TLS1.1) Кое-что я рихтанул в свойственной мне манере. процесс пошел, но не для гугла с его ютюбом. Короче, Socks 5 применил , но как proxy.pac применить ? Кнопки есть , а Pac как заделать с socks5 ? привожу примеры: Это для Http , к сожалению
Снят вопрос , все сделал.

Отредактировано solombala (06-12-2019 01:51:11)

Отсутствует

 

№1393505-12-2019 23:48:50

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

Re: Custom Buttons

Dumby мда, не долго музыка играла

Выделить код

Код:

var {label} = gBrowser.selectedTab;
var re = /(.+) (\(.+\)) \[(\d{4})[^\]]+\] (.+) (.+) (.+)/;
re.test(label) && gClipboard.write(
    label.replace(re, "$1 $2 ($4) ($3)").replace(/ \/ /g, " - ")
);

только я привык к этой кнопке, бац и обновления 71, СВ установлен, но кнопка исчезла из панели, в меню больше нет под ПКМ пункта про кнопку, что делать???

Отсутствует

 

№1393606-12-2019 06:35:37

func4ptch4
Участник
 
Группа: Members
Зарегистрирован: 03-05-2018
Сообщений: 177
UA: Firefox 71.0

Re: Custom Buttons

Garalf
Проверил, и это удобно? у меня по привычке то что по стандарту.
И по привычке тыкаю а там все окна бах и нет..) мда ну эту кнопку, да и 2-клик по вкладке тоже мне легче выборочно.
BBCode работает, вот бы еще меню вылазил по автопопапу, а так все норм.)

solombala, как решил? интересно.
Вроде сокс видел, а вот с авторизацией .pac не сделать.

Отредактировано func4ptch4 (06-12-2019 06:54:52)

Отсутствует

 

№1393706-12-2019 09:09:00

solombala
Участник
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 280
UA: Firefox 71.0

Re: Custom Buttons

func4ptch4
Прокси нормальный нужен .  Пример (сам прокси от фонаря, сам ищи )

скрытый текст
function FindProxyForURL(url, host) 
{
var proxy_server = 'SOCKS 162.168.161.141:8888; DIRECT'; 

var no_proxy = 'DIRECT';
{
var proxy_list = new Array(
'whoer.net',
'yandex.ua',
'yandex.ru',
'rutube.ru',
'ren.tv',
'yadi.sk',
'yandex.net',
'yandex.sx',
'naydex.net',         
'youtube.com',
'static.yandex.sx',
'ok.ru',
'vk.com',
'hdrezka.ag',
'mail.ru',
'kinopoisk.ru',
'yastatic.net',
'yandex.sx',
'youtube.com',
'ya.ru',
'2ip.ru',                                   
             
);
for (var i = 0; i < proxy_list.length; i++){
var value = proxy_list[i];
if (dnsDomainIs(host, '.' + value) || host === value) {
return proxy_server;
}
}
return no_proxy;
}
return no_proxy;
}

Кстати это нельзя к профилю привязать, а не к диску? file:///D:/proxy/Proxy1.pac

Отредактировано solombala (06-12-2019 12:19:29)

Отсутствует

 

№1393806-12-2019 15:56:54

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 161
UA: Firefox 52.0

Re: Custom Buttons

solombala пишет:

Кстати это нельзя к профилю привязать, а не к диску? file:///D:/proxy/Proxy1.pac

У меня есть вот такая кнопка, если не ошибаюсь от Dumby:

Выделить код

Код:

(()=> {
// Задать путь к файлу в папке chrome. ..........
(({io, dirsvc, prefs}) => {

    var substitution = "chrome", dir = "UChrm";

    var rph = io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
    addDestructor(reason => reason[5] == "e" && rph.hasSubstitution(substitution) && rph.setSubstitution(substitution, null));
    if (rph.hasSubstitution(substitution)) return;

    rph.setSubstitution(substitution, io.newFileURI(dirsvc.get(dir, Ci.nsIFile)));

})(Services);
})();

Далее в папку chrome в профиле я положил файл proxy.pac и в настройках прокси указал resource://chrome/proxy.pac.
https://imageup.ru/img33/3518832/untitled-2.png
У меня это работает в [firefox] 68 ESR. Сработает ли в более новых версиях, я не знаю.

Отредактировано unter_officer (06-12-2019 15:57:55)

Отсутствует

 

№1393906-12-2019 17:40:43

solombala
Участник
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 280
UA: Firefox 71.0

Re: Custom Buttons

unter_officer
В 68  тоже не работает ...

Отсутствует

 

№1394006-12-2019 18:02:27

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 161
UA: Firefox 52.0

Re: Custom Buttons

solombala пишет:

unter_officer
В 68  тоже не работает ...

Ну, не знаю. У меня работает.

Отредактировано unter_officer (06-12-2019 18:02:50)

Отсутствует

 

№1394106-12-2019 18:10:46

solombala
Участник
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 280
UA: Firefox 71.0

Re: Custom Buttons

unter_officer
Профиль где? В системе? У меня портабл и профиль в каталоге .

Отсутствует

 

№1394206-12-2019 18:18:06

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 161
UA: Firefox 52.0

Re: Custom Buttons

solombala пишет:

unter_officer
Профиль где? В системе? У меня портабл и профиль в каталоге .

У меня портабл от portableapps.com и профиль в каталоге.

Отсутствует

 

№1394306-12-2019 22:26:39

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

Re: Custom Buttons

solombala пишет:

Нельзя глянуть?

Я же говорил, что не хочу больше с этой темой связываться,
слишком сложно для меня. Ладно, подкрутил тяп-ляп кое-что.
Тестировать не буду, делать правильней и лучше не стану.
Вот, просто чтоб тебе совсем без ничего не остаться

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

Выделить код

Код:

((bar, button = true, insertAtTop = true, ctrlFcloseFinbar = false) => ({
    init(parent) {
        var has = bar = parent.querySelector("#appcontent > findbar");
        has || this.initFinbar(parent);
        var lo = bar.linkedObject;
        lo.listenCtrlF = ctrlFcloseFinbar
            ? listen => listen
                ? addEventListener("keydown", lo, true)
                : removeEventListener("keydown", lo, true)
            : () => {};
        has && !bar.hidden && lo.listenCtrlF(true);
        if (button) self._handleClick = () => bar.hidden
            ? bar.startFind(bar.FIND_NORMAL)
            : bar.collapsed || bar.close();
        addDestructor(lo.destroy, lo);
    },
    destroy(reason) {
        if (reason[5] != "e") return;
        bar.close();
        bar._browser = {};
        bar.remove();
        this.setProgressListener(false);
        if (!this.receiver) this.actorProto.receiveMessage = this.actorReceiveMessage;
        for(var key of ["gFindBar", "gFindBarInitialized"])
            key in this && Object.defineProperty(window, key, this[key]);
        for(key of this.gBrKeys) gBrowser[key] = this[key];
        Services.ppmm.removeDelayedProcessScript(this.url);
        Services.ppmm.loadProcessScript("data:," + encodeURIComponent(`
            (ai => ai.processType == ai.PROCESS_TYPE_DEFAULT || ai.processType == ai.PROCESS_TYPE_CONTENT)(
                Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
            ) && (nsvo => {
                var proto = nsvo.Finder.prototype;
                if ("_requestMatchesCount" in proto) {
                    proto.requestMatchesCount = proto._requestMatchesCount;
                    delete proto._requestMatchesCount;
                }
            })(Cu.import("resource://gre/modules/Finder.jsm", {}));`
        ) , false);
    },
    initFinbar(parent) {
        for(var tab of gBrowser.tabs) {
            if (!tab._findBar) continue;
            tab._findBar.browser = null;
            tab._findBar._browser = {};
            tab._findBar.remove();
            delete tab._findBar;
        }
        bar = document.createXULElement("findbar");
        var p = new Proxy({}, {get: () => () => {}});
        bar._browser = {finder: p, messageManager: p};
        parent.insertBefore(bar, insertAtTop ? parent.firstChild : null);
        bar.linkedObject = this;

        ["gFindBar", "gFindBarInitialized"].forEach((key, ind) => {
            var desc = Object.getOwnPropertyDescriptor(window, key);
            if (!desc.configurable) return;
            this[key] = desc;
            delete window[key];
            window[key] = ind ? true : bar;
        });
        var key = "getCachedFindBar" in gBrowser ? "getCachedFindBar" : "getFindBar";
        this.gBrKeys = [key];
        key = "isFindBarInitialized";
        if (key in gBrowser) this.gBrKeys.push(key);
        this.gBrKeys.forEach((key, ind) => {
            this[key] = gBrowser[key];
            gBrowser[key] = ind ? () => true : () => bar;
        });
        var props = [
            "close", "startFind", "onMatchesCountResult",
            "_updateMatchesCount", "_onBrowserKeypress"
        ];
        if ((this.receiver = "receiveMessage" in bar))
            props.push("receiveMessage");
        else {
            this.actorProto = Object.getPrototypeOf(
                gBrowser.selectedBrowser.browsingContext.currentWindowGlobal.getActor("FindBar")
            );
            this.actorReceiveMessage = this.actorProto.receiveMessage;
            this.actorProto.receiveMessage = msg => {
                if (msg.name == "Findbar:Keypress") bar._onBrowserKeypress(msg.data);
                else if (msg.name == "Findbar:Mouseup") bar.onMouseUp();
            }
        }
        props.forEach((key, ind) => {
            var func = bar[key].bind(bar);
            bar[key] = ind
                ? (...args) => this[key](...args) || func(...args)
                : (...args) => func(...args) || this[key](...args);
        });
        this.url = "data:," + encodeURIComponent(`
            (ai => ai.processType == ai.PROCESS_TYPE_DEFAULT || ai.processType == ai.PROCESS_TYPE_CONTENT)(
                Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime)
            ) && (nsvo => {
                var proto = nsvo.Finder.prototype;
                if ("_requestMatchesCount" in proto) return;
                proto._requestMatchesCount = proto.requestMatchesCount;
                proto.requestMatchesCount = ${
                    this.newRequestMatchesCount
                }
            })(Cu.import("resource://gre/modules/Finder.jsm", {}));`
        );
        delete this.newRequestMatchesCount;
        Services.ppmm.loadProcessScript(this.url, true);

        var desc = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
        var setValue = desc.set.bind(bar._findField);
        desc.set = val => Components.stack.formattedStack.includes(
            "set browser@chrome://global/content/elements/findbar.js"
        ) ? val : setValue(val);
        Object.defineProperty(bar._findField, "value", desc);
    },
    newRequestMatchesCount: async function requestMatchesCount(aWord, aLinksOnly, aUseSubFrames = true) {
        if (aLinksOnly && aLinksOnly.constructor.name == "Object") {
            var {linksOnly, data} = aLinksOnly;
            aLinksOnly = linksOnly;

            this.entireWord = data.entireWord;
            this.caseSensitive = data.caseSensitive;
            this.onModalHighlightChange(data.useModalHighlight);
            this.onHighlightAllChange(data.highlightAll);
            data.highlightAll && await this.highlighter.highlight(true, aWord, linksOnly);
            this._iterator && this._iterator.reset();
            var obj;
            Object.defineProperty(this, "_currentMatchesCountResult", {
                configurable: true, enumerable: true,
                get: (val = obj) => {
                    if (val && val._currentFound)
                        val.total = Math.floor(val.total) + .0001;
                    return obj = val;
                },
                set: val => {
                    if (val) {
                        val.total = 10000;
                        return obj = val;
                    }
                    delete this._currentMatchesCountResult;
                    return obj = this._currentMatchesCountResult = val;
                }
            });
        }
        return await this._requestMatchesCount(aWord, aLinksOnly, aUseSubFrames);
    },

    close() {
        bar.collaped = false;
        this.setProgressListener(false);
        this.setBrowser(null, null);
    },
    startFind() {
        if (this.maybeCollapse(gBrowser.selectedBrowser))
            return true;
        if (bar.hidden)
            this.setBrowser(300),
            this.setProgressListener(true);
        else if (!ctrlFcloseFinbar)
            setTimeout(() => this.updateMatchesCount(), 100);
    },
    get pf() {
        delete this.pf;
        return this.pf = bar.pluralForm || ChromeUtils.import(
            "resource://gre/modules/PluralForm.jsm"
        ).PluralForm;
    },
    onMatchesCountResult(res) {
        if (res.total <= 1000) return;

        var strTotal = String(res.total);
        var found = strTotal.includes(".");
        if (found) strTotal = strTotal.split(".")[0];
        if ((res.total = +strTotal.slice(-4)) >= 1000) {
            res.total = -1;
            return;
        }
        if (res.current > 1000)
            res.current = +String(res.current).slice(-4);

        if (res.current && found) return;

        bar._foundMatches.value = `${+res.total || "Нет"} совпадени${
            this.pf.get(res.total, "е;я;й")
        }.`;
        bar._foundMatches.hidden = false;
        return true;
    },
    _updateMatchesCount() {
        return true;
    },
    _onBrowserKeypress(e) {
        if (!bar.hidden) return;
        if (!e.charCode) return true;
        this.setBrowser(300);
        this.setProgressListener(true);
    },
    receiveMessage(msg) {
        msg.target = bar._browser;
    },

    progressListenerAdded: false,
    setProgressListener(add) {
        if (add) {
            if (this.progressListenerAdded) return;
            this.progressListenerAdded = true;
            gBrowser.addProgressListener(this);
            this.listenCtrlF(true);
        } else {
            if (!this.progressListenerAdded) return;
            this.progressListenerAdded = false;
            gBrowser.removeProgressListener(this);
            this.listenCtrlF(false);
        }
    },
    handleEvent(e) {
        if (
            e.ctrlKey && e.code == "KeyF"
            && !e.shiftKey && !e.altKey && !bar.collapsed
        )
            e.preventDefault(),
            e.stopPropagation(),
            bar.close();
    },
    updateMatchesCount() {
        var str = bar._findField.value;
        if (!str) return;
        var data = {
            entireWord: bar._entireWord,
            caseSensitive: bar._typeAheadCaseSensitive,
            highlightAll: bar._highlightAll,
            useModalHighlight: bar._useModalHighlight
        };
        bar.browser.finder.requestMatchesCount(
            bar._findField.value,
            {linksOnly: bar._findMode == bar.FIND_LINKS, data}
        );
    },
    maybeCollapse(br) {
        return br.isSyntheticDocument ||
            br.documentContentType == "application/vnd.mozilla.xul+xml";
    },
    setBrowser(updateDelay, br = gBrowser.selectedBrowser) {
        if (bar._browser != br) {
            var b = bar._browser;
            if (b) {
                this.receiver && b.messageManager
                    .removeMessageListener("Findbar:Mouseup", bar);
                b.finder.removeResultListener(bar);
                bar._highlightAll && b.finder.highlight(false);
            }
            if (br) {
                this.receiver && br.messageManager
                    .addMessageListener("Findbar:Mouseup", bar);
                bar._updateBrowserWithState();
            }
            bar._browser = br;
        }
        if (!br) return;
        bar._updateStatusUI();
        bar._foundMatches.value = "";
        br.finder.addResultListener(bar);
        if (
            !(bar.collapsed = this.maybeCollapse(br))
            && br.currentURI.spec != "about:blank"
            && updateDelay !== null
        )
            updateDelay
                ? setTimeout(this.updateMatchesCount, updateDelay)
                : this.updateMatchesCount();
    },
    onStateChange(wpr, req, state) {
        state & Ci.nsIWebProgressListener.STATE_STOP && this.setBrowser();
    },
    onLocationChange(wpr, req) {
        req || wpr.isLoadingDocument ||
            gBrowser.selectedTab.hasAttribute("pending") || this.setBrowser();
    }
}).init(document.getElementById("appcontent")))();


□□□□□□□□□□□ пишет:

только я привык к этой кнопке, бац и обновления 71

Не подходит тебе CB, не те нынче времена.
Может лучше сделай себе аналогичный WebExtensions.
Прослужит дольше, а если сводить его в мазилу на приём к подписологу,
то вообще будет вечное, разве что только зависимо от рутрекера.

Собственно нужно два текстовых файла и парочка иконок.
Запаковываешь всё это в зип-папку, называешь как_нибудь.xpi
и всё, можно устанавливать. Простенький набросок:

скрытый текст
manifest.json

Выделить код

Код:

{
    "manifest_version": 2,
    "name": "Some WebExtensions Name",
    "version": "1.0",
    "description": "Some WebExtensions Description",
    "applications": {
        "gecko": {
            "id": "{1136c9cb-3899-41d3-8a71-61d74140780d}"
        }
    },
    "icons": {
        "32": "webextensions-image32.png"
    },
    "permissions": [
        "tabs",
        "clipboardWrite"
    ],
    "browser_action": {
        "default_icon": "button-image32.png",
        "default_title": "Some Button Title"
    },
    "background": {
        "scripts": ["background.js"]
    }
}

background.js

Выделить код

Код:

var re = /(.+) (\(.+\)) \[(\d{4})[^\]]+\] (.+) (.+) (.+)/;
var query = {active: true, currentWindow: true};

browser.browserAction.onClicked.addListener(async () => {
    var [tab] = await browser.tabs.query(query);
    var {title} = tab;
    re.test(title) && navigator.clipboard.writeText(
        title
            .replace(re, "$1 $2 ($4) ($3)")
            .replace(/ \/ /g, " - ")
    );
});

Отсутствует

 

№1394406-12-2019 22:43:30

solombala
Участник
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 280
UA: Firefox 71.0

Re: Custom Buttons

Dumby
Еще не было случая , что бы ты промахнулся... Ф, что на это скажите? https://forum.mozilla-russia.org/viewto … 88#p775488
Лажа какая-то...?

Отредактировано solombala (06-12-2019 22:44:00)

Отсутствует

 

№1394506-12-2019 23:52:07

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

Re: Custom Buttons

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

Добавлено 07-12-2019 00:18:55
еще хотел замену двоеточию на юникодный символ,

.replace(/ \: /g, " ׃ ")  что то не так сделал, плиз покажи как

Отредактировано Mrakobes666 (07-12-2019 00:18:55)

Отсутствует

 

№1394607-12-2019 09:09:11

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

Re: Custom Buttons

solombala пишет:

что на это скажите?

Ну, попробовал проверить на 73. Такие наблюдения

скрытый текст
Создал в папке chrome файл proxy.pac следующего содержания:
var FindProxyForURL = () => "DIRECT"; alert(this);

Создал кнопку и расположил её первой на Панели меню.
Установил network.proxy.type - 2
и network.proxy.autoconfig_url - resource://chrome/proxy.pac

Рестарт. В консоли вижу сообщение:
PAC-alert: [object PACResolutionThreadGlobal]

и, следом за ним, второе:
PAC file installed from file:///C:/Users/Admin/AppData/Roaming/-bla-bla-bla-/chrome/proxy.pac

Так что сама концепция, видимо, работает.

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

То есть, полагаю, здесь весьма скользкая тайминг-грань.
Если так уж прямо нужно «заресурсить» папку chrome,
то надёжнее видоизменить код и расположить его в config.js

Выделить код

Код:

//
try {(ios => ios.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
    .setSubstitution("chrome", ios.newFileURI(
        Cc["@mozilla.org/file/directory_service;1"]
            .getService(Ci.nsIDirectoryService)
            .QueryInterface(Ci.nsIProperties)
            .get("UChrm", Ci.nsIFile)
    ))
)(Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService));}
catch(ex) {Cu.reportError(ex);}


□□□□□□□□□□□ пишет:

.replace(/ \: /g, " ׃ ")  что то не так сделал, плиз покажи как

Здесь у тебя идёт замена последовательностей
«пробел — двоеточие — пробел» на последовательность
«пробел — HEBREW PUNCTUATION SOF PASUQ (\u05C3) — пробел».

Код вполне рабочий, обратный экранирующий слэш
в этой регулярке не нужен, но и не мешает.

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

Отсутствует

 

№1394707-12-2019 09:18:43

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

Re: Custom Buttons

Dumby пишет:

так что замысел непонятен, а угадатель из меня никакой

прошу прощения, вот:

Рэмбо: Последняя кровь / Rambo: Last Blood (Адриан Грюнберг / Adrian Grunberg) [2019, США, боевик, триллер, приключения, HDRip] Dub (iTunes)

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

Рэмбо׃ Последняя кровь - Rambo׃ Last Blood (Адриан Грюнберг - Adrian Grunberg) (2019)

в этом примере визуально осталось двоеточие, но оно в символах unicode

еще бы ? заменить на .. к примеру ‽

как написать строку реплейс?

Добавлено 07-12-2019 09:43:36
.replace(/: /g, "׃ ")
.replace(/? /g, "‽ ")

не пашет

Отредактировано Mrakobes666 (07-12-2019 09:43:36)

Отсутствует

 

№1394807-12-2019 11:41:27

solombala
Участник
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 280
UA: Firefox 71.0

Re: Custom Buttons

Dumby
то jе дисно тонка гранка... Работают два proxy.pac , как и раньше, но на Socks. И то надо знать какие и саму 71 рихтануть надо в модулях.Блокировки не прокатят без этого!
https://s19.directupload.net/images/191207/temp/ydd8g3kn.png

Отсутствует

 

№1394907-12-2019 12:02:10

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

Re: Custom Buttons

□□□□□□□□□□□ пишет:

не пашет

Так у тебя строка с «Рэмбо» не подходит под твой основной RegExp,
потому что она, в отличие от строки с «Как чокнутые», не заканчивается на « :: RuTracker.org».

То, что в предполагаемой результирующей строке от строки с «Рэмбо»
отсутствует напрашивающийся «(Dub (iTunes))» окончательно запутывает ситуацию.

Замысел остаётся непонятен. Тогда наугад — обе строки подходят под RegExp,
и двоеточие, соответственно, будет успешно реплейситься так, как у тебя написано,
но «(Dub (iTunes))» во второй результирующей строке будет.

Вот такой новый RegExp:
var re = /(.+) (\(.+\)) \[(\d{4})[^\]]+\] (.+ \((.+)\))( .+)?/;

Отсутствует

 

№1395007-12-2019 13:19:45

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

Re: Custom Buttons

Dumby вот досада, я сам забыл, что под регулярку попадает строка из названия вкладки, сам же это придумал, выходит Вы лучше меня знаете мои же запросы)))

совершенно верно, эта строка:

Рэмбо: Последняя кровь / Rambo: Last Blood (Адриан Грюнберг / Adrian Grunberg) [2019, США, боевик, триллер, приключения, HDRip] Dub (iTunes) :: RuTracker.org

Должна стать этим:

Рэмбо׃ Последняя кровь - Rambo׃ Last Blood (Адриан Грюнберг - Adrian Grunberg) (Dub (iTunes)) (2019)

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

признаюсь, что запутал Вас

Выделить код

Код:

var re = /(.+) (\(.+\)) \[(\d{4})[^\]]+\] (.+ \((.+)\))( .+)?/;
var query = {active: true, currentWindow: true};

browser.browserAction.onClicked.addListener(async () => {
    var [tab] = await browser.tabs.query(query);
    var {title} = tab;
    re.test(title) && navigator.clipboard.writeText(
        title
            .replace(re, "$1 $2 ($4) ($3)")
            .replace(/ \/ /g, " - ")
    );
});

этот код работает правильно, информацию об аудиодороге (Dub (iTunes)) вставляет в нужное место

теперь бы дополнить строкой по замене двух запрещенных символов : и ? на ׃  и ‽ соответственно

чтобы было

Куда ты пропала, Бернадетт? / Where'd You Go, Bernadette (Ричард Линклейтер / Richard Linklater) [2019, США, драма, комедия, детектив, BDRip] Dub (iTunes) :: RuTracker.org

стало

Куда ты пропала, Бернадетт - Where'd You Go, Bernadette (Ричард Линклейтер - Richard Linklater) (Dub (iTunes)) (2019)

Отредактировано Mrakobes666 (07-12-2019 13:23:26)

Отсутствует

 

Board footer

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