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

Хотите узнать больше о расширениях? Посмотрите ролики, рассказывающие о работе с расширениями Firefox.

№1382628-10-2019 11:20:52

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

Re: Custom Buttons

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

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

Отсутствует

 

№1382728-10-2019 15:34:14

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

Re: Custom Buttons

Dumby пишет

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

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

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

Отсутствует

 

№1382828-10-2019 15:47:35

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

Re: Custom Buttons

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

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

Отсутствует

 

№1382929-10-2019 23:40:52

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

Re: Custom Buttons

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

Отсутствует

 

№1383031-10-2019 16:06:37

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

Re: Custom Buttons

Andrey_Krropotkin пишет

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

Вариант

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

Выделить код

Код:

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

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

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

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

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

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

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

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

Отсутствует

 

№1383131-10-2019 18:28:47

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

Re: Custom Buttons

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

Отсутствует

 

№1383201-11-2019 21:34:54

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

Re: Custom Buttons

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

Отсутствует

 

№1383301-11-2019 23:53:34

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

Re: Custom Buttons

Нет не в курсе

Отсутствует

 

№1383402-11-2019 00:36:34

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

Re: Custom Buttons

solombala пишет

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

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

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

Поиск: PT__onMouseMove

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

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

Выделить код

Код:

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

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

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

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

Отсутствует

 

№1383502-11-2019 09:08:55

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

Re: Custom Buttons

Dumby
Сказать, что это круто, ничего не сказать... В самом browserPlacesViews.js

скрытый текст
this._openedMenuButton.open = false;
      target.open = false;

И седела....Велико Хвала, брате!

Отсутствует

 

№1383602-11-2019 14:27:57

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1700
UA: Firefox 42.0

Re: Custom Buttons

solombala пишет

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

Это когда на панели закладок одну папку открыл, а потом при наведении курсора на другие папки, они автоматически открываются?

UPD
Получилось, Dumby спасибо.
Только не понял почему только сейчас заработало, сразу после перезапуска не работало.

Отредактировано Stkvsky (03-11-2019 20:00:31)

Отсутствует

 

№1383704-11-2019 10:29:06

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

Re: Custom Buttons

Dumby
Очистка истории загрузок , а никак просто в код ? Или только при выходе?

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

Выделить код

Код:

Services.obs.addObserver(closer, "quit-application", false);

((g, id, {history}) => addDestructor(r => id in g && g[id].destroy(r)) || id in g || ({
    clearOnRestart: false,
    su: Services.startup,
    init() {
        g.AsyncShutdown.quitApplicationGranted.addBlocker(
            id, this.condition = this.condition.bind(g[id] = this)
        );
    },
    destroy(reason) {
        if (reason[5] != "e") return;
        delete g[id];
        g.AsyncShutdown.quitApplicationGranted.removeBlocker(this.condition);
    },
    condition() {
        return this.su.restarting && !this.clearOnRestart || history.removeVisitsByFilter({
            transition: history.TRANSITIONS.DOWNLOAD
        });
    }
}).init())(
    Cu.import("resource://gre/modules/AsyncShutdown.jsm", {}),
    "Custom Buttons button: Clear downloads history.", PlacesUtils
);

Отсутствует

 

№1383804-11-2019 13:36:47

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

Re: Custom Buttons

solombala пишет

Очистка истории загрузок

Ну, наверно, смотря что чистить. Если всё, то может так

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

Выделить код

Код:

Downloads.getList(Downloads.ALL).then(
    async list => (await list.getAll()).forEach(list.remove, list),
    Cu.reportError
);
PlacesUtils.history.removeVisitsByFilter({
    transition: PlacesUtils.history.TRANSITIONS.DOWNLOAD
}).catch(Cu.reportError);

Отсутствует

 

№1383904-11-2019 17:40:40

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1700
UA: Firefox 42.0

Re: Custom Buttons

Dumby
Добавляю ссылки в закладки с помощью вашей кнопки Добавить закладку в: в контекстном меню
А можно вас попросить сделать горячую клавишу для этой кнопки? ПКМ+ЛКМ
Чтобы при зажатой ПКМ и клике ЛКМ кнопка срабатывала.

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

Выделить код

Код:

