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

Будьте в курсе последних изменений в мире Mozilla, следя за нашим микроблогом в Twitter.

№35128-06-2022 23:57:33

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

Re: UCF - ваши кнопки, скрипты…

antialt пишет

Подскажите, как вернуть к жизни add_toolbar_buttons.2021.9.5.xpi на 102 (Final или ESR), очень уж удобный плагин :)!

Вы же процитировали решение, просто обновите код для отключения... на тот что под спойлером!


Win7

Отсутствует

 

№35229-06-2022 00:10:54

antialt
Участник
 
Группа: Members
Зарегистрирован: 18-01-2017
Сообщений: 9
UA: Firefox 101.0

Re: UCF - ваши кнопки, скрипты…

Извиняюсь, вставлял код на профиль после запуска со старой "антиподпиской", не сработал. Сейчас вытащил из бэкапа профиль от 101 версии, накатил обнову и новый код. Всё отлично, спасибо :)!

Отсутствует

 

№35303-07-2022 09:14:02

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 1644
UA: Firefox 91.0

Re: UCF - ваши кнопки, скрипты…

Dumby
Можете посмотреть расширение Open Link with New Tab? На 91.11 и 102 начался периодический отвал, проявляется в том что иногда ссылки по Ctrl+ЛКМ начинают открываться в новом окне, перезапуск расширения лечит это.

Отредактировано _zt (03-07-2022 09:14:24)

Отсутствует

 

№35403-07-2022 16:54:37

Inko7
Участник
 
Группа: Members
Зарегистрирован: 09-11-2009
Сообщений: 1008
UA: Firefox 102.0

Re: UCF - ваши кнопки, скрипты…

Dumby
с последним обновлением ff отваливается такой скрипт, не везде срабатывает: в строке адреса, в строке поиска на стартовом экране - не работает совсем, а на большинстве форум в окнах ввода срабатывает. Странно...

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

Выделить код

Код:

// MiddleMouse.Paste с заменой выделенного текста (порт с СВ)

try {((id, code, gmon) => {

    var d = "data:,", ref = "globalThis." + id, dref = d + ref;
    var psi = `${dref} = ${encodeURIComponent(code)};`;
    var psd = `${d}delete ${ref};`;

    var e10s = Services.appinfo.browserTabsRemoteAutostart;
    if (e10s) var
        fsi = `${dref}.listen(this, "add");`,
        fsd = `${dref}.listen(this);`;

    var g = Cu.getGlobalForObject(Cu), pref = "middlemouse.paste";
    var obs = {
        pref: Services.prefs.getBoolPref.bind(null, pref),
        startup() {
            Services.prefs.addObserver(pref, this);
            Services.obs.addObserver(this, "quit-application-granted", false);
            this.pref() && this.init();
            this.gmon();
        },
        async gmon() {
            Cu.importGlobalProperties(["fetch"]);
            var url = "chrome://custombuttons/content/editExternal.js";
            try {var src = await (await fetch(url)).text();} catch(ex) {return;}
            src = src.replace(/function gmon_edit_mouseclick[^}]+?}/, gmon);
            var arr = [["override", url, "data:," + encodeURIComponent(src)]];
            url = Services.io.getProtocolHandler("resource").getSubstitution("gre");
            this.gmonHelper = Cc["@mozilla.org/addons/addon-manager-startup;1"]
                .getService(Ci.amIAddonManagerStartup).registerChrome(url, arr);
        },
        shutdown() {
            this.pref() && this.destroy();
            e10s && Services.ppmm.removeDelayedProcessScript(psi),
            Services.ppmm.loadProcessScript(psd, false);
            Services.prefs.removeObserver(pref, this);
            Services.obs.removeObserver(this, "quit-application-granted");
            this.gmonHelper && this.gmonHelper.destruct();
        },
        init() {
            e10s && Services.mm.loadFrameScript(fsi, true);
            Services.obs.addObserver(this, "widget-first-paint", false);
            this.wins("add");
        },
        destroy() {
            if (e10s)
                Services.mm.removeDelayedFrameScript(fsi),
                Services.mm.loadFrameScript(fsd, false);
            Services.obs.removeObserver(this, "widget-first-paint");
            this.wins();
        },
        observe(subj, topic) {
            var char = topic[0];
            if (char == "w") return this.call(subj, "add");
            if (char == "q") return this.shutdown();
            this[this.pref() ? "init" : "destroy"]();
        },
        wins(arg) {
            for(var win of Services.wm.getEnumerator(null)) this.call(win, arg);
        },
        listen() {}
    };
    Services.ppmm.loadProcessScript(psi, e10s);
    g[id].call = g[id].listen;
    Object.assign(g[id], obs).startup();

})("ucf_custom_script_js_MiddleMousePaste", `{

    listen(trg, prfx = "remove") {
        var meth = prfx + "EventListener";
        trg[meth]("auxclick", this, true);
        trg[meth]("unload", this);
    },
    handleEvent(e) {this[e.type](e);},
    unload(e) {this.listen(e.target);},
    sn: Ci.nsISelectionController.SELECTION_NORMAL,
    inRect: (r, x, y) => y > r.top && y < r.bottom && x < r.right && x > r.left,
    auxclick(e) {
        if (e.button != 1) return;
        var trg = (e.originalTarget || e.target).closest(
            "input:not([disabled]),textarea:not([disabled])"
        );
        if (!trg) return;
        var ed = trg.editor;
        if (!ed || ed.selection.isCollapsed || !ed.canPaste(this.sn)) return;

        var x = e.clientX, y = e.clientY, rng = ed.selection.getRangeAt(0);
        if (!this.inRect(rng.getBoundingClientRect(), x, y)) return;

        var list = rng.getClientRects();
        if (list.length == 1 || Array.from(list).some(
            rect => this.inRect(rect, x, y)
        ))
            ed.paste(this.sn, e.preventDefault());
    }
}`, `\
function gmon_edit_mouseclick(e) {
    var mmp = Cc["@mozilla.org/preferences-service;1"]
        .getService(Ci.nsIPrefBranch).getBoolPref.bind(null, "middlemouse.paste");
    (gmon_edit_mouseclick = e => e.button != 1 || mmp() || edittarget(e.target))(e);
}`);
} catch(ex) {Cu.reportError(ex);}


