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

Многие проблемы быстрее решаются поиском по форуму и чтением FAQ, чем созданием новой темы и томительным ожиданием ответа.

№912607-09-2020 19:57:54

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

Re: Настройка внешнего вида Firefox в userChrome.css

razoo
Если используете Custom Buttons здесь или здесь подробнее.

Отсутствует

 

№912708-09-2020 08:18:17

razoo
Участник
 
Группа: Members
Зарегистрирован: 23-07-2009
Сообщений: 48
UA: Firefox 78.0

Re: Настройка внешнего вида Firefox в userChrome.css

xrun1
Спасибо, дельный совет. Но, при всём уважении к CB (использовал на [firefox] c 3 по 52), пока воздержусь их прикручивать. На альтернативном профиле предложенную вами кнопку попробовал: это фактически реплика опции почившей TM+. Мощно, но многовато функций. )
Мне нужно максимально просто: клик > список.

Отсутствует

 

№912808-09-2020 14:08:54

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

Re: Настройка внешнего вида Firefox в userChrome.css

razoo пишет

Как сделать, чтобы new-tab-button был всегда прижат в крайнее правое положение

А воткнуть между вкладками и new-tab-button в Персонализация... --> Растягивающийся интервал?

Отсутствует

 

№912909-09-2020 00:00:07

razoo
Участник
 
Группа: Members
Зарегистрирован: 23-07-2009
Сообщений: 48
UA: Firefox 78.0

Re: Настройка внешнего вида Firefox в userChrome.css

xrun1 пишет

Растягивающийся интервал?

razoo пишет

У меня эту кнопку сейчас просто спейсинг подпирает с минусовым отступом

Это он и есть, а обратный отступ, чтобы минимизировать пространство недоступное для двойного клика, т.к. на special-spring не работает pointer-events: none. Привык вызывать таб даблкликом по таббару. Ради него вся канитель.

Отсутствует

 

№913009-09-2020 17:50:35

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

Re: Настройка внешнего вида Firefox в userChrome.css

Sidebar Tabs (бывший SidebarModoki, теперь полностью переписанный)
[firefox] 78 +

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

Выделить код

Код:

