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

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

№20106-12-2024 16:28:15

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

Re: userChrome.js

dinn пишет

а как бы вы сделали?

Я? Ну, мне бы хотелось видеть нечто
чуть более информативное, то есть типа это альфа, бета, esr'ка...


Хотя, может быть таков и был твой замысел, обрезать именно
до трёх символов, чтобы занимало меньше места (отсюда же замысел не видно).


Всё нижепоследующее не имеет хоть сколько-нибудь
какого-то значения, но лишь чистая вкусовщина.


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


Название переменной elem, возможно, чтобы подчеркнуть,
что это не просто нода, а именно элемент.
Но я, скорее, склонен был бы её так и назвать — label


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


Если есть возможность прицепить в обёртку нечто,
заведомо не могущее образовать ошибку (типа просто строка),
то, вроде, так чуть красивее смотриться, чем просто голые скобки ()


Вобщем, то же самое — вид сбоку

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

Выделить код

Код:

(async css => {
	var label = document.createElement("label");
	label.append(AppConstants.MOZ_APP_VERSION_DISPLAY);   
	label.style.cssText = css;
	gURLBar._inputContainer.append(label);
})(`
	padding-block: 1px;
	font-size: 13px;
	color: gray;
`);

Отсутствует

 

№20209-12-2024 13:11:46

dinn
Участник
 
Группа: Members
Зарегистрирован: 28-09-2024
Сообщений: 46
UA: Firefox 133.0

Re: userChrome.js

Dumby, спасибо, подправил у себя + проверка на окно, чтобы консоль не пищала на AppConstants.


Возвращаясь к этому, не хватает подсказки при наведении мыши на кнопку - многострочную. Придумал так
btn.setAttribute("title", "1\tFirst line\n2\tSecond line");
Не знаю, как по другому еще можно и нужно ли


Не в тему, но отсутствие ответа на вопрос не дает мне норм спать по ночам. Можно ли как-то посмотреть прослушки на #main-window? В инспекторе есть кнопка event, но при ее нажатии ошибка в консоли
Error while calling actor 'domnode's method 'getEventListenerInfo' passing non-debuggable global to addDebuggee

Отсутствует

 

№20309-12-2024 20:52:00

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

Re: userChrome.js

dinn пишет

Придумал так
btn.setAttribute("title", "1\tFirst line\n2\tSecond line");
Не знаю, как по другому еще можно

Да чего там ещё от добра добра искать.
resource://gre/modules/TooltipTextProvider.sys.mjs
твой "title" подхватит, и в #aHTMLTooltip'е будет показан.

Можно ли как-то посмотреть прослушки на #main-window? В инспекторе есть кнопка event

Кнопка, это конечно хорошо, но,
раз такое дело, то почему бы не попрактиковать аскетику.


Запускаешь
Services.els.getListenerInfoFor(document.documentElement);
и смотришь.


Но, что-то там ничего особо интересного не видно.
Мне отдаёт массив всего из пяти экземпляров nsIEventListenerInfo
у каждого из которых, свойство listenerObject есть null


Впрочем, если задуматься, ничего удивительного, что так мало.
Кому бы понадобилось вешать листенер именно на html#main-window
Либо на что-то более конкретное дочернее,
либо, тогда уж, сразу на документ, окно, windowRoot окна
(вот там, числа уже вокруг сотни).

Отсутствует

 

№20415-12-2024 14:13:43

dinn
Участник
 
Группа: Members
Зарегистрирован: 28-09-2024
Сообщений: 46
UA: Firefox 133.0

Re: userChrome.js

Dumby пишет

resource://gre/modules/TooltipTextProvider.sys.mjs
твой "title" подхватит, и в #aHTMLTooltip'е будет показан.

да и без файла подхватывает, а отображение в aHTMLTooltip не особо нужно

Кому бы понадобилось вешать листенер именно на html#main-window

Да часто лопушусь из-за названия main-window и считаю, что в нем прослушки на window


Я вот тута подумал, а можно ведь версию сабжа отображать вместо дефолтного placeholder с никому не нужной "Search or enter address".
Но реализация у меня костыльная. Здеся можно стилями изменить название, а если замутить


