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

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

№147621-04-2024 15:26:40

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Vitaliy V.
Спасибо за расширение.
   

Vitaliy V. пишет

А что системные уведомления не проще включить

Да я с удовольствием бы, но они мелькают ровно на секунду и в истории не сохраняются, хотя в настройках уведомлений Win, для Fx указано иное.

Добавлено 21-04-2024 15:38:29
Хотя, действительно, лучше включу системные.

Отредактировано _zt (21-04-2024 15:38:29)

Отсутствует

 

№147721-04-2024 16:59:07

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Vitaliy V. пишет

попробуй заменить на item.addEventListener("command", cmd);

Я так переделал, и всё работает: item.onclick = cmd
Менюшка в оконном скрипте потому, что там весь основной код – перехват кликов и прочие функции.

Отсутствует

 

№147821-04-2024 17:06:17

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Dobrov пишет

Я так переделал, и всё работает

Нет я же написал это не пойдет, открой второе окно и понажимай там пункт, перезагружаться будет в первом окне

Отредактировано Vitaliy V. (21-04-2024 17:07:46)

Отсутствует

 

№147921-04-2024 19:41:40

b0ttle
Участник
 
Группа: Members
Зарегистрирован: 22-10-2020
Сообщений: 182
UA: Firefox 124.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Vitaliy V. || Спасибо, обновился.
Здраствуйте. Хотел выдернуть с ATB "меню с дополнениями" и "восстановить фавиконки". Но у меня не выходит, туповат для этого. Просто там какие-то изменения все же уже имеются, вот и хотел скрипты обновить. Можно их как-то вытащить в отдельные скрипты в ucf? Как раньше. Другие кнопки особо не нужны как и ATB.


add:
Можно добавить в "Long Left Click", функцию клика ПКМ, чтобы быстро открывать несколько ссылок, например на новостных сайтах. По типу дополнения "Right Links We"? Ну или отдельным скриптом, если можно. Хотя наверно с просьбами уже запарил.


Просто ATB бесит тем, что он горит красным в about:addons, плюс правки в about:config, плюс лишние кнопки тоже мозолят(у меня ноут) в "Настройка панели инструментов". Насчет "Long Left Click", может его добавить в AMO? Если бы еще добавить правый клик. Отдельным скриптом тоже будет норм. Ладно, в общем, если завал просьбами то пойму. Оставлю как есть, пока работает.

Отредактировано b0ttle (22-04-2024 19:38:42)

Отсутствует

 

№148022-04-2024 01:45:32

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

b0ttle
Так это "эксперимент", он будет гореть пока плашку не скроете стилем. Подозреваю, что, по этой же причине, на AMO их не будет.
А так да, прикольная функция, но мне так и не пригодилась - Snap Links Plus

Отсутствует

 

№148122-04-2024 12:34:03

b0ttle
Участник
 
Группа: Members
Зарегистрирован: 22-10-2020
Сообщений: 182
UA: Firefox 124.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

_zt
Интересное дополнение, не знал что можно таким образом открывать несколько вкладок. ПКМ все же привычнее, заметил, что вообще в контекстное меню не заглядывал продолжительное время, может пол года. По идее и ПКМ не нужен, если через Ctrl кликать, но это же руку надо тянуть к клавиатуре. Плюс контекстным меню все равно не пользуюсь.
Кстати, вроде есть настройка about:config, которая по клику открывает все ссылки в новой вкладке. Может он тоже сойдет. Обычно, в том же окне открываю лишь закладки. На самих вкладках наоборот, редко, там обычно ПКМ и в новой вкладке.

Отредактировано b0ttle (22-04-2024 12:40:44)

Отсутствует

 

№148222-04-2024 15:43:55

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

b0ttle пишет

Можно их как-то вытащить в отдельные скрипты в ucf?

Ну хорошо, только сначала нужно обновить UCF, незначительное обновление добавлен модуль ExtensionParent, может пригодится и для других скриптов.
Upd: + файл настроек CustomStylesScripts.mjs вынесен в корень user_chrome_files

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

Выделить код

Код:

(async (
    id = "ucf-aom-button",
    label = "Дополнения",
    tooltiptext = "ЛКМ: Меню дополнений\nСКМ: Отладка дополнений\nПКМ: Открыть менеджер дополнений",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:none;stroke:context-fill rgb(39, 174, 129);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M12.9 15.3H3.2c-.88 0-1.6-.6-1.6-1.4v-2.7c0-.4.33-.6.74-.6h1.72c.7 0 1.25-.64 1.25-1.2 0-.64-.55-1.15-1.25-1.15H2.34c-.41 0-.74-.32-.74-.68V5.84c0-.81.72-1.48 1.6-1.48h2.36V3.13c0-1.21.93-2.297 2.21-2.419C9.23.57 10.5 1.62 10.5 2.98v1.38h2.4c.9 0 1.5.67 1.5 1.48v8.06c0 .8-.6 1.4-1.5 1.4z'/></svg>",
    checkbox_img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 16 16'><path d='M 3,7 7,11 13,5' style='fill:none;stroke:white;stroke-width:1;'/></svg>",
    show_version = true,
    show_description = true,
    user_permissions = true,
    show_hidden = true,
    show_disabled = true,
    enabled_first = true,
    exceptions_listset = new Set([

    ]),
    exceptions_type_listset = new Set([

    ]),

    extensionOptionsMenu = {
        get alertsService() {
            delete this.alertsService;
            return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
        },
        get clipboardHelp() {
            delete this.clipboardHelp;
            return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
        },
        get exceptions_type_listarr() {
            delete this.exceptions_type_listarr;
            var arr = ["extension", "theme", "locale", "dictionary"];
            if (!exceptions_type_listset.size)
                return this.exceptions_type_listarr = arr;
            return this.exceptions_type_listarr = arr.filter(type => !exceptions_type_listset.has(type));
        },
        async populateMenu(e) {
            var popup = e.target, doc = e.view.document;
            var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr);
            var addonsMap = new WeakMap();
            var setAttributesMenu = (mi, addon, extension) => {
                var permissions, uuid;
                var props = {
                    label: `${addon.name} ${show_version ? addon.version : ""}`,
                    class: "menuitem-iconic",
                    tooltiptext: `${(show_description && addon.description) ? `${addon.description}\n` : ""}ID: ${addon.id}${addon.isActive && (uuid = extension?.uuid) ? `\nUUID: ${uuid}` : ""}${(user_permissions && (permissions = addon.userPermissions?.permissions)?.length) ? `\nРазрешения: ${permissions.join(", ")}` : ""}\n${addon.optionsURL ? "\nЛКМ: Настройки" : ""}\nCtrl+ЛКМ: Копировать ID${uuid ? "\nShift+ЛКМ: Копировать UUID" : ""}${addon.creator?.url ? "\nCtrl+Shift+ЛКМ: Автор" : ""}${addon.homepageURL ? "\nСКМ: Домашняя страница" : ""}${!addon.isBuiltin ? "\nCtrl+СКМ: Просмотр источника" : ""}\nShift+СКМ: Просмотр источника во вкладке\nПКМ: Включить/Отключить${(!addon.isSystem && !addon.isBuiltin) ? "\nCtrl+ПКМ: Удалить" : ""}`,
                };
                for (let p in props)
                    mi.setAttribute(p, props[p]);
                if (addon.iconURL)
                    mi.setAttribute("image", addon.iconURL);
                var cls = mi.classList;
                addon.isActive ? cls.remove("ucf-disabled") : cls.add("ucf-disabled");
                addon.optionsURL ? cls.remove("ucf-notoptions") : cls.add("ucf-notoptions");
                addon.isSystem ? cls.add("ucf-system") : cls.remove("ucf-system");
                cls.add(`ucf-type-${addon.type}`);
            };
            var {GlobalManager} = ExtensionParent;
            addons.filter(a => !(a.iconURL || "").startsWith("resource://search-extensions/")).sort((a, b) => {
                var ka = `${(enabled_first ? a.isActive ? "0" : "1" : "")}${a.type || ""}${a.name.toLowerCase()}`;
                var kb = `${(enabled_first ? b.isActive ? "0" : "1" : "")}${b.type || ""}${b.name.toLowerCase()}`;
                return (ka < kb) ? -1 : 1;
            }).forEach(addon => {
                if (!exceptions_listset.has(addon.id) &&
                    (!addon.hidden || show_hidden) &&
                    (!addon.userDisabled || show_disabled)) {
                    let extension = GlobalManager.extensionMap.get(addon.id),
                    mi = doc.createXULElement("menuitem");
                    setAttributesMenu(mi, addon, extension);
                    mi._Addon = addon;
                    mi._Extension = extension;
                    popup.append(mi);
                    addonsMap.set(addon, mi);
                }
            });
            var click = e => {
                e.preventDefault();
                e.stopPropagation();
                this.handleClick(e);
            };
            popup.addEventListener("click", click);
            var listener = {
                onEnabled: addon => {
                    var mi = addonsMap.get(addon);
                    if (mi)
                        setAttributesMenu(mi, addon, mi._Extension);
                },
                onDisabled: addon => {
                    listener.onEnabled(addon);
                },
                onInstalled: addon => {
                    var extension = GlobalManager.extensionMap.get(addon.id),
                    mi = doc.createXULElement("menuitem");
                    setAttributesMenu(mi, addon, extension);
                    mi._Addon = addon;
                    mi._Extension = extension;
                    popup.prepend(mi);
                    addonsMap.set(addon, mi);
                },
                onUninstalled: addon => {
                    var mi = addonsMap.get(addon);
                    if (mi) {
                        mi.remove();
                        addonsMap.delete(addon);
                    }
                },
            };
            AddonManager.addAddonListener(listener);
            popup.addEventListener("popuphiding", () => {
                AddonManager.removeAddonListener(listener);
                popup.removeEventListener("click", click);
                addonsMap = null;
                for (let item of popup.querySelectorAll("menuitem"))
                    item.remove();
            }, { once: true });
        },
        handleClick(e) {
            var win = e.view, mi = e.target;
            if (!("_Addon" in mi) || !("_Extension" in mi))
                return;
            var addon = mi._Addon, extension = mi._Extension;
            switch (e.button) {
                case 0:
                    if (e.ctrlKey && e.shiftKey) {
                        if (addon.creator?.url)
                            win.gBrowser.selectedTab = this.addTab(win, addon.creator.url);
                    } else if (e.ctrlKey) {
                        this.clipboardHelp.copyString(addon.id);
                        win.setTimeout(() => {
                            this.alertsService.showAlertNotification(null, "ID в буфере обмена!", addon.id, false);
                        }, 100);
                    } else if (e.shiftKey) {
                        if (extension?.uuid) {
                            this.clipboardHelp.copyString(extension.uuid);
                            win.setTimeout(() => {
                                this.alertsService.showAlertNotification(null, "UUID в буфере обмена!", extension.uuid, false);
                            }, 100);
                        }
                    } else if (addon.isActive && addon.optionsURL)
                        this.openAddonOptions(addon, win);
                    win.closeMenus(mi);
                    break;
                case 1:
                    if (e.ctrlKey) {
                        if (!addon.isBuiltin)
                            this.browseDir(addon);
                    } else if (e.shiftKey)
                        this.browseDir(addon, win);
                    else if (addon.homepageURL)
                        win.gBrowser.selectedTab = this.addTab(win, addon.homepageURL);
                    win.closeMenus(mi);
                    break;
                case 2:
                    if (!e.ctrlKey) {
                        let endis = addon.userDisabled ? "enable" : "disable";
                        if (addon.id == "screenshots@mozilla.org")
                            Services.prefs.setBoolPref("extensions.screenshots.disabled", !addon.userDisabled);
                        else if (addon.id == "webcompat-reporter@mozilla.org")
                            Services.prefs.setBoolPref("extensions.webcompat-reporter.enabled", addon.userDisabled);
                        addon[endis]({ allowSystemAddons: true });
                    } else if (!addon.isSystem && !addon.isBuiltin) {
                        win.closeMenus(mi);
                        if (Services.prompt.confirm(win, null, `Удалить ${addon.name}?`))
                            addon.uninstall();
                    }
                break;
            }
        },
        openAddonOptions(addon, win) {
            switch (addon.optionsType) {
                case 5:
                    let viewID = `addons://detail/${encodeURIComponent(addon.id)}/preferences`;
                    if ("openAddonsMgr" in win.BrowserAddonUI)
                        win.BrowserAddonUI.openAddonsMgr(viewID);
                    else
                        win.BrowserOpenAddonsMgr(viewID);
                    break;
                case 3:
                    win.switchToTabHavingURI(addon.optionsURL, true);
                    break;
            }
        },
        browseDir(addon, win) {
            try {
                if (!win) {
                    let file = Services.io.getProtocolHandler("file")
                    .QueryInterface(Ci.nsIFileProtocolHandler)
                    .getFileFromURLSpec(addon.getResourceURI().QueryInterface(Ci.nsIJARURI).JARFile.spec);
                    if (file.exists())
                        file.launch();
                } else
                    win.gBrowser.selectedTab = this.addTab(win, addon.getResourceURI().spec);
            } catch (e) {}
        },
        addTab(win, url, params = {}) {
            params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
            params.relatedToCurrent = true;
            return win.gBrowser.addTab(url, params);
        },
    }
) => { Services.io.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
    .setSubstitution(`${id}-img`, Services.io.newURI(img));
    CustomizableUI.createWidget({
        id,
        type: "custom",
        label,
        tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onBuild(doc) {
            var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView;
            var props = {
                id,
                label,
                context: "",
                tooltiptext,
                type: "menu",
                class: "toolbarbutton-1 chromeclass-toolbar-additional",
            };
            for (let p in props)
                btn.setAttribute(p, props[p]);
            btn.addEventListener("click", e => {
                if (e.button == 1)
                    e.view.switchToTabHavingURI("about:debugging#/runtime/this-firefox", true, { ignoreFragment: "whenComparing", triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), });
                else if (e.button == 2) {
                    let win = e.view, viewID = "addons://list/extension";
                    if ("openAddonsMgr" in win.BrowserAddonUI)
                        win.BrowserAddonUI.openAddonsMgr(viewID);
                    else
                        win.BrowserOpenAddonsMgr(viewID);
                }
            });
            var mp = doc.createXULElement("menupopup");
            mp.id = `${id}-popup`;
            mp.addEventListener("contextmenu", e => {
                e.preventDefault();
                e.stopPropagation();
            });
            mp.addEventListener("popupshowing", e => {
                extensionOptionsMenu.populateMenu(e);
            });
            btn.append(mp);
            var btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(`
                #${id} {
                    list-style-image: url("resource://${id}-img") !important;
                }
                #${id}-popup menuitem {
                    fill: currentColor;
                    fill-opacity: .8;
                    list-style-image: url("resource://${id}-img") !important;
                    &::after {
                        display: flex !important;
                        content: "" !important;
                        height: 16px !important;
                        width: 16px !important;
                        padding: 0 !important;
                        border: 1px solid #0074e8 !important;
                        border-radius: 0 !important;
                        background-repeat: no-repeat !important;
                        background-position: center !important;
                        background-size: 16px !important;
                        background-color: #0074e8 !important;
                        background-image: url("${checkbox_img}") !important;
                        opacity: 1 !important;
                    }
                    &.ucf-disabled::after {
                        border-color: currentColor !important;
                        background-color: transparent !important;
                        background-image: none !important;
                        opacity: .25 !important;
                    }
                    &.ucf-disabled > label,
                    &.ucf-notoptions > label {
                        opacity: .6 !important;
                    }
                    &.ucf-system > label {
                        text-decoration: underline !important;
                        text-decoration-style: dotted !important;
                    }
                    & > label {
                        margin-inline-end: 0 !important;
                    }
                    & > .menu-accel-container {
                        display: flex !important;
                        padding: 4px !important;
                        margin: 0 !important;
                        opacity: 1 !important;
                    }
                    & > .menu-accel-container .menu-iconic-accel {
                        display: flex !important;
                        margin: 0 !important;
                        height: 8px !important;
                        width: 8px !important;
                        border-radius: 4px !important;
                        background-color: transparent !important;
                        opacity: 1 !important;
                        font-size: 0 !important;
                    }
                    &.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel {
                        background-color: #e31b5d !important;
                    }
                    &.ucf-type-locale > .menu-accel-container .menu-iconic-accel {
                        background-color: #27ae81 !important;
                    }
                    &.ucf-type-theme > .menu-accel-container .menu-iconic-accel {
                        background-color: #f38525 !important;
                    }
                }
            `);
            try {
                win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET);
            } catch (e) {}
            return btn;
        },
    });
})();

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