/** Подключение:

CustomStylesScripts.jsm:
    scriptschrome:
        load:
            { path: "ucf_SidebarTabs.js", ucfobj: true, },

*/
var sidebar_tabs = {
    // -- Настройки  Sidebar Tabs -->
    ST_RIGHT: false, // Расположение панели
    ST_WIDTH: 260,
    ST_AUTOHIDE: true, // Скрывать в полноэкранном режиме
    ST_NAME: "Sidebar Tabs",
    CLOSE_BTN_TOOLTIP: "Закрыть панель",
    ST_HIDE_HEADER: false,
    TAB_SRC_0: "chrome://browser/content/places/bookmarksSidebar.xhtml",
    TAB_LABEL_0: "Закладки",
    TAB_SRC_1: "chrome://browser/content/places/historySidebar.xhtml",
    TAB_LABEL_1: "История",
    TAB_SRC_2: "chrome://browser/content/downloads/contentAreaDownloadsView.xhtml",
    TAB_LABEL_2: "Загрузки",
    KEY: "KeyB_true_true_false", // Сочетание клавиш для для переключения Sidebar Tabs - code ctrlKey altKey shiftKey
    // <-- Настройки  Sidebar Tabs --

    last_open: "extensions.ucf.sidebar_tabs.last_open",
    last_index: "extensions.ucf.sidebar_tabs.last_index",
    toolbox_width: "extensions.ucf.sidebar_tabs.toolbox_width",
    toolbox: null,
    button: null,
    get prefs() {
        delete this.prefs;
        return this.prefs = Services.prefs;
    },
    init(that) {
        var docElm = document.documentElement, sidebar;
        if (docElm.matches("[chromehidden~='extrachrome']") || !(sidebar = document.querySelector("#sidebar-box"))) return;
        var style = "data:text/css;charset=utf-8," + encodeURIComponent(`
            #st_toolbox {
                background-color: var(--toolbar-bgcolor, -moz-Dialog) !important;
                color: var(--toolbar-color, -moz-DialogText) !important;
                text-shadow: inherit !important;
                -moz-box-ordinal-group: ${this.ST_RIGHT ? "101" : "0"} !important;
            }
            #st_toolbox :is(tabs,tabpanels,tab) {
                -moz-appearance: none !important;
                appearance: none !important;
                background-color: transparent !important;
                color: inherit !important;
                margin: 0 !important;
                padding: 0 !important;
                border: none !important;
            }
            #st_splitter {
                -moz-appearance: none !important;
                appearance: none !important;
                padding-inline: 4px !important;
                min-width: 9px !important;
                margin-inline: -4px !important;
                position: relative !important;
                z-index: 2 !important;
                -moz-box-ordinal-group: ${this.ST_RIGHT ? "100" : "0"} !important;
                -moz-box-orient: vertical !important;
                border: none !important;
                background: none !important;
            }
            #st_splitter::after {
                content: "";
                display: inline-block;
                -moz-box-flex: 1;
                width: 1px;
                border-left: 1px solid var(--chrome-content-separator-color, rgba(127,127,137,.5)) !important;
            }
            #st_toolbox tab {
                margin-top: 2px !important;
                padding: 3px 6px !important;
                outline: none !important;
                border-bottom: 2px solid transparent !important;
            }
            #st_toolbox tab:hover {
                border-bottom-color: rgba(127,127,127,.3) !important;
            }
            #st_toolbox tab[visuallyselected="true"] {
                border-bottom-color: #0074E8 !important;
            }
            #ucf-additional-vertical-container[v_vertical_bar_start="true"],
            #browser-border-start {
                -moz-box-ordinal-group: 0 !important;
            }
            #ucf-additional-vertical-container[v_vertical_bar_start="false"],
            #browser-border-end {
                -moz-box-ordinal-group: 102 !important;
            }
            ${this.ST_AUTOHIDE ? ":root[inFullscreen] :is(#st_toolbox,#st_splitter)," : ""}
            :root[inDOMFullscreen] :is(#st_toolbox,#st_splitter),
            :root[chromehidden~="extrachrome"] :is(#st_toolbox,#st_splitter) {
                visibility: collapse !important;
            }
            ${this.ST_HIDE_HEADER ? `#st_header {
                display: none !important;
            }` : ""}
        `);
        try {
            windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET);
        } catch (e) {}
        docElm.setAttribute("sidebar_tabs_right", `${this.ST_RIGHT}`);
        var template = document.importNode(MozXULElement.parseXULToFragment(`
            <vbox id="st_toolbox" class="chromeclass-extrachrome">
                <hbox id="st_header" align="center">
                    <label>${this.ST_NAME}</label>
                    <spacer flex="1000"/>
                    <toolbarbutton id="st_close_button" class="close-icon tabbable" tooltiptext="${this.CLOSE_BTN_TOOLTIP}"/>
                </hbox>
                <tabbox id="st_tabbox" flex="1">
                    <tabs id="sbar_tabs">
                        <tab id="st_tab0" label="${this.TAB_LABEL_0}"/>
                        <tab id="st_tab1" label="${this.TAB_LABEL_1}"/>
                        <tab id="st_tab2" label="${this.TAB_LABEL_2}"/>
                    </tabs>
                    <tabpanels id="st_tabpanels" flex="1">
                        <vbox id="st_tab_container_0" flex="1">
                            <browser id="st_browser_0" flex="1" autoscroll="false"/>
                        </vbox>
                        <vbox id="st_tab_container_1" flex="1">
                            <browser id="st_browser_1" flex="1" autoscroll="false"/>
                        </vbox>
                        <vbox id="st_tab_container_2" flex="1">
                            <browser id="st_browser_2" flex="1" autoscroll="false"/>
                        </vbox>
                    </tabpanels>
                </tabbox>
            </vbox>
            <splitter id="st_splitter" class="chromeclass-extrachrome"></splitter>
            `), true);
        sidebar.before(template);

        this.toolbox = document.querySelector("#st_toolbox");
        this.splitter = document.querySelector("#st_splitter");
        this.st_browser_0 = this.toolbox.querySelector("#st_browser_0");
        this.st_browser_1 = this.toolbox.querySelector("#st_browser_1");
        this.st_browser_2 = this.toolbox.querySelector("#st_browser_2");
        this.st_tabpanels = this.toolbox.querySelector("#st_tabpanels");
        this.st_tabbox = this.toolbox.querySelector("#st_tabbox");
        this.st_close_btn = this.toolbox.querySelector("#st_close_button");
        this.st_tabbox.selectedIndex = this.aIndex = this.prefs.getIntPref(this.last_index, 0);
        this._open = this.prefs.getBoolPref(this.last_open, true);
        this.st_tabbox.handleEvent = function handleEvent() {};
        this.toggle(true);
        window.addEventListener("keydown", this);
        this.st_close_btn.addEventListener("command", this);
        that.unloadlisteners?.push("sidebar_tabs");
    },
    select(e, aIndex) {
        if (e.target != this.st_tabpanels || (aIndex = this.st_tabpanels.selectedIndex) == this.aIndex) return;
        this[`st_browser_${this.aIndex}`].setAttribute("src", "about:blank");
        this.aIndex = aIndex;
        this.prefs.setIntPref(this.last_index, aIndex);
        this.toolbox.width = this.prefs.getIntPref(`${this.toolbox_width}${aIndex}`, this.ST_WIDTH);
        this[`st_browser_${aIndex}`].setAttribute("src", this[`TAB_SRC_${aIndex}`]);
    },
    toggle(force) {
        var tog = !force ? !this._open : this._open;
        if (tog) {
            if (this.button = CustomizableUI.getWidget("sidebar_tabs_button")?.forWindow(window).node) {
                this.button.checked = true;
                if (!this.button.sidebar_tabs_toggle)
                    this.button.sidebar_tabs_toggle = () => {
                        this.toggle();
                    };
            }
            this.toolbox.hidden = false;
            this.splitter.hidden = false;
            this.toolbox.width = this.prefs.getIntPref(`${this.toolbox_width}${this.aIndex}`, this.ST_WIDTH);
            this.prefs.setBoolPref(this.last_open, true);
            this._open = true;
            this.st_tabpanels.addEventListener("select", this);
            this.toolbox.addEventListener("resize", this);
            this[`st_browser_${this.aIndex}`].setAttribute("src", this[`TAB_SRC_${this.aIndex}`]);
        } else
            this.close();
    },
    close() {
        this.st_tabpanels.removeEventListener("select", this);
        this.toolbox.removeEventListener("resize", this);
        if (this.button = CustomizableUI.getWidget("sidebar_tabs_button")?.forWindow(window).node) {
            this.button.checked = false;
            if (!this.button.sidebar_tabs_toggle)
                this.button.sidebar_tabs_toggle = () => {
                    this.toggle();
                };
        }
        this.toolbox.hidden = true;
        this.splitter.hidden = true;
        this.prefs.setBoolPref(this.last_open, false);
        this._open = false;
        this.st_browser_0.setAttribute("src", "about:blank");
        this.st_browser_1.setAttribute("src", "about:blank");
        this.st_browser_2.setAttribute("src", "about:blank");
    },
    resize() {
        this.prefs.setIntPref(`${this.toolbox_width}${this.aIndex}`, this.toolbox.getBoundingClientRect().width);
    },
    keydown(e) {
        if (this.KEY === `${e.code}_${e.ctrlKey}_${e.altKey}_${e.shiftKey}`)
            this.toggle();
    },
    command() {
        this.close();
    },
    handleEvent(e) {
        this[e.type](e);
    },
    destructor() {
        window.removeEventListener("keydown", this);
        this.st_close_btn.removeEventListener("command", this);
        this.st_tabpanels.removeEventListener("select", this);
        this.toolbox.removeEventListener("resize", this);
    },
};
sidebar_tabs.init(this);

кнопка (необязательно) для него в custom_script.js

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

Выделить код

Код:

try {
    CustomizableUI.createWidget({
        id: "sidebar_tabs_button",
        label: "Sidebar Tabs",
        tooltiptext: "Открыть / Закрыть Sidebar Tabs",
        defaultArea: CustomizableUI.AREA_NAVBAR,
        localized: false,
        onCreated(btn) {
            btn.style.setProperty("list-style-image", `url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='context-fill rgb(142, 142, 152)'> <path d='M2 2C.892 2 0 2.89 0 4v9.1a2 2 0 0 0 2 2h12c1.1 0 2-.9 2-2V4a2 2 0 0 0-2-2Zm0 1h12c.6 0 1 .45 1 1v9.1c0 .5-.5.9-1 .9H1.99c-.55 0-.99-.4-.99-.9V4c0-.55.45-1 1-1Z'/> <rect width='14' height='1' x='1' y='6'/> <rect width='1' height='7' x='5' y='7'/> </svg>")`);
        },
        onCommand(e) {
            e.target.sidebar_tabs_toggle();
        }
    });
} catch(e) {}


razoo пишет

new-tab-button был всегда прижат в крайнее правое положение

так и есть если не путать #tabs-newtab-button

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

Выделить код

Код:

#tabs-newtab-button {
    display: none !important;
}
#new-tab-button {
    display: -moz-box !important;
}

Отредактировано Vitaliy V. (16-10-2021 12:00:16)

Отсутствует

 

№913109-09-2020 18:46:38

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

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V.
Отлично smayl-tantsuyushchiy-animatsionnaya-kartinka-0008.1599665731.gif Спасибо огромное.
   
