Объявление

В связи с наплывом спама и ботов на форуме, регистрация новых пользователей будет приостановлена. О восстановлении регистрации будет сообщено дополнительно

Administrator

№1730123-03-2025 18:07:35

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: unknown 0.0

Re: Custom Buttons

Dumby
#window-modal-dialog::backdrop {
   
      background-color: inherit !important;
}
Не тухнет, но здесь не помогло. Стоит modal выпасть ,back кнопка тухнет, а после очистки опять горит, а, ссылок там уже нет. Надо или перезапуск делать или новую открывать...
1.png
Ясен пень, SanitizeDialog  старой FF выпадает окном ,а не modal и не бьет по кнопкам

Отредактировано green25 (23-03-2025 18:50:16)

Отсутствует

 

№1730223-03-2025 19:20:24

T0PMØ3iLLA
Участник
 
Группа: Members
Зарегистрирован: 18-09-2017
Сообщений: 29
UA: Firefox 91.0

Re: Custom Buttons

Так… значит мне ничего нового прописывать уже было не нужно — заработало только либо после очистки startupCache, либо всё-таки после полного удаления расширения и повторной установки (paxmod, ибо с bootstrap`ом мне ещё лет 6 назад пришлось возиться, так и не добившись результата), довелось завести хотя бы "ночной режим"… Сразу определить работоспособность хотя бы кнопки "Ночной режим" не получилось — после очисти startupCache на спех проверялось только в about:* страницах, где, оказалось, она не работает, но после повторного добавления, наконец заработала (несмотря на то, что «затемнена», как и надпись, если добавлять в специальное "»" подменю). А вот с переключалкой настроек проблемы остались — к тому моменту уже было опробован другой код из какого-то сообщения этой темы (то ли за 21-й то ли 23/24г), но над ним мне тогда пришлось полдня повозиться, чтоб предварительно убедиться в том, что убираемые процедуры и переменные из подозрительного кода не используются в остальных его местах — скорее всего где-то тут была "промашка"…

а тот старый, что был до замены…
Пролистывая код испорченнй кнопки в AkelPad`е, сверяю Ctrl+(Shift)+Tab`ом с сохранённой в 2020-м отдельным .txt версией — особых различий в нижней части кода толком не замечаю, и, думая, что в коде ничего не менялось, тупо беру какой-то "новый" попавшийся из этой темы (то ли за 21-й, то ли за 23/24 год), удаляю оттуда кучу ненужных мне пунктов меню, включая ещё какой-то подозрительный код, обращающийся к «файловой системе» (да блин, нужен же переключатель только каких-то заранее заданных параметров — их же легко править!), и заменяю кнопку… Ну… видимо что-то при такой правке кода было что-то "лишнее удалено", раз кнопка не работает…
Добавив CB 0.0.7.0.0.16 ещё раз и вставив тот скопированный URL обратно, замечаю, что заменённая мною кнопка-то действительно не пашет…
Пробую пропихнуть поверх старую версию CB (0.0.7.0.0.11) — о! на удивление, дополнение НЕ ОТКЛЮЧИЛОСЬ! Хах! Так вот как можно "обмануть систему" (т.е. тупо удалить расширение и поставить ещё раз)? Пробую поставить ещё раз ту "сломавшуюся кнопку" (что была сохранена отдельным .txt в 2020-м) — э! Всё равно кнопка "уехала" (сместив остальные панели инструментов вместе с панелью вкладок на "пару пунктов" вниз)… Пфф… значит всё-таки где-то какая-та буква была изменена в верхней части кода, между удалёнными кусками комментариев… Видимо, и тут "промашка"…
Пришлось копировать теперь "изуродованную" кнопку со старого профиля (где она хотя бы как-то работала, но она какая-то слишком навороченная, и, следовательно, глючная)… Видимо, ради того, чтоб продолжить пользоваться классическим вариантом этой кнопки, я в итоге решусь откатиться от 91esr до какой-нибудь 88 (не esr), заодно исправив проблему глючного интерфейса самой лисы, а может ещё и проблему с подтасовкой истории переходов вкладок (предыдущая/следующая страница) вкладок в приватном просмотре… главное не забыть --allow-downgrade
Ну хоть всё равно спасибо, что разъяснили… Не стоило мне беспокоить :/
Консоль по F12 | Ctrl+Shift+I была пустая, это уже потом дошло, что нужна была консоль по Ctrl+Shift+J — после вынужденного использования "инспектора" на многих проблемных страницах (приходилось слишком часто вручную убирать "снегопад" и пр. раздражающие элементы при посещении определённых сайтов) думалось, что там консоль та же, а оказалось нет…

Отсутствует

 

№1730324-03-2025 12:13:26

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: unknown 0.0

Re: Custom Buttons

Удаляет Историю..А надо Сессии...
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_HISTORY, () => {});

Отредактировано green25 (25-03-2025 10:16:30)

Отсутствует

 

№1730427-03-2025 10:00:36

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

Re: Custom Buttons

green25
В 115 есть отдельный флаг CLEAR_SESSION_HISTORY
А в нынешних версиях уже нет, свалили докучи в CLEAR_HISTORY


В любом случае, для удаления всего,
просто рассылается топик без третьего аргумента:
Services.obs.notifyObservers(null, "browser:purge-session-history");

Отсутствует

 

№1730527-03-2025 12:29:35

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: unknown 0.0

Re: Custom Buttons

Dumby

Dumby пишет

Services.obs.notifyObservers(null, "browser:purge-session-history");

Класс, тонкий ход...

Отсутствует

 

№1730627-03-2025 21:29:11

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

Re: Custom Buttons

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

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

Выделить код

Код:

addEventListener('popupshowing', e=> {
      if (e.target != e.currentTarget) return;
      var sel = gContextMenu.isTextSelected;
      menu.hidden = !sel;
   }, false, contextMenu);

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

Выделить код

Код:

(this.contextviewpageinfo = {
    
    init(that) {
        var contextMenu = this.contextMenu = document.querySelector("#contentAreaContextMenu");
        if (!contextMenu) return;
        contextMenu.addEventListener("popupshowing", this);
     //   that.unloadlisteners.push("contextviewpageinfo");
    },
   
    handleEvent(e) {
        if (gContextMenu.isTextSelected || gContextMenu.onImage || gContextMenu.onLink || gContextMenu.webExtBrowserType === "popup") return;
        if ( document.getElementById("viewPageInf") ) return; 
        var menuitem = document.createXULElement("menuitem");
        menuitem.setAttribute("id", "viewPageInf")
        menuitem.setAttribute("label", "Информация о странице");
        menuitem.setAttribute("oncommand", "_viewPageInfo();");
        menuitem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACp0lEQVQ4jV2TPW9cVRCGn3fOuffu9Xo3TnCEkANYQotB2WJpUqWwJSqIUuQPRKKlsAUFpeUmEpXXEv+ACClFitQowmUIMmxASowIkjuQk9jr/fDd7F3fQ7HWdcxI04zmfc47RzPif9G4cXdR0iqy5flL9VYRAoe9rCNpG9nW7v1be2/2qxR+/v0c0vp7C/NrV5euMCkijoYTXucnEALDYcaLwx7DLGsjbTy7d7NbAk7FP12/ttSq1uZ48vyYLA/UZhwg+qMCZ5A6GGVDesODDtLK0x8+69rUh9avX1tqWVzn0dMhWR4A8eDOxzy48xEyEWQcB4O0Tlq73JK5dQBr3Li7+P7C/NpsbY4nf2dTTxKYyhnNG/KGeQfeEVXrRJXqWvP2w0UvafXq0rv8+vz4TCwhJz795s/p62ZlHQkJ4uoFTnqvVj2y5UnwZOP8XNPj75rlTze/3MV5YU4IoQCJS5Bzy3b5rXrraDgBQQEMRgUH/QmNL/4oAXHiiSueJPUkM554JmK2FlGppC1fBBjnBeNJ4HAwQWZEicN7KwFRxeHjaU1mSDCbBIZ9jx0cHXfyyQkvD3NCAHPCnOEid85BUvEkMxGV6jQvzkVk45OOSdp+dTDAOZDpFCCcK3cMnziiiidJp+JaPcZZgZzfNmRbR4MBl2aENE0zIXc2go8cUeKJU0+lGvPhlYh/9kfI3Jbt3r+1N85ftykyUkcJ6Ww2SsCPX7+Nc4aPHY2FiH5vzL8vx+2dzeaeP93Ejfykv+zMtwKzAHzy1V8kaVTOXavFfDAP3f0BP+8cdGS2AWAAz+7d7CKtSL22D11U5MQBqha4GAfeqQYuKOP33/Z59PhFmxBWfvm2cXZMb0bz9sNFma3K+eUkSVs+dozyoiPnt2Vua2ezee6c/wN/E94boB6vcgAAAABJRU5ErkJggg==");
        menuitem.className = "menuitem-iconic";
        menuitem._viewPageInfo = this.viewPageInfo.bind(this);

        addDestructor(function() { contextMenu.removeChild( menuitem ) });

        (this.contextMenu.querySelector("#context-viewsource") || this.contextMenu.lastElementChild).after(menuitem);
        this.handleEvent = () => menuitem.hidden = (gContextMenu.isTextSelected || gContextMenu.onImage || gContextMenu.onLink || gContextMenu.webExtBrowserType === "popup");
    },
    viewPageInfo() {
        BrowserCommands.pageInfo(
            gContextMenu.contentData.docLocation,
            "generalTab",
            gContextMenu.PageInfo,
            null,
            gContextMenu.browser
        );
    },
}).init(this);


Я считаю что в этом коде слишком перемудрено
 
И вот что заметил если использую кнопку Source Editor, которую недавно подправили, в ошибках при редактировании любой кнопки в ошибках показывает такое сообщение -TypeError: this.cssProperties is undefined, хотя оно не на что не влияет
.
Еще один момент. Есть код. Там ошибка, которая тоже не на что не влияет - Uncaught Error: Action with ID 'TranslateBufer1' already added, опять же при редактировании этой кнопки
скрытый текст

Выделить код

Код:

((id, g) => addDestructor(reason => id in g && g[id].destroy(reason)) || id in g || ({
    actions: [{
        title: "Перевод из буфера",
        tooltip: "Перевод из буфера",
        iconURL: gticon,
        id: "TranslateBufer1",
        _insertBeforeActionID: "copyURL",

        onCommand: (e, btn) => ujs_google_translat('auto|ru')
    }],
    init() {
        g[id] = this;
        this.actions = this.actions.map(action => {
            action.extensionID = "custombuttons@xsms.org";
            return g.PageActions.addAction(new g.PageActions.Action(action));
        });
    },
    destroy(reason) {
        if (reason[5] != "e") return;
        delete g[id];
        for(var action of this.actions) action.remove();
    }
}).init())(
    "CBPageActionsMaker", ChromeUtils.importESModule("resource:///modules/PageActions.sys.mjs", {})
);


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

Отредактировано Andrey_Krropotkin (28-03-2025 07:39:48)

Отсутствует

 

№1730730-03-2025 10:49:11

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: unknown 0.0

Re: Custom Buttons

Чья кнопка ? Перестала менять ,кроме строки адреса...Раньше в любом поиске меняла....

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

Выделить код

Код:

(keybUtils => {
    var btn = this;
    var listener = {
        handleEvent(e) {
            if(e.target != btn)
                return;
            e.preventDefault();
            e.stopPropagation();
            this.switch();
        },
        switch() {
            var br = document.activeElement;
            br && br.localName == "browser" && br.isRemoteBrowser
                ? br.messageManager.loadFrameScript(this.url, false)
                : this.keybUtils.switchSelKeybLayout();
        },
        get url() {
            delete this.url;
            return this.url = `data:;charset=utf-8,(${
                encodeURIComponent(keybUtils)
            }).switchSelKeybLayout()`;
        },
        get keybUtils() {
            delete this.keybUtils;
            var url = "data:;charset=utf-8,this.keybUtils = " + encodeURIComponent(keybUtils);
            Services.scriptloader.loadSubScript(url, this);
            this.keybUtils.button = btn;
            this.keybUtils.getFocusedElement = function(_subCall, _focusFixed) {
                if(
                    !_focusFixed
                    && "closeMenus" in window
                    && document.commandDispatcher.focusedElement == this.button
                ) {
                    closeMenus(this.button);
                    setTimeout(function(_this) {
                        _this.switchSelKeybLayout(_subCall, true);
                    }, 0, this);
                    return;
                }
                return document.commandDispatcher.focusedElement;
            }
            return this.keybUtils;
        }
    };
    if(btn instanceof XULElement && addEventListener.length > 3) {
        addEventListener("command", listener, true, this.parentNode);
    }
    listener.switch();
})(`{
    //== Options
    noSelBehavior: { // Shift+Home
        ctrlKey:  false,
        altKey:   false,
        shiftKey: true,
        metaKey:  false,
        keyCode:  KeyEvent.DOM_VK_HOME,
        charCode: 1
    },
    // 0 - do nothing
    // 1 - convert all text
    // Or use object like following to simulate "keypress" event:
    /*
    noSelBehavior: { // Ctrl+Shift+Left
        ctrlKey:  true,
        altKey:   false,
        shiftKey: true,
        metaKey:  false,
        keyCode:  KeyEvent.DOM_VK_LEFT,
        charCode: 0
    }
    */
    convTableForward: { // ru -> en
        "\\"": "@",
        ":": "^",
        ";": "$",
        "?": "&",
        ",": "?",
        "/": "|",
        ".": "/",
        "э": "'",
        "б": ",",
        "ю": ".",
        "Ж": ":",
        "ж": ";",
        "Б": "<",
        "Ю": ">",
        "Э": "\\"",
        "х": "[",
        "ъ": "]",
        "ё": "\`",
        "Х": "{",
        "Ъ": "}",
        "Ё": "~",
        "№": "#",
        "Ф": "A",
        "ф": "a",
        "И": "B",
        "и": "b",
        "С": "C",
        "с": "c",
        "В": "D",
        "в": "d",
        "У": "E",
        "у": "e",
        "А": "F",
        "а": "f",
        "П": "G",
        "п": "g",
        "Р": "H",
        "р": "h",
        "Ш": "I",
        "ш": "i",
        "О": "J",
        "о": "j",
        "Л": "K",
        "л": "k",
        "Д": "L",
        "д": "l",
        "Ь": "M",
        "ь": "m",
        "Т": "N",
        "т": "n",
        "Щ": "O",
        "щ": "o",
        "З": "P",
        "з": "p",
        "Й": "Q",
        "й": "q",
        "К": "R",
        "к": "r",
        "Ы": "S",
        "ы": "s",
        "Е": "T",
        "е": "t",
        "Г": "U",
        "г": "u",
        "М": "V",
        "м": "v",
        "Ц": "W",
        "ц": "w",
        "Ч": "X",
        "ч": "x",
        "Н": "Y",
        "н": "y",
        "Я": "Z",
        "я": "z",
        __proto__: null
    },
    //== End of options

    get convTableBackward() {
        var ctb = { __proto__: null };
        var ctf = this.convTableForward;
        for(var c in ctf)
            ctb[ctf[c]] = c;
        delete this.convTableBackward;
        return this.convTableBackward = ctb;
    },
    inPrimaryLayout: function(s) {
        for(var i = 0, l = s.length; i < l; ++i) {
            var c = s.charAt(i);
            if(c in this.convTableForward)
                return true;
            if(c in this.convTableBackward)
                return false;
        }
        return false;
    },
    switchKeybLayout: function(s, convTable) {
        var res = "";
        for(var i = 0, l = s.length; i < l; ++i) {
            var c = s.charAt(i);
            res += c in convTable ? convTable[c] : c;
        }
        return res;
    },
    getFocusedElement: function() {
        return Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
            .getFocusedElementForWindow(content, true, {});
    },
    switchSelKeybLayout: function(_subCall, _focusFixed) {
        var fe = this.getFocusedElement(_subCall, _focusFixed);
        if(!fe)
            return;
        if(fe instanceof HTMLInputElement || fe instanceof HTMLTextAreaElement) {
            var ta = fe;
            try {
                var val = ta.value;
                var sel = val.substring(ta.selectionStart, ta.selectionEnd);
            }
            catch(e) { // Non-text HTMLInputElement
                return;
            }
            if(!sel && val && this.noSelBehavior && !_subCall) {
                if(this.noSelBehavior == 1) {
                    ta.selectionStart = 0;
                    ta.selectionEnd = val.length;
                    sel = val;
                }
                else {
                    this.handleNoSel(ta);
                    return;
                }
            }
            if(!sel)
                return;
            var res = this.switchKeybLayout(
                sel,
                this.inPrimaryLayout(sel)
                    ? this.convTableForward
                    : this.convTableBackward
            );
            if(res != sel)
                this.insertText(ta, res);
        }
        else if(fe.contentEditable == "true") {
            var doc = fe.ownerDocument;

            var docURI = doc.documentURI;
            if(
                docURI.substr(0, 5) == "data:"
                && docURI.indexOf("chrome://browser/skin/devtools/") != -1
            ) {
                //~ todo: seems like we only can use paste from clipboard here...
                return;
            }

            var sel = doc.defaultView.getSelection();
            var rng = sel.rangeCount && sel.getRangeAt(0);
            var tmpNode;
            if(!rng || rng.collapsed) {
                if(!this.noSelBehavior || _subCall)
                    return;
                if(this.noSelBehavior == 1) {
                    var r = doc.createRange();
                    r.selectNodeContents(fe);
                    sel.removeAllRanges();
                    sel.addRange(r);
                    tmpNode = fe.cloneNode(true);
                }
                else {
                    this.handleNoSel(fe);
                    return;
                }
            }
            else {
                tmpNode = doc.createElementNS("http://www.w3.org/1999/xhtml", "div");
                tmpNode.appendChild(rng.cloneContents());
            }

            var orig = tmpNode.innerHTML;
            var convTable = this.inPrimaryLayout(tmpNode.textContent)
                ? this.convTableForward
                : this.convTableBackward;

            var _this = this;
            var parseChildNodes = function(node) {
                if(node instanceof Element) {
                    var childNodes = node.childNodes;
                    for(var i = childNodes.length - 1; i >= 0; --i)
                        parseChildNodes(childNodes[i]);
                }
                else if(node.nodeType == node.TEXT_NODE) {
                    var text = node.nodeValue;
                    var newText = _this.switchKeybLayout(node.nodeValue, convTable);
                    if(newText != text)
                        node.parentNode.replaceChild(doc.createTextNode(newText), node);
                }
            }
            parseChildNodes(tmpNode);

            var res = tmpNode.innerHTML;
            if(res != orig)
                doc.execCommand("insertHTML", false, res);
        }
    },
    handleNoSel: function(node) {
        this.select(node);
        this.switchSelKeybLayout(true);
    },
    select: function(node) {
        var e = this.noSelBehavior;
        if(!e || typeof e != "object")
            return;
        var evt = node.ownerDocument.createEvent("KeyboardEvent");
        evt.initKeyEvent(
            "keypress", true /*bubbles*/, true /*cancelable*/, node.ownerDocument.defaultView,
            e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
            e.keyCode, e.charCode
        );
        node.dispatchEvent(evt);
    },
    insertText: function(ta, text) {
        //var editor = ta.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor
        var editor = ta.editor
            .QueryInterface(Components.interfaces.nsIPlaintextEditor || Ci.nsIEditor);
        if(editor.flags & editor.eEditorReadonlyMask)
            return;

        var sTop = ta.scrollTop;
        var sHeight = ta.scrollHeight;
        var sLeft = ta.scrollLeft;
        // var sWidth = ta.scrollWidth;

        if(text)
            editor.insertText(text);
        else
            editor.deleteSelection(0, 0);

        ta.scrollTop = sTop + (ta.scrollHeight - sHeight);
        ta.scrollLeft = sLeft; // + (ta.scrollWidth - sWidth);
    }
}`);

Отсутствует

 

№1730831-03-2025 01:41:04

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: unknown 0.0

Re: Custom Buttons

Dumby
Добавляю закладку !
1.png
Стоит появится этому и все identity-icon-box - пропадает ?

1.png
СНЯТ ВОПРОС  Было:
#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] {
  pointer-events:  none;
  -moz-user-focus: ignore;
}
Надо:
#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] {
  pointer-events: inherit;
  -moz-user-focus: ignore;
}

Отредактировано green25 (31-03-2025 08:19:04)

Отсутствует

 

№1730931-03-2025 13:50:49

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

Re: Custom Buttons

Andrey_Krropotkin пишет

Я считаю что в этом коде слишком перемудрено

А можно поподробнее?
По пунктам, где именно ты считаешь перемудрено.

в ошибках при редактировании любой кнопки в ошибках показывает такое сообщение -TypeError: this.cssProperties is undefined

Это, видимо, из-за options.cssInHelp
Либо переключить в false, либо, если прям очень надо,
то попробовать дописать после var optsOvr = options.codeMirror;

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

Выделить код

Код:

//
					if (isCSS) {
						var {generateCssProperties} = require("resource://devtools/server/actors/css-properties.js");
						var {CssProperties, normalizeCssData} = require("resource://devtools/client/fronts/css-properties.js");
						opts.cssProperties = new CssProperties(normalizeCssData({properties: generateCssProperties(document)}));
					}

Uncaught Error: Action with ID 'TranslateBufer1' already added

Ну так ChromeUtils.importESModule()
не возвращает ничего даже близко похожего на g


Можно разделить, PageActions отдельно,
а g, допустим, пусть будет SystemGlobal

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

Выделить код

Код:

((id, g, pa) => addDestructor(reason => id in g && g[id].destroy(reason)) || id in g || ({
    actions: [{
        title: "Перевод из буфера",
        tooltip: "Перевод из буфера",
        iconURL: gticon,
        id: "TranslateBufer1",
        _insertBeforeActionID: "copyURL",

        onCommand: (e, btn) => ujs_google_translat('auto|ru')
    }],
    init() {
        g[id] = this;
        this.actions = this.actions.map(action => {
            action.extensionID = "custombuttons@xsms.org";
            return pa.addAction(new pa.Action(action));
        });
    },
    destroy(reason) {
        if (reason[5] != "e") return;
        delete g[id];
        for(var action of this.actions) action.remove();
    }
}).init())(
    "CBPageActionsMaker", Cu.getGlobalForObject(Cu), PageActions
);

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

Нет такого «как добавлять».
Как-то насильно запихать разве что.
И, из кнопки это не слишком удобно, возможно что-то типа

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

Выделить код

Код:

(() => {
	var url = "about:downloads";
	var img = "chrome://browser/skin/downloads/downloads.svg";

	var id = "viewDownloadsSidebar";
	var fluentFile = "browser/appmenu.ftl";
	var fluentLabel = "appmenuitem-downloads";

	var sc = SidebarController;

	var sep = document.querySelector("#sidebarMenu-popup > menuseparator");
	if (sep) {
		var switcher = document.createXULElement("menuitem");
		switcher.dataset.l10nId = fluentLabel;
		switcher.id = "sidebar-switcher-downloads";
		switcher.addEventListener("command", () => sc.toggle(id));
		sep.before(switcher);
	}
	var sb = sc.makeSidebar({
		url,
		iconUrl: img,
		elementId: switcher?.id,
		menuL10nId: fluentLabel,
		revampL10nId: fluentLabel,
		menuId: "menu_downloadsSidebar"
	});
	var popup = document.getElementById("viewSidebarMenu");
	var menuitem = sc.createMenuItem(id, sb);
	popup.insertBefore(menuitem,popup.querySelector(".webextension-menuitem"));

	var maybeAddSidebar = sb => {
		var bars = sc.sidebars;
		bars.has(id) || bars.set(id, sb);
	}
	Object.defineProperty(sb, "hasOwnProperty", {value(prop) {
		prop == "extensionId" && setTimeout(maybeAddSidebar, 0, sb);
		return Object.hasOwn(sb, prop);
	}, configurable: true, enumerable: true});

	sc.sidebars.set(id, sb);

	var br = sc.browser;
	var ls = `[href="${fluentFile}"]`;
	try {var tools = toolsNameMap;} catch {tools = defaultTools;}

	Object.defineProperty(tools, id, {get() {
		var doc = br.contentDocument;
		var cust = doc?.querySelector("sidebar-customize");
		if (cust && !doc.head.querySelector(ls)) {
			var link = doc.createElement("link");
			link.rel = "localization";
			link.href = fluentFile;
			doc.head.append(link);
			link.l10nMap = cbu.dbg.ref("l10nMap", cust.constructor, 0).set(id, fluentLabel);
		}
		return "downloads";
	}, configurable: true, enumerable: true});

	var sm = sc.sidebarMain;
	var initSM = setTimeout.bind(null, () => {
		sc._toolsAndExtensions = null;
		sm.fluentStrings.addResourceIds([fluentFile]);
		window.dispatchEvent(new CustomEvent("SidebarItemAdded"));
	});

	if (customElements.get("sidebar-main")) initSM();
	else {
		var resolver = Promise.withResolvers();
		Promise.any([customElements.whenDefined("sidebar-main"), resolver.promise])
			.then(add => add && initSM());
	}

	addDestructor(reason => {
		if (reason[5] != "e") return;

		if (sc.isOpen) {
			var cid = sc.currentID;
			if (cid == id) sc.hide();
			else if (cid == "viewCustomizeSidebar") {
				var link = br.contentDocument.head.querySelector(ls);
				link.l10nMap.delete(id);
				link.remove();
			}
		}
		menuitem.remove();
		switcher?.remove();

		sc.sidebars.delete(id);
		sc.toolsAndExtensions.delete(id);

		resolver?.resolve();
		sm.fluentStrings?.removeResourceIds([fluentFile]);

		window.dispatchEvent(new CustomEvent("SidebarItemRemoved"));		
	});
})();

green25 пишет

Чья кнопка ?

Ничья. Это мод-перемод одной из наследия Infocatcher
Андрей когда-то нечто подобное спрашивал,
но там весьма развесисто в смысле правок.

Отсутствует

 

№1731031-03-2025 18:27:46

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: unknown 0.0

Re: Custom Buttons

Dumby

Dumby пишет

Андрей когда-то нечто подобное спрашивал,
но там весьма развесисто в смысле правок.

Да,уж..Черт ногу сломит..Придется расстаться

Отсутствует

 

№1731131-03-2025 18:51:41

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

Re: Custom Buttons

Bug 721336 - Ban sync XMLHttpRequest with chrome privileges (Firefox 138+)


Custom Buttons 0.0.7.0.0.36

Отсутствует

 

№1731202-04-2025 10:27:54

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

Re: Custom Buttons

Content-Security-Policy: (Политика Report-Only) Настройки страницы блокируют выполнение обработчика события (script-src-attr), поскольку он нарушает следующую директиву: «script-src-attr 'none' 'report-sample' - что это за ошибки, почти во многих кнопках и скриптах

вроде разобрался,  только с массивами не понятно

Отредактировано Andrey_Krropotkin (15-04-2025 22:55:48)

Отсутствует

 

№1731302-04-2025 12:33:52

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: unknown 0.0

Re: Custom Buttons

Что делать. В ФФ  после 115 скрипты кастомнык не работают.

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

Выделить код

Код:

try {
    (function() {
        var Cu = Components.utils;
        var {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
        var sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), {
            wantComponents: true,
            sandboxName: "user_chrome_files"
        });
        sandbox.Services = Services;
        Cu.evalInSandbox(`
            var Ci = Components.interfaces;
            var config = {
                subScript: {},
                observe: function(aSubject, aTopic, aData) {
                    if (aTopic == "domwindowopened" && aSubject instanceof Ci.nsIDOMWindow) {
                        aSubject.addEventListener("DOMContentLoaded", function domLoad() {
                            aSubject.removeEventListener("DOMContentLoaded", domLoad, true);
                            var loc = aSubject.location;
                            if (loc && loc.protocol == "chrome:") {
                                try {
                                    config.subScript.user_chrome.loadIntoWindow(aSubject, loc.href);
                                } catch(ex) { }
                            }
                        }, true);
                    } else if (aTopic == "profile-after-change") {
                        Services.obs.removeObserver(config, "profile-after-change");
                        var file = Services.dirsvc.get("UChrm", Ci.nsIFile);
                        file.append("user_chrome_files");
                        file.append("user_chrome.manifest");
                        if (!file.exists() || !file.isFile()) {
                            this.removeObs();
                            return;
                        }
                        try {
                            var reg = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
                            reg.autoRegister(file);
                        } catch(ex) {
                            this.removeObs();
                            return;
                        }

                        try {
                            Services.scriptloader.loadSubScript("chrome://user_chrome_files/content/user_chrome.js", this.subScript, "UTF-8");
                        } catch(ex) {
                            this.removeObs();
                        }
                    }
                },
                removeObs: function() {
                    Services.obs.removeObserver(config, "domwindowopened");
                }
            };
            Services.obs.addObserver(config, "profile-after-change", false);
            Services.obs.addObserver(config, "domwindowopened", false);
        `, sandbox);
    })();
} catch(ex) {Cu.reportError(ex);}

Отсутствует

 

№1731402-04-2025 13:04:19

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

Re: Custom Buttons

green25
Сразу бросается в глаза. Сейчас такая конструкция для всех resource://gre/modules/
ChromeUtils.importESModule("resource://gre/modules/Services.sys.mjs")
а дальше сам смотри

Отсутствует

 

№1731502-04-2025 13:37:55

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: unknown 0.0

Re: Custom Buttons

Andrey_Krropotkin

Andrey_Krropotkin пишет

ChromeUtils.importESModule("resource://gre/modules/Services.sys.mjs"

И где его взять ? в 137  его нет...

Отсутствует

 

№1731602-04-2025 13:48:32

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

Re: Custom Buttons

green25 Попробуй var {Services} = Components.utils.getGlobalForObject(Components.utils);

Отсутствует

 

№1731702-04-2025 14:13:31

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: unknown 0.0

Re: Custom Buttons

Andrey_Krropotkin
У вас как с этим ? Не используется? Эксперименты не работают. Сто раз спрашивал. Есть варианты?

Отсутствует

 

№1731802-04-2025 14:35:09

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

Re: Custom Buttons

green25
Больше вариантов нет

Отсутствует

 

№1731902-04-2025 14:49:48

Farby
Участник
 
Группа: Members
Зарегистрирован: 21-11-2012
Сообщений: 334
UA: Google 2.1

Re: Custom Buttons

green25 пишет

Есть варианты?

Есть такой вариант и это называется UCF и  тема отдельная есть


Жизнь иногда такое выкидывает, что хочется подобрать...

Отсутствует

 

№1732003-04-2025 15:54:39

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: unknown 0.0

Re: Custom Buttons

в 133 прошло,  137 - нет
config.js

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

Выделить код

Код:

// version, date year-month-day: 2025-1-17
(async () => {
    var file = Services.dirsvc.get("UChrm", Ci.nsIFile), iname;
    file.append("user_chrome_files");
    file.append("user_chrome.manifest");
    if (!file.exists() || !file.isFile())
        return;
    switch (Services.appinfo.ID) {
        case "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}": // Firefox or etc.
            iname = "user_chrome.js";
            break;
        case "{3550f703-e582-4d05-9a08-453d09bdfdc6}": // Thunderbird
            iname = "user_chrome_tb.js";
            break;
        default:
            return;
    }
    Components.manager.QueryInterface(Ci.nsIComponentRegistrar)
    .autoRegister(file);
    var sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), {
        wantComponents: true,
        sandboxName: "UserChromeFiles",
        wantGlobalProperties: ["ChromeUtils"],
    });
    Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/user_chrome/${iname}`, sandbox);
})();
//
(async xp => {
	var imprt, ids = [
		"custombuttons@xsms.org",
	];
	if (Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).inSafeMode) return;

	if (Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST)
		var {XPIInternal} = (imprt = url => Cu.import(url, {}))(xp);

	else { // Fx 101+
		var g = Cu.getGlobalForObject(Cu), te = new g.TextEncoder();
		var imp = g.ChromeUtils.import, {XPIInternal} = imp(xp);
		var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
		var rph = ios.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
		imprt = (url, id) => {
			var subst = te.encode(id).join("");
			rph.setSubstitution(subst, ios.newURI(url));
			return imp(`resource://${subst}/`);
		}
	}
	var load = async (file, id) => {
		var rootURI = XPIInternal.getURIForResourceInFile(file, "");
		imprt(rootURI.resolve("startup.jsm"), id).start(rootURI);
	}
	var proto = XPIInternal.BootstrapScope.prototype;
	var func = proto._beforeCallBootstrapMethod;

	proto._beforeCallBootstrapMethod = () => {
		proto._beforeCallBootstrapMethod = func;
		for(var {id, loader, file} of XPIInternal.XPIStates.enabledAddons())
			ids.includes(id) && !loader && load(file, id);
	}
})("resource://gre/modules/addons/XPIProvider.jsm");