Выделить код

Код:

(async (
    id = "ucf-loads-favicons",
    label = "Восстановить фавиконки",
    tooltiptext = "Восстановить фавиконки закладок",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M3.6.6v14.8L8 11l4.4 4.4V.6z'/></svg>",
    maxrequests = 50, // Максимальное количество параллельных запросов
    maxtimeout = 30, // Длительность до прерывания запроса в секундах
    alertnotification = true, // Уведомление о завершении поиска фавиконок для закладок

    favicons = {
        _favrunning: false,
        get alertsService() {
            delete this.alertsService;
            return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
        },
        showAlert(title, val) {
            try {
                this.alertsService.showAlertNotification(null, title, val, false);
            } catch(e) {}
        },
        favSearchStart() {
            if (this._favrunning) return;
            this._favrunning = true;
            this.callWithEachWindow(id, {fill: "color-mix(in srgb, currentColor 20%, #e31b5d)"});
            PlacesUtils.promiseBookmarksTree(PlacesUtils.bookmarks.rootGuid).then(root => {
                var urlsList = [];
                var convert = (node, url) => {
                    if (node.children)
                        node.children.map(convert);
                    else if ((url = node.uri) && /^(?:https?|ftp|file):/.test(url))
                        urlsList.push(url);
                };
                convert(root);
                var favForPage = siteURI => {
                    return new Promise(resolve => {
                        try {
                            siteURI = Services.io.newURI(siteURI);
                        } catch(e) {
                            resolve(null);
                        }
                        PlacesUtils.favicons.getFaviconURLForPage(siteURI, uri => {
                            if (uri === null)
                                resolve(siteURI);
                            else
                                resolve(null);
                        });
                    });
                };
                Promise.all(urlsList.map(favForPage)).then(results => this.favSearchResults(results.filter(url => url !== null)));
            });
        },
        favComplete(favsuccesslength, favmaxlength) {
            this._favrunning = false;
            this.callWithEachWindow(id, {fill: ""});
            if (alertnotification)
                this.showAlert("Поиск фавиконок", `Успешно обработано - ${favsuccesslength}, не удалось обработать - ${favmaxlength - favsuccesslength}`);
        },
        favSearchResults(results) {
            var favmaxlength = results.length;
            var favsuccesslength = 0;
            if (!favmaxlength) {
                this.favComplete(0, 0);
                return;
            }
            var favmaxtimeout = maxtimeout * 1000;
            var _favmaxlength = favmaxlength;
            var splice = results.splice(0, maxrequests);
            var favSearchPage = siteURI => {
                (new Promise(resolve => {
                    try {
                        let req = new XMLHttpRequest();
                        req.mozBackgroundRequest = true;
                        req.open("GET", siteURI.spec, true);
                        req.responseType = "document";
                        req.overrideMimeType("text/html");
                        req.timeout = favmaxtimeout;
                        req.onload = () => {console.log(req)
                            try {
                                let doc = req.responseXML, favURI;
                                if (doc) {
                                    let links = doc.querySelectorAll("head link[href][rel~='icon']"), lastlink, is16, is32, isany;
                                    for (let link of links) {
                                        if (link.sizes.length === 1) {
                                            let size = link.sizes[0];
                                            if (/any/i.test(size))
                                                isany = link;
                                            else if (/32x32/i.test(size))
                                                is32 = link;
                                            else if (/16x16/i.test(size))
                                                is16 = link;
                                        }
                                        lastlink = link;
                                    }
                                    links = isany || is32 || is16 || lastlink;
                                    if (links)
                                        favURI = links.href;
                                }
                                if (!favURI)
                                    favURI = `${req.responseURL ? Services.io.newURI(req.responseURL).prePath : siteURI.prePath}/favicon.ico`;
                                let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
                                let request = PlacesUtils.favicons.setAndFetchFaviconForPage(siteURI, Services.io.newURI(favURI), false, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, {
                                    onComplete() {
                                        ++favsuccesslength;
                                        resolve();
                                        timer.cancel();
                                        timer = null;
                                        request = null;
                                    },
                                }, Services.scriptSecurityManager.getSystemPrincipal());
                                if (!request) {
                                    resolve();
                                    timer = null;
                                    return;
                                }
                                timer.initWithCallback(() => {
                                    resolve();
                                    try {
                                        request.cancel();
                                    } catch(e) {}
                                    timer = null;
                                    request = null;
                                }, favmaxtimeout, timer.TYPE_ONE_SHOT);
                            } catch(e) {
                                resolve();
                            }
                        };
                        req.onabort = () => {
                            resolve();
                        };
                        req.onerror = req.ontimeout = () => {
                            resolve();
                            req.abort();
                        };
                        req.send(null);
                    } catch(e) {
                        resolve();
                    }
                })).then(() => {
                    if (!(--_favmaxlength)) {
                        this.favComplete(favsuccesslength, favmaxlength);
                        return;
                    }
                    if (!results.length) return;
                    favSearchPage(results.shift());
                });
            };
            splice.map(favSearchPage);
        },
        callWithEachWindow(buttonID, atr) {
            var getW = CustomizableUI.getWidget(buttonID);
            if (getW.instances.length)
                for (let {node} of getW.instances) {
                    if (!node) continue;
                    for (let a in atr)
                        node.style.setProperty(a, atr[a]);
                }
            else
                for (let win of CustomizableUI.windows) {
                    let node = getW.forWindow(win).node;
                    if (!node) continue;
                    for (let a in atr)
                        node.style.setProperty(a, atr[a]);
                }
        },
    }
) => {Services.io.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
    .setSubstitution(`${id}-img`, Services.io.newURI(img));
    CustomizableUI.createWidget({
        id,
        label,
        tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onCreated(btn) {
            btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important");
            if (favicons._favrunning)
                btn.style.setProperty("fill", "color-mix(in srgb, currentColor 20%, #e31b5d)");
        },
        onCommand(e) {
            favicons.favSearchStart();
        },
    });
})();

Добавлено 22-04-2024 15:52:41

b0ttle пишет

Можно добавить в "Long Left Click", функцию клика ПКМ

Не планирую, не заинтеросован в данной функции

b0ttle пишет

Насчет "Long Left Click", может его добавить в AMO?

Experimental WebExtensions APIs невозможно добавить на AMO, и также нельзя просто подписать подобное расширение.
Из того что можно добавить на AMO у меня только New Tab Page и уже подписано.

Отредактировано Vitaliy V. (22-04-2024 21:55:09)

Отсутствует

 

№148322-04-2024 17:47:54

egorsemenov06
Участник
 
Группа: Members
Зарегистрирован: 12-06-2018
Сообщений: 407
UA: Firefox 125.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Vitaliy V. Обновите пожалуйста эти две кнопки

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

Выделить код

Код:

//Ссылки кликабельны
try {(() => {
    var id = "ucf-text-to-link",
    label = "Текст URL в кликабельные ссылки",
    tooltiptext = "Превратить текст URL в кликабельные ссылки",
    img = (rph => {
        var subst = "ucf-text-to-link-btn-img";
        rph.setSubstitution(subst, Services.io.newURI(
           "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path style='fill:none;stroke:context-fill;stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='m5.6 10.4 4.8-4.8m-8.9 4.9c-2.6 2.6 1.4 6.6 4 4l1-1c2.6-2.6-1.4-6.6-4-4zm9-9c2.6-2.6 6.6 1.4 4 4l-1 1c-2.6 2.6-6.6-1.4-4-4z'/></svg>"        ));
        return `resource://${subst}/`;
    })(Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler));
	
    var texttolink = {
        _registerActor() {
            if (this.registerActor) return;
            ChromeUtils.registerWindowActor("UcfTextToLinkActor", {
                child: {
                    esModuleURI: "chrome://user_chrome_files/content/custom_scripts/UcfTextToLinkActorChild.mjs"
                },
                allFrames: true,
                messageManagerGroups: ["browsers"],
            });
            this.registerActor = true;
        },
        sendAsyncMessages(win, message, data) {
            this._registerActor();
            this.sendAsyncMessages = this._sendAsyncMessages;
            this.sendAsyncMessages(win, message, data);
        },
        _sendAsyncMessages(win, message, data) {
            var {browsingContext} = win.gBrowser.selectedBrowser;
            ({
                "UcfTextToLinkActor:TextToLink"() {
                    for (let actor of this)
                        actor.sendAsyncMessage(message);
                },
                *[Symbol.iterator]() {
                    var contextsToVisit = [browsingContext];
                    while (contextsToVisit.length) {
                        let currentContext = contextsToVisit.pop();
                        let global = currentContext?.currentWindowGlobal;
                        if (!global) continue;
                        yield global.getActor("UcfTextToLinkActor");
                        contextsToVisit.push(...currentContext.children);
                    }
                },
            })[message]?.();
        },
    };
    CustomizableUI.createWidget({
        id: id,
        label: label,
        tooltiptext: tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onCreated(btn) {
            btn.style.setProperty("list-style-image", `url("${img}")`, "important");
        },
        onCommand(e) {
            texttolink.sendAsyncMessages(e.view, "UcfTextToLinkActor:TextToLink");
        },
    });
})();} catch(e) {}

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

Выделить код

Код:

var excludedTags = Object.defineProperty({}, "has", {
    value: tag => (excludedTags = new Set([
        "a","svg","canvas","applet","input","button","area","embed","noembed","frame","frameset","head","iframe","img",
        "select","option","datalist","map","meta","noscript","video","audio","object","param","script","style","textarea","code"
    ])).has(tag)
});