content: attr(ffversion);


а затем через обсервер в config.js


  let str = Services.appinfo.name + " " + Services.appinfo.platformVersion + " " + Services.appinfo.defaultUpdateChannel;
  doc.getElementById("urlbar-input").parentNode?.setAttribute("ffversion", str);


то получим то, что хотели

Отсутствует

 

№20516-12-2024 21:26:42

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

Re: userChrome.js

dinn пишет

да и без файла подхватывает, а отображение в aHTMLTooltip не особо нужно

Это было просто информационное сообщение.
Оно может быть понятным, или не понятным,
интересным, или не интересным ...


Но, оно не для того, чтобы комментировать поперёк.
Разве что только если я не прав. Хорошо, давай проверим.

и без файла подхватывает

Испортим то, что делает файл. Запускаем с консоли браузера:


ChromeUtils.importESModule("resource://gre/modules/TooltipTextProvider.sys.mjs")
    .TooltipTextProvider.prototype.getNodeText = (elm, out) => out.value = "???";


Затем, наводим указатель мыши на кнопку.
Что видно в тултипе?

отображение в aHTMLTooltip не особо нужно

Ладно, тогда долой. Запускаем aHTMLTooltip.remove();
Снова наводим. Как теперь видно?

версию сабжа отображать вместо дефолтного placeholder
можно стилями изменить название

Ну, не прямо «изменить».
Это некая CSS-мимикрия под это дело.
Довольно симпатичная, пока для псевдоэлемента
хватает горизонтального места.


А, если именно «изменить»,
то, скорее, наверно, типа как-то так.


Увы, изменить мало, надо ещё как-то предотвратить
обратную перестановку со стороны браузера.
Вариант с MutationObserver'ом

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

Выделить код

Код:

(async (attr, rem) => {
	var input = document.getElementById("urlbar-input");
	(rem = () => input.removeAttribute(attr))();
	new MutationObserver(rem).observe(input, {
		attributes: true, attributeFilter: [attr]
	});

	input.setAttribute("placeholder", "Version Info");

})("data-l10n-id");


и без него
скрытый текст

Выделить код

Код:

(async keys => {
	var input = document.getElementById("urlbar-input");
	input.removeAttribute("data-l10n-id");

	input.setAttribute("placeholder", "Version Info");

	var p = Promise.resolve(), noop = () => p;
	for(var key of keys) BrowserSearch[key] = noop;

	Object.getOwnPropertyDescriptor(window, "gURLBar").get
		&& await document.documentReadyForIdle;

	var code = `{${gURLBar.view.input._updateSearchModeUI}}`.replace(
		/this\.document\.l10n\.setAttributes\([^)]+?this\.inputField.+?\);/gs,
		"// placeholder setup was here"
	);
	var url = `data:,Object.assign(gURLBar.view.input, ${encodeURIComponent(code)});`;
	(await ChromeUtils.compileScript(url)).executeInGlobal(window);
})([
	"initPlaceHolder",
	"_setURLBarPlaceholder",
	"_updateURLBarPlaceholder",
	"_updateURLBarPlaceholderFromDefaultEngine"
]);

Отсутствует

 

№20617-12-2024 13:11:05

dinn
Участник
 
Группа: Members
Зарегистрирован: 28-09-2024
Сообщений: 46
UA: Firefox 133.0

Re: userChrome.js

Dumby пишет

Это было просто информационное сообщение.
Оно может быть понятным, или не понятным

Мне не понятно, почему один и тот же атрибут на элементе button ведет себя по разному.
для одной кнопки атрибут title связан с подсказкой, а tooltiptext не пашет
для другой кнопки атрибут tooltiptext связан с подсказкой, а title - с названием
Может зависит от типа родительского элемента?


Dumby пишет

Испортим то, что делает файл

Да, теперь вижу зависимость от файла. "Хорошо" сломало тултипы с пониженными правами


Про placeholder, благодарю за оба варианта. Потестирую и если что не так - отпишусь.

Отсутствует

 

№20717-12-2024 20:04:41

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

Re: userChrome.js

dinn пишет

