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

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

№1532616-03-2021 10:27:06

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

Re: Custom Buttons

voqabuhe

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

Выделить код

Код:

(async (id, sel) => {
	var g = Cu.getGlobalForObject(Cu), stt = g[id];
	if (!stt) {
		var {obs, prefs} = Services, {bookmarks: bm, observers: pobs} = PlacesUtils;
		stt = g[id] = {
			bm,
			pref: `ucf.${id}Guid`,
			async init() {
				bm.addObserver(this);
				pobs.addListener(["bookmark-added"], this.added = events => {
					for(var e of events) this.record(e.itemType, e.source, e.parentGuid);
				});
				obs.addObserver(this, "quit-application-granted");
				this.args = [b => this.bguids.add(b.parentGuid), {concurrent: true}];
				var guid = prefs.getStringPref(this.pref, "");
				if (!guid) try {var [guid] = await PlacesUtils.metadata.get(
					PlacesUIUtils.LAST_USED_FOLDERS_META_KEY, []
				)} catch {}
				this.guids.push(guid || await PlacesUIUtils.defaultParentGuid || bm.unfiledGuid);
			},
			observe() {
				bm.removeObserver(this);
				pobs.removeListener(["bookmark-added"], this.added);
				obs.removeObserver(this, "quit-application-granted");
				prefs.setStringPref(this.pref, this.guids[0]);
			},
			skipTags: true,
			bguids: new g.Set(),
			guids: new g.Array(),
			QueryInterface: g.ChromeUtils.generateQI([Ci.nsINavBookmarkObserver]),
			record(type, src, guid) {
				if (type == bm.TYPE_BOOKMARK && src == bm.SOURCES.DEFAULT) this.guids[0] = guid;
			},
			onItemMoved(a, b, c, d, e, itemType, f, oldParentGuid, newParentGuid, source) {
				newParentGuid != oldParentGuid && this.record(itemType, source, newParentGuid);
			},
			fetch(win) {
				this.bguids.clear();
				return bm.fetch({url: win.gBrowser.currentURI.spec}, ...this.args);
			},
			tt(win) {
				var list = win.InspectorUtils
					.getChildrenForNode(win.document.documentElement, true);
				return list.item(list.length - 1);
			}
		};
		var ps = ["onBeginUpdateBatch", "onEndUpdateBatch", "onItemChanged", "onItemVisited"];
		var noop = () => {}; for(var p of ps) stt[p] = noop; stt.init();

		var func = id => this[id].handleEvent = async function(e) {
			var win = e.view;
			var star = e.target;
			star.tooltipText = "\u3164";
			var starred = star.hasAttribute("starred");
			starred && await this.fetch(win);
			var result = [];
			for(var guid of (starred ? this.bguids : this.guids)) {
				var arr = [], num = 50;
				while(--num) {
					if (!star.matches(":hover")) return;
					var res = await this.bm.fetch(guid);
					if (!res) break;
					if ((guid = res.parentGuid) == this.bm.rootGuid) {
						arr.unshift(this.bm.getLocalizedTitle(res));
						break;
					}
					arr.unshift(res.title || "[Безымянная папка]");
				}
				arr.length && result.push(arr.join("\\"));
			}
			if (!star.matches(":hover")) return;
			if (!result.length) return win.document.l10n.translateElements([star]);
			var text = result.join("\n");
			if (starred) {
				var m = result.length > 1;
				text = `Адрес${m ? "а" : ""} заклад${m ? "ок" : "ки"}:\n${text}`;
			}
			win.document.tooltipNode == star
				? this.tt(win).label = text : star.tooltipText = text;
		}
		var url = "data:;charset=utf-8," + encodeURIComponent(`(${func})("${id}")`);
		g.ChromeUtils.compileScript(url).then(ps => ps.executeInGlobal(g));
	}
	await delayedStartupPromise;
	var stars = Array.from(document.querySelectorAll(sel));
	for(var star of stars) star.addEventListener("mouseenter", stt);
	var destructor = () => {
		for(var star of stars) star.removeEventListener("mouseenter", stt);
	}
	var ucf = window.ucf_custom_script_win || window.ucf_custom_script_all_win;
	if (ucf)
		ucf[id] = {destructor},
		ucf.unloadlisteners.push(id);
	else
		window.addEventListener("unload", destructor, {once: true});
})("ucfBookmarksStarFTooltipHelper", "#star-button, #context-bookmarkpage");

Отсутствует

 

№1532716-03-2021 18:59:13

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

Re: Custom Buttons

Dumby, классно, всё работает идеально. Спасибо.

Отсутствует

 

№1532819-03-2021 12:05:01

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 152
UA: Firefox 86.0

Re: Custom Buttons

Dumby
Не могу этот красный hbox привязать к #BMB_unsortedBookmarksPopup , только отдельно...stylesheet ? custom_style_user.css - не помогает...Приходиться так:
hbox[part="innerbox"] {margin-left: 1px !important; border-left: none !important;  margin-top: -3px !important; margin-bottom: 0px !important;} Вроде как фуфлыжно...
hko2wh4b.jpg
Это здесь:
bpbhg9tn.jpg

Отредактировано ВВП (19-03-2021 12:09:35)

Отсутствует

 

№1532919-03-2021 14:51:47

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

Re: Custom Buttons

ВВП пишет

Не могу этот красный hbox привязать к #BMB_unsortedBookmarksPopup
custom_style_user.css - не помогает

У меня в custom_style_author.css работает.
(Не забудь галку в ucf-настройках для author проставить).

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

Выделить код

Код:

@-moz-document url(chrome://browser/content/browser.xhtml) {
	#BMB_unsortedBookmarksPopup::part(innerbox) {
		background-color: yellow !important;
		outline: 7px solid blue !important;
		outline-offset: -7px !important;
	}
}

Отредактировано Dumby (19-03-2021 14:52:49)

Отсутствует

 

№1533019-03-2021 16:10:32

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 152
UA: Firefox 86.0

Re: Custom Buttons

Dumby
От же,....в шаге был от разгадки. ::part(innerbox) - в этом вся фишка. Благодарю.

Отсутствует

 

№1533119-03-2021 17:42:18

hartumov
Участник
 
Группа: Members
Зарегистрирован: 17-11-2013
Сообщений: 127
UA: Firefox 85.0

Re: Custom Buttons

Подскажите пожалуйста. Вот есть где то в интернетах файл abcd.js. Он большой, а мне нужен оттуда маленький кусочек. Я делаю:

Выделить код

Код:

