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

Список ответов на каверзные вопросы можно получить в FAQ-разделе форума.

№1395111-12-2019 17:27:14

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

Re: Custom Buttons

Dumby
В71 размер иконок СВ заманал... Как уменьшить?

скрытый текст
.card-heading-icon > .addon[type="custombuttons"] .icon (
  width: 16px !important;
  height: 16px !important;
)

Отсутствует

 

№1395211-12-2019 18:43:29

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

Re: Custom Buttons

solombala
Вот парочка вариантов, которые работают.
Может ещё как-нибудь можно. А вот как лучше — без понятия.

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

Выделить код

Код:

addon-card[addon-id^="custombutton://buttons/"] .addon-icon {
    width: 16px !important;
    height: 16px !important;
    /*
    padding-top: 3px !important;
    */
}
Выделить код

Код:

addon-list[type=custombuttons] .addon-icon {
    width: 16px !important;
    height: 16px !important;
    /*
    padding-top: 3px !important;
    */
}

Отсутствует

 

№1395311-12-2019 19:12:45

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

Re: Custom Buttons

Dumby
Если знать куда вставлять, то шикардос! Так, раз уж ты король кнопок , как тут выровнять? Значок могу шевелить , а текст то не опустится...Тако курвье будали ово мазиловци.
fzn79br5.png

Отредактировано solombala (12-12-2019 11:48:41)

Отсутствует

 

№1395412-12-2019 14:01:48

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

Re: Custom Buttons

solombala пишет

как тут выровнять? Значок могу шевелить , а текст то не опустится...

Попробуй так:

Выделить код

Код:

addon-list[type=custombuttons] .card-contents {
    padding-top: 3px !important;
}

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


«The Truth Is Out There»

Отсутствует

 

№1395512-12-2019 14:20:42

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

Re: Custom Buttons

unter_officer
Шикарно! Жаль размер текста никак...

Отсутствует

 

№1395612-12-2019 15:25:12

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

Re: Custom Buttons

solombala пишет

Жаль размер текста никак...

addon-list[type=custombuttons] .addon-name {
    font-size: 22px !important;
}


«The Truth Is Out There»

Отсутствует

 

№1395712-12-2019 15:53:19

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

Re: Custom Buttons

unter_officer

unter_officer пишет

addon-list[type=custombuttons] .addon-name {
    font-size: 22px !important;
}

Не срабатывает. И самих аддонов тоже не могу сделать.

Отсутствует

 

№1395812-12-2019 16:22:15

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

Re: Custom Buttons

solombala пишет

И самих аддонов тоже не могу сделать.

В этом коде font-size не для всех аддонов, а только для СВ.

solombala пишет

Не срабатывает.

Не срабатывает возможно из-за версии [firefox], я на 68 ESR проверял, там срабатывает. А [firefox] 71+ я пока не устанавливал, поэтому проверить не могу.


«The Truth Is Out There»

Отсутствует

 

№1395913-12-2019 08:37:08

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

Re: Custom Buttons

Dumby
В 71 отрихтованая Вами Flip-Close_Tab ....ПКМ -  на prev Tab - не пашет ( это я па правый переделал  , но сам код не трогал) В 70 - океу...

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

Выделить код

Код:

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 == 2) {
                        var old = gtBrowser.selectedTab;
                        var tabs = Array.filter(old.parentNode.getElementsByAttribute("flipselectedID", "*"), tab => !tab.hidden && !tab.closing);
                        var last  = 2;
                        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 == 0) {
                        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) { }

Отсутствует

 

№1396013-12-2019 13:59:57

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

Re: Custom Buttons

solombala пишет

ПКМ -  на prev Tab - не пашет ( это я па правый переделал  , но сам код не трогал)

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

Выделить код

Код:

toolbarbutton_0.addEventListener("click", function(event) {
                    var gtBrowser = window.gBrowser;
                    if (event.button == 2) {
                        event.preventDefault();
                        event.stopPropagation();
                        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 == 0) {
                        gtBrowser.removeTab(gtBrowser.selectedTab);
                    }
                }, false);

Отсутствует

 

№1396113-12-2019 14:31:03

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

Re: Custom Buttons

Dumby
Круто , очень ! Нема речи!