//
try {
    (function() {
        var Cu = Components.utils;
        var {Services} = Components.utils.getGlobalForObject(Components.utils);
        var sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), {
            wantComponents: true,
            sandboxName: "user_chrome_files"
        });
        sandbox.Services = Services;
        Cu.evalInSandbox(`
            var Ci = Components.interfaces;
            var config = {
                subScript: {},
                observe: function(aSubject, aTopic, aData) {
                    if (aTopic == "domwindowopened" && aSubject instanceof Ci.nsIDOMWindow) {
                        aSubject.addEventListener("DOMContentLoaded", function domLoad() {
                            aSubject.removeEventListener("DOMContentLoaded", domLoad, true);
                            var loc = aSubject.location;
                            if (loc && loc.protocol == "chrome:") {
                                try {
                                    config.subScript.user_chrome.loadIntoWindow(aSubject, loc.href);
                                } catch(ex) { }
                            }
                        }, true);
                    } else if (aTopic == "profile-after-change") {
                        Services.obs.removeObserver(config, "profile-after-change");
                        var file = Services.dirsvc.get("UChrm", Ci.nsIFile);
                        file.append("user_chrome_files");
                        file.append("user_chrome.manifest");
                        if (!file.exists() || !file.isFile()) {
                            this.removeObs();
                            return;
                        }
                        try {
                            var reg = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
                            reg.autoRegister(file);
                        } catch(ex) {
                            this.removeObs();
                            return;
                        }

                        try {
                            Services.scriptloader.loadSubScript("chrome://user_chrome_files/content/user_chrome.js", this.subScript, "UTF-8");
                        } catch(ex) {
                            this.removeObs();
                        }
                    }
                },
                removeObs: function() {
                    Services.obs.removeObserver(config, "domwindowopened");
                }
            };
            Services.obs.addObserver(config, "profile-after-change", false);
            Services.obs.addObserver(config, "domwindowopened", false);
        `, sandbox);
    })();
} catch(ex) {Cu.reportError(ex);}