((bu, bm, {star} = bu) => addEventListener("mouseenter", {
    async handleEvent() {
        if (!this.starred) return;
        star.tooltipText = "\u3164";
        var result = [];
        await this.fetch();
        for(var guid of this.guids) {
            var arr = [];
            while(true) {
                if (!this.hover) return;
                var res = await bm.fetch(guid);
                if ((guid = res.parentGuid) == bm.rootGuid) {
                    arr.unshift(bm.getLocalizedTitle(res));
                    break;
                }
                arr.unshift(res.title || "[Безымянная папка]");
            }
            result.push(arr.join("\\"));
        }
        this.hover && this.setTooltip(result);
    },
    get fetch() {
        addDestructor(() => this.starred && document.l10n.translateElements([star]));
        var set = this.guids = new Set();
        var args = [b => set.add(b.parentGuid), {concurrent: true}];
        delete this.fetch; return this.fetch = () => set.clear()
            || bm.fetch({url: gBrowser.currentURI.spec}, ...args);
    },
    setTooltip(arr) {
        var m = arr.length > 1;
        var text = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${arr.join("\n")}`;
        document.tooltipNode == star ? this.tt.label = text : star.tooltipText = text;
    },
    get tt() {
        var list = InspectorUtils.getChildrenForNode(document.documentElement, true);
        delete this.tt; return this.tt = list.item(list.length - 1);
    },
    get starred() {return bu._itemGuids.size;},
    get hover() {return star.matches(":hover");}
}, false, star || 1))(BookmarkingUI, PlacesUtils.bookmarks);


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


и вопрос по тому же Switch Keyboard Layout button: переключаешь раскладку для слов начинающихся на букву Б, Ю, Ж - код срабатывает некорректно

Отредактировано Inko7 (03-07-2022 16:59:15)

Отсутствует

 

№35503-07-2022 19:05:43

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

Re: UCF - ваши кнопки, скрипты…

Dumby
Сделайте пожалуйста, что бы скрипт: Очистить панель адреса или поиска прокруткой колёсиком мыши на панели работал во всех панелях поиска, включая контент!


Win7

Отсутствует

 

№35603-07-2022 19:49:53

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

Re: UCF - ваши кнопки, скрипты…

_zt пишет

расширение

Это не расширение, а WebExtensions.

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

иногда

И где же мне взять это «иногда»? Не́где.

Можете посмотреть

Смотреть там особо неначто.
Регистрируется контентский скрипт, который,


запрашивает пользовательскую аддонскую настройку,
и если она не равна нулю (типа, установлена, и как 1 или 2)


тогда идёт перебор всех элементов <a>, которые присутствуют в DOM-дереве документа
(на момент исполнения скрипта, добавленные [как-то] позже идут лесом; и те, которые в Shadow DOM тоже, наверно, в пролёте),
и, если элемент (собственно ссылка) имеет href, тогда ему уставливается атрибут "target" со значением "_blank".
(ну, там в зависимости от 1 или 2, как-бы same-site или нет, неважно).


Вот и всё. Атрибут либо уставливается, либо нет.
Если атрибут должен устанавливаться, но не устанавливается,
тогда не знаю почему. Может storage.sync глючит (?).
В таком случае можно попробовать заменить все browser.storage.sync на browser.storage.local
и заново посетить настройки аддона. Предположение, разумеется, ни на чём не основано.


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

Inko7 пишет

такой скрипт

Это ты мне что-то совсем левое древнее впариваешь.
Ещё и какой-то star-тултипский код в конце прицеплен, непонятно зачем.


Последний вариант вроде как здесь.


Но, железная поступь проекта «JSM-геноцид»,
рано или поздно, сметёт не только это, а вообще всё.
Если нет возможности вникнуть в это сейчас (пока никто не торопит)
то лучше отказаться от всего подобного сразу, нечего не дожидаясь.

для слов начинающихся на букву Б, Ю, Ж - код срабатывает некорректно

Да видел я пост про «Б». Ин-валидно.
Нет никаких проблем с «Б» (как и с «Ю»).


С «Ж», да, есть проблемы.
Так же, как есть проблемы и с «б», «ю», «ж», «Э».


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

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

Выделить код

Код:

/*
            if(c in this.convTableForward)
                return true;
            if(c in this.convTableBackward)
                return false;
*/
            var primary = c in this.convTableForward;
            if(primary ^ c in this.convTableBackward)
                return primary;

kokoss пишет

включая контент

Увы, делам контентским, вебским, я весьма посторонен.
Могу только извиниться за это.

Отсутствует

 

№35703-07-2022 21:06:23

Inko7
Участник
 
Группа: Members
Зарегистрирован: 09-11-2009
Сообщений: 1008
UA: Firefox 102.0

Re: UCF - ваши кнопки, скрипты…

Dumby пишет

Последний вариант вроде как здесь.

Как-то пропустил его, но он все равно не работает в строке адреса и в строке поиска на стартовой странице FF. Может оно и не особо критично...

Dumby пишет

Возможно, чуть лучше будет с такой правкой

изменений пока не заметил

Отсутствует

 

№35803-07-2022 21:18:03

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

Re: UCF - ваши кнопки, скрипты…

Inko7
Ну, значит у кого-то из нас (двоих) руки кривые.
Тут бы хорошо услышать мнение третьей стороны,
но вряд-ли таковое нарисуется, сложновато это всё, наверно.

Отсутствует

 

№35903-07-2022 21:28:11

Inko7
Участник
 
Группа: Members
Зарегистрирован: 09-11-2009
Сообщений: 1008
UA: Firefox 102.0

Re: UCF - ваши кнопки, скрипты…

Dumby пишет

Ещё и какой-то star-тултипский код в конце прицеплен, непонятно зачем.

Точно! Думаю, где же он спрятался)))
У меня есть два варианта кода, кто из них новее/лучше не знаю. Но у обоих есть глюк - открываем закладку, с нее переходим по внутр. ссылкам куда-либо, звездочка соответственно теперь пустая в адресной строке, а тултип все равно показывается с путём к изначально открытой закладке. Такое очень часто.

скрытый текст
этот наверное новее

Выделить код

Код:

// Показать адрес существующей закладки при наведении на звездочку

try {((bu, bm, {star} = bu) => {
    var listener = {
        async handleEvent() {
            if (!bu._itemGuids.size) return;
            star.tooltipText = "\u3164";
            var result = [];
            await this.fetch();
            for(var guid of this.guids) {
                var arr = [];
                while(true) {
                    if (!this.hover) return;
                    var res = await bm.fetch(guid);
                    if ((guid = res.parentGuid) == bm.rootGuid) {
                        arr.unshift(bm.getLocalizedTitle(res));
                        break;
                    }
                    arr.unshift(res.title || "[Безымянная папка]");
                }
                result.push(arr.join("\\"));
            }
            this.hover && this.setTooltip(result);
        },
        get fetch() {
            var set = this.guids = new Set();
            var args = [b => set.add(b.parentGuid), {concurrent: true}];
            delete this.fetch; return this.fetch = () => set.clear()
                || bm.fetch({url: gBrowser.currentURI.spec}, ...args);
        },
        setTooltip(arr) {
            var m = arr.length > 1;
            var text = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${arr.join("\n")}`;
            document.tooltipNode == star ? this.tt.label = text : star.tooltipText = text;
        },
        get tt() {
            var list = InspectorUtils.getChildrenForNode(document.documentElement, true);
            delete this.tt; return this.tt = list.item(list.length - 1);
        },
        get hover() {return star.matches(":hover");}
    };
    star.addEventListener("mouseenter", listener);
    addEventListener("unload",
        () => star.removeEventListener("mouseenter", listener)
    , {once: true});
})(BookmarkingUI, PlacesUtils.bookmarks);} catch(ex) {Cu.reportError(ex);}


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

