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

Заказывай стафф с атрибутикой Mozilla и... пусть все вокруг завидуют тебе! Быть уникальным - быть с Mozilla!

№140121-04-2024 17:06:17

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

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

Dobrov пишет

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

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

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

Отсутствует

 

№140221-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)

Отсутствует

 

№140322-04-2024 01:45:32

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

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

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

Отсутствует

 

№140422-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)

Отсутствует

 

№140522-04-2024 15:43:55

Vitaliy V.
Участник
 
Группа: Members
Зарегистрирован: 19-09-2014
Сообщений: 2186
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)

Отсутствует

 

№140623-04-2024 19:18:19

Vitaliy V.
Участник
 
Группа: Members
Зарегистрирован: 19-09-2014
Сообщений: 2186
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();
        },
    });
})();

Отсутствует

 

№140724-04-2024 00:32:29

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

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

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

Отсутствует

 

№140824-04-2024 01:44:20

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

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

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

Отсутствует

 

№140924-04-2024 02:51:01

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

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

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

Отсутствует

 

№141024-04-2024 09:19:19

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

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

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

Отсутствует

 

№141124-04-2024 09:28:51

Farby
Участник
 
Группа: Members
Зарегистрирован: 21-11-2012
Сообщений: 306
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;


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

Отсутствует

 

№141224-04-2024 11:13:37

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 1644
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)

Отсутствует

 

№141324-04-2024 16:46:34

Vitaliy V.
Участник
 
Группа: Members
Зарегистрирован: 19-09-2014
Сообщений: 2186
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)

Отсутствует

 

№141424-04-2024 17:09:58

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

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

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

Отсутствует

 

№141524-04-2024 22:59:55

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

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

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

Отсутствует

 

№141624-04-2024 23:09:14

_zt
Участник
 
Группа: Members
Зарегистрирован: 10-11-2014
Сообщений: 1644
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;
        }
    });
})();

Отсутствует

 

№141725-04-2024 07:11:16

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

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

_zt пишет

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

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

Отсутствует

 

№141825-04-2024 13:14:06

Farby
Участник
 
Группа: Members
Зарегистрирован: 21-11-2012
Сообщений: 306
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..


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

Отсутствует

 

№141925-04-2024 14:32:21

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

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

_zt пишет

А с about:cfg

Надо было выложить сам about:cfg полностью, а то ссылки недействительны кроме https://forum.mozilla-russia.org/viewto … 48#p806748
а там нет папки locale.
Вариант как и было с окном about:cfg

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

Выделить код

Код:

(async (
    id = "ucf-open-old-about-config",
    label = "about:config",
    tooltiptext = "ЛКМ: Открыть about:config\nCtrl+ЛКМ: Искать выделенное / буфер в about:config\nПКМ: Открыть окно about:cfg\nCtrl+ПКМ: Искать выделенное / буфер в окне about:cfg",
    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>",
    aboutoldurl = "about:cfg",

    about_config = {
        get clipboardHelp() {
            delete this.clipboardHelp;
            return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
        },
        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;
        },
        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;
            }
            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, 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 w = Services.wm.getMostRecentWindow(type);
            if (!w) {
                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 {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", 700) || 700;
                let ht = +xs.getValue(url, id, "height") || xs.setValue(url, id, "height", 600) || 600;
                let sm = xs.getValue(url, id, "sizemode");
                let features = `chrome,dialog=no,resizable,${`screenX=${sx},screenY=${sy}`}${`,width=${wh},height=${ht}`}`;
                w = win.openDialog(url, type, features);
                await new Promise(resolve => {
                    w.windowRoot.addEventListener("DOMContentLoaded", () => {
                        w.windowRoot.addEventListener("MozUpdateWindowPos", () => {
                            if (sm === "maximized")
                                w.maximize();
                        }, { once: true, capture: true });
                        resolve();
                    }, { once: true });
                });
                let docEl = w.document.documentElement;
                docEl.setAttribute("windowtype", type);
                docEl.id = id;
                docEl.setAttribute("persist", "screenX screenY width height sizemode");
                if (copy && nowarn)
                    w.setTimeout(() => {
                        Services.prefs.setBoolPref(pref, true);
                    }, 200);
            }
            w.focus();
            if (!copy || !(input = w.document.querySelector("search-textbox#textbox"))) return;
            input.value = filter;
            input.focus();
            input.dispatchEvent(new w.Event("input", { bubbles: true }));
        },
    }
) => { 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");
            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 => {
                if (e.button == 0) {
                    let win = e.view;
                    if (e.getModifierState("Control"))
                        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("Control"))
                        about_config.openSelectedConfig(e.view, undefined, true);
                    else
                        about_config.openOldConfigWin(e.view);
                }
            });
            return btn;
        },
    });
})();