Отсутствует

 

№1396214-12-2019 16:22:49

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

Re: Custom Buttons

Есть кнопка Proxy. В ней есть функция:

Выделить код

Код:

// Функция открывает настройки прокси в окне ...................  
function openConnections() {
   self.win && self.win.close();
   self.win = openDialog("chrome://browser/content/preferences/connection.xul", "Proxy", "centerscreen");
   
   // добавить атрибут "prefwindow"
   self.win.addEventListener("load", function f(e) {
       this.removeEventListener("load", f, true); 
       e.target.documentElement.setAttribute("type", "prefwindow");
   }, true);

   // закрыть настройки прокси по клику на странице 
   gBrowser.addEventListener("click", function c() {
      this.removeEventListener("click", c);
      try { self.win.close() } catch(e) {}; 
   }, true);
};

В целом функция работает нормально - открывает настройки прокси в окне, но при этом в консоли появляется ошибка: TypeError: window.opener.gSubDialog is undefined
Поскольку всё работает, ошибка особо не напрягает, но всё же, возможно ли это поправить под [firefox] 68 ESR?


«The Truth Is Out There»

Отсутствует

 

№1396314-12-2019 16:57:42

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

Re: Custom Buttons

Dumby
Что с мульти в 71? Код config.js  ? В портабл в ini это MOZ_FORCE_DISABLE_E10S=1
Раньше обходилось  config.js и кнопкой   cbu.setPrefs(s, cbu.getPrefs(s) == true ? false : true);
Теперь наглухо только  MOZ_FORCE_DISABLE_E10S .... " Проблема небольшая с раскрытием подробностей в about:addons (кнопки СВ - редактирование) и аддоны тоже..
Шняга  вылазит ..Типа, не может протокол обработать ...
https://forum.mozilla-russia.org/viewto … 94#p775894

Отредактировано solombala (14-12-2019 17:29:03)

Отсутствует

 

№1396414-12-2019 20:17:29

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

Re: Custom Buttons

unter_officer пишет

поправить под [firefox] 68 ESR

Может так

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

Выделить код

Код:

function openConnections() {
    var url = "chrome://browser/content/preferences/connection.xul";
    var win = [...Services.wm.getEnumerator(null)].find(w => w.location == url);
    if (win) return win.focus();

    win = openDialog(url, "Proxy", "centerscreen");
    win.opener = {gSubDialog: {_dialogs: [{
        _frame: {get contentDocument() {
            var args = ["click", win.close.bind(win), true];
            var unload = () => gBrowser.removeEventListener(...args);
            gBrowser.addEventListener(...args);
            win.addEventListener("unload", unload, {once: true});

            delete this.contentDocument;
            return this.contentDocument = win.document;
        }},
        resizeVertically: () => win.sizeToContent()
    }]}};
}

solombala пишет

Раньше обходилось  config.js и кнопкой

Это похерили ещё в 70. Я пробовал тогда раскопать,
и мне показалось, что вот здесь расклад запрашивается
для решения, запускать ли socket-процесс, а будучи запрошенным,
всё, поздно уже что-то в config.js переставлять.
Но, разумеется, это гадание на кофейной гуще, факт лишь в том,
что работать перестало, и с этим ничего не поделаешь.

solombala пишет

Шняга  вылазит

Да, у меня воспроизводится, если отключить многопроцессность,
и кликать по названию аддона.
Как любителю правки omni.ja, могу предложить попробовать
добавить e.preventDefault(); в aboutaddons.js, вот сюда

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

Выделить код

Код:

default:
          // Handle a click on the card itself.
          if (
            !this.expanded &&
            (e.target === this.addonNameEl || !e.target.closest("a"))
          ) {
            e.preventDefault(); // <= ДОБАВИТЬ
            loadViewFn(`detail/${this.addon.id}`, e);
          } else if (

Отсутствует

 

№1396514-12-2019 20:31:57

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

Re: Custom Buttons

Dumby пишет

Может так

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

Выделить код

Код:

function openConnections() {
    var url = "chrome://browser/content/preferences/connection.xul";
    var win = [...Services.wm.getEnumerator(null)].find(w => w.location == url);
    if (win) return win.focus();

    win = openDialog(url, "Proxy", "centerscreen");
    win.opener = {gSubDialog: {_dialogs: [{
        _frame: {get contentDocument() {
            var args = ["click", win.close.bind(win), true];
            var unload = () => gBrowser.removeEventListener(...args);
            gBrowser.addEventListener(...args);
            win.addEventListener("unload", unload, {once: true});

            delete this.contentDocument;
            return this.contentDocument = win.document;
        }},
        resizeVertically: () => win.sizeToContent()
    }]}};
}

То, что надо! Спасибо!


«The Truth Is Out There»

Отсутствует

 

№1396614-12-2019 21:10:35

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

Re: Custom Buttons

Dumby
На аддонах вроде перестало вылазить...А на кнопках  СВ - также...Может там рихтануть?

Отсутствует

 

№1396714-12-2019 21:18:56

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

Re: Custom Buttons

solombala пишет

А на кнопках  СВ - также...Может там рихтануть?

Да, точно, в CB тоже e.preventDefault() надо дописать.
Я добавлю в addons-html.js, спасибо.

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

Выделить код

Код:

click(e) {
        if (this.cbAddonList && !e.button && !e.target.matches(this.ignoreClickSelectors)) {
            var addon = a(e);
            if (addon) e.stopPropagation(), e.preventDefault(), e.detail == 1 && this.editButton(addon);
        }
    },

Отсутствует

 

№1396814-12-2019 21:31:03

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

Re: Custom Buttons

Dumby
Курвье  маjка ! Три дня мудохался , пока мульти определил... Благо есть такие врачи ...Хвала, брате! Чува тебе Бог!

browser.tabs.remote.autostart - true // На СВ - влияет , только true !
Очередная поганка! https://forum.mozilla-russia.org/viewto … 53#p775953
Нужен код в config.js ///Эта штука в ini MOZ_FORCE_DISABLE_E10S=  все портит...

Отредактировано solombala (15-12-2019 20:45:42)

Отсутствует

 

№1396916-12-2019 12:15:21

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

Re: Custom Buttons

Dumby скажи пожалуйста в вновь создаваемых кнопках в секциях Код и Инициализация отсутствуют /*CODE*/ и /*Initialization Code*/ так должно быть или только у меня?
Версия 71 и custom_buttons-0.0.7.0.0.8-fx-paxmod.xpi, кеш сброшен

В кнопке

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

Выделить код

Код:

/*Initialization Code*/

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

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

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

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

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


перестали работать 2 и 3 пункты, ссылаясь на var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft;
Глянте пожайлуста.

solombala пишет

Доп пункты в about;addons

обсуждалось на 556 стр. со значками и без. Мой вариант

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

Выделить код

Код:

//Дополнительные пункты контекстного меню на странице about:addons для аддонов, плагинов, тем, CB.....................................................................................
((id, g, iconizer) => addDestructor(r => r[5] == "e" && id in g && g[id].destroy()) + addEventListener("shown", {
    //------------------------------------------------------------------
    "Копировать имя_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByUlEQVQ4jY2TTUhUURiGn5tD0Sp00iAwXM1iFu4kWkUZg/9MoZQhdoUCV7ooItq4atFORRGkuLMwoc0kNBGKDLSwFpEIQgspqGUUNsjI3HvPX4s7I3Nn7oW+1fn5vvd8z3vOsYiIgXuPneFMr21ZVmh9+m7GisoPxcTsM2d46on5c1gy9bHgvDVR+afqJzNzy870xIgNUJGGkqf4XVEAuJ4XeWCiNpibX3MGr/XYPd0pADxlOK0MQgf7Xw++sfJq0zRiJQAWcgWndHRkr28UWcrlAfCVwa8KrK4XOPxbYqz/MsnWcyfFi7lCIPD9x0/70YNRykKz+eELQkny74sIJbnQmqQ71UVhe+cES2hoP9uC63mBgO/7dF7s4NexZPRmBqlBaMPHnc+kL7UTh1VxqwKuGxjkaUP+zRZCSVqwKJeP2dvdj8SqGZuod9hXhr6hGwgNL5ZfEoc1PnaL2sFNAlvvthFKxmJJbfCUqXbghhHSyTOkJwcBmHr4vAnLVwKhJEPZbLgDXwh678yG7rfjfLIJS2qD0IEP9R6kiq8XrzS+sOz9p5+asKodXB0YCQkcNBbHYUXlxP6u67dnIj9PY8QJpIC2/6iX/wDxeTOAfNDrywAAAABJRU5ErkJggg==",
    "Копировать имя"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.name);
    },
    //------------------------------------------------------------------
    "Копировать ID_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByUlEQVQ4jY2TTUhUURiGn5tD0Sp00iAwXM1iFu4kWkUZg/9MoZQhdoUCV7ooItq4atFORRGkuLMwoc0kNBGKDLSwFpEIQgspqGUUNsjI3HvPX4s7I3Nn7oW+1fn5vvd8z3vOsYiIgXuPneFMr21ZVmh9+m7GisoPxcTsM2d46on5c1gy9bHgvDVR+afqJzNzy870xIgNUJGGkqf4XVEAuJ4XeWCiNpibX3MGr/XYPd0pADxlOK0MQgf7Xw++sfJq0zRiJQAWcgWndHRkr28UWcrlAfCVwa8KrK4XOPxbYqz/MsnWcyfFi7lCIPD9x0/70YNRykKz+eELQkny74sIJbnQmqQ71UVhe+cES2hoP9uC63mBgO/7dF7s4NexZPRmBqlBaMPHnc+kL7UTh1VxqwKuGxjkaUP+zRZCSVqwKJeP2dvdj8SqGZuod9hXhr6hGwgNL5ZfEoc1PnaL2sFNAlvvthFKxmJJbfCUqXbghhHSyTOkJwcBmHr4vAnLVwKhJEPZbLgDXwh678yG7rfjfLIJS2qD0IEP9R6kiq8XrzS+sOz9p5+asKodXB0YCQkcNBbHYUXlxP6u67dnIj9PY8QJpIC2/6iX/wDxeTOAfNDrywAAAABJRU5ErkJggg==",
    "Копировать ID"(addon, hideOn) {
        if (hideOn) return false;

        gClipboard.write(addon.id);
    },
    //------------------------------------------------------------------
    "Копировать версию_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByUlEQVQ4jY2TTUhUURiGn5tD0Sp00iAwXM1iFu4kWkUZg/9MoZQhdoUCV7ooItq4atFORRGkuLMwoc0kNBGKDLSwFpEIQgspqGUUNsjI3HvPX4s7I3Nn7oW+1fn5vvd8z3vOsYiIgXuPneFMr21ZVmh9+m7GisoPxcTsM2d46on5c1gy9bHgvDVR+afqJzNzy870xIgNUJGGkqf4XVEAuJ4XeWCiNpibX3MGr/XYPd0pADxlOK0MQgf7Xw++sfJq0zRiJQAWcgWndHRkr28UWcrlAfCVwa8KrK4XOPxbYqz/MsnWcyfFi7lCIPD9x0/70YNRykKz+eELQkny74sIJbnQmqQ71UVhe+cES2hoP9uC63mBgO/7dF7s4NexZPRmBqlBaMPHnc+kL7UTh1VxqwKuGxjkaUP+zRZCSVqwKJeP2dvdj8SqGZuod9hXhr6hGwgNL5ZfEoc1PnaL2sFNAlvvthFKxmJJbfCUqXbghhHSyTOkJwcBmHr4vAnLVwKhJEPZbLgDXwh678yG7rfjfLIJS2qD0IEP9R6kiq8XrzS+sOz9p5+asKodXB0YCQkcNBbHYUXlxP6u67dnIj9PY8QJpIC2/6iX/wDxeTOAfNDrywAAAABJRU5ErkJggg==",
    "Копировать версию"(addon, hideOn) {
        if (hideOn) return ["custombuttons"];

        gClipboard.write(addon.version);
    },
    //------------------------------------------------------------------
    "Копировать имя и версию_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAByUlEQVQ4jY2TTUhUURiGn5tD0Sp00iAwXM1iFu4kWkUZg/9MoZQhdoUCV7ooItq4atFORRGkuLMwoc0kNBGKDLSwFpEIQgspqGUUNsjI3HvPX4s7I3Nn7oW+1fn5vvd8z3vOsYiIgXuPneFMr21ZVmh9+m7GisoPxcTsM2d46on5c1gy9bHgvDVR+afqJzNzy870xIgNUJGGkqf4XVEAuJ4XeWCiNpibX3MGr/XYPd0pADxlOK0MQgf7Xw++sfJq0zRiJQAWcgWndHRkr28UWcrlAfCVwa8KrK4XOPxbYqz/MsnWcyfFi7lCIPD9x0/70YNRykKz+eELQkny74sIJbnQmqQ71UVhe+cES2hoP9uC63mBgO/7dF7s4NexZPRmBqlBaMPHnc+kL7UTh1VxqwKuGxjkaUP+zRZCSVqwKJeP2dvdj8SqGZuod9hXhr6hGwgNL5ZfEoc1PnaL2sFNAlvvthFKxmJJbfCUqXbghhHSyTOkJwcBmHr4vAnLVwKhJEPZbLgDXwh678yG7rfjfLIJS2qD0IEP9R6kiq8XrzS+sOz9p5+asKodXB0YCQkcNBbHYUXlxP6u67dnIj9PY8QJpIC2/6iX/wDxeTOAfNDrywAAAABJRU5ErkJggg==",
    "Копировать имя и версию"(addon, hideOn) {
        if (hideOn) return ["custombuttons"];

        gClipboard.write(addon.name + " " + addon.version);
    },
    //------------------------------------------------------------------
    "Домашняя страница_i": "data:image/png;base64,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",
    "Домашняя страница"(addon, hideOn) {
        if (hideOn) return !addon.homepageURL;

        var url = addon.homepageURL;
        if (!url) {
        if (addon.reviewURL) {
        url = addon.reviewURL.replace(/\/reviews\/.*$/, "/");
        }
        }
       openURL(url);
    },
    //------------------------------------------------------------------
    "Поиск на АМО_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAJGSURBVDjLjdJLSNRBHMDx78yqLZaKS75DPdgDDaFDbdJmde5QlhCJGxgpRJfqEEKnIsJLB7skQYQKZaSmdLaopPCgEvSCShCMzR5a7oq7/3l12RVtjfzBMA/4fWZ+MyOccwBM3g8HEbIdfCEhfAFnLVapOa28Uevpjrqz/WOsERJgsu9Uq5CZQzgqrJfo9BajNd5irEYn4p3OUiFExtCLmw2tawFi4l5zUMjMIau9u7K+qxeoAcoAA0wDb2OPwmfA16LiiaOHLj1edRLpkO3WmIis7+oBDgJbgQ2AH6gC6jY19N62RkcctKeVIJAhp9QgUA3kJXdONZVcq9JxPSgQoXRAyIDRth8oAXQyKdWnoCKrTD9CBv4GMqx1WGNZkeRWJKbG2hiD1Cb9FbTnzWFdY/LCdLKlgNQ84gyNKqHm0gDjqVHnxDHgA/B9RQkpaB6YklkZl62np9KBhOqwjpKFgeY2YAz4BESBWHI8Hhs6PVVSvc3v98ye4fP7T676B845nt040ip98qpWJmI9PWiU6bfWgXGN2YHcKwU7tsuc4kpUPMbU0+f8+vKt+Pitl7PLAMDI9cNBoB0hQwICzjqUp6MZvsy8yvp95BRuQUjJ75mPvH4wYo1NlJ64Mza7DPwrhi8cCOeXl/aUB4P4c/NJxKLMvpngycCrzxVFG2v/CwAMnguF80oLe8p27cQh+fnpPV/fTc95S6piXQDAw7a9YbWkezZXFbAwMx/xPFXb1D3+Y90AQF/L7kAsri9mZ4lrTd0TcYA/Kakr+x2JSPUAAAAASUVORK5CYII=",
    "Поиск на АМО"(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);
    },
    //------------------------------------------------------------------
    "Папка установки_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABAklEQVR42mNkoBAwAjEXEAcCMTsW+U9AvB6I/+I0gJ2Noe3QJoZKASEgjwkq+h+C795lYPCKZMgC8mZg0fsfbICIIMOcF6cZkrGZ/v8fA0PndIa/7z8BXfAPqgVKv//A8GPeZoYERmE+hjmP1+AwAOgiTjOIP7HZLyjLMJNRmB/ogjMMyYzsUC8wIhQwsgCFWHAHoKAy0AARIYY5r69idwEhIKgBMgAYBq8vkGmALsyAU2QaYAwz4CiZBliADBAAGnCATANsYQbsJtMAJ5ABwGh8uZE8A4R9gAYwMzHkT8hl6Bfgxp5ecIH3Xxj+F05hyIdpUmXAnpnwge9AfJckW7EBAC/gSzisxsnmAAAAAElFTkSuQmCC",
        "Папка установки"(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);
                }
            }
    },
    //------------------------------------------------------------------
    "Файл установки_i": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAA51AAAOdQG5Y1EyAAAAhklEQVQ4y6WT0QnAIAxE78Bt2v1cod3PznP9kVLTRKUGBD+Sd5eQUBJWggCWCAkAJPGXOqlUPyVKkrSPQIoCQJGE6AF4HFyGuBmrR3cGQX8Wmp2cL8Cqv5JPD5Zm1D0nFZjTjHpQ7DuI1L3iBjBS9/pvhtjr21OukVkXiX/ug6SWj4mr53wDMz1vldHlLJkAAAAASUVORK5CYII=",
        "Файл установки"(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 = 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;
    },
    revealPath: function(path){
            var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
            file.initWithPath(path);
            if(file.exists())
                file.reveal();
        }
}, true, gBrowser.tabpanels || 1))("CBAddonsMenuExt", Cu.import("resource://gre/modules/Services.jsm", {}), {});


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