Выделить код

Код:

// Показать адрес существующей закладки при наведении на звездочку

((bu, bm, {star} = bu) => addEventListener("mouseenter", {
    async handleEvent() {
        if (!this.starred) return;
        star.tooltipText = "\u3164";
        var result = [];
        await this.fetch();
        for(var guid of this.guids) {
            var arr = [];
            while(true) {
                if (!this.hover) return;
                var res = await bm.fetch(guid);
                if ((guid = res.parentGuid) == bm.rootGuid) {
                    arr.unshift(bm.getLocalizedTitle(res));
                    break;
                }
                arr.unshift(res.title || "[Безымянная папка]");
            }
            result.push(arr.join("\\"));
        }
        this.hover && this.setTooltip(result);
    },
    get fetch() {
        addDestructor(() => this.starred && document.l10n.translateElements([star]));
        var set = this.guids = new Set();
        var args = [b => set.add(b.parentGuid), {concurrent: true}];
        delete this.fetch; return this.fetch = () => set.clear()
            || bm.fetch({url: gBrowser.currentURI.spec}, ...args);
    },
    setTooltip(arr) {
        var m = arr.length > 1;
        var text = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${arr.join("\n")}`;
        document.tooltipNode == star ? this.tt.label = text : star.tooltipText = text;
    },
    get tt() {
        var list = InspectorUtils.getChildrenForNode(document.documentElement, true);
        delete this.tt; return this.tt = list.item(list.length - 1);
    },
    get starred() {return bu._itemGuids.size;},
    get hover() {return star.matches(":hover");}
}, false, star || 1))(BookmarkingUI, PlacesUtils.bookmarks);

Добавлено 03-07-2022 21:46:08

Dumby пишет

Ну, значит у кого-то из нас (двоих) руки кривые.

тут спору нет :)
о каком конкретно скрипте речь?

Отредактировано Inko7 (03-07-2022 21:46:08)

Отсутствует

 

№36003-07-2022 22:38:43

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

Re: UCF - ваши кнопки, скрипты…

Inko7 пишет

а тултип все равно показывается с путём к изначально открытой закладке

:/

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

Выделить код

Код:

/*
            if (!bu._itemGuids.size) return;
*/
            if (!bu._itemGuids.size) return star.removeAttribute("tooltiptext");

о каком конкретно скрипте речь?

Об обоих двух.

Отсутствует

 

№36104-07-2022 00:02:31

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3231
UA: Firefox 102.0

Re: UCF - ваши кнопки, скрипты…

Dumby пишет

Inko7
Ну, значит у кого-то из нас (двоих) руки кривые.
Тут бы хорошо услышать мнение третьей стороны,
но вряд-ли таковое нарисуется, сложновато это всё, наверно.

У меня везде всё вставляет, без проблем. :)

Отсутствует

 

№36204-07-2022 00:16:34

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

Re: UCF - ваши кнопки, скрипты…

voqabuhe пишет

У меня везде всё вставляет, без проблем.

Премного благодарен, спасибо за взгляд со стороны.

Отредактировано Dumby (04-07-2022 00:17:36)

Отсутствует

 

№36304-07-2022 09:46:53

Inko7
Участник
 
Группа: Members
Зарегистрирован: 09-11-2009
Сообщений: 1008
UA: Firefox 102.0

Re: UCF - ваши кнопки, скрипты…

Dumby
Понял в чем было дело. По инструкции для MMPaste.jsm нужно было:

можно добавив в конфигурационный CustomStylesScripts.jsm
в массив UcfStylesScripts.scriptsbackground объект вида
{ func: 'ChromeUtils.import("chrome://user_chrome_files/content/custom_scripts/MMPaste.jsm");' },

а у меня скрипты загружались уже через сам файл custom_script.js

в нем прописан вот такой код:

Выделить код

Код:

(() => {
    var loadscript = name => {
        try {
            Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${name}`, globalThis, "UTF-8");
        } catch(e) {}
    };

    loadscript("./js/kbd_layout.js");
    loadscript("./js/MiddleMouse_Paste.js");

})();