fetch (http://abcd.js )
  .then(resp => resp.text())
  .then(scr => { 
        let my_scr = scr.match(regexp)[0] // получаю нужный фрагмент из файла abcd.js, полностью он мне не нужен
    } )

Теперь есть у меня нужный фрагмент my_scr в виде строки. А как сделать, чтоб этот код начал выполняться в кнопке?

Отсутствует

 

№1533219-03-2021 23:06:35

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

Re: Custom Buttons

hartumov пишет

есть у меня нужный фрагмент my_scr в виде строки. А как сделать, чтоб этот код начал выполняться

eval? Не, никогда не слышал.

Отсутствует

 

№1533320-03-2021 01:46:09

hartumov
Участник
 
Группа: Members
Зарегистрирован: 17-11-2013
Сообщений: 127
UA: Firefox 85.0

Re: Custom Buttons

Dumby пишет
hartumov пишет

есть у меня нужный фрагмент my_scr в виде строки. А как сделать, чтоб этот код начал выполняться

eval? Не, никогда не слышал.

Пробовал. У меня этот eval блокируется. В консоли две ошибки:

Выделить код

Код:

eval() и eval-подобное использование других методов не разрешено
в Родительском процессе или в Системных контекстах (Использование заблокировано в
«chrome://custombuttons-context/content/button.js?windowId=Firefox&id=custombuttons-button3@init»)

и

Выделить код

Код:

Uncaught (in promise) EvalError: call to eval() blocked by CSP

И если это важно, добавлю, что у меня отключен мультипроцессорный режим.

Отредактировано hartumov (20-03-2021 01:52:13)

Отсутствует

 

№1533420-03-2021 06:30:33

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

Re: Custom Buttons

hartumov пишет

В консоли две ошибки

Ого! Не думал что такое (пока) встречается "в дикой природе".
Значит CB установлен на релиз или бету вылеченную не через config.js,
либо на билд изначально не нуждающийся в лечении (DE, Unbraindead, ...)
и без config.js как такового.


То есть, по своей природе eval-like расширение работает через Debugger.
Для indirect eval замен много, а вот direct eval практически незаменим.
Если MDN-страница eval недостаточно запугала, то можно переключить
настройку security.allow_eval_with_system_principal

Отсутствует

 

№1533521-03-2021 21:22:48

hartumov
Участник
 
Группа: Members
Зарегистрирован: 17-11-2013
Сообщений: 127
UA: Firefox 85.0

Re: Custom Buttons

Dumby пишет
hartumov пишет

В консоли две ошибки

Ого! Не думал что такое (пока) встречается "в дикой природе".
Значит CB установлен на релиз или бету вылеченную не через config.js,
либо на билд изначально не нуждающийся в лечении (DE, Unbraindead, ...)
и без config.js как такового.

Да, я ставил CB через правку omni.ja

Если MDN-страница eval недостаточно запугала, то можно переключить
настройку security.allow_eval_with_system_principal

Переключил. eval заработал. Ну посмотрим как оно что будет. Спасибо за помощь! :)

Отсутствует

 

№1533622-03-2021 10:18:48

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 152
UA: Firefox 86.0

Re: Custom Buttons

Dumby
В мульти крякнула кнопка "добавить закладку"...Короче, окно это падает.  Не, сам не справлюсь...уж больно крутая кнопка. Если бы не аддоны ( без мульти - не настроишь многие), короче, кроме жора памяти никаких плюшек не вижу....

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

Выделить код

Код:

((popup, {lastChild} = popup, pref = "CB.bookmarkFolderGuidForSaving") =>
addDestructor(reason => reason == "delete" && Services.prefs.clearUserPref(pref)) +
addEventListener("popupshowing", {
    index: 0, // 0 - первой, PlacesUtils.bookmarks.DEFAULT_INDEX - последней
    width: 500,
    height: 640,
    nodePosition: .35,
    handleEvent(e) {
        if (e.target != popup || this.shouldHide()) return;
        var menuitem = document.createElementNS(xulns, "menuitem");
        menuitem.id = "context-addBookmark";
        menuitem.className = "menuitem-iconic";
        menuitem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQKPK/0Cjyv9Ao8r/QKPK/0Cjyv9Ao8r/QKPK/0Cjyv9Ao8r/QKPK/0Cjyv9nn8T/Z57E22edw3IAAAAAAAAAAESmzP+Q5/b/h+T0/4Dh8/983/L/eN3x/3Xb8P902vD/dtvw/3nc8P9Epsz/Vczq/1jG5f9nnsTbAAAAAAAAAABJqc7/j+j2/4bl9f9/4fP/ed7y/3Xc8f9y3PD/cdrw/3La8P932/D/SanO/1vP6//TpUn/Zp/E/wAAAAAAAAAATqzR/5Dp9v+H5fX/f+L0/3ng8v913vL/c9zx/3Hb8f9z2vD/dtzx/06s0f9j0uz/3bld/2ahxf8AAAAAAAAAAFOv0/+T6/j/iuj3/4Ll9f984vT/eeDz/3Xe8v9z3fH/ddzx/3nd8f9Tr9P/a9Xu/+zs7P9mosb/AAAAAAAAAABZs9b/l+75/4/q+P+H6Pb/geX1/37j9P964fP/eODy/3rf8v994PL/WbPW/3TZ7//s7Oz/ZaPG/wAAAAAAAAAAX7fZ/5zw+v+U7fj/jOr3/4fo9v+D5vX/f+T1/37j9P9+4vT/geL0/1+32f9+3fH/7Ozs/2Wlx/8AAAAAAAAAAGW63P+g8vv/mO/5/5Ht+f+M6/j/iOn3/4Tn9v+C5fX/guX1/4Xl9P9lutz/uO34/7bt9/9kp8j/AAAAAAAAAABrvt//pPX8/5zy+/+W7/r/ke35/43r+P+K6ff/h+f2/4fm9v+I5fT/p9ns/4TV6P8pj9X/ZKjJlgAAAAAAAAAAcMLi/6j2/P+h9Pz/m/L7/5Xw+v+S7vn/j+z4/4zq9/+K6ff/u/H6/ymP1f91veP/I7P+/3q55Ycpj9X/AAAAAHbF5P+r+P3/pfb9/5/0/P+a8vv/l/H6/5Pv+v+R7fn/j+z4/73z+/+G0e3/I7P+/1vN//8js/7/ernlhwAAAAB7yOf/r/r+/6n4/v+k9v3/oPX8/53z+/+a8fv/l/D6/7/1+/8pj9X/I7P+/1LJ//86u/3/W83//yOz/v8pj9X/gMvp/7T7//+u+v7/qvn+/6f4/f+k9vz/ofX8/57z+/+d8fr/xfb8/4zT7/8js/7/W83//yOz/v96ueWHAAAAAITO6/+4/P//tfv//7H6/v+u+f7/rPj9/6n3/f+n9vz/pvX8/8r4/f8pj9X/f8Po/yOz/v96ueWHKY/V/wAAAACH0O3/h9Dt/4fQ7f+H0O3/h9Dt/4fQ7f+H0O3/h9Dt/4fQ7f+H0O3/t+P0/77j7awpj9X/AAAAAAAAAAAAAAAA//8AAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAADAAAAAwAAAAMAAAABAAAAAQAAAAAAAAABAAAAAQAAAAcAAA==");
        menuitem.setAttribute("oncommand", "linkedObject.oncommand(event);");
        menuitem.linkedObject = this;
        menuitem.onauxclick = e => {
            if (e.button == 1) return;
            e.preventDefault();
            popup.hidePopup();
            this.pick();
        }
        lastChild.after(menuitem);
        addDestructor(() => menuitem.remove());
        (this.handleEvent = e => e.target == popup
            && !(menuitem.hidden = this.shouldHide())
            && this.update(menuitem)
        )(e);
    },
    ons: ["isContentSelected", "onTextInput", "onImage", "onVideo", "onCanvas", "onAudio"],
    shouldHide() {
        if (gContextMenu.onLink) return false;
        return this.ons.some(on => gContextMenu[on]);
    },
    oncommand(e) {
        this[e.ctrlKey || e.shiftKey ? "pick" : "bookmark"](e.target);
    },
    get guid() {
        return Services.prefs.getStringPref(pref, PlacesUtils.bookmarks.toolbarGuid);
    },
    async update(menuitem) {
        var info = await PlacesUtils.bookmarks.fetch(this.guid);
        var title = PlacesUtils.bookmarks.getLocalizedTitle(info);
        menuitem.label = "Добавить закладку в: " + (
            menuitem.folderName = title || "[без заголовка]"
        );
    },
    pick() {
        var features = "chrome,all,resizable,centerscreen,modal";
        window.openDialog(this.url, "_blank", features, this.guid);
    },
    bookmark({folderName}) {
        if (gContextMenu.onLink) {
            var url = gContextMenu.linkURL;
            var title = gContextMenu.linkText();
        } else {
            var url = gBrowser.currentURI.spec;
            var title = gBrowser.contentTitle || gBrowser.selectedTab.label;
        }
        var info = {url, title, parentGuid: this.guid, index: this.index};
        PlacesUtils.bookmarks.insert(info).then(
            () => this.notify(title, "Добавил закладку в папку: " + folderName),
            err => this.notify("Ошибка", err)
        );
    },
    get as() {
        delete this.as;
        return this.as = Cc["@mozilla.org/alerts-service;1"]
            .getService(Ci.nsIAlertsService);
    },
    notify(title, msg) {
        this.as.showAlertNotification("chrome://global/skin/icons/cpd_OK.png", title, msg);
        setTimeout(this.as.closeAlert, 1800);
    },
    get url() {
        var xul =
            `<?xml version="1.0"?>
            <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
            <?xml-stylesheet href="chrome://browser/content/places/places.css"?>
            <?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
            <?xml-stylesheet href="chrome://browser/skin/places/tree-icons.css"?>
            <dialog xmlns="${xulns}"
                id="bookmark-folder-saver-dialog"
                windowtype="bookmark-folder-saver:dialog"
                title="Выберите папку"
                buttons="accept,cancel"
                onload="init();"
               width="${this.width}"
                height="${this.width}">

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

                <tree id="tree" type="places" is="places-tree"
                    place="place:type=${
                        Ci.nsINavHistoryQueryOptions.RESULTS_AS_ROOTS_QUERY
                    }&amp;excludeItems=1&amp;excludeQueries=1"
                    hidecolumnpicker="true" seltype="single" flex="1">
                    <treecols>
                        <treecol id="title" flex="1" primary="true" hideheader="true" />
                    </treecols>
                    <treechildren />
                </tree>
                <script type="application/javascript"><![CDATA[
                    var tree = document.getElementById("tree");
                    function init() {
                        tree.selectItems([window.arguments[0]]);
                        var ind = tree.view.selection.currentIndex;
                        ind != -1 && setTimeout(() => {
                            if ("nsITreeBoxObject" in Ci) {
                                var tbo = tree.treeBoxObject;
                                var visibleRows = tbo.height/tbo.rowHeight;
                            } else {
                                var tbo = tree;
                                var visibleRows = tbo.getPageLength();
                            }
                            var cur = tbo.view.selection.currentIndex;
                            var first = tbo.getFirstVisibleRow();
                            var newFirst = cur - ${this.nodePosition}*visibleRows + 1;
                            tbo.scrollByLines(Math.round(newFirst - first));
                        }, 0);
                        var onKeydown = e => e.ctrlKey && e.key == "Enter" && !e.shiftKey
                            && document.documentElement.acceptDialog(e.stopPropagation());
                        addEventListener("keydown", onKeydown, true);
                        addEventListener("dialogaccept", dialogCallback);
                        window.onunload = () => {
                            removeEventListener("keydown", onKeydown, true);
                            removeEventListener("dialogaccept", dialogCallback);
                        }
                    }
                  function dialogCallback() {
                        var ind = tree.view.selection.currentIndex;
                        if (ind == -1) return;
                        var item = tree.view.nodeForTreeIndex(ind);
                        item && Services.prefs.setStringPref(
                            "${pref}", PlacesUtils.getConcreteItemGuid(item)
                        );
                    }
                ]]></script>
            </dialog>`;
        var url = URL.createObjectURL(new Blob(
            [xul], {type: "application/xhtml+xml"}
        ));
        addDestructor(() => URL.revokeObjectURL(url));
        delete this.url; return this.url = url;
    }
}, false, popup || 1))(document.getElementById("contentAreaContextMenu"));

Buferobmena-1.1616397463.jpg

  var url = URL.createObjectURL(new Blob   ???

Отредактировано ВВП (22-03-2021 18:15:39)

Отсутствует

 

№1533722-03-2021 16:12:42

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

Re: Custom Buttons

del

Отредактировано egorsemenov06 (22-03-2021 16:26:21)

Отсутствует

 

№1533822-03-2021 21:37:37

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

Re: Custom Buttons

ВВП пишет

В мульти крякнула

Ага. Год назад.

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

Выделить код

Код:

/*
        var url = URL.createObjectURL(new Blob(
            [xul], {type: "application/xhtml+xml"}
        ));
        addDestructor(() => URL.revokeObjectURL(url));
*/
        var version = parseInt(Services.appinfo.platformVersion);
        var url, type = `application/${version >= 73 ? "xhtm" : "vnd.mozilla.xu"}l+xml`;
        if (version >= 69 && Services.appinfo.browserTabsRemoteAutostart) {
            url = `chrome://custombuttons/content/cbfolderpicker${Date.now()}.xul`;
            var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
            this.helper = ams.registerChrome(
                Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)),
                [["override", url, `data:${type},${encodeURIComponent(xul)}`]]
            );
            addDestructor(this.helper.destruct);
        } else {
            url = URL.createObjectURL(new Blob([xul], {type}));
            addDestructor(() => URL.revokeObjectURL(url));
        }