для одной кнопки атрибут title связан с подсказкой, а tooltiptext не пашет
для другой кнопки атрибут tooltiptext связан с подсказкой

Процитирую часть кода из TooltipTextProvider.sys.mjs

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

Выделить код

Код:

.....
      if (tipElement.namespaceURI == XUL_NS) {
        lookingForSVGTitle = false;
        titleText = tipElement.getAttribute("tooltiptext");
      } else if (!defView.SVGElement.isInstance(tipElement)) {
        lookingForSVGTitle = false;
        titleText = tipElement.getAttribute("title");
      }


То есть, если это XUL элемент, то берётся атрибут "tooltiptext".
Иначе, если это не SVG элемент, то берётся атрибут "title".


Вот, демо-код для запуска с консоли.
Окошко с двумя кнопками.
У обоих кнопок присутствуют оба атрибута.
Какой будет показан в тултипе?

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

Выделить код

Код:

(async (TITLE, TOOLTIP_TEXT) => {

	var win = openDialog("about:blank", "", "chrome,centerscreen,width=340,height=220");
	Services.scriptloader.loadSubScript("chrome://global/content/customElements.js", win);
	await new Promise(resolve => win.addEventListener("DOMContentLoaded", resolve, {once: true}));

	win.windowUtils.loadSheetUsingURIString("data:text/css," + encodeURIComponent(`
		:root, body {
			height: 100vh;
			display: flex;
			align-items: center;
			flex-direction: column;
			justify-content: space-around;
		}
		button {
			color: gray;
			font: 42px monospace, auto;
		}
	`), win.windowUtils.USER_SHEET);

	var doc = win.document;
	doc.title = "Test";


	var htmlButton = doc.createElement("button");
	
	htmlButton.setAttribute("title", `\n   HTML Button ${TITLE} Attribute   \n `);
	htmlButton.setAttribute("tooltiptext", `\n   HTML Button ${TOOLTIP_TEXT} Attribute   \n `);

	htmlButton.append("HTML Button");
	doc.body.append(htmlButton);


	var xulButton = doc.createXULElement("button");

	xulButton.setAttribute("title", `\n   XUL Button ${TITLE} Attribute   \n `);
	xulButton.setAttribute("tooltiptext", `\n   XUL Button ${TOOLTIP_TEXT} Attribute   \n `);

	xulButton.setAttribute("label", "XUL Button");
	doc.body.append(xulButton);
})(
	"\u{1d413}\u{1d408}\u{1d413}\u{1d40b}\u{1d404}",
	"\u{1d413}\u{1d40e}\u{1d40e}\u{1d40b}\u{1d413}\u{1d408}\u{1d40f} \u{1d413}\u{1d404}\u{1d417}\u{1d413}"
);

Отсутствует

 

№20818-12-2024 20:37:19

dinn
Участник
 
Группа: Members
Зарегистрирован: 28-09-2024
Сообщений: 46
UA: Firefox 133.0

Re: userChrome.js

Dumby пишет

То есть, если это XUL элемент, то берётся атрибут "tooltiptext".
Иначе, если это не SVG элемент, то берётся атрибут "title".

Ок, теперь ясно



Возвращаясь к скрытым вкладкам, обнаружил траблу.
Для короткоживущих (например, при открытии исх кода в новом окне) код работает как мне надо, т.е. не выводит алерт, однако это происходит за счет ошибки в консоли
"record.target.linkedBrowser is null"
Для исправления немного переделал код и вроде теперь все ок

original

Выделить код

Код:

var notify = records => alert('"true" hidden attribute on tab(s) detected.\n\n' + records.map(info).join("\n\n"));

mod

Выделить код

Код:

var notify = records => {
	for (let mutation of records) {
		if (mutation.target.collapsed) return;
	}
	alert('"true" hidden attribute on tab(s) detected.\n\n' + records.map(info).join("\n\n"));
}

Отсутствует

 

№20903-02-2025 20:16:11

dinn
Участник
 
Группа: Members
Зарегистрирован: 28-09-2024
Сообщений: 46
UA: Firefox 134.0

Re: userChrome.js