((popup, {lastChild} = popup, pref = "CB.bookmarkFolderGuidForSaving") =>
addDestructor(reason => reason == "delete" && Services.prefs.clearUserPref(pref)) +
addEventListener("popupshowing", {
    index: 0, // 0 - первой, PlacesUtils.bookmarks.DEFAULT_INDEX - последней
    width: 500,
    height: 640,
    nodePosition: .35,
    handleEvent(e) {
        if (this.shouldHide) return;
        var menuitem = document.createElementNS(xulns, "menuitem");
        menuitem.id = "context-addBookmark";
        menuitem.className = "menuitem-iconic";
        menuitem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACD0lEQVR42oWTXUhTYRiAP89qziAYepG6TfAiyV1JsFojMJrVjf3dDOsmMoOwCwnSXLSJXgWDqAWBF7aGoFGGV0EUrL9FERoh1bQsqeiXfrzoB0N6es8528ncaC88fOfwnff53vN976eUUprafJk8lPIKS1XRkI8LRVayUVgmLBFsQklBwfhb8rAkRauSidQLDK49/zvqFKmqxBKcn4BzDzBGnU39BVZfTMOxQ6ZIXk6msdh7wUz+9IP/RraaLYYgfAUL73Fz8tJjs5rBh3B2HPrvQ/P+N8TvYJAVdBqCfRcxWH8aYm0dpCIRxvr6SG7bSWLrDsZ6e7ke7SESaiV61UoeFVoMwfYEBrGWNr6NjEAmY5JKmUxPw9QU35NJDq/ekBOcEqoNQSAOnh5Ih0IwPAwJsQ0MSP2DMDTEfDTKV7+f904nN12uBavr/SECZ6dZ1u11Aejqgu5u2ZAwv9vbmfP5mLXZeK0UrzSNGy53bnWXdYw6K47CEX8znwMB5oNBvtTX87G0lA+SmEueqazkYHWdLtgl1OVaybvwfPd41vLI42HGbicjiZPCy7IyntTUcKBqpZ58Iru61dZ6a64RwkJMmGi022dv1dbyrKKCp+XlpOW5yeH4KXPvhMbs3fgndJtDqDJ3VjX4NO3MqNs9J/xapWn3sv/dlJfcGr+rFbijunC5EBQ6hN2C27j6i+IP/uDMhPNYgHUAAAAASUVORK5CYII=");
        menuitem.setAttribute("oncommand", "linkedObject.oncommand(event);");
        menuitem.linkedObject = this;
        menuitem.oncontextmenu = e => this.pick(e.preventDefault());

        lastChild.after(menuitem);
        addDestructor(() => menuitem.remove());
        (this.handleEvent = e => e.target == popup
            && !(menuitem.hidden = this.shouldHide)
            && this.update(menuitem)
        )(e);
    },
    ons: ["isContentSelected", "onTextInput", "onImage", "onVideo", "onCanvas", "onAudio"],
    get shouldHide() {
        if (gContextMenu.onLink) return false;
        return this.ons.some(on => gContextMenu[on]);
    },
    oncommand(e) {
        this[e.ctrlKey || e.shiftKey ? "pick" : "bookmark"](e.target);
    },
    get guid() {
        return Services.prefs.getStringPref(pref, PlacesUtils.bookmarks.toolbarGuid);
    },
    async update(menuitem) {
        var info = await PlacesUtils.bookmarks.fetch(this.guid);
        var title = PlacesUtils.bookmarks.getLocalizedTitle(info);
        menuitem.label = "Добавить закладку в: " + (
            menuitem.folderName = title || "[без заголовка]"
        );
    },
    pick() {
        var features = "chrome,all,resizable,centerscreen,modal";
        window.openDialog(this.url, "_blank", features, this.guid);
    },
    bookmark({folderName}) {
        if (gContextMenu.onLink) {
            var url = gContextMenu.linkURL;
            var title = gContextMenu.linkText();
        } else {
            var url = gBrowser.currentURI.spec;
            var title = gBrowser.contentTitle || gBrowser.selectedTab.label;
        }
        var info = {url, title, parentGuid: this.guid, index: this.index};
        PlacesUtils.bookmarks.insert(info).then(
            () => this.notify(title, "Добавил закладку в папку: " + folderName),
            err => this.notify("Ошибка", err)
        );
    },
    get alert() {
        var as = this.as = Cc["@mozilla.org/alerts-service;1"]
            .getService(Ci.nsIAlertsService);
        this.alertName = _id + "-bookmark-alert";
        delete this.alert;
        return this.alert = as.showAlertNotification
            .bind(as, "chrome://global/skin/icons/warning.svg");
    },
    notify(title, msg) {
        this.alert(title, msg, false, null, null, this.alertName);
        setTimeout(() => this.as.closeAlert(this.alertName), 1800);
    },
    get url() {
        var xul =
            `<?xml version="1.0"?>
            <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
            <?xml-stylesheet href="chrome://browser/content/places/places.css"?>
            <?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
            <?xml-stylesheet href="chrome://browser/skin/places/tree-icons.css"?>
            <dialog xmlns="${xulns}"
                id="bookmark-folder-saver-dialog"
                windowtype="bookmark-folder-saver:dialog"
                title="Выберите папку"
                buttons="accept,cancel"
                onload="init();"
                width="${this.width}"
                height="${this.height}">

                <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
                <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
                <script type="application/javascript"><![CDATA[
                    ChromeUtils.defineModuleGetter(window, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm");
                    ChromeUtils.defineModuleGetter(window, "PlacesUIUtils", "resource:///modules/PlacesUIUtils.jsm");
                    ChromeUtils.defineModuleGetter(window, "PlacesTransactions", "resource://gre/modules/PlacesTransactions.jsm");
                    ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
                    XPCOMUtils.defineLazyScriptGetter(window, "PlacesTreeView", "chrome://browser/content/places/treeView.js");
                    XPCOMUtils.defineLazyScriptGetter(
                        window,
                        ["PlacesInsertionPoint", "PlacesController", "PlacesControllerDragHelper"],\n\
                        "chrome://browser/content/places/controller.js"\n\
                    );
                ]]></script>
                <script type="application/javascript" src="chrome://browser/content/places/places-tree.js"/>

                <tree id="tree" type="places" is="places-tree"
                    place="place:type=${
                        Ci.nsINavHistoryQueryOptions.RESULTS_AS_ROOTS_QUERY
                    }&amp;excludeItems=1&amp;excludeQueries=1"
                    hidecolumnpicker="true" seltype="single" flex="1">
                    <treecols>
                        <treecol id="title" flex="1" primary="true" hideheader="true" />
                    </treecols>
                    <treechildren />
                </tree>
                <script type="application/javascript"><![CDATA[
                    var tree = document.getElementById("tree");
                    function init() {
                        tree.selectItems([window.arguments[0]]);
                        var ind = tree.view.selection.currentIndex;
                        ind != -1 && setTimeout(() => {
                            if ("nsITreeBoxObject" in Ci) {
                                var tbo = tree.treeBoxObject;
                                var visibleRows = tbo.height/tbo.rowHeight;
                            } else {
                                var tbo = tree;
                                var visibleRows = tbo.getPageLength();
                            }
                            var cur = tbo.view.selection.currentIndex;
                            var first = tbo.getFirstVisibleRow();
                            var newFirst = cur - ${this.nodePosition}*visibleRows + 1;
                            tbo.scrollByLines(Math.round(newFirst - first));
                        }, 0);
                        var onKeydown = e => e.ctrlKey && e.key == "Enter" && !e.shiftKey
                            && document.documentElement.acceptDialog(e.stopPropagation());
                        addEventListener("keydown", onKeydown, true);
                        addEventListener("dialogaccept", dialogCallback);
                        window.onunload = () => {
                            removeEventListener("keydown", onKeydown, true);
                            removeEventListener("dialogaccept", dialogCallback);
                        }
                    }
                    function dialogCallback() {
                        var ind = tree.view.selection.currentIndex;
                        if (ind == -1) return;
                        var item = tree.view.nodeForTreeIndex(ind);
                        item && Services.prefs.setStringPref(
                            "${pref}", PlacesUtils.getConcreteItemGuid(item)
                        );
                    }
                ]]></script>
            </dialog>`;
        var url, type = "application/vnd.mozilla.xul+xml";
        if (parseInt(Services.appinfo.platformVersion) >= 69 && Services.appinfo.browserTabsRemoteAutostart) {
            url = `chrome://custombuttons/content/cbfolderpicker${Date.now()}.xul`;
            var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
            this.helper = ams.registerChrome(
                Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)),
                [["override", url, `data:${type},${encodeURIComponent(xul)}`]]
            );
            addDestructor(this.helper.destruct);
        } else {
            url = URL.createObjectURL(new Blob([xul], {type}));
            addDestructor(() => URL.revokeObjectURL(url));
        }
        delete this.url; return this.url = url;
    }
}, false, popup || 1))(document.getElementById("contentAreaContextMenu"));