А отдельную кнопку, открывающую его поверх страницы, никак не сделать? С автоскрытием после действия.
Хотелось бы иметь такую возможность, не теряя возможность открывать его рядом со страницей без автоскрытия.
Или ЛКМ/ПКМ на существующей кнопке.

Отсутствует

 

№913210-09-2020 01:16:19

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

Re: Настройка внешнего вида Firefox в userChrome.css

_zt пишет

Или ЛКМ/ПКМ на существующей кнопке.

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

Выделить код

Код:

try {(() => {
    var label = "Sidebar Tabs",
    tooltiptext = "ЛКМ: Открыть / Закрыть Sidebar Tabs\nShift+ЛКМ: AutoHide Sidebar Tabs Откл/Вкл",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><rect x='0' y='0' width='16' height='16' rx='1' ry='1' style='fill:rgb(0, 120, 173);'/><path style='fill:white;' d='M 3.62,1 H 12.4 C 13.8,1 15,2.35 15,4 V 12 C 15,13.7 13.8,15 12.4,15 H 3.62 C 2.18,15 1,13.7 1,12 V 4 C 1.01,2.35 2.18,1.01 3.62,1 Z M 13.2,12 V 4 C 13.2,3.44 12.9,3 12.4,3 H 8 V 13 H 12.4 C 12.9,13 13.2,12.5 13.2,12 Z M 2.75,12 C 2.75,12.5 3.14,13 3.62,13 H 7.12 V 3 H 3.62 C 3.14,3 2.75,3.44 2.75,4 Z' /><path style='fill:white;' d='M 4.33,5 H 5.67 C 5.85,5 6,4.78 6,4.5 6,4.22 5.85,4 5.67,4 H 4.33 C 4.15,4 4,4.22 4,4.5 4,4.78 4.15,5 4.33,5 Z M 4.33,7 H 5.67 C 5.85,7 6,6.77 6,6.5 6,6.23 5.85,6 5.67,6 H 4.33 C 4.15,6 4,6.23 4,6.5 4,6.77 4.15,7 4.33,7 Z M 5,9 H 5.67 C 5.85,9 6,8.78 6,8.5 6,8.23 5.85,8 5.67,8 H 5 C 4.82,8 4.67,8.23 4.67,8.5 4.67,8.78 4.82,9 5,9 Z' /></g></svg>",
    pref = "extensions.ucf.sidebar_tabs.auto_hide";

    var sidebar_tabs_button = {
        get style() {
            delete this.style;
            return this.style = "data:text/css;charset=utf-8," + encodeURIComponent(`
            #st_toolbox {
                --v-sidebar-min-width: 2px;
                --v-sidebar-min-width-normal: 5px;
                --v-sidebar-max-width: 30em;
                --v-sidebar-transition-delay-show: .3s;
                --v-sidebar-transition-delay-hide: .6s;
                --v-sidebar-transition-duration: .3s;
                /* ********************************************** */

                position: relative !important;
                z-index: 1 !important;
                min-width: var(--v-sidebar-max-width) !important;
                width: var(--v-sidebar-max-width) !important;
                max-width: var(--v-sidebar-max-width) !important;
                overflow: hidden !important;
                opacity: 0 !important;
                --v-sidebar-margin-max-width: calc(-1 * var(--v-sidebar-max-width));
                --v-sidebar-margin-left-locale-dir: 0;
                --v-sidebar-margin-right-locale-dir: var(--v-sidebar-margin-max-width);
                --v-sidebar-transform-locale-dir: -1;
                --v-sidebar-transform-locale-dir-visible: 1;
                margin-left: var(--v-sidebar-margin-left-locale-dir) !important;
                margin-right: var(--v-sidebar-margin-right-locale-dir) !important;
                transform: translateX(calc(var(--v-sidebar-transform-locale-dir) * (var(--v-sidebar-max-width) - var(--v-sidebar-min-width)))) !important;
                transition-timing-function: linear, step-start !important;
                transition-delay: var(--v-sidebar-transition-delay-hide), calc(var(--v-sidebar-transition-delay-hide) + var(--v-sidebar-transition-duration)) !important;
                transition-duration: var(--v-sidebar-transition-duration), 0s !important;
                transition-property: transform, opacity !important;
                border-inline-end: 1px solid var(--chrome-content-separator-color, rgba(127,127,127,.5)) !important;
            }

            *|*:root[sidebar_tabs_right="true"] #st_toolbox {
                border-inline-start: 1px solid var(--chrome-content-separator-color, rgba(127,127,127,.5)) !important;
                border-inline-end: none !important;
            }

            *|*:root[sidebar_tabs_right="true"] #st_toolbox,
            #st_toolbox:-moz-locale-dir(rtl) {
                --v-sidebar-margin-left-locale-dir: var(--v-sidebar-margin-max-width);
                --v-sidebar-margin-right-locale-dir: 0;
                --v-sidebar-transform-locale-dir: 1;
                --v-sidebar-transform-locale-dir-visible: -1;
            }

            *|*:root[sidebar_tabs_right="true"] #st_toolbox:-moz-locale-dir(rtl) {
                --v-sidebar-margin-left-locale-dir: 0;
                --v-sidebar-margin-right-locale-dir: var(--v-sidebar-margin-max-width);
                --v-sidebar-transform-locale-dir: -1;
                --v-sidebar-transform-locale-dir-visible: 1;
            }

            *|*:root[sizemode="normal"] #st_toolbox {
                --v-sidebar-min-width: var(--v-sidebar-min-width-normal) !important;
            }

            #st_toolbox:hover,
            #st_toolbox[sidebardrag] {
                transform: translateX(0px) !important;
                opacity: 1 !important;
                transition-delay: var(--v-sidebar-transition-delay-show) !important;
            }

            *|*:root[v_vertical_bar_visible][v_vertical_bar_start="true"][sidebar_tabs_right="false"] #st_toolbox,
            *|*:root[v_vertical_bar_visible][v_vertical_bar_start="false"][sidebar_tabs_right="true"] #st_toolbox {
                transform: translateX(calc(var(--v-sidebar-transform-locale-dir-visible) * var(--v-vertical_bar_width, 0px))) !important;
                opacity: 1 !important;
                transition-delay: 0s !important;
            }

            #browser > #st_splitter {
                display: none !important;
            }
            `);
        },
        loadstyle(win) {
            try {
                win.windowUtils.loadSheetUsingURIString(this.style, win.windowUtils.USER_SHEET);
            } catch (e) {}
        },
        removestyle(win) {
            try {
                win.windowUtils.removeSheetUsingURIString(this.style, win.windowUtils.USER_SHEET);
            } catch (e) {}
        },
    };
    CustomizableUI.createWidget({
        id: "sidebar_tabs_button",
        label: label,
        tooltiptext: tooltiptext,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        localized: false,
        onBeforeCreated(doc) {
            if (Services.prefs.getBoolPref(pref, true))
                sidebar_tabs_button.loadstyle(doc.defaultView);
        },
        onCreated: function(btn) {
            btn.style.setProperty("list-style-image", `url("${img}")`);
        },
        onCommand: function(e) {
            if (!e.shiftKey)
                e.target.sidebar_tabs_toggle();
            else {
                let prf = Services.prefs.getBoolPref(pref, true),
                loadremove = !prf ? "loadstyle" : "removestyle";
                Services.prefs.setBoolPref(pref, !prf);
                for (let win of CustomizableUI.windows)
                    sidebar_tabs_button[loadremove](win);
            }
        }
    });
})();} catch(e) {}