((cn, flag, css) => addEventListener("update", ({
    btnActions: ["preferences", "toggle-disabled", "remove", "install-update"],
    every(reason) {
        reason || addDestructor(this.every, this);
        var g = this.g || (this.g = Cu.import(
            "resource://gre/modules/AddonManager.jsm", {}
        ));
        var has = flag in g;
        if (reason) {
            if (!has || reason[5] != "e") return;
        } else if (has) return this;

        var method, wins = Array.from(
            g.AddonManagerInternal.addonListeners, Cu.getGlobalForObject
        ).filter(
            w => w.docShell && w.docShell.name == "html-view-browser"
        );
        if (reason) method = "destroyDoc", delete g[flag];
        else method = "initDoc", g[flag] = true;
        for(var win of new Set(wins)) this[method](win.document);
        return this;
    },
    initDoc(doc, onlyStyle) {
        if (doc[flag]) return; doc[flag] = true;
        doc.ownerGlobal.windowUtils.loadSheetUsingURIString(this.url, this.type);
        if (onlyStyle) return;
        for(var card of doc.getElementsByTagName("addon-card")) this.onCard(card);
    },
    destroyDoc(doc) {
        if (!doc[flag]) return; delete doc[flag];
        for(var span of Array.from(doc.getElementsByClassName(cn))) span.remove();
        doc.ownerGlobal.windowUtils.removeSheetUsingURIString(this.url, this.type);
    },
    get url() {
        this.type = windowUtils.USER_SHEET;
        this.btnActions = this.btnActions.map(
            action => `panel-list > panel-item[action="${action}"]`
        );
        delete this.url;
        return this.url = "data:text/css;charset=utf-8," +
            encodeURIComponent(css.replace(/;/g, " !important;"));
    },
    handleEvent(e) {
        var card = e.target;
        card.nodeName == "ADDON-CARD" && this.onCard(card);
    },
    onCard(card, again) {
        var div = card.querySelector("div.more-options-menu");
        if (!div) return again || card.ownerGlobal.requestAnimationFrame(
            () => this.onCard(card, true)
        );
        var [span] = card.getElementsByClassName(cn);
        if (span) span.textContent = "";
        else {
            var doc = card.ownerDocument;
            doc[flag] || this.initDoc(doc, true);
            div.before(span = doc.createElement("span"));
            span.className = cn;
            span.onclick = this.onclick;
        }
        var btns = this.btnActions.map(sel => {
            var item = div.querySelector(sel);
            return item && item.cloneNode(true);
        });
        var {addon} = card, cbbtn = addon.type == "custombuttons";
        for(var item of btns) if (item) {
            span.append(item);
            item.shadowRoot.querySelector("button").classList.add("cb-cloned-button");
            if (cbbtn) item.closest = this.closest;
        }
        if (addon.id != "custombuttons@xsms.org") return;
        var item = span.querySelector("[action=preferences]");
        if (item) item.removeAttribute("hidden"), item.onclick = this.cbprefs;
    },
    onclick(e) {
        InspectorUtils.removeContentState(e.target, 4, true);
        Services.focus.clearFocus(e.target.ownerGlobal);
    },
    closest(sel) {
        return sel == ".more-options-menu" || this.ownerGlobal
            .Element.prototype.closest.call(this, sel);
    },
    cbprefs(e) {
        var url = "chrome://custombuttons/content/prefs.xul";
        for(var win of Services.wm.getEnumerator(null))
            if (!win.closed && win.document.documentURI == url)
                return win.focus();
        e.view.requestAnimationFrame(() => openDialog(
            url, "", "chrome,titlebar,toolbar,centerscreen,modal"
        ));
    }
}).every(), true))("cb-cloned-buttons-container", "AAcbButtonizedFlag", `

    addon-card:not([expanded]) .card-contents {
        width: 1px;
    }
    span.cb-cloned-buttons-container {
        display: flex;
    }
    button.cb-cloned-button {
        width: auto;
        padding: 1px 6px 3px 6px;
        margin: 0 1px;
        background-image: none;
//background: #CCFFFF ;
  border: 1px solid var(--in-content-box-border-color); 

//border-style: solid;  
//border-color: #99FFFF #99FFFF;
        border-radius: 0px;

        font-size: 13px;
        font-family: Segoe UI;
    }
button.cb-cloned-button:hover {
background: gold ;
}
    button.cb-cloned-button:after {
        display: none;
    }
`);