Отсутствует

 

№1732103-04-2025 18:29:02

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

Re: Custom Buttons

Dumby

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

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

Выделить код

Код:

/*Initialization Code*/
(this.type != "menu" && (this.type = "menu") && !this.hasAttribute("is")) || (popup => {
    var inserter = {
        get docShell() {
            delete this.docShell;
            return this.docShell = "docShell" in document
                && document.docShell instanceof Ci.nsIDocShell
                ? document.docShell : window.docShell;
        },
        get insertText() {
            delete this.insertText;
            return this.insertText = text => {
                if (!this.docShell.isCommandEnabled("cmd_insertText")) return;
                var params = "createCommandParams" in Components.utils
                    ? Cu.createCommandParams()
                    : Components.classes["@mozilla.org/embedcomp/command-params;1"]
                        .createInstance(Components.interfaces.nsICommandParams);
                params.setStringValue("state_data", text);
                this.docShell.doCommandWithParams("cmd_insertText", params);
            }
        },
       insert(text) {
            var br = document.activeElement;
            !br || br.localName != "browser" || !br.isRemoteBrowser
            ? this.insertText(text) : br.messageManager.loadFrameScript(
                `data:,(${this.insertText})${encodeURIComponent(text.toSource())}`
            , false, true);
        }
    };
    this.onmousedown = e => {
        if (e.button) return;
        this.onmousedown = null;

        var data, save = () => {
            var link = custombuttons.makeButtonLink("update", _id);
            var params = custombuttons.cbService.getButtonParameters(link).wrappedJSObject;
            params.help = JSON.stringify(data, null, "\t");
            custombuttons.cbService.installButton(params.wrappedJSObject = params);
        }
        popup.setAttribute("context", "");
        //popup.setAttribute("onpopupshowing", "firstChild.disabled = !gClipboard.read();");
        popup.addEventListener("popupshowing", (event) => {this.firstChild.disabled = !gClipboard.read();}, false);
        popup.add = () => save(data.push(gClipboard.read()));

        var menuitem = popup.appendChild(document.createXULElement("menuitem"));
        menuitem.setAttribute("label", "Добавить из буфера");
       // menuitem.setAttribute("oncommand", "parentNode.add();");
       menuitem.onclick = function (event) { this.parentNode.add(); };
        if (!(data = JSON.parse(this.Help || "[]")).length) return;

        popup.insert = ind => inserter.insert(data[ind]);
        popup.delete = ind => save(data.splice(ind, 1));

        var df = document.createDocumentFragment();
        df.append(document.createXULElement("menuseparator"));
 
        var menugroup = df.appendChild(document.createXULElement("menugroup"));
        //menugroup.setAttribute("oncommand", "parentNode.insert(event.target.index);");
        menugroup.onclick = function (event) { this.parentNode.insert(event.target.index); };

        menugroup.setAttribute("orient", "vertical");
        menugroup.setAttribute("context", "_child");
    

        var context = menugroup
            .appendChild(document.createXULElement("menupopup"))
            .appendChild(document.createXULElement("menuitem"));
        context.setAttribute("label", "Удалить элемент?");
        context.setAttribute("oncommand", "event.stopPropagation(); menupopup.delete(popupNode.index);");
        //context.onclick = function (event) { event.stopPropagation();  this.menupopup.delete(popupNode.index); };
       context.menupopup = popup;

        data.forEach((text, ind) => {
            var menuitem = menugroup.appendChild(document.createXULElement("menuitem"));
            menuitem.setAttribute("label", text.trimLeft().replace(/\s+/g, " ").slice(0, 70));
            menuitem.index = ind;
        });
        popup.append(df);
    }
})(this.appendChild(document.createXULElement("menupopup")));