Отредактировано Stkvsky (04-11-2019 17:41:03)

Отсутствует

 

№1384005-11-2019 09:16:16

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

Re: Custom Buttons

Dumby
Да, чистит и в библиотеке, класс!

Отсутствует

 

№1384106-11-2019 12:54:45

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

Re: Custom Buttons

После обновления до 70.0.1 (с 68-й) перестали показываться менюшки кнопок Quick toggle for about:config preferences и Восстановить закрытую вкладу (Undo Closed Tab, где можно выбрать какую вкладку/окно восстановить), причём именно эти кнопки стали отображаться на уровне меню и кнопками управления окном, а все рабочие кнопки (в т.ч. CB) и строка поиска упала ниже, сместив панель вкладок (картинка на ЯД). Причём сам редактор кнопок открываться не хотел! Чтоб накатить 7.0.0.6 (которая на anonfile всё ещё хранится) на 7.0.0.7 спас только scratchpad (а консоль писала что-то про «Cc»). Возможно уже после замены дополнения и перезапуска окно редактирования кнопки стало открываться, но наконец получилось всё исправить: оказалось достаточно было во всех проблемных кнопках (те, что выскочили вверх) заменить createElement на createXULElement. И разко кнопки стали на свои места, убрав пустое пространство в строке меню, и панель вкладок стала видна нормально. Спасибо func4ptch4 за обновлённый код, а то до меня не сразу дошло, к чему был разговор про createXULElement и createElementNS(xulns...
Закрепите отдельную модерируемую тему с инструкциями к разным версиям [firefox], чтоб по несколько раз не гонять каждого пользователя перелистывать десятки (а то и больше) страниц, – не придётся просить модераторов менять шапку этой темы (ага, а то последний раз Yan`ом редактировалась аж в конце 2010г) – сами будете обновлять свои же посты, добавляя решения для новых версий.

Отредактировано T0PMØ3iLLA (06-11-2019 12:56:53)

Отсутствует

 

№1384206-11-2019 15:28:30

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

Re: Custom Buttons

привет.
есть исправленная кнопка с переводом страницы через яндекс перевод?
спасибо

Отсутствует

 

№1384306-11-2019 17:35:17

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

Re: Custom Buttons

firepox
Для какого релиза нужна?

Отсутствует

 

№1384406-11-2019 17:57:06

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

Re: Custom Buttons

Garalf
56.0.2

Отсутствует

 

№1384506-11-2019 17:59:48

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

Re: Custom Buttons

Garalf пишет

firepox
Для какого релиза нужна?

а можно для [firefox]70.0.1 CB 0.0.7.0.0.7

Отсутствует

 

№1384606-11-2019 18:20:03

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

Re: Custom Buttons

7dk60f4.png

Отредактировано firepox (06-11-2019 18:20:46)

Отсутствует

 

№1384706-11-2019 19:56:23

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

Re: Custom Buttons

sachka
Для 70

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

Выделить код

Код:

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

//Ключи
//Яндекс
var keyuser = "trnsl.1.1.20190511T084252Z.63e27c3fa2187826.f878f92f5d49b20661cfcff87fb996fe773a9b35"; //"trnsl.1.1.20170531T164120Z.57e9764369279ca0.2a07c3f1cc980dab3c31eb4d00e5a85d78cfd50d"; - ключ из свободного доступа
//Microsoft
var keyus = "____Ваш ключ______"; 


//Варианты выбора языка переводчика для перевода текста в окне. Нужное разкоментировать. Остальное закоментировать.
//Google,
var langFrom_google_text = "auto";//авто
var langTo_google_text = "ru"; 
//Microsoft 
var langFrom_Microsoft_text = "";//авто 
var langTo_Microsoft_text = "ru"; 
//Promt 
var langFrom_PROMT_text = "a";//авто
var langTo_PROMT_text = "r"; 
//Яндекс 
var langFrom_yandex_text = ""; //авто
//var langFrom_yandex_text = "en-"; //английский и так же другие языки, тире обязательно
var langTo_yandex_text = "ru";
      
//Назначаем иконки
var mainicon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAALCAIAAAD5gJpuAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQtJREFUKM9VkSFOhFEQg799/CjEihWAwKDgIFwAyWHgLDjuAGfZgMCQDQkG8abtQ/z8u9A0k4rOTCez2u0GB0gCsLELbCuxLduJy0zAZgOQBBqQALEbtOQoyRgjSZLt9nOaJyf5K2zPjr01SWst8ermZtzd5euLhCQ2Y9iOHXssIvZYr1f39x/T87Ourtr7O3ZUyK6KlN5HVRaOqlxcNGACJKRItigdHFXpFdXoPVWRGmSac0suRYWUWhz7zt5/BXh65Pi6Hr7rI/IopZyqpSqldLsq9onPX3iabuHYr6o3pCVHP2Sa11nIzZdnMAmOSpyejiocVEhtjrwc15L5l4HVDgReCGTR+V9n/AAByma0J+vVwwAAAABJRU5ErkJggg==";
var gticon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADPElEQVR4nGWTTWhjZRSG3/uTNr39mTqTn1KacagTqyKIlYJ2ExQCUhiprgpduRVFpLvZjOCsXEgWFqRk0RZcWLopmOnCQcPUsVBiTEZbalrGTJOZJm2aNGm++92b737fcdGZTfvAuznwnMV7OBouEI/HdSHEyNzcXCwajb7r8/n6T09P99bW1u4PDw8/SiQSbHd396IGBINBJJPJQDqdvssYK0kpO0SkiIiUUlII0SqVSr8lk8n3JycnjUsLZmdnb5bL5T+klPK5RNzp0BlzyHEFKXU+cxynubKy8tXExIQJABoAzM/PB6amptYikch70DRtv3iMh5kClPQglcKzozMMXhnAh7E3EL0RhCcEX19f/6xSqSxhdHRUT6VS39i2LYUQtJ7epm9/uEdHtSZJKUkpRa0zm75fvE+f3/mRmM3JcRyqVqulmZmZl7G6uhopl8sHtm3TduEpffH1T1Srn9FFavUmnTRaJKUkx3Go0WiojY2N22aj0Yj5fL6wJyVS6R289koYVwd7L3V07aUBAICUEkopSCk1v99/Sw+Hw5NSyi7OXZQrTQwFBy6f6DlKKSil4HkeOp0ODMO4btq23S+EgFQaAAKzO1BKQdd1AICmaSAiEBGUlBBCwHVduK4LzrlpHh4e7nHOVW+vofdbPmxkHuPWB6/D6vFD13UoRfj38TPsP6mBOxJjN64gdNUC5xz1er2l5/P5XxqNBvNEByPBLmS2n+LXzQK4zcH5ebp9GkAeEksPwJgNxhhs20axWMzo7Xb7US6Xyx7Xanh7LIhXRywklh7i9z/30Wy1YNsMfT0mrG4DGoCO64Ixhlqt5uTz+UVjZ2dHDA0NFYPB4Cd9fVb3W2MhnDZb+DldwD+FCk5OWvivVEX27ycY7APevHkNouNSNpu9l8vlvtMAIBQKGfF4/Mvp6em7oVCoxzAMOB0PjAsQEfxdPvi7DBgG4Dgu5fP5vxYWFj4uFAoHBgAwxmhvby8jpTywLOsdy7IGfKah9XSb56IOeJ7A0dGxs7m5mVpeXv60Xq8fcM7Pf+EFsVhMq1Qq18fHx2ej0ehHgUAgYpqm2W63W6VSKVMsFhe3trYeVKtV/sL5HwhICaDODiyAAAAAAElFTkSuQmCC";
var promticon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADQ0lEQVQ4jX2TX2xTdRTHT7O4GWL0gSwKmphoi3SsdFXHZiRjDExGSIxGHoTgwzDAUoM4skgEE6ckmiiEB2D8GYqbo2LLrmxZ51rWlob+W1e2ua2z2tp1ZVzrunZr161r7/3drw9TCLr4Sc7b+Zycc3IO0QNkY4M333LrD19zGbSc64aWc/VoOZepnnOZD3KuHi3nNB9rCQQcW2kl7CPjH3tPF7OUjpAxEbKDhNwEQUgSxBRBiD8GYWY/UlONzHO76YJery+4LwcmJmrHZtL5tlOVmGsjzPcQFgcIuRBBmCaIaYKYJIip18HyHiylv2Ae5wUtERGFef5ZZzQWS4sSmjgO060yzBsJi/2E3G8E4Y/lDpajDJIwDEkMwW2rHvf5fI/QlZHQFc+CBO8CQ9efOVw8s225gIewFCDkeRnEuSKwzGqw7PuQWAySlMFcrJ4NeIyv0SFv+N5nvIjdgSx2+NLYZ/Sio7nW4uTqdE7jIZ3TfFzntH6u03ON9g/aq9DQvgkftlfg5A+1aGk50EG77MHEK3cyKLHPQm6aRrkljqYu+/V/L/mNjroual0HuqwAnVeAzsix9og6Rg23xjmlLQm5OQ65OQ7FzRlstUyJtoHB7f/Ivf6+2kdNKpFMSlC3EvTjepDhBexo3tNLY+Ep9YaeyaX1tiSU9llscKSw0TOPPTecQ8FgsCgYDBZtt789Sv6NoGEVaKAU5C5F4fWSrHPIW05ERMetQxfV/fPQ+Bbw8nAWFaM5vDq6iK9tt9+77Pnu8NOz20AJDSimAd0tA4XVOGhovHR/vkgksqbqVjC5+VcBVSGGLb8zbAkxVHe642+OvpuQiSqQoAblNaClF1Hs2jQdjUbXPrSks1bHR5UjWZQPZqDxpKFyzEJ17VNckr5HIZOD2HMgUQHKrsOpn84e+c8p8zy/6qVzvZFnDJN46moYxedM+HKyGUPSCOpZI9awUjzBFCjr2+zneX7Viv/Q2tm3t+CEixWccKC68ygmhCj8wi8wCr04JnyCkruqfHd/984V5b+RnbxqbNj11VHLzrZ9kRr9O9ka614orTXseUPZvW8s39b9n/wQfr+/MBwOP+n+2V3huOOoTCQSj6+U9xeWlBixn0UlkAAAAABJRU5ErkJggg==";
var yndicon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC8UlEQVQ4jY2TTWgcZQCGv1OLgkX0UlChaC8iEUo1kNJV0UiTNl1SFasYk2pELeohVkOgWkILDSTR2tWGjRILhigVoxIbf1oaWkJtIokmYWOa3253t2T/Z2dnZmfnm5nv8RZIhdIXnst7eE7vK+oH5JvPfSe5HfZ963SImxPsL9E45PD6r/KWvDYsCfaXnN2nzYp1gt2nDZqGbJqGbJrP2ixrPpZU+AoMR5GxFCNRj6Yhmxe/t6j9uji6TvDsV3kaBk1az5XQy4q0pbia8WgYNMmVFA2DJhdWXCypaPrJJPhNgere/ME1wZM9aQ78oOMrGItJlIJIyiVf8rFdxWLW4+UzBfSyImv5vDCg8URPKlf1afw+IYQQO07eIGv5jMcc+v+2OPhjnqThkbV89g9kee9njZzlM5Fw+GXOpueKwa4vU1R9dmNACCHEY91RMqbH5Ws2ZVcR01ySRY/OCwXq+5LU9yWJaS5ayeeV/hQ5y6e+L8nOkzG2dy3vEYETK8Q0l7pwgpThURdOUBdOkLc89vYmiGkug9MGe3sTRHMSWyrqwgme+fw6FccXF0XFsTl026cmFGUx7VATilITihK+lKfsKjr/yKx1CymHklTUhKIEupd4uH32H/HQRzMYZZ94XlJ2FasFyWpBcmneIFN0CYZWqO5e4vlT15CeQrM8qruXeKQ9woOHp3aKB1onieccaj9ZIKW7PNVxdY1dXfOkiy77Ty2TNVzmV21az8R59MgM93842SuEEGJzyxjVx/9Fs1xe+mKB85ECgaMRAkcj1HbOYTk+17Nl9nTNkdIljx+ZZnPLldym5j/vEUIIce+7o1R9PEWwaxbD9nA9RVqXzMRMpqImTx+bwSx7pHVJoH2aLe+Pcfc7o6+uDWnT2yNUtk1Q2TbBjsOTXJzVsKVPseRxcVYjrUtOnI1T2TbB1pbL3PXWyPop3/nGebYdGmf7B3/dkm2Hxrmj+Zyzsfn3resEGxqHOzYc+I3bonH4f3f+Dz63ssfSaOz4AAAAAElFTkSuQmCC";
var bingicon="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABMUlEQVQ4jY2SsU7DMBCG/TJYYqpEPDojcbq0NGM7sXdnggnigYFOyVDqLLBAkRJLTIwJSwdYw8gj8AQ/Q0kaO6HNSZbPp/P332+ZkJ7hSo2uvNdFV2rwMEOVGw28UVjl5bZZaqi8hA3aqzB/KOBKDVWUrcZ6ir/dgLlSY/HxAx5mmD++d15u7jzMjDNxpcbZyzeE+mz563o4bteaY9nj2bktwP97F7upS72yUgdLfNDIA428g9SD/6APZG84SoDGwoDQeFurly3CEh+OEmBKIFgPcWwBCCHkKPJwt7nA+dvIFBg/C9wUV3VhsbnF4L4NmKYT0Fjg9HVoApgSSL/WBuBkZQKm6QQ08jDLgraF8ZPAdX6JJnCw3AFo5IHGArMs2NVsi44SYIkPlviozraFrvgFK3TyTsPvtF8AAAAASUVORK5CYII=";

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

var lc = navigator.lastClick = {};
addEventListener("mouseup", e => {
    if (e.button) return;
    lc.X = e.screenX - mozInnerScreenX;
    lc.Y = e.screenY - mozInnerScreenY;
}, false, gBrowser.tabpanels || 1);

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

    var docEle = (doc.compatMode == 'CSS1Compat' && win.postMessage) ? doc.documentElement : doc.body;
    var mX = docEle.clientWidth-w.offsetWidth, mY = docEle.clientHeight-w.offsetHeight;
    if(mX < 0){cnt.style.width = parseInt(cnt.style.width)+mX+'px'; mX = 0};
    if(mY < 0){cnt.style.height = parseInt(cnt.style.height)+mY+'px'; mY =0};
    var hW = parseInt(w.offsetWidth/2);
    w.style.left = (pos && pos.X < mX+hW ? (pos.X > hW ? pos.X-hW : 0) : mX)+'px';
    w.style.top = (pos && pos.Y+10 < mY ? pos.Y+10 : mY)+'px';
    w.style.visibility = 'visible';
    doc.addEventListener('keydown', keyDown, false);
    return w;
};

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

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

    return sM(txt);
};

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

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



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


//----------Перевести текст в окне Яндекс------------
function ujs_yandex_translate() {
         var txt = gContextMenuContentData.selectionInfo.fullText;
         var encTxt = encodeURIComponent(txt);
         var lng = 'ru';
         var winWait = function(lng){createWindow('', (lng == 'ru' ? '\u041F\u0435\u0440\u0435\u0432\u043E\u0434\u0438\u043C' : 'Translating')+'\u2026', 'Яндекс', '_gt', window.navigator.lastClick)};
   
     if (txt) { 
     winWait(lng);
        var xhr = new XMLHttpRequest();
        var encTxt = encodeURIComponent(txt);
        var url ="https://translate.yandex.net/api/v1.5/tr.json/translate?key="+keyuser+"&lang="+langFrom_yandex_text+langTo_yandex_text+"&text=" + encTxt;

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

        if (txt && location. hostname != 'http://api.microsofttranslator.com/')
         { var result="", status="Подождите идет перевод";
            createWindow(result, status,'<a href="'+url.replace(/&/g,'&amp;')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Bing</a>', '_gt', window.navigator.lastClick);
         }
        function gettransdata(){
           xmlhttp=GetXmlHttpObject();
           xmlhttp.onreadystatechange=stateChanged;
           xmlhttp.open(post ? 'POST' : 'GET', url, true);
           if(post)xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
           xmlhttp.send(post ? encTxt : null);
           xmlhttp1=GetXmlHttpObject();
           xmlhttp1.onreadystatechange=stateChanged;
           xmlhttp1.open('GET', uridetect, true);
           xmlhttp1.send(null);
        }
       function stateChanged(){
         if (xmlhttp.readyState==4 && xmlhttp1.readyState==4)
         {
           var tryain=xmlhttp.responseText;
           tryain=tryain.replace(/\"/g, '').replace(/\\u000d/g, " ").replace(/\\u000a/g, "<br />").replace(/\//g, '').replace(/\\n/g, "<br/>").replace(/\\r/g, "");
           var tryain1=xmlhttp1.responseText;
           tryain1=tryain1.replace(/\"/g, '');
           var result = tryain;
          var status =(tryain1 +' -\u203A '+ "ru").toUpperCase();
          createWindow(result, status, '<a href="'+urlt.replace(/&/g,'&amp;')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:#009;font:16px Times New Roman;">Bing</a>', '_gt', window.navigator.lastClick);
         }
       }  
      gettransdata();
   } 
};


//----------Заменить текст переводом Microsoft------------
function ujs_Microsoft_TexReplace (){
      var txt = gContextMenuContentData.selectionInfo.fullText;
    var encTxt = encodeURIComponent(txt);
    if (txt) { 
        var xhr = new XMLHttpRequest();
        var encTxt = encodeURIComponent(txt), post = encTxt.length > 1024;
        var urlt = 'http://www.bing.com/translator/?from='+langFrom_Microsoft_text+'&to='+langTo_Microsoft_text+'&SourceText=' + encTxt;       
        var uridetect = "http://api.microsofttranslator.com/V2/Ajax.svc/Detect?appId="+keyus+"&text="+ encTxt;
        var url="http://api.microsofttranslator.com/V2/Ajax.svc/Translate?appId="+keyus+"&from="+langFrom_Microsoft_text+"&to="+langTo_Microsoft_text+"&text="+ encTxt;
 
        function gettransdata(){
           xmlhttp=GetXmlHttpObject();
           xmlhttp.onreadystatechange=stateChanged;
           xmlhttp.open(post ? 'POST' : 'GET', url, true);
           if(post)xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
           xmlhttp.send(post ? encTxt : null);
           xmlhttp1=GetXmlHttpObject();
           xmlhttp1.onreadystatechange=stateChanged;
           xmlhttp1.open('GET', uridetect, true);
           xmlhttp1.send(null);
        }
       function stateChanged(){
         if (xmlhttp.readyState==4 && xmlhttp1.readyState==4)
         {
           var tryain=xmlhttp.responseText;
           tryain=tryain.replace(/\"/g, '').replace(/\\u000d/g, " ").replace(/\\u000a/g, "<br />").replace(/\//g, '').replace(/\\n/g, "<br/>").replace(/\\r/g, "");
           var tryain1=xmlhttp1.responseText;
           tryain1=tryain1.replace(/\"/g, '');
           var result = tryain;
             
      var msgName = _id + ":ReplaceSelectionRangeAt0";
      var url = "data:," + encodeURIComponent(
       `addMessageListener("${msgName}", function listener(msg) {
        removeMessageListener("${msgName}", listener);
        var win = {};
        Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
            .getFocusedElementForWindow(content, true, win);

        var sel = win.value.document.getSelection();
        if (sel.isCollapsed) return;
        var range = sel.getRangeAt(0);
        range.deleteContents();
        range.insertNode(range.createContextualFragment(msg.data));
    });`
);
function replace(tagString) {
    var mm = gBrowser.selectedBrowser.messageManager;
    mm.loadFrameScript(url, false);
    mm.sendAsyncMessage(msgName, tagString);
}
replace('<span>'+result+'</span>');

              
         }
       }  
      gettransdata();
   } 
};
//----------Заменить текст переводом Яндекс------------ 
function ujs_TexReplace_translate() {
      var txt = gContextMenuContentData.selectionInfo.fullText;
       var encTxt = encodeURIComponent(txt);
       if (txt) { 
         var xhr = new XMLHttpRequest();
         var encTxt = encodeURIComponent(txt);
         var url ="https://translate.yandex.net/api/v1.5/tr.json/translate?key="+keyuser+"&lang="+langFrom_yandex_text+langTo_yandex_text+"&text=" + encTxt;

        function gettransdata(){
           xmlhttp=GetXmlHttpObject();
           xmlhttp.onreadystatechange=stateChanged;
           xmlhttp.open('GET', url, true);
           xmlhttp.send(null);
        }
        function stateChanged(){
          if (xmlhttp.readyState==4)
           {
           var tryain=xmlhttp.responseText;
           tryain=tryain.replace(/\\n/g, "<br />");
           var data = JSON.parse( tryain );
           var result = data.text;
             
      var msgName = _id + ":ReplaceSelectionRangeAt0";
      var url = "data:," + encodeURIComponent(
       `addMessageListener("${msgName}", function listener(msg) {
        removeMessageListener("${msgName}", listener);
        var win = {};
        Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
            .getFocusedElementForWindow(content, true, win);

        var sel = win.value.document.getSelection();
        if (sel.isCollapsed) return;
        var range = sel.getRangeAt(0);
        range.deleteContents();
        range.insertNode(range.createContextualFragment(msg.data));
    });`
);
function replace(tagString) {
    var mm = gBrowser.selectedBrowser.messageManager;
    mm.loadFrameScript(url, false);
    mm.sendAsyncMessage(msgName, tagString);
}
replace('<span>'+result+'</span>');
              
              
           }
        }  
        gettransdata();
      } 
    
};  
//----------Заменить текст переводом Google------------
function ujs_google_TexReplace() {
    var lng = 'ru';
    var txt = gContextMenuContentData.selectionInfo.fullText;
    if (txt) {
        var xhr = new XMLHttpRequest();
        var url = 'https://translate.google.com/translate_a/single?client=t&sl=' + langFrom_google_text + '&tl=' + langTo_google_text + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt);
       
           function gettransdata(){
           xmlhttp=GetXmlHttpObject();
           xmlhttp.onreadystatechange=stateChanged;
           xmlhttp.open('POST', url, true);
           xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
           xmlhttp.send('q=' + encodeURIComponent(txt));
        }
        function stateChanged() {
            
                if (xmlhttp.readyState == 4 ) {
           var result = '';
           var data = JSON.parse(xmlhttp.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />"));
           for(var i = 0, n; n = data[0][i]; i++){
                        if(n[0])result += n[0].toString();
                    };
             
      var msgName = _id + ":ReplaceSelectionRangeAt0";
      var url = "data:," + encodeURIComponent(
       `addMessageListener("${msgName}", function listener(msg) {
        removeMessageListener("${msgName}", listener);
        var win = {};
        Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
            .getFocusedElementForWindow(content, true, win);

        var sel = win.value.document.getSelection();
        if (sel.isCollapsed) return;
        var range = sel.getRangeAt(0);
        range.deleteContents();
        range.insertNode(range.createContextualFragment(msg.data));
    });`
);
function replace(tagString) {
    var mm = gBrowser.selectedBrowser.messageManager;
    mm.loadFrameScript(url, false);
    mm.sendAsyncMessage(msgName, tagString);
}
replace('<span>'+result+'</span>');
                                     
                }
        }  
        gettransdata();
    } 
};



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

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






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

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

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

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

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

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



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

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

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

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

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

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

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

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

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


Добавлено 06-11-2019 20:00:30
firepox
Для 56 у меня есть только перевод выделенного текста в окне Яндекса, перевода всей страницы в Яндексе нет

Отредактировано Garalf (07-11-2019 07:04:18)

Отсутствует

 

№1384806-11-2019 20:14:30

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

Re: Custom Buttons

Garalf спасибо. работает

Отсутствует

 

№1384906-11-2019 21:57:07

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

Re: Custom Buttons

Stkvsky пишет

А можно вас попросить сделать горячую клавишу для этой кнопки? ПКМ+ЛКМ
Чтобы при зажатой ПКМ и клике ЛКМ кнопка срабатывала.

Полагаю, это не следует понимать буквально,
ведь "кнопка" добавляет пункт в контекстное меню.

Надеюсь устроит такая горячая клавиша мыши:
RMB-Down+LMB-Click — добавить адрес активной вкладки в закладки.

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

Выделить код

Код:

((popup, {lastChild} = popup, pref = "CB.bookmarkFolderGuidForSaving") =>
addDestructor(reason => reason == "delete" && Services.prefs.clearUserPref(pref))
|| ({
    index: 0, // 0 - первой, PlacesUtils.bookmarks.DEFAULT_INDEX - последней
    width: 500,
    height: 640,
    nodePosition: .35,
    init() {
        this.handleEvent = e => this[e.type](e);
        addEventListener("click", this, true);
        addEventListener("mousedown", this, true);
        addEventListener("contextmenu", this, true);
        addEventListener("popupshowing", this, false, popup || 1);
    },
    stop(e) {
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
    },
    async click(e) {
        if (!e.button && e.buttons == 2 && e.detail == 1)
            this.stop(e), this.bookmark({folderName: await this.getTitle()});
    },
    mousedown(e) {
        if (!e.button && e.buttons == 3 && e.detail == 1)
            this.stop(e), this.flag = true;
    },
    contextmenu(e) {
        if (this.flag) this.stop(e), this.flag = false;
    },
    popupshowing(e) {
        if (this.shouldHide) return;
        var menuitem = document.createElementNS(xulns, "menuitem");
        menuitem.id = "context-addBookmark";
        menuitem.className = "menuitem-iconic";
        menuitem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACD0lEQVR42oWTXUhTYRiAP89qziAYepG6TfAiyV1JsFojMJrVjf3dDOsmMoOwCwnSXLSJXgWDqAWBF7aGoFGGV0EUrL9FERoh1bQsqeiXfrzoB0N6es8528ncaC88fOfwnff53vN976eUUprafJk8lPIKS1XRkI8LRVayUVgmLBFsQklBwfhb8rAkRauSidQLDK49/zvqFKmqxBKcn4BzDzBGnU39BVZfTMOxQ6ZIXk6msdh7wUz+9IP/RraaLYYgfAUL73Fz8tJjs5rBh3B2HPrvQ/P+N8TvYJAVdBqCfRcxWH8aYm0dpCIRxvr6SG7bSWLrDsZ6e7ke7SESaiV61UoeFVoMwfYEBrGWNr6NjEAmY5JKmUxPw9QU35NJDq/ekBOcEqoNQSAOnh5Ih0IwPAwJsQ0MSP2DMDTEfDTKV7+f904nN12uBavr/SECZ6dZ1u11Aejqgu5u2ZAwv9vbmfP5mLXZeK0UrzSNGy53bnWXdYw6K47CEX8znwMB5oNBvtTX87G0lA+SmEueqazkYHWdLtgl1OVaybvwfPd41vLI42HGbicjiZPCy7IyntTUcKBqpZ58Iru61dZ6a64RwkJMmGi022dv1dbyrKKCp+XlpOW5yeH4KXPvhMbs3fgndJtDqDJ3VjX4NO3MqNs9J/xapWn3sv/dlJfcGr+rFbijunC5EBQ6hN2C27j6i+IP/uDMhPNYgHUAAAAASUVORK5CYII=");
        menuitem.setAttribute("oncommand", "linkedObject.oncommand(event);");
        menuitem.linkedObject = this;
        menuitem.oncontextmenu = e => this.pick(e.preventDefault());

        lastChild.after(menuitem);
        addDestructor(() => menuitem.remove());
        (this.popupshowing = e => e.target == popup
            && !(menuitem.hidden = this.shouldHide)
            && this.update(menuitem)
        )(e);
    },
    ons: ["isContentSelected", "onTextInput", "onImage", "onVideo", "onCanvas", "onAudio"],
    get shouldHide() {
        if (gContextMenu.onLink) return false;
        return this.ons.some(on => gContextMenu[on]);
    },
    oncommand(e) {
        this[e.ctrlKey || e.shiftKey ? "pick" : "bookmark"](e.target);
    },
    get guid() {
        return Services.prefs.getStringPref(pref, PlacesUtils.bookmarks.toolbarGuid);
    },
    async getTitle() {
        var info = await PlacesUtils.bookmarks.fetch(this.guid);
        return PlacesUtils.bookmarks.getLocalizedTitle(info);
    },
    async update(menuitem) {
        menuitem.label = "Добавить закладку в: " + (
            menuitem.folderName = (await this.getTitle()) || "[без заголовка]"
        );
    },
    pick() {
        var features = "chrome,all,resizable,centerscreen,modal";
        window.openDialog(this.url, "_blank", features, this.guid);
    },
    bookmark({folderName}) {
        if (window.gContextMenu && gContextMenu.onLink) {
            var url = gContextMenu.linkURL;
            var title = gContextMenu.linkText();
        } else {
            var url = gBrowser.currentURI.spec;
            var title = gBrowser.contentTitle || gBrowser.selectedTab.label;
        }
        var info = {url, title, parentGuid: this.guid, index: this.index};
        PlacesUtils.bookmarks.insert(info).then(
            () => this.notify(title, "Добавил закладку в папку: " + folderName),
            err => this.notify("Ошибка", err)
        );
    },
    get alert() {
        var as = this.as = Cc["@mozilla.org/alerts-service;1"]
            .getService(Ci.nsIAlertsService);
        this.alertName = _id + "-bookmark-alert";
        delete this.alert;
        return this.alert = as.showAlertNotification
            .bind(as, "chrome://global/skin/icons/warning.svg");
    },
    notify(title, msg) {
        this.alert(title, msg, false, null, null, this.alertName);
        setTimeout(() => this.as.closeAlert(this.alertName), 1800);
    },
    get url() {
        var xul =
            `<?xml version="1.0"?>
            <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
            <?xml-stylesheet href="chrome://browser/content/places/places.css"?>
            <?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
            <?xml-stylesheet href="chrome://browser/skin/places/tree-icons.css"?>
            <dialog xmlns="${xulns}"
                id="bookmark-folder-saver-dialog"
                windowtype="bookmark-folder-saver:dialog"
                title="Выберите папку"
                buttons="accept,cancel"
                onload="init();"
                width="${this.width}"
                height="${this.height}">

                <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
                <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
                <script type="application/javascript"><![CDATA[
                    ChromeUtils.defineModuleGetter(window, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm");
                    ChromeUtils.defineModuleGetter(window, "PlacesUIUtils", "resource:///modules/PlacesUIUtils.jsm");
                    ChromeUtils.defineModuleGetter(window, "PlacesTransactions", "resource://gre/modules/PlacesTransactions.jsm");
                    ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
                    XPCOMUtils.defineLazyScriptGetter(window, "PlacesTreeView", "chrome://browser/content/places/treeView.js");
                    XPCOMUtils.defineLazyScriptGetter(
                        window,
                        ["PlacesInsertionPoint", "PlacesController", "PlacesControllerDragHelper"],\n\
                        "chrome://browser/content/places/controller.js"\n\
                    );
                ]]></script>
                <script type="application/javascript" src="chrome://browser/content/places/places-tree.js"/>

                <tree id="tree" type="places" is="places-tree"
                    place="place:type=${
                        Ci.nsINavHistoryQueryOptions.RESULTS_AS_ROOTS_QUERY
                    }&amp;excludeItems=1&amp;excludeQueries=1"
                    hidecolumnpicker="true" seltype="single" flex="1">
                    <treecols>
                        <treecol id="title" flex="1" primary="true" hideheader="true" />
                    </treecols>
                    <treechildren />
                </tree>
                <script type="application/javascript"><![CDATA[
                    var tree = document.getElementById("tree");
                    function init() {
                        tree.selectItems([window.arguments[0]]);
                        var ind = tree.view.selection.currentIndex;
                        ind != -1 && setTimeout(() => {
                            if ("nsITreeBoxObject" in Ci) {
                                var tbo = tree.treeBoxObject;
                                var visibleRows = tbo.height/tbo.rowHeight;
                            } else {
                                var tbo = tree;
                                var visibleRows = tbo.getPageLength();
                            }
                            var cur = tbo.view.selection.currentIndex;
                            var first = tbo.getFirstVisibleRow();
                            var newFirst = cur - ${this.nodePosition}*visibleRows + 1;
                            tbo.scrollByLines(Math.round(newFirst - first));
                        }, 0);
                        var onKeydown = e => e.ctrlKey && e.key == "Enter" && !e.shiftKey
                            && document.documentElement.acceptDialog(e.stopPropagation());
                        addEventListener("keydown", onKeydown, true);
                        addEventListener("dialogaccept", dialogCallback);
                        window.onunload = () => {
                            removeEventListener("keydown", onKeydown, true);
                            removeEventListener("dialogaccept", dialogCallback);
                        }
                    }
                    function dialogCallback() {
                        var ind = tree.view.selection.currentIndex;
                        if (ind == -1) return;
                        var item = tree.view.nodeForTreeIndex(ind);
                        item && Services.prefs.setStringPref(
                            "${pref}", PlacesUtils.getConcreteItemGuid(item)
                        );
                    }
                ]]></script>
            </dialog>`;
        var url, type = "application/vnd.mozilla.xul+xml";
        if (parseInt(Services.appinfo.platformVersion) >= 69 && Services.appinfo.browserTabsRemoteAutostart) {
            url = `chrome://custombuttons/content/cbfolderpicker${Date.now()}.xul`;
            var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
            this.helper = ams.registerChrome(
                Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)),
                [["override", url, `data:${type},${encodeURIComponent(xul)}`]]
            );
            addDestructor(this.helper.destruct);
        } else {
            url = URL.createObjectURL(new Blob([xul], {type}));
            addDestructor(() => URL.revokeObjectURL(url));
        }
        delete this.url; return this.url = url;
    }
}).init())(document.getElementById("contentAreaContextMenu"));

Отсутствует

 

№1385006-11-2019 22:08:38

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1700
UA: Firefox 42.0

Re: Custom Buttons

Dumby
Да, вы правильно поняли, срабатывание имел ввиду добавление закладки.
Поставил, работает, только одно но - не работает на ссылках
Если обычным способом нажать ПКМ на ссылке и выбрать добавить в закладки, добавляется именно ссылка, а не активаная вкладка
Не могли бы вы пожалуйста сделать так же и для RMB-Down+LMB-Click?

Отредактировано Stkvsky (07-11-2019 02:03:05)

Отсутствует

 

Board footer

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