Отредактировано Vitaliy V. (25-04-2024 14:44:51)

Отсутствует

 

№142025-04-2024 15:13:54

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

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

Vitaliy V.
Спасибо.
aboutconfigOLDv3-mjs-115+.7z
   
Может подскажите еще как убрать этот отстойный салатовый цвет в старом about_config, вот это работает, для списка
:root {
    --in-content-primary-button-text-color: white;
    --in-content-primary-button-background: #0074E8;
а это, для поля поиска, нет
    --in-content-focus-outline: #0074E8;
xul|search-textbox[focused] {
    border: 1px solid #0074E8;

Отредактировано _zt (25-04-2024 17:18:56)

Отсутствует

 

№142125-04-2024 18:36:47

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

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

fuchsfan
Farby
Да мой и так работал, даже на [nightly], просто, раз уж пошла такая пьянка, решил попросить обновить.
   
Добавлено 25-04-2024 18:47:09
   
Dumby
QuickToggleAboutConfig перестал обновлять страницу на [nightly] , можете поправить? - Регистр не исправил - win.BrowserCommands.reloadSkipCache()
И еще при активации пункта с перезагрузкой из второго меню, при отказе от перезагрузки (например, когда надо еще один пункт переключить) открывается первое меню. А ожидается открытие последнего использованного меню.

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

Выделить код

Код:

(async (name, id, func) => {
	if (name == "Object") return CustomizableUI.createWidget(func());
// Несовместимо с Fx 116+
//	var win = name == "Window", g = Components.utils.import("resource://gre/modules/Services.jsm", {});
	if (g[id]) {if (win) return;} else g[id] = func();
	if (win) return CustomizableUI.createWidget(g[id]);
	addDestructor(r => r[5] == "e" && delete g[id]);
	g[id].onCreated(this);
})(this.constructor.name, "QuickToggleAboutConfigSettings", () => {

	var {prefs} = Services, db = prefs.getDefaultBranch("");
	var pv = parseInt(Services.appinfo.platformVersion);
	var xul_ns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";

	var primary = [{

			pref: ["network.proxy.type", "Настройки прокси"],
			userChoice: 5, userAlt: 1, refresh: true,
			values: [
				[0, "Не проксировать", "0"],
				[5, "Системные (IE)", "5"],
				[2, "Авто (proxi.pac)", "2"],
				[1, "Прописанные", "1"],
				[4, "Автоопределение", "4"]
	]},
			null,
	{
			pref: ["browser.zoom.full", "Масштабировать"],
			userChoice: false, userAlt: true, refresh: true,
			values: [[true, "Весь контент"], [false, "Только текст"]]
	},
			null,
	{
			pref: ["permissions.default.image", "Загружать web-графику"],
			userChoice: 1, userAlt: 2, refresh: true,
			values: [
				[1, "Да", "1"],
				[3, "С сайта", "3"],
				[2, "Нет", "2"]
	]}
	];

//=============================================================================

	var secondary = [{
			pref: ["dom.security.https_only_mode", "Режим Только HTTS"],
			userChoice: false, refresh: true,
			values: [[true, "Скучно без проблем"], [false, "Нет"]]
	},{
			pref: ["browser.display.use_document_fonts", "Загружать web-шрифты"],
			userChoice: 1, refresh: true,
			values: [[1, "Да"], [0, "Нет"]]
	},{
			pref: ["layout.css.font-visibility", "Видимость лок.шрифтов"],
			userChoice: 1, refresh: true,
			values: [
				[1, "Базовые"],
				[2, "+доп.яз.пак."],
				[3, "+уст.польз."],
	]},
			null,
	{
			pref: ["ui.prefersReducedMotion", "Анимация chrome"],
			userChoice: 1, userAlt: 0,
			values: [[1, "Отключена"], [0, "Включена"]]
	},{
			pref: ["gfx.webrender.software", "• Software (also bug w7)"],
			userChoice: true, userAlt: false, restart: true,
			values: [[true, "Включен"], [false, "Отключен"]]
	}
	];

	return {
		id: "QuickToggleAboutConfigSettings",
		label: "Quick Toggle Settings",
		tooltiptext: "Quick Toggle Settings\n\nЛКМ	Первое меню\nПКМ	Второе меню",
		localized: false,
		image: "chrome://user_chrome_files/content/custom_styles/svg/QuickToggle.svg",
		onCreated(btn) {
			btn.setAttribute("image", this.image);
			var doc = btn.ownerDocument;

			btn.btn = true;
			btn.domParent = null;
			btn.popups = new btn.ownerGlobal.Array();
			this.createPopup(doc, btn, "primary", primary);
			this.createPopup(doc, btn, "secondary", secondary);
			this.createCloseMenusOption(doc, btn);

			btn.linkedObject = this;
			for(var type of ["command", "contextmenu"])
				btn.setAttribute("on" + type, `linkedObject.${type}(event)`);
		},
		createPopup(doc, btn, name, data) {
			var popup = doc.createElementNS(xul_ns, "menupopup");
			var prop = name + "Popup";
			btn.popups.push(btn[prop] = popup);
			popup.id = this.id + "-" + prop;
			for (var type of ["popupshowing", "click"])
				popup.setAttribute("on" + type, `parentNode.linkedObject.${type}(event)`);
			for(var obj of data) popup.append(this.createElement(doc, obj));
			btn.append(popup);
		},
		map: {b: "Bool", n: "Int", s: "String"},
		createElement(doc, obj) {
			if (!obj) return doc.createElementNS(xul_ns, "menuseparator");
			var pref = doc.ownerGlobal.Object.create(null), node, img, bool;
			for(var [key, val] of Object.entries(obj)) {
				if (key == "pref") {
					var [apref, lab, akey, ttt] = val;
					pref.pref = apref; pref.lab = lab || apref;
					if (ttt) pref.ttt = ttt;
				}
				else if (key == "image") img = val, pref.img = true;
				else if (key != "values") pref[key] = val;
				else pref.hasVals = true;
			}
			var type = prefs.getPrefType(pref.pref);
			var str = this.map[type == prefs.PREF_INVALID
				? obj.values ? (typeof obj.values[0][0])[0] : "b"
				: type == prefs.PREF_BOOL ? "b" : type == prefs.PREF_INT ? "n" : "s"
			];
			pref.get = prefs[`get${str}Pref`];
			pref.set = prefs[`set${str}Pref`];

			node = doc.createElementNS(xul_ns, "menu");
			node.className = "menu-iconic";
			node.setAttribute("closemenu", "none");
			img && node.setAttribute("image", img);
			akey && node.setAttribute("accesskey", akey);
			(node.pref = pref).vals = doc.ownerGlobal.Object.create(null);
			this.createRadios(doc,
				str.startsWith("B") && !pref.hasVals ? [[true, "true"], [false, "false"]] : obj.values,
				node.appendChild(doc.createElementNS(xul_ns, "menupopup"))
			);
			if ("userChoice" in obj) pref.noAlt = !("userAlt" in obj);
			return node;
		},
		createCloseMenusOption(doc, btn) {
			var pn = this.closePref = "QuickToggleAboutConfigSettings.closeMenus";
			var data = [null, {
				pref: [pn, "Автозакрытие этого меню"], values: [[true, "Да"], [false, "Нет"]]
			}];
			var setCloseMenus = e => {
				e.stopPropagation();
				var trg = e.target, {pref, val} = trg, updPopup = true, clear;
				switch(e.type) {
					case "command": pref = (trg = trg.closest("menu")).pref; updPopup = false; break;
					case "click": if (e.button) return; break;
					case "contextmenu": e.preventDefault(); clear = pref;
				}
				if (!pref) return;
				if (clear) prefs.clearUserPref(pn);
				else if (!updPopup && val === pref.val) return;
				else pref.set(pn, val !== undefined ? val : !pref.val);
				this.upd(trg);
				updPopup && this.popupshowing(null, trg.querySelector("menupopup"));
			}
			(this.createCloseMenusOption = (doc, btn) => {
				for(var obj of data)
					btn.secondaryPopup.append(this.createElement(doc, obj));
				var m = btn.secondaryPopup.lastChild;
				m.style.cssText = "fill: lightblue !important; list-style-image: url(chrome://browser/skin/menu.svg) !important;";
				m.setAttribute("oncommand", "setCloseMenus(event)");
				m.onclick = m.oncontextmenu = m.setCloseMenus = setCloseMenus;
			})(doc, btn);
		},
		UserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHqSURBVDhPpVJBTxNBGH1LLakxVEJQQIkhlZCAJDYR/BGScNCDwZMcuEji2ZP+BD14MCGciDEaEw8e1At3QGLlwAUOFtm6tut2uwtb2t3p8GbZ0iXlVF/y5ttkv+/Nmzej5XI5/A+6otoxTh1ks9mwhniJHvRiBAHXLjRIEy7yeIqjqAPNuXYHS5jGVby7PTT27eHo7Or9zL3Va/19Xyj5FsuYjLpOcdbBG9xFGh+fZRaGJ5O3tB7tMrcXcGQZP+pb8tXuyjpdPcA89HYHynYazxdvzg5nkgOapFsPNleXP+uY6L6hzYxMT+EC5vCVa4SWAM880Ju4cyVxUXNkERUeuyJLIR1+O6wTqcEEUngEA5eiqZgAAxtMpfur0sIBLA7+hS2NkK5UGVpsqgEJjLMkT4biAkzbE27D5u7/ZAFWSB1l0iRtUokyEj+aCBEXMHcOA70Y/IElfsMUeyiJPIpBHiZZEvv4Vcsrge9Mi1ZO0BJQ98yw9w4tWT4yYNV1ki78AuyggHLNwLZjC1Txnpl60VRMQD2SBl5sGsHaT88XJd+DEzioCAd6rYpN1xf7Jj5T4BMe00eE9pf4GteZ8Ry6mbYKDDyzxAblP4TDT1BUbc2585+yumd1Vc201ZmV7djObQKdopVBRwCOAVyl9qcQtNEaAAAAAElFTkSuQmCC",
		notUserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHqSURBVDhPpVJNSxtRFD1PJ9GMMVpaKyWhRGwRFy7Utv+gVFyUgoWif8Ct+APMsvQX+BuUWhdBcOvSDwi1XVhK0WgmTr4mmphoJvPRe5NnxhLdpAcO9828d869794nXNfF/6BLxo7RqiAcDjciYx3oDwFRBxikT4ey5CtAcg64aZ4ANE1rxDaDLeB176Aae/zx/ZR/NDqEuu1UD39oxsZ2wnIRmwV+8rl7DeLAGzXg+/pidSWivBwVCPQDvH91AfPot/tn6fOedW3NzTT0TYNWD7hsVfWtjH1ZjCjPggImFV25AKpE+xr+6CMxsvzpVXePmE8AipR5Bnzn4bcT0yJoCZSyQDkPXOrEDDHXYG8k0B18/nSBdvukzDPghqlB/xOUi4BBgiIJDUleF0lmVaEo7ngd8EnZP2N0uiolBwXKmksDegrISubovvyPWauR3kPLgBb5q+O8hnMyOD8jJoknTaZPKZLRSQp2+eaA6q9JmWcwTHPWv2cT0E0XGcqos4lkhgz4X7Jql3O1NZNaK2WewSQ9EtqIHcWPd5FybWQNoECNNApkdgmcwv61k47TbDbf0VykrP0hfaPlADAfCmFBERiHQN2sY79UwTqLP1BX+NyDL5HBc+ZR3Xab78xl383cZtAp7o6xAwB/AT+Y7GFJS/NjAAAAAElFTkSuQmCC",
		UserAltImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAH7SURBVDhPpVJLa1NBFP5mJolNcrWhtiq9Betjk0VFfNS1O7ciXbQguBDXxR9g3Lnown8g3SqCi24K/gCxVbqogiBaxdyY5nFrkt5H5j7GmZvxphDdxA8+Dgzn+86Zcw4RQuB/QHUcG2kHpmkmUWHtEo6DY55mUCIhYkHQOlXA97vv4esUWJaVxBGDp2Vcz54klakbN69kZ8wZRHHsVT9b7e2tHdFH5eEuPqi8vxqsLWDxmIGX5+8/mMufPkdA8zIBiMMuvNo3sbf+bCt2cWd1V+kHBukMVNuFE3h08d7SXHF6glC4oHFXGnTBmA9j1iBnb9+6xvJYfryIjJYdGaL889TlC1cLkyFhQQek3wThjYSUt8GCX9Iky/JniitGF0WtGhpQgdLEJJvO8AMpUgIbtK/JbflmI0cc2Y0oy/JZLRsaEIKYcCemXgvUlVXdOpj/c0Bnf0BXdhXxQEsSpAZqVU7NtkRPJh5aoAmrCYnzA9SpIbDr4G74Lsihr2VDA7Xn5kdvx2mGgnr7soNaSubXQb0GelUv8lt4Pj8rJ6yRGqgjERyVT68P3rarJIo6HojrJOS2h8Yejb6+OdyIe3i1tIlIy0YP6ckCTCOH5WIJKxmGsnwKeB/bbgcvlHj1Cxoq75+XqKD2rFb1Z9rqz6rto5VHDMZFOoPxAPwGQ077rbKVfhEAAAAASUVORK5CYII=",
		upd(node) {
			var {pref} = node, def = false, user = false, val;
			if (prefs.getPrefType(pref.pref) != prefs.PREF_INVALID) {
				var pn = pref.pref;
				try {val = pref.defVal = db[pref.get.name](pn); def = true}
				catch(ex) {def = false;}
				var user = prefs.prefHasUserValue(pn);
				if (user) try {val = pref.get(pn, undefined);} catch(ex) {}
			}
			if (val == pref.val && def == pref.def && user == pref.user) return;
			pref.val = val; pref.def = def; pref.user = user;
			var exists = def || user;

			var ttt = exists ? val : "Этот преф не существует";
			if (ttt === "") ttt = "[ empty_string ]";
			ttt += "\n" + pref.pref;
			if (pref.ttt) ttt += "\n" + pref.ttt;
			node.tooltipText = ttt;

			var img, alt = "userAlt" in pref && val == pref.userAlt;
			if (alt) img = this.UserAltImg;
			if ("userChoice" in pref)
				if (val == pref.userChoice)
					//node.style.removeProperty("color"),
					img = this.UserChoiceImg;
				else {
					//node.style.setProperty("color", "maroon", "important");
					if (!alt) img = this.notUserChoiceImg;
				}
			if (!pref.img) img
				? node.setAttribute("image", img)
				: node.removeAttribute("image");
			user
				? node.style.setProperty("font-style", "italic", "important")
				: node.style.removeProperty("font-style");

			var {lab} = pref;
			if (exists && pref.hasVals) {
				if (val in pref.vals) var sfx = pref.vals[val] || val;
				else var sfx = user ? "Другое" : "По умолчанию";
				lab += ` ${"restart" in pref ? "— ↯" : "refresh" in pref ? "— ⧖" : "— -"} "${sfx}"`;
			}
			node.setAttribute("label", lab);
		},
		createRadios(doc, vals, popup) {
			for(var arr of vals) {
				if (!arr) {
					popup.append(doc.createElementNS(xul_ns, "menuseparator"));
					continue;
				}
				var [val, lab, key, ttt] = arr;
				var menuitem = doc.createElementNS(xul_ns, "menuitem");
				menuitem.setAttribute("type", "radio");
				menuitem.setAttribute("closemenu", "none");
				menuitem.style.setProperty("font-style", "italic", "important"),
				menuitem.setAttribute("label", popup.parentNode.pref.vals[val] = lab);
				key && menuitem.setAttribute("accesskey", key);
				var tip = menuitem.val = val;
				if (ttt) tip += "\n" + ttt;
				menuitem.tooltipText = tip;
				popup.append(menuitem);
			}
		},
		openPopup(popup) {
			var btn = popup.parentNode;
			if (btn.domParent != btn.parentNode) {
				btn.domParent = btn.parentNode;
				var pos;
				if (btn.matches(".widget-overflow-list > :scope"))
					pos = "after_start";
				else var win = btn.ownerGlobal, {width, height, top, bottom, left, right} =
					btn.closest("toolbar").getBoundingClientRect(), pos = width > height
						? `${win.innerHeight - bottom > top ? "after" : "before"}_start`
						: `${win.innerWidth - right > left ? "end" : "start"}_before`;
				for(var p of btn.popups) p.setAttribute("position", pos);
			}
			popup.openPopup(btn);
		},
 		maybeRestart(node, conf) {
			if (conf && !Services.prompt.confirm(null, this.label, "Перезапустить браузер?")) return;

			var cancel = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
			Services.obs.notifyObservers(cancel, "quit-application-requested", "restart");
			return cancel.data ? Services.prompt.alert(null, this.label, "Запрос на выход отменен.") : this.restart();
		},
		async restart() {
			var meth = Services.appinfo.inSafeMode ? "restartInSafeMode" : "quit";
			Services.startup[meth](Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
		},
		regexpRefresh: /^(?:view-source:)?(?:https?|ftp)/,
		maybeRe(node, fe) {
			var {pref} = node;
			if ("restart" in pref) {
				if (this.maybeRestart(node, pref.restart)) return;
			}
			else this.popupshowing(fe, node.parentNode);
			if ("refresh" in pref) {
				var win = node.ownerGlobal;
				if (this.regexpRefresh.test(win.gBrowser.currentURI.spec)) pref.refresh
					? win.BrowserCommands.reloadSkipCache() : win.BrowserCommands.reload();
			}
		},
		maybeClosePopup(e, trg) {
			!e.ctrlKey && prefs.getBoolPref(this.closePref, undefined)
				&& trg.parentNode.hidePopup();
		},
		command(e) {
			var trg = e.target;
			if (trg.btn) return trg.secondaryPopup.state == "closed" && this.openPopup(trg.primaryPopup);

			var menu = trg.closest("menu"), newVal = trg.val;
			this.maybeClosePopup(e, menu);
			if (newVal != menu.pref.val)
				menu.pref.set(menu.pref.pref, newVal),
				this.maybeRe(menu, true);
		},
		popupshowing(e, trg = e.target) {
			if (trg.state == "closed") return;
			if (trg.id) {
				for(var node of trg.children) {
					if (node.nodeName.endsWith("r")) continue;
					this.upd(node);
					!e && node.open && this.popupshowing(null, node.querySelector("menupopup"));
				}
				return;
			}
			var {pref} = trg.closest("menu"), findChecked = true;

			var findDef = "defVal" in pref;
			var checked = trg.querySelector("[checked]");
			if (checked) {
				if (checked.val == pref.val) {
					if (findDef) findChecked = false;
					else return;
				}
				else checked.removeAttribute("checked");
			}
			if (findDef) {
				var def = trg.querySelector("menuitem:not([style*=font-style]");
				if (def)
					if (def.val == pref.defVal) {
						if (findChecked) findDef = false;
						else return;
					}
					else def.style.setProperty("font-style", "italic", "important");
			}
			for(var node of trg.children) if ("val" in node) {
				if (findChecked && node.val == pref.val) {
					node.setAttribute("checked", true);
					if (findDef) findChecked = false;
					else break;
				}
				if (findDef && node.val == pref.defVal) {
					node.style.removeProperty("font-style");
					if (findChecked) findDef = false;
					else break;
				}
			}
		},
		contextmenu(e) {
			var trg = e.target;
			if (trg.btn) {
				if (e.ctrlKey || e.shiftKey) return;
				if (e.detail == 2) return trg.secondaryPopup.hidePopup();
				this.openPopup(trg.secondaryPopup);
			}
			else if ("pref" in trg) {
				this.maybeClosePopup(e, trg);
				if (trg.pref.user)
					prefs.clearUserPref(trg.pref.pref),
					this.maybeRe(trg);
			}
			e.preventDefault();
		},
		click(e) {
			if (e.button) return;
			var trg = e.target, {pref} = trg;
			if (!pref) return;

			this.maybeClosePopup(e, trg);
			if (!("noAlt" in pref)) return;

			if (pref.val == pref.userChoice)
				if (pref.noAlt) return;
				else  pref.set(pref.pref, pref.userAlt);
			else
				pref.set(pref.pref, pref.userChoice);
			this.maybeRe(trg);
		}
	};
});

Отредактировано _zt (25-04-2024 20:45:55)

Отсутствует

 

№142225-04-2024 20:55:36

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

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

_zt пишет

ожидается открытие последнего использованного меню

Что-то я не припомню, чтобы после confirm'а
вообще ожидалось открытие каких-либо меню.


Но, раз ожидается, возможно, так подойдёт

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

Выделить код

Код:

/*
			if (conf && !Services.prompt.confirm(null, this.label, "Перезапустить браузер?")) return;
*/
			if (conf) {
				node.ownerGlobal.event.preventDefault();
				if (!Services.prompt.confirm(null, this.label, "Перезапустить браузер?")) {
					var popup = node.closest("menupopup");
					return popup.openPopup(popup.parentNode);
				}
			}

Отсутствует

 

№142325-04-2024 22:47:48

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

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

_zt пишет

Да мой и так работал, даже на [nightly]

Ну и пользуйтесь на здоровье...
Vitaliy V. спасибо за ucf-open-about-config, классная идея передачи параметров, а я думал что так нельзя!!!!


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

Отсутствует

 

№142425-04-2024 22:57:22

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

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

Dumby
Спасибо. Да, возможно только я это ожидал.

Отсутствует

 

№142527-04-2024 08:05:46

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

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

egorsemenov06

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

Выделить код

Код:

/*
		btn.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAk1BMVEX///8/Pz8BAQF8fHwJCQkCAgIJCQl8fHx9fX0AAABJSUkBAQENDQ0wMDBVVVUAAABra2t0dHR7e3thYWEBAQEAAAAAAAABAQEAAAAgICABAQEBAQH8/Pzw8PDp6en39/fj4+Pe3t41V9I/YeWKioqDg4N9fX0jRa8wUrVoaGhkhuxWeNx1dXVCZMhvb28kRqsqTL4KidXxAAAAHHRSTlMAAABndwAAAAA0blVZcm1naWhNa6hrcJ8AAKRU4jk/3gAAAHVJREFUeF6FyMUCwjAUBdEbaQupUMOjqMv/fx1dQN6yZ3aDcWnyw6ezoRWNYc15kqKQZCFlgTKQQwgllL/dn5f3+bPb+6P3CpWNw56srdCZOMzDmA61i8O9nKvRaHLVukEryFKIFtnkj7ENYxmNdd5v+5xj1BcJ/w9Kj6K7ZAAAAABJRU5ErkJggg==";
*/
		btn.image = this.icon;
	},
	get icon() {
		var icon = "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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity;' d='M0 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm13 .25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5a.25.25 0 0 0-.25.25zM2.25 8a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 3 8.75v-.5A.25.25 0 0 0 2.75 8h-.5zM4 8.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 5 8.75v-.5A.25.25 0 0 0 4.75 8h-.5a.25.25 0 0 0-.25.25zM6.25 8a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 7 8.75v-.5A.25.25 0 0 0 6.75 8h-.5zM8 8.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 9 8.75v-.5A.25.25 0 0 0 8.75 8h-.5a.25.25 0 0 0-.25.25zM13.25 8a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5zm0 2a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5zm-3-2a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-1.5zm.75 2.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5a.25.25 0 0 0-.25.25zM11.25 6a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5zM9 6.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5A.25.25 0 0 0 9.75 6h-.5a.25.25 0 0 0-.25.25zM7.25 6a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 8 6.75v-.5A.25.25 0 0 0 7.75 6h-.5zM5 6.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 6 6.75v-.5A.25.25 0 0 0 5.75 6h-.5a.25.25 0 0 0-.25.25zM2.25 6a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h1.5A.25.25 0 0 0 4 6.75v-.5A.25.25 0 0 0 3.75 6h-1.5zM2 10.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5a.25.25 0 0 0-.25.25zM4.25 10a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h5.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-5.5z'/></svg>";
		var subst = this.id.toLowerCase() + "-icon";
		Services.io.getProtocolHandler("resource")
			.QueryInterface(Ci.nsIResProtocolHandler)
			.setSubstitution(subst, Services.io.newURI(icon));
		delete this.icon;
		return this.icon = "resource://" + subst;

Отсутствует

 

Board footer

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