и обновите ucf_SidebarTabs.js

Отредактировано Vitaliy V. (10-09-2020 01:26:12)

Отсутствует

 

№913310-09-2020 02:03:36

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

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V.
А для Save-To-Read можете сделать тёмную тему?

Отсутствует

 

№913410-09-2020 08:20:55

razoo
Участник
 
Группа: Members
Зарегистрирован: 23-07-2009
Сообщений: 48
UA: Firefox 78.0

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V. пишет

если не путать #tabs-newtab-button

Холмс, но как?!...
Получается, в интерфейсе спрятаны две совершенно одинаковые по виду и функции кнопки, отличающиеся лишь поведением... Прямо "Сокровища Агры" с близнецами.
Vitaliy V.
Ещё одно Глобальное Спасибо.
А что насчет превращения "Recently Closed Tabs" в дропмаркер на тулбаре? Если скажете "невозможно", значит невозможно.

Отсутствует

 

№913510-09-2020 10:44:26

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

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V.
Спасибо. Так тоже хорошо.
   
Заметил, что ширина заданная в ucf_SidebarTabs.js не влияет на вкладку закладок, она всегда шире чем другие вкладки, после перезагрузки скрипта.

Отсутствует

 

№913610-09-2020 13:14:15

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

Re: Настройка внешнего вида Firefox в userChrome.css

voqabuhe

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

Выделить код

Код:

@-moz-document regexp("moz-extension:\/\/.*\/(?:src\/sidebar|src\/popup)\.html") {
html {
background: #f5f6f7 !important;
color: #18191a !important;
--v-input-border-color: #cccccc;
--v-input-background-color: rgba(255,255,255,0.8);
--v-input-background-color-hover: rgba(204,204,204,.35);
--v-input-background-color-active: rgba(204,204,204,.5);
--v-input-background-color-focus: #ffffff;
--v-highlight-background-color: #0074e8;
--v-highlight-background-color-hover: #178bff;
--v-highlight-background-color-active: #0059e8;
--v-highlight-color: #ffffff;
--v-scrollbar-color: var(--v-highlight-background-color) #ffffff;
font: message-box;
margin: 0 !important;
}
@media (prefers-color-scheme: dark) {
html {
background: #18181a !important;
color: #b1b1b3 !important;
--v-input-border-color: #3c3c3d;
--v-input-background-color: rgba(0,0,0,0.5);
--v-input-background-color-hover: rgba(249,249,250,.1);
--v-input-background-color-active: rgba(249,249,250,.15);
--v-input-background-color-focus: #000000;
--v-scrollbar-color: var(--v-highlight-background-color) #000000;
}
}
body {
margin: 0 !important;
background: none !important;
color: inherit !important;
}
html, body, .s2r-table-container {
scrollbar-width: thin !important;
scrollbar-color: var(--v-scrollbar-color) !important;
}
input[type="search"],
select {
-moz-appearance: none !important;
border: 1px solid var(--v-input-border-color) !important;
background-color: var(--v-input-background-color) !important;
background-clip: border-box !important;
color: inherit !important;
padding: 1px 2px !important;
height: auto !important;
min-height: 22px !important;
box-shadow: none !important;
border-radius: 0 !important;
outline: none !important;
font-size: inherit !important;
font-family: inherit !important;
margin: 0 !important;
}
select {
-moz-appearance: none !important;
background: none !important;
}
input[type="search"]:focus {
border-color: var(--v-highlight-background-color) !important;
background-color: var(--v-input-background-color-focus) !important;
}
select:focus {
border-color: var(--v-highlight-background-color) !important;
}
select:hover {
border-color: var(--v-input-border-color) !important;
background-color: var(--v-input-background-color-hover) !important;
}
select:hover:active {
background-color: var(--v-input-background-color-active) !important;
}
input[type="search"]::selection {
background-color: var(--v-highlight-background-color) !important;
color: var(--v-highlight-color) !important;
}
.s2r-table-container {
border-color: var(--v-input-border-color) !important;
}
.filter-sort {
padding: 2px;
margin: 0 !important;
width: auto !important;
}
.sort {
margin-left: 2px !important;
}
.cell {
min-height: 16px;
margin-block: 2px !important;
}
}

razoo пишет

А что насчет превращения "Recently Closed Tabs" в дропмаркер на тулбаре? Если скажете "невозможно", значит невозможно.

Стилем что-ли? конечно невозможно, а если скриптом то я выкладывал уже кнопку https://forum.mozilla-russia.org/viewto … 32#p784332

_zt пишет

Заметил, что ширина заданная в ucf_SidebarTabs.js не влияет на вкладку закладок, она всегда шире чем другие вкладки, после перезагрузки скрипта

Ширина заданная в ucf_SidebarTabs.js влияет только на дефолтное состояние когда ещё нет настроек в about:config - extensions.ucf.sidebar_tabs.toolbox_width(0|1|2) для каждого таба. Просто мышкой при перетаскивании за splitter настройте ширину какую надо для каждого таба и она сохранится в about:config, кстати обновил опять ucf_SidebarTabs.js, убрал атрибут collapse у splitter чтобы не сворачивал панель.
А если включен стиль auto hide то ширину надо настраивать в нём.

Отредактировано Vitaliy V. (10-09-2020 13:34:06)

Отсутствует

 

№913710-09-2020 18:21:46

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

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V.
Разобрался. Отлично получилось. Спасибо, еще раз.

Отсутствует

 

№913811-09-2020 04:50:56

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

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V.
Спасибо большое! Замечательно получилось.

Отредактировано voqabuhe (11-09-2020 04:51:23)

Отсутствует

 

№913915-09-2020 08:25:57

razoo
Участник
 
Группа: Members
Зарегистрирован: 23-07-2009
Сообщений: 48
UA: Firefox 78.0

Re: Настройка внешнего вида Firefox в userChrome.css