но так же они тоже подгружались, просто как-то не совсем корректно?

Отсутствует

 

№36404-07-2022 11:01:46

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

Re: UCF - ваши кнопки, скрипты…

Inko7 пишет

"./js/kbd_layout.js"

Это что ещё за дот-слэш в начале?
В данном случае — совершенно неуместно.
Работает, видимо, только потому, что где-то стоит защита от подобных выкрутасов.

но так же они тоже подгружались, просто как-то не совсем корректно?

kbd_layout.js — это просто скрипт.
Можно грузить так, как у тебя, можно инлайн,
можно любым другим аналогичным способом, так что здесь всё верно.


А Middle Mouse Paste — это модуль (jsm'ка, пока ещё).
Модули не грузят как скрипт. Их импортируют.
Так что здесь неверно, следует импортировать так, как сказано.

Отсутствует

 

№36504-07-2022 11:43:27

Inko7
Участник
 
Группа: Members
Зарегистрирован: 09-11-2009
Сообщений: 1008
UA: Firefox 102.0

Re: UCF - ваши кнопки, скрипты…

Dumby
Тепрь всё понятно и всё заработало как надо. Star-tooltip тоже отлично работает.
Спасибо.

Отсутствует

 

№36605-07-2022 14:17:27

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 1644
UA: Firefox 91.0

Re: UCF - ваши кнопки, скрипты…

Dumby

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

Да, есть маленько.

В таком случае можно попробовать заменить все browser.storage.sync на browser.storage.local и заново посетить настройки аддона.

Уже не хочу, так как найденный скрипт работает лучше, например на github внешние ссылки корректно открывает в новой вкладке, ну и т.п.
   
Только вот, можете этот скрипт переделать под ucf, с настройками в самом файле.

Отсутствует

 

№36706-07-2022 04:33:54

Dobrov
Участник
 
Группа: Members
Зарегистрирован: 04-10-2011
Сообщений: 475
UA: Firefox 102.0

Re: UCF - ваши кнопки, скрипты…

Dumby пишет

Middle Mouse Paste — это модуль (jsm'ка, пока ещё).

Раз jsm-ки скоро отвалится, то весь UCF и CustomStylesScripts.jsm и CustomStylesScriptsChild.jsm тоже перестанут работать?

если поддержку jsm уберут, просьба переделать в JS модуль сохранения картинок ClickPicSave.jsm

Выделить код

Код:

var EXPORTED_SYMBOLS = ["MouseImgSaverChild", "MouseImgSaverParent"]; // by Dumby сохранить картинку колёсиком или перетащив вправо; DBL поиск похожих

var u = {get it() { // https://forum.mozilla-russia.org/viewtopic.php?pid=793837#p793837
	delete this.it;
	return this.it = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools);
}};
for(let name of ["E10SUtils", "PrivateBrowsingUtils"])
	ChromeUtils.defineModuleGetter(u, name, `resource://gre/modules/${name}.jsm`);

class MouseImgSaverChild extends JSWindowActorChild {
	handleEvent(e) { // клики мышью
		if (e.button > 1) return; // только ЛКМ, СКМ
		var trg = e.explicitOriginalTarget; // dragstart
		trg.nodeType == Node.ELEMENT_NODE
			&& trg instanceof Ci.nsIImageLoadingContent
			&& this[e.type](trg, e);
	}
	handleDragEvent(e) {
		this[e.type](e);
	}
	dragstart(trg, e) {
		this.trg = trg;
		this.x = e.screenX; this.y = e.screenY;
		this.drag("add");
		this.handleEvent = this.handleDragEvent;
		this.checkTextLinkyTool(trg.ownerDocument);
	}
	events = ["dragover", "drop", "dragend"];
	drag(meth = (delete this.handleEvent, delete this.trg, "remove")) {
		meth += "EventListener";
		var win = this.contentWindow;
		for(var type of this.events) win[meth](type, this, true);
	}
	drop() {
		this.drag();
	}
	dragover(e) {
		var {x, y} = this,
			cx = e.screenX, cy = e.screenY,
			dx = cx - x,
			ax = Math.abs(dx), ay = Math.abs(cy - y);

		if (ax < 10 && ay < 10) return;
		if (dx < 0 || ax < ay) return this.drag();
		this.x = cx; this.y = cy;
	}
	dragend(e) { // перетаскивание рисунка
		var dt = e.dataTransfer, {trg} = this;
		this.drag();
		dt.mozUserCancelled || this.send(trg, e.screenX); // сохранить
		// dt.mozUserCancelled || this.sendAsyncMessage("dragend", (trg.currentRequestFinalURI || uri).spec);
	}
	auxclick(trg) { // клик СКМ
		trg.matches(":any-link :scope") || this.send(trg);
	}
	dblclick(trg) { // ЛКМ
		trg.matches(":any-link :scope")
			|| this.sendAsyncMessage("dblclick", (trg.currentRequestFinalURI || uri).spec);
	}
	send(trg, sx) {
		var uri = trg.currentURI;
		if (!uri) return;

		var doc = trg.ownerDocument;
		var cookieJarSettings = u.E10SUtils
			.serializeCookieJarSettings(doc.cookieJarSettings);

		var referrerInfo = Cc["@mozilla.org/referrer-info;1"]
			.createInstance(Ci.nsIReferrerInfo);
		referrerInfo.initWithElement(trg);
		referrerInfo = u.E10SUtils.serializeReferrerInfo(referrerInfo);

		var contentType = null, contentDisposition = null;
		try {
			var props = u.it.getImgCacheForDocument(doc).findEntryProperties(uri, doc);
			var cs = Ci.nsISupportsCString;
			try {contentType = props.get("type", cs).data;} catch {}
			try {contentDisposition = props.get("content-disposition", cs).data;} catch {}
		} catch {}

		this.sendAsyncMessage("", {
			title: trg.closest("[title]")?.title,
			url: (trg.currentRequestFinalURI || uri).spec,
			contentType, referrerInfo, cookieJarSettings, contentDisposition, sx,
			isPrivate: u.PrivateBrowsingUtils.isContentWindowPrivate(trg.ownerGlobal)
		});
	}
	checkTextLinkyTool(doc) {
		if (doc.title || !doc.documentURI.startsWith("moz-extension:")) return;
		var lab = doc.querySelector("body > label#lblFrom:first-child")?.textContent;
		if (lab) doc.title = lab.slice(0, lab.lastIndexOf("("));
	}
}
if (!ChromeUtils.domProcessChild.childID) {
	ChromeUtils.registerWindowActor("MouseImgSaver", {
		allFrames: true,
		parent: {moduleURI: __URI__},
		messageManagerGroups: ["browsers"],
		child: {moduleURI: __URI__, events: {auxclick: {capture: true}, dblclick: {capture: true}, dragstart: {capture: true}}}
	});
	var wref, titles = Object.create(null);
	var data = Object.assign(Object.create(null), {
		"browser.download.dir": {type: "String", get set() {

			var win = wref.get(), {prefs, dirsvc} = win.Services
			var {DownloadPaths, FileUtils} = win;
			var map = val => DownloadPaths.sanitize(val);

			win.Downloads.getList(win.Downloads.ALL).then(list => list.addView({
				onDownloadChanged(download) {
					if (!download.stopped) return;
					var {url} = download.source, title = titles[url];
					if (!title) return;
					delete titles[url];
					if (!download.succeeded) return;

					var file = FileUtils.File(download.target.path), {leafName} = file;
					var ext = leafName.slice(leafName.lastIndexOf("."));
					var newName = map(title) + ext, {parent} = file;
					var newFile = parent.clone();
					newFile.append(newName);
					try {
						newFile.createUnique(file.NORMAL_FILE_TYPE, file.permissions);
						file.renameTo(parent, newFile.leafName);
						download.target.path = newFile.path;
						download.refresh();
					} catch {}
				}
			}));
			Object.defineProperty(this, "set", {get() {
				try {var dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {var dir = dirsvc.get("DfltDwnld", Ci.nsIFile);}
				var arr = prefs.getStringPref("ucf.savedirs", "_Web||_Images|0").split('|').slice(2, 4);
				// подпапки в [Загрузках]: нет | папка графики | имя вкладки | домен
				arr[1] = (arr[1]) ? wref.get().gBrowser.selectedTab.label.slice(0, 64).replace(/ \| — Mozilla Firefox|[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim() : ""; // имя вкладки
				arr.map(map).forEach(dir.append); dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777);
				return dir.path;
			}});
			return this.set;
		}},
		"browser.download.folderList": {type: "Int", set: 2},
		"browser.download.useDownloadDir": {type: "Bool", set: true}
	});
	var MouseImgSaverParent = class extends JSWindowActorParent {
		receiveMessage(msg) {
			var win = msg.target.browsingContext.topChromeWindow, {name} = msg;
			if (name) return this[name](win, msg.data);

			var {url, contentType, contentDisposition, sx, title,
				isPrivate, referrerInfo, cookieJarSettings} = msg.data;
			if (sx && sx > win.mozInnerScreenX + win.innerWidth) return;

			if (title) titles[url] = title;

			wref = Cu.getWeakReference(win);
			var p = win.Services.prefs;

			for(var pref in data) {
				var obj = data[pref], meth = `et${obj.type}Pref`;
				obj.val = p.prefHasUserValue(pref) ? p["g" + meth](pref) : null;
				p["s" + meth](pref, obj.set);
			}
			try {win.internalSave(
				url,
				null, // document
				null, // file name
				contentDisposition,
				contentType,
				false, // do not bypass the cache
				null, // filepicker title key
				null, // chosen data
				u.E10SUtils.deserializeReferrerInfo(referrerInfo),
				u.E10SUtils.deserializeCookieJarSettings(cookieJarSettings),
				win.document, // initiating doc
				true, // skip prompt for where to save
				null, // cache key
				isPrivate,
				win.document.nodePrincipal
			);}
			finally {
				for(var pref in data) data[pref].val === null
					? p.clearUserPref(pref)
					: p[`set${data[pref].type}Pref`](pref, data[pref].val);
			}
		}
		dblclick(win, imgURL) {
			var gb = win.gBrowser, index = gb.selectedTab._tPos + 1;
			gb.selectedTab = gb.addTrustedTab('https://yandex.ru/images/search?rpt=imageview&url=' + imgURL, {index});
		}
	}
}

Отсутствует

 

№36806-07-2022 14:38:26

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

Re: UCF - ваши кнопки, скрипты…

Dobrov пишет

Раз jsm-ки скоро отвалится, то весь UCF и CustomStylesScripts.jsm и CustomStylesScriptsChild.jsm тоже перестанут работать?

ESM модули вместо них, несложная конвертация модулей jsm --> mjs, у меня уже работает на FF 103

Отредактировано Vitaliy V. (06-07-2022 14:46:22)

Отсутствует

 

№36906-07-2022 19:22:45

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

Re: UCF - ваши кнопки, скрипты…

_zt пишет

с настройками в самом файле

Что-то мне в голову не влезает то, что там навёрнуто,
не смог понять как это должно работать, сколько ни пытался.


Могу попробовать просто процитировать, без осознания,
но вряд ли из этого что-то выйдет.

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

Выделить код

Код:

var cfg = {
	rootzone: false,
	parent: true,
	neighbor: true,
	host: true,
	child: true,

	background: false,
	insert: true,
	setParent: true
};
var name = "ExternalLinkNewtaber";
if (ChromeUtils.domProcessChild.childID) {
	var empty = new RegExp("^$");

	var click = function(e) {
		e.preventDefault();
		e.stopImmediatePropagation();
		this.ownerGlobal.windowGlobalChild
			.getActor(name).sendAsyncMessage("", this.href);
	}
	var EXPORTED_SYMBOLS = [name + "Child"];
	var ExternalLinkNewtaberChild = class extends JSWindowActorChild {
		actorCreated() {
			this.pp = this.ph = empty;
			var host = this.contentWindow.location.hostname;

			// quot ===========================================================================

			let parent = host.replace(/^[^.]*\./, '').replace(/\./g, '\\\.');
			host = host.replace(/\./g, '\\\.');

			if (cfg.parent){this.pp = new RegExp(`^${parent}$`);}    // abc.x               => ^abc\.x$
			if (cfg.neighbor){
				const flat = host.replace(/\..*/, '');
				if (cfg.parent){
					this.pp = new RegExp(`[^(${flat}\.)]?${parent}$`);     // abc.x + *.abc.x     => [^(w\.)]?abc\.x$
				}
				else {this.pp = new RegExp(`[^(${flat})]?\.${parent}$`);}  // *.abc.x             => [^(w)]?\.abc\.x$
			}
			if (!cfg.rootzone && parent.search(/\..+\./) == -1){this.pp = empty;}
			if (cfg.host){this.ph = new RegExp(`^${host}$`);}    // w.abc.x             => ^w\.abc\.x$
			if (cfg.child){
				if (cfg.host){
					this.ph = new RegExp(`(.+\.)?${host}$`);                  // w.abc.x + *.w.abc.x => (.+\.)?w\.abc\.x$
				}
				else {this.ph = new RegExp(`.+\.${host}$`);}                  // *.w.abc.x           => .+\.w\.abc\.x$
			}

			// =========================================================================== quot
		}
		handleEvent(e) {
			for(var a of this.document.getElementsByTagName("a")) if (a.hasAttribute("href")) {
				var {host} = a;
				!host || empty.test(host) || this.pp.test(host) || this.ph.test(host)
					|| a.addEventListener("click", click);
			}
		}
	}
} else {
	var {background, insert, setParent} = cfg;
	var arg = insert || setParent, fg = !background;
	var EXPORTED_SYMBOLS = [name + "Parent"];
	var ExternalLinkNewtaberParent = class extends JSWindowActorParent {
		receiveMessage(msg) {
			var opts, gb = this.browsingContext.topChromeWindow.gBrowser;
			if (arg) {
				opts = {};
				var st = gb.selectedTab;
				if (insert) opts.index = st._tPos + 1;
				if (setParent) opts.ownerTab = st;
			}
			var tab = gb.addTrustedTab(msg.data, opts);
			if (fg) gb.selectedTab = tab;
		}
	}
	ChromeUtils.registerWindowActor(name, {
		allFrames: true,
		matches: ["*://*/*"],
		messageManagerGroups: ["browsers"],
		parent: {moduleURI: __URI__},
		child: {moduleURI: __URI__, events: {load: {capture: true}}}
	});
}

Dobrov пишет

просьба переделать в JS модуль сохранения картинок ClickPicSave.jsm

Сейчас пока не очень удобно, поскольку лисьи jsm'ки ещё не сконвертированы.


А вообще это не очень сложно (и, нужен Firefox 103+).
Сам модуль импортируется не ChromeUtils.import() а ChromeUtils.importESModule()
При регистрации ChromeUtils.register{Window, Process}Actor() указываем не moduleURI а esModuleURI
Свойства __URI__ в этих модулях нет, подойдёт Components.stack.filename
Вместо var EXPORTED_SYMBOLS = []; используем инструкцию export
Ну, вобщем, как-то так:

ClickPicSave.mjs

Выделить код

Код:

export {MouseImgSaverChild, MouseImgSaverParent};

var u = {get it() {
	delete this.it;
	return this.it = Cc["@mozilla.org/image/tools;1"].getService(Ci.imgITools);
}};
["E10SUtils", "PrivateBrowsingUtils"].forEach(name => Object.defineProperty(u, name, {
	configurable: true, enumerable: true, get() {
		var url = `resource://gre/modules/${name}.`;
		try {var exp = ChromeUtils.importESModule(url + "sys.mjs");}
		catch {exp = ChromeUtils.import(url + "jsm");}
		delete this[name];
		return this[name] = exp[name];
	}
}));

class MouseImgSaverChild extends JSWindowActorChild {
	handleEvent(e) { // клики мышью
		if (e.button > 1) return; // только ЛКМ, СКМ
		var trg = e.explicitOriginalTarget; // dragstart
		trg.nodeType == Node.ELEMENT_NODE
			&& trg instanceof Ci.nsIImageLoadingContent
			&& this[e.type](trg, e);
	}
	handleDragEvent(e) {
		this[e.type](e);
	}
	dragstart(trg, e) {
		this.trg = trg;
		this.x = e.screenX; this.y = e.screenY;
		this.drag("add");
		this.handleEvent = this.handleDragEvent;
		this.checkTextLinkyTool(trg.ownerDocument);
	}
	events = ["dragover", "drop", "dragend"];
	drag(meth = (delete this.handleEvent, delete this.trg, "remove")) {
		meth += "EventListener";
		var win = this.contentWindow;
		for(var type of this.events) win[meth](type, this, true);
	}
	drop() {
		this.drag();
	}
	dragover(e) {
		var {x, y} = this,
			cx = e.screenX, cy = e.screenY,
			dx = cx - x,
			ax = Math.abs(dx), ay = Math.abs(cy - y);

		if (ax < 10 && ay < 10) return;
		if (dx < 0 || ax < ay) return this.drag();
		this.x = cx; this.y = cy;
	}
	dragend(e) { // перетаскивание рисунка
		var dt = e.dataTransfer, {trg} = this;
		this.drag();
		dt.mozUserCancelled || this.send(trg, e.screenX); // сохранить
		// dt.mozUserCancelled || this.sendAsyncMessage("dragend", (trg.currentRequestFinalURI || uri).spec);
	}
	auxclick(trg) { // клик СКМ
		trg.matches(":any-link :scope") || this.send(trg);
	}
	dblclick(trg) { // ЛКМ
		trg.matches(":any-link :scope")
			|| this.sendAsyncMessage("dblclick", (trg.currentRequestFinalURI || uri).spec);
	}
	send(trg, sx) {
		var uri = trg.currentURI;
		if (!uri) return;

		var doc = trg.ownerDocument;
		var cookieJarSettings = u.E10SUtils
			.serializeCookieJarSettings(doc.cookieJarSettings);

		var referrerInfo = Cc["@mozilla.org/referrer-info;1"]
			.createInstance(Ci.nsIReferrerInfo);
		referrerInfo.initWithElement(trg);
		referrerInfo = u.E10SUtils.serializeReferrerInfo(referrerInfo);

		var contentType = null, contentDisposition = null;
		try {
			var props = u.it.getImgCacheForDocument(doc).findEntryProperties(uri, doc);
			var cs = Ci.nsISupportsCString;
			try {contentType = props.get("type", cs).data;} catch {}
			try {contentDisposition = props.get("content-disposition", cs).data;} catch {}
		} catch {}

		this.sendAsyncMessage("", {
			title: trg.closest("[title]")?.title,
			url: (trg.currentRequestFinalURI || uri).spec,
			contentType, referrerInfo, cookieJarSettings, contentDisposition, sx,
			isPrivate: u.PrivateBrowsingUtils.isContentWindowPrivate(trg.ownerGlobal)
		});
	}
	checkTextLinkyTool(doc) {
		if (doc.title || !doc.documentURI.startsWith("moz-extension:")) return;
		var lab = doc.querySelector("body > label#lblFrom:first-child")?.textContent;
		if (lab) doc.title = lab.slice(0, lab.lastIndexOf("("));
	}
}
if (!ChromeUtils.domProcessChild.childID) {
	var esModuleURI = Components.stack.filename;
	ChromeUtils.registerWindowActor("MouseImgSaver", {
		allFrames: true,
		parent: {esModuleURI},
		messageManagerGroups: ["browsers"],
		child: {esModuleURI, events: {auxclick: {capture: true}, dblclick: {capture: true}, dragstart: {capture: true}}}
	});
	var wref, titles = Object.create(null);
	var data = Object.assign(Object.create(null), {
		"browser.download.dir": {type: "String", get set() {

			var win = wref.get(), {prefs, dirsvc} = win.Services
			var {DownloadPaths, FileUtils} = win;
			var map = val => DownloadPaths.sanitize(val);

			win.Downloads.getList(win.Downloads.ALL).then(list => list.addView({
				onDownloadChanged(download) {
					if (!download.stopped) return;
					var {url} = download.source, title = titles[url];
					if (!title) return;
					delete titles[url];
					if (!download.succeeded) return;

					var file = FileUtils.File(download.target.path), {leafName} = file;
					var ext = leafName.slice(leafName.lastIndexOf("."));
					var newName = map(title) + ext, {parent} = file;
					var newFile = parent.clone();
					newFile.append(newName);
					try {
						newFile.createUnique(file.NORMAL_FILE_TYPE, file.permissions);
						file.renameTo(parent, newFile.leafName);
						download.target.path = newFile.path;
						download.refresh();
					} catch {}
				}
			}));
			Object.defineProperty(this, "set", {get() {
				try {var dir = prefs.getComplexValue("browser.download.dir", Ci.nsIFile);} catch {var dir = dirsvc.get("DfltDwnld", Ci.nsIFile);}
				var arr = prefs.getStringPref("ucf.savedirs", "_Web||_Images|0").split('|').slice(2, 4);
				// подпапки в [Загрузках]: нет | папка графики | имя вкладки | домен
				arr[1] = (arr[1]) ? wref.get().gBrowser.selectedTab.label.slice(0, 64).replace(/ \| — Mozilla Firefox|[\\\/?*\"'`]+/g,'').replace(/\s+/g,' ').replace(/[|<>]+/g,'_').replace(/:/g,'։').trim() : ""; // имя вкладки
				arr.map(map).forEach(dir.append); dir.exists() && dir.isDirectory() || dir.create(dir.DIRECTORY_TYPE, 0o777);
				return dir.path;
			}});
			return this.set;
		}},
		"browser.download.folderList": {type: "Int", set: 2},
		"browser.download.useDownloadDir": {type: "Bool", set: true}
	});
	var MouseImgSaverParent = class extends JSWindowActorParent {
		receiveMessage(msg) {
			var win = msg.target.browsingContext.topChromeWindow, {name} = msg;
			if (name) return this[name](win, msg.data);

			var {url, contentType, contentDisposition, sx, title,
				isPrivate, referrerInfo, cookieJarSettings} = msg.data;
			if (sx && sx > win.mozInnerScreenX + win.innerWidth) return;

			if (title) titles[url] = title;

			wref = Cu.getWeakReference(win);
			var p = win.Services.prefs;

			for(var pref in data) {
				var obj = data[pref], meth = `et${obj.type}Pref`;
				obj.val = p.prefHasUserValue(pref) ? p["g" + meth](pref) : null;
				p["s" + meth](pref, obj.set);
			}
			try {win.internalSave(
				url,
				null, // original url
				null, // document
				null, // file name
				contentDisposition,
				contentType,
				false, // do not bypass the cache
				null, // filepicker title key
				null, // chosen data
				u.E10SUtils.deserializeReferrerInfo(referrerInfo),
				u.E10SUtils.deserializeCookieJarSettings(cookieJarSettings),
				win.document, // initiating doc
				true, // skip prompt for where to save
				null, // cache key
				isPrivate,
				win.document.nodePrincipal
			);}
			finally {
				for(var pref in data) data[pref].val === null
					? p.clearUserPref(pref)
					: p[`set${data[pref].type}Pref`](pref, data[pref].val);
			}
		}
		dblclick(win, imgURL) {
			var gb = win.gBrowser, index = gb.selectedTab._tPos + 1;
			gb.selectedTab = gb.addTrustedTab('https://yandex.ru/images/search?rpt=imageview&url=' + imgURL, {index});
		}
	}
}

Отсутствует

 

№37006-07-2022 22:36:01

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 1644
UA: Firefox 91.0

Re: UCF - ваши кнопки, скрипты…

Dumby
К сожалению не работает, или я не знаю как его прописать.

Отсутствует

 

№37107-07-2022 00:05:19

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

Re: UCF - ваши кнопки, скрипты…

_zt пишет

не работает, или я не знаю как его прописать

Да обычная jsm'ка, как и другие. То есть ChromeUtils.import("урл");
Чтоб совсем уж не работало это вряд ли. Откровенно "внешние" ссылки
должны открываться в новой вкладке, во всяком случае те, которые в есть в html сразу.
А вот конфигурация — вообще непонятно, ну кроме background, insert, setParent.

Отсутствует

 

№37207-07-2022 01:02:46

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 1644
UA: Firefox 91.0

Re: UCF - ваши кнопки, скрипты…

Dumby
Точно, забыл ее в лоадере проверить. Работает не хуже чем в обезьяне, на первый взгляд. Спасибо.
   
Я не знаю чего он там учесть пытался, без parent: true host: true она работает плохо, все подряд открывает в новой, в том числе и когда здесь по имени щелкаешь. Возможно последовательно опции добавлял, да так и оставил, у меня все как по умолчанию.

Отредактировано _zt (07-07-2022 07:12:41)

Отсутствует

 

№37312-07-2022 23:42:49

ez7pac
Участник
 
Группа: Members
Откуда: Кубань
Зарегистрирован: 27-12-2015
Сообщений: 200
UA: Firefox 102.0

Re: UCF - ваши кнопки, скрипты…

Привет мастерам!
Ребят, пару кнопок из шапки задействовал, работают прекрасно, спасибо большое создателям. Единственное, что поменял бы на свой вкус - сами иконки кнопок. Подскажите как можно это сделать, пожалуйста!

Отсутствует

 

№37413-07-2022 01:06:23

xrun1
Участник
 
Группа: Members
Зарегистрирован: 12-12-2013
Сообщений: 1224
UA: Firefox 102.0

Re: UCF - ваши кнопки, скрипты…

ez7pac
Свою иконку конвертируете в формат base64. Онлайн-конвертеров в сети полно.
Ищете в коде кнопки что-то типа такого

Выделить код

Код:

"chrome://browser/skin/search-engine-placeholder.png"

Это иконка из [firefox], можно взять то, что между двойными кавычками, вставить в адресную строку [firefox] и посмотреть. Заменяете на свой код.
Или смотрите уже сконвертированные иконки в коде типа

Выделить код

Код:

"data:image/что-то_непонятное"

Механизм такой же - заменяете на свой код то, что между двойными кавычками.

Отсутствует

 

№37513-07-2022 02:06:19

ez7pac
Участник
 
Группа: Members
Откуда: Кубань
Зарегистрирован: 27-12-2015
Сообщений: 200
UA: Firefox 91.0

Re: UCF - ваши кнопки, скрипты…

xrun1
Ага, понял, спасибо!
Такого нет:

Выделить код

Код:

"chrome://browser/skin/***.png"

Т.е. иконка не дефолтная, а своя.
Вот такое есть

Выделить код

Код:

"data:image/что-то_непонятное"

С конвертацией и заменой разберусь, думаю. Но тогда другой вопрос возник - а нельзя вместо кода иконки, вот этого "непонятного", воткнуть в код кнопки дефолтную иконку? Я там (chrome://browser/skin/browser.css) глянул - подходящие для меня есть.
Если можно, то как это сделать, чтобы не накосячить?

Отсутствует

 

Board footer

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