export class UcfTextToLinkActorChild extends JSWindowActorChild {
    receiveMessage(msg) {
        return ({
            "UcfTextToLinkActor:TextToLink": () => {
                this.textToLink();
            },
        })[msg.name]?.();
    }
    textToLink() {
        if (this.running || !this.document?.body)
            return;
        this.running = true;
        var url_regexp = /(^|[\s(,;'"`“\[\]=_])((?:(?:https?|ftp):\/\/[-\wа-яё.!~*'();,/?:@&=+$#%_\u2300-\u23FF\u2600-\u27BF]|www\d{0,3}[.][a-zа-яё0-9.-]{2,249}|[a-zа-яё0-9.-]{2,250}[.][a-zа-яё]{2,4}\/)[-\wа-яё.!~*'();,/?:@&=+$#%_\u2300-\u23FF\u2600-\u27BF]*)/gim,
        email_regexp = /(^|mailto:|[\s(,;'"`“\[\]=])([\w!#$%&'*+/=?^`{|}~.-]{2,}@[\[\]a-z0-9.-]+)/gim,
        setEmail = (node, text) => {
            var repl = text.replace(email_regexp, '$1<a href="mailto:$2" class="add__TextToEmail">$2</a>');
            if (text.length == repl.length)
                return;
            var span = node.ownerDocument.createElement("span");
            span["innerHTML"] = repl;
            node.replaceWith(span);
        },
        setLink = (node, text) => {
            if (!(text = node.textContent)) return;
            text = text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
            var repl = text.replace(url_regexp, '$1<a href="$2" target="_blank" class="add__TextToLink">$2</a>');
            if (text.length == repl.length) {
                setEmail(node, text);
                return;
            }
            var span = node.ownerDocument.createElement("span");
            span["innerHTML"] = repl;
            for (let el of span.querySelectorAll("a.add__TextToLink[href]:not([href^='http']):not([href^='ftp'])"))
                el.setAttribute("href", `http://${el.getAttribute("href")}`);
            node.replaceWith(span);
            var txtnode = Node.TEXT_NODE;
            for (let child of span.childNodes) {
                let txt;
                if (child.nodeType === txtnode && (txt = child.textContent))
                    setEmail(child, txt);
            }
        },
        elList = [],
        getWalker = elem => {
            var doc = elem.ownerDocument, reject = NodeFilter.FILTER_REJECT, skip = NodeFilter.FILTER_SKIP, accept = NodeFilter.FILTER_ACCEPT, txtnode = Node.TEXT_NODE;
            var walker = doc.createTreeWalker(elem, NodeFilter.SHOW_ALL, {
                acceptNode(node) {
                    if (excludedTags.has(node.localName))
                        return reject;
                    if (node.nodeType !== txtnode && !node.shadowRoot)
                        return skip;
                    return accept;
                }
            }, false);
            while (walker.nextNode()) {
                let currnode = walker.currentNode;
                if (!currnode.shadowRoot)
                    elList.push(currnode);
                else
                    getWalker(currnode.shadowRoot);
            }
        };
        getWalker(this.document.body);
        for (let el of elList)
            setLink(el);
        elList = [];
        this.running = false;
    }
}

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

Выделить код

Код:

//Переключить Куки
try {(() => {
    var id = "ucf-cookie-toggle",
    label = "Переключить Куки",
    tooltiptext = "ЛКМ: Переключить Куки\nСКМ: Удалить куки домена текущей страницы\nПКМ: Управление куками",
    gpref = "network.cookie.cookieBehavior",
    img = (rph => {
        var subst = "ucf-cookie-toggle-btn-img";
        rph.setSubstitution(subst, Services.io.newURI(
            "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='32'><path style='fill:none;stroke:context-fill;stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M12.5 10.5v-1h-1v1h1m-4-4h1v1h-1v-1m0 7h1v-1h-1v1m-6-7h1v1h-1v-1m4 4v-1h-1v1h1m-3 3v-1h-1m3-9h1v1h-1v-1M8 .6C8 5 11 8 15.4 8c0 4-3.4 7.4-7.4 7.4S.6 12 .6 8 4 .6 8 .6M12.5 26.5v-1h-1v1h1m-4-4h1v1h-1v-1m0 7h1v-1h-1v1m-6-7h1v1h-1v-1m4 4v-1h-1v1h1m-3 3v-1h-1m3-9h1v1m2-3.5v.5h1V17m2 2.5v1h1v-1h-1m3.5 3h-.5v1h.5m-8.5-3h-1v-1M8 16.6c4 0 7.4 3.4 7.4 7.4S12 31.4 8 31.4.6 28 .6 24 4 16.6 8 16.6'/></svg>"
        ));
        return `resource://${subst}/`;
    })(Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler));
	
    var tbarbtns = {
        initialised: false,
        get network_cookie_cookieBehavior() {
            delete this.network_cookie_cookieBehavior;
            try {
                return this.network_cookie_cookieBehavior = Services.prefs.getIntPref(gpref);
            } catch(e) { }
            return this.network_cookie_cookieBehavior = null;
        },
        init() {
            if (this.initialised) return;
            this.initialised = true;
            Services.prefs.addObserver(gpref, this);
        },
        prefToggleNumber(pref, next) {
            Services.prefs.setIntPref(pref, next[Services.prefs.getIntPref(pref)]);
        },
        getETDL(uri) {
            var eTLD = "";
            try {
                eTLD = Services.eTLD.getBaseDomain(uri);
            } catch (e) {
                try {
                    eTLD = uri.asciiHost;
                } catch (e) {}
            }
            return eTLD;
        },
//
        async viewCookies(win) {
            var func = async sds => {
                await document.documentReadyForIdle;
                var upd, box = document.getElementById("searchBox");
                (upd = site => box.setUserInput(site, box.focus()))(window.arguments[0]);
                var attr = "data-isCurrentSortCol", sel = `treecol[${attr}=true]`;
                window.updSearch = async site => {
                    var sites = sds._sites = await SiteDataManager.getSites();
                    var col = document.querySelector(sel);
                    col.removeAttribute(attr);
                    sds._sortSites(sites, col);
                    sds._buildSitesList(sites);
                    window.focus(upd(site));
                }
            }
            var type = "Browser:SDS";
            var xhtml = (await (await win.fetch("chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml")).text())
                .replace(/(persist=".+)"/, `$1 screenX screenY sizemode" windowtype="${type}"`)
                .replace(/<script .+>/, `$&\n  <script>(${func})(gSiteDataSettings);\n  </script>\n${
                    ["globalOverlay", "editMenuOverlay"]
                        .map(n => `  <script src="chrome://global/content/${n}.js"/>`).join("\n")
                }`);

            var sds = "chrome://ucfsdswnd/content/sds.xhtml";
            this.cr = Cc["@mozilla.org/addons/addon-manager-startup;1"]
                .getService(Ci.amIAddonManagerStartup).registerChrome(
                    Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)),
                    [["override", sds, "data:application/xhtml+xml," + encodeURIComponent(xhtml)]]
                );
            (this.viewCookies = async win => {
                var uri = win.gBrowser.selectedBrowser.currentURI;
                try {
                    var u = win.ReaderMode.getOriginalUrl(uri.spec);
                    if (u) uri = Services.io.newURI(u);
                } catch {}
                uri = this.getETDL(uri);

                await win.SiteDataManager.updateSites();
                var w = Services.wm.getMostRecentWindow(type);
                w ? w.updSearch(uri) : win.openDialog(sds, type, "chrome,dialog=no,resizable", uri);
            })(win);
        },
        callWithEachWindow(buttonID, atr) {
            var getW = CustomizableUI.getWidget(buttonID);
            if (getW.instances.length)
                for (let {node} of getW.instances) {
                    if (!node) continue;
                    for (let a in atr)
                        node.setAttribute(a, atr[a]);
                }
            else
                for (let win of CustomizableUI.windows) {
                    let node = getW.forWindow(win).node;
                    if (!node) continue;
                    for (let a in atr)
                        node.setAttribute(a, atr[a]);
                }
        },
        observe(subject, topic, pref) {
            if (pref == gpref) {
                delete this.network_cookie_cookieBehavior;
                let network_cookie_cookieBehavior = this.network_cookie_cookieBehavior = Services.prefs.getIntPref(pref);
                this.callWithEachWindow(id, {badge: network_cookie_cookieBehavior, badgeStyle: `background: ${network_cookie_cookieBehavior !== 2 ? "#0074e8" : "#e31b5d"}; color: #ffffff; font-size: 10px; line-height: 10px; box-shadow: none; text-shadow: none; padding-block: 0 1px !important; padding-inline: 2px !important; min-width: 0 !important;`});
            }
        },
        uninit() {
            if (!this.initialised) return;
            Services.prefs.removeObserver(gpref, this);
            this.initialised = false;
        },
    };
    CustomizableUI.createWidget({
        id: id,
        type: "custom",
        label: label,
        tooltiptext: tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onBuild(document) {
            var win = document.defaultView, trbn = document.createXULElement("toolbarbutton");
            trbn.id = id;
            trbn.className = "toolbarbutton-1 chromeclass-toolbar-additional badged-button";
            trbn.setAttribute("badged", "true");
            trbn.setAttribute("constrain-size", "true");
            trbn.setAttribute("label", label);
            trbn.setAttribute("context", "false");
            trbn.setAttribute("tooltiptext", tooltiptext);
			trbn.setAttribute("image", img);
            var cookieBehavior = tbarbtns.network_cookie_cookieBehavior;
            if (cookieBehavior !== null) {
                trbn.setAttribute("badge", cookieBehavior);
                trbn.setAttribute("badgeStyle", `background: ${cookieBehavior !== 2 ? "#0074e8" : "#e31b5d"}; color: #ffffff; font-size: 10px; line-height: 10px; box-shadow: none; text-shadow: none; padding-block: 0 1px !important; padding-inline: 2px !important; min-width: 0 !important;`);
                trbn.addEventListener("click", e => {
                    if (e.button == 0)
                        tbarbtns.prefToggleNumber(gpref, [1,2,3,4,5,0]);
                    else if (e.button == 1) {
                        if (!win.gIdentityHandler?._uriHasHost || win.gIdentityHandler._pageExtensionPolicy)
                            return;
                        let baseDomain = win.SiteDataManager.getBaseDomainFromHost(win.gIdentityHandler._uri.host);
                        win.SiteDataManager.hasSiteData(baseDomain).then(hasData => {
                            if (hasData && win.SiteDataManager.promptSiteDataRemoval(win, [baseDomain]))
                                win.SiteDataManager.remove(baseDomain);
                        });
                    } else if (e.button == 2) {
                        e.preventDefault();
                        e.stopPropagation();
                        tbarbtns.viewCookies(win);
                    }
                });
            }
            var btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(`

                #${id} image {
                    --h: 16px;
                    height: var(--h); !important;
                    object-fit: cover !important;
                    object-position: top !important;
                }
                #${id}[badge="0"] image {
                    object-position: 0 calc(-1 * var(--h)) !important;
                }
                #${id}[badge="2"] {
                    fill: color-mix(in srgb, currentColor 20%, #e31b5d) !important;
                }
            `);
            try {
                win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET);
            } catch (e) {}
            tbarbtns.init();
            return trbn;
        },
        onDestroyed(doc) {
            tbarbtns.uninit();
        },
    });
})();} catch(e) {}

Отсутствует

 

№148423-04-2024 19:18:19

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

egorsemenov06

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

Выделить код

Код:

//Ссылки кликабельны
(async (
    id = "ucf-text-to-link",
    label = "Текст URL в кликабельные ссылки",
    tooltiptext = "Превратить текст URL в кликабельные ссылки",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='m5.6 10.4 4.8-4.8m-8.9 4.9c-2.6 2.6 1.4 6.6 4 4l1-1c2.6-2.6-1.4-6.6-4-4zm9-9c2.6-2.6 6.6 1.4 4 4l-1 1c-2.6 2.6-6.6-1.4-4-4z'/></svg>",

    texttolink = {
        _registerActor() {
            if (this.registerActor) return;
            ChromeUtils.registerWindowActor("UcfTextToLinkActor", {
                child: {
                    esModuleURI: "chrome://user_chrome_files/content/custom_scripts/UcfTextToLinkActorChild.mjs"
                },
                allFrames: true,
                messageManagerGroups: ["browsers"],
            });
            this.registerActor = true;
        },
        sendAsyncMessages(win, message, data) {
            this._registerActor();
            this.sendAsyncMessages = this._sendAsyncMessages;
            this.sendAsyncMessages(win, message, data);
        },
        _sendAsyncMessages(win, message, data) {
            var {browsingContext} = win.gBrowser.selectedBrowser;
            ({
                "UcfTextToLinkActor:TextToLink"() {
                    for (let actor of this)
                        actor.sendAsyncMessage(message);
                },
                *[Symbol.iterator]() {
                    var contextsToVisit = [browsingContext];
                    while (contextsToVisit.length) {
                        let currentContext = contextsToVisit.pop();
                        let global = currentContext?.currentWindowGlobal;
                        if (!global) continue;
                        yield global.getActor("UcfTextToLinkActor");
                        contextsToVisit.push(...currentContext.children);
                    }
                },
            })[message]?.();
        },
    }
) => { Services.io.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
    .setSubstitution(`${id}-img`, Services.io.newURI(img));
    CustomizableUI.createWidget({
        id,
        label,
        tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onCreated(btn) {
            btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important");
        },
        onCommand(e) {
            texttolink.sendAsyncMessages(e.view, "UcfTextToLinkActor:TextToLink");
        },
    });
})();


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

Выделить код

Код:

const lazy = {
    get excludedTags() {
        delete this.excludedTags;
        return this.excludedTags = new Set(["a","svg","canvas","applet","input","button","area","embed","noembed","frame","frameset","head","iframe","img","select","option","datalist","map","meta","noscript","video","audio","object","param","script","style","textarea","code"]);
    },
};
export class UcfTextToLinkActorChild extends JSWindowActorChild {
    receiveMessage(msg) {
        return ({
            "UcfTextToLinkActor:TextToLink": () => {
                this.textToLink();
            },
        })[msg.name]?.();
    }
    textToLink() {
        if (this.running || !this.document?.body)
            return;
        this.running = true;
        var url_regexp = /(^|[\s(,;'"`“\[\]=_])((?:(?:https?|ftp):\/\/[-\wа-яё.!~*'();,/?:@&=+$#%_\u2300-\u23FF\u2600-\u27BF]|www\d{0,3}[.][a-zа-яё0-9.-]{2,249}|[a-zа-яё0-9.-]{2,250}[.][a-zа-яё]{2,4}\/)[-\wа-яё.!~*'();,/?:@&=+$#%_\u2300-\u23FF\u2600-\u27BF]*)/gim;
        var email_regexp = /(^|mailto:|[\s(,;'"`“\[\]=])([\w!#$%&'*+/=?^`{|}~.-]{2,}@[\[\]a-z0-9.-]+)/gim;
        var elList = [];
        var setEmail = (node, text) => {
            var repl = text.replace(email_regexp, '$1<a href="mailto:$2" class="add__TextToEmail">$2</a>');
            if (text.length == repl.length)
                return;
            var span = node.ownerDocument.createElement("span");
            span["innerHTML"] = repl;
            node.replaceWith(span);
        };
        var setLink = (node, text) => {
            if (!(text = node.textContent)) return;
            text = text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
            var repl = text.replace(url_regexp, '$1<a href="$2" target="_blank" class="add__TextToLink">$2</a>');
            if (text.length == repl.length) {
                setEmail(node, text);
                return;
            }
            var span = node.ownerDocument.createElement("span");
            span["innerHTML"] = repl;
            for (let el of span.querySelectorAll("a.add__TextToLink[href]:not([href^='http']):not([href^='ftp'])"))
                el.setAttribute("href", `http://${el.getAttribute("href")}`);
            node.replaceWith(span);
            var txtnode = Node.TEXT_NODE;
            for (let child of span.childNodes) {
                let txt;
                if (child.nodeType === txtnode && (txt = child.textContent))
                    setEmail(child, txt);
            }
        };
        var getWalker = elem => {
            var doc = elem.ownerDocument, reject = NodeFilter.FILTER_REJECT, skip = NodeFilter.FILTER_SKIP, accept = NodeFilter.FILTER_ACCEPT, txtnode = Node.TEXT_NODE;
            var walker = doc.createTreeWalker(elem, NodeFilter.SHOW_ALL, {
                acceptNode(node) {
                    if (lazy.excludedTags.has(node.localName))
                        return reject;
                    if (node.nodeType !== txtnode && !node.shadowRoot)
                        return skip;
                    return accept;
                }
            }, false);
            while (walker.nextNode()) {
                let currnode = walker.currentNode;
                if (!currnode.shadowRoot)
                    elList.push(currnode);
                else
                    getWalker(currnode.shadowRoot);
            }
        };
        getWalker(this.document.body);
        for (let el of elList)
            setLink(el);
        elList = [];
        this.running = false;
    }
}


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

Выделить код

Код:

//Переключить Куки
(async (
    id = "ucf-cookie-toggle",
    label = "Переключить Куки",
    tooltiptext = "ЛКМ: Переключить Куки\nСКМ: Удалить куки домена текущей страницы\nПКМ: Управление куками",
    gpref = "network.cookie.cookieBehavior",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M12.5 10.5v-1h-1v1h1m-4-4h1v1h-1v-1m0 7h1v-1h-1v1m-6-7h1v1h-1v-1m4 4v-1h-1v1h1m-3 3v-1h-1m3-9h1v1h-1v-1M8 .6C8 5 11 8 15.4 8c0 4-3.4 7.4-7.4 7.4S.6 12 .6 8 4 .6 8 .6M12.5 26.5v-1h-1v1h1m-4-4h1v1h-1v-1m0 7h1v-1h-1v1m-6-7h1v1h-1v-1m4 4v-1h-1v1h1m-3 3v-1h-1m3-9h1v1m2-3.5v.5h1V17m2 2.5v1h1v-1h-1m3.5 3h-.5v1h.5m-8.5-3h-1v-1M8 16.6c4 0 7.4 3.4 7.4 7.4S12 31.4 8 31.4.6 28 .6 24 4 16.6 8 16.6'/></svg>",

    tbarbtns = {
        initialised: false,
        get network_cookie_cookieBehavior() {
            delete this.network_cookie_cookieBehavior;
            try {
                return this.network_cookie_cookieBehavior = Services.prefs.getIntPref(gpref);
            } catch(e) { }
            return this.network_cookie_cookieBehavior = null;
        },
        init() {
            if (this.initialised) return;
            this.initialised = true;
            Services.prefs.addObserver(gpref, this);
        },
        prefToggleNumber(pref, next) {
            Services.prefs.setIntPref(pref, next[Services.prefs.getIntPref(pref)]);
        },
        getETDL(uri) {
            var eTLD = "";
            try {
                eTLD = Services.eTLD.getBaseDomain(uri);
            } catch (e) {
                try {
                    eTLD = uri.asciiHost;
                } catch (e) {}
            }
            return eTLD;
        },
        async viewCookies(win) {
            var uri = win.gBrowser.selectedBrowser.currentURI;
            try {
                let _uri = win.ReaderMode.getOriginalUrl(uri.spec);
                if (_uri)
                    uri = Services.io.newURI(_uri);
            } catch(e) {}
            uri = this.getETDL(uri);
            var type = "Browser:SiteDataSettings", id = "SiteDataSettingsDialog";
            var _win = Services.wm.getMostRecentWindow(type);
            if (!_win) {
                await win.SiteDataManager.updateSites();
                let url = "chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml", {xulStore: xs} = Services;
                let sx = +xs.getValue(url, id, "screenX") || xs.setValue(url, id, "screenX", 1) || 1;
                let sy = +xs.getValue(url, id, "screenY") || xs.setValue(url, id, "screenY", 1) || 1;
                let wh = +xs.getValue(url, id, "width") || xs.setValue(url, id, "width", 600) || 600;
                let ht = +xs.getValue(url, id, "height") || xs.setValue(url, id, "height", 500) || 500;
                let sm = xs.getValue(url, id, "sizemode");
                let features = `chrome,dialog=no,resizable,${`screenX=${sx},screenY=${sy}`}${`,width=${wh},height=${ht}`}`;
                _win = win.openDialog(url, type, features);
                await new Promise(resolve => {
                    _win.windowRoot.addEventListener("DOMContentLoaded", () => {
                        _win.windowRoot.addEventListener("MozUpdateWindowPos", () => {
                            if (sm === "maximized")
                                _win.maximize();
                        }, { once: true, capture: true });
                        resolve();
                    }, { once: true });
                });
                let docEl = _win.document.documentElement;
                docEl.setAttribute("windowtype", type);
                docEl.id = id;
                docEl.setAttribute("persist", "screenX screenY width height sizemode");
            }
            _win.focus();
            var filter = _win.document.querySelector("#searchBox");
            if (!filter) return;
            filter.value = uri;
            filter.focus();
            filter.dispatchEvent(new _win.Event("input", { bubbles: true }));
        },
        callWithEachWindow(buttonID, atr) {
            var getW = CustomizableUI.getWidget(buttonID);
            if (getW.instances.length)
                for (let {node} of getW.instances) {
                    if (!node) continue;
                    for (let a in atr)
                        node.setAttribute(a, atr[a]);
                }
            else
                for (let win of CustomizableUI.windows) {
                    let node = getW.forWindow(win).node;
                    if (!node) continue;
                    for (let a in atr)
                        node.setAttribute(a, atr[a]);
                }
        },
        observe(subject, topic, pref) {
            if (pref == gpref) {
                delete this.network_cookie_cookieBehavior;
                let network_cookie_cookieBehavior = this.network_cookie_cookieBehavior = Services.prefs.getIntPref(pref);
                this.callWithEachWindow(id, {badge: network_cookie_cookieBehavior, badgeStyle: `background: ${network_cookie_cookieBehavior !== 2 ? "#0074e8" : "#e31b5d"}; color: #ffffff; font-size: 10px; line-height: 10px; box-shadow: none; text-shadow: none; padding-block: 0 1px !important; padding-inline: 2px !important; min-width: 0 !important;`});
            }
        },
        uninit() {
            if (!this.initialised) return;
            Services.prefs.removeObserver(gpref, this);
            this.initialised = false;
        },
    },
    protocolHandler = Services.io.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
) => { protocolHandler.setSubstitution(`${id}-img`, Services.io.newURI(img));
    protocolHandler.setSubstitution(`${id}-img-0`, Services.io.newURI(img.replace("viewBox='0 0 16 16'", "viewBox='0 16 16 16'")));
    CustomizableUI.createWidget({
        id,
        type: "custom",
        label,
        tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onBuild(document) {
            var win = document.defaultView, trbn = document.createXULElement("toolbarbutton");
            var props = {
                id,
                label,
                context: "",
                tooltiptext,
                class: "toolbarbutton-1 chromeclass-toolbar-additional badged-button",
                badged: "true",
                "constrain-size": "true",
            };
            for (let p in props)
                trbn.setAttribute(p, props[p]);
            var cookieBehavior = tbarbtns.network_cookie_cookieBehavior;
            if (cookieBehavior !== null) {
                trbn.setAttribute("badge", cookieBehavior);
                trbn.setAttribute("badgeStyle", `background: ${cookieBehavior !== 2 ? "#0074e8" : "#e31b5d"}; color: #ffffff; font-size: 10px; line-height: 10px; box-shadow: none; text-shadow: none; padding-block: 0 1px !important; padding-inline: 2px !important; min-width: 0 !important;`);
                trbn.addEventListener("click", e => {
                    if (e.button == 0)
                        tbarbtns.prefToggleNumber(gpref, [1,2,3,4,5,0]);
                    else if (e.button == 1) {
                        if (!win.gIdentityHandler?._uriHasHost || win.gIdentityHandler._pageExtensionPolicy)
                            return;
                        let baseDomain = win.SiteDataManager.getBaseDomainFromHost(win.gIdentityHandler._uri.host);
                        win.SiteDataManager.hasSiteData(baseDomain).then(hasData => {
                            if (hasData && win.SiteDataManager.promptSiteDataRemoval(win, [baseDomain]))
                                win.SiteDataManager.remove(baseDomain);
                        });
                    } else if (e.button == 2) {
                        e.preventDefault();
                        e.stopPropagation();
                        tbarbtns.viewCookies(win);
                    }
                });
            }
            var btnstyle = `data:text/css;charset=utf-8,${encodeURIComponent(`
                #${id} {
                    list-style-image: url("resource://${id}-img") !important;
                }
                #${id}[badge="0"] {
                    list-style-image: url("resource://${id}-img-0") !important;
                }
                #${id}[badge="2"] {
                    fill: color-mix(in srgb, currentColor 20%, #e31b5d) !important;
                }
            `)}`;
            try {
                win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET);
            } catch (e) {}
            tbarbtns.init();
            return trbn;
        },
        onDestroyed(doc) {
            tbarbtns.uninit();
        },
    });
})();

Отсутствует

 

№148523-04-2024 19:43:54

egorsemenov06
Участник
 
Группа: Members
Зарегистрирован: 12-06-2018
Сообщений: 407
UA: Firefox 125.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Vitaliy V. пишет

egorsemenov06

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

Выделить код

Код:

//Ссылки кликабельны
(async (
    id = "ucf-text-to-link",
    label = "Текст URL в кликабельные ссылки",
    tooltiptext = "Превратить текст URL в кликабельные ссылки",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='m5.6 10.4 4.8-4.8m-8.9 4.9c-2.6 2.6 1.4 6.6 4 4l1-1c2.6-2.6-1.4-6.6-4-4zm9-9c2.6-2.6 6.6 1.4 4 4l-1 1c-2.6 2.6-6.6-1.4-4-4z'/></svg>",

    texttolink = {
        _registerActor() {
            if (this.registerActor) return;
            ChromeUtils.registerWindowActor("UcfTextToLinkActor", {
                child: {
                    esModuleURI: "chrome://user_chrome_files/content/custom_scripts/UcfTextToLinkActorChild.mjs"
                },
                allFrames: true,
                messageManagerGroups: ["browsers"],
            });
            this.registerActor = true;
        },
        sendAsyncMessages(win, message, data) {
            this._registerActor();
            this.sendAsyncMessages = this._sendAsyncMessages;
            this.sendAsyncMessages(win, message, data);
        },
        _sendAsyncMessages(win, message, data) {
            var {browsingContext} = win.gBrowser.selectedBrowser;
            ({
                "UcfTextToLinkActor:TextToLink"() {
                    for (let actor of this)
                        actor.sendAsyncMessage(message);
                },
                *[Symbol.iterator]() {
                    var contextsToVisit = [browsingContext];
                    while (contextsToVisit.length) {
                        let currentContext = contextsToVisit.pop();
                        let global = currentContext?.currentWindowGlobal;
                        if (!global) continue;
                        yield global.getActor("UcfTextToLinkActor");
                        contextsToVisit.push(...currentContext.children);
                    }
                },
            })[message]?.();
        },
    }
) => { Services.io.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
    .setSubstitution(`${id}-img`, Services.io.newURI(img));
    CustomizableUI.createWidget({
        id,
        label,
        tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onCreated(btn) {
            btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important");
        },
        onCommand(e) {
            texttolink.sendAsyncMessages(e.view, "UcfTextToLinkActor:TextToLink");
        },
    });
})();


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

Выделить код

Код:

const lazy = {
    get excludedTags() {
        delete this.excludedTags;
        return this.excludedTags = new Set(["a","svg","canvas","applet","input","button","area","embed","noembed","frame","frameset","head","iframe","img","select","option","datalist","map","meta","noscript","video","audio","object","param","script","style","textarea","code"]);
    },
};
export class UcfTextToLinkActorChild extends JSWindowActorChild {
    receiveMessage(msg) {
        return ({
            "UcfTextToLinkActor:TextToLink": () => {
                this.textToLink();
            },
        })[msg.name]?.();
    }
    textToLink() {
        if (this.running || !this.document?.body)
            return;
        this.running = true;
        var url_regexp = /(^|[\s(,;'"`“\[\]=_])((?:(?:https?|ftp):\/\/[-\wа-яё.!~*'();,/?:@&=+$#%_\u2300-\u23FF\u2600-\u27BF]|www\d{0,3}[.][a-zа-яё0-9.-]{2,249}|[a-zа-яё0-9.-]{2,250}[.][a-zа-яё]{2,4}\/)[-\wа-яё.!~*'();,/?:@&=+$#%_\u2300-\u23FF\u2600-\u27BF]*)/gim;
        var email_regexp = /(^|mailto:|[\s(,;'"`“\[\]=])([\w!#$%&'*+/=?^`{|}~.-]{2,}@[\[\]a-z0-9.-]+)/gim;
        var elList = [];
        var setEmail = (node, text) => {
            var repl = text.replace(email_regexp, '$1<a href="mailto:$2" class="add__TextToEmail">$2</a>');
            if (text.length == repl.length)
                return;
            var span = node.ownerDocument.createElement("span");
            span["innerHTML"] = repl;
            node.replaceWith(span);
        };
        var setLink = (node, text) => {
            if (!(text = node.textContent)) return;
            text = text.replace(/</g, "&lt;").replace(/>/g, "&gt;");
            var repl = text.replace(url_regexp, '$1<a href="$2" target="_blank" class="add__TextToLink">$2</a>');
            if (text.length == repl.length) {
                setEmail(node, text);
                return;
            }
            var span = node.ownerDocument.createElement("span");
            span["innerHTML"] = repl;
            for (let el of span.querySelectorAll("a.add__TextToLink[href]:not([href^='http']):not([href^='ftp'])"))
                el.setAttribute("href", `http://${el.getAttribute("href")}`);
            node.replaceWith(span);
            var txtnode = Node.TEXT_NODE;
            for (let child of span.childNodes) {
                let txt;
                if (child.nodeType === txtnode && (txt = child.textContent))
                    setEmail(child, txt);
            }
        };
        var getWalker = elem => {
            var doc = elem.ownerDocument, reject = NodeFilter.FILTER_REJECT, skip = NodeFilter.FILTER_SKIP, accept = NodeFilter.FILTER_ACCEPT, txtnode = Node.TEXT_NODE;
            var walker = doc.createTreeWalker(elem, NodeFilter.SHOW_ALL, {
                acceptNode(node) {
                    if (lazy.excludedTags.has(node.localName))
                        return reject;
                    if (node.nodeType !== txtnode && !node.shadowRoot)
                        return skip;
                    return accept;
                }
            }, false);
            while (walker.nextNode()) {
                let currnode = walker.currentNode;
                if (!currnode.shadowRoot)
                    elList.push(currnode);
                else
                    getWalker(currnode.shadowRoot);
            }
        };
        getWalker(this.document.body);
        for (let el of elList)
            setLink(el);
        elList = [];
        this.running = false;
    }
}


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

Выделить код

Код:

//Переключить Куки
(async (
    id = "ucf-cookie-toggle",
    label = "Переключить Куки",
    tooltiptext = "ЛКМ: Переключить Куки\nСКМ: Удалить куки домена текущей страницы\nПКМ: Управление куками",
    gpref = "network.cookie.cookieBehavior",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M12.5 10.5v-1h-1v1h1m-4-4h1v1h-1v-1m0 7h1v-1h-1v1m-6-7h1v1h-1v-1m4 4v-1h-1v1h1m-3 3v-1h-1m3-9h1v1h-1v-1M8 .6C8 5 11 8 15.4 8c0 4-3.4 7.4-7.4 7.4S.6 12 .6 8 4 .6 8 .6M12.5 26.5v-1h-1v1h1m-4-4h1v1h-1v-1m0 7h1v-1h-1v1m-6-7h1v1h-1v-1m4 4v-1h-1v1h1m-3 3v-1h-1m3-9h1v1m2-3.5v.5h1V17m2 2.5v1h1v-1h-1m3.5 3h-.5v1h.5m-8.5-3h-1v-1M8 16.6c4 0 7.4 3.4 7.4 7.4S12 31.4 8 31.4.6 28 .6 24 4 16.6 8 16.6'/></svg>",

    tbarbtns = {
        initialised: false,
        get network_cookie_cookieBehavior() {
            delete this.network_cookie_cookieBehavior;
            try {
                return this.network_cookie_cookieBehavior = Services.prefs.getIntPref(gpref);
            } catch(e) { }
            return this.network_cookie_cookieBehavior = null;
        },
        init() {
            if (this.initialised) return;
            this.initialised = true;
            Services.prefs.addObserver(gpref, this);
        },
        prefToggleNumber(pref, next) {
            Services.prefs.setIntPref(pref, next[Services.prefs.getIntPref(pref)]);
        },
        getETDL(uri) {
            var eTLD = "";
            try {
                eTLD = Services.eTLD.getBaseDomain(uri);
            } catch (e) {
                try {
                    eTLD = uri.asciiHost;
                } catch (e) {}
            }
            return eTLD;
        },
        async viewCookies(win) {
            var uri = win.gBrowser.selectedBrowser.currentURI;
            try {
                let _uri = win.ReaderMode.getOriginalUrl(uri.spec);
                if (_uri)
                    uri = Services.io.newURI(_uri);
            } catch(e) {}
            uri = this.getETDL(uri);
            var type = "Browser:SiteDataSettings", id = "SiteDataSettingsDialog";
            var _win = Services.wm.getMostRecentWindow(type);
            if (!_win) {
                await win.SiteDataManager.updateSites();
                let url = "chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml", {xulStore: xs} = Services;
                let sx = +xs.getValue(url, id, "screenX") || xs.setValue(url, id, "screenX", 1) || 1;
                let sy = +xs.getValue(url, id, "screenY") || xs.setValue(url, id, "screenY", 1) || 1;
                let wh = +xs.getValue(url, id, "width") || xs.setValue(url, id, "width", 600) || 600;
                let ht = +xs.getValue(url, id, "height") || xs.setValue(url, id, "height", 500) || 500;
                let sm = xs.getValue(url, id, "sizemode");
                let features = `chrome,dialog=no,resizable,${`screenX=${sx},screenY=${sy}`}${`,width=${wh},height=${ht}`}`;
                _win = win.openDialog(url, type, features);
                await new Promise(resolve => {
                    _win.windowRoot.addEventListener("DOMContentLoaded", () => {
                        _win.windowRoot.addEventListener("MozUpdateWindowPos", () => {
                            if (sm === "maximized")
                                _win.maximize();
                        }, { once: true, capture: true });
                        resolve();
                    }, { once: true });
                });
                let docEl = _win.document.documentElement;
                docEl.setAttribute("windowtype", type);
                docEl.id = id;
                docEl.setAttribute("persist", "screenX screenY width height sizemode");
            }
            _win.focus();
            var filter = _win.document.querySelector("#searchBox");
            if (!filter) return;
            filter.value = uri;
            filter.focus();
            filter.dispatchEvent(new _win.Event("input", { bubbles: true }));
        },
        callWithEachWindow(buttonID, atr) {
            var getW = CustomizableUI.getWidget(buttonID);
            if (getW.instances.length)
                for (let {node} of getW.instances) {
                    if (!node) continue;
                    for (let a in atr)
                        node.setAttribute(a, atr[a]);
                }
            else
                for (let win of CustomizableUI.windows) {
                    let node = getW.forWindow(win).node;
                    if (!node) continue;
                    for (let a in atr)
                        node.setAttribute(a, atr[a]);
                }
        },
        observe(subject, topic, pref) {
            if (pref == gpref) {
                delete this.network_cookie_cookieBehavior;
                let network_cookie_cookieBehavior = this.network_cookie_cookieBehavior = Services.prefs.getIntPref(pref);
                this.callWithEachWindow(id, {badge: network_cookie_cookieBehavior, badgeStyle: `background: ${network_cookie_cookieBehavior !== 2 ? "#0074e8" : "#e31b5d"}; color: #ffffff; font-size: 10px; line-height: 10px; box-shadow: none; text-shadow: none; padding-block: 0 1px !important; padding-inline: 2px !important; min-width: 0 !important;`});
            }
        },
        uninit() {
            if (!this.initialised) return;
            Services.prefs.removeObserver(gpref, this);
            this.initialised = false;
        },
    },
    protocolHandler = Services.io.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
) => { protocolHandler.setSubstitution(`${id}-img`, Services.io.newURI(img));
    protocolHandler.setSubstitution(`${id}-img-0`, Services.io.newURI(img.replace("viewBox='0 0 16 16'", "viewBox='0 16 16 16'")));
    CustomizableUI.createWidget({
        id,
        type: "custom",
        label,
        tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onBuild(document) {
            var win = document.defaultView, trbn = document.createXULElement("toolbarbutton");
            var props = {
                id,
                label,
                context: "",
                tooltiptext,
                class: "toolbarbutton-1 chromeclass-toolbar-additional badged-button",
                badged: "true",
                "constrain-size": "true",
            };
            for (let p in props)
                trbn.setAttribute(p, props[p]);
            var cookieBehavior = tbarbtns.network_cookie_cookieBehavior;
            if (cookieBehavior !== null) {
                trbn.setAttribute("badge", cookieBehavior);
                trbn.setAttribute("badgeStyle", `background: ${cookieBehavior !== 2 ? "#0074e8" : "#e31b5d"}; color: #ffffff; font-size: 10px; line-height: 10px; box-shadow: none; text-shadow: none; padding-block: 0 1px !important; padding-inline: 2px !important; min-width: 0 !important;`);
                trbn.addEventListener("click", e => {
                    if (e.button == 0)
                        tbarbtns.prefToggleNumber(gpref, [1,2,3,4,5,0]);
                    else if (e.button == 1) {
                        if (!win.gIdentityHandler?._uriHasHost || win.gIdentityHandler._pageExtensionPolicy)
                            return;
                        let baseDomain = win.SiteDataManager.getBaseDomainFromHost(win.gIdentityHandler._uri.host);
                        win.SiteDataManager.hasSiteData(baseDomain).then(hasData => {
                            if (hasData && win.SiteDataManager.promptSiteDataRemoval(win, [baseDomain]))
                                win.SiteDataManager.remove(baseDomain);
                        });
                    } else if (e.button == 2) {
                        e.preventDefault();
                        e.stopPropagation();
                        tbarbtns.viewCookies(win);
                    }
                });
            }
            var btnstyle = `data:text/css;charset=utf-8,${encodeURIComponent(`
                #${id} {
                    list-style-image: url("resource://${id}-img") !important;
                }
                #${id}[badge="0"] {
                    list-style-image: url("resource://${id}-img-0") !important;
                }
                #${id}[badge="2"] {
                    fill: color-mix(in srgb, currentColor 20%, #e31b5d) !important;
                }
            `)}`;
            try {
                win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET);
            } catch (e) {}
            tbarbtns.init();
            return trbn;
        },
        onDestroyed(doc) {
            tbarbtns.uninit();
        },
    });
})();

Огромное СПАСИБО!!!!!

Отсутствует

 

№148624-04-2024 00:32:29

b0ttle
Участник
 
Группа: Members
Зарегистрирован: 22-10-2020
Сообщений: 182
UA: Firefox 124.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Vitaliy V.
Просто пожелание, ATB все время обновляется, а что обновляется не ясно. Стоит качать или нет, не понятно. Может changelog? Хотя, его наверно не все поймут. Сейчас дошло, что можно скачивать и в распакованном виде сравнить с предыдущим) Но changelog, если будет понятный, то наверно было бы неплохо. Если никто не поймет, то ладно.

Отсутствует

 

№148724-04-2024 01:44:20

b0ttle
Участник
 
Группа: Members
Зарегистрирован: 22-10-2020
Сообщений: 182
UA: Firefox 124.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Нечаянно забрел, и увидел такое. С каких пор в путях можно прописывать %ProfD%\\..\\..\\? Возможно у него это реализовано в самом Handy_Clicks?

Отсутствует

 

№148824-04-2024 02:51:01

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

b0ttle
Это переменные среды, они в системе настраиваются. Написано же (example).

Отсутствует

 

№148924-04-2024 08:10:02

egorsemenov06
Участник
 
Группа: Members
Зарегистрирован: 12-06-2018
Сообщений: 407
UA: Firefox 125.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Vitaliy V. Можно еще пару кнопок обновить пожалуйста

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

Выделить код

Код:

//about_config..........................................
try {
    ((id, label, tooltiptext, about_config) => {
        CustomizableUI.createWidget({
            id: id,
            type: "custom",
            label: label,
            tooltiptext: tooltiptext,
            localized: false,
            defaultArea: CustomizableUI.AREA_NAVBAR,
            onBuild: function(document) {
                var win = document.defaultView;
                var toolbarbutton = document.createXULElement("toolbarbutton");
                toolbarbutton.id = id;
                toolbarbutton.className = "toolbarbutton-1 chromeclass-toolbar-additional";
                toolbarbutton.setAttribute("label", label);
                toolbarbutton.setAttribute("context", "false");
                toolbarbutton.setAttribute("tooltiptext", tooltiptext);
                toolbarbutton.setAttribute("image", "data:image/svg+xml;charset=utf-8;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+PGltYWdlIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgaHJlZj0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFCQUFBQUFRQ0FNQUFBQW9MUTlUQUFBQUJHZEJUVUVBQUxHUEMveGhCUUFBQUNCalNGSk4gQUFCNkpnQUFnSVFBQVBvQUFBQ0E2QUFBZFRBQUFPcGdBQUE2bUFBQUYzQ2N1bEU4QUFBQzRsQk1WRVVhR2hvaUlpSWVIaDRqSXlNciBLeXVIaFliRnhNUXpMekFrSXlNUkVCQnBaMmVtcEtUdzhQQ3RxcXFJaFlablpHYWJtWm9jSEJ5bW82TnJaMmVYbFpiMjl2WUFBQUNtIG9xSnJiWEdrb3FNZkh4ODdORFpBYnBlOHU3dENPejFGVEVpMnVMbTN0N2k2dTd6Mjl2Y2ZIeDRxWTQ5L05WTzR0TE84dDdiZERRM2MgUHpEZVNEcmtMeDdpT0NjQUFBTGtNQ0FlSEJvOFdJbTlFQkhtTGl2eDdlZ2FXNVFQT0Y4ckFBQXRLaWI4L1B5VWs1TXlNREYwY25PYSBtWm5QejgvZDNOek15OHVSa1pIdjcrOWxaR1JMUjBoVVUxTitmSDIvdnI2SGhvYU1pWW1Wa3BOTlRVMnFxS202dDdlenNMQjJjM1czIHRiYTF0TFNOaTR1bXBLU1lscGYzOS9jSkNBbWxvYUswc2JHZm5KMTFjbkhMeTh5OHU3eXdyNitVa3BNaUlpSStPRHFvcEtXMXNySmQgWFYvTXhzR1BqbzZ0cTZ5cXFLa0FBQUJFUFQrbG9hTyt0ck1QVTZ1MHFhU1psWmE3dUxpL3ZyN0F2NzgvT1R0RE96MmNwS2liamFjaiBXOEF0VjN1YnBhYzBYb0ErYlpSdlpZZVdQbEtjS2ltemQzYTVzSzhBQUFBeFpwQThkNlVxYnJ6QUtDRGVjblhETUN6RUJ3TFlFZ3ZiIE95d2ZIeDhBQUFBelpvMUpmYnBpVG9HbUVRK2lEUTNMSEJiZ0xSdjI5L2NmSHg4NmJxb2FXY01zZHRBbVQ0Nm1CUVdsR1JuaGIyK1kgRGczUExTSGdPaXoxOXZjU09Xd1JUTGt5Yzg0VFZwNmpGUlRrZUhpYURnN1hJaDgzVzRrTVE3QVpWYVFnTWxHSUV4R3ZFaEtiRUJEaCBkbmFtRUJEY0t5ckcyUFFZVDZrZFQ1a1VUNlFFRHhrQUFBRnpBZ0tkRUJEZmJHdlhMaTZJbGJFS1BKRTBiclVSUG93SEZDQUVBZ0VGIEF3SUlDQWdJQndjQUJ3Y0VCQVFxQlFWb0R3L2RjSENGTVRFTUdqVVVLbFVVRWhFV0V3NFdGeGdYR0JnWEZ4Y1pGeGNYRmhZT0ZoWU4gRmhaR0ZSVTJGeGNKRXhQdDdPeSt2YjM3Ky92cjYrdkJ3TUNPalkvaDRPQjJqN3FHTkZYdmVYVFpSajFWSzJFTE9xRWFacy9aWUdIQiBRa01TUDZiRFFrSVFRcTJtSUNERVJFUWFXc2N3ZE5PcUlpSXllZUd4SHgvRFBqNnJIQnovLy84RVlVVjJBQUFBMlhSU1RsTUFBQUFBIEFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFCb2lnSUIgUHJUbWJBSTZpUVlDTmZoK0VCUXk1R0lGQkkvK2RNSnFBeDdrWVFVRXN2ZmREd1FmNUdFUzVmeEZBd01lNW1PdythbDdLd0lESDhUTSA5VWdDQVFPdnB3Y0hBUUlCQkxQNi92NXlBUUlCQVFPdnlkZTlJUU1CQXFiOTZoY3crdnZ0T1FNRGxQbitSbjMxN1NoODltOEZBUU82IDlzd0xTTkt6bFFJQkRMbjNoRXZYemNBSERBNE5EUThKQ0p6eVAyYVJPa0pOVFUxTlRrVXdkMUVCN0hFdHV3QUFBQUZpUzBkRTlVWFMgRzlzQUFBQUpjRWhaY3dBQUN4SUFBQXNTQWRMZGZ2d0FBQUFIZEVsTlJRZmtBeFlYSmdKSGF0WmFBQUFCRzBsRVFWUVkwd0VRQWUvKyBBRGs2QURzQkFnTUVQQVU5UGo5QUJrRUFRdGxEQjBRSUNVVUtSa2ZhU0VsS0N3QU1TMHhORFU0T1R3OVEyMUZTVTFRUUFGVVJWbGRZIEVsbGFFMXZjWE4xZFhoUUFGVjhXWUdGaUZ4aGpaTjVsMzJZWlp3QVZHbWdiYVdwckhHemdiVzV2Y0IxeEFCVWFGbkllYzNSMTRYWjMgSDNnZ0lTSUFJeVFXZVhvbGUrTGpmQ1o5Zm44bktBQWpKSUNCZ29Qa2hJV0doeW1JaVNvckFDT0tpNHlONWVhT2orZm9rSkVza2kwQSBrNVF1bGVtV2w1aVptcHZxbkowdm5nQ2ZNS0Ryb2FLak1US2s3S1h0cHFjekFEU283cW52cWpXcnJLMnU4Sy9xc0xFQXNyTzA4YlUyIHRoYTNON2k1OHJyenV3Qzh2YjYvd01IQ3c4VEZ4c2ZJOU1uS0FEakx6TTNPejlEUjBkTFQxTlhXMTlqMkVuZHVKeExhcXdBQUFDVjAgUlZoMFpHRjBaVHBqY21WaGRHVUFNakF5TUMwd015MHlNbFF5TXpvek9Eb3dNaXN3TURvd01MMVl5a0FBQUFBbGRFVllkR1JoZEdVNiBiVzlrYVdaNUFESXdNakF0TURNdE1qSlVNak02TXpnNk1ESXJNREE2TURETUJYTDhBQUFBQUVsRlRrU3VRbUNDIi8+PC9zdmc+");
                toolbarbutton.addEventListener("click", function(event) {
                    if (event.button == 0)
                        win.gBrowser.selectedTab = about_config.addTab(win, "about:config",  {
                            relatedToCurrent: true,
                        });
                    else if (event.button == 1)
                        about_config.openSelectedConfigTab(win);
                    else if (event.button == 2) {
                        event.preventDefault();
                        event.stopPropagation();
                        win.gBrowser.selectedTab = about_config.addTab(win, "about:about",  {
                            relatedToCurrent: true,
                        });
                    }
                });
                return toolbarbutton;
            }
        });
    })(
        "ucf-open-about-config",
        "about:config",
        "ЛКМ: Открыть about:config\nСКМ: Искать выделенное в about:config\nПКМ: Открыть about:about",
        {
            get ClipboardHelper() {
                delete this.ClipboardHelper;
                return this.ClipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
            },
            openClipboardConfigTab: function(win, clip = "", copy) {
                var filter = this.readFromClipboard(win), nowarn = false, pref = "browser.aboutConfig.showWarning";
                if (copy && clip != filter)
                    this.ClipboardHelper.copyString(clip);
                if (Services.prefs.getBoolPref(pref, false)) {
                    Services.prefs.setBoolPref(pref, false);
                    nowarn = true;
                }
                var browser = win.gBrowser.getBrowserForTab(win.gBrowser.selectedTab = this.addTab(win, "about:config", {
                    relatedToCurrent: true,
                }));
                browser.addEventListener("pageshow", (e) => {
                    var doc = e.currentTarget.contentDocument, input = (doc && doc.querySelector("input#about-config-search"));
                    if (input && filter) {
                        input.value = filter;
                        input.dispatchEvent(new doc.defaultView.Event("input", { bubbles: true }));
                    }
                    if (nowarn)
                        setTimeout(() => {
                            Services.prefs.setBoolPref(pref, true);
                        }, 200);
                }, { once: true });
            },
            openSelectedConfigTab: function(win) {
                var clip = this.readFromClipboard(win);
                win.goDoCommand("cmd_copy");
                setTimeout(() => {
                    this.openClipboardConfigTab(win, clip, true);
                }, 100);
            },
            addTab: function(win, url, params = {}) {
                params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
                return win.gBrowser.addTab(url, params);
            },
    readFromClipboard() {
        var {getData, kGlobalClipboard: kGK} = Services.clipboard;
        var flavor = `text/${parseInt(Services.appinfo.platformVersion) >= 111 ? "plain" : "unicode"}`;
        var transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
        transferable.init(null);
        transferable.addDataFlavor(flavor);

        return (this.readFromClipboard = () => {
            try {
                getData(transferable, kGK);
                var out = {};
                transferable.getTransferData(flavor, out);
                var url = out.value.QueryInterface(Ci.nsISupportsString).data;
            }
            finally {
                transferable.setTransferData(flavor, null);
                return url || "";
            }
        })();
    },
        }
    );
} catch(e) {}

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

Выделить код

Код:

//Очистить историю
try {
    ((img, preventClearThumbs) => {
        CustomizableUI.createWidget({
            id: "bt-clear-history",
            label: "Очистить историю",
            tooltiptext: "Очистить историю",
            defaultArea: CustomizableUI.AREA_NAVBAR,
            onCreated: function(bt) {
            var subst = this.id + "-svg-image";
            Services.io.getProtocolHandler("resource")
                .QueryInterface(Ci.nsIResProtocolHandler)
                .setSubstitution(subst, Services.io.newURI(img));
            var url = `resource://${subst}/`;
            (this.onCreated = btn => btn.image = url)(bt);
			},
            onCommand: function(event) {
                var win = event.target.ownerDocument.defaultView;
                var itemsToClear = [
                    "history",
					"sessions",
                    "formdata",					
                    "cache",
		            "downloads",
                    "offlineApps",
                    "pluginData"			
                ];
                var range = win.Sanitizer.getClearRange(0);
                win.Sanitizer.sanitize(itemsToClear, {
                    ignoreTimespan: !range,
                    range,
                }).then(() => {
                    var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
                    alertsService.showAlertNotification(img, "История Очищена!", "", false);
                    win.setTimeout(()=> alertsService.closeAlert(), 2000);
                });
            }
        });
    })("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M5.5.7c1.1 0 1.1 1.6 0 1.6S4.4.7 5.5.7zm8.3.5L9.5 5.5s-1.24.1-2.68.12C5.18 7.15 4.12 7.66.822 8.01v1.2C3.35 13.3 4.97 15.2 9.21 15.2h1.09c1.4-1.7 2-2.9 2.5-4.9V9.21c-.5-1.19-1.6-2.41-1.6-2.41l4.1-4.1zm-10.3 2c1.7 0 1.7 2.6 0 2.6s-1.7-2.6 0-2.6z'/></svg>", null);
} catch(e) {}

Отсутствует

 

№149024-04-2024 09:19:19

fuchsfan
Участник
 
Группа: Members
Зарегистрирован: 07-08-2023
Сообщений: 110
UA: Firefox 125.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Скрипт "Переключить куки" под третим спойлером https://forum.mozilla-russia.org/viewto … 11#p809311 , по ЛКМ пять опций, опишите, плиз, их назначение.

Отсутствует

 

№149124-04-2024 09:28:51

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

b0ttle пишет

Нечаянно забрел, и увидел такое. С каких пор в путях можно прописывать %ProfD%\\..\\..\\? Возможно у него это реализовано в самом Handy_Clicks?

Это обычный массив, который обрабатывает расширение Handy_Clicks
для Handy_Clicks это %ProfD%\\..\\..\\ а для [firefox] получиться Services.dirsvc.get("ProfD", Ci.nsIFile).parent.parent.path;


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

Отсутствует

 

№149224-04-2024 10:37:33

egorsemenov06
Участник
 
Группа: Members
Зарегистрирован: 12-06-2018
Сообщений: 407
UA: Firefox 125.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

fuchsfan пишет

Скрипт "Переключить куки" под третим спойлером https://forum.mozilla-russia.org/viewto … 11#p809311 , по ЛКМ пять опций, опишите, плиз, их назначение.

скрытый текст
95b38b938415eb85852e954bf1297975.png
нажимайте кнопку и следите за именениями в настройках

Отсутствует

 

№149324-04-2024 11:13:37

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

fuchsfan
Это исключительно для персональной схемы защиты от отслеживания about:preferences#privacy или browser.contentblocking.category = custom, в других схемах переключение не работает.
Интересен только один пункт "Блокировать межсайтовые отслеживающие куки, а другие изолировать" или network.cookie.cookieBehavior = 5, этот режим включает изоляцию кук друг от друга.
В строгой схеме защиты он включен по умолчанию.
Основная межсайтовая регистрация остается доступной, а если кажется, что работа сайта нарушена, то читаем
   
Остальные пункты и так понятны. Они или превращают браузер в решето, или ломают сайты, или создают проблемы с межсайтовой регистрацией.

Добавлено 24-04-2024 11:30:08
Кстати, должно быть не 5, а 6, видимо network.cookie.cookieBehavior = 0 нет. Что аналогично снятой галке в настройках.

Отредактировано _zt (24-04-2024 11:30:08)

Отсутствует

 

№149424-04-2024 16:46:34

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

egorsemenov06 пишет

Можно еще пару кнопок обновить

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

Выделить код

Код:

//about_config..........................................
(async (
    id = "ucf-open-about-config",
    label = "about:config",
    tooltiptext = "ЛКМ: Открыть about:config\nСКМ: Искать выделенное в about:config\nПКМ: Открыть about:about",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;'><path d='m 8.66,15.4 h -1.2 c -0.69,0 -1.3,-0.5 -1.5,-1.2 L 5.58,13 C 5.32,12.9 5.07,12.7 4.82,12.5 L 3.41,12.9 C 2.76,13 2.04,12.8 1.69,12.1 L 1.09,11.2 C 0.748,10.5 0.838,9.75 1.31,9.33 l 1,-1 V 7.52 L 1.32,6.55 C 0.842,6.06 0.748,5.36 1.1,4.78 L 1.7,3.8 C 2.04,3.22 2.75,2.93 3.4,3.08 L 4.84,3.4 C 5.1,3.24 5.34,3.1 5.58,2.99 L 5.96,1.72 C 6.16,1.08 6.77,0.631 7.46,0.629 h 1.2 C 9.35,0.629 9.94,1.07 10,1.7 L 10.4,3 c 0.3,0.11 0.5,0.25 0.8,0.4 L 12.5,3.08 C 13.2,2.93 14,3.22 14.3,3.8 l 0.6,0.98 c 0.4,0.57 0.3,1.28 -0.2,1.77 l -1,0.97 v 0.81 l 1,1 c 0.5,0.42 0.6,1.17 0.2,1.87 l -0.6,0.9 C 14,12.8 13.2,13 12.5,12.9 l -1.3,-0.4 c -0.3,0.2 -0.5,0.4 -0.8,0.5 L 10,14.2 c -0.1,0.7 -0.64,1.2 -1.34,1.2 z'/><circle cx='8' cy='8' r='2.4'/></g></svg>",

    about_config = {
        get clipboardHelp() {
            delete this.clipboardHelp;
            return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
        },
        openClipboardConfigTab(win, clip = "", copy) {
            var filter = this.readFromClipboard(win), nowarn = false, pref = "browser.aboutConfig.showWarning";
            if (copy && clip != filter)
                this.clipboardHelp.copyString(clip);
            if (Services.prefs.getBoolPref(pref, false)) {
                Services.prefs.setBoolPref(pref, false);
                nowarn = true;
            }
            win.gBrowser.getBrowserForTab(win.gBrowser.selectedTab = this.addTab(win, "about:config"))
            .addEventListener("pageshow", e => {
                var doc = e.target;
                var input = doc?.querySelector("input#about-config-search");
                if (input && filter) {
                    input.value = filter;
                    input.focus();
                    input.dispatchEvent(new doc.defaultView.Event("input", { bubbles: true }));
                }
                if (nowarn)
                    win.setTimeout(() => {
                        Services.prefs.setBoolPref(pref, true);
                    }, 200);
            }, { once: true });
        },
        openSelectedConfigTab(win) {
            var clip = this.readFromClipboard(win);
            win.goDoCommand("cmd_copy");
            win.setTimeout(() => {
                this.openClipboardConfigTab(win, clip, true);
            }, 100);
        },
        addTab(win, url, params = {}) {
            params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
            params.index = win.gBrowser.selectedTab._tPos + 1;
            return win.gBrowser.addTab(url, params);
        },
        readFromClipboard(win) {
            var url = "";
            try {
                let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
                trans.init(win.docShell.QueryInterface(Ci.nsILoadContext));
                trans.addDataFlavor("text/plain");
                let {clipboard} = Services;
                clipboard.getData(trans, clipboard.kGlobalClipboard);
                let data = {};
                trans.getTransferData("text/plain", data);
                if (data.value)
                    url = data.value.QueryInterface(Ci.nsISupportsString).data;
            } catch (ex) {}
            return url;
        },
    }
) => { Services.io.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
    .setSubstitution(`${id}-img`, Services.io.newURI(img));
    CustomizableUI.createWidget({
        id,
        type: "custom",
        label,
        tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onBuild: function(doc) {
            var btn = doc.createXULElement("toolbarbutton");
            var props = {
                id,
                label,
                context: "",
                tooltiptext,
                class: "toolbarbutton-1 chromeclass-toolbar-additional",
            };
            for (let p in props)
                btn.setAttribute(p, props[p]);
            btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important");
            btn.addEventListener("click", e => {
                var win = e.view;
                if (e.button == 0)
                    win.gBrowser.selectedTab = about_config.addTab(win, "about:config");
                else if (e.button == 1)
                    about_config.openSelectedConfigTab(win);
                else if (e.button == 2) {
                    e.preventDefault();
                    e.stopPropagation();
                    win.gBrowser.selectedTab = about_config.addTab(win, "about:about");
                }
            });
            return btn;
        },
    });
})();


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

Выделить код

Код:

//Очистить историю
(async (
    id = "ucf-clear-history",
    label = "Очистить историю",
    tooltiptext = "Очистить историю",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M5.5.7c1.1 0 1.1 1.6 0 1.6S4.4.7 5.5.7zm8.3.5L9.5 5.5s-1.24.1-2.68.12C5.18 7.15 4.12 7.66.822 8.01v1.2C3.35 13.3 4.97 15.2 9.21 15.2h1.09c1.4-1.7 2-2.9 2.5-4.9V9.21c-.5-1.19-1.6-2.41-1.6-2.41l4.1-4.1zm-10.3 2c1.7 0 1.7 2.6 0 2.6s-1.7-2.6 0-2.6z'/></svg>",
) => { Services.io.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
    .setSubstitution(`${id}-img`, Services.io.newURI(img));
    CustomizableUI.createWidget({
        id,
        label,
        tooltiptext,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onCreated(btn) {
            btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important");
        },
        onCommand(e) {
            var win = e.view;
            var itemsToClear = [
                "history",
                "sessions",
                "formdata",
                "cache",
                "downloads",
                "offlineApps",
                "pluginData"
            ];
            var range = win.Sanitizer.getClearRange(0);
            win.Sanitizer.sanitize(itemsToClear, {
                ignoreTimespan: !range,
                range,
            }).then(() => {
                var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
                alertsService.showAlertNotification(null, "История Очищена!", "", false);
                win.setTimeout(()=> alertsService.closeAlert(), 2000);
            });
        },
    });
})();

_zt пишет

Кстати, должно быть не 5, а 6, видимо network.cookie.cookieBehavior = 0 нет.

Где нет? В кнопке есть network.cookie.cookieBehavior = 0,
номер на значке toolbarbutton-badge соответствует настройке в about:config

Отредактировано Vitaliy V. (24-04-2024 16:51:06)

Отсутствует

 

№149524-04-2024 17:09:58

fuchsfan
Участник
 
Группа: Members
Зарегистрирован: 07-08-2023
Сообщений: 110
UA: Firefox 125.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Парни, спасибо за разъяснения, все понял.

Отсутствует

 

№149624-04-2024 17:21:19

egorsemenov06
Участник
 
Группа: Members
Зарегистрирован: 12-06-2018
Сообщений: 407
UA: Firefox 125.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Vitaliy V. пишет
egorsemenov06 пишет

Можно еще пару кнопок обновить

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

Выделить код

Код:

//about_config..........................................
(async (
    id = "ucf-open-about-config",
    label = "about:config",
    tooltiptext = "ЛКМ: Открыть about:config\nСКМ: Искать выделенное в about:config\nПКМ: Открыть about:about",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;'><path d='m 8.66,15.4 h -1.2 c -0.69,0 -1.3,-0.5 -1.5,-1.2 L 5.58,13 C 5.32,12.9 5.07,12.7 4.82,12.5 L 3.41,12.9 C 2.76,13 2.04,12.8 1.69,12.1 L 1.09,11.2 C 0.748,10.5 0.838,9.75 1.31,9.33 l 1,-1 V 7.52 L 1.32,6.55 C 0.842,6.06 0.748,5.36 1.1,4.78 L 1.7,3.8 C 2.04,3.22 2.75,2.93 3.4,3.08 L 4.84,3.4 C 5.1,3.24 5.34,3.1 5.58,2.99 L 5.96,1.72 C 6.16,1.08 6.77,0.631 7.46,0.629 h 1.2 C 9.35,0.629 9.94,1.07 10,1.7 L 10.4,3 c 0.3,0.11 0.5,0.25 0.8,0.4 L 12.5,3.08 C 13.2,2.93 14,3.22 14.3,3.8 l 0.6,0.98 c 0.4,0.57 0.3,1.28 -0.2,1.77 l -1,0.97 v 0.81 l 1,1 c 0.5,0.42 0.6,1.17 0.2,1.87 l -0.6,0.9 C 14,12.8 13.2,13 12.5,12.9 l -1.3,-0.4 c -0.3,0.2 -0.5,0.4 -0.8,0.5 L 10,14.2 c -0.1,0.7 -0.64,1.2 -1.34,1.2 z'/><circle cx='8' cy='8' r='2.4'/></g></svg>",

    about_config = {
        get clipboardHelp() {
            delete this.clipboardHelp;
            return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
        },
        openClipboardConfigTab(win, clip = "", copy) {
            var filter = this.readFromClipboard(win), nowarn = false, pref = "browser.aboutConfig.showWarning";
            if (copy && clip != filter)
                this.clipboardHelp.copyString(clip);
            if (Services.prefs.getBoolPref(pref, false)) {
                Services.prefs.setBoolPref(pref, false);
                nowarn = true;
            }
            win.gBrowser.getBrowserForTab(win.gBrowser.selectedTab = this.addTab(win, "about:config"))
            .addEventListener("pageshow", e => {
                var doc = e.target;
                var input = doc?.querySelector("input#about-config-search");
                if (input && filter) {
                    input.value = filter;
                    input.focus();
                    input.dispatchEvent(new doc.defaultView.Event("input", { bubbles: true }));
                }
                if (nowarn)
                    win.setTimeout(() => {
                        Services.prefs.setBoolPref(pref, true);
                    }, 200);
            }, { once: true });
        },
        openSelectedConfigTab(win) {
            var clip = this.readFromClipboard(win);
            win.goDoCommand("cmd_copy");
            win.setTimeout(() => {
                this.openClipboardConfigTab(win, clip, true);
            }, 100);
        },
        addTab(win, url, params = {}) {
            params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
            params.index = win.gBrowser.selectedTab._tPos + 1;
            return win.gBrowser.addTab(url, params);
        },
        readFromClipboard(win) {
            var url = "";
            try {
                let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
                trans.init(win.docShell.QueryInterface(Ci.nsILoadContext));
                trans.addDataFlavor("text/plain");
                let {clipboard} = Services;
                clipboard.getData(trans, clipboard.kGlobalClipboard);
                let data = {};
                trans.getTransferData("text/plain", data);
                if (data.value)
                    url = data.value.QueryInterface(Ci.nsISupportsString).data;
            } catch (ex) {}
            return url;
        },
    }
) => { Services.io.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
    .setSubstitution(`${id}-img`, Services.io.newURI(img));
    CustomizableUI.createWidget({
        id,
        type: "custom",
        label,
        tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onBuild: function(doc) {
            var btn = doc.createXULElement("toolbarbutton");
            var props = {
                id,
                label,
                context: "",
                tooltiptext,
                class: "toolbarbutton-1 chromeclass-toolbar-additional",
            };
            for (let p in props)
                btn.setAttribute(p, props[p]);
            btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important");
            btn.addEventListener("click", e => {
                var win = e.view;
                if (e.button == 0)
                    win.gBrowser.selectedTab = about_config.addTab(win, "about:config");
                else if (e.button == 1)
                    about_config.openSelectedConfigTab(win);
                else if (e.button == 2) {
                    e.preventDefault();
                    e.stopPropagation();
                    win.gBrowser.selectedTab = about_config.addTab(win, "about:about");
                }
            });
            return btn;
        },
    });
})();


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

Выделить код

Код:

//Очистить историю
(async (
    id = "ucf-clear-history",
    label = "Очистить историю",
    tooltiptext = "Очистить историю",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M5.5.7c1.1 0 1.1 1.6 0 1.6S4.4.7 5.5.7zm8.3.5L9.5 5.5s-1.24.1-2.68.12C5.18 7.15 4.12 7.66.822 8.01v1.2C3.35 13.3 4.97 15.2 9.21 15.2h1.09c1.4-1.7 2-2.9 2.5-4.9V9.21c-.5-1.19-1.6-2.41-1.6-2.41l4.1-4.1zm-10.3 2c1.7 0 1.7 2.6 0 2.6s-1.7-2.6 0-2.6z'/></svg>",
) => { Services.io.getProtocolHandler("resource")
    .QueryInterface(Ci.nsIResProtocolHandler)
    .setSubstitution(`${id}-img`, Services.io.newURI(img));
    CustomizableUI.createWidget({
        id,
        label,
        tooltiptext,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onCreated(btn) {
            btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important");
        },
        onCommand(e) {
            var win = e.view;
            var itemsToClear = [
                "history",
                "sessions",
                "formdata",
                "cache",
                "downloads",
                "offlineApps",
                "pluginData"
            ];
            var range = win.Sanitizer.getClearRange(0);
            win.Sanitizer.sanitize(itemsToClear, {
                ignoreTimespan: !range,
                range,
            }).then(() => {
                var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
                alertsService.showAlertNotification(null, "История Очищена!", "", false);
                win.setTimeout(()=> alertsService.closeAlert(), 2000);
            });
        },
    });
})();

_zt пишет

Кстати, должно быть не 5, а 6, видимо network.cookie.cookieBehavior = 0 нет.

Где нет? В кнопке есть network.cookie.cookieBehavior = 0,
номер на значке toolbarbutton-badge соответствует настройке в about:config

Большое СПАСИБО!!!!!

Отсутствует

 

№149724-04-2024 22:59:55

b0ttle
Участник
 
Группа: Members
Зарегистрирован: 22-10-2020
Сообщений: 182
UA: Firefox 124.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Тоже всем благодарен за разъяснения. Farby, спасибо за наглядный пример, взял в заначки.

Отсутствует

 

№149824-04-2024 23:09:14

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

Vitaliy V. пишет

Где нет?

Да я не смотрел скрипт, выше написали что пунктов пять.
   
А с about:cfg можете исправить

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

Выделить код

Код:

(async (
id = "ucf-open-about-config",
label = "about:config",
tooltiptext = "	   ЛКМ	Открыть about:config\n  Ctrl+ЛКМ	Искать выделенное / буфер в about:config\n	   ПКМ 	Открыть окно about:cfg\n  Ctrl+ПКМ	Искать выделенное / буфер в окне about:cfg",
img = "chrome://user_chrome_files/content/custom_styles/svg/about-config-16.svg",
aboutoldurl = "about:cfg",
about_config = {
    get clipboardHelp() {
        delete this.clipboardHelp;
        return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
    },
// https://forum.mozilla-russia.org/viewtopic.php?pid=804061#p804061
    readFromClipboard() {
        var {getData, kGlobalClipboard: kGK} = Services.clipboard;
        var flavor = `text/${parseInt(Services.appinfo.platformVersion) >= 111 ? "plain" : "unicode"}`;
        var transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
        transferable.init(null);
        transferable.addDataFlavor(flavor);

        return (this.readFromClipboard = () => {
            try {
                getData(transferable, kGK);
                var out = {};
                transferable.getTransferData(flavor, out);
                var url = out.value.QueryInterface(Ci.nsISupportsString).data;
            }
            finally {
                transferable.setTransferData(flavor, null);
                return url || "";
            }
        })();
    },
    openClipboardConfigTab(win, clip = "", copy, url = "about:config") {
        var filter = this.readFromClipboard(win), nowarn = false, pref = url === "about:config" ? "browser.aboutConfig.showWarning" : "general.warnOnAboutConfig";
        if (copy && clip != filter)
            this.clipboardHelp.copyString(clip);
        if (Services.prefs.getBoolPref(pref, true)) {
            Services.prefs.setBoolPref(pref, false);
            nowarn = true;
        }
        var browser = win.gBrowser.getBrowserForTab(win.gBrowser.selectedTab = this.addTab(win, url));
        browser.addEventListener("pageshow", e => {
            var doc = e.target;
            var input = doc && doc.querySelector("input#about-config-search, search-textbox#textbox");
            if (input && filter) {
                input.value = filter;
                input.focus();
                input.dispatchEvent(new doc.defaultView.Event("input", { bubbles: true }));
            }
            if (nowarn)
                win.setTimeout(() => {
                    Services.prefs.setBoolPref(pref, true);
                }, 200);
        }, { once: true });
    },
    openSelectedConfig(win, url, oldwin) {
        var clip = this.readFromClipboard(win);
        win.goDoCommand("cmd_copy");
        win.setTimeout(() => {
            if (!oldwin)
                this.openClipboardConfigTab(win, clip, true, url);
            else
                this.openOldConfigWin(win, clip, true);
        }, 100);
    },
    addTab(win, url, params = {}) {
        params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
        params.index = win.gBrowser.selectedTab._tPos + 1;
        return win.gBrowser.addTab(url, params);
    },
    get configoldurl() {
        delete this.configoldurl;
        var mod = Cc[`@mozilla.org/network/protocol/about;1?what=${aboutoldurl.split(":")[1]}`].getService(Ci.nsIAboutModule);
        var url;
        try {
            url = mod.getChromeURI(Services.io.newURI(aboutoldurl)).spec;
        } catch (e) {
            url = mod.wrappedJSObject.uri?.spec;
        }
        return this.configoldurl = url || aboutoldurl;
    },
    async openOldConfigWin(win, clip = "", copy) {
        var filter, input;
        if (copy) {
            filter = this.readFromClipboard(win);
            if (clip != filter)
                this.clipboardHelp.copyString(clip);
        }
        var type = "Preferences:ConfigManager", id = "config";
        var _win = Services.wm.getMostRecentWindow(type);
        if (!_win) {
            let nowarn = false, pref = "general.warnOnAboutConfig";
            if (copy && Services.prefs.getBoolPref(pref, true)) {
                Services.prefs.setBoolPref(pref, false);
                nowarn = true;
            }
            let url = this.configoldurl;
            let xs = Services.xulStore;
            let sx = xs.getValue(url, id, "screenX");
            let sy = xs.getValue(url, id, "screenY");
            let wh = xs.getValue(url, id, "width");
            let ht = xs.getValue(url, id, "height");
            let sm = xs.getValue(url, id, "sizemode");
            let features = `chrome,dialog=no,resizable,${sx && sy ? `screenX=${sx !== "0" ? sx : "1"},screenY=${sy !== "0" ? sy : "1"}` : "centerscreen"}${wh && ht ? `,width=${wh},height=${ht}` : ""}`;
            _win = win.openDialog(url, type, features);
            await new Promise(resolve => {
                _win.windowRoot.addEventListener("DOMContentLoaded", () => {
                    _win.windowRoot.addEventListener("MozUpdateWindowPos", () => {
                        if (sm === "maximized")
                            _win.maximize();
                    }, { once: true, capture: true });
                    resolve();
                }, { once: true });
            });
            if (copy && nowarn)
                _win.setTimeout(() => {
                    Services.prefs.setBoolPref(pref, true);
                }, 200);
        }
        var doc = _win.document;
        var docEl = doc.documentElement;
        docEl.setAttribute("windowtype", type);
        docEl.id = id;
        docEl.setAttribute("persist", "screenX screenY width height sizemode");
        _win.focus();
        if (!copy || !(input = doc.querySelector("search-textbox#textbox"))) return;
        input.value = filter;
        input.focus();
        input.dispatchEvent(new _win.Event("input", { bubbles: true }));
    },
}) => {
    CustomizableUI.createWidget({
        id: id,
        type: "custom",
        label: label,
        tooltiptext: tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onBuild(doc) {
            var win = doc.defaultView;
            var trbn = doc.createXULElement("toolbarbutton");
            trbn.id = id;
            trbn.className = "toolbarbutton-1 chromeclass-toolbar-additional";
            trbn.setAttribute("label", label);
            trbn.setAttribute("context", "");
            trbn.setAttribute("tooltiptext", tooltiptext);
            trbn.style.setProperty("list-style-image", `url("${img}")`, "important");
            trbn.addEventListener("click", e => {
                if (e.button == 0) {
                    if (e.getModifierState("Accel"))
                        about_config.openSelectedConfig(win);
                    else
                        win.gBrowser.selectedTab = about_config.addTab(win, "about:config");
                }
                else if (e.button == 2) {
                    e.preventDefault();
                    e.stopPropagation();
                    if (e.getModifierState("Accel"))
                        about_config.openSelectedConfig(win, undefined, true);
                    else
                        about_config.openOldConfigWin(win);
                }
            });
            return trbn;
        }
    });
})();

Отсутствует

 

№149925-04-2024 07:11:16

fuchsfan
Участник
 
Группа: Members
Зарегистрирован: 07-08-2023
Сообщений: 110
UA: Firefox 125.0

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

_zt пишет

А с about:cfg можете исправить

Если только about:config, без доп. бантиков, то работает это (изменить в конце третьей строки снизу на желаемое)
https://forum.mozilla-russia.org/viewto … 74#p804474

Отсутствует

 

№150025-04-2024 13:14:06

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

Re: UCF - ваши кнопки, темы, дополнения, скрипты…

_zt пишет

с about:cfg

Пока Vitaliy V. не пришёл, сделает лучше, можно попробовать такой вариант:

ucf-open-about-config

Выделить код

Код:

// by Vitaly V. https://forum.mozilla-russia.org/viewtopic.php?pid=809326#p809326

(async (
	id = "ucf-open-about-config",
	label = "about:config",
	tooltiptext = Services.locale.requestedLocale.startsWith("ru")
		? "ЛКМ: Открыть about:config\nЛКМ+Shift: Открыть about:cfg\nСКМ: Искать выделенное в about:config\nСКМ+Shift: Искать выделенное в about:cfg\nПКМ: Открыть about:about"
		: "Left-click: Open about:config\nLeft-click+Shift: Open about:cfg\nMidle-click: Search for the highlighted in about:config\nMidle-click+Shift: Search for the highlighted in about:cfg\nRight-click: Open about:about",
	img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;'><path d='m 8.66,15.4 h -1.2 c -0.69,0 -1.3,-0.5 -1.5,-1.2 L 5.58,13 C 5.32,12.9 5.07,12.7 4.82,12.5 L 3.41,12.9 C 2.76,13 2.04,12.8 1.69,12.1 L 1.09,11.2 C 0.748,10.5 0.838,9.75 1.31,9.33 l 1,-1 V 7.52 L 1.32,6.55 C 0.842,6.06 0.748,5.36 1.1,4.78 L 1.7,3.8 C 2.04,3.22 2.75,2.93 3.4,3.08 L 4.84,3.4 C 5.1,3.24 5.34,3.1 5.58,2.99 L 5.96,1.72 C 6.16,1.08 6.77,0.631 7.46,0.629 h 1.2 C 9.35,0.629 9.94,1.07 10,1.7 L 10.4,3 c 0.3,0.11 0.5,0.25 0.8,0.4 L 12.5,3.08 C 13.2,2.93 14,3.22 14.3,3.8 l 0.6,0.98 c 0.4,0.57 0.3,1.28 -0.2,1.77 l -1,0.97 v 0.81 l 1,1 c 0.5,0.42 0.6,1.17 0.2,1.87 l -0.6,0.9 C 14,12.8 13.2,13 12.5,12.9 l -1.3,-0.4 c -0.3,0.2 -0.5,0.4 -0.8,0.5 L 10,14.2 c -0.1,0.7 -0.64,1.2 -1.34,1.2 z'/><circle cx='8' cy='8' r='2.4'/></g></svg>",

	about_config = {
		get clipboardHelp() {
			delete this.clipboardHelp;
			return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
		},
		openClipboardConfigTab(win, url, clip = "", copy) {
			var filter = this.readFromClipboard(win), nowarn = false,
				pref = "browser.aboutConfig.showWarning", prefOld = "general.warnOnAboutConfig";
			if (copy && clip != filter)
				this.clipboardHelp.copyString(clip);
			switch (url) {
				case "about:config":
					if (Services.prefs.getBoolPref(pref, false)) {
						Services.prefs.setBoolPref(pref, false);
						nowarn = true;
					}
					break;
				case "about:cfg":
					if (Services.prefs.getBoolPref(prefOld, false)) {
						Services.prefs.setBoolPref(prefOld, false);
						nowarn = true;
					}
					break;
			}
			win.gBrowser.getBrowserForTab(win.gBrowser.selectedTab = this.addTab(win, url))
			.addEventListener("pageshow", e => {
				var doc = e.target;
				var input = doc?.querySelector("input#about-config-search") || doc?.querySelector("#textbox");
				if (input && filter) {
					input.value = filter;
					input.focus();
					input.dispatchEvent(new doc.defaultView.Event("input", { bubbles: true }));
				}
				if (nowarn)
					win.setTimeout(() => {
						switch (url) {
							case "about:config":
								Services.prefs.setBoolPref(pref, true);
								break;
							case "about:cfg":
								Services.prefs.setBoolPref(prefOld, true);
								break;
						}
					}, 200);
			}, { once: true });
		},
		openSelectedConfigTab(win, url) {
			var clip = this.readFromClipboard(win);
			win.goDoCommand("cmd_copy");
			win.setTimeout(() => {
				this.openClipboardConfigTab(win, url, clip, true);
			}, 100);
		},
		addTab(win, url, params = {}) {
			params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
			params.index = win.gBrowser.selectedTab._tPos + 1;
			return win.gBrowser.addTab(url, params);
		},
		readFromClipboard(win) {
			var url = "";
			try {
				let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable);
				trans.init(win.docShell.QueryInterface(Ci.nsILoadContext));
				trans.addDataFlavor("text/plain");
				let {clipboard} = Services;
				clipboard.getData(trans, clipboard.kGlobalClipboard);
				let data = {};
				trans.getTransferData("text/plain", data);
				if (data.value)
					url = data.value.QueryInterface(Ci.nsISupportsString).data;
			} catch (ex) {}
			return url;
		},
	}
) => { Services.io.getProtocolHandler("resource")
	.QueryInterface(Ci.nsIResProtocolHandler)
	.setSubstitution(`${id}-img`, Services.io.newURI(img));
	CustomizableUI.createWidget({
		id,
		type: "custom",
		label,
		tooltiptext,
		localized: false,
		defaultArea: CustomizableUI.AREA_NAVBAR,
		onBuild: function(doc) {
			var btn = doc.createXULElement("toolbarbutton");
			var props = {
				id,
				label,
				context: "",
				tooltiptext,
				class: "toolbarbutton-1 chromeclass-toolbar-additional",
			};
			for (let p in props)
				btn.setAttribute(p, props[p]);
			btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important");
			btn.addEventListener("click", e => {
				var win = e.view;
				if (e.button == 0)
					if (!e.shiftKey)
						win.gBrowser.selectedTab = about_config.addTab(win, "about:config");
					else
						win.gBrowser.selectedTab = about_config.addTab(win, "about:cfg");
				else if (e.button == 1)
					if (!e.shiftKey)
						about_config.openSelectedConfigTab(win, "about:config");
					else
						about_config.openSelectedConfigTab(win, "about:cfg");
				else if (e.button == 2) {
					e.preventDefault();
					e.stopPropagation();
					win.gBrowser.selectedTab = about_config.addTab(win, "about:about");
				}
			});
			return btn;
		},
	});
})();


ЗЫ: добавил URL: "about:cfg" через Shift, Разумеется "about:cfg" должен быть доступен. Скрипт из поста №1494 by Vitaliy V..


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

Отсутствует

 

Board footer

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