Добрый день всем.
Если добавить chrome://browser/content/places/places.xhtml в закладки, то Library будет открываться не в новом окне, а в табе. При этом всё работает, кроме создания новой папки. Похоже, что окошко bookmarkProperties просто не вызывается, если журнал открыт во вкладке.
(Из-за невызываемого окошка создание нового букмарка вручную там тоже не работает, но это практически неиспользуемая функция, ибо шорткат унд драг-энд-дроп.)
Если  bookmarkProperties.xhtml все же вызывается, но где-то прячется, то можно ли с помощью стиля показать его "на поверхности"? Или это только инжектом скриптов чинится?

Отсутствует

 

№914017-09-2020 01:37:11

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

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V.
Спасибо большое за обновление Add Toolbar Buttons и добавление кнопки Дополнения. Прикольно что добавили в кнопку возможность управления темами. Вот только хотелось, чтоб меню не закрывалось при каждом переключение темы. И на мой взгляд хорошо бы их отсортировать в низ списка, под дополнениями, чтоб они были все в одном месте и не путались с расширеними.

Отредактировано voqabuhe (17-09-2020 01:45:25)

Отсутствует

 

№914117-09-2020 12:54:22

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

Re: Настройка внешнего вида Firefox в userChrome.css

обновил Add Toolbar Buttons, почти все добавил, изменил то что спрашивали

Отредактировано Vitaliy V. (18-09-2020 16:42:20)

Отсутствует

 

№914217-09-2020 15:27:15

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

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V.
Может еще опций отображения добавить? Просто опишу свое видение этого меню:
В подсказке - описание и тип, как по мне, только место занимают. Заголовок "Разрешения" - выглядит лишним. И так понятно, что это разрешения. Например, у описания же нету заголовка "Описание". ID и UUID там понятно, без заголовка можно спутать.
Темы и лангпаки - тоже не всем нужны. Мне точно не нужны, английский лангпак только зря ширину меню увеличивает на десяток символов. Если конечно ширина зависит от длины имен элементов (лучше бы зависела, до определенного максимума).
И хорошо бы цветовое выделение добавить отключенным расширениям, в виде опции.
СКМ - "открыть менеджер дополнений". Ну почему СКМ? )
   
Для меня смысл меню не отобразить все, а отобразить то что может потребоваться отключить или быстро настроить. Ни тему, ни лангпак я никогда переключать не буду. А вот скрытые пригодятся, вдруг при обновлении удалить что то забуду.

Отсутствует

 

№914318-09-2020 18:22:39

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

Re: Настройка внешнего вида Firefox в userChrome.css

Если кому нужна отдельно кнопка Дополнения как в Add Toolbar Buttons то вот для custom_script.js

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

Отредактировано Vitaliy V. (07-05-2022 12:12:25)

Отсутствует

 

№914418-09-2020 18:48:02

sandro79
Участник
 
Группа: Members
Зарегистрирован: 15-11-2017
Сообщений: 1750
UA: Firefox 80.0

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V. пишет

Если кому нужна отдельно кнопка Дополнения как в Add Toolbar Buttons то вот для custom_script.js

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

Выделить код

Код:

try {(() => {
    var id = "ucf-aom-button",
    label = "Дополнения",
    tooltiptext = "ЛКМ: Меню дополнений\nShift+ЛКМ: Меню дополнений + открыть менеджер\nСКМ: Открыть менеджер дополнений",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 24,4.5 18,12 3,23.7 12,32.7 3.9,44.1 7.8,48 H 45 C 46.7,48 48,46.7 48,45 V 26.1 L 34.8,12.9 31.8,12.3 Z'/><path style='fill:white;' d='M 19.88,3 C 16.93,3 14.55,4.662 14.55,6.701 14.63,7.474 15.11,8.438 15.37,8.762 16.59,10.41 16.59,11.44 16.29,12.06 H 6.299 C 4.476,12.06 3,13.53 3,15.35 V 23.68 C 3.625,24 4.65,24 6.299,22.77 6.625,22.52 7.587,22.02 8.363,21.94 10.4,21.94 12.06,24.35 12.06,27.29 12.06,30.24 10.4,32.65 8.363,32.65 7.725,32.63 6.774,32.07 6.299,31.82 4.65,30.59 3.625,30.59 3,30.91 V 41.71 C 3,43.53 4.476,45 6.299,45 H 19.58 C 19.88,44.38 19.88,43.35 18.65,41.71 18.4,41.38 17.91,40.42 17.82,39.65 17.82,37.6 20.23,35.94 23.18,35.94 26.14,35.94 28.55,37.6 28.55,39.65 28.53,40.28 27.97,41.23 27.71,41.71 26.47,43.35 26.47,44.38 26.79,45 H 32.65 C 34.47,45 35.96,43.53 35.96,41.71 V 32.55 C 36.56,32.23 37.59,32.23 39.23,33.47 39.72,33.73 40.68,34.29 41.29,34.29 43.35,34.29 45,31.91 45,28.94 45,25.99 43.35,23.59 41.29,23.59 40.54,23.67 39.58,24.17 39.23,24.41 37.59,25.65 36.56,25.65 35.96,25.33 V 15.35 C 35.96,13.53 34.47,12.06 32.65,12.06 H 23.49 C 23.19,11.44 23.19,10.41 24.41,8.762 24.66,8.287 25.22,7.337 25.23,6.713 25.23,4.662 22.85,3 19.88,3' /></g></svg>",
    checked = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='M 4,5 7.5,8.5 12,4 V 8 L 8,12 H 7 L 4,9 Z' style='fill:white'/></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([

    ]);
    if (!("AddonManager" in this))
        ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
    if (!("GlobalManager" in this))
        XPCOMUtils.defineLazyGetter(this, "GlobalManager", () => {
            const { GlobalManager } = ChromeUtils.import("resource://gre/modules/Extension.jsm", null);
            return GlobalManager;
        });
    var 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));
        },
        populateMenu: async function(e) {
            var popup = e.target, doc = e.view.document;
            var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr);
            var addonsMap = new WeakMap(),
            setAttributesMenu = (mi, addon, extension) => {
                var permissions, uuid,
                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}`);
            };
            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) => {
                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", (e) => {
                AddonManager.removeAddonListener(listener);
                popup.removeEventListener("click", click);
                addonsMap = null;
                while (popup.hasChildNodes())
                    popup.firstChild.remove();
            }, { once: true });
        },
        handleClick: function(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);
                        try {
                            this.alertsService.showAlertNotification(`${img}`, "ID в буфере обмена!", addon.id, false);
                        } catch(e) {}
                    } else if (e.shiftKey) {
                        if (extension?.uuid) {
                            this.clipboardHelp.copyString(extension.uuid);
                            try {
                                this.alertsService.showAlertNotification(`${img}`, "UUID в буфере обмена!", extension.uuid, false);
                            } catch(e) {}
                        }
                    } 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 && Services.prompt.confirm(win, null, `Удалить ${addon.name}?`))
                        addon.uninstall();
                break;
            }
        },
        openAddonOptions: function(addon, win) {
            switch (addon.optionsType) {
                case 5:
                    win.BrowserOpenAddonsMgr(`addons://detail/${encodeURIComponent(addon.id)}/preferences`);
                    break;
                case 3:
                    win.switchToTabHavingURI(addon.optionsURL, true);
                    break;
            }
        },
        browseDir: function(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: function(win, url, params = {}) {
            params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
            params.relatedToCurrent = true;
            return win.gBrowser.addTab(url, params);
        },
    };
    CustomizableUI.createWidget({
        id: id,
        type: "custom",
        label: label,
        tooltiptext: tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onBuild: function(doc) {
            var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView,
            props = {
                id: id,
                label: label,
                tooltiptext: 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 == 0) {
                    if (e.shiftKey)
                        win.BrowserOpenAddonsMgr();
                } else if (e.button == 1)
                    win.BrowserOpenAddonsMgr();
            });
            var mp = doc.createXULElement("menupopup");
            mp.id = `${id}-popup`;
            mp.addEventListener("click", (e) => {
                e.preventDefault();
                e.stopPropagation();
            });
            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}, #${id}-popup menuitem {
                    list-style-image: url("${img}") !important;
                }
                #${id}-popup menuitem::after {
                    display: -moz-box !important;
                    content: "" !important;
                    height: 16px !important;
                    width: 16px !important;
                    padding: 0 !important;
                    border: 1px solid rgb(0, 116, 232) !important;
                    border-radius: 0 !important;
                    background-repeat: no-repeat !important;
                    background-position: center !important;
                    background-size: 16px !important;
                    background-color: rgb(0, 116, 232) !important;
                    background-image: url("${checked}") !important;
                    opacity: 1 !important;
                }
                #${id}-popup menuitem.ucf-disabled::after {
                    border-color: currentColor !important;
                    background-color: transparent !important;
                    background-image: none !important;
                    opacity: .6 !important;
                }
                #${id}-popup menuitem.ucf-disabled > label,
                #${id}-popup menuitem.ucf-notoptions > label {
                    opacity: .6 !important;
                }
                #${id}-popup menuitem.ucf-system > label {
                    text-decoration: underline !important;
                    text-decoration-style: dotted !important;
                }
                #${id}-popup menuitem > label {
                    margin-inline-end: 0 !important;
                }
                #${id}-popup menuitem > .menu-accel-container {
                    display: -moz-box !important;
                    padding: 4px !important;
                    margin: 0 !important;
                    opacity: 1 !important;
                }
                #${id}-popup menuitem > .menu-accel-container .menu-iconic-accel {
                    display: -moz-box !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;
                }
                #${id}-popup menuitem.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel {
                    background-color: rgb(227, 27, 93) !important;
                }
                #${id}-popup menuitem.ucf-type-locale > .menu-accel-container .menu-iconic-accel {
                    background-color: rgb(48, 172, 55) !important;
                }
                #${id}-popup menuitem.ucf-type-theme > .menu-accel-container .menu-iconic-accel {
                    background-color: rgb(219, 106, 0) !important;
                }
            `);
            try {
                win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET);
            } catch (e) {}
            return btn;
        },
    });
})();} catch (e) {}

Конечно же нужна. Эта ещё круче прежней! Огромное Спасибо! :beer:


Обновлённый код с правкой для 101+

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

Выделить код

Код:

try {(() => {
    var id = "ucf-aom-button",
    label = "Дополнения",
    tooltiptext = "ЛКМ: Меню дополнений\nShift+ЛКМ: Меню дополнений + открыть менеджер\nСКМ: Открыть менеджер дополнений",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 24,4.5 18,12 3,23.7 12,32.7 3.9,44.1 7.8,48 H 45 C 46.7,48 48,46.7 48,45 V 26.1 L 34.8,12.9 31.8,12.3 Z'/><path style='fill:white;' d='M 19.88,3 C 16.93,3 14.55,4.662 14.55,6.701 14.63,7.474 15.11,8.438 15.37,8.762 16.59,10.41 16.59,11.44 16.29,12.06 H 6.299 C 4.476,12.06 3,13.53 3,15.35 V 23.68 C 3.625,24 4.65,24 6.299,22.77 6.625,22.52 7.587,22.02 8.363,21.94 10.4,21.94 12.06,24.35 12.06,27.29 12.06,30.24 10.4,32.65 8.363,32.65 7.725,32.63 6.774,32.07 6.299,31.82 4.65,30.59 3.625,30.59 3,30.91 V 41.71 C 3,43.53 4.476,45 6.299,45 H 19.58 C 19.88,44.38 19.88,43.35 18.65,41.71 18.4,41.38 17.91,40.42 17.82,39.65 17.82,37.6 20.23,35.94 23.18,35.94 26.14,35.94 28.55,37.6 28.55,39.65 28.53,40.28 27.97,41.23 27.71,41.71 26.47,43.35 26.47,44.38 26.79,45 H 32.65 C 34.47,45 35.96,43.53 35.96,41.71 V 32.55 C 36.56,32.23 37.59,32.23 39.23,33.47 39.72,33.73 40.68,34.29 41.29,34.29 43.35,34.29 45,31.91 45,28.94 45,25.99 43.35,23.59 41.29,23.59 40.54,23.67 39.58,24.17 39.23,24.41 37.59,25.65 36.56,25.65 35.96,25.33 V 15.35 C 35.96,13.53 34.47,12.06 32.65,12.06 H 23.49 C 23.19,11.44 23.19,10.41 24.41,8.762 24.66,8.287 25.22,7.337 25.23,6.713 25.23,4.662 22.85,3 19.88,3' /></g></svg>",
    checked = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='M 4,5 7.5,8.5 12,4 V 8 L 8,12 H 7 L 4,9 Z' style='fill:white'/></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([

    ]);
    if (!("AddonManager" in this))
        ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm");
    if (!("GlobalManager" in this))
        XPCOMUtils.defineLazyGetter(this, "GlobalManager", () =>
    ChromeUtils.import("resource://gre/modules/ExtensionParent.jsm").ExtensionParent.GlobalManager);
    var 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));
        },
        populateMenu: async function(e) {
            var popup = e.target, doc = e.view.document;
            var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr);
            var addonsMap = new WeakMap(),
            setAttributesMenu = (mi, addon, extension) => {
                var permissions, uuid,
                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}`);
            };
            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) => {
                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", (e) => {
                AddonManager.removeAddonListener(listener);
                popup.removeEventListener("click", click);
                addonsMap = null;
                while (popup.hasChildNodes())
                    popup.firstChild.remove();
            }, { once: true });
        },
        handleClick: function(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);
                        try {
                            this.alertsService.showAlertNotification(`${img}`, "ID в буфере обмена!", addon.id, false);
                        } catch(e) {}
                    } else if (e.shiftKey) {
                        if (extension?.uuid) {
                            this.clipboardHelp.copyString(extension.uuid);
                            try {
                                this.alertsService.showAlertNotification(`${img}`, "UUID в буфере обмена!", extension.uuid, false);
                            } catch(e) {}
                        }
                    } 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 && Services.prompt.confirm(win, null, `Удалить ${addon.name}?`))
                        addon.uninstall();
                break;
            }
        },
        openAddonOptions: function(addon, win) {
            switch (addon.optionsType) {
                case 5:
                    win.BrowserOpenAddonsMgr(`addons://detail/${encodeURIComponent(addon.id)}/preferences`);
                    break;
                case 3:
                    win.switchToTabHavingURI(addon.optionsURL, true);
                    break;
            }
        },
        browseDir: function(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: function(win, url, params = {}) {
            params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
            params.relatedToCurrent = true;
            return win.gBrowser.addTab(url, params);
        },
    };
    CustomizableUI.createWidget({
        id: id,
        type: "custom",
        label: label,
        tooltiptext: tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onBuild: function(doc) {
            var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView,
            props = {
                id: id,
                label: label,
                tooltiptext: 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 == 0) {
                    if (e.shiftKey)
                        win.BrowserOpenAddonsMgr();
                } else if (e.button == 1)
                    win.BrowserOpenAddonsMgr();
            });
            var mp = doc.createXULElement("menupopup");
            mp.id = `${id}-popup`;
            mp.addEventListener("click", (e) => {
                e.preventDefault();
                e.stopPropagation();
            });
            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}, #${id}-popup menuitem {
                    list-style-image: url("${img}") !important;
                }
                #${id}-popup menuitem::after {
                    display: -moz-box !important;
                    content: "" !important;
                    height: 16px !important;
                    width: 16px !important;
                    padding: 0 !important;
                    border: 1px solid rgb(0, 116, 232) !important;
                    border-radius: 0 !important;
                    background-repeat: no-repeat !important;
                    background-position: center !important;
                    background-size: 16px !important;
                    background-color: rgb(0, 116, 232) !important;
                    background-image: url("${checked}") !important;
                    opacity: 1 !important;
                }
                #${id}-popup menuitem.ucf-disabled::after {
                    border-color: currentColor !important;
                    background-color: transparent !important;
                    background-image: none !important;
                    opacity: .6 !important;
                }
                #${id}-popup menuitem.ucf-disabled > label,
                #${id}-popup menuitem.ucf-notoptions > label {
                    opacity: .6 !important;
                }
                #${id}-popup menuitem.ucf-system > label {
                    text-decoration: underline !important;
                    text-decoration-style: dotted !important;
                }
                #${id}-popup menuitem > label {
                    margin-inline-end: 0 !important;
                }
                #${id}-popup menuitem > .menu-accel-container {
                    display: -moz-box !important;
                    padding: 4px !important;
                    margin: 0 !important;
                    opacity: 1 !important;
                }
                #${id}-popup menuitem > .menu-accel-container .menu-iconic-accel {
                    display: -moz-box !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;
                }
                #${id}-popup menuitem.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel {
                    background-color: rgb(227, 27, 93) !important;
                }
                #${id}-popup menuitem.ucf-type-locale > .menu-accel-container .menu-iconic-accel {
                    background-color: rgb(48, 172, 55) !important;
                }
                #${id}-popup menuitem.ucf-type-theme > .menu-accel-container .menu-iconic-accel {
                    background-color: rgb(219, 106, 0) !important;
                }
            `);
            try {
                win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET);
            } catch (e) {}
            return btn;
        },
    });
})();} catch (e) {}

Проверено и работоспособно на 78, 91 и 103 [nightly]

Отредактировано sandro79 (31-05-2022 13:17:51)

Отсутствует

 

№914519-09-2020 02:26:05

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

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V. пишет

обновил Add Toolbar Buttons, почти все добавил, изменил то что спрашивали

Круто, ну очень круто.  Просто великолепная кнопка получилась. Темы теперь очень удобно переключать. Спасибо большое!

Отсутствует

 

№914621-09-2020 22:18:02

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

Re: Настройка внешнего вида Firefox в userChrome.css

egorsemenov06
https://forum.mozilla-russia.org/viewto … 07#p785107

Отредактировано Vitaliy V. (15-12-2021 15:03:02)

Отсутствует

 

№914722-09-2020 12:12:23

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

Re: Настройка внешнего вида Firefox в userChrome.css

egorsemenov06 пишет

так у меня не заработали сочетания Ctrl+ЛКМ и Shift+ЛКМ

Проверил ещё раз, всё работает,
только заменил #appMenu-viewCache на template#appMenu-viewCache чтобы в [firefox] 74 - 79 тоже работало.

Отредактировано Vitaliy V. (22-09-2020 12:28:58)

Отсутствует

 

№914822-09-2020 20:28:10

sandro79
Участник
 
Группа: Members
Зарегистрирован: 15-11-2017
Сообщений: 1750
UA: Firefox 80.0

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V. пишет

только заменил #appMenu-viewCache на template#appMenu-viewCache чтобы в [firefox] 74 - 79 тоже работало

Виталий, а можно сделать чтоб было как в user_chrome_files, те же самые команды и в той же последовательности как в user_chrome_files, по ЛКМ, СКМ и ПКМ в appMenu для 78 - 80? Очень хочется заменить эту кнопку на Вашу.
Использую как резервную, если не туда мышкой попал, что частенько случается, одна в "Другие инструменты", другая в Гамбургер-меню.

Скрин и используемый сейчас в 80 чуть подправленный под себя скрипт
e5eb125966a7.png

Выделить код

Код:

// Restart item script for Firefox 60+ by Aris
//
// left-click on restart item: normal restart
// middle-click on restart item: restart + clear caches
// right-click on restart item: no special function
//
// based on 'addRestartButton.uc.js' script by Alice0775
// restart code from Classic Theme Restorer add-on
// invalidate caches from Session Saver add-on

var {Services} = Components.utils.import("resource://gre/modules/Services.jsm", {});
var appversion = parseInt(Services.appinfo.version);

var RestartMenuFileAppItems = {
  init: function() {

	var button_label = "Перезапуск";
	
	try {
	  switch (document.getElementById("nav-bar").getAttribute("aria-label")) {
		case "Navigations-Symbolleiste": button_label = "Neustarten"; break;
		case "Панель навигации": button_label = "Перезапустить"; break;
	  }
	} catch(e) {}

	try {
	  if(appversion <= 62) restartitem_filemenu = document.createElement("menuitem");
	  else restartitem_filemenu = document.createXULElement("menuitem");
	  restartitem_filemenu.setAttribute("label", button_label);
	  restartitem_filemenu.setAttribute("id","fileMenu-restart-item");
	  restartitem_filemenu.setAttribute("key", "R");
	  restartitem_filemenu.setAttribute("insertbefore", "menu_FileQuitItem");
	  restartitem_filemenu.setAttribute("onclick", "if (event.button == 0) {RestartMenuFileAppItems.restartApp(false);} else if (event.button == 1) {RestartMenuFileAppItems.restartApp(true)};");
	  restartitem_filemenu.setAttribute("oncommand", "RestartMenuFileAppItems.restartApp(false);");

	  if(document.getElementById("menu_FileQuitItem").previousSibling.id != "fileMenu-restart-item" )
		document.getElementById("menu_FileQuitItem").parentNode.insertBefore(restartitem_filemenu,document.getElementById("menu_FileQuitItem"));
	} catch(e) {}

	try {
	  if(appversion <= 62) restartitem_appmenu = document.createElement("toolbarbutton");
	  else restartitem_appmenu = document.createXULElement("toolbarbutton");
	  restartitem_appmenu.setAttribute("label", button_label);
	  restartitem_appmenu.setAttribute("id","appMenu-restart-button");
	  restartitem_appmenu.setAttribute("class","subviewbutton subviewbutton-iconic");
	  restartitem_appmenu.setAttribute("key", "R");
	  restartitem_appmenu.setAttribute("insertbefore", "appMenu-quit-button");
	  restartitem_appmenu.setAttribute("onclick", "if (event.button == 0) {RestartMenuFileAppItems.restartApp(false);} else if (event.button == 1) {RestartMenuFileAppItems.restartApp(true)};");
	  restartitem_appmenu.setAttribute("oncommand", "RestartMenuFileAppItems.restartApp(false);");

	  if(document.getElementById("appMenu-quit-button").previousSibling.id != "appMenu-restart-button" )
		document.getElementById("appMenu-quit-button").parentNode.insertBefore(restartitem_appmenu,document.getElementById("appMenu-quit-button"));
	} catch(e) {}

	var sss = Components.classes["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService);

	// style button icon
	var uri = Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent('\
	  \
	  #appMenu-restart-button {\
		list-style-image: url("chrome://browser/skin/reload.svg"); /* icon / path to icon */ \
	  }\
	  #appMenu-restart-button .toolbarbutton-icon {\
		color: red; /* icon color name/code */\
	  }\
	  \
	'), null, null);

	sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
	
  },

  restartApp: function(clearcaches) {

	var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].createInstance(Components.interfaces.nsISupportsPRBool);
	var observerSvc = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);

	if(clearcaches) {
	  Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).invalidateCachesOnRestart();
	}

	observerSvc.notifyObservers(cancelQuit, "quit-application-requested", "restart");

	if(cancelQuit.data) return false;

	Services.startup.quit(Services.startup.eRestart | Services.startup.eAttemptQuit);

  }

}

RestartMenuFileAppItems.init();


Виталий, и можно чтоб кнопка была красного цвета, как у Aris-a. Спасибо заранее.

Отредактировано sandro79 (22-09-2020 20:58:24)

Отсутствует

 

№914923-09-2020 00:13:04

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

Re: Настройка внешнего вида Firefox в userChrome.css

sandro79
про классическое меню ничего не сказано но добавил и туда на всякий случай

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

Выделить код

Код:

(async (
    id = Symbol("menusrestartitems"),
    btnID = "ucf-appmenu-restart-button",
    muimID = "ucf_menu_FileRestartItem",
) => (this[id] = {
    init() {
        var abtn = document.querySelector("template#appMenu-viewCache")?.content.querySelector("#appMenu-quit-button2");
        if (abtn) {
            let frag = MozXULElement.parseXULToFragment(`<toolbarbutton/>`);
            let btn = this.btn = frag.firstElementChild;
            btn.id = btnID;
            btn.className = "subviewbutton";
            btn.setAttribute("label", "Перезапуск");
            btn.setAttribute("tooltiptext", "ЛКМ: Перезапустить приложение\nСКМ: Перезапустить без дополнений\nПКМ: Перезапустить и заново создать кэш быстрого запуска");
            btn.setAttribute("shortcut", "Ctrl+Alt+Q");
            btn.addEventListener("click", this);
            abtn.before(frag);
        }
        var aftermuim = document.querySelector("#menu_FilePopup #menu_FileQuitItem");
        if (aftermuim) {
            let muim = this.muim = document.createXULElement("menuitem");
            muim.id = muimID;
            muim.className = "menuitem-iconic";
            muim.setAttribute("label", "Перезапуск");
            muim.setAttribute("tooltiptext", "ЛКМ: Перезапустить приложение\nСКМ: Перезапустить без дополнений\nПКМ: Перезапустить и заново создать кэш быстрого запуска");
            muim.setAttribute("acceltext", "Ctrl+Alt+Q");
            muim.setAttribute("context", "");
            muim.addEventListener("click", this);
            aftermuim.before(muim);
        }
        var style = "data:text/css;charset=utf-8," + encodeURIComponent(`
            #${btnID}, #${muimID} {
                list-style-image: url("chrome://global/skin/icons/reload.svg") !important;
                -moz-context-properties: fill;
                fill: color-mix(in srgb, currentColor 20%, #f38525) !important;
            }
        `);
        try {
            windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET);
        } catch (e) {}
        window.addEventListener("keydown", this);
        setUnloadMap(id, this.destructor, this);
    },
    click(e) {
        switch (e.button) {
            case 0:
                this._restart_mozilla();
                break;
            case 1:
                e.view.safeModeRestart();
                break;
            case 2:
                this._restart_mozilla(true);
                break;
        }
    },
    keydown(e) {
        if (e.code == "KeyQ" && e.ctrlKey && e.altKey)
            this._restart_mozilla();
    },
    _restart_mozilla(nocache = false) {
        var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool);
        Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart");
        if (cancelQuit.data)
            return false;
        if (nocache)
            Services.appinfo.invalidateCachesOnRestart();
        var {startup} = Services;
        startup.quit(startup.eAttemptQuit | startup.eRestart);
    },
    handleEvent(e) {
        this[e.type](e);
    },
    destructor() {
        window.removeEventListener("keydown", this);
        this.btn?.removeEventListener("click", this);
        this.muim?.removeEventListener("click", this);
    },
}).init())();

Отредактировано Vitaliy V. (Сегодня 18:07:53)

Отсутствует

 

№915023-09-2020 01:16:55

sandro79
Участник
 
Группа: Members
Зарегистрирован: 15-11-2017
Сообщений: 1750
UA: Firefox 80.0

Re: Настройка внешнего вида Firefox в userChrome.css

Vitaliy V. пишет

sandro79
про классическое меню ничего не сказано но добавил и туда на всякий случай

Да-да, там тоже лишним не будет. Огромное Вам Спасибо, подключил, всё отлично работает :beer: :rock:

скрытый текст
86cc5d966b98.png

Отсутствует

 

Board footer

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