Выглядит вот так
скрытый текст
_cf3b61e70f36e72956705ac525ddda4d.jpeg

Отредактировано Andrey_Krropotkin (16-12-2019 12:43:55)

Отсутствует

 

№1397016-12-2019 17:29:54

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

Re: Custom Buttons

Andrey_Krropotkin
Шикарно! А, как кнопочку эту отцентровать?  С тремя точками (querySelector?)

Отсутствует

 

№1397116-12-2019 17:37:50

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

Re: Custom Buttons

solombala а хз, не задавался этим вопросом

Отредактировано Andrey_Krropotkin (16-12-2019 17:38:21)

Отсутствует

 

№1397216-12-2019 19:07:05

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

Re: Custom Buttons

solombala пишет

А, как кнопочку эту отцентровать?

Как-то так, наверное. :/

Выделить код

Код:

@-moz-document  url-prefix(chrome://mozapps/content/extensions/) {

.more-options-button.ghost-button {
  margin: 10px 6px 0 2px !important;
}

}

Цифры свои подберешь.


«The Truth Is Out There»

Отсутствует

 

№1397316-12-2019 19:45:45

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

Re: Custom Buttons

xerjvstn.png

Отсутствует

 

№1397416-12-2019 20:35:38

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

Re: Custom Buttons

unter_officer
Все хорошо, но теперь popup при нажатии не привязан к кнопке этой . Он так и висит  справа и выше...

Отсутствует

 

№1397517-12-2019 00:15:37

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

Re: Custom Buttons

solombala
В теме по стилям Vitaliy V. вам ответил как это исправить.
У меня нет [firefox] 71, поэтому проверить не могу.

А на [firefox] 68 ESR стиль от Виталия не совсем подошел. Поэтому пришлось немного переделать под себя:

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

Выделить код

Код:

addon-card .cb-cloned-buttons-container,
addon-card .more-options-menu {
  display: flex !important;
  align-self: center !important;
  margin: 0 0 0 1px !important;
}
addon-card panel-list[valign="top"] {
  bottom: 20px !important;
}


Выберите сами, какой вариант вам подходит.

Отредактировано unter_officer (17-12-2019 00:54:51)


«The Truth Is Out There»

Отсутствует

 

Board footer

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