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

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

№127607-03-2024 18:57:13

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

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

Dumby пишет

Но тогда, да, действительно, мы получим вообще всё и сразу

Что ж пусть так и будет. Модули только нужно подгружать по необходимости
https://github.com/VitaliyVstyle/Vitali … me.js#L177

Отсутствует

 

№127708-03-2024 10:27:29

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

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

Vitaliy V. пишет

Что ж пусть так и будет.

Сунул в custom_script.js
некий рандомно-тестовый код, и всё работает так, как ожидалось.

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

Выделить код

Код:

var bla = "bla";

var test = {
	"globalThis.bla": globalThis.bla, // user box, expected string
	"SystemGlobal.bla": Cu.getGlobalForObject(Cu).bla, // SystemGlobal, expected undefined

	// expected all exsists

	// dom idl
	PathUtils: PathUtils,
	AbortController: AbortController,
	HTMLAnchorElement: HTMLAnchorElement,

	// global properties
	FileReader: FileReader,
	XMLSerializer: XMLSerializer,
	URLSearchParams: URLSearchParams,

	// modules
	PlacesUtils: PlacesUtils,
	AppConstants: AppConstants,
	CustomizableUI: CustomizableUI,

	// internal stuff
	UcfPrefs: UcfPrefs,
	user_chrome: user_chrome,
	user_chrome_files_sandbox: user_chrome_files_sandbox,
};
for(let key in test) test[key] = typeof test[key];
console.log(JSON.stringify(test, null, "\t"));


Парадигма сдвинута.

Отсутствует

 

№127813-03-2024 23:48:54

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 599
UA: Firefox 115.0

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

Есть вот такой скрипт: "Переключить текущий поисковик" (первый спойлер)


Кто-нибудь на FF123 пользуется этим скриптом?


Дело в том, что на Windows 7, по понятным причинам, крайнюю версию оригинального FF я поставить не могу.
Но нашлись "умельцы", которые делают сборки крайних FF, которые работают на Win7.
Так вот, на такой сборке сам скрипт работает, поисковики переключает, но вот иконки поисковиков почему-то не подгружает.
Untitled-2.png
Пытаюсь разобраться, это проблема скрипта в FF123 или "умельцы" что-то накрутил в своей сборке.


Кому не сложно, проверьте пожалуйста этот скрипт в оригинальном FF123.

Отредактировано unter_officer (14-03-2024 00:20:52)


«The Truth Is Out There»

Отсутствует

 

№127914-03-2024 08:24:55

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

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

unter_officer пишет

Пытаюсь разобраться

Это Bug 1870644 - Provide a single function for obtaining icon URLs from search engines


Farby предложил такую конструкцию:
engine._iconURI ? engine._iconURI.spec : engine.iconURI ? engine.iconURI.spec : this.defaultImg
что слегка замудро. Надеюсь, чуть лучше так:
(engine._iconURI || engine.iconURI)?.spec || this.defaultImg


Затем getIconURL() сделали асинхронной,
но пока ещё работает, то есть
img: e => (e._iconURI || e.iconURI)?.spec || "chrome://browser/skin/search-engine-placeholder.png",


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


Ну, и на самой кнопке иконка не подхватывается, нужно прицепить wrappedJSObject.

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

Выделить код

Код:

/*
			var engine = popup.getDefaultEngine();
*/
			var engine = popup.getDefaultEngine().wrappedJSObject;

Отсутствует

 

№128014-03-2024 10:22:31

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 599
UA: Firefox 115.0

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

Dumby
egorsemenov06
Большое вам спасибо за помощь!


«The Truth Is Out There»

Отсутствует

 

№128114-03-2024 10:28:50

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

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

Dumby пишет

img: e => (e._iconURI || e.iconURI)?.spec || "chrome://browser/skin/search-engine-placeholder.png",

Спасибо, забрал. :beer:
Там ещё не работает скрытие неиспользуемых поисковиков, при excludeHiddenOneOffs: true, но полазил по форуму и нашел решение от Vitaliy V.

excludeHiddenOneOffs

Выделить код

Код:

//	excludeHiddenOneOffs: false,
	excludeHiddenOneOffs: true, // скрыть не нужные поисковики
..
//		if (this.excludeHiddenOneOffs)
//			var ex = Services.prefs.getStringPref(this.pref, "").split(",");
		var visibleEngines = await Services.search.getVisibleEngines();
		if (this.excludeHiddenOneOffs) {
			var args = "hideOneOffButton" in Services.search.defaultEngine
					? [e => !e.hideOneOffButton]
					: Object.defineProperty(
						[function(e) {return !this.includes(e.name);}], "1", {
							get: () => Services.prefs.getStringPref("browser.search.hiddenOneOffs")?.split(",") || []
						});
			visibleEngines = visibleEngines.filter(...args);
		}