Dumby возможно ли через скрипт получить полномочия аддонов webRequestBlocking для окучивания заголовка Content-Disposition?

Отсутствует

 

№21004-02-2025 16:54:03

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

Re: userChrome.js

dinn пишет

через скрипт получить полномочия аддонов webRequestBlocking

Наооборот. Скрипты проксируют полномочия для WebExtensions.
У самих скриптов все полномочия уже есть от природы.

для окучивания заголовка Content-Disposition

Здесь особо помочь не смогу,
дела контентские, мне негде взять подобные заголовки.
Наверно, можно оттолкнуться от чего-то такого

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

Выделить код

Код:

window.__SSi == "window0" && (async topic => {

	var obs = (channel, topic) => {

		try {var header = channel.getResponseHeader("content-type");}
		catch(ex) {header = "[ERROR] " + ex.name;}
		console.log(topic + "\n" + channel.name.slice(0, 100) + "\nContent-Type: " + header);


		try {channel.setResponseHeader("Last-Modified", "Sat, 01 Jan 2000 00:00:00", false);}
		catch(ex) {console.log("[ERROR] " + topic, ex);}
	}

	Services.obs.addObserver(obs, topic);
	Services.obs.addObserver(function quit(s, t) {
		Services.obs.removeObserver(quit, t);
		Services.obs.removeObserver(obs, topic);
	}, "quit-application-granted");
})(
	"http-on-examine-response"
);


Чтиво: nsIHttpProtocolHandler.idl (топики), nsIHttpChannel.idl ({g, s}etResponseHeader).

Отсутствует

 

№21106-02-2025 13:21:10

dinn
Участник
 
Группа: Members
Зарегистрирован: 28-09-2024
Сообщений: 46
UA: Firefox 134.0

Re: userChrome.js

Dumby крутяк, дарю благо. Ранее этот топик был мною опробован, но почему-то всегда пытался получить (а не установить) заголовок, который на испытуемом сайте никогда сам не устанавливался. Теперь все ок.

Отсутствует

 

№21207-02-2025 14:30:09

dinn
Участник
 
Группа: Members
Зарегистрирован: 28-09-2024
Сообщений: 46
UA: Firefox 134.0

Re: userChrome.js

Dumby в этом коде прослушку лучше вынести за пределы рендера?

Отредактировано dinn (07-02-2025 14:30:46)

Отсутствует

 

№21308-02-2025 15:20:32

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

Re: userChrome.js

dinn
Если бы чуть намекнул, чем вызвана идея этой инициативы,
то у меня хотя бы был бы шанс попробовать задуматься.


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


Кстати, я вроде видел этот код, и даже мод сочинял, если интересно.

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

Выделить код

Код:

// Mod
location == "chrome://browser/content/browser.xhtml" && (async img => {

	var menuitem = menu_pageInfo.cloneNode(false);
	menuitem.id = "context-viewPageInfo-mod";
	document.getElementById("context-viewsource").before(menuitem);

	var hidden = (d = nsContextMenu.contentData, {context: c, browser: b} = d) =>
		c.link || d.selectionInfo.text || c.onImage || c.onCanvas || c.onVideo || c.onAudio || c.onTextInput || b.className.startsWith("webext");

	menuitem.render = () => {
		if (menuitem.hidden = hidden()) return;

		menuitem.removeAttribute("key");
		menuitem.className = "menuitem-iconic";

		delete menuitem.render;
		menuitem.render();
		menuitem.querySelector(".menu-iconic-icon").src = img;

		// Just visual diff, not part of mod.
		menuitem.querySelector(".menu-iconic-icon").style.filter = "hue-rotate(-100deg) brightness(1.35)";

		menuitem.render = () => menuitem.hidden = hidden();
	}
})(
	"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACp0lEQVQ4jV2TPW9cVRCGn3fOuffu9Xo3TnCEkANYQotB2WJpUqWwJSqIUuQPRKKlsAUFpeUmEpXXEv+ACClFitQowmUIMmxASowIkjuQk9jr/fDd7F3fQ7HWdcxI04zmfc47RzPif9G4cXdR0iqy5flL9VYRAoe9rCNpG9nW7v1be2/2qxR+/v0c0vp7C/NrV5euMCkijoYTXucnEALDYcaLwx7DLGsjbTy7d7NbAk7FP12/ttSq1uZ48vyYLA/UZhwg+qMCZ5A6GGVDesODDtLK0x8+69rUh9avX1tqWVzn0dMhWR4A8eDOxzy48xEyEWQcB4O0Tlq73JK5dQBr3Li7+P7C/NpsbY4nf2dTTxKYyhnNG/KGeQfeEVXrRJXqWvP2w0UvafXq0rv8+vz4TCwhJz795s/p62ZlHQkJ4uoFTnqvVj2y5UnwZOP8XNPj75rlTze/3MV5YU4IoQCJS5Bzy3b5rXrraDgBQQEMRgUH/QmNL/4oAXHiiSueJPUkM554JmK2FlGppC1fBBjnBeNJ4HAwQWZEicN7KwFRxeHjaU1mSDCbBIZ9jx0cHXfyyQkvD3NCAHPCnOEid85BUvEkMxGV6jQvzkVk45OOSdp+dTDAOZDpFCCcK3cMnziiiidJp+JaPcZZgZzfNmRbR4MBl2aENE0zIXc2go8cUeKJU0+lGvPhlYh/9kfI3Jbt3r+1N85ftykyUkcJ6Ww2SsCPX7+Nc4aPHY2FiH5vzL8vx+2dzeaeP93Ejfykv+zMtwKzAHzy1V8kaVTOXavFfDAP3f0BP+8cdGS2AWAAz+7d7CKtSL22D11U5MQBqha4GAfeqQYuKOP33/Z59PhFmxBWfvm2cXZMb0bz9sNFma3K+eUkSVs+dozyoiPnt2Vua2ezee6c/wN/E94boB6vcgAAAABJRU5ErkJggg=="
);

Отсутствует

 

№214Вчера 04:43:53

dinn
Участник
 
Группа: Members
Зарегистрирован: 28-09-2024
Сообщений: 46
UA: Firefox 134.0

Re: userChrome.js

Dumby пишет

Если бы чуть намекнул, чем вызвана идея этой инициативы

Да думал, что прослушка внутри рендера будет неоднократно вызываться, а раз она с анонимной функцией, то это не гуд.
Мод интересен, конечно.
Тоже думал о cloneNode, но, не имея опыта, так и не стал пробовать.
Не догадался втюхать иконку внутри рендера, т.к. не предполагал, что в этом случае не понадобится регистрации для data:image


Переделал по моду и "Copy Link Text". Такую замену нужно на будущее, если не ошибаюсь, а подрубать defineLazyServiceGetter будет излишним

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

Выделить код

Код:

/*
menuitem.setAttribute("oncommand", "navigator.clipboard.writeText(gContextMenu.linkTextStr);");
*/

menuitem.addEventListener("command", () => {
	var clipbrd = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
	clipbrd.copyString(gContextMenu.linkTextStr);
});

А не, разобрался. Пашет и
menuitem.addEventListener("command", () => {navigator.clipboard.writeText(gContextMenu.linkTextStr);});
Так получилось, что id указал "context-copylink" со всеми вытекающими

Отредактировано dinn (Вчера 11:47:24)

Отсутствует

 

№215Вчера 21:52:42

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

Re: userChrome.js

dinn пишет

думал, что прослушка внутри рендера будет неоднократно вызываться

В смысле добавление прослушки будет неоднократно вызываться?
Вроде как это не так уж и сложно проверить.


Перед строкой добавляющей прослушку пишем лог-строку типа
console.log("Щас будет добавлена прослушка");


Если (на одно окно браузера) лог-строка отконсолится более одного раза,
значит твоё опасение подтвердилось.


А если отконсолится только один раз,
значит всё нормально, всё идёт так, как и задумано.
Само контекстное меню, разумеется, следует вызвать несколько раз.

думал о cloneNode, но, не имея опыта, так и не стал пробовать

Клонирование не есть суть.
Можно и создать, проставив атрибуты "command" и "data-l10n-id".
Хрен редьки не фиолетовее.


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

Отсутствует

 

Board footer

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