Отредактировано Andrey_Krropotkin (19-04-2025 22:28:30)

Отсутствует

 

№1732204-04-2025 03:13:41

green25
Участник
 
Группа: Members
Зарегистрирован: 14-12-2024
Сообщений: 56
UA: Firefox 133.0

Re: Custom Buttons

Dumby
Перестал открываться sidebar в 133

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

Выделить код

Код:

/*Initialization Code*/

this.onclick = this.oncontextmenu = function(event) {

if (event.button == 0) {

var id = "viewHistorySidebar";
		SidebarUI.isOpen && SidebarUI.currentID == id || SidebarUI.show(id);

	
if (Services.prompt.confirm(null, "ВНИМАНИЕ !", "   Сброс истории ! Кнопки по умолчанию?")){
CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed);

 var s = "browser.zoom.full";
      cbu.setPrefs(s, cbu.getPrefs(s) == true ? true : true); 
 
SidebarUI.hide();
       var s = "media.autoplay.default";
 cbu.setPrefs(s, cbu.getPrefs(s) == 5 ? 5: 5);

    var s = "extensions.long_left_click.timeContent";
     cbu.setPrefs(s, cbu.getPrefs(s) == 300 ? 300: 300);




 var ssi = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStoreInternal;
for(var win of CustomizableUI.windows) {
	for(var br of win.gBrowser.browsers) try {br.purgeSessionHistory();} catch {};
	for(var node of win.document.querySelectorAll('[id="Browser:Back"],[id="Browser:Forward"]'))
		node.setAttribute("disabled", true);
	ssi.saveStateDelayed(win);
} 

Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_DOM_STORAGES, () => {});

 PlacesUtils.history.clear();

	}else if (WindowIsClosing()) {
CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed);

}		SidebarUI.hide();
         


}

 if(event.button == 1 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey){
SidebarUI.toggle('viewHistorySidebar');
CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed);

}
     
if(event.button == 2 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey){

 if (Services.prompt.confirm(null, "ВНИМАНИЕ !", "   Сброс Всего ! Кнопки по умолчанию?")){
gBrowser.removeAllTabsBut(gBrowser.selectedTab); 
Services.obs.notifyObservers(null, "browser:purge-session-history");
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_HISTORY, () => {});
 Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_DOM_STORAGES, () => {});
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_SECURITY_SETTINGS, () => {}); 
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_DOM_PUSH_NOTIFICATIONS, () => {});
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_ALL_CACHES, () => {});
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_AUTH_CACHE, () => {});
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_AUTH_TOKENS, () => {});
Services.clearData.deleteData(Ci.nsIClearDataService.CLEAR_DOWNLOADS, () => {});
SidebarUI.hide();
 var ssi = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {}).SessionStoreInternal;
for(var win of CustomizableUI.windows) {
	for(var br of win.gBrowser.browsers) try {br.purgeSessionHistory();} catch {};
	for(var node of win.document.querySelectorAll('[id="Browser:Back"],[id="Browser:Forward"]'))
		node.setAttribute("disabled", true);
	ssi.saveStateDelayed(win);
} 
(lc => {
	var {_cps2, name} = FullZoom;                                                                
	_cps2.removeByName(name, lc, {handleCompletion() {
		_cps2.setGlobal(name, 1.0, lc);
 		for(var [url, zoom] of Object.entries({            
                      "about:preferences":  0.95,
                        "about:preferences#search":  0.95,
                        "about:preferences#privacy":  0.95,
                        "about:preferences#general":  0.95,
			"about:addons":  0.90,
			"rezka-ua.tv": 1.1,
			
		}))
			_cps2.set(_cps2.extractDomain(url), name, zoom, lc);
	}});
})(Cu.createLoadContext());
 
CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed);
 var s = "browser.zoom.full";
      cbu.setPrefs(s, cbu.getPrefs(s) == true ? true : true); 

 
  var s = "media.autoplay.default";
 cbu.setPrefs(s, cbu.getPrefs(s) == 5 ? 5: 5);
SidebarUI.hide();
    var s = "extensions.long_left_click.timeContent";
     cbu.setPrefs(s, cbu.getPrefs(s) == 300 ? 300: 300);

 Sanitizer.showUI(window);

try {
              Services.cache.evictEntries(Ci.nsICache.STORE_IN_MEMORY);
              Services.cache.evictEntries(Ci.nsICache.STORE_ON_DISK);
              
              }
          catch(e) { Services.cache2.clear() }  
              
 var file = Services.dirsvc.get('ProfD', Ci.nsIFile);
         file.initWithPath(file.path + "\\memory\\start.vbs"); 
         file.launch();  
         

 CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed);        
       
    
}
};
}


this.tooltipText = "ЛКМ: Очистка Истории\nСКМ: Боковая история \nПКМ: Окно очистки всего"; 
(url => addEventListener("pageshow", e => {
	if (e.target.documentURI != url) return;

	var rn = e.target.getElementById("historyTree").view._rootNode;
	var ind = rn.childCount;
	while(ind--) {
		var node = rn.getChild(ind);
		if (node.containerOpen) continue;
		node.containerOpen = true;
		Services.xulStore.setValue(url, node.uri, "open", "true");
	}
}, false, document.getElementById("sidebar") || 1))(
	"chrome://browser/content/places/historySidebar.xhtml"

); 
this.oncontextmenu =e=> { e.button && !e.ctrlKey && e.preventDefault() };


Но это ерунда, по сравнению с этой крутой кнопкой  замена на  XPIDatabase.sys.mjs тоже не катит
скрытый текст

Выделить код

Код:

/*Initialization Code*/

((id, g) => {
    addDestructor(r => r[5] == "e" && id in g && g[id].destroy());
    if (g[id]) return;
    var {obs, xulStore, prefs} = Services;
    var topic = "quit-application", doc = document.documentURI;
    obs.addObserver(g[id] = {
        observe(s, t, data) {
            this.destroy();
            if (data != "shutdown") return;
          

xulStore.removeValue(doc, "sidebar-box", "checked");


         
            for(var pref of [                                             
               
                "intl.accept_languages",
               "network.proxy.type",
               
                "extensions.long_left_click.timeContent",
                "browser.toolbars.bookmarks.visibility",
                 "general.useragent.override",
            ])
                prefs.clearUserPref(pref);
        },
        destroy() {
            delete g[id];
            obs.removeObserver(this, topic);
        }
    }, topic, false);

})(
    "CBQuitApplication", Cu.getGlobalForObject(Cu)
);


((id, g) => {
    addDestructor(r => r[5] == "e" && id in g && g[id].destroy());                                         
    if (g[id]) return;
    var topic = "quit-application-granted", {obs} = Services;
    obs.addObserver(g[id] = {
        // true - disable, false - enable
        states: {
            "{97d566da-42c5-4ef4-a03b-5a2e5f7cbcb2}": true,
            "jid1-s2tSKqH4h0BHUw@jetpack": false,
            "mozilla_cc3@internetdownloadmanager.com": true,
            "{74145f27-f039-47ce-a470-a662b129930a}": true,
            "{acf99872-d701-4863-adc2-cdda1163aa34}": true,
            "{8f4bbf79-5514-4d04-a901-d5fabfe91d73}": true, 
            
        },
        filter(addon) {
            var state = this.states[addon.id];
            if (
                state !== undefined && addon.userDisabled != state
                && addon.type.endsWith("extension")
                && addon.location.name != "app-builtin"
            ) {
                addon.active = addon.location.get(addon.id).enabled
                    = !(addon.userDisabled = state);
                return true;
            }
        },
        observe() {
            this.destroy();
            if (g.XPIDatabase.getAddons().filter(this.filter, this).length)
                g.XPIDatabase.saveChanges(), g.XPIStates.save();
        },
        destroy() {
            delete g[id];
            obs.removeObserver(this, topic);
        }
    }, topic, false);
})(
    "CBQuitApplicationExtensionsSwitcher",
    Cu.import("resource://gre/modules/addons/XPIDatabase.jsm", {})
);

Тогда по-проще как сюда второй код всунуть ?
this.click = e => e.button ||  this.launch();

Отредактировано green25 (05-04-2025 20:41:06)

Отсутствует

 

№1732305-04-2025 21:11:46

mokujin
Участник
 
Группа: Members
Зарегистрирован: 17-02-2017
Сообщений: 516
UA: unknown 0.0

Re: Custom Buttons

Andrey_Krropotkin пишет

Заменить  m.setAttribute('oncommand', sCommand); на что другое чтобы избавиться от oncommand