Отсутствует

 

№1533922-03-2021 22:00:28

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 152
UA: Firefox 86.0

Re: Custom Buttons

Dumby

Черт знает, но браузер в ступоре после нажатия ...Огласите низ кода до упора?
Не надо, справился...Благодарю.
Код memory , в 77 версии вместо цифр крозебяки...?

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

Выделить код

Код:

//
(async id => ({

	delay: 2e3,

	get limit() {
		var mb = 950 * 950;
		delete this.limit;
		return this.limit = this.notMulti
			? 900 * mb // not multiprocess, 900MB
			: 1.1 * 950 * mb; // multiprocess, 1.1GB
	},
	xul: `
		<hbox
			id="${id}"
			value="ram"
			tooltiptext="ЛКМ: Очистить Память"
		>
			<label id="${id += "-label"}"/>
		</hbox>
	`,
	css: `
		min-height: 23px !important;
		height: 23px !important;
		border-radius: 3px !important;
		padding: 0px 5px 0px !important;
		font-family: segoe ui !important;
		color: #00ffff !important;
		font-size: 15px !important;
		margin-bottom: 2px !important;
		margin-right: 1px !important;
		margin-left: 3px !important;
		background: linear-gradient(rgb(72, 85, 108),rgb(20, 25, 34)) !important;
	`,
	launch() {
		var file = Services.dirsvc.get("ProfD", Ci.nsIFile);
		["memred", "start.vbs"].forEach(file.append);
		(this.launch = file.launch)();
	},
	val: "",
	init(topic, mm) {
		Services.obs.addObserver(mm = this, topic);
		Services.obs.addObserver(function quit(s, t) {
			this.timer?.cancel();
			Services.obs.removeObserver(mm, topic);
			Services.obs.removeObserver(quit, t);
		}, "quit-application-granted");
	},
	observe(win) {
		var df = win.MozXULElement.parseXULToFragment(this.xul);
		this.click = e => e.button || this.launch();
		this.notMulti = !Services.appinfo.browserTabsRemoteAutostart;
		this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);

		(this.observe = async win => {
			this.timer.cancel();
			await new Promise(win.requestAnimationFrame);
			var clone = win.document.importNode(df, true);
			var hbox = clone.firstChild;
			win.document.getElementById("page-action-buttons").append(clone);
			hbox.onclick = this.click;
			hbox.style.cssText = this.css;
			hbox.firstChild.style.setProperty("margin", "0", "important");
			this.notify();
		})(win);
	},
	async notify() {
		var info = await ChromeUtils.requestProcInfo();
		var bytes = info.residentSetSize;
		for(var child of info.children) bytes += child.residentUniqueSize;
		this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT);

		var prev = this.val;
		if ((this.val = this.mgb(bytes)) != prev)
			for(var win of CustomizableUI.windows)
				win.document.getElementById(id).value = this.val;

		//this.notMulti &&
			bytes > this.limit && this.launch();
	},
	mgb: bytes => bytes < 1073741824
		? String(Math.round(bytes / 1048576))
		: (bytes / 1073741824).toFixed(2)
}).init("browser-delayed-startup-finished"))("ucf-mem-indicator");

Вот еще, ссылки кликабельны , а на постоянке нельзя?

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

Выделить код

Код:

gBrowser.selectedBrowser.messageManager.loadFrameScript(this.fsURL || (
    this.fsURL = `data:,(match => {\n${encodeURIComponent(this.Help)}\n})()`
), false);

Отредактировано ВВП (23-03-2021 19:46:49)

Отсутствует

 

№1534023-03-2021 15:57:06

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

Re: Custom Buttons

Dumby - можете добавить Tooltip-подсказки для пунктов меню QuickToggleSettings ?
Это нужно, чтобы после значений ключа и опций в подсказке для пункта меню было ещё и краткое описание.
Ещё правый клик на МакОС не работал, я исправил, но не полностью... var lin = e.view.AppConstants.platform == "macosx";

Выделить код

Код:

// Quick Toggle https://forum.mozilla-russia.org/viewtopic.php?pid=784139#p784139
// https://forum.mozilla-russia.org/viewtopic.php?pid=784165#p784165
// Быстрое переключение параметров about:config
// LongClick не срабатывает второй раз, сначала нужно открыть меню

(async (name, id, func) => {
	if (name == "Object") return CustomizableUI.createWidget(func());
	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, "QuickToggleAboutConfigSettingsUCF", () => {

	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";

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

	// refresh:
	//	false - reload current tab
	//	true - reload current tab skip cache
	//
	// restart:
	//	false - restart browser
	//	true - restart browser with confirm

	var primary = [{
			pref: ["network.proxy.autoconfig_url", "Прокси (VPN) URL"],
			userChoice: 0, userAlt: 1, refresh: true,
			values: [
				["127.0.0.1", "отключен…", "0"],
				["https://antizapret.prostovpn.org/proxy.pac", "АнтиЗапрет", "1", "Надёжный доступ на заблокированные сайты\n\nУстановите «Настройки прокси» = 2"],
				[prefs.getStringPref("user.pacfile", "file:///etc/proxy.pac"), "user .pac файл", "2"],
				["https://git.io/ac-anticensority-pac", "ac-anticensority", "3"],
				["localhost", "Tor Browser", "4"]
	]},{
			pref: ["network.proxy.type", "Режим прокси"],
			userChoice: 0, userAlt: 2, refresh: true,
			values: [
				[0, "Без прокси", "0", "по-умолчанию"],
				[5, "Системные (из IE)", "5"],
				[2, "URL автонастройки", "2", "about:config — user.pacfile"],
				[1, "Ручная настройка", "1", "вторая строка"],
				[4, "Автоопределение", "4"]
	]},{
			pref: ["network.proxy.share_proxy_settings", "Прокси для всех протоколов"],
			userChoice: true, refresh: true,
			values: [[true, "Да", "", "Прокси для всех протоколов при ручной настройке"], [false, "Нет"]]
	},{
			pref: ["network.trr.mode", "DNS через HTTPS"],
			userChoice: 2, userAlt: 0, refresh: true,
			values: [
				[0, "Выключен", "0"], [2, "TRR + мой", "2"], [3, "только TRR", "3"]
	]},null,{
			pref: ["permissions.default.image", "Разрешить загрузку изображений"],
			userChoice: 1, userAlt: 3, refresh: true,
			values: [[1, "Да"], [3, "Только с сайта"], [2, "Нет"]]
	},{
			pref: ["image.animation_mode", "Анимация изображений"],
			userChoice: "none", refresh: true,
			values: [["none", "Выключена"], ["normal", "Включена"], ["once", "Единожды"]]
	},{
			pref: ["browser.display.use_document_fonts", "Загружать web-шрифты"],
			userChoice: 1, refresh: true,
			values: [[1, "Да"], [0, "Нет"]]
	},null,{
			pref: ["media.autoplay.default", "Авто-play аудио/видео"],
			userChoice: 5, refresh: true,
			values: [
				[0, "Разрешить", "0"],
				[1, "Запретить", "1"],
				[2, "Спрашивать", "2"],
				[5, "Блокировать", "5"]
	]},{
			pref: ["media.autoplay.blocking_policy", "Автозапуск (политика)"],
			userChoice: 1, userAlt: 2, refresh: true,
			values: [
				[1, "Временная", "1"],
				[2, "По действию", "2"],
				[0, "Постоянная", "0"]
	]},{
			pref: ["plugin.state.flash", "Flash-plugin"],
			userChoice: 2, refresh: true,
			values: [
				[2, "Всегда включать", "2"],
				[1, "Включать по запросу", "1"],
				[0, "Никогда не включать", "0"]
	]},null,{
			pref: ["network.cookie.cookieBehavior", "Cookies"],
			userChoice: 1, userAlt: 3, refresh: false,
			values: [
				[1, "Не принимать сторонние"], [3, "Не принимать с не посещенных"], [4, "Не принимать от трекеров"],
				[2, "Не принимать со всех"], [0, "Принимать со всех"]
	]},{
			pref: ["javascript.enabled", "Выполнять скрипты Java"],
			userChoice: true, refresh: true,
			values: [[true, "Да"], [false, "Нет"]]
	},null,{
			pref: ["dom.storage.enabled", "Локальное хранилище"],
			userChoice: true
	}
];

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

	var secondary = [{

			pref: ["dom.enable_performance", "Статус загрузки страницы"],
			userChoice: false
	},{
			pref: ["browser.display.document_color_use", "Использовать цвета сайтов"],
			userChoice: 0,
			values: [[0, "Авто", "0"], [1, "Всегда", "1"], [2, "Никогда", "2"]]
	},{
			pref: ["intl.accept_languages", "Язык для веб-страниц"],
			userChoice: "ru-RU, ru, en-US, en",
			values: [["chrome://global/locale/intl.properties", "По-умолчанию"], ["en-US, en, ru-RU, ru", "Английская локаль"], ["ru-RU, ru, en-US, en", "Русская локаль"]]
	},null,{
			pref: ["network.http.sendRefererHeader", "Referer - для чего"],
			userChoice: 1,
			values: [[0, "Ни для чего", "0"], [1, "Только ссылки", "1"], [2, "Ссылки и изобр.", "2"]]
  },{
			pref: ["media.peerconnection.enabled", "WebRTC утечка IP"],
			userChoice: false
	},{
			pref: ["gfx.webrender.all", "WebRender для всего"],
			userChoice: false, refresh: true,
			values: [[true, "Да"], [false, "Нет"]]
	},{
			pref: ["media.webm.enabled", "Декодер WebM VP8"],
			userChoice: false, refresh: true,
			values: [[true, "Да"], [false, "Нет"]]
	}
	];

	return {
		label: "Quick Toggle Settings",
		id: "QuickToggleAboutConfigSettings",
		tooltiptext: "Quick Toggle Settings\n	ЛКМ	ПКМ",
		localized: false,
		image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFPSURBVDhPnVPNSsNAEJ5tamnBk+A7BMEcikohp/gi9i18nRafQoT00kK16tnn8CJo4vp9m5m41eSgH0zmd3d+diJ/gfdedvl0QW7k1PcLwem+3TjowZagK+Nn6yc3gNCJ+LCCh9LzzTMdqeoNbkQSFZmpJLGCW5Gx2hZaQahMbZ52VuDSfHpnAVJXOb4FKzianbzCXiLrHLYl5C3t5NTRwtxaKJxUTZ/JcOTr6q2Rxwf0aVb2/hLs4KqL3Isckz/mmSdRRksjyg+z7IM6LzDCBfuvAEOJmIKBOqAWmo1YodxLlQNsyO0rsIV/AZM+JGc2a4GgzhZ2p9mFmrpboCMqNYBDdMlwompoTWN6F2nFT5hBXb0PEpmo/Gk+oH+RrqNZINPeIlnZViV1jQuLFJQuWGB0gJdwgShvqdPXZv6J+F/QS7oXqQ9xBTFZ5oa8fAGs9fed5YhPSwAAAABJRU5ErkJggg==",
		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", "mousedown"])
				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/9hAAACRUlEQVR42qWTS2gTQRjH/zPJZo2BDfgkB62vYg5CjQdvRUE8WB8HKyahYotIQQOeFKGCF7EgvQlBqOCjWFKlevBRDyL4uHloLXhYqWJroaEqlETSptndGb+ZPDH0ojN8O8vA98vv+/Itw38u1nSRYRE6UhKyg4FF1R292/Q+xhhLi4TIrgjgIzwe4MbgmR2nrZMtxxEN63zYORuPZp7gzpehvCu9XjfuPmwCUHIiEtw4fK89zVvD2+FHAD56quXBpV3CVO4ret6nxHzxZxdBRuqADCKmz7RHD9y2tlmbYbBVfwE8DXBkEd/y39H5+mze8ZyoSIpsFXC9u/VE3/ldpyg5AAMEoJMTQi2hANKBgyKdy0h/eoChqcf9MimvVAHjd/fdiG0NRwgQpDAp1agBpDZwdHKJLKZzc+h5e3kCSexh5c5j8fmhW0HGpNZXFkqfsQpAKgcFKGmAlAxHXp5bkkmsrhosjh4cCIJ5pG5qfQXgtMslqO1qgEMWTPrR+eriEhoA4wN7L8TWh0KVXzfgY2RQAUjVBenWLH4UCrj04Wa9BNXEo5va+w63xCiJ6WRVP2MVgNQIgjgEA17MTODZ7Lt+AtSaGDG4377a1m2FAkKrc11/dUwIID1dSKHEcW3yft4RbpR6kK1PYgaJtaY1nNp5jIeMsjKNbs1AWRUcjvTnp2Kh9LtLJGTDINUhcTIZ3L+hzdq9ZgvWmSF9/Wu5gI8L03gzP5l3hddL/3/zKDdA9MdE0UERrdzaFGMUaap75Y/pX9Yfap76EQYaCeEAAAAASUVORK5CYII=",
		notUserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACNUlEQVR42qXTT2jTUBwH8G9e0ta2ks5ND0Ww/qX1oGyevEwQnOBA6EHXwLwoUh3eRGRs501RPE6xgp6KrexQECZY8DBPXmbRS4Z/K0gRtmmDa2yb5PlLX7p2Gwpi4EfCy8sn3/dPwn9e0saGnCRF6XYFnA9DkhKtRs51ep6jmtEcp/JHIM9Yivl9mf0XNDV2Ngn1YLzVxdB1lJ8U8P5hzuCWnR6xrPwmIM8kLRjdkT326BaLHNgLKAFA9ouXdhOw6qi++4j589cd89vSaMqyc2sAPUXlgF8fyt9WI3t2Av4w4NsCMJ8AHAKav6hqqH76iuLINcNuNhOawyttYCp+7tRE/6XT9GFQAG4CpniATQkIaNQIMVG6/xSL2WfTGueTbWDh5L2rA9t29QGBrQQEPUDuAuoEmFSr+P5lGc8v33mtAUfaQO3M4/GgDOoYCIkUin8D0BDDoBQ2ZMxqN0wCQh0gMxaUnYb4uzt+dwIZ8wBHTGQbYAHMpu+uAxaGxpMDvSr3AHcFaAIlD+BtoN6ag5WqhOLNwrohTMWPH5roP7pdLIwb3wW6EziWGAZhpVdLWHzxdpqAyc4yKrJ+4uKg2oMV+lgRK9CdwAVsG1WpF8UH84Zt2QkCKmsbiRAtFAllB5OHWQ9fpr81OwlcgBL9kPrwsvDGMQ1zNMV5ZyN1ISlZYZl9/TE1tjuMSFgA1VWO8uef+FAqG47tpFMcm7dyFyIOEzBMlfCadao5qhk39l9P479evwFbiOcRSXKueAAAAABJRU5ErkJggg==",
		UserAltImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIfSURBVDhPpVM9b9NQFD02cSKKFVGKIFFREFsmFiCA1AEQQrQjC0gssLCkC0jJj0iFWFoGdiT4Ay0SEmJBhPI5FBokikL4SCC0Te2UxInt13Mdu1CVrVc6713fe86x/T6w09DCeTNKJ7Q0pzyUmoCmZYOiUhXms8RMcd6vB7UwthhM5fTLWix2L3PmYjKdOwdz9DDFGtr1KuovnqD29JGlfO9Goew9DCV/DaZy2pXE8PD9Y/mbupk6xE6cVWPQhEujHo2+4fXdO76ztnq1UPYfSCcwKB1HWjeMyunCraSZOsDqbkBPsBOTNoMGvkOTLto/f+F56bble262OK/qesiYzIydTJojFLjrgEe4bcIOEdXWYe6LITN2KgmFSRFGBuPpo0eAngX0SexTJHD5LOgLpEZTcgKuUuMijAyy5l7+r0NSb21g5LQI5gGYSy2AjYBLjQyRAUniTnJXsBoayBzm3RBBndwwIoOK3fgNdIREQYCV/0DqLdiNZqCRITKYayx85RfQuUNiZ3k7IgO+vfGeXGpkiAyma++WLHtZhZ8o5H/FEVpos1V7u8TFwLQId8nw+Afa51Oq2vyycmlk9KCW0GXFZeu63IUO8z88Bx5s28SbuUXfddzrxVcobxpI0GTh7H734/dPzQt9d0/CGBpCPB7nbhmwbAPVxR4+PPtsuU7/WuElth/lKORUcsoTE8TgMg0WbJaY4Zu3XKYdBrABARUk+ls4DfQAAAAASUVORK5CYII=",
		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 += ` — "${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) {
			var msgRest = "Перезапустить браузер?", msgAbort = "Запрос на выход отменен.";
			if (pv >= 77) {
				var title = node.closest("toolbarbutton").label;
				var pp = domWin => Services.prompt.wrappedJSObject.pickPrompter({
					domWin, modalType: Ci.nsIPrompt.MODAL_TYPE_WINDOW
				});
				var confirm = win => pp(win).confirm(title, msgRest);
				var alert = win => pp(win).alert(title, msgAbort);
			} else {
				var confirm = win => win.confirm(msgRest);
				var alert = win => win.alert(msgAbort);
			}
			return (this.mayBeRestart = (node, conf) => {
				var win = node.ownerGlobal;
				if (conf && !confirm(win)) return;
				if (win.BrowserUtils.restartApplication() === false) alert(win);
				else return true;
			})(node, conf);
		},
		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.BrowserReloadSkipCache() : win.BrowserReload();
			}
		},
		maybeClosePopup(e, trg) {
			!e.ctrlKey && prefs.getBoolPref(this.closePref, undefined)
				&& trg.parentNode.hidePopup();
		},
		command(e) {
			var trg = e.target;
			if (trg.btn) return 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 && trg.pref.user)
				prefs.clearUserPref(trg.pref.pref),
				this.maybeRe(trg, true);
			e.preventDefault();
		},
		mousedown(e) {
			var reset = e => e.target.linkedObject = this;
			var id, lo = {command: reset, mousedown: reset};

			var lin = e.view.AppConstants.platform == "macosx"; // linux win
			var stop = e => reset(e) && e.preventDefault();

			lo.contextmenu = lin
				? e => e.ctrlKey || e.shiftKey ? dsp(e) : stop(e) : stop;
			var context = lin
				? e => e.button == 2 && e.type.endsWith("p") && this.contextmenu(e) : () => {};

			var dsp = (e, timeout) => {
				var trg = e.target;
				trg.onmouseup = trg.onmouseleave = null;
				if (timeout) return this.londPress(e);
				e.view.clearTimeout(id);
				reset(e);
				context(e);
			}
			(this.mousedown = e => {
				var trg = e.target;
				if (!trg.btn) return;
				trg.linkedObject = lo;
				trg.onmouseup = trg.onmouseleave = dsp;
				id = e.view.setTimeout(dsp, 500, e, true);
			})(e);
		},
		londPress(e) { // удержание кнопки мыши, выбирать команды, отводящие мышь от кнопки
			var msg = "QuickSettings\nLONG PRESS: e.button = " + e.button;
			Components.utils.reportError(msg);
			e.view.alert(msg);
		}
	};
});

Отредактировано Dobrov (23-03-2021 16:23:17)

Отсутствует

 

№1534123-03-2021 20:27:59

Азат55555
Участник
 
Группа: Members
Зарегистрирован: 01-11-2018
Сообщений: 22
UA: Chrome 89.0

Re: Custom Buttons

...

Отредактировано Азат55555 (24-03-2021 12:35:01)

Отсутствует

 

№1534224-03-2021 01:36:10

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

Re: Custom Buttons

Dumby - нужно в QuickToggleSettings для элементов values: [ …] добавить ключ выполнения указанного имени функции. (аналог refresh: true)


Ведь если меняем proxy.autoconfig_url на "Антизапрет", то ещё требуется изменить network.proxy.type на "2" для нормальной работы.
Поэтому в элемент values [ …], переключающий proxy.autoconfig на "Антизапрет", нужно добавить выполнение указанной функции (или строки команд).
То есть, после подменю: proxy.autoconfig_url на "Антизапрет" нужно, чтобы этот пункт подменю запустил конкретную функцию или команду, которая поменяет network.proxy.type на "2".
Примерные варианты синтаксиса - ищем ключевое слово в массиве и после изменения параметра запускаем указанное имя функции, а только потом выполняем флаг refresh.
values: [
    ["https://antizapret.prostovpn.org/proxy.pac", "АнтиЗапрет", "1", "TOOLTIP после ключевого слова - текст подсказки", "custombuttons.setPrefs("network.proxy.type", 2)"], нет ключевого слова TOOLTIP, значит выполнить эту строку как Java-код
    ["https://antizapret.prostovpn.org/proxy.pac", "АнтиЗапрет", "1", "Строки дополнительной подсказки", "RUN CheckProxy"],
    ["https://antizapret.prostovpn.org/proxy.pac", "АнтиЗапрет", "1", "Дополнительная подсказка", "JAVA custombuttons.setPrefs("network.proxy.type", 2)"], это прямо прописанная команда
    ["127.0.0.1", "отключен…", "0"], … …]
Логика работы: после установки параметра выполняем функцию CheckProxy, а только затем обновляем страницу (если refresh: true)


То есть под-пункт меню должен после установки about:config параметра выполнять функцию или строку команды, которая поменяет network.proxy.type на "2" или просто покажет всплывающую подсказку или ещё что-нибудь…
Dumby - это возможно сделать в коде кнопки QuickToggleSettings ?

Отредактировано Dobrov (24-03-2021 04:27:14)

Отсутствует

 

№1534324-03-2021 08:38:02

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

Re: Custom Buttons

ВВП пишет

Код memory , в 77 версии вместо цифр крозебяки...?

NaN это не «крозебяки».
Уже было спрошено, и ответ был даден.

ссылки кликабельны , а на постоянке нельзя?

снова-здорова


Dobrov пишет

добавить Tooltip-подсказки

За МакОС, разумеется, ничего сказать не могу,
а в Win7 на FF 84.0.2 «Tooltip-подсказки» есть.

Dobrov пишет

скрытый текст
Примерный синтаксис такой - ищем ключевое слово в массиве и после изменения параметра запускаем указанное имя функции, а только потом выполняем флаг refresh.
values: [
    ["https://antizapret.prostovpn.org/proxy.pac", "АнтиЗапрет", "1", "Строки дополнительной подсказки", "RUN CheckProxy"],
    ["https://antizapret.prostovpn.org/proxy.pac", "АнтиЗапрет", "1", "Строки дополнительной подсказки", "JAVA custombuttons.setPrefs("network.proxy.type", 2)"], это прямо прописанная команда
    ["127.0.0.1", "отключен…", "0"], … …]
Логика работы: после установки параметра выполняем функцию CheckProxy, а только затем обновляем страницу (если refresh: true)


То есть под-пункт меню должен после установки about:config параметра выполнять функцию или строку команды

Претензия на spec. Сейчас нет времени вникать,
но, если ничего не будет отвлекать, то, может, попробую.


Азат55555 пишет

некоторые действия

Отредактировано Dumby (24-03-2021 08:40:05)

Отсутствует

 

№1534424-03-2021 10:31:04

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

Re: Custom Buttons

Dumby пишет

Претензия на spec. Сейчас нет времени вникать, но, если ничего не будет отвлекать, то, может, попробую.

Уточню, для QuickToggleSettings все варианты не нужны! Наиболее удобный, это убрать подсказку совсем или переделать, чтобы её текст был строкой с ключевым словом. А текст, начинающийся НЕ с ключевого слова, запускать как строку кода.

Выделить код

Код:

values: [
    ["https://antizapret.prostovpn.org/proxy.pac", "АнтиЗапрет", "1", "TOOLTIP после ключевого слова - текст подсказки", 
    "custombuttons.setPrefs("network.proxy.type", 2)"], нет ключевого слова TOOLTIP, значит выполнить эту строку как Java-код.

Отсутствует

 

№1534524-03-2021 16:46:22

DenisRodman
Участник
 
Группа: Members
Зарегистрирован: 24-03-2021
Сообщений: 7
UA: Firefox 63.0

Re: Custom Buttons

Приветствую моё первое сообщение :)

Пользуюсь Мозилой версией 63.0.3 и CB устанавливал custom_buttons-0.0.7.0.0.6-fx-paxmod.xpi и custom_buttons-0.0.7.0.0.6-fx-bootstrap.xpi . Далее два файла

config.js

Выделить код

Код:

//
try {(code => {
    var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
    var jsval, evl = true, re = e => Cu.reportError(e), imp = name => {try {
        return Cu.import(`resource://gre/modules/addons/${name}.jsm`, {});
    } catch(ex) {}}
    if ((jsval = imp("AddonSettings"))) {
        jsval.AddonSettings = {ADDON_SIGNING: false, REQUIRE_SIGNING: false, ALLOW_LEGACY_EXTENSIONS: true};
        try {evl = jsval.eval("this") === jsval;} catch(ex) {evl = false;}
    }
    var jsvals = ["XPIProvider", "XPIInstall"].map(imp).filter(i => i);
    jsvals[0].AddonSettings && lockPref("extensions.allow-non-mpc-extensions", true);
    jsvals[0].signaturesNotRequired = true;

    if (evl) return jsvals.forEach(jsval => {try {jsval.eval(code);} catch(ex) {re(ex);}});

    var sl = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader);
    Cu.importGlobalProperties(["URL", "Blob"]); var url = URL.createObjectURL(new Blob([(code)]));
    jsvals.forEach(jsval => {try {sl.loadSubScript(url, jsval);} catch(ex) {re(ex);}});

})(String.raw`((vzss, pckg) => {
    var trueDesc = {enumerable: true, value: true};
    typeof Extension == "function" && Object.defineProperty(Extension.prototype, "experimentsAllowed", trueDesc);
    "AddonInternal" in this && Object.defineProperty(AddonInternal.prototype, "providesUpdatesSecurely", trueDesc);
    this.isDisabledLegacy = () => false;
    if ("XPIDatabase" in this) this.XPIDatabase.isDisabledLegacy = () => false;
    try {SIGNED_TYPES.clear();} catch(ex) {};

    if (!vzss && !pckg) return;

    var re = /\x06\x03U\x04\x03..(\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}|[a-z0-9-\._]*\@[a-z0-9-\._]+)0\x82\x02"0\r\x06\t/i;
    var getUUID = () => {
        var gen = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator);
        return (getUUID = () => gen.generateUUID().toString())();
    }
    var getIdFromString = str => {
        var match = str && str.match(re);
        return match ? match[1] : getUUID();
    }
    var getState = arg => ({
        signedState: AddonManager.SIGNEDSTATE_NOT_REQUIRED,
        cert: typeof arg == "object" ? arg : {commonName: arg}
    });
    var checkAddon = addon => {
        if (addon.id || (
            "_installLocation" in addon
                ? addon._installLocation.name == KEY_APP_TEMPORARY
                : addon.location.isTemporary
        ))
            return getState(null);
    }
    var getRoot = () =>
        !AppConstants.MOZ_REQUIRE_SIGNING && Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false)
            ? Ci.nsIX509CertDB.AddonsStageRoot : Ci.nsIX509CertDB.AddonsPublicRoot;

    if (vzss) {
        var getURI = file => {
            var jsval = Cu.import("resource://gre/modules/addons/XPIProvider.jsm", {});
            return (getURI = file => jsval.getURIForResourceInFile(file, "META-INF/mozilla.rsa"))(file);
        }
        var getIdFromFile = file => {
            var str, is = {close() {}}, sis = {close() {}};
            try {
                is = Services.io.newChannelFromURIWithLoadInfo(getURI(file), null).open();
                sis = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
                sis.init(is);
                str = sis.readBytes(sis.available());
            } catch(ex) {}
            sis.close(); is.close();
            return getIdFromString(str);
        }
        this.verifyZipSignedState = function verifyZipSignedState(aFile, aAddon) {
            var res = checkAddon(aAddon);
            return res ? Promise.resolve(res) : new Promise(resolve => {
                var callback = {openSignedAppFileFinished(rv, zipReader, cert) {
                    zipReader && zipReader.close();
                    resolve(getState(cert || getIdFromFile(aFile)));
                }};
                gCertDB.openSignedAppFileAsync(getRoot(), aFile, callback.wrappedJSObject = callback);
            });
        }
    }

    if (pckg) Package.prototype.verifySignedState = function verifySignedState(addon) {
        var res = checkAddon(addon);
        return res ? Promise.resolve(res) : new Promise(resolve =>
            this.verifySignedStateForRoot(addon, getRoot()).then(({cert}) => {
                if (cert)
                    resolve(getState(cert));
                else
                    this.readBinary("META-INF", "mozilla.rsa").then(
                        buffer => resolve(getState(
                            getIdFromString(String.fromCharCode(...new Uint8Array(buffer)))
                        )),
                        () => resolve(getState(getUUID()))
                    );
            }, Cu.reportError)
        );
    }
})(
    "verifyZipSignedState" in this, typeof Package == "function"
);`)} catch(err) {
    err.message != "Components is not defined" && Components.utils.reportError(err);
}


config-prefs.js

Выделить код

Код:

pref("general.config.obscure_value", 0);
pref("general.config.filename", "config.js");
pref("general.config.sandbox_enabled", false);


Код кнопки во вкладе Инициализация

Выделить код

Код:

// Быстрое переключение параметров about:config от 24.07.2016
this._handleClick=()=>menuPopup.openPopup(this,"after_start");var menuPopup=self.appendChild(document.createElement("menupopup"));menuPopup.id='quick-aboutconfig-menupopup';
// Изменить иконку при несоответствие любого параметра пользовательскому предпочтению (см.ниже)||Иконка меняется только при изменеии параметров через меню кнопки, либо после его открытия.
  var s='CB.hasNotUserChoice';function toggleImage(){var val=custombuttons.getPrefs(s);self.image=val
//var s='CB.hasNotUserChoice';function toggleImage(){custombuttons.getPrefs(s)?        self.style.cssText='':self.style.cssText='filter:grayscale(100%)';};
? 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB6klEQVQ4jZWTv2tUQRDHv8ntd28GLLQQfwS5VkuDSgRF/wlRiIiCQQQhhZ1VII1/wDUWkkLTBAsbC0FJYZGQ3NuZRcHYW6UQEQzoeXkW791xXh5CptodZr8z85kd4BBWRJwDgB5wyoCjh3mLbfK8C/ddW11XJlduNgYaeTFpvJWA0+P+BBx3Cf2sLEy5m4WrS8A0AGANaBUSrgKAKzdcY5k0PF4HJGm47NK6nSUMXOIXAEgSrrnG0oU/AGDKNb6qHe9c+Ms1lqbxqws/uoTfWVp3ksRll/DTJM6bcMWEn1KbDysBCW+zsnSNpWssTbg3PNf3uw7MuHDgym8uoW8aX496SxKXs7J0iTsFObcGRBfey8rShP1EXthSnDHhShJ0vM0H1uYiAKBSHWZqLYyDc+H7sSpeNlMX9l1jWWebEAgjgSxcbRRYB46YhCcVxH9bqDP3nbyUBB0XPk+Cjgnvj1qoqohvJqDtTUBdcGAmSzgIEQBM2R0fY/U41GPkwNpcTBKfmnDPNN4w4TOX+NnbfAQAWAKmXcMVAMgaNqrM1UfqkbMmrXkT/nGJO1XF4Xod8/0Ak4KcKzTe3AROjPs/AMdM2M8atk25a8IXAKYawTZZj5jNEvZN2TVldg3Ny/RfkYizALAFnByu819tzvCRWXKqTwAAAABJRU5ErkJggg=='
: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAB6klEQVQ4jZWTv2tUQRDHv8ntd28GLLQQfwS5VkuDSgRF/wlRiIiCQQQhhZ1VII1/wDUWkkLTBAsbC0FJYZGQ3NuZRcHYW6UQEQzoeXkW791xXh5CptodZr8z85kd4BBWRJwDgB5wyoCjh3mLbfK8C/ddW11XJlduNgYaeTFpvJWA0+P+BBx3Cf2sLEy5m4WrS8A0AGANaBUSrgKAKzdcY5k0PF4HJGm47NK6nSUMXOIXAEgSrrnG0oU/AGDKNb6qHe9c+Ms1lqbxqws/uoTfWVp3ksRll/DTJM6bcMWEn1KbDysBCW+zsnSNpWssTbg3PNf3uw7MuHDgym8uoW8aX496SxKXs7J0iTsFObcGRBfey8rShP1EXthSnDHhShJ0vM0H1uYiAKBSHWZqLYyDc+H7sSpeNlMX9l1jWWebEAgjgSxcbRRYB46YhCcVxH9bqDP3nbyUBB0XPk+Cjgnvj1qoqohvJqDtTUBdcGAmSzgIEQBM2R0fY/U41GPkwNpcTBKfmnDPNN4w4TOX+NnbfAQAWAKmXcMVAMgaNqrM1UfqkbMmrXkT/nGJO1XF4Xod8/0Ak4KcKzTe3AROjPs/AMdM2M8atk25a8IXAKYawTZZj5jNEvZN2TVldg3Ny/RfkYizALAFnByu819tzvCRWXKqTwAAAABJRU5ErkJggg==';};
toggleImage();Services.prefs.addObserver(s,toggleImage,false);addDestructor(()=>Services.prefs.removeObserver(s,toggleImage));

// nodeName: menuitem - для логических(boolean) параметров, menu - для целых(integer) и строковых(string). menuseparator - для разделителя.
// pref - параметр about:config.
// Параметры имеющие значения отличные от дефолтных - выделены жирным стилем текста.
// restart (задавать с пустым значением. т.е., restart: "") - добавляет возможность перезапуска браузера
// (с подтверждением в диалоговом окне) после изменения параметра.
// key - задает accesskey - клавиши для быстрой навигации по меню.
// userChoice - задает предпочитаемое значение и если текущее значение с ним не совпадает, пункт меню/название меню помечаются красным цветом.
// Также можно установить предупреждающую иконку для таких пунктов. См. стиль в посте ккнопки.
// А также меняется иконка самой кнопки (см. выше).
// strValues - значения и отображаемое в меню название значения. Задавать для целых(integer) и строковых(string) параметров.
// Задается в виде: значение,,,название,,,accesskey|||значение2,,,название2,,,accesskey2|||значение3,,,название3 и т.д. (accesskey - задается опционально)
// Полное значение отображается в подсказках, при наведении на название подменю/пункт подменю.
// Для логических(boolean) - отображается сразу после самого параметра (значение true - также ставит галочку для него).
// ЛКМ по пунктам меню - перключает значения для логических(boolean) параметров,
// любая кнопка по пунктам в субменю - задает это значение для целых(integer) и строковых(string) параметров.
// ПКМ по пунктам меню и названию субменю - сбрасывает значение параметра в дефолтное.
// Клавиатура: Enter - переключение параметра.
// Спецклавиша вызова контекстного меню / Shift+Enter - сброс в дефолтное значение.
// Alt + M - открыть меню кнопки. (Сочетание можно сменить на свое. См. в конце кода)
[ //{nodeName:"menuitem", name:"Откл. дискового кэша", pref:"browser.cache.disk.enable", userChoice:"false"},
  //{nodeName:"menuitem", name:"Откл. кэша в оперативной памяти", pref:"browser.cache.memory.enable", userChoice:"false"},
  //{nodeName:"menuseparator"},
  //{nodeName:"menuitem", name:"Откл. локального хранилища DB (Storage)", pref:"dom.indexedDB.enabled", key:'d'},
  //{nodeName:"menuitem", name:"Откл. локального хранилища", pref:"dom.storage.enabled", key:'s'},
  //{nodeName:"menuseparator"},
  //{nodeName:"menu", name:"Back-story-cash [Tessssttt]", pref:"browser.sessionhistory.max_total_viewers", strValues:"0,,,0"},
  //{nodeName:"menu", pref:"image.animation_mode", key:'i', userChoice:"none", strValues:"normal,,,Анимация картинок вкл.,,,|||none,,,Анимация картинок выкл.,,,"},
  //{nodeName:"menu", pref:"network.cookie.cookieBehavior", key:'k', userChoice:"1", strValues:"2,,,Не принимать куки с сайтов,,,|||0,,,Принимать куки со сторонних сайтов всегда,,,|||3,,,Принимать куки со сторонних посещённых сайтов,,,|||1,,,Принимать куки со сторонних сайтов никогда,,,"},
  //{nodeName:"menuseparator"},
  //{nodeName:"menu", pref:"general.useragent.locale", key:'l', restart:"", strValues:"en-US,,,English,,,e|||ru,,,Русский,,,r"},
  //{nodeName:"menu", name:"language", pref:"intl.accept_languages", strValues:"en-US, en;q=0.5,,,en-US, en;q=0.5,,,e|||en-US, en, ru-RU, ru,,,en-US, en, ru-RU, ru,,,r"},
  //{nodeName:"menu", pref:"browser.display.document_color_use", key:'c', userChoice:"0", strValues:"0,,,Automatic,,,0|||1,,,Always,,,1|||2,,,Never,,,2"},
  //{nodeName:"menu", pref:"CB.TEST", key:'t', userChoice:"C:\\Downloads\\TEST1", strValues:"C:\\Downloads\\TEST1,,,TEST1,,,1|||C:\\Downloads\\TEST2,,,TEST2,,,2"}
  //{nodeName:"menuseparator"},
  //{nodeName:"menuitem", name:"Откл. инфу начало/конец загрузки стр", pref:"dom.enable_performance", userChoice:"false"},
  //{nodeName:"menu", name:"Вкл/Выкл Referer", pref:"network.http.sendRefererHeader", strValues:"0,,,0"},
  //{nodeName:"menuitem", name:"В качестве реферера корень сайта", pref:"network.http.referer.spoofSource", userChoice:"true"},
  //{nodeName:"menu", name:"referer.trimmingPolicy", pref:"network.http.referer.trimmingPolicy", strValues:"2,,,2"},
  //{nodeName:"menuseparator"},
  //{nodeName:"menu", name:"On/Off Image", pref:"permissions.default.image", userChoice:1, strValues:"2,,,Off"},
  //{nodeName:"menuitem", name:"On/Off Multiprocessing", pref:"browser.tabs.remote.autostart", restart:"", userChoice:"true"},   //about:support=Multiprocess Windows|forum.ru-board.com/topic.cgi?forum=5&topic=49695&start=0&limit=1&m=9#1
                                                                                                                                //opennet.ru/opennews/art.shtml?num=50691
  //{nodeName:"menuitem", name:"On/Off javascript", pref:"javascript.enabled", key:'j', userChoice:"true"},
  //{nodeName:"menuitem", pref:"dom.workers.enabled", key:'w', userChoice:"false"},
  //{nodeName:"menuitem", pref:"media.autoplay.enabled", key:'m', userChoice:"false"},
  //{nodeName:"menu", name:"Stopautoplay", pref:"media.autoplay.default", userChoice:0, strValues:"0,,,Stop,,,0|||1,,,Play,,,1"},
  //{nodeName:"menuitem", pref:"xpinstall.signatures.required"},                       //Check is compatibility
  //{nodeName:"menuitem", pref:"browser.bookmarks.autoExportHTML"},                    //BookmarksHtml [false=places.sqlite]
  //{nodeName:"menuitem", pref:"media.peerconnection.enabled"},                        //WebRTC false=off!


  //{nodeName:"menuitem", name:"On/Off useragentS", pref:"general.useragent.site_specific_overrides", userChoice:"true"},
  //{nodeName:"menuitem", name:"On/Off media.play-stand-alone", pref:"media.play-stand-alone"},   //сразу скачивать медиафайлы, без перехода на новую страницу.
  {nodeName:"menuseparator"},
  {nodeName:"menu", name:"Язык браузера", pref:"intl.locale.requested", restart:"", strValues:"en-US,,,English,,,e|||ru-RU,,,Русский,,,r"},
  {nodeName:"menu", name:"Язык веб-страниц", pref:"intl.accept_languages", strValues:"en-US, en, ru-RU, ru,,,English,,,e|||ru-RU, ru, en-US, en,,,Русский,,,r"},
  {nodeName:"menuseparator"},
  //{nodeName:"menu", name:"Configure Proxies", pref:"network.proxy.type", userChoice:5, strValues:"1,,,httpP,,,1|||2,,,AutomaticP,,,2|||5,,,Use systemP,,,5"},
  //{nodeName:"menu", name:"AutomaticP", pref:"network.proxy.autoconfig_url", strValues:"file:///X:/FFQ/_.pac,,,file:///X:/FFQ/_.pac,,,1|||https://antizapret.prostovpn.org/proxy.pac,,,https://antizapret.prostovpn.org/proxy.pac,,,2"},
  //{nodeName:"menuseparator"}, 
  
  //userChoice:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:57.0) Gecko/20100101 Firefox/99.0",
  //{nodeName:"menu", name:"User Agent", pref:"general.useragent.override", key:'u', strValues:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:60.0) Gecko/20100101 Firefox/60.0,,,Firefox 60/MacOSX 10.13|||Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36,,,Chrome 66/MacOSX 10.13.5|||Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36,,,Chrome 57/MacOSX|||Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.1 Safari/603.1.30,,,Safari Generic/MacOSX|||Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36,,,Chrome57/W7|||Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12 Version/12.16,,,Opera12/W8|||Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Safari/537.36,,,Chrome61/W10|||Mozilla/5.0 (Linux; Android 7.0; PLUS Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.98 Mobile Safari/537.36,,,Chrome61/Android7|||Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html),,,GoogleBot|||Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots),,,YandexBot|||Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp),,,YahooBot|||Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm),,,BingBot|||DuckDuck bot/1.0; (+http://duckduckgo.com/duckduckbot.html),,,DuckDuckBot|||Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html),,,BaiduspiderBot|||ia_archiver (+http://www.alexa.com/site/help/webmasters; crawler@alexa.com),,,AlexaCrawlerBot|||Mozilla/5.0 (Linux; Android 5.1.1; SM-G928X Build/LMY47X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.83 Mobile Safari/537.36,,,Samsung Galaxy S6 Edge Plus|||Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586,,,Microsoft Lumia 950|||Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Xbox; Xbox One) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/13.10586,,,Xbox One|||Mozilla/5.0 (PlayStation 4 3.11) AppleWebKit/537.73 (KHTML, like Gecko),,,Playstation 4|||,,,Пустое значение"},
].forEach(function(m){var mItem=document.createElement(m.nodeName);var browserRestart='';
if ("restart" in m) browserRestart=' if (custombuttons.confirmBox(null, "Restart?", "Yes", "Cancel")) Services.startup.quit(Services.startup.eAttemptQuit | Services.startup.eRestart);';
if ("name" in m) mItem.setAttribute('name',m.name);if ("pref" in m) {mItem.setAttribute('closemenu','none');
mItem.setAttribute('oncontextmenu','event.preventDefault();custombuttons.clearPrefs("'+m.pref+'");'+browserRestart);}
if ("key" in m) mItem.setAttribute('accesskey', m.key);if (m.nodeName==="menuitem") {mItem.setAttribute('type','checkbox');
mItem.setAttribute('oncommand','custombuttons.setPrefs("'+m.pref+'",!custombuttons.getPrefs("'+m.pref+'"));if (event.shiftKey && event.keyCode==event.DOM_VK_RETURN){event.preventDefault();custombuttons.clearPrefs("'+m.pref+'")};'+browserRestart);}
if (m.nodeName==="menu"){mItem.setAttribute('class','menu-iconic');

var subMenu=mItem.appendChild(document.createElement("menupopup"));

for (var value of m.strValues.split('|||')){var submItem=document.createElement("menuitem");var smVal=value.split(',,,')[0];
var smValConv=convertFromUnicode("UTF-8",smVal);var smName=value.split(',,,')[1];var key=value.split(',,,')[2];

key && submItem.setAttribute('accesskey',key);submItem.setAttribute('type','radio');submItem.setAttribute('label',smName);submItem.setAttribute('tooltiptext',smVal);submItem.setAttribute('closemenu','none');
submItem.setAttribute('oncommand','try{custombuttons.setPrefs("'+m.pref+'","'+smValConv.replace(/\\/g,'\\\\')+'")}catch(e){Services.prefs.setIntPref("'+m.pref+'","'+smValConv+'")};'+browserRestart);
subMenu.appendChild(submItem);}}

menuPopup.appendChild(mItem);

  // Листенеры отслеживающие переключение параметров
  // и устанавливающие соответствующие названия и чекбоксы для пунктов меню при открытии меню и кликах
  for (var type of ['command','popupshowing','contextmenu']){addEventListener(type,(e)=>{setTimeout(()=>{if ("pref" in m){var val,def;
   def=Services.prefs.prefHasUserValue(m.pref);
   try {val=Services.prefs.getComplexValue(m.pref,Ci.nsISupportsString).data;} catch(e) {
   if (Services.prefs.getPrefType(m.pref)==64) val=custombuttons.getPrefs(m.pref).toString();else val=custombuttons.getPrefs(m.pref);}
   def ? mItem.style.setProperty('font-weight', 'bold', 'important') : mItem.style.removeProperty('font-weight');}

     if (m.nodeName==='menuitem'){mItem.setAttribute('checked',val);mItem.label=(mItem.hasAttribute('name') ? mItem.getAttribute('name') : m.pref)+' - "'+val+'"';
     if ("userChoice" in m){try {var usrChc=(val.toString()===m.userChoice)} catch(e) {usrChc=false};

     mItem.setAttribute('user-choice',usrChc);usrChc ? mItem.style.removeProperty('color') : mItem.style.setProperty('color','orangered','important');}}
     if (subMenu){for (var smitem of subMenu.getElementsByTagName('menuitem')) {var smval=smitem.getAttribute('tooltiptext');smitem.setAttribute('checked',(val===smval) ? true : false);}}
     if (m.nodeName==="menu") {var vname;
     try {vname=subMenu.getElementsByAttribute('checked','true')[0].getAttribute('label');} catch(e) {if (!Services.prefs.prefHasUserValue(m.pref)) vname='Default';else vname='Other';}

     mItem.setAttribute('label',(mItem.hasAttribute('name') ? mItem.getAttribute('name') : m.pref)+' - "'+vname+'"');
     mItem.setAttribute('tooltiptext',val || 'This preferences has null value or does not exist.');

     if ("userChoice" in m) {var smUsrChc=(val===m.userChoice.toString());mItem.setAttribute('user-choice',smUsrChc);
     smUsrChc ? mItem.style.removeProperty('color') : mItem.style.setProperty('color','orangered','important');}}

     if ("userChoice" in m) {var hasNotUserChoice=menuPopup.getElementsByAttribute('user-choice','false')[0];custombuttons.setPrefs(s,hasNotUserChoice ? true : false);}}, 0)},false,menuPopup)}});

// Листенер позволяющий сброс параметров с субменю по Shift + Enter||За код спасибо Dumby
addEventListener("popupshown",{handleEvent: function(e){this[e.type](e);},
popupshown: function(e) {if (e.target!=menuPopup) return;menuPopup.addEventListener("popuphidden", this, false);window.addEventListener("keydown", this, true);},
popuphidden: function(e) {if (e.target!=menuPopup) return;menuPopup.removeEventListener("popuphidden", this, false);window.removeEventListener("keydown", this, true);},
popupshowing: function(e) {e.target.parentNode.removeEventListener("popupshowing", this, false);e.preventDefault();},get old() {delete this.old;
this.e = new MouseEvent("contextmenu", {});return this.old=parseInt(Services.appinfo.platformVersion) < 25;},get prop() {delete this.prop;
if ("key" in KeyboardEvent.prototype) this.prop = "key", this.val="Enter";else this.prop = "keyCode", this.val=KeyboardEvent.DOM_VK_RETURN;return this.prop;},
keydown: function(e) {if (!e.shiftKey || e.ctrlKey || e.altKey || e[this.prop] != this.val) return;var target=menuPopup.querySelector("menu[_moz-menuactive]:not([open])");
if (!target) return;this.old ? target.addEventListener("popupshowing", this, false) : e.stopPropagation();target.dispatchEvent(this.e);menuPopup.dispatchEvent(this.e);}}, false, menuPopup);

// Открыть меню кнопки по сочетанию клавиш Alt + M (не зависит от текущей раскладки клавиатуры)
// Посмотреть коды клавиш можно здесь: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Constants_for_keyCode_value
addEventListener('keyup',(e)=>{if (e.altKey && !e.shiftKey && !e.ctrlKey && e.keyCode==77){e.preventDefault();e.stopPropagation();
menuPopup.showPopup(this,-1,-1,"popup","bottomleft","topleft");}},false,window);
// Конвертировать текст в юникод .............
function convertFromUnicode(charset,str) {var converter=Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset=charset;str=converter.ConvertFromUnicode(str);return str+converter.Finish();};


Сама кнопка работает и свою функцию выполняет. Код этот общий, сам его не писал его наверно все знают, вот и я убрал лишь // для того, чтобы кнопка выполняла, то что мне нужно. Решил обновить версию Мозилы на 69.0.3, точнее уже обновил, все тесты заранее проводил на виртуальной машине, поскольку уже научен опытом, что лучше эксперементы с обновленями проводить не на основном ПК.
Так вот после обновления Мозилы кнопка перестала функционировать, при нажатии ничего не происходит, ни меню не всплывает, ни действий нет никаких. Ещё сама кнопка почему-то для себя стала использовать много место т.е. она расширило позицию панели где находятся все иконки от расширений, но вроде эту проблему решил в Настройках расширения поставил галочку в пункте "Отключить инициализацию кнопок ... " теперь размеры самой кнопки такие же как у всех иконок. Когда обновился на 69.0.3 то сама CB пропала, поэтому xpi ставил по новой единственно поставилась только одна из двух эта custom_buttons-0.0.7.0.0.6-fx-paxmod.xpi, а второй -fx-bootstrap.xpi не захотел ставиться. Два нужных файла .js были на месте, ну а код кнопки добавил в Инициализацию. Результат кнопка нерабочая.


Вопрос простой, что сделать чтобы кнопка заработала?


[windows] 7 ULT SP1; [firefox] 69.0.3

Отсутствует

 

№1534624-03-2021 17:46:59

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

Re: Custom Buttons

DenisRodman пишет

код кнопки добавил в Инициализацию

Чисто из любопытства:
а кодом, который предложил господин «Сам Custom Buttons бесполезен»,
пробовал в Инициализации заменить?


Реверс этого, конечно, (плюс рестарт).

в Настройках расширения поставил галочку в пункте "Отключить инициализацию кнопок ... "

Отсутствует

 

№1534724-03-2021 18:15:52

DenisRodman
Участник
 
Группа: Members
Зарегистрирован: 24-03-2021
Сообщений: 7
UA: Firefox 63.0

Re: Custom Buttons

Dumby
Ничего не понял. Можно по конкретней и по проще объяснить. Что и какие действия необходимы для решения проблемы с кнопкой?

Отсутствует

 

№1534824-03-2021 19:04:26

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

Re: Custom Buttons

DenisRodman
Ожидалось

Да, заменил приведённый код в Инициализации, на код,
предоставленный господином «Сам Custom Buttons бесполезен».


Снял галку в пункте "Отключить инициализацию кнопок ... ", перезапустился.
Теперь работает (всё ещё не работает).

Но найдено

Ничего не понял.

Я бы и сам проверил, но там ссылка на (для меня) г-хостинг.
А что-то искать лениво.

Отсутствует

 

№1534924-03-2021 19:58:14

harryk
Участник
 
Группа: Members
Зарегистрирован: 23-12-2019
Сообщений: 415
UA: Firefox 68.0

Re: Custom Buttons

Dumby пишет

но там ссылка на (для меня) г-хостинг

upload.ee или wdfiles.ru подойдёт?

На форуме

 

№1535024-03-2021 20:06:59

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

Re: Custom Buttons

harryk
Да, полагаю что upload.ee подойдёт,
хоть и не часто с него что-то брал, но всегда без проблем.
Надеюсь не испортили.

Отсутствует

 

Board footer

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