..
//		for(var engine of await Services.search.getVisibleEngines()) {
		for(var engine of visibleEngines) {
..
//			if (this.excludeHiddenOneOffs && ex.includes(engine.name)) continue;


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

Отсутствует

 

№128214-03-2024 17:10:30

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

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

Vitaliy V.
Вы делали кнопку

Тултипы с URL

Выделить код

Код:

// Ссылка у курсора в тултипе, кнопка https://forum.mozilla-russia.org/viewtopic.php?pid=783755#p783755
(async () => {
    var id = "ucf-toggle-tooltip-url",
    label = "Тултипы с URL",
    tooltiptext = "Переключить тултипы",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' style='fill:context-fill rgb(142, 142, 152);'><path d='M9.618 6.721a2.483 2.483 0 0 0-.39-.317l-.735.734A1.486 1.486 0 0 1 8.91 9.55l-2.12 2.122a1.486 1.486 0 0 1-2.122 0 1.486 1.486 0 0 1 0-2.121l.605-.605a3.53 3.53 0 0 1-.206-1.209L3.961 8.843a2.506 2.506 0 0 0 0 3.535 2.506 2.506 0 0 0 3.535 0l2.122-2.121a2.506 2.506 0 0 0 0-3.536z'/><path d='M6.79 9.55c.12.121.25.226.389.317l.734-.734a1.486 1.486 0 0 1-.417-2.411L9.618 4.6a1.486 1.486 0 0 1 2.121 0 1.486 1.486 0 0 1 0 2.121l-.605.605c.137.391.211.798.206 1.209l1.106-1.107a2.506 2.506 0 0 0 0-3.535 2.506 2.506 0 0 0-3.535 0L6.789 6.014a2.506 2.506 0 0 0 0 3.536z'/><circle style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round' cx='8' cy='8' r='7.4'/></svg>",
    imgcolordisable = "color-mix(in srgb, currentColor 20%, #e31b5d)";

    var branch = "extensions.ucf.", pref = "tooltip_url_enable";
    var tpurl = {
        initialised: false,
        tooltip_url_enable: true,
        get ext_branch() {
            delete this.ext_branch;
            return this.ext_branch = Services.prefs.getBranch(branch);
        },
        init() {
            if (this.initialised) return;
            Services.prefs.getDefaultBranch(branch).setBoolPref(pref, true);
            Services.prefs.addObserver(`${branch}${pref}`, this);
            if (this.tooltip_url_enable = this.ext_branch.getBoolPref(pref))
                this.registerActor();
            this.initialised = true;
        },
        observe(subject, topic, data) {
            var fill = "";
            if ((this.tooltip_url_enable = this.ext_branch.getBoolPref(pref)) === true)
                this.registerActor();
            else {
                fill = imgcolordisable;
                this.unregisterActor();
            }
            this.callWithEachWindow(id, {fill: fill});
        },
        callWithEachWindow(buttonID, atr) {
            var getW = CustomizableUI.getWidget(buttonID);
            if (getW.instances.length)
                for (let {node} of getW.instances) {
                    if (!node) continue;
                    for (let a in atr)
                        node.style.setProperty(a, atr[a]);
                }
            else
                for (let win of CustomizableUI.windows) {
                    let node = getW.forWindow(win).node;
                    if (!node) continue;
                    for (let a in atr)
                        node.style.setProperty(a, atr[a]);
                }
        },
        registerActor() {
            ChromeUtils.registerWindowActor("UcfTooltipUrl", {
                child: {
                    moduleURI: "chrome://user_chrome_files/content/custom_scripts/cs/UcfTooltipUrlChild.jsm",
                    events: {
                        mouseover: { capture: true },
                    },
                },
                allFrames: true,
                matches: ["<all_urls>"],
                messageManagerGroups: ["browsers"],
            });
        },
        unregisterActor() {
            ChromeUtils.unregisterWindowActor("UcfTooltipUrl");
        },
    };
    CustomizableUI.createWidget({
        id: id,
        label: label,
        tooltiptext: tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onCreated(btn) {
            tpurl.init();
            btn.style.setProperty("list-style-image", `url("${img}")`, "important");
            if (!tpurl.tooltip_url_enable)
                btn.style.setProperty("fill", imgcolordisable);
        },
        onCommand(e) {
            tpurl.ext_branch.setBoolPref(pref, !tpurl.ext_branch.getBoolPref(pref));
        },
    });
})();


UcfTooltipUrlChild.jsm

Выделить код

Код:

var EXPORTED_SYMBOLS = ["UcfTooltipUrlChild"];
ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
class UcfTooltipUrlChild extends JSWindowActorChild {
    handleEvent(e) {
        timer.cancel();
        timer.initWithCallback(() => {
            var elm = e.isTrusted && e.composedTarget, el, titl;
            if (!elm) return;
            do {
                if (!elm.matches) continue;
                if (elm.matches(":any-link")) {
                    if (elm.matches("[href='#'], [href^='javascript']"))
                        return;
                    el = elm;
                    if (elm.matches("[title]"))
                        titl = elm;
                    else
                        while (elm = elm.flattenedTreeParentNode) {
                            if (!elm.matches) continue;
                            if (elm.matches("[title]")) {
                                titl = elm;
                                break;
                            }
                        }
                    break;
                }
                if (elm.matches("[title]")) {
                    titl = elm;
                    while (elm = elm.flattenedTreeParentNode) {
                        if (!elm.matches) continue;
                        if (elm.matches(":any-link")) {
                            if (elm.matches("[href='#'], [href^='javascript']"))
                                return;
                            el = elm;
                            break;
                        }
                    }
                    break;
                }
            } while (elm = elm.flattenedTreeParentNode);
            if (!el) return;
            var href = el.href;
            if (titl) el = titl;
            titl = (el.title || "");
            var title = titl.trim(), pre = "", path = "";
            try {
                href = Services.io.newURI(href);
                pre = href.displayPrePath;
                path = `\n${href.pathQueryRef}`;
                if (path === "\n/") path = "";
                href = `${pre}${path}`;
            } catch (e) {}
            try {
                href = decodeURIComponent(href);
            } catch (e) {}
            el.title = title = `${href}${title === "" ? "" : `\nTitle: ${title}`}`;
            this.contentWindow.addEventListener("mouseout", () => {
                try {
                    if (!el || title !== el.title) return;
                    if (titl !== "")
                        el.title = titl;
                    else
                        el.removeAttribute("title");
                } catch (e) {}
            }, { once: true });
        }, 100, Ci.nsITimer.TYPE_ONE_SHOT); /* было 400 */
    }
    didDestroy() {
        timer.cancel();
    }
}


Пока работает, но можно переделать на mjs?
P.S. Может, уже переделывали в теме, не уследил...

Отсутствует

 

№128314-03-2024 17:59:39

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

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

Farby пишет

нашел решение от Vitaliy V

Не, Виталий такую шляпу не пишет, у него всё как-то более академично.
Это моё, наверно. Кстати, ошибку свою заметил.


Настройка "browser.search.hiddenOneOffs" дефолтно существовала (до 116),
а значит, если там ничего не было, то значением возвращалась пустая строка.
А выражение ""?.split(",") возвращает массив с пустой строкой, и это совсем не то, что нужно.


Dumby пишет

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

Ха, оказывается они уже слетели (причём, во всём браузере),
если руками включить настройку browser.search.newSearchConfig.enabled


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


Но ничего, теперь хотя бы понятно, что engine._iconURI для них больше не подходит.
Вобщем вот, небольшая модификация обсуждавшегося кода

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

Выделить код

Код:

try {CustomizableUI.createWidget({
	label: "Переключить текущий поисковик",
	id: "ucf-cbbtn-ToggleCurrentSearchEngine",
	image: "data:image/png;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA",
	excludeHiddenOneOffs: true,
	gn: () => Services.search.defaultEngine,
	gp: () => Services.search.defaultPrivateEngine,
	sn: val => Services.search.defaultEngine = val,
	sp: val => Services.search.defaultPrivateEngine = val,
	onCreated(btn) {
		btn.type = "menu";
		btn.owner = this;
		btn.setAttribute("image", this.image);

		var win = btn.ownerGlobal;
		var popup = btn.appendChild(win.document.createXULElement("menupopup"));
		var pr = win.PrivateBrowsingUtils.isWindowPrivate(win);
		popup.getDefaultEngine = pr ? this.gp : this.gn;
		popup.setDefaultEngine = pr ? this.sp : this.sn;
		popup.setAttribute("oncommand", "setDefaultEngine(event.target.engine)");
		popup.setAttribute("onpopupshowing", "this.shouldRebuild && owner.rebuild(this, document)");

		this.autoOpenCloseFeature(win, btn);
		this.updButton(btn, win);
	},
	getEngines() {
		var ve = Services.search.getVisibleEngines;
		if (!this.excludeHiddenOneOffs) return (this.getEngines = ve)();

		var arr = [];
		var args = this.fx116
			? [e => !e.hideOneOffButton]
			: Object.defineProperty(
				[function(e) {return !this.includes(e.name);}], "1", {get: () => {
					var str = Services.prefs.getStringPref(this.pref);
					return str ? str.split(",") : arr;
				}}
			);
		return (this.getEngines = async () => (await ve()).filter(...args))();
	},
	async rebuild(popup, doc) {
		popup.textContent = "";
		var df = doc.createDocumentFragment();
		var de = popup.getDefaultEngine().wrappedJSObject, jsde = this.json(de);
		var check = true;
		for(var engine of await this.getEngines()) {
			if (check && engine.name == de.name && this.json(engine) == jsde) {
				check = false; continue;
			}
			var menuitem = df.appendChild(doc.createXULElement("menuitem"));
			menuitem.engine = engine;
			menuitem.label = engine.name;
			menuitem.className = "menuitem-iconic";
			menuitem.image = await this.img(engine);
		}
		popup.append(df);
		delete popup.shouldRebuild;
	},
	async updButton(btn, win) {
		this.updButton = () => {};
		Services.search.isInitialized || await Services.search.init();
		this.fx116 = "hideOneOffButton" in Services.search.defaultEngine;

		var topics = ["browser-search-engine-modified", "quit-application-granted"];
		for(var topic of topics) Services.obs.addObserver(this, topic, false);
		this.observe = (s, topic) => this[topic[0]]();

		var remove = () => topics.forEach(
			topic => Services.obs.removeObserver(this, topic)
		);
		var {id} = this;
		var wins = callback => {
			for(var win of CustomizableUI.windows) {
				var btn = win.document.getElementById(id);
				btn && callback(btn, win);
			}
		}
		if (this.excludeHiddenOneOffs && !this.fx116) {
			var setRebuild = btn => btn.firstChild.shouldRebuild = true;
			var {pref} = this, obs = () => wins(setRebuild);
			Services.prefs.addObserver(pref, obs);
			this.q = () => remove(Services.prefs.removeObserver(pref, obs));
		}
		else this.q = remove;

		var updButton = (btn, win) => {
			var popup = btn.firstChild;
			var engine = popup.getDefaultEngine();
			/*btn.label =*/ btn.tooltipText = engine.name;
			popup.shouldRebuild = true;
			win.requestAnimationFrame(async () => btn.icon.src = await this.img(engine));
		}
		(this.b = () => wins(updButton))();
		this.updButton = updButton;
		btn.tooltipText || updButton(btn, win);
	},
	pref: "browser.search.hiddenOneOffs",
	json: e => JSON.stringify(e.toJSON()),
	img: async e => await e.getIconURL?.() || e.iconURI?.spec || "chrome://browser/skin/search-engine-placeholder.png",

	// https://github.com/Infocatcher/Custom_Buttons/blob/master/code_snippets/autoOpenCloseMenu.js
	// Automatically open menu on mouse over (and hide it on mouse out)
	autoOpenCloseFeature(win, btn, openDelay = 200, closeDelay = 350) {
		var _openTimer = 0;
		var _closeTimer = 0;
		btn.onmouseover = function(e) {
			win.clearTimeout(_closeTimer);
			if(e.target == btn && closeOtherMenus()) {
				btn.open = true;
				return;
			}
			_openTimer = win.setTimeout(function() {
				btn.open = true;
			}, openDelay);
		};
		btn.onmouseout = function(e) {
			win.clearTimeout(_openTimer);
			_closeTimer = win.setTimeout(function() {
					btn.open = false;
			}, closeDelay);
		};
		function closeOtherMenus() {
			return win.Array.prototype.some.call(
				btn.parentNode.getElementsByTagName("*"),
				function(node) {
					if(
						node != btn
						&& win.XULElement.isInstance(node)
						// See https://github.com/Infocatcher/Custom_Buttons/issues/28
						//&& node.boxObject
						//&& node.boxObject instanceof Components.interfaces.nsIMenuBoxObject
						&& "open" in node
						&& node.open
						&& node.getElementsByTagName("menupopup").length
					) {
						node.open = false;
						return true;
					}
					return false;
				}
			);
		}
	}
});} catch(ex) {Cu.reportError(ex);}

Отсутствует

 

№128414-03-2024 18:55:25

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 599
UA: Firefox 115.0

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

Dumby пишет

Вобщем вот, небольшая модификация обсуждавшегося кода

Dumby, в консоль пишет: CustomizableUI: Could not localize property 'ucf-cbbtn-ToggleCurrentSearchEngine.tooltiptext'.


Если в код добавить что-то типа:
tooltiptext: "Переключить текущий поисковик",
то тогда в консоли чисто.


«The Truth Is Out There»

Отсутствует

 

№128514-03-2024 20:06:02

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

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

egorsemenov06 пишет

Получаеться что и эта кнпка не будет работать

Ну, что значит не будет работать?
В данном случае речь о том, что перестанут подхватываться иконки
встроенных поисковиков (не поисковиков, которые поставил пользователь),
когда включат search-config-v2 (пока что, только в Nightly).


А правка там простая

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

Выделить код

Код:

/*
        node.setAttribute("image", engine._iconURI ? engine._iconURI.spec : engine.iconURI ? engine.iconURI.spec : this.defaultImg);
*/
        node.setAttribute("image", await engine.getIconURL?.() || engine.iconURI?.spec || this.defaultImg);

unter_officer пишет

в консоль пишет: CustomizableUI: Could not localize property 'ucf-cbbtn-ToggleCurrentSearchEngine.tooltiptext'.

Да, есть такое, за всем не уследишь.
Можно добавить, например, второй строкой
localized: false,


xrun1 пишет

переделать на mjs?

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


Никаких выкрутасов, никаких __URI__ (которого в ESM нет),
никакого использования top-level this (который в ESM undefined),
разве что для Services, но он всё равно уже давно везде определён.


В скрипте меняем

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

Выделить код

Код:

/*
                    moduleURI: "chrome://user_chrome_files/content/custom_scripts/cs/UcfTooltipUrlChild.jsm",
*/
                    esModuleURI: "chrome://user_chrome_files/content/custom_scripts/cs/UcfTooltipUrlChild.mjs",


а в модуле
скрытый текст

Выделить код

Код:

/*
var EXPORTED_SYMBOLS = ["UcfTooltipUrlChild"];
ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
class UcfTooltipUrlChild extends JSWindowActorChild {
*/
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
export class UcfTooltipUrlChild extends JSWindowActorChild {


Вот и всё.

Отсутствует

 

№128614-03-2024 20:24:16

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 599
UA: Firefox 115.0

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

Dumby пишет

Да, есть такое, за всем не уследишь.
Можно добавить, например, второй строкой
localized: false,

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


«The Truth Is Out There»

Отсутствует

 

№128714-03-2024 22:46:44

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

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

Dumby пишет

Не, Виталий такую шляпу не пишет, у него всё как-то более академично.

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


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

Отсутствует

 

№128814-03-2024 23:43:16

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

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

Dumby пишет

Вобщем вот, небольшая модификация обсуждавшегося кода

ой а без директивы localized: false вы сразу отшибаете таких пользователей как например я..


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

Отсутствует

 

№128915-03-2024 00:15:46

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

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

Dumby
Спасибо за урок, есть много нюансов которые не знал где почерпнуть (async await)


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

Отсутствует

 

№129015-03-2024 01:08:46

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 599
UA: Firefox 115.0

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

Dumby
Вы когда-то помогли мне переделать кнопку CB в UCF:

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

Выделить код

Код:

(async initCode => CustomizableUI.createWidget({
    id: "ucf_UpDownCenterPage",
    label: "Up/Down/Center Page",
    // defaultArea: CustomizableUI.AREA_NAVBAR,
    localized: false,
    onCreated(btn) {
        btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAFo9M/3AAAACXBIWXMAAAAAAAAAAAHqZRakAAACvElEQVQ4y3VTX0jTURT+rrsqmm3gwm02dZOZOk3RFCTMp4ggEQIT9GUD7VV8mDNF2NaD4qY2X8PBBpGkDwX64EP6YILGilzl3B/dnI5UMHSUWHO/3+1h/pva93S595zvfN8551IcgyYcZMYbHhpV17MU4xShABBV17MU9xR5xjSMAsCIe34ZAKb7F86S00aJ77CN3aJNUpVbnpYhX2pNvj7b5gQVJaceEEJWZ4mzEgBolHGrHPicwg5FxGtdF51ydCjKI9Z1lwgXQAGgr7CWJQkEGKh+yLqc00Tdlb+TdCTA92G/hAJAj3eenGQUmPKYsDsNAKBKzY3r1sgLJ+wlDxr1vg+TFsMS8RsulDiPfE3OWKg0fLvgh3Lf8yJQeykg4NhsBgAPAmcMnP0t48w2pLiniFIjn7hrL238rPdOeizBBjpYXMcslhHwACw1j9ioyO1y6da2wRMFAFDdyhxheffZoUqB9JlRgsUr+kBC7wlC8YuaaAkDgHZBJ1oE2vi8RiH1hcXXeOPPtaLFlGXymrOzFoGWnDK0VtUVoKQCRkc3AODk8co+XAWlRj6htMsaZRAjBxK8089NeizBhksEHYryyJDRKBzoM6PHt3BahYDEFmyf/NE9RLMOxFQUE2YmKDDllbFekwmc2QbObIOOiqFT1zPD7xD6N76RgGOzGY54whZ2sYXdxC4ZQl+JQfv4vxZUT3Od6S9JVfpRBm5yUrh7g19WhgKVCRbaFWVLaYTKjijhwZDE87Eda8BVVj2oZnyUAzVT8AwI89uQZIkrsi1ZbKZzkZwSRGJ//SPSonKIJYA0G/q5Nx8BwKlzk9wmmTv7VWYxOZ7f807TL89wUJigwBH2PnGEvVda2BjfUm+Mb6GwQxFpsWpFlzYlvvNFY/fC+3f28Cd6IBbTfVHGrjXgqj0f7LWuX/py/wDHfA2DzTMorQAAAABJRU5ErkJggg==");
        new btn.ownerGlobal.Function(initCode).call(btn);
    }
}))(`(u => {
    var id, lfs = url => gBrowser.selectedBrowser.messageManager.loadFrameScript(url, false);
    var max = () => {
        var url = u([
            "var args = [scroller.scrollHeight, 0];",
            "scroller.scrollTop != 0 || args.reverse();",
            "content.scrollTo(...args);"
        ].join("\\n\\t"));
        (max = () => lfs(url))();
    }
    var mid = () => {
        var url = u("content.scrollTo(0, (scroller.scrollHeight - scroller.clientHeight) / 2);");
        (mid = () => id = lfs(url))();
    }
    var obj = {
        mousedown: () => id = setTimeout(mid, 500),
        mouseup: () => id && max(id = clearTimeout(id))
    };
    this.onmousedown = this.onmouseup = e => e.button || obj[e.type]();
    this.tooltipText = "ЛКМ:   Вверх/Вниз по странице \\nдЛКМ: Центрирование страницы";
})
(code => "data:," + encodeURIComponent(\`(doc => {
    var root = doc.documentElement;
    var body = doc.body || root;
    var scroller = body.scrollHeight > root.scrollHeight ? body : root;
    \${code}
})(content.document)\`));`);

Я этой кнопкой пользуюсь нечасто, поэтому как-то сразу не заметил один нюанс.
Если в исходном коде страницы сайта отсутствует элемент <!DOCTYPE>, то кнопка начинает работать неправильно. Проверить можно, например, на forum.ru-board.com
Это возможно как-то поправить?


«The Truth Is Out There»

Отсутствует

 

№129115-03-2024 05:20:16

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

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

Dumby - поправь код менюшки! Не работает upd(){… для подменю!
Одинаковый код обновления не пашет в подменю, но работает в первой и последней строках меню.
screen-2024-03-15-10-11-19.png

Выделить код

Код:

(async id => { // forum.mozilla-russia.org/viewtopic.php?pid=808738#p808738

MyMenu = { //массив команд пользователя, alt() клик правой кнопкой
	Pics: { // Графика сайтов Вкл/Выкл permissions.default.image

		upd() { // обновлять сроку перед показом меню
			// var {G} = this.ownerGlobal;
			var val = G.pref(G.v), s = val == 1, i = G.pdi; s ? i = i.replace("-blocked","") : 0;
			this.label = `Графика сайтов ${s ? "загружается" : val == 3 ? "кроме сторонних" : "отключена"}`;
			this.image = i || G.chk;
			this.tooltipText = G.v +" "+ val +"\nRClick – кроме сторонних";
		},
		cmd(){
			G.pref(G.v, G.pref(G.v) == 2 ? 1 : 2);
			BrowserReload();
		},
		// alt(){ //для RClick нужен ucf_hookClicks.js
		// 	G.pref(G.v, 3); BrowserReload();
		// },
	},
	"SubMenu": { men: 1, //подменю
		"SubItem": {
			lab: "SubItem Mod",
			// img: G.opt,
			upd() { // обновлять сроку перед показом меню
				var val = G.pref(G.v), s = val == 1, i = G.pdi; s ? i = i.replace("-blocked","") : 0;
				this.label = `SubItem: Графика ${s ? "загружается" : val == 3 ? "кроме сторонних" : "отключена"}`;
				this.image = i || G.chk;
				this.tooltipText = G.v +" "+ val +"\nRClick – кроме сторонних";
			},
			cmd(){console.log(this.label)},
		},
	},
	"End Menu": { sep: 1, //сперва разделитель
		upd() { //обновить иконку
			var val = G.pref(G.v), s = val == 1, i = G.pdi; s ? i = i.replace("-blocked","") : 0;
			this.image = i;
		},
	},
}

CustomizableUI.createWidget({
		id: id, label: id, tooltiptext: id, localized: false,
		defaultArea: CustomizableUI.AREA_NAVBAR,
		onCreated(btn) {
			btn.style.setProperty("list-style-image", "url(chrome://branding/content/icon32.png)");
			btn.type = "menu";
			var doc = btn.ownerDocument, m = nn => doc.createXULElement(nn);
			var popup = m("menupopup"), menu = m("menuitem");
			menu.m = m;
			menu.fill = this.fill;
			menu.render = this.render;
			popup.append(menu);
			btn.prepend(popup);
		},
		render(){
			var popup = this.parentNode;
			this.remove();
			this.fill(MyMenu, popup);
		},

	fill(o, popup) {
		for (key in o) {
			var val = o[key];
			if (typeof val != "object") continue;

			var {lab, inf, img, cmd, alt, sep, men, upd} = val;

			sep && popup.append(this.m("menuseparator"));
			var name = men ? "menu" : "menuitem";
			var item = this.m(name);

			item.setAttribute("label", lab || key);
			// item.alt = alt; //RClick в ucf_hookClicks.js {Mouse…
			if (inf)
				item.tooltipText = inf;
			if (img || /this\.image.*=/.test(upd))
				item.className = name + "-iconic", item.setAttribute("image", img || G.nul);
			men || cmd && item.setAttribute("oncommand", cmd.toString().replace(
				/cmd\(.*?\){/, "{var trg = event.target || event;"
			));
			popup.append(item);
			upd && (item.render = upd).call(item);
			men && this.fill(val, item.appendChild(this.m("menupopup")));
		}
	},
});

var {prefs} = Services;
G = {
	pref(key,set){ //или key = [key,default]
		if (!Array.isArray(key)) key = [key];
		var t = prefs.getPrefType(key[0]), m = {b:"Bool",n:"Int",s:"String"};
		t = m[t == 128 ? "b" : t == 64 ? "n" : t == 32 ? "s" : ""];
		if (set == "get") return t; //тип опции
		if (!t) t = m[set != undefined ? (typeof set)[0] : (typeof key[1])[0]];
		if (t) if (set != undefined)
			prefs[`set${t}Pref`](key[0],set)
		else
			set = prefs[`get${t}Pref`](...key);
		return set;
	},
	v: "permissions.default.image",
	pdi: "chrome://browser/skin/canvas-blocked.svg",
	chk: "chrome://devtools/skin/images/check.svg",
	nul: "chrome://devtools/skin/images/blocked.svg",
}

})("ucf_test_menu");

Отсутствует

 

№129215-03-2024 14:46:57

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

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

unter_officer пишет

Это возможно как-то поправить?

Даже не знаю, может так попробовать

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

Выделить код

Код:

/*
    var root = doc.documentElement;
    var body = doc.body || root;
    var scroller = body.scrollHeight > root.scrollHeight ? body : root;
*/
    var scroller = doc.scrollingElement;

Dobrov пишет

код обновления не пашет в подменю

Разве? Код-то как раз пашет, но пункт не render'ится.


Когда добавляешь пункт в основное меню он render'ится сразу,
но когда в субменю, тогда нет. А когда будет следующий вызов render()
метод уже переопределён и ничего не render'ит.


Можно сразу принудительно отрендерить, но лучше, наверно, отложить.
Плюс, upd() вызывается для пунктов субменю даже просто при открытии основного меню,
а это слегка нехорошо. Возможно, стоит проверять, что субменю открыто.


Вобщем, так поменял фрагмент кода создания виджета

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

Выделить код

Код:

CustomizableUI.getWidget(id)?.label || (self => CustomizableUI.createWidget(self = {
		id, label: id, tooltiptext: id, localized: false,
		defaultArea: CustomizableUI.AREA_NAVBAR,
		onCreated(btn) {
			btn.style.setProperty("list-style-image", "url(chrome://branding/content/icon32.png)");
			btn.type = "menu";
			var doc = btn.ownerDocument, m = nn => doc.createXULElement(nn);
			var popup = m("menupopup"), menu = m("menuitem");
			menu.m = m;
			menu.fill = this.fill;
			menu.render = this.render;
			popup.append(menu);
			btn.prepend(popup);
		},
		render(){
			var popup = this.parentNode;
			this.remove();
			this.fill(MyMenu, popup);
		},
		fill(o, popup) {
			for (key in o) {
				var val = o[key];
				if (typeof val != "object") continue;

				var {lab, inf, img, cmd, alt, sep, men, upd} = val;

				sep && popup.append(this.m("menuseparator"));
				var name = men ? "menu" : "menuitem";
				var item = this.m(name);

				item.setAttribute("label", lab || key);
				// item.alt = alt; //RClick в ucf_hookClicks.js {Mouse…
				if (inf)
					item.tooltipText = inf;
				if (img || /this\.image.*=/.test(upd))
					item.className = name + "-iconic", item.setAttribute("image", img || G.nul);
				men || cmd && item.setAttribute("oncommand", cmd.toString().replace(
					/cmd\(.*?\){/, "{var trg = event.target || event;"
				));
				popup.append(item);

				if (upd)
					if (item.renderedOnce) (item.render = upd).call(item);
					else item.upd = upd, item.render = self.renderSub;

				men && this.fill(val, item.appendChild(this.m("menupopup")));
			}
		},
		renderSub() {
			delete this.render;
			this.render();
			this.render = self.updSub;
			this.upd();
		},
		updSub() {
			this.parentNode.state.startsWith("c") || this.upd();
		}
}))();

Отсутствует

 

№129315-03-2024 17:16:39

unter_officer
Участник
 
Группа: Members
Откуда: Санкт-Петербург
Зарегистрирован: 27-03-2011
Сообщений: 599
UA: Firefox 115.0

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

Dumby пишет

Даже не знаю, может так попробовать

Dumby, большое спасибо. Как всегда всё супер!


«The Truth Is Out There»

Отсутствует

 

№129416-03-2024 16:59:51

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

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

Dumby - спасибо, добавил примеры в пользовательское меню, где меняются иконки, текст и подсказки в зависимости от настроек.
Изменяемые по клику строки меню отличаются выделенным шрифтом.


Обновил меню в ucf_hookClicks.js и исправил совместимость с UCF 2024.
Firefox/config.js может грузить старую и новую версию UCF.

Отсутствует

 

№129516-03-2024 18:41:23

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

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

Dobrov пишет

исправил совместимость с UCF 2024.
Firefox/config.js может грузить старую и новую версию UCF

Немного запоздало я как раз недавно обновил несколько файлов config.js user_chrome.js vertical_top_bottom_bar.css
https://github.com/VitaliyVstyle/Vitali … /config.js

Отсутствует

 

№129616-03-2024 18:56:23

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

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

Vitaliy V. - спасибо!
забываю проверять обновления UCF…
и теперь новый упрощённый config.js не загружает user_chrome.js от старого UCF

Отсутствует

 

№129716-03-2024 22:42:39

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

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

Dobrov
Спасибо за обновы, особенно за ucf_hookClicks.js) Удобная штука. Все что хотел раньше от скриптов, все в одном флаконе, под любые хотелки. Кстати, а что за сборка 116? esr?

Отсутствует

 

№129816-03-2024 23:32:57

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

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

Vitaliy V.
Спасибо за обновления. Рад вас видеть.
   
Dumby
Приветствую.
Лоадер применительно к mjs не изменился?
Предполагаю что нет, так как один конвертированный скрипт в нем уже работает.
   
И, пожалуйста, переделайте в mjs jsm-ки:
1. TST Reload Tab Interval
2. TST TabPreview
   
TST

Отредактировано _zt (16-03-2024 23:42:36)

Отсутствует

 

№129917-03-2024 04:13:31

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

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

Dumby :beer: такой глупый вопрос: JS скрипты будут дóльше поддерживаться в Firefox, чем JSM-ки?


Если это так, то возможно переделать в JS скрипт сохранения страниц SingleHTML.JSM (в custom_scripts UCF 2024 тоже JS-скрипты)
Его функции используют два скрипта (а могут и другие): ClickPicSave.jsm и ucf_hookClicks.js


b0ttle пишет

ucf_hookClicks.js Удобная штука. Все что хотел раньше от скриптов, все в одном флаконе
а что за сборка 116? esr?

в ucf_hookClicks.js код слишком компактный, чтоб легко подстроить «под себя» строки меню/нажатия клавиш/клики мыши в первых блоках. Позже отформатирую по правилам, разграничив блоки разных назначений.
А браузер обычный LibreWolf 116 arm64 на Apple Silicon Mac M3, не вижу смысла постоянно обновлять (поставил в игнор для менеджера пакетов brew)

Отсутствует

 

№130017-03-2024 07:08:48

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

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

Vitaliy V. - пожелание:
добавить подключение стилей по имени в зависимости от OS – иногда нужно использовать один профиль на разных системах, для которых CSS не совпадают.
вот так работает в CustomStylesScripts.mjs (на MacOS подключается custom_styles_all_user_macosx.css):

Выделить код

Код:

const {AppConstants} = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
var os = name => `${name.replace(/\.[^.$]+$/,'')}_${AppConstants.platform}${name.lastIndexOf('.') > 0 ? "."+ name.split('.').pop() : ""}`;
…………
	stylesall: [ // Для всех документов
		{ path: "custom_styles_all_user.css", type: "USER_SHEET", sheet() { registerSheet(this); }, },
	// стиль для вашей операционной системы: *_macosx.css, *_linux.css, *_win.css
		{ path: os("custom_styles_all_user.css"), type: "USER_SHEET", sheet() { registerSheet(this); }, },
	],

Отредактировано Dobrov (17-03-2024 07:15:48)

Отсутствует

 

Board footer

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