m.onclick = sCommand;  ?


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

Отсутствует

 

№1732405-04-2025 23:08:22

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

Re: Custom Buttons

mokujin не пашет, полностью код

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

Выделить код

Код:

/*Initialization Code*/

var idb=this.id;
var button = document.getElementById(idb);
this.tooltipText = 'ЛКМ: ExtraConfigMenu\nСКМ: открыть папку Chrome в браузере';

 (function(){
	var uProfMenu = {
                     // ----- Настройки
// ----- Начало 
  // Введите путь к текстовому редактору. Если запись неверна, считывается из view_source.editor.path:
  TextOpenExe : 'C:\\Program Files (x86)\\AkelPad\\AkelPad.exe',
  // При желании введите файловый менеджер (оставьте значение пустым для файлового менеджера системы). Примеры:  vFileManager: 'C:\\Program Files (x86)\\FreeCommander\\FreeCommander.exe'
  vFileManager: '',
 // В Linux следует / можно попытаться отсортировать сценарии userChromeJS, в Windows это может не потребоваться (сортировка не будет чувствительна к регистру * - функция sort () вызывается соответственно с функцией сравнения)
  sortScripts: 0,   // 1, чтобы сделать сортировку
  // Интеграция папки скриптов GM (0: нет, 1: Greasemonkey [каталог профиля], 2: UserScriptLoader [каталог chrome], 3: scriptish [каталог профиля]):
  gmOrdner: 0,
  // Вставить папку CSS (0: нет, 1: папка CSS в каталоге Chrome):
  cssOrdner: 1,
  // В строке  about: введите адреса, которые также должны быть вызваны.
  // - Спрятать пункт abouts: [],
  // - Чтобы пункты about: были перечислены не как подменю, а непосредственно как пункты меню, первый элемент должен иметь значение «0»:
  // abouts: ['0','about:about','about:addons','about:cache','about:config','about:support'],
   abouts: ['about:about','about:addons','about:cache','about:config','about:buildconfig','about:crashes','about:home','about:memory','about:plugins','about:support','about:debugging','about:profiles','about:preferences','about:performance','about:firefoxview-next'],
  // пункт настройки Firefox (0: нет, 1: да):
  showNormalPrefs: 1,
  // Предоставляет «список сценариев в буфере обмена» (1: да, 2: с отдельной нумерацией) или нет (0):
  enableScriptsToClip: 2};
 // ----- Конец 

   var menupopup = button.appendChild(createME("menupopup",0,0,0,"ExtraConfigMenu-popup"));

    button.type = "menu";
    button.orient = "horizontal";
   // button.setAttribute("onpopupshowing", "getScripts(0)");
 //   button.setAttribute("onclick", "if (event.button === 1 && !this.open) openTrustedLinkIn('file:///'+getPrefDirectoryPath(`UChrm`), 'tab');");
    button.addEventListener("popupshowing", (event) => {getScripts(0)}, false);
   button.onclick = function (event) { if (event.button === 1 && !this.open) openTrustedLinkIn('file:///'+getPrefDirectoryPath(`UChrm`), 'tab') };
   
   
   
    menupopup.appendChild(createME("menuitem","userChrome.js","edit(0,'userChrome.js');","uProfMenu_edit",0));
  
    // Создание подменю для сценариев userChromeJS (они будут заполнены позже)
    var submenu = menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-ucjs"));
    submenu.appendChild(createME("menupopup",0,0,0,"submenu-ucjs-items"));
    var submenu2=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-css"));
	  submenu2.appendChild(createME("menupopup",0,0,0,"submenu-css-items")); 
    var submenu1=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-ucxu"));
	  var submenupopup = submenu1.appendChild(createME("menupopup",0,0,0,"submenu-ucxu-items"));
    if (uProfMenu.enableScriptsToClip) menupopup.appendChild(createME("menuitem","Скопировать в буфер список","getScripts(1)","uProfMenu_clipboard",0));
    // Завершить создание подменю для сценариев userChromeJS
    menupopup.appendChild(document.createXULElement('menuseparator'));
    // Интеграция конфигурационных файлов
    menupopup.appendChild(createME("menuitem","userChrome.css","edit(0,'userChrome.css');","uProfMenu_edit1",0));
    menupopup.appendChild(createME("menuitem","userContent.css","edit(0,'userContent.css');","uProfMenu_edit1",0));
    menupopup.appendChild(createME("menuitem","prefs.js","edit(1,'prefs.js');","uProfMenu_edit",0));
    menupopup.appendChild(createME("menuitem","user.js","edit(1,'user.js');","uProfMenu_edit"),0);
    // Завершить интеграцию конфигурационных файлов
    menupopup.appendChild(document.createXULElement('menuseparator'));
    // Интеграция папок
    switch (uProfMenu.gmOrdner) {
      case 1:
        menupopup.appendChild(createME("menuitem","Папка gm_scripts","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'gm_scripts');","uProfMenu_folder"),0);
        break;
      case 2:
        menupopup.appendChild(createME("menuitem","USL Skripte","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'UserScriptLoader');","uProfMenu_folder"),0);
        break;
      case 3:
        menupopup.appendChild(createME("menuitem","Scriptish Skripte","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'scriptish_scripts');","uProfMenu_folder"),0);
        break;
    }
    if (uProfMenu.cssOrdner) {
     menupopup.appendChild(createME("menuitem","Папка Chrome","prefDirOpen('UChrm');","uProfMenu_folder"),0);
      menupopup.appendChild(createME("menuitem","Папка CSS","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'CSS');","uProfMenu_folder"),0);
    }
    menupopup.appendChild(createME("menuitem","Папка user_chrome_files","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'user_chrome_files');","uProfMenu_folder"),0);
    menupopup.appendChild(createME("menuitem","Папка профиля","prefDirOpen('ProfD');","uProfMenu_folder"),0);
    menupopup.appendChild(createME("menuitem","Папка extensions","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'extensions');","uProfMenu_folder"),0);
    menupopup.appendChild(createME("menuitem","Папка Mozilla","prefDirOpen('CurProcD');","uProfMenu_folder"),0);
    menupopup.appendChild(createME("menuitem","Папка startupCache","dirOpen(getPrefDirectoryPath('ProfLD')+getDirSep()+'startupCache');","uProfMenu_folder"),0);
    // Завершить интеграцию папок
    // Интеграция abouts
    if (uProfMenu.abouts.length>0) {
      menupopup.appendChild(document.createXULElement('menuseparator'));
      // если первая запись массива = '0', не создавайте подменю, а интегрируйте его непосредственно как пункты меню
      if (uProfMenu.abouts[0]=='0') {
        for (var i = 1; i < uProfMenu.abouts.length; i++) {
         menupopup.appendChild(createME("menuitem",uProfMenu.abouts[i],"openTrustedLinkIn('"+uProfMenu.abouts[i]+"','tab')","uProfMenu_about"),0);
        }
       } else {
        // Первая запись массива не равна '0', поэтому устанавливается как подменю
        var submenu=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-about"));
        var submenupopup = submenu.appendChild(createME("menupopup",0,0,0,"submenu-about-items"));
        fillMenu("submenu-about","submenu-about-items", "about:",uProfMenu.abouts,"uProfMenu_about",1);
      }
    }
    // Завершение интеграции abouts
    // Разделитель, если он еще не был сгенерирован abouts и будет следовать за другими пунктами меню
    if (uProfMenu.abouts.length==0 && uProfMenu.showNormalPrefs) menupopup.appendChild(document.createXULElement('menuseparator'));
    // При желании (см. Раздел настроек), доступ к обычным настройкам Firefox
    if (uProfMenu.showNormalPrefs) menupopup.appendChild(createME("menuitem","Настройки","try{openOptionsDialog();}catch(e){openPreferences();}","uProfMenu_prefs"),0);
    if (uProfMenu.showNormalPrefs) menupopup.appendChild(createME("menuitem","Перезапуск","Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart)","uProfMenu_Restart"),0);
 


   getDirSep = function  () {
    // Определить операционную систему в соответствии с https://developer.mozilla.org/en/Code_snippets/Miscellaneous
    var osString = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS;
    var dirsep="/";
    switch(osString) {
      case "WINNT":
        dirsep="\\";
        break;
      case "Linux":
        dirsep="/";
        break;
      case "Darwin":
        dirsep="/";
        break;
    }
    return dirsep;
  };


  edit = function (OpenMode,Filename){
    var Path = "";
    var dSep = getDirSep();  // Сделать разделители между папками в зависимости от операционной системы
    switch (OpenMode){
      //Текущая Chrome директория
      case 0:
        var Path = getPrefDirectoryPath("UChrm") + dSep + Filename;
        break;
      //Текущая Profile директория
      case 1:
        var Path = getPrefDirectoryPath("ProfD") + dSep + Filename;
        break;
      //Текущая директория Root
      case 2:
        var Path = Filename;
        break;
       //Текущая CSS  директория
      case 3:
        var Path = getPrefDirectoryPath("UChrm") + dSep + "CSS" + dSep + Filename;
        break; 
    }
    launch(uProfMenu.TextOpenExe,Path);
  };



  dirOpen = function (Path){
    if (uProfMenu.vFileManager.length != 0) {
      var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
      var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
      var args=[Path];
      file.initWithPath(uProfMenu.vFileManager);
      process.init(file);
      // Открыть каталог с другим файловым менеджером
      process.run(false, args, args.length);
     } else {
      // Откройте каталог с помощью файлового менеджера системы
      var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
      dir.initWithPath(Path);
      dir.launch();
    }
  };


  prefDirOpen = function (prefDir){
    Path = getPrefDirectoryPath(prefDir);
    dirOpen(Path);
  };


  getPrefDirectoryPath = function (str){
    var file = Components.classes["@mozilla.org/file/directory_service;1"]
      .getService(Components.interfaces.nsIProperties)
      .get(str, Components.interfaces.nsIFile);
    if (str == 'CurProcD') {
      file = file.parent;
    };
    return file.path;
  };


 launch = function (RanPath,OpenPath){
    var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile);
    var proc = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
    var args = [OpenPath];
    file.initWithPath(RanPath);
    // если редактор, определенный в разделе конфигурации, не найден, переключитесь на настройку в about: config:
    if (!file.exists()) {
      var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
      RanPath=pref.getCharPref("view_source.editor.path");
      file.initWithPath(RanPath);
    }
    proc.init(file);
    proc.run(false, args, args.length);
  };


  stringComparison = function (a, b){
    a = a.toLowerCase();
    a = a.replace(/ä/g,"a");
    a = a.replace(/ö/g,"o");
    a = a.replace(/ü/g,"u");
    a = a.replace(/ß/g,"s");
    b = b.toLowerCase();
    b = b.replace(/ä/g,"a");
    b = b.replace(/ö/g,"o");
    b = b.replace(/ü/g,"u");
    b = b.replace(/ß/g,"s");
    return(a==b)?0:(a>b)?1:-1;
  };


  getScripts = function   (iType) {
    // Массивы (по одному массиву для uc.js,uc.xul, css) выбирают имена найденных скриптов
    var ucJsScripts = [];
    var ucXulScripts = [];
    var ucCSScripts = [];
    // Шаблон поиска, то есть расширения файлов uc.js, uc.xul, css
    var extjs = /\.uc\.js$/i;
    var extxul= /\.uc\.xul$/i;
    var exttcss= /\.css$/i;
   // Для uc.js, uc.xul
    var aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path);
    var files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
   // Для css
    var sFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    sFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path);
    sFolder.appendRelativePath("CSS");
    var sfiles = sFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
    // Просматривать папки или файлы и проверять, включены ли найденные файлы для uc.js, uc.xul
    while (files.hasMoreElements()) {
      var file = files.getNext().QueryInterface(Ci.nsIFile);
      // нет нужного файла, поэтому продолжайте
      if (!extjs.test(file.leafName) && !extxul.test(file.leafName)) continue;
      // uc.js найдено -> положить в массив
      if (extjs.test(file.leafName)) ucJsScripts.push(file.leafName);
      // uc.xul найдено -> положить в массив
    if (extxul.test(file.leafName)) ucXulScripts.push(file.leafName);
    }
   // Просматривать папки или файлы и проверять, включены ли найденные файлы для css
    while (sfiles.hasMoreElements()) {
      var sfile = sfiles.getNext().QueryInterface(Ci.nsIFile);
      // нет нужного файла, поэтому продолжайте
      if (!exttcss.test(sfile.leafName)) continue;
      // css найдено -> положить в массив
      if (exttcss.test(sfile.leafName)) ucCSScripts.push(sfile.leafName);
    }
    if (uProfMenu.sortScripts) {
      ucJsScripts.sort(stringComparison);
      ucXulScripts.sort(stringComparison);
      ucCSScripts.sort(stringComparison);
    }
    // Вызов следующих методов для заполнения подменю или буфера обмена
    if (iType==0) {
      fillMenu("submenu-ucjs","submenu-ucjs-items", "Файлы  uc.js",ucJsScripts,"uProfMenu_ucjs",0);
      fillMenu("submenu-ucxu","submenu-ucxu-items", "Файлы uc.xul",ucXulScripts,"uProfMenu_ucxu",0);
      fillMenu1("submenu-css","submenu-css-items", "Файлы css",ucCSScripts,"uProfMenu_css",0);
     } else {
     var result = fillClipboardValue(ucJsScripts,ucXulScripts,ucCSScripts);
      Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper).copyString(result);
    }
  };


  function fillMenu (whichsubmenu, whichsubmenuitems, strlabel, scriptArray,sClass,sTyp,sId) {
    // Добавить заголовок подменю с количеством найденных файлов
    var e = document.getElementById(whichsubmenu);
    e.setAttribute('label',strlabel + ' (' + scriptArray.length + ')');
    var popup = document.getElementById(whichsubmenuitems);
    // подменю
    while(popup.hasChildNodes()){
      popup.removeChild(popup.firstChild);
    }
    // Подменю заполнить
    for (var i = scriptArray.length-1; i > -1; i--) {
      // для пунктов подменю uc.js, uc.xul, abouts 
      if (sTyp==0){
        var mitem = createME("menuitem",scriptArray[i],"edit(0,'"+scriptArray[i]+"')",sClass,0);
        mitem.setAttribute("onclick","openAtGithub(event,'"+scriptArray[i]+"')");
        mitem.setAttribute("tooltiptext"," ЛКМ: Редактировать\n СКМ: Поиск по форуму camp-firefox.de\n ПКМ: Поиск по сайту GitHub");
       } else  {
        var mitem = createME("menuitem",scriptArray[i],"openTrustedLinkIn('"+scriptArray[i]+"','tab')",sClass,0);
      } 
      popup.insertBefore(mitem, popup.firstChild);
      
    }
  };

   function fillMenu1 (whichsubmenu, whichsubmenuitems, strlabel, scriptArray,sClass,sTyp,sId) {
    // Добавить заголовок подменю с количеством найденных файлов
    var e = document.getElementById(whichsubmenu);
    e.setAttribute('label',strlabel + ' (' + scriptArray.length + ')');
    var popup = document.getElementById(whichsubmenuitems);
    // подменю
    while(popup.hasChildNodes()){
      popup.removeChild(popup.firstChild);
    }
    // Подменю заполнить
    for (var i = scriptArray.length-1; i > -1; i--) {
      // для пунктов подменю css
      if (sTyp==0){
        var mitem1 = createME("menuitem",scriptArray[i],"edit(3,'"+scriptArray[i]+"')",sClass,0);
       }
      popup.insertBefore(mitem1, popup.firstChild);
      
    }
  }; 

   function fillClipboardValue (sArray,xArray,yArray) {
    var retValue;
    var s = 0;
    var x = 0;
     var y = 0; 
    s = sArray.length;
    x = xArray.length;
    y = yArray.length;
    switch(uProfMenu.enableScriptsToClip) {
      case 1:
        retValue = "userChrome/uc.js ("+s+"):\n------------------------\n"+sArray.join("\n")+
                   "\n\nuserChrome/uc.xul ("+x+"):\n-------------------------\n"+xArray.join("\n")+
                   "\n\nuserChrome/css ("+y+"):\n-------------------------\n"+yArray.join("\n");
        break;
      case 2:
        retValue = "userChrome/uc.js ("+s+"):\n------------------------";
        for (var i = 0; i < s ; i++) {
          j = i + 1;
          retValue = retValue + "\n" + j + ". " + sArray[i];
        }
        retValue = retValue + "\n\nuserChrome/uc.xul ("+x+"):\n-------------------------";
        for (var i = 0; i < x ; i++) {
          g = i + 1;
          retValue = retValue + "\n" + g + ". " + xArray[i];
        }
        retValue = retValue + "\n\nuserChrome/css ("+y+"):\n-------------------------";
       for (var i = 0; i < y ; i++) {
          h = i + 1;
          retValue = retValue + "\n" + h + ". " + yArray[i];
        }
    }
    return retValue;
  };


function createME (sTyp,sLabel,sCommand,sClass,sId) {
    // Создание элемента меню, меню или меню - параметры, не используемые для определенных типов, передаются как 0
    const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    var m = document.createElementNS(XUL_NS, sTyp);
    switch (sTyp) {
      case "menuitem":
        m.setAttribute('label', sLabel);
        m.setAttribute('oncommand',sCommand);
        m.setAttribute('class',sClass);
        break;
      case "menu":
        m.setAttribute('label', sLabel);
        m.setAttribute('id', sId);
        break;
      case "menupopup":
        m.setAttribute('id', sId);
        break;
    }
    return m;
  };
openAtGithub = function (e,sScript) {
    if (e.button==1){
      // СКМ - Начать поиск на camp-firefox.de (работает, только если имя файла хранится в коде):
      var sUrl="https://www.google.com/search?as_q="+sScript+"&as_sitesearch=www.camp-firefox.de&gws_rd=ssl";
      openWebLinkIn(sUrl, 'tab');
    }
    if (e.button==2){
      // ПКМ - Начать поиск на GitHub (работает, только если имя файла хранится в коде):
      e.preventDefault();
      var sUrl="https://www.google.com/search?as_q="+sScript+"&as_sitesearch=github.com&gws_rd=ssl";
      openWebLinkIn(sUrl, 'tab');
    }
  };


 function cleanFileName(sName) {
    sName=sName.toLowerCase();
    /* Следующий массив содержит регулярные выражения для удаления недопустимых строк:
    /Datei-Erweiterungen am Ende/, /"ucjs_" am Anfang/, /"_"gefolgtVonZahlUndDanachBeliebigenZeichen/
    / "_fx"gefolgtVonZahl(en)/, /"-" oder "+" oder "."/, /"_v"gefolgtVonZahlen
    */
    var regs=[/\.uc\.js$/,/\.uc\.xul$/,/^ucjs_/,/_\d.+/,/_fx\d+/,/[-+\.]/g,/_v\d+/];
    for (var i = 0; i < regs.length; i++) {
      sName=sName.replace(regs[i],"");
    }
    return sName;
  };
	})();

Отредактировано Andrey_Krropotkin (07-04-2025 22:22:37)

Отсутствует

 

№1732506-04-2025 00:21:30

mokujin
Участник
 
Группа: Members
Зарегистрирован: 17-02-2017
Сообщений: 516
UA: unknown 0.0

Re: Custom Buttons

И куда ты это месиво собрался втулить ?! :lol: Ему 10+лет этому скрипту. С тех пор FF уже четырежды минимум менял-ся.
Тут пару ошибок древнюююююющих было.
В PM вот ↓ работающий код, а как там оно будет в FF последних.., полагаю что никак вообще. ибо такая мешанина что это тот-самый случай, когда написать с нуля проще, чем все это исправлять. Но автору простительно, он на заре это все писал, добавляя по кускам.  Да и есть\были отдельные норм. кнопки с меню about:, файлами и открытием папок

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

Выделить код

Код:

/*Initialization Code*/
// ==UserScript==
// @name           extras_config_menu.uc.js
// @compatibility  Firefox 8.*, 9.*, 10.*, 11.*, 12.*, 13.*, 14.*, 15.*, 16.*, 17.*, 57.*, 62.*
// @include        main
// @version        1.0.20180914
// ==/UserScript==
var idb=this.id;
var button = document.getElementById(idb);
this.tooltipText = 'ЛКМ: ExtraConfigMenu\nСКМ: открыть папку Chrome в браузере';

 (function(){
	var uProfMenu = {
                     // ----- Настройки
// ----- Начало 
  // Введите путь к текстовому редактору. Если запись неверна, считывается из view_source.editor.path:
  TextOpenExe : 'd:\\MyPROGRAMs\\FM\\TC9\\Plugins\\exe\\AkelPad\\AkelPad.exe',
  // При желании введите файловый менеджер (оставьте значение пустым для файлового менеджера системы). Примеры:  vFileManager: 'C:\\Program Files (x86)\\FreeCommander\\FreeCommander.exe'
  vFileManager: '',
 // В Linux следует / можно попытаться отсортировать сценарии userChromeJS, в Windows это может не потребоваться (сортировка не будет чувствительна к регистру * - функция sort () вызывается соответственно с функцией сравнения)
  sortScripts: 0,   // 1, чтобы сделать сортировку
  // Интеграция папки скриптов GM (0: нет, 1: Greasemonkey [каталог профиля], 2: UserScriptLoader [каталог chrome], 3: scriptish [каталог профиля]):
  gmOrdner: 0,
  // Вставить папку CSS (0: нет, 1: папка CSS в каталоге Chrome):
  cssOrdner: 1,
  // В строке  about: введите адреса, которые также должны быть вызваны.
  // - Спрятать пункт abouts: [],
  // - Чтобы пункты about: были перечислены не как подменю, а непосредственно как пункты меню, первый элемент должен иметь значение «0»:
  // abouts: ['0','about:about','about:addons','about:cache','about:config','about:support'],
   abouts: ['about:about','about:addons','about:cache','about:config','about:buildconfig','about:crashes','about:home','about:memory','about:plugins','about:support','about:debugging','about:profiles','about:preferences','about:performance','about:firefoxview-next'],
  // пункт настройки Firefox (0: нет, 1: да):
  showNormalPrefs: 1,
  // Предоставляет «список сценариев в буфере обмена» (1: да, 2: с отдельной нумерацией) или нет (0):
  enableScriptsToClip: 2};
 // ----- Конец 

   var menupopup = button.appendChild(createME("menupopup",0,0,0,"ExtraConfigMenu-popup"));

    button.type = "menu";
    button.orient = "horizontal";
   // button.setAttribute("onpopupshowing", "getScripts(0)");
    button.addEventListener("popupshowing", (event) => {getScripts(0)}, false);
   // button.setAttribute("onclick", "if (event.button === 1 && !this.open) gBrowser.selectedTab = gBrowser.addTab('file:///'+getPrefDirectoryPath(`UChrm`), 'tab');");
   button.onclick = function (event) { if (event.button === 1 && !this.open) gBrowser.selectedTab = gBrowser.addTab('file:///'+getPrefDirectoryPath(`UChrm`)) };
   
    menupopup.appendChild(createME("menuitem","userChrome.js","edit(0,'userChrome.js');","uProfMenu_edit",0));
  
    // Создание подменю для сценариев userChromeJS (они будут заполнены позже)
    var submenu = menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-ucjs"));
    submenu.appendChild(createME("menupopup",0,0,0,"submenu-ucjs-items"));
    var submenu2=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-css"));
	  submenu2.appendChild(createME("menupopup",0,0,0,"submenu-css-items")); 
    var submenu1=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-ucxu"));
	  var submenupopup = submenu1.appendChild(createME("menupopup",0,0,0,"submenu-ucxu-items"));
    if (uProfMenu.enableScriptsToClip) menupopup.appendChild(createME("menuitem","Скопировать в буфер список","getScripts(1)","uProfMenu_clipboard",0));
    // Завершить создание подменю для сценариев userChromeJS
    //menupopup.appendChild(document.createElement("menuseparator"));
    menupopup.appendChild(document.createElement("menuseparator"));
    // Интеграция конфигурационных файлов
    menupopup.appendChild(createME("menuitem","userChrome.css","edit(0,'userChrome.css');","uProfMenu_edit1",0));
    menupopup.appendChild(createME("menuitem","userContent.css","edit(0,'userContent.css');","uProfMenu_edit1",0));
    menupopup.appendChild(createME("menuitem","prefs.js","edit(1,'prefs.js');","uProfMenu_edit",0));
    menupopup.appendChild(createME("menuitem","user.js","edit(1,'user.js');","uProfMenu_edit"),0);
    // Завершить интеграцию конфигурационных файлов
    menupopup.appendChild(document.createElement("menuseparator"));
    // Интеграция папок
    switch (uProfMenu.gmOrdner) {
      case 1:
        menupopup.appendChild(createME("menuitem","Папка gm_scripts","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'gm_scripts');","uProfMenu_folder"),0);
        break;
      case 2:
        menupopup.appendChild(createME("menuitem","USL Skripte","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'UserScriptLoader');","uProfMenu_folder"),0);
        break;
      case 3:
        menupopup.appendChild(createME("menuitem","Scriptish Skripte","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'scriptish_scripts');","uProfMenu_folder"),0);
        break;
    }
    if (uProfMenu.cssOrdner) {
     menupopup.appendChild(createME("menuitem","Папка Chrome","prefDirOpen('UChrm');","uProfMenu_folder"),0);
      menupopup.appendChild(createME("menuitem","Папка CSS","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'CSS');","uProfMenu_folder"),0);
    }
    menupopup.appendChild(createME("menuitem","Папка user_chrome_files","dirOpen(getPrefDirectoryPath('UChrm')+getDirSep()+'user_chrome_files');","uProfMenu_folder"),0);
    menupopup.appendChild(createME("menuitem","Папка профиля","prefDirOpen('ProfD');","uProfMenu_folder"),0);
    menupopup.appendChild(createME("menuitem","Папка extensions","dirOpen(getPrefDirectoryPath('ProfD')+getDirSep()+'extensions');","uProfMenu_folder"),0);
    menupopup.appendChild(createME("menuitem","Папка Mozilla","prefDirOpen('CurProcD');","uProfMenu_folder"),0);
    menupopup.appendChild(createME("menuitem","Папка startupCache","dirOpen(getPrefDirectoryPath('ProfLD')+getDirSep()+'startupCache');","uProfMenu_folder"),0);
    // Завершить интеграцию папок
    // Интеграция abouts
    if (uProfMenu.abouts.length>0) {
      menupopup.appendChild(document.createElement("menuseparator"));
      // если первая запись массива = '0', не создавайте подменю, а интегрируйте его непосредственно как пункты меню
      if (uProfMenu.abouts[0]=='0') {
        for (var i = 1; i < uProfMenu.abouts.length; i++) {
         menupopup.appendChild(createME("menuitem",uProfMenu.abouts[i],"gBrowser.selectedTab = gBrowser.addTab('"+uProfMenu.abouts[i]+"')","uProfMenu_about"),0);
//         menupopup.appendChild(createME("menuitem",uProfMenu.abouts[i],"gBrowser.selectedTab = gBrowser.addTab('"+uProfMenu.abouts[i]+"','tab')","uProfMenu_about"),0);
        }
       } else {
        // Первая запись массива не равна '0', поэтому устанавливается как подменю
        var submenu=menupopup.appendChild(createME("menu","uc.js",0,0,"submenu-about"));
        var submenupopup = submenu.appendChild(createME("menupopup",0,0,0,"submenu-about-items"));
        fillMenu("submenu-about","submenu-about-items", "about:",uProfMenu.abouts,"uProfMenu_about",1);
      }
    }
    // Завершение интеграции abouts
    // Разделитель, если он еще не был сгенерирован abouts и будет следовать за другими пунктами меню
    if (uProfMenu.abouts.length==0 && uProfMenu.showNormalPrefs) //menupopup.appendChild(document.createElement("menuseparator"));
    // При желании (см. Раздел настроек), доступ к обычным настройкам Firefox
    if (uProfMenu.showNormalPrefs) menupopup.appendChild(createME("menuitem","Настройки","try{openOptionsDialog();}catch(e){openPreferences();}","uProfMenu_prefs"),0);
    if (uProfMenu.showNormalPrefs) menupopup.appendChild(createME("menuitem","Перезапуск","Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart)","uProfMenu_Restart"),0);
 


   getDirSep = function  () {
    // Определить операционную систему в соответствии с https://developer.mozilla.org/en/Code_snippets/Miscellaneous
    var osString = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).OS;
    var dirsep="/";
    switch(osString) {
      case "WINNT":
        dirsep="\\";
        break;
      case "Linux":
        dirsep="/";
        break;
      case "Darwin":
        dirsep="/";
        break;
    }
    return dirsep;
  };


  edit = function (OpenMode,Filename){
    var Path = "";
    var dSep = getDirSep();  // Сделать разделители между папками в зависимости от операционной системы
    switch (OpenMode){
      //Текущая Chrome директория
      case 0:
        var Path = getPrefDirectoryPath("UChrm") + dSep + Filename;
        break;
      //Текущая Profile директория
      case 1:
        var Path = getPrefDirectoryPath("ProfD") + dSep + Filename;
        break;
      //Текущая директория Root
      case 2:
        var Path = Filename;
        break;
       //Текущая CSS  директория
      case 3:
        var Path = getPrefDirectoryPath("UChrm") + dSep + "CSS" + dSep + Filename;
        break; 
    }
    launch(uProfMenu.TextOpenExe,Path);
  };



  dirOpen = function (Path){
    if (uProfMenu.vFileManager.length != 0) {
      var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
      var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
      var args=[Path];
      file.initWithPath(uProfMenu.vFileManager);
      process.init(file);
      // Открыть каталог с другим файловым менеджером
      process.run(false, args, args.length);
     } else {
      // Откройте каталог с помощью файлового менеджера системы
      var dir = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
      dir.initWithPath(Path);
      dir.launch();
    }
  };


  prefDirOpen = function (prefDir){
    Path = getPrefDirectoryPath(prefDir);
    dirOpen(Path);
  };


  getPrefDirectoryPath = function (str){
    var file = Components.classes["@mozilla.org/file/directory_service;1"]
      .getService(Components.interfaces.nsIProperties)
      .get(str, Components.interfaces.nsIFile);
    if (str == 'CurProcD') {
      file = file.parent;
    };
    return file.path;
  };


 launch = function (RanPath,OpenPath){
    var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsIFile);
    var proc = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
    var args = [OpenPath];
    file.initWithPath(RanPath);
    // если редактор, определенный в разделе конфигурации, не найден, переключитесь на настройку в about: config:
    if (!file.exists()) {
      var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
      RanPath=pref.getCharPref("view_source.editor.path");
      file.initWithPath(RanPath);
    }
    proc.init(file);
    proc.run(false, args, args.length);
  };


  stringComparison = function (a, b){
    a = a.toLowerCase();
    a = a.replace(/ä/g,"a");
    a = a.replace(/ö/g,"o");
    a = a.replace(/ü/g,"u");
    a = a.replace(/ß/g,"s");
    b = b.toLowerCase();
    b = b.replace(/ä/g,"a");
    b = b.replace(/ö/g,"o");
    b = b.replace(/ü/g,"u");
    b = b.replace(/ß/g,"s");
    return(a==b)?0:(a>b)?1:-1;
  };


  getScripts = function   (iType) {
    // Массивы (по одному массиву для uc.js,uc.xul, css) выбирают имена найденных скриптов
    var ucJsScripts = [];
    var ucXulScripts = [];
    var ucCSScripts = [];
    // Шаблон поиска, то есть расширения файлов uc.js, uc.xul, css
    var extjs = /\.uc\.js$/i;
    var extxul= /\.uc\.xul$/i;
    var exttcss= /\.css$/i;
   // Для uc.js, uc.xul
    var aFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    aFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path);
    var files = aFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
   // Для css
    var sFolder = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
    sFolder.initWithPath(Services.dirsvc.get("UChrm", Ci.nsIFile).path);
    sFolder.appendRelativePath("CSS");
    var sfiles = sFolder.directoryEntries.QueryInterface(Ci.nsISimpleEnumerator);
    // Просматривать папки или файлы и проверять, включены ли найденные файлы для uc.js, uc.xul
    while (files.hasMoreElements()) {
      var file = files.getNext().QueryInterface(Ci.nsIFile);
      // нет нужного файла, поэтому продолжайте
      if (!extjs.test(file.leafName) && !extxul.test(file.leafName)) continue;
      // uc.js найдено -> положить в массив
      if (extjs.test(file.leafName)) ucJsScripts.push(file.leafName);
      // uc.xul найдено -> положить в массив
    if (extxul.test(file.leafName)) ucXulScripts.push(file.leafName);
    }
   // Просматривать папки или файлы и проверять, включены ли найденные файлы для css
    while (sfiles.hasMoreElements()) {
      var sfile = sfiles.getNext().QueryInterface(Ci.nsIFile);
      // нет нужного файла, поэтому продолжайте
      if (!exttcss.test(sfile.leafName)) continue;
      // css найдено -> положить в массив
      if (exttcss.test(sfile.leafName)) ucCSScripts.push(sfile.leafName);
    }
    if (uProfMenu.sortScripts) {
      ucJsScripts.sort(stringComparison);
      ucXulScripts.sort(stringComparison);
      ucCSScripts.sort(stringComparison);
    }
    // Вызов следующих методов для заполнения подменю или буфера обмена
    if (iType==0) {
      fillMenu("submenu-ucjs","submenu-ucjs-items", "Файлы  uc.js",ucJsScripts,"uProfMenu_ucjs",0);
      fillMenu("submenu-ucxu","submenu-ucxu-items", "Файлы uc.xul",ucXulScripts,"uProfMenu_ucxu",0);
      fillMenu1("submenu-css","submenu-css-items", "Файлы css",ucCSScripts,"uProfMenu_css",0);
     } else {
     var result = fillClipboardValue(ucJsScripts,ucXulScripts,ucCSScripts);
      Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper).copyString(result);
    }
  };


  function fillMenu (whichsubmenu, whichsubmenuitems, strlabel, scriptArray,sClass,sTyp,sId) {
    // Добавить заголовок подменю с количеством найденных файлов
    var e = document.getElementById(whichsubmenu);
    e.setAttribute('label',strlabel + ' (' + scriptArray.length + ')');
    var popup = document.getElementById(whichsubmenuitems);
    // подменю
    while(popup.hasChildNodes()){
      popup.removeChild(popup.firstChild);
    }
    // Подменю заполнить
    for (var i = scriptArray.length-1; i > -1; i--) {
      // для пунктов подменю uc.js, uc.xul, abouts 
      if (sTyp==0){
        var mitem = createME("menuitem",scriptArray[i],"edit(0,'"+scriptArray[i]+"')",sClass,0);
        //mitem.setAttribute("onclick","openAtGithub(event,'"+scriptArray[i]+"')");
        mitem.onclick = function (event) { openAtGithub(event,'"+scriptArray[i]+"') };
        mitem.setAttribute("tooltiptext"," ЛКМ: Редактировать\n СКМ: Поиск по форуму camp-firefox.de\n ПКМ: Поиск по сайту GitHub");
       } else  {
        var mitem = createME("menuitem",scriptArray[i],"gBrowser.selectedTab = gBrowser.addTab('"+scriptArray[i]+"')",sClass,0);
      } 
      popup.insertBefore(mitem, popup.firstChild);
      
    }
  };

   function fillMenu1 (whichsubmenu, whichsubmenuitems, strlabel, scriptArray,sClass,sTyp,sId) {
    // Добавить заголовок подменю с количеством найденных файлов
    var e = document.getElementById(whichsubmenu);
    e.setAttribute('label',strlabel + ' (' + scriptArray.length + ')');
    var popup = document.getElementById(whichsubmenuitems);
    // подменю
    while(popup.hasChildNodes()){
      popup.removeChild(popup.firstChild);
    }
    // Подменю заполнить
    for (var i = scriptArray.length-1; i > -1; i--) {
      // для пунктов подменю css
      if (sTyp==0){
        var mitem1 = createME("menuitem",scriptArray[i],"edit(3,'"+scriptArray[i]+"')",sClass,0);
       }
      popup.insertBefore(mitem1, popup.firstChild);
      
    }
  }; 

   function fillClipboardValue (sArray,xArray,yArray) {
    var retValue;
    var s = 0;
    var x = 0;
     var y = 0; 
    s = sArray.length;
    x = xArray.length;
    y = yArray.length;
    switch(uProfMenu.enableScriptsToClip) {
      case 1:
        retValue = "userChrome/uc.js ("+s+"):\n------------------------\n"+sArray.join("\n")+
                   "\n\nuserChrome/uc.xul ("+x+"):\n-------------------------\n"+xArray.join("\n")+
                   "\n\nuserChrome/css ("+y+"):\n-------------------------\n"+yArray.join("\n");
        break;
      case 2:
        retValue = "userChrome/uc.js ("+s+"):\n------------------------";
        for (var i = 0; i < s ; i++) {
          j = i + 1;
          retValue = retValue + "\n" + j + ". " + sArray[i];
        }
        retValue = retValue + "\n\nuserChrome/uc.xul ("+x+"):\n-------------------------";
        for (var i = 0; i < x ; i++) {
          g = i + 1;
          retValue = retValue + "\n" + g + ". " + xArray[i];
        }
        retValue = retValue + "\n\nuserChrome/css ("+y+"):\n-------------------------";
       for (var i = 0; i < y ; i++) {
          h = i + 1;
          retValue = retValue + "\n" + h + ". " + yArray[i];
        }
    }
    return retValue;
  };


function createME (sTyp,sLabel,sCommand,sClass,sId) {
    // Создание элемента меню, меню или меню - параметры, не используемые для определенных типов, передаются как 0
    const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
    var m = document.createElementNS(XUL_NS, sTyp);
    switch (sTyp) {
      case "menuitem":
        m.setAttribute('label', sLabel);
       m.setAttribute('oncommand', sCommand);
       m.setAttribute('class',sClass);
        break;
      case "menu":
        m.setAttribute('label', sLabel);
        m.setAttribute('id', sId);
        break;
      case "menupopup":
        m.setAttribute('id', sId);
        break;
    }
    return m;
  };
openAtGithub = function (e,sScript) {
    if (e.button==1){
      // СКМ - Начать поиск на camp-firefox.de (работает, только если имя файла хранится в коде):
      var sUrl="https://www.google.com/search?as_q="+sScript+"&as_sitesearch=www.camp-firefox.de&gws_rd=ssl";
      openWebLinkIn(sUrl, 'tab');
    }
    if (e.button==2){
      // ПКМ - Начать поиск на GitHub (работает, только если имя файла хранится в коде):
      e.preventDefault();
      var sUrl="https://www.google.com/search?as_q="+sScript+"&as_sitesearch=github.com&gws_rd=ssl";
      openWebLinkIn(sUrl, 'tab');
    }
  };


 function cleanFileName(sName) {
    sName=sName.toLowerCase();
    /* Следующий массив содержит регулярные выражения для удаления недопустимых строк:
    /Datei-Erweiterungen am Ende/, /"ucjs_" am Anfang/, /"_"gefolgtVonZahlUndDanachBeliebigenZeichen/
    / "_fx"gefolgtVonZahl(en)/, /"-" oder "+" oder "."/, /"_v"gefolgtVonZahlen
    */
    var regs=[/\.uc\.js$/,/\.uc\.xul$/,/^ucjs_/,/_\d.+/,/_fx\d+/,/[-+\.]/g,/_v\d+/];
    for (var i = 0; i < regs.length; i++) {
      sName=sName.replace(regs[i],"");
    }
    return sName;
  };
	})();




/*Initialization Code*/
// ==UserScript==
// @name           SaveUserChromeJS.uc.js
// @author         ywzhaiqi
// @description    установка контекстного меню кнопок на github для скачивания скриптов
// @include        main
// @charset        UTF-8
// @version        0.4b
// @homepageURL    https://github.com/ywzhaiqi/userChromeJS/tree/master/SaveUserChromeJS
// @reviewURL      http://bbs.kafan.cn/thread-1590873-1-1.html
// ==/UserScript==

(function() {

// Включены ли уведомления после сохранения?
var notificationsAfterInstall = true;

// Загружается ли скрипт после сохранения (запускать не нужно)? Поддерживается только .uc.js, некоторые скрипты проблематичны.
var runWithoutRestart = true;

let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
if (!window.Services) Cu.import("resource://gre/modules/Services.sys.mjs");

const RE_USERCHROME_JS = /\.uc(?:-\d+)?\.(?:js|xul)$|userChrome\.js$/i;
const RE_CONTENTTYPE = /text\/html/i;

var ns = window.saveUserChromeJS = {

    init: function() {
           // добавить в contentAreaContextMenu
              if ( document.getElementById("uc-install-menu") ) return; 
              var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
        var icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAICAAP//AICAgMDAwP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcj7VkAAABfdFJOU/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8Ak5pfLAAAAAlwSFlzAAAOwwAADsMBx2+oZAAAAFxJREFUKFNljgEOwCAIAwuF/395RWXMrDExHLQA3gKYpVXojwPo6SpewDSzAHGAXvWpkQYagNSWN2EyfGUM+G/RQWZFOnSt9AZMR3nGwggivqF1Q12xQVzavRHwALQIAv2bDRzYAAAAAElFTkSuQmCC";
        var contextMenu = document.getElementById("contentAreaContextMenu");
              var menuitem = document.createElementNS(xulns, "menuitem");
        menuitem.setAttribute("id", "uc-install-menu");
        menuitem.setAttribute("label", "Установить для userChromeJS");
        menuitem.setAttribute("class", "menuitem-iconic");
        menuitem.setAttribute("image", icon);
        menuitem.setAttribute("accessKey", "I");
       // menuitem.setAttribute("oncommand", "saveUserChromeJS.saveScript(gContextMenu.linkURL)");
menuitem.onclick = function (event) { saveUserChromeJS.saveScript(gContextMenu.linkURL) };
              contextMenu.insertBefore(menuitem, contextMenu.firstChild);
              contextMenu.addEventListener("popupshowing", this, false);
        this._menuitem = menuitem;
    },
    handleEvent: function(event){
        switch(event.type){
            case "popupshowing":
                if (event.target != event.currentTarget) return;
                if(gContextMenu.onLink){
                    this._menuitem.hidden = !RE_USERCHROME_JS.test(gContextMenu.linkURL);
                }else{
                    this._menuitem.hidden = true;
                }
                break;
        }
    },
    saveScript: function(url) {
        var name, fileName, fileExt, charset;
        name = name && name[1] ? name[1] : decodeURIComponent(url.split("/").pop());
        fileName = name.replace(/\.uc\.(js|xul)$|$/i, ".uc.$1").replace(/\s/g, '_');
        if (fileName.match(/\.uc\.$/i)) {  // Исправить имя
            var m = url.match(/\.(js|xul)$/);
            if (m)
                fileName += m[1];
        }
        charset = "UTF-8";
            var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
            var err = false;
          
            // fp.init(window, "", Ci.nsIFilePicker.modeSave);
           // fp.init(parseInt(Services.appinfo.platformVersion) < 125 ? window : window.browsingContext,"", fp.modeSave);
          fp.init(window.browsingContext, "", Ci.nsIFilePicker.modeSave);
         
        var SCRIPTS_FOLDER = Services.dirsvc.get("UChrm", Ci.nsIFile);
        var xhr = new XMLHttpRequest();
        var url2 = url.replace("\/blob", "raw");
        xhr.open('GET', url2, true);
        xhr.onload = () => {
        if (xhr.status == 200) {
        var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
          uc.charset = 'utf-8';
          var text = uc.ConvertFromUnicode(xhr.responseText);
            }

        fp.displayDirectory = SCRIPTS_FOLDER; 
            fp.appendFilters(Ci.nsIFilePicker.filterAll);
            fp.defaultExtension = fileExt;
            fp.defaultString = fileName;
            var nsIFilePicker = Components.interfaces.nsIFilePicker;
            fp.open(function (rv) {
        if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {

        var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
        foStream.init(fp.file, 0x02|0x20|0x08, 0666, 0);
         
         foStream.write(text, text.length);
        foStream.close();
            if(notificationsAfterInstall){
                                    var win = err ? ns.getMostRecentWindow() : window;
                                    win.setTimeout(function(){
                                    fileExt1 = name.match(/\.uc\.(js|xul)$/i);
                                    fileExt1 = fileExt && fileExt[1] ? fileExt[1] : "js";
                                    ns.showInstallMessage({
                                        fileExt: fileExt1,
                                        fileName: fileName,
                                        file: fp.file,
                                        charset: charset
                                    });
                                }, 100);
                                      }
             }
         });
}
        xhr.send();
    },
    showInstallMessage: function(info){
        var isRun = (info.fileExt == "js");

        var mainAction, secondActions;
        if(runWithoutRestart && isRun){
            mainAction = {
                label: "Выполнить без перезапуска.",
                accessKey: "a",
                callback: function(){
                var dir = Services.dirsvc.get("UChrm", Ci.nsIFile);
                dir.initWithPath(dir.path + "\\" + info.fileName);
                var url = Services.io.newFileURI(dir).spec;
                let context = {};
                Services.scriptloader.loadSubScript( url, context, "UTF-8");

             var showedMsg1 = ns.popupNotification({
             id: "userchromejs1-install-popup-notification",
             message: "Скрипт запущен",
             options: {
                removeOnDismissal: true,
                persistWhileVisible: true
                      }
                   });
                }
            };
            secondActions = [{
                label: "Перезагрузите сейчас",
                accessKey: "s",
                callback: ns.restartApp
            }];
        }else{
            mainAction = {
                label: "Перезагрузите сейчас",
                accessKey: "s",
                callback: ns.restartApp
            };
            secondActions = null;
        }

        var showedMsg = ns.popupNotification({
            id: "userchromejs-install-popup-notification",
            message: "'" + info.fileName + "' Установка завершена.",
            mainAction: mainAction,
            secondActions: secondActions,
            options: {
                removeOnDismissal: true,
                persistWhileVisible: true
            }
        });
    },
    popupNotification: function(details){
        var win = ns.getMostRecentWindow();
        if (win && win.PopupNotifications) {
            win.PopupNotifications.show(
                win.gBrowser.selectedBrowser,
                details.id,
                details.message,
                "",
                details.mainAction,
                details.secondActions,
                details.options);
            return true;
        }

        return false;
    },
    getMostRecentWindow: function(){
        return Services.wm.getMostRecentWindow("navigator:browser")
    },
    restartApp: function() {
       Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart)
    }
};
function log(arg){ Application.console.log("[SaveUserChromeJS]" + arg);}
})();
window.saveUserChromeJS.init();


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

Отсутствует

 

Board footer

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