UserChromeFiles загрузчик скриптов/стилей расширяет возможности Firefox, используя функцию autoconfig. © Vitaliy V.

Установка: содержимое папки Firefox поместить в папку его установки, папку chrome поместить в папку вашего профиля. После изменения/добавления скриптов нажать в about:support «Очистить кэш запуска» или в UCF-диалоге «Перезапустить*». В окне UCF (кнопка Шестерня или about:user-chrome-files) включить нужные панели и настройки. Примеры подключения в custom_script.js, CustomStylesScripts.jsm, CustomStylesScriptsChild.jsm.


Demo-ПРОФИЛЬ для Firefox 78+ от 12.04.22 (полное описание) - 24 UCF-скрипта расширяют функционал, добавляют кнопки, клики, стили: градиент загрузки страниц, автоскрытие панели вкладок, яркость, быстрая закладка, восстановить удалённые закладки, сохранить картинку кликом, запись страниц/выделенного текста даже из режима чтения в единый HTML, перевод сайта/выдел. текста, url в подсказке ссылок, играть/скачать видео-ссылку из контекст-меню, переключение скрытых настроек, копирование ссылки перетаскиванием, режим Прокси меняет цвет фона кнопки ≡ Меню и многое другое…
Подсказки на кнопках (скрипт ucf_hookClicks.js) и встроенная Справка вам в помощь - жмите кнопку «Печать» секунду.

Скрипты/кнопки, установленные в Демо-профиле
Кнопки — расширяемые кликами кнопок мыши и колёсика, сочетания клавиш и жесты:
новые 14 — Журнал и меню опций, История, Закладки, Папки, Пароли, Просмотр части страницы или Запись в Html, Менеджер сессий, Восстановить удалённые закладки или fav-иконки, Ссылки в подсказках, Дополнения, Инспектор атрибутов, UCF…
стандартные 7 — Загрузки, ≡ Меню, Печать, Звёздочка, Щит защиты, Замок, Обновить/Стоп
расширения 2 — SingleFile (сохранение по Alt+Shift+S), Reader View.
User.js скрипт пользователя: запуск по Alt+X, ucf_aom-button.js управление дополнениями
ucf_hookClicks.js глобальные функции, подсказки, перехват нажатий мыши и клавиатуры
ucf_QuickToggle.js открытие боковой панели, меню скрытых системных настроек
attrsInspector.js Attributes Inspector, auto_hide_sidebar.js скрытие боковой панели
menubarVisibilityChance.js, ucf_autohidetabstoolbar.js автоскрытие панели с одной вкладкой
ucf-loads-favicons.js восстановить иконки закладок
ucf_BookmarkDir.js быстрая закладка, перевод сайта/текста
ucf_contextsearch.js поиск в контекстном меню, ucf_findbarclose.js автоскрытие поиска
ucf_cooks-pass.js пароли и куки, ucf_UrlTooltip.js ссылки в подсказках
ucf_LocationBarEnhancer.js градиент загрузки страниц
ucf_pauseResume.js кнопка Пауза для скачиваемых файлов
ucf_downloads_clear.js кнопка "Очистить загрузки" на DownloadsPanel
ucf_session.js сохранение | восстановление сессий
ucf_tab-update.js автообновление вкладок по таймеру
ucf_undo-tab.js история закрытых вкладок/окон
ucf_win_contextmenuopenwith.js можно прописать свои приложения открытия ссылок
ucf_win_mousedrag.js жесты мыши для ссылок и выделенного текста
AppMenuTbbSaveHTMLChild.jsm сохранение страниц в единый Html
ClickPicSave.jsm сохранение картинок, в том числе и недоступных для сохранения обычным способом
UCFTitleChangedChild.jsm авто-коррекция имён (заголовков) вкладок
PageReadMode.user.js выбор части страницы курсорными клавишами после нажатия Alt+R
undoBookmarksContextMenu.uc.js восстановить удалённые Закладки в панели закладок
Возможности дополняются пользовательскими скриптами, например Vk Media Downloader

    Скрипты Для докум. окна браузера [ChromeOnly]:
hookClicks — перехват кликов (в демо-профиле другой код) позволяет «разгрузить» кнопки, не добавлять в них код кликов
UCF drag and go жесты мыши
Обновление вкладок по таймеру
Перезапустить приложение в основном и классическом меню
Фавикон в адресной строке
Автоскрытие панели вкладок
Контекстный поиск
Добавление прокси из контекстного меню
Запуск приложений из контекстного меню
Скрытие панели поиска после клика на странице
Информация о странице, вкладка разрешения
Sidebar Tabs
Добавить кнопку "Очистить загрузки" на DownloadsPanel


    Скрипты В фоне [System Principal]:
Восстановить фавиконки закладок
Автоматически добавлять выделенный текст в SearchBar (авт. Dumby)
Тултипы с URL (авт. Dumby)
Кнопка Дополнения
Кнопка Восстановить
Кнопка Прокси
Добавить кнопку Пауза/Продолжить в загрузки
Замена фавиконок для сайтов
Кнопка «Сохранить» комбинированная, конвертировать в base64


Simple Session Manager by Dumby (+ справка и время сохранения сессии)

Выделить код

Код:

(async (pid, mp, self) => CustomizableUI.createWidget((self = { id: "797321", tooltiptext:
		`Менеджер сессий: Браузер каждые ${Services.prefs.getIntPref('browser.sessionstore.interval',15e3)/60e3} мин
сохраняет сессии, это снижает ресурс SSD\n
Правый клик на Имени сессии:
	Выделить и Открывать при запуске
Колёсико или Клик + Ctrl:
	Открыть сессию в новых вкладках
Сортировка: тащите строки мышью
или курсором, удерживая Shift`, label: "Simple Session Manager", localized: false,
	init() {
		this.handleEvent = e => this[e.type](e);
		this.onTimeout = async () => await this.saveSession() || this.save();
		Services.obs.addObserver(this, "quit-application");
		var {openMenu} = this;
		this.render = function() {
			this.openMenu = openMenu;
			this.constructor.prototype.render.call(this);
		}
		if (!Services.startup.wasRestarted && this.meta.boot != null) setTimeout(() => {
			var name = this.id + "-startup-notification";
			var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
			as.showAlertNotification(	this.image, this.label,
				"Восстановление [boot]-сессии\n\n" + this.meta.order[this.meta.boot],
				false, null, null, name );
			setTimeout(() => as.closeAlert(name), 7e3); // закрыть уведомление
		}, 3e3);
		delete this.init;
		return this;
	},
	image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAEnQAABJ0BfDRroQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGxSURBVDiNnZE/T1NRGMZ/7zn3lmKLkIKpaUxZFINEJZ0YHXRwcnBxMQ6aOJi4+FH8Dm5OOjA4+AEYGCTRook1JlVIVUrbW/rnPg63UtReIr7bOXmf5/ye59jDlanHS3O+wn/Mu+/DF8HFeVe5f+vaPTdfPpF4UNvk6frmhwAvXOEsvrR0IoN47xM4CHCADmDQBkAHbdTrTBRZdgYLs6NTD/MiMC+gC8MO6ke8ffWsXv3S3JpksHouv7Z4/UEeM8z6IwKfEGjYRt0G1d3m1p3n0Y1JBi/vTtfKw1Yec2CHBDFmXYjboAgL4tTc5pXsmcNcDxIDUFQHuqgfYT69OAuE9qqAoX4jIcAL7b9H+0deOYYg3tkYXxx2EAo7dQYEBF/TEULD5oow7KHut18RhGVD3GwxMZ36YWn6IJd37vQCSMSNBpYQCMs43PQMAJXlwtr6k7CGfo9iznN1ebGY7Ak1NSJwYERYJgM+Q+nClVzp/OXc3wWMwdT+jAVKCMwLC2PUeoMrrEI4m94BQq0a6mxjoca/YKFgUCfeqR8jPhoHcIAHe3ST2+UFLv2T8o/5uMvrnx9Wn65p5nMEAAAAAElFTkSuQmCC",
	onCreated(btn) {
		btn.type = "menu";
		btn.phTimestamp = 0;
		btn.render = this.render;
		btn.onclick = this.click;
		btn.setAttribute("image", this.image);
		var popup = btn.ownerDocument.createXULElement("menupopup");
		popup.filler = this;
		popup.id = pid;
		popup.setAttribute("onpopupshowing", "event.defaultPrevented || filler.fill(event)");
		btn.prepend(popup);

		btn.addEventListener("mouseenter", this);
		btn.addEventListener("mousedown", this);
		popup.addEventListener("command", this);
		btn.ownerGlobal.addEventListener("unload", () => {
			btn.removeEventListener("mouseenter", this);
			btn.removeEventListener("mousedown", this);
			popup.removeEventListener("command", this);
			if (popup.filler != this)
				popup.removeEventListener("dragstart", this),
				popup.removeEventListener("popuphidden", this);
		}, {once: true});
	},
	openMenu(arg) {
		var pos;
		if (this.matches(".widget-overflow-list > :scope"))
			pos = "after_start";
		else var win = this.ownerGlobal, {width, height, top, bottom, left, right} =
			this.closest("toolbar").getBoundingClientRect(), pos = width > height
				? `${win.innerHeight - bottom > top ? "after" : "before"}_start`
				: `${win.innerWidth - right > left ? "end" : "start"}_before`;
		this.firstChild.setAttribute("position", pos);
		delete this.openMenu;
		this.openMenu(arg);
	},
	mousedown(e) {
		if (e.button) return;
		var trg = e.target;
		if (trg.nodeName.startsWith("t"))
			trg.mdTimestamp = Cu.now(),
			trg.tid = e.view.setTimeout(this.onTimeout, 500),
			e.preventDefault();
	},
	mouseenter(e) { // обновить время сохранения сессии браузера
		e.view.document.getElementById(self.id).tooltipText = self.tooltiptext.replace(new RegExp(/ые .* ми/,''),'ые '+ Services.prefs.getIntPref('browser.sessionstore.interval',15e3)/60e3 + ' ми');
	},
	boot(trg) {
		var popup = trg.parentNode;
		var old = popup.querySelector("[boot]");
		if (old != trg) old?.removeAttribute("boot");
		trg.toggleAttribute("boot");
		popup.bootChanged = true;
	},
	muTimestamp: 0,
	click(e) {
		var trg = e.target;
		if (trg.nodeName == "menu") {
			if (e.button > 1) self.boot(trg);
			else if (Cu.now() - self.muTimestamp > 50)
				e.view.closeMenus(trg.menupopup),
				self.restoreSession(trg.label, (e.button || e.ctrlKey) && e.view);
		}
		else if (trg != this || e.button) return;
		e.view.clearTimeout(this.tid);
		if (this.mdTimestamp - this.phTimestamp > 50) this.open = true;
	},
	async command(e) {
		var arg, trg = e.target, cmd = trg.value;
		if (cmd.startsWith("r"))
			arg = trg.parentNode.parentNode.label;
		await this[cmd](arg) || this.save();
	},
	dragstart(e) {
		var trg = e.target;
		if (trg.nodeName != "menu") return;

		var popup = trg.parentNode;
		this.dragData = {trg, mouse: true};
		trg.menupopup.hidePopup();

		var win = trg.ownerGlobal;
		win.setCursor("grabbing");
		var {width} = trg.getBoundingClientRect();
		trg.setAttribute("maxwidth", width);

		win.addEventListener("mouseup", this);
		popup.addEventListener("mousemove", this);
	},
	mousemove(e) {
		var trg = e.target, dtrg = this.dragData.trg;
		if (trg == dtrg || trg.nodeName != "menu") return;

		e.movementY > 0
			? trg.nextSibling != dtrg && trg.after(dtrg)
			: trg.previousSibling != dtrg && trg.before(dtrg);
	},
	mouseup(arg) {
		if (arg.constructor.isInstance?.(arg)) {
			arg.preventDefault();
			var {trg} = this.dragData;
			this.dragData.mouse = false;
			this.muTimestamp = Cu.now();
		}
		else var trg = arg;

		trg.removeAttribute("maxwidth");
		trg.ownerGlobal.setCursor("auto");
		trg.ownerGlobal.removeEventListener("mouseup", this);
		trg.parentNode.removeEventListener("mousemove", this);
	},
	popuphidden(e) {
		if (!e.target.id) return;
		e.view.removeEventListener("keydown", this, true);
		var popup = e.target;
		popup.parentNode.phTimestamp = Cu.now();

		var save;
		if (this.dragData) {
			var {trg, mouse} = this.dragData;
			mouse && this.mouseup(trg);

			delete this.dragData;
			var order = Array.from(popup.getElementsByTagName("menu"), m => m.label);
			if (order.toString() != this.meta.order.toString()) {
				var hasBoot = this.meta.boot != null;
				if (hasBoot) var bootName = this.meta.order[this.meta.boot];
				this.meta.order = order;
				if (hasBoot) this.meta.boot = this.meta.order.indexOf(bootName);
				save = true;
			}
		}
		if (popup.bootChanged) {
			delete popup.bootChanged;
			var {boot} = this.meta;
			var bootNode = e.target.querySelector("[boot]");
			var ind = bootNode && this.meta.order.indexOf(bootNode.label);
			if (ind != boot)
				this.meta.boot = ind,
				save = true;
		}
		save && this.save(e.view);
	},

	sku: `#${pid} > menu[maxwidth]`,
	skd: `#${pid} > menu:is([maxwidth],[_moz-menuactive]):not([open])`,
	keydown(e) {
		if (e.repeat && e.key == "Shift" || !e.shiftKey && e.key != " ") return;
		var func = this.keyHandlers[e.key];
		if (!func) return;

		var menu = e.view.windowRoot
			.ownerGlobal.document.querySelector(this.skd);
		if (menu)
			e.stopImmediatePropagation(),
			func.call(this, menu, e);
	},
	keyup(e) {
		if (e.key != "Shift") return;
		var win = e.view.windowRoot.ownerGlobal;
		win.removeEventListener("keyup", this, true);
		win.document.querySelector(this.skd)?.removeAttribute("maxwidth");
	},
	keyHandlers: {
		Enter(menu) {
			this.boot(menu);
		},
		ArrowDown(menu) {
			var ns = menu.nextSibling;
			if (ns) ns.after(menu), this.arrow(menu);
		},
		ArrowUp(menu) {
			var ps = menu.previousSibling;
			if (ps.nodeName == "menu") ps.before(menu), this.arrow(menu);
		},
		" "(menu, e) {
			e.preventDefault();
			menu.ownerGlobal.closeMenus(menu.parentNode);
			this.restoreSession(menu.label, e.ctrlKey && menu.ownerGlobal);
		}
	},
	arrow(menu) {
		if (menu.hasAttribute("maxwidth")) return;
		menu.setAttribute("maxwidth", menu.getBoundingClientRect().width);
		menu.ownerGlobal.addEventListener("keyup", this, true);
		this.dragData = {trg: menu};
	},
	fill(e) {
		var mxe = e.view.MozXULElement;

		var initFrag = mxe.parseXULToFragment(`
			<menuitem value="saveSession" class="menuitem-iconic" label="Сохранить сессию"/>
			<menuitem value="deleteAllSessions" class="menuitem-iconic" label="Удалить все сессии"/>
			<menuseparator/>
		`);
		this.menuFrag = mxe.parseXULToFragment(`<menu class="menu-iconic"><menupopup>
			<menuitem label="Переименовать"
				class="menuitem-iconic" value="renameSession"/>
			<menuitem label="Удалить"
				class="menuitem-iconic" value="removeSession"/>
		</menupopup></menu>`);

		this.regStyle();

		var filler = {fill: e => e.target.id
			? e.view.addEventListener("keydown", this, true)
				|| e.target.fillFlag || this.fillSessions(e.target)
			: this.dragData?.mouse && e.preventDefault()
		};

		(this.fill = e => {
			var trg = e.target;
			trg.setAttribute("context", "");
			trg.append(trg.ownerDocument.importNode(initFrag, true));
			(trg.filler = filler).fill(e);
			trg.addEventListener("dragstart", this);
			trg.addEventListener("popuphidden", this);
		})(e);
	},
	fillSessions(popup) {
		while(popup.lastChild.nodeName == "menu") popup.lastChild.remove();
		var ind = 0, {boot} = this.meta;
		for(var name of this.meta.order) {
			var df = popup.ownerDocument.importNode(this.menuFrag, true);
			df.firstChild.setAttribute("label", name);
			if (ind++ == boot) df.firstChild.toggleAttribute("boot");
			popup.append(df);
		}
		popup.fillFlag = true;
	},
	regStyle() {
		delete this.regStyle;
		var subst = "ucf-ssm-style-resurl";
		Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler).setSubstitution(
			subst, Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent(`
			@-moz-document url-prefix(chrome://browser/content/browser.xhtml) {
				#${pid} > menu {
					list-style-image: url("${this.image}");
				}
				#${pid} > [value=saveSession] {
					list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKVSURBVHjajFNNTBNREJ6+7na73bLbQn8I0BKNCYWKGr0oYoiJPxeNh6oHozcOxgSVi4le1JNHQRPigRsewURNPKiJMQicSISUACelRVJ2tz/bdktpy9adBzT8xTjJ5L35ezNv5hsLHEAv7noEntguChx7EuV8oTydKRhfno8kCnt9LTuFZ7f87mAz/8rnl86GOoOBBq+LQX1S1ioLs0txWdEmsulS38Phlcy+BwZ6W0L+JsfolcjpsFDnBKNcgQ193bRUwSrwQFgr6Dkd3o9NzilqMdI/FF+sPYCZ245I4zdunw9DtQr6LxlK6bVdpdrcPAiHfGBYLDD69ltUXsmfw0oIGoPNjkHMjMHa3J9asDyRpoyEOrQR0+dq5MxR0c29Rj3Bhvn8YjeWjZmN9cpWcApSkzpkptYg8T1FdWjTfysg1Ang9YtdT+80OogTbJc7OlsD+OftzOqsBrMflqHe6QKXIEL00zLV0UpSBbM/G9DeEQy6OXKJsfPsCbdXYjb0Yu2/nmMS9LSGYGlYpXLPkxCwkq1mR98Gn8Q4XexxYhhgYKf3TPTfRDaPqklkvViaSSpaxSpw/x1v5e0UG8W10k+iW8qfF2ZiccIydFQ7ScsXKO8ep4NiYj4ai6k5+Eoev1F1Wcn8QJDgnAnHbGYRWTh800cZ77Ryzmr6eCGXzYGiZCcQ2vQ32XT5PiIMTJBI4Waw1ZtZzLu7XaSMd1s9b9paKJA+vpuKqols3y4ov7wXaPN67GPXIl1hnDOOansyVicHhGHMzHkzeDKqqPnr/UOJxX3LNNDb5BJd3KC3Uexu7wgEGxq3limRqcxH47FVWRtPreYePBpJagdu4zYhwjx1cMFus59CuVgqTmPDDlrnvwIMAGS8IFCLagHpAAAAAElFTkSuQmCC");
				}
				#${pid} [value=restoreSession] {
					list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAACzElEQVQ4jX2QPWwbZRjHf+/5vfPdObZjO3Ga2pVpGtxCP4QIDKgqDCDUNQwgJCS2qFI3hBCRCvXSCcTAAu0GY0Fi4kuq+IjUCpWAgCTq4IpS3Di2G8c+x/bZ57t7mSJFMfBf/3p+z+95BPvy3pufxqKmcVY3ZFFKmQtFGIReuNnrDze6lv5TqfSyx4EIgA/e+fzkZML6MDmVnD80mz1kxW3DMAxQCs/z6Hb6g3q1Xt1ttdfa7dbFN668vrkHkADJhPntufNnc0LTDi7AjFkkUknzcGF2LvCDuZVvfiwCj+/1GoAmhL3x6x2cZhsVqjFIGIZs15ts/LJOJCLt/Z0EiE3Y9eLpR1ONaoMH9zbHAGiC9FSKkwunWF1Z3RoDABhRg/zRPPmj+XHA/0QDaLectFLj6gcT+AHdTm9mzMC27e766lrWtCwy2Qz2hIUeNVDAaDCku9ujWW/ij3wsO9oaMzCiunf66TMU5gt4wyGbf1Upr5W5u15mq1JDhYqZQo6HIuqtueLw4vLXzwC89NZXeQFw/ePv7zx5buHEf6nf3qgMVipOGE0ko6EKhoQi3NnZ+c51BwsaQLOxM9N1uv86vNtz+aHSDn0pH9S2tl6r/Pn3s/VG/WYunzs/NZ2OSID0dKpRrzZS98v3kYbEsi1004BQcbtc9Q07bdYb229/dvmFL5aWVvVts9mq1Wo/e54vJIAQqGOPzQHgj3zcvos39BAIBshRqJQYjYZ/AFy79tQIeHVx+ctiIDRTA+g43Xud9q4PIHVJPBknk82QzqY5VZg2UUrEYhOX9s5aXL5RnMykb8Rj9kcC4OrSVZ1Hpt+PJ5PPz+SzR5KpyYRpGgRKMei7fHLr7lBmZ1XHcX4LgsCxLPt4JBLRm82Hr4j9DyuVSprdO/ZELGafkXpkXtPA94OK03Vv/R4/csEw5XOGbuieN6y6bv/S9XdfvPkPTgcoDlpQJpwAAAAASUVORK5CYII=");
				}
				#${pid} [value=renameSession] {
					list-style-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPFJREFUeNrEU0sOgkAMbc1IIHoQT+KeY7hkBW5ccwLdsOICxI2X8peIGhggI21gggpCwsImM01f+tpOO0WlFIwR0efgeR5nsG0boihizPd91A5UwZDjuq5qwycwUkQYhttSr4Y4l76fDdtBEAQqz3OVZdnPQ09o2sQhrpBSQgnAen/qzLxZzljHcawxy7KAuCJNUyiKAm53SS0FBGQNlUW3lFO2iVCLYRhAXJEkCQPn65NGAswpL/4fWAebt1ZGXB3geHlw9maXsKqjS94CHNxF7xRM0/wKgI7jDBojvbnZAz3Gv/9E7NvGvmXCsev8EmAAWocA9ofpaRIAAAAASUVORK5CYII=");
				}
				#${pid} :is([value=removeSession], [value=deleteAllSessions]) {
					list-style-image: url("resource://usercontext-content/cart.svg");
				}
				#${pid} > menuseparator:last-child,
				#${pid} > menu[maxwidth] > .menu-right,
				#${pid} > [value=deleteAllSessions]:nth-last-child(2) {
					display: none;
				}
				#${pid} > menu[boot] {
					color: red;
					font-weight: bold;
				}
				#${pid} > menu[maxwidth] {
					color: blue;
					font-weight: bold;
					outline-offset: -2px;
					outline: 2px solid orangered;
				}
			}
		`.replace(/;$/gm, " !important;"))));
		var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
		sss.loadAndRegisterSheet(Services.io.newURI("resource://" + subst), sss.USER_SHEET);
	},
	get gs() {
		delete this.gs;
		return this.gs = Cu.import("resource:///modules/sessionstore/SessionStore.jsm", {});
	},
	splice(name, newName) {
		var ind = this.meta.order.indexOf(name);
		if (ind == -1) return;
		var args = [ind, 1];

		if (1 in arguments) args.push(newName);
		else {
			if (ind == this.meta.boot) this.meta.boot = null;
			else if (ind < this.meta.boot) this.meta.boot--;
		}
		this.meta.order.splice(...args);
	},
	get meta() {
		var file = Services.dirsvc.get("UChrm", Ci.nsIFile);
		file.append("simple_session_manager.json");
		this.path = file.path;
		try {
			this.data = JSON.parse(Cu.readUTF8File(file));
		} catch {
			this.pp = file.parent.path;
			this.data = Object.create(null);
		}
		var meta = this.data[mp];
		if (!meta) {
			var order = Object.keys(this.data);
			meta = this.data[mp] = {order, boot: null};
		}
		delete this.meta;
		return this.meta = meta;
	},
	async save(excWin) {
		var io = Cu.getGlobalForObject(Cu).IOUtils;
		if (this.pp)
			await io.makeDirectory(this.pp), delete this.pp;
		(this.save = excWin => {
			this.meta.order.length
				? io.writeJSON(this.path, this.data)
				: io.remove(this.path, {ignoreAbsent: true});
			for(var win of CustomizableUI.windows) {
				if (win == excWin) continue;
				var popup = win.document.getElementById(pid);
				if (popup) popup.fillFlag = false;
			}
		})(excWin);
	},
	get prompter() {
		var {prompt} = Services;
		var p = {}, args = [null, null, "UCF Simple Session Manager"];
		p.alert = prompt.alert.bind(...args);
		p.confirm = prompt.confirm.bind(...args);
		var pr = prompt.prompt.bind(...args);
		p.prompt = (msg, value) => {
			var res = {value};
			return pr(msg, res, null, {}) ? res.value : null;
		}
		delete this.prompter;
		return this.prompter = p;
	},
	observe(s, t, data) {
		Services.obs.removeObserver(this, "quit-application");
		if (data.includes("restart")) return;

		var {boot} = this.meta;
		if (boot == null) return;

		var state = this.data[this.meta.order[boot]];
		var ssi = this.gs.SessionStoreInternal;
		ssi.getCurrentState = () => state;
		Services.obs.removeObserver(ssi, "browser:purge-session-history");

		Services.prefs.setBoolPref("browser.sessionstore.resume_session_once", true);
	},
	get bwt() {
		delete this.bwt;
		var url = "resource:///modules/BrowserWindowTracker.jsm";
		return this.bwt = ChromeUtils.import(url).BrowserWindowTracker;
	},
	getName(state) {
		var wl = state.windows.length, tl = 0;
		for(var w of state.windows) tl += w.tabs.length;
		return `${
			this.bwt.getTopWindow().gBrowser.selectedTab.label.slice(0, 70)
		} ${wl}/${tl} [${
			new Date().toLocaleString("mn").replace(" ", "-")
		}]`;
	},
	exists(name) {
		this.meta;
		return (this.exists = name => name in this.data &&
			!this.prompter.alert("Сессия с тем же именем уже существует!"))(name);
	},
	getState() {
		return JSON.parse(this.gs.SessionStore.getBrowserState());
	},
	get spref() {
		var pref = "browser.sessionstore.interval";
		var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
		var wait = cb => timer.initWithCallback(cb, 1e3, timer.TYPE_ONE_SHOT);
		delete this.spref;
		return this.spref = async cb => {
			var val = Services.prefs.getIntPref(pref);
			Services.prefs.setIntPref(pref, 100);
			await new Promise(wait);
			Services.prefs.setIntPref(pref, val);
		}
	},
	async saveSession(name = this.getName(this.getState())) {
		var name = this.prompter.prompt("Сохранить:", name);
		if (name == null) return true;

		if (this.exists(name)) return this.saveSession(name);

		await this.spref();
		this.data[name] = this.getState();

		this.meta.order.push(name);
		//this.meta.order.unshift(name);
		//if (this.meta.boot != null) this.meta.boot++;
	},
	restoreSession(name, win) {
		var ss = this.gs.SessionStore;
		var state = JSON.stringify(this.data[name]);
		win ? ss.setWindowState(win, state) : ss.setBrowserState(state);
	},
	renameSession(name, newName = name) {
		var newName = this.prompter.prompt(`Переименовать "${name}" в:`, newName);
		if (newName == null || newName == name) return true;

		if (this.exists(newName)) return this.renameSession(name, newName);

		var {data} = this;
		this.splice(name, newName);
		data[newName] = data[name];
		delete data[name];
	},
	removeSession(name) {
		if (!this.prompter.confirm(`Вы уверены, что хотите удалить ${name} ?`))
			return true;
		delete this.data[name];
		this.splice(name);
	},
	deleteAllSessions() {
		if (!this.prompter.confirm(`Вы уверены, что хотите удалить все сессии?`))
			return true;
		delete this.dragData;
		delete this.bwt.getTopWindow().document.getElementById(pid).bootChanged;
		this.meta = (this.data = Object.create(null))[mp] = {order: [], boot: null};
	}
}).init()))("ucf-ssm-menupopup", "{07cae4f5-18b0-487b-80eb-973304af9528}");

Предыстория создания темы для UCF-скриптов

Vitaliy V. пишет

можно добавить в репозиторий скрипты, а смысл, всё равно если что отвалится все пишут на форум, а мне следить за тем чем не пользуюсь ?!

Найти UCF-скрипты на forum.mozilla… – очень сложный квест! Скрипты для User Chrome Files обсуждаются сразу в двух темах.
Вероятно, многие вопросы по скриптам/стилям уже встречались десятки раз на 400/600 страницах тем userChrome.css и Custom Buttons! Значительно удобнее для всех держать актуальные UCF-скрипты в папке «родного» проекта user_chrome_files и давать постоянные ссылки вида: https://github.com/VitaliyVstyle/VitaliyVstyle.github.io/raw/master/stylesff/user_chrome_files/README.md
Ведь Infocatcher хранит все CB-скрипты на гитхабе, тот же подход используется для скриптов LUA-расширений Double Commander…


Это будет полезно для всех - хранить UCF-скрипты в папке «родного» проекта. Допустим, кто-то сделал UCF-скрипт. Через месяц другой захочет улучшить этот же код, но как он найдёт свежую версию? Проще в гитхаб добавить/обсудить commit, чем искать здесь этот скрипт и другие наработки среди тысячи страниц, а сколько на форуме разбросано ещё полезных наработок, я просто не знаю!!!

del

Vitaliy V.

Удаляйте все загрузчики скриптов из custom_script_all_win.js
добавляйте этот

У меня там только

стандартный загрузчик

Выделить код

Код:

load() {
        if (this.initialized)
            return;
        this.initialized = true;
        /* ************************************************ */

        // Здесь может быть ваш код который сработает по событию "load" не раньше

        /* ************************************************ */
    },


Его нужно заменить на тот, что по ссылке?

harryk
Загрузчики можно добавить где комментарий // Здесь может быть ваш код который сработает по событию "load" не раньше
но добавлять необязательно это для тех кто хочет чтобы были отдельные файлы.
Что касается custom_script_all_win.js у вас же там ничего нет значит и добавлять ничего не надо

Т.е. тот загрузчик нужно вставить вместо или рядом с комментарием?

Да


to all
Добавляйте здесь ссылки на скрипты или сами скрипты кто чем пользуется...

Vitaliy V.
Да, у меня там ничего нет. Пока нет, но я над этим работаю :)
Т.е. тот загрузчик нужно вставить вместо или рядом с комментарием?

Vitaliy V.
Огромное Спасибо за обновлённые загрузчики, скрипты и кнопки.
Еще добавлю здесь ссылку на дропмакер в адресной строке urlbarhistorydropmarker.
В 91+ тоже работает исправно, только иконка там поменялась на arrow-down.svg, сменил у себя в [nightly].
Ещё добавлю переработанные по Вашим советам скрипты классического окна загрузок для custom_script_all_win.js и русифицированные к тому же

ucjsDownloadsManager.uc.js

Выделить код

Код:

if (location.href == "chrome://browser/content/browser.xhtml") {
  Cu.import("resource://gre/modules/Services.jsm");

  window.ucjs_downloadManager = {
    _summary: null,
    _list: null,

    createElement: function(localName, arryAttribute) {
      let elm = document.createXULElement(localName);
      for(let i = 0; i < arryAttribute.length; i++) {
        elm.setAttribute(arryAttribute[i].attr, arryAttribute[i].value);
      }
      return elm;
    },

    init: function() {
      window.addEventListener("unload", this, false);

      let ref = document.getElementById("menu_openDownloads");
      let menu = ref.parentNode.insertBefore(
        this.createElement("menuitem",
          [{attr: "label", value:"Менеджер загрузок"},

           {attr : "oncommand", value: "ucjs_downloadManager.openDownloadManager(true);"}
          ]), ref);

      XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
                "resource://gre/modules/Downloads.jsm");
      // Ensure that the DownloadSummary object will be created asynchronously.
      if (!this._summary) {
        this.Downloads.getSummary(this.Downloads.ALL).then(summary => {
          this._summary = summary;
          return this._summary.addView(this);
        }).then(null, Cu.reportError);
      }

      if (!this._list) {
        this.Downloads.getList(this.Downloads.ALL).then(list => {
          this._list = list;
          return this._list.addView(this);
        }).then(null, Cu.reportError);
      }
    },

    uninit: function() {
      window.removeEventListener("unload", this, false);

      if (this._summary) {
        this._summary.removeView(this);
      }
      if (this._list) {
        this._list.removeView(this);
      }
    },

    handleEvent: function(event) {
      switch (event.type) {
        case "unload":
          this.uninit();
          break;
      }
    },

    openDownloadManager: function ucjs_openDownloadManager(aForceFocus) {
      var enumerator = Services.wm.getEnumerator(null);
      while(enumerator.hasMoreElements()) {
        var win = enumerator.getNext();
        if (win.location == "chrome://browser/content/downloads/contentAreaDownloadsView.xhtml"
          && PrivateBrowsingUtils.isWindowPrivate(window) ==
             PrivateBrowsingUtils.isWindowPrivate(win)) {
          if (aForceFocus)
            win.focus();
          return;
        }
      }

      try {
        var height = Math.max(100,Services.prefs.getIntPref("browser.download.manager.size.height"));
        var width  = Math.max(300,Services.prefs.getIntPref("browser.download.manager.size.width"));
        var screenX = Math.min(Math.max(0,Services.prefs.getIntPref("browser.download.manager.size.screenX")), screen.availWidth - width);
        var screenY = Math.min(Math.max(0,Services.prefs.getIntPref("browser.download.manager.size.screenY")), screen.availHeight - height);
      } catch(r){
        height = 300;
        width  = 480;
        screenX = 5;
        screenY = 5;
      }
      var win = window.open("chrome://browser/content/downloads/contentAreaDownloadsView.xhtml",
                            "Download" +
                              (PrivateBrowsingUtils.isWindowPrivate(window) ? " - Private Window"
                                                                            : ""),
                            "outerWidth=" + width + ",outerHeight=" + height +
                            ",left=" + screenX + ",top=" + screenY +
                            ",chrome,toolbar=yes,dialog=no,resizable");
    },

    closeDownloadManager: function ucjs_closeDownloadManager() {
      var enumerator = Services.wm.getEnumerator(null);
      while(enumerator.hasMoreElements()) {
        var win = enumerator.getNext();
        if (win.location == "chrome://browser/content/downloads/contentAreaDownloadsView.xhtml") {
          win.close();
          return;
        }
      }
    },

    onDownloadAdded: function (aDownload) {
      var showWhenStarting = true;
      try {
        showWhenStarting = Services.prefs.getBoolPref("browser.download.manager.showWhenStarting");
      } catch(e) {}
      var numDls = 0;
      if (showWhenStarting) {
        if (this._list) {
          this._list.getAll().then(downloads => {
            for (let download of downloads) {
              if (!download.stopped)
                numDls++;
            }
            if (numDls > 0)
              this.openDownloadManager(false);
          }).then(null, Cu.reportError);
        }
      }
    },

    onDownloadChanged: function (aDownload) {
      if (!this._list)
        return;
      this._list.getAll().then(downloads => {
        var num = 0;
        for (let download of downloads) {
          if (!download.succeeded)
            num++;
        }
        if (num == 0) {
          var closeWhenDone = true;
          try {
            closeWhenDone = Services.prefs.getBoolPref("browser.download.manager.closeWhenDone");
          } catch(e) {}
          if (closeWhenDone) {
            this.closeDownloadManager();
          }
        }
      }).then(null, Cu.reportError);
    }
  };
  ucjs_downloadManager.init();
}

ucjsDownloadsManager2.uc.js

Выделить код

Код:

Cu.import("resource://gre/modules/Services.jsm");
  Cu.import("resource://gre/modules/DownloadIntegration.jsm");

  window.ucjs_downloadManagerMain = {
    originalTitle:"",
    _summary: null,
    _list: null,
    _wait:false,

    createElement: function(localName, arryAttribute) {
      let elm = document.createXULElement(localName);
      for(let i = 0; i < arryAttribute.length; i++) {
        elm.setAttribute(arryAttribute[i].attr, arryAttribute[i].value);
      }
      return elm;
    },

    createElementNS: function(NS, localName, arryAttribute) {
      let elm = document.createElementNS(NS, localName);
      for(let i = 0; i < arryAttribute.length; i++) {
        elm.setAttribute(arryAttribute[i].attr, arryAttribute[i].value);
      }
      return elm;
    },

    init: function() {
      window.addEventListener("unload", this, false);

      // xxx remove in-content css
      var elements = document.childNodes;
      for (var i = 0; i <= elements.length; i++) {
        var element = elements[i];
        if (element.nodeValue.indexOf("chrome://browser/skin/downloads/contentAreaDownloadsView.css") > -1) {
          document.removeChild(element);
          break;
        }
      }

      document.getElementById("downloadsListEmptyDescription").setAttribute("flex", "1");
      let ref = document.documentElement;
      ref = ref.appendChild(this.createElement("hbox", []));
      ref.appendChild(this.createElement("button",
        [{attr: "id", value: "ucjs_clearListButton"},
         {attr: "label", value: "Очистить загрузки"},

        ]));
      ref.appendChild(this.createElement("spacer",
        [{attr: "flex", value: "1"}]));
      ref.appendChild(this.createElementNS("http://www.w3.org/1999/xhtml", "input",
        [{attr: "id", value: "ucjs_downloadManagerMain_input"},
         {attr: "clickSelectsAll", value: "true"},
         {attr: "type", value: "search"},
         {attr: "placeholder", value: "Поиск в загрузках"},
         {attr: "aria-autocomplete", value: "list"}
        ]));

        document.getElementById("ucjs_clearListButton").addEventListener("command", function(event) {
            ucjs_downloadManagerMain.clearDownloads();
          });
        document.getElementById("ucjs_downloadManagerMain_input")
                .addEventListener("input", function(event) {
            ucjs_downloadManagerMain.doSearch(event.target.value);
          });

      this.originalTitle = document.title +
                           (PrivateBrowsingUtils.isWindowPrivate(window) ? " - Private Window"
                                                                         : "");

/*
      // xxx Bug 1279329 "Copy Download Link" of context menu in Library is grayed out
      var listBox = document.getElementById("downloadsRichListBox");
      var placesView = listBox._placesView;
      var place = placesView.place;
      placesView.place= null;
      placesView.place = place;
*/

      setTimeout(function(){this._wait = true}.bind(this), 0);

      // Ensure that the DownloadSummary object will be created asynchronously.
      if (!this._summary) {
        Downloads.getSummary(Downloads.ALL).then(summary => {
          this._summary = summary;
          return this._summary.addView(this);
        }).then(null, Cu.reportError);
      }

      if (!this._list) {
        Downloads.getList(Downloads.ALL).then(list => {
          this._list = list;
          return this._list.addView(this);
        }).then(null, Cu.reportError);
      }

      try {
        var showProgressInTaskButton = Services.prefs.getBoolPref("browser.download.manager.showProgressInTaskButton")
      } catch(ex) {
        showProgressInTaskButton = true; //default
      }
      if (showProgressInTaskButton)
        setTimeout(function() {
          try {
            let docShell = window.QueryInterface(Ci.nsIInterfaceRequestor)
                                  .getInterface(Ci.nsIWebNavigation)
                                  .QueryInterface(Ci.nsIDocShellTreeItem).treeOwner
                                  .QueryInterface(Ci.nsIInterfaceRequestor)
                                  .getInterface(Ci.nsIXULWindow).docShell;
            let gWinTaskbar = Components.classes["@mozilla.org/windows-taskbar;1"]
                                      .getService(Components.interfaces.nsIWinTaskbar);
            this._taskbarProgress = gWinTaskbar.getTaskbarProgress(docShell);
          } catch(ex) {
            this._taskbarProgress = null;
          }
        }.bind(this), 10);
    },

    uninit: function() {
      window.removeEventListener("unload", this, false);

      this._taskbarProgress = null;
      if (this._wait)
        this.saveSizePosition();

      if (this._summary) {
        this._summary.removeView(this);
      }
      if (this._list) {
        this._list.removeView(this);
      }
    },

    handleEvent: function(event) {
      switch (event.type) {
        case "unload":
          this.uninit();
          break;
      }
    },

    saveSizePosition: function() {
      if (window.windowState == 3) {
        Services.prefs.setIntPref("browser.download.manager.size.height", window.outerHeight);
        Services.prefs.setIntPref("browser.download.manager.size.width", window.outerWidth);
        Services.prefs.setIntPref("browser.download.manager.size.screenX", window.screenX);
        Services.prefs.setIntPref("browser.download.manager.size.screenY", window.screenY);
      }
    },

    onSummaryChanged: function () {
      if (!this._summary)
        return;
      if (this._summary.allHaveStopped || this._summary.progressTotalBytes == 0) {
        document.title = this.originalTitle;
        if (this._taskbarProgress) {
          this._taskbarProgress.setProgressState(
                                     Ci.nsITaskbarProgress.STATE_NO_PROGRESS, 0, 0);
        }
        Cu.import("resource://gre/modules/Services.jsm");
        var enumerator = Services.wm.getEnumerator("navigator:browser");
        while(enumerator.hasMoreElements()) {
          return;
        }

        var closeWhenDone = true;
        try {
          closeWhenDone = Services.prefs.getBoolPref("browser.download.manager.closeWhenDone");
        } catch(e) {}
        if (closeWhenDone) {
          DownloadIntegration._store.save();
          window.close();
        }

      } else {

        // If the last browser window has been closed, we have no indicator any more.
        if (this._taskbarProgress) {
          if (this._summary.allHaveStopped || this._summary.progressTotalBytes == 0) {
            this._taskbarProgress.setProgressState(
                                     Ci.nsITaskbarProgress.STATE_NO_PROGRESS, 0, 0);
          } else {
            // For a brief moment before completion, some download components may
            // report more transferred bytes than the total number of bytes.  Thus,
            // ensure that we never break the expectations of the progress indicator.
            let progressCurrentBytes = Math.min(this._summary.progressTotalBytes,
                                                this._summary.progressCurrentBytes);
            this._taskbarProgress.setProgressState(
                                     Ci.nsITaskbarProgress.STATE_NORMAL,
                                     progressCurrentBytes,
                                     this._summary.progressTotalBytes);
          }
        }

        // Update window title
        var numDls = 0;
        if (!this._list)
          return;
        this._list.getAll().then(downloads => {
          for (let download of downloads) {
            if (download.hasProgress && !download.succeeded)
              numDls++;
          }

          let progressCurrentBytes = Math.min(this._summary.progressTotalBytes,
                                            this._summary.progressCurrentBytes);
          let percent = Math.floor(progressCurrentBytes / this._summary.progressTotalBytes * 100);
          let text = percent + "% из " + numDls + (numDls < 2 ? " файла - " : " файлов - ") ;
          document.title = text + this.originalTitle;
        }).then(null, Cu.reportError);
      }
    },

    clearDownloads: function ucjs_clearDownloads() {
      var DO_NOT_DELETE_HISTORY = true; /* custmizable true or false */
      var richListBox = document.getElementById("downloadsRichListBox");

      var places = [];
      function addPlace(aURI, aTitle, aVisitDate) {
        places.push({
          uri: aURI,
          title: aTitle,
          visits: [{
            visitDate: (aVisitDate || Date.now()) * 1000,
            transitionType: Ci.nsINavHistoryService.TRANSITION_LINK
          }]
        });
      }
      function moveDownloads2History(d) {
        if (DO_NOT_DELETE_HISTORY &&
            !PrivateBrowsingUtils.isWindowPrivate(window)) {
          for (let element of richListBox.childNodes) {
            let download = element._shell.download;
            let aURI = makeURI(download.source.url);
            // let aTitle = document.getAnonymousElementByAttribute(element, "class", "downloadTarget").value
            let aTitle = download.target.path;
            aTitle = aTitle.match( /[^\\]+$/i )[0];
            aTitle = aTitle.match( /[^/]+$/i )[0];

            let aVisitDate = download.endTime || download.startTime;
            addPlace(aURI, aTitle, aVisitDate)
          }
        }

        // Clear List
        richListBox._placesView.doCommand('downloadsCmd_clearDownloads');

        if (DO_NOT_DELETE_HISTORY &&
            !PrivateBrowsingUtils.isWindowPrivate(window)) {
          if (places.length > 0) {
            var asyncHistory = Components.classes["@mozilla.org/browser/history;1"]
                     .getService(Components.interfaces.mozIAsyncHistory);
              asyncHistory.updatePlaces(places);
          }
        }
      }
      var btn = document.getElementById("ucjs_clearListButton");
      moveDownloads2History(0);
    },

    doSearch: function ucjs_doSearch(filterString) {
      var richListBox = document.getElementById("downloadsRichListBox");
      richListBox._placesView.searchTerm = filterString;
    }
  };
  ucjs_downloadManagerMain.init();

Added: Скрипт со стилием и иконками для добавления кнопки паузы в окна загрузок.
Небольшие косметические улучшения
Image_001.png

Выделить код

Код:

@-moz-document url(chrome://browser/content/downloads/contentAreaDownloadsView.xhtml) {
#downloadsListEmptyDescription {
    margin: 0 !important;
    padding: 1px 0 0 6px !important;
    background-color: white !important;
}
#contentAreaDownloadsView > hbox {
    background-color: -moz-Dialog !important;
    padding-top: 2px !important;
    border: 1px solid gainsboro !important;	
}
#ucjs_clearListButton {
    margin: 1px 2px 2px !important;
}
}

Скрипты авторства Dumby, которые использую:
Переключение вкладок наведением указателя на вкладку, и там же, как бы костыль, добавления закладки звёздочкой в адресной строке в меню закладок, а через меню на странице - в "Другие закладки" https://forum.mozilla-russia.org/viewto … 27#p786627
Действие двойного клика на панели вкладок - открыть новую вкладку вместо развернуть окно https://forum.mozilla-russia.org/viewto … 49#p782149
Кнопка "Закрыть другие вкладки" https://forum.mozilla-russia.org/viewto … 81#p788681
Скрипт возврата в адресную строку значка "Копировать ссылку" https://forum.mozilla-russia.org/viewto … 96#p790496
Скрипт возврата пункта "Информация о странице" https://forum.mozilla-russia.org/viewto … 92#p792092
Другой вариант возврата пункта "Информация о странице" с открытием вкладки "Разрешения", код в самом низу поста https://forum.mozilla-russia.org/viewto … 04#p792104
Ещё кнопка авторства Vitaliy V. вкл/откл звука на вкладке/вкладках https://forum.mozilla-russia.org/viewto … 10#p787710, тоже сильно выручает.
Через файл user_chrome.manifest комплекта user_chrome_files можно легко поменять значки интерфейса и так же на служебных страницах, что я и сделал в 89+, использовав значки из [firefox] 78 и свои кое-где

user_chrome.manifest firefox 90
Image_001.png

Выделить код

Код:

content user_chrome_files ./
# Не уверены, не редактируйте этот файл!

override chrome://global/skin/icons/defaultFavicon.svg chrome://user_chrome_files/content/custom_styles/svg/defaultFavicon.svg

override chrome://branding/content/identity-icons-brand.svg chrome://user_chrome_files/content/custom_styles/svg/defaultFavicon.svg

override chrome://mozapps/skin/extensions/extension.svg chrome://user_chrome_files/content/custom_styles/svg/extension.svg

override chrome://global/skin/icons/settings.svg chrome://user_chrome_files/content/custom_styles/svg/settings.svg

override chrome://mozapps/skin/extensions/extensionGeneric.svg chrome://user_chrome_files/content/custom_styles/svg/extension.svg

override chrome://global/skin/icons/help.svg chrome://user_chrome_files/content/custom_styles/svg/help.svg

override chrome://global/skin/icons/plugin.svg chrome://user_chrome_files/content/custom_styles/svg/pluginGeneric.svg

override chrome://mozapps/skin/extensions/category-discover.svg chrome://user_chrome_files/content/custom_styles/svg/category-discover.svg

override chrome://mozapps/skin/extensions/category-extensions.svg chrome://user_chrome_files/content/custom_styles/svg/category-extensions.svg

override chrome://mozapps/skin/extensions/category-themes.svg chrome://user_chrome_files/content/custom_styles/svg/category-themes.svg

override chrome://mozapps/skin/extensions/category-plugins.svg chrome://user_chrome_files/content/custom_styles/svg/category-plugins.svg

override chrome://browser/skin/preferences/category-general.svg chrome://user_chrome_files/content/custom_styles/svg/settings.svg

override chrome://browser/skin/home.svg chrome://user_chrome_files/content/custom_styles/svg/home.svg

override chrome://browser/skin/preferences/category-search.svg chrome://user_chrome_files/content/custom_styles/svg/category-search.svg

override chrome://browser/skin/preferences/category-privacy-security.svg chrome://user_chrome_files/content/custom_styles/svg/category-privacy-security.svg

override chrome://browser/skin/preferences/category-experiments.svg chrome://user_chrome_files/content/custom_styles/svg/category-experiments.svg

override chrome://global/skin/icons/more.svg chrome://user_chrome_files/content/custom_styles/svg/more.svg

override chrome://global/skin/icons/folder.svg chrome://user_chrome_files/content/custom_styles/svg/folder.svg

override chrome://browser/skin/places/folder.svg chrome://user_chrome_files/content/custom_styles/svg/folder.svg

override chrome://global/skin/icons/arrow-dropdown-16.svg chrome://user_chrome_files/content/custom_styles/svg/arrow-dropdown-16.svg

override chrome://browser/skin/history.svg chrome://user_chrome_files/content/custom_styles/svg/history.svg

override chrome://global/skin/icons/chevron.svg chrome://user_chrome_files/content/custom_styles/svg/chevron.svg

override chrome://browser/skin/menu.svg chrome://user_chrome_files/content/custom_styles/svg/menu.svg

override chrome://global/skin/icons/page-portrait.svg chrome://global/skin/icons/info.svg

override chrome://branding/content/icon16.png chrome://branding/content/identity-icons-brand.svg

override chrome://browser/skin/controlcenter/tracking-protection.svg chrome://user_chrome_files/content/custom_styles/svg/tracking-protection.svg

Частично менял стилем там, где не нужно все скопом менять или другие причины
скрытый текст

Выделить код

Код:

/* иконка щита "трекеры не обнаружены" */
#urlbar-input-container[pageproxystate="valid"] > #tracking-protection-icon-container > #tracking-protection-icon-box > #tracking-protection-icon {
	list-style-image: url(./svg/tracking-protection.svg) !important;
	fill-opacity: 0.6 !important;
}
/* иконка щита "блокируются трекеры" */
#urlbar-input-container[pageproxystate="valid"] > #tracking-protection-icon-container > #tracking-protection-icon-box:not([hasException])[active] > #tracking-protection-icon {
	display: block !important;
	background-image: url(./svg/tracking-protection-active.svg) !important;
	transform: translateX(-256px) !important;
	width: 272px !important;
	background-size: auto !important;
	height: 16px !important;
	min-height: 16px !important;
	-moz-context-properties: fill, fill-opacity !important;
}
/* зелёный замок */
#identity-box[pageproxystate="valid"].verifiedDomain #identity-icon, #identity-box[pageproxystate="valid"].mixedActiveBlocked #identity-icon {
	list-style-image:  url(./svg/security.svg) !important;
        fill: #12BC00 !important;
}
/* зелёный замок в "информация о сайте" */
#identity-popup[connection^="secure"] .identity-popup-security-connection {
	background-image:  url(./svg/security.svg) !important;
        fill: #12BC00 !important;
}
/* чёрный замок смешанного содержимого */
#identity-box[pageproxystate="valid"].weakCipher #identity-icon, #identity-box[pageproxystate="valid"].mixedDisplayContent #identity-icon, #identity-box[pageproxystate="valid"].mixedDisplayContentLoadedActiveBlocked #identity-icon, #identity-box[pageproxystate="valid"].certUserOverridden #identity-icon, #identity-box[pageproxystate="valid"].certErrorPage #identity-icon {
	list-style-image: url(./svg/security-warning.svg) !important;
	fill-opacity: 0.6 !important;
}
/* чёрный замок смешанного содержимого в "информация о сайте" */
#identity-popup[ciphers="weak"] .identity-popup-security-connection, #identity-popup[mixedcontent~="passive-loaded"][isbroken] .identity-popup-security-connection {
	background-image: url(./svg/security-warning.svg) !important;
}
/* зачёркнутый замок незащещённого содержимого */
#identity-box[pageproxystate="valid"].notSecure #identity-icon, #identity-box[pageproxystate="valid"].mixedActiveContent #identity-icon, #identity-box[pageproxystate="valid"].httpsOnlyErrorPage #identity-icon {
	list-style-image: url(./svg/security-broken.svg) !important;
	fill-opacity: 0.6 !important;
}
/* зачёркнутый замок незащещённого содержимого в "информация о сайте" */
.identity-popup-security-connection {
	background-image: url(./svg/security-broken.svg) !important;
}
/* значок дополнительных разрешений */
#permissions-granted-icon {
	list-style-image: url(./svg/permissions.svg) !important;
	fill-opacity: 0.6 !important;
}
/* значок запрета автовоспроизведения */
.autoplay-media-icon.blocked-permission-icon {
	list-style-image: url(./svg/autoplay-media-blocked.svg) !important;
	fill-opacity: 0.6 !important;
}
/* значок разрешённого автовоспроизведения */
.autoplay-media-icon {
	list-style-image: url(./svg/autoplay-media.svg) !important;
	fill-opacity: 0.6 !important;
}
/* кнопка "назад" */
#back-button {
	list-style-image: url("./svg/back.svg") !important;
}
/* кнопка "вперёд" */
#forward-button {
	list-style-image: url("./svg/forward.svg") !important;
}
/* значок "v" "показать историю" */
#urlbar .urlbar-history-dropmarker {
	/* list-style-image: url(./svg/arrow-dropdown-16.svg) !important; */
	fill-opacity: 0.6 !important;
}
/* звёздочка в адресной строке */
#pageAction-panel-bookmark, #star-button {
	list-style-image: url("./svg/bookmark-hollow.svg") !important;
	fill-opacity: 0.6 !important;
}
#pageAction-panel-bookmark[starred], #star-button[starred] {
	list-style-image: url("./svg/bookmark.svg") !important;
	fill-opacity: 1 !important;
}
/* прозрачность значка "копироать ссылку" */
#pageAction-urlbar-ucf-copyURL .urlbar-icon {
	fill-opacity: .6 !important;
}

Папка со значками.

Скрипты для custom_script.js:
URL tooltip: https://forum.mozilla-russia.org/viewto … 55#p783755;
Proxy: https://forum.mozilla-russia.org/viewto … 94#p782794;


Скрипты для custom_script_win.js:
Скрыть ненужные папки в боковой панели: https://forum.mozilla-russia.org/viewto … 25#p777225;
AutoPopup: https://forum.mozilla-russia.org/viewto … 64#p789264
Скрипты: search_image_contextmenu ... https://forum.mozilla-russia.org/viewto … 29#p788229

UndoBookmarksContextMenu - пункты контекстного меню закладок "вернуть\повторить удаление" (закладки)
Для custom_script_win.js или custom_script_all_win.js, в зависимости где должно работать -
панель закладок, сайдбар, библиотека в окне или библиотека во вкладке.
Строка загрузки - loadscript("subfolder/script_file_name.uc.js", win); или loadscript("script_file_name.uc.js", win);

скрытый текст
// ==UserScript==
// @name          s_UndoBookmarksContextMenu
// @namespace     http://space.geocities.yahoo.co.jp/gl/alice0775
// @include       *
// @compatibility Firefox 60
// @author        alice0775
// @version       2019/11/20 23:00 fix redeclaration error
// @version       2019/07/10 10:00 fix 70 Bug 1558914 - Disable Array generics in Nightly
// @version       2018/10/04 20:00 remove conflict shortcuts key for main window
// @version       2018/10/04 60+
// ==/UserScript==
if (typeof window.undobookmarksmenu == "undefined") {
  window.undobookmarksmenu = {
    popup: null,

    handleEvent: function(event) {
      switch (event.type) {
        case 'unload':
          this.uninit();
          break;
        case 'popupshown':
          this.popupshown(event);
          break;
      }
    },

    init: function() {
      window.addEventListener('unload', this, false);
      this.popup = document.getElementById("placesContext");
      if (!this.popup)
        return;
      this.popup.addEventListener('popupshown', this, false);
      let template = (location.href == "chrome://browser/content/browser.xul")  ?
                [
                  ["menuitem", {id: "undobookmarksmenuUndo",
                                disabled: "true",
                                label: "Вернуть удаленное",
                                key: "key_undo",
                                oncommand: "PlacesTransactions.undo().catch(Cu.reportError);",
                                selection: "any"
                  }],
                  ["menuitem", {id:"undobookmarksmenuRedo",
                                disabled: "true",
                                label: "Повторить удаление",
                                key: "key_redo",
                                oncommand: "PlacesTransactions.redo().catch(Cu.reportError);",
                                selection: "any"
                  }]
                ] : [
                  ["menuitem", {id: "undobookmarksmenuUndo",
                                disabled: "true",
                                label: "Вернуть удаленное",
                                key: "key_undo",
                                oncommand: "PlacesTransactions.undo().catch(Cu.reportError);",
                                acceltext: "Ctrl+Z",
                                selection: "any"
                  }],
                  ["menuitem", {id:"undobookmarksmenuRedo",
                                disabled: "true",
                                label: "Повторить удаление",
                                key: "key_redo",
                                oncommand: "PlacesTransactions.redo().catch(Cu.reportError);",
                                acceltext: "Ctrl+Y",
                                selection: "any"
                  }]
                ];

      let ref = document.getElementById("placesContext_deleteSeparator");
      ref.parentNode.insertBefore(this.jsonToDOM(template, document, {}), ref);
    },

    uninit: function() {
      window.removeEventListener('unload', this, false);
      if (!this.popup)
        return;
      this.popup.removeEventListener('popupshown', this, false);
    },

    popupshown: function(event){
      var menuitem = document.getElementById("undobookmarksmenuUndo");
      if (menuitem)
        menuitem.setAttribute('disabled', PlacesTransactions.topUndoEntry == null);
      menuitem = document.getElementById("undobookmarksmenuRedo");
      if (menuitem)
        menuitem.setAttribute('disabled', PlacesTransactions.topRedoEntry == null);
    },

    jsonToDOM: function(jsonTemplate, doc, nodes) {
      jsonToDOM.namespaces = {
      html: "http://www.w3.org/1999/xhtml",
      xul: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
      };
      jsonToDOM.defaultNamespace = jsonToDOM.namespaces.xul;
      function jsonToDOM(jsonTemplate, doc, nodes) {
        function namespace(name) {
            var reElemNameParts = /^(?:(.*):)?(.*)$/.exec(name);
            return { namespace: jsonToDOM.namespaces[reElemNameParts[1]], shortName: reElemNameParts[2] };
        }

        // Note that 'elemNameOrArray' is: either the full element name (eg. [html:]div) or an array of elements in JSON notation
        function tag(elemNameOrArray, elemAttr) {
          // Array of elements?  Parse each one...
          if (Array.isArray(elemNameOrArray)) {
            var frag = doc.createDocumentFragment();
            Array.prototype.forEach.call(arguments, function(thisElem) {
              frag.appendChild(tag.apply(null, thisElem));
            });
            return frag;
          }

          // Single element? Parse element namespace prefix (if none exists, default to defaultNamespace), and create element
          var elemNs = namespace(elemNameOrArray);
          var elem = doc.createElementNS(elemNs.namespace || jsonToDOM.defaultNamespace, elemNs.shortName);

          // Set element's attributes and/or callback functions (eg. onclick)
          for (var key in elemAttr) {
            var val = elemAttr[key];
            if (nodes && key == "key") {
                nodes[val] = elem;
                continue;
            }

            var attrNs = namespace(key);
            if (typeof val == "function") {
              // Special case for function attributes; don't just add them as 'on...' attributes, but as events, using addEventListener
              elem.addEventListener(key.replace(/^on/, ""), val, false);
            } else {
              // Note that the default namespace for XML attributes is, and should be, blank (ie. they're not in any namespace)
              elem.setAttributeNS(attrNs.namespace || "", attrNs.shortName, val);
            }
          }

          // Create and append this element's children
          var childElems = Array.prototype.slice.call(arguments, 2);
          childElems.forEach(function(childElem) {
            if (childElem != null) {
              elem.appendChild(
                  childElem instanceof doc.defaultView.Node ? childElem :
                      Array.isArray(childElem) ? tag.apply(null, childElem) :
                          doc.createTextNode(childElem));
            }
          });
          return elem;
        }
        return tag.apply(null, jsonTemplate);
      }

      return jsonToDOM(jsonTemplate, doc, nodes);
    }
  }


  window.undobookmarksmenu.init();
}

To be continued... Потом еще десяток выложу.

Кнопка для Attributes_Inspector от Dumby
https://forum.mozilla-russia.org/viewto … 07#p789007
Путь к attrsInspector.js прописать свой.
Сам attrsInspector.js - https://github.com/Infocatcher/Custom_B … _Inspector
Например, chrome://user_chrome_files/content/custom_scripts/custom_js/attrsInspector.js =
пути ФС - .\chrome\user_chrome_files\custom_scripts\custom_js\attrsInspector.js
Для custom_script.js в user_chrome_files
 
Открытие окна "Инструменты браузера" по ПКМ на иконке Attributes Inspector
Создано по шаблонам от Vitaliy V.

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

Выделить код

Код:

// Открытие окна "Инструменты браузера"
// по ПКМ на иконке Attributes Inspector
// Создано по шаблонам, где то здесь -
// https://forum.mozilla-russia.org/viewtopic.php?pid=791976#p791976
(this.opendevtoolsrclick3 = {
    async init(that) {
        await window.delayedStartupPromise;
        var btn = CustomizableUI.getWidget("AttributesInspector")?.forWindow(window).node;
        if (!btn) return;
        btn.setAttribute("context", "");
        btn.tooltipText = `ЛКМ: Attributes Inspector\nПКМ: Инструменты браузера`;
        var listener = e => {
            if (e.button != 2) return;
            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
            var pref = Services.prefs, chr = "devtools.chrome.enabled", rem = "devtools.debugger.remote-enabled";
                if (!pref.getBoolPref(chr) || !pref.getBoolPref(rem)) {
                    pref.setBoolPref(chr, true);
                    pref.setBoolPref(rem, true);
            }
            var { BrowserToolboxLauncher } = ChromeUtils.import("resource://devtools/client/framework/browser-toolbox/Launcher.jsm");
            BrowserToolboxLauncher.init();
        };
        btn.addEventListener("click", listener);
        that.unloadlisteners.push("opendevtoolsrclick3");
        this.destructor = () => {
            btn.removeEventListener("click", listener);
        };
    }
}).init(this);

Для custom_script_win.js
Строка загрузки - loadscript("subfolder/script_file_name.uc.js", this); или loadscript("script_file_name.uc.js", this);

Vitaliy V.
Спрошу в этой теме, возможно это можно сделать тоже только скриптом. Вы мне делали скрипт смены иконки поисковика.
Стилем, по этому шаблону, я сменил ещё иконку на старую на закладке.
Старую иконку взял по этому адресу https://yandex.ru/favicon.ico, странно что сейчас везде отображается не она а буква Я в красном круге, но не суть важно.

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

Выделить код

Код:

.bookmark-item:not([container])[image^='page-icon:https://yandex.ru/'] image {
    object-position: 16px 0px !important;
    list-style-image: none !important;
    background: url("./svg/yandex.ico") transparent center no-repeat !important;
}

Хотел вас спросить, может можно сменить фавикон на вкладке для заданного адреса, т.е. там где он изначально формируется, чтоб на вкладке и в адресной строке была одна и та же иконка.
Я использую этот скрипт для отображения фавикона в строке адреса, но наверно он там же считывает иконку, где и Ваш faviconinurlbar. Может можно что-то придумать.
Ещё поменял на NNM сразу на трёх адресах, там у них вообще странно, если масштаб страницы 100%, то отображается одна бабочка(нормальная), повёрнутая вправо, а если ставлю больше масштаб(133% использую почти везде), то уже другая.
Мелочи это всё конечно, но как-то это нелогично, в slimjet с бабочкой такой проблемы нет, а в [firefox] давненько уже.
скрытый текст
______.PNG
Войдите или зарегистрируйтесь, чтобы увидеть скрытый текст.

Выделить код

Код:

.bookmark-item:not([container]):is([image^='page-icon:https://nnm-club.me/'], [image^='page-icon:https://nnmclub.ro/'], [image^='page-icon:https://nnmclub.to/']) image {
    object-position: 16px 0px !important;
    list-style-image: none !important;
    background: url("./svg/nnmclub.ico") transparent center no-repeat !important;
}
sandro79 пишет

возможно это можно сделать тоже только скриптом

Это скрипты для сайтов, для этого есть Greasemonkey и т.д.

sandro79 пишет

там где он изначально формируется

Естественно со страницы сайта по ссылке например
<link rel="icon" href="favicon.ico">
либо из кеша


Ладно попробую но только потому что в Greasemonkey не сработают некоторые события.
Размеры например sizes="32x32" не учитываются, для всех одна иконка
custom_script.js

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

Выделить код

Код:

ChromeUtils.registerWindowActor("LinkWinActor", {
    child: {
        moduleURI: "chrome://user_chrome_files/content/custom_scripts/LinkWinActorChild.jsm",
        events: {
            DOMLinkAdded: { capture: true },
            DOMLinkChanged: {},
            DOMHeadElementParsed: {},
            pageshow: {},
        },
    },
    messageManagerGroups: ["browsers"],
    matches: [ // адреса где работает скрипт
        "https://yandex.ru/",
        "https://yandex.ru/?*",
        "https://yandex.ru/search/*",
        "https://passport.yandex.ru/*",
        "https://nnmclub.to/*",
        "about:config",
        "about:user-chrome-files",
    ],
});


LinkWinActorChild.jsm
скрытый текст

Выделить код

Код:

var EXPORTED_SYMBOLS = ["LinkWinActorChild"];
ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
const LINK_SELECTOR = "link[href]:is([rel~='icon'],[rel~='apple-touch-icon'],[rel~='apple-touch-icon-precomposed'],[rel~='fluid-icon'],[rel~='mask-icon'])";
const ICONS = { // "домен, или адрес для about|chrome|resource": "иконка",
    "yandex.ru": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><rect rx='2' ry='2' width='16' height='16' style='fill:rgb(231, 43, 90);'/><path d='M 8.56,2 C 6.31,2 4.49,3.5 4.49,5.99 4.49,7.49 5.31,8.48 6.97,9.57 L 4,13.5 V 14 H 5.76 L 8.53,9.57 H 9.47 V 14 H 11 V 2 Z M 9.47,8.48 H 8.67 C 7.36,8.48 6.05,7.98 6.05,5.99 6.05,4 7.26,3 8.47,3 H 9.47 Z' style='fill:white;'/></g></svg>",
    "nnmclub.to": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><path d='M 0.887,0 C 0.54,0.14 0.289,0.279 0.135,0.711 0.051,0.851 0.015,0.991 0,1.27 -0.009,1.71 0.061,2.16 0.325,3.05 0.564,3.88 0.612,4.12 0.612,4.37 0.612,4.48 0.612,4.56 0.588,4.67 0.457,5.43 0.457,6.07 0.588,6.56 0.672,6.87 0.779,7.09 0.947,7.28 1.21,7.57 1.49,7.73 2.05,7.87 L 2.27,7.91 2.11,7.96 C 1.87,8.01 1.71,8.08 1.55,8.19 1.33,8.31 1.22,8.41 1.09,8.59 0.947,8.65 0.887,8.83 0.839,8.99 0.803,9.17 0.792,9.41 0.827,9.65 0.851,9.93 0.851,9.93 0.827,10 0.827,10.1 0.767,10.3 0.708,10.5 0.588,10.9 0.564,11.1 0.564,11.2 0.564,11.5 0.612,11.6 0.875,11.8 1.15,12.2 1.18,12.3 1.15,12.6 1.1,13.2 1.18,13.6 1.39,13.7 1.49,13.7 1.6,13.9 1.75,14 1.93,14 2.05,14.1 2.28,14.4 2.48,14.5 2.55,14.5 2.64,14.5 2.73,14.7 2.73,14.7 2.87,14.7 3.04,14.7 3.04,14.7 3.47,14.5 4.03,14 4.19,13.9 4.44,13.9 4.55,13.7 4.6,13.7 4.68,13.7 4.88,13.6 5.11,13 5.35,11.9 5.39,11.8 5.43,11.6 5.47,11.5 5.65,10.9 5.89,10.4 6.12,10 6.24,9.83 6.48,9.59 6.49,9.59 6.49,9.59 6.49,9.75 6.48,10.1 6.44,10.3 6.43,10.5 6.28,11.1 6.12,11.5 6.08,11.7 6.05,12 6.03,12.4 6.11,12.6 6.21,12.9 6.32,13 6.43,13 6.57,13 6.71,12.9 6.81,12.6 6.91,12.4 7.07,12 7.11,11.7 7.11,11 7.11,10.7 7.13,10.4 7.27,10 7.35,9.75 7.32,9.75 7.37,9.83 7.52,10.1 7.64,10.7 7.69,11.3 7.72,11.6 7.72,12.2 7.69,12.4 7.64,13 7.61,13.6 7.68,14 7.72,14.4 7.76,14.5 8.01,14.5 8.15,14.7 8.31,14.8 8.67,15.5 8.92,15.9 9.03,15.9 9.11,16 9.17,16 9.17,16 9.33,16 9.52,16 9.52,16 9.77,15.9 10.1,15.7 10.1,15.7 10.4,15.7 10.7,15.7 10.7,15.7 10.7,15.7 11,15.6 11.1,15.5 11.4,14.9 11.4,14.9 11.4,14.8 11.5,14.7 11.5,14.5 11.6,14.4 11.7,14.1 12.2,13.9 12.2,13.9 12.2,13.7 12.4,13.6 12.4,13.6 12.4,13 12.4,12.6 12.5,12.4 12.5,12.3 12.5,12.3 12.5,12.2 12.7,12 12.8,11.7 12.8,11.6 12.8,11.5 12.8,11.2 12.8,11.1 12.8,11.1 12.7,10.7 12.4,10.3 12,9.93 11.9,9.83 11.9,9.83 11.9,9.83 12.2,9.93 12.7,9.93 12.9,9.93 13.7,9.75 14,9.08 14.1,7.84 14.1,7.76 14.3,7.59 14.3,7.49 14.3,7.27 14.3,7.19 14.5,7.01 14.5,6.83 14.8,6.6 15.1,6.19 15.7,5.24 15.9,4.85 16,4.41 16,4.31 16,4.25 16,4.03 16,3.84 16,3.76 16,3.69 15.7,3.03 15.2,2.68 14.3,2.75 13.7,2.76 13,2.97 12.2,3.32 12,3.4 11.6,3.63 11.4,3.81 10.2,4.49 9.11,5.55 8.08,6.85 7.95,7 7.85,7.11 7.85,7.11 7.85,7.11 7.84,7.05 7.84,7.04 7.76,6.93 7.72,6.87 7.61,6.81 L 7.53,6.73 7.64,6.47 C 7.92,5.92 8.13,5.51 8.31,5.23 8.35,5.12 8.51,4.91 8.76,4.63 9.43,3.73 9.68,3.47 9.77,3.35 10,3.21 10,3.2 10,3.15 10.1,3.05 10,2.92 10,2.87 9.95,2.87 9.95,2.91 9.84,2.97 9.84,3.11 9.52,3.44 9.11,4.03 8.92,4.19 8.76,4.37 8.76,4.45 8.35,4.95 7.95,5.69 7.61,6.47 7.53,6.6 7.49,6.73 7.47,6.73 7.47,6.73 7.43,6.71 7.37,6.71 L 7.28,6.68 V 6.59 C 7.2,5.69 7.08,5.08 6.91,4.49 6.83,4.16 6.8,4 6.59,3.44 6.33,2.75 6.2,2.32 6.2,2.21 6.17,2.09 6.05,2.08 6,2.2 5.97,2.31 5.99,2.39 6.11,2.55 6.21,2.75 6.32,2.97 6.73,4.15 7,4.96 7.07,5.13 7.2,6.29 7.23,6.68 7.23,6.68 7.2,6.68 7.13,6.68 6.97,6.75 6.89,6.83 6.83,6.87 6.81,6.89 6.81,6.89 6.81,6.89 6.75,6.73 6.68,6.56 6.53,6.07 6.4,5.77 6.2,5.27 5.36,3.43 4.39,2.01 3.36,1.13 2.64,0.571 2.01,0.14 1.49,0 1.32,0 1.02,0 0.887,0 Z' style='fill:rgb(0, 140, 255);stroke:black;stroke-width:0.6;stroke-linejoin:round;stroke-linecap:round;'/></g></svg>",
    "about:config": "chrome://global/skin/icons/settings.svg",
    "about:user-chrome-files": "chrome://global/skin/icons/settings.svg",
};

class LinkWinActorChild extends JSWindowActorChild {
    actorCreated() {
        var docURI = this.document.documentURIObject, host;
        if (!/^(?:about|chrome|resource)$/.test(docURI.scheme))
            try {
                let baseDomain = Services.eTLD.getBaseDomain(docURI);
                host = Cc["@mozilla.org/network/idn-service;1"].getService(Ci.nsIIDNService)
                .convertToDisplayIDN(baseDomain, {});
            } catch (e) {
                try {
                    host = docURI.displayHost;
                } catch (e) {
                    host = docURI.specIgnoringRef;
                }
            }
        else
            host = docURI.specIgnoringRef;
        var icon = ICONS[host];
        if (!icon) {
            this.handleEvent = e => {};
            return;
        }
        this._icon = icon;
        this.onHeadParsed(this.document.head);
    }
    onHeadParsed(target) {
        for (let link of target.querySelectorAll(LINK_SELECTOR))
            link.remove();
        var link = this.document.createElement("link");
        link.setAttribute("rel", "icon");
        link.setAttribute("sizes", "any");
        link.setAttribute("href", this._icon);
        target.append(link);
    }
    onLinkEvent(link) {
        if (!link.matches(LINK_SELECTOR) || link.href == this._icon) return;
        link.href = this._icon;
        link.setAttribute("rel", "icon");
        link.setAttribute("sizes", "any");
        if (link.hasAttribute("type"))
            link.removeAttribute("type");
    }
    handleEvent(e) {
        switch (e.type) {
            case "DOMLinkAdded":
            case "DOMLinkChanged":
                this.onLinkEvent(e.target);
                break;
            case "pageshow":
                this.onHeadParsed(e.target.head);
                break;
        }
    }
}


Или вариант поддомен + домен, для тех кому надо устанавливать разные иконки для поддоменов

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

Выделить код

Код:

var EXPORTED_SYMBOLS = ["LinkWinActorChild"];
ChromeUtils.defineModuleGetter(this, "Services", "resource://gre/modules/Services.jsm");
const LINK_SELECTOR = "link[href]:is([rel~='icon'],[rel~='apple-touch-icon'],[rel~='apple-touch-icon-precomposed'],[rel~='fluid-icon'],[rel~='mask-icon'])";
const ICONS = { // "поддомен + домен, или адрес для about|chrome|resource": "иконка",
    "yandex.ru": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><rect rx='2' ry='2' width='16' height='16' style='fill:rgb(231, 43, 90);'/><path d='M 8.56,2 C 6.31,2 4.49,3.5 4.49,5.99 4.49,7.49 5.31,8.48 6.97,9.57 L 4,13.5 V 14 H 5.76 L 8.53,9.57 H 9.47 V 14 H 11 V 2 Z M 9.47,8.48 H 8.67 C 7.36,8.48 6.05,7.98 6.05,5.99 6.05,4 7.26,3 8.47,3 H 9.47 Z' style='fill:white;'/></g></svg>",
    get "passport.yandex.ru"() { return this["yandex.ru"]; },
    "nnmclub.to": "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><path d='M 0.887,0 C 0.54,0.14 0.289,0.279 0.135,0.711 0.051,0.851 0.015,0.991 0,1.27 -0.009,1.71 0.061,2.16 0.325,3.05 0.564,3.88 0.612,4.12 0.612,4.37 0.612,4.48 0.612,4.56 0.588,4.67 0.457,5.43 0.457,6.07 0.588,6.56 0.672,6.87 0.779,7.09 0.947,7.28 1.21,7.57 1.49,7.73 2.05,7.87 L 2.27,7.91 2.11,7.96 C 1.87,8.01 1.71,8.08 1.55,8.19 1.33,8.31 1.22,8.41 1.09,8.59 0.947,8.65 0.887,8.83 0.839,8.99 0.803,9.17 0.792,9.41 0.827,9.65 0.851,9.93 0.851,9.93 0.827,10 0.827,10.1 0.767,10.3 0.708,10.5 0.588,10.9 0.564,11.1 0.564,11.2 0.564,11.5 0.612,11.6 0.875,11.8 1.15,12.2 1.18,12.3 1.15,12.6 1.1,13.2 1.18,13.6 1.39,13.7 1.49,13.7 1.6,13.9 1.75,14 1.93,14 2.05,14.1 2.28,14.4 2.48,14.5 2.55,14.5 2.64,14.5 2.73,14.7 2.73,14.7 2.87,14.7 3.04,14.7 3.04,14.7 3.47,14.5 4.03,14 4.19,13.9 4.44,13.9 4.55,13.7 4.6,13.7 4.68,13.7 4.88,13.6 5.11,13 5.35,11.9 5.39,11.8 5.43,11.6 5.47,11.5 5.65,10.9 5.89,10.4 6.12,10 6.24,9.83 6.48,9.59 6.49,9.59 6.49,9.59 6.49,9.75 6.48,10.1 6.44,10.3 6.43,10.5 6.28,11.1 6.12,11.5 6.08,11.7 6.05,12 6.03,12.4 6.11,12.6 6.21,12.9 6.32,13 6.43,13 6.57,13 6.71,12.9 6.81,12.6 6.91,12.4 7.07,12 7.11,11.7 7.11,11 7.11,10.7 7.13,10.4 7.27,10 7.35,9.75 7.32,9.75 7.37,9.83 7.52,10.1 7.64,10.7 7.69,11.3 7.72,11.6 7.72,12.2 7.69,12.4 7.64,13 7.61,13.6 7.68,14 7.72,14.4 7.76,14.5 8.01,14.5 8.15,14.7 8.31,14.8 8.67,15.5 8.92,15.9 9.03,15.9 9.11,16 9.17,16 9.17,16 9.33,16 9.52,16 9.52,16 9.77,15.9 10.1,15.7 10.1,15.7 10.4,15.7 10.7,15.7 10.7,15.7 10.7,15.7 11,15.6 11.1,15.5 11.4,14.9 11.4,14.9 11.4,14.8 11.5,14.7 11.5,14.5 11.6,14.4 11.7,14.1 12.2,13.9 12.2,13.9 12.2,13.7 12.4,13.6 12.4,13.6 12.4,13 12.4,12.6 12.5,12.4 12.5,12.3 12.5,12.3 12.5,12.2 12.7,12 12.8,11.7 12.8,11.6 12.8,11.5 12.8,11.2 12.8,11.1 12.8,11.1 12.7,10.7 12.4,10.3 12,9.93 11.9,9.83 11.9,9.83 11.9,9.83 12.2,9.93 12.7,9.93 12.9,9.93 13.7,9.75 14,9.08 14.1,7.84 14.1,7.76 14.3,7.59 14.3,7.49 14.3,7.27 14.3,7.19 14.5,7.01 14.5,6.83 14.8,6.6 15.1,6.19 15.7,5.24 15.9,4.85 16,4.41 16,4.31 16,4.25 16,4.03 16,3.84 16,3.76 16,3.69 15.7,3.03 15.2,2.68 14.3,2.75 13.7,2.76 13,2.97 12.2,3.32 12,3.4 11.6,3.63 11.4,3.81 10.2,4.49 9.11,5.55 8.08,6.85 7.95,7 7.85,7.11 7.85,7.11 7.85,7.11 7.84,7.05 7.84,7.04 7.76,6.93 7.72,6.87 7.61,6.81 L 7.53,6.73 7.64,6.47 C 7.92,5.92 8.13,5.51 8.31,5.23 8.35,5.12 8.51,4.91 8.76,4.63 9.43,3.73 9.68,3.47 9.77,3.35 10,3.21 10,3.2 10,3.15 10.1,3.05 10,2.92 10,2.87 9.95,2.87 9.95,2.91 9.84,2.97 9.84,3.11 9.52,3.44 9.11,4.03 8.92,4.19 8.76,4.37 8.76,4.45 8.35,4.95 7.95,5.69 7.61,6.47 7.53,6.6 7.49,6.73 7.47,6.73 7.47,6.73 7.43,6.71 7.37,6.71 L 7.28,6.68 V 6.59 C 7.2,5.69 7.08,5.08 6.91,4.49 6.83,4.16 6.8,4 6.59,3.44 6.33,2.75 6.2,2.32 6.2,2.21 6.17,2.09 6.05,2.08 6,2.2 5.97,2.31 5.99,2.39 6.11,2.55 6.21,2.75 6.32,2.97 6.73,4.15 7,4.96 7.07,5.13 7.2,6.29 7.23,6.68 7.23,6.68 7.2,6.68 7.13,6.68 6.97,6.75 6.89,6.83 6.83,6.87 6.81,6.89 6.81,6.89 6.81,6.89 6.75,6.73 6.68,6.56 6.53,6.07 6.4,5.77 6.2,5.27 5.36,3.43 4.39,2.01 3.36,1.13 2.64,0.571 2.01,0.14 1.49,0 1.32,0 1.02,0 0.887,0 Z' style='fill:rgb(0, 140, 255);stroke:black;stroke-width:0.6;stroke-linejoin:round;stroke-linecap:round;'/></g></svg>",
    "about:config": "chrome://global/skin/icons/settings.svg",
    "about:user-chrome-files": "chrome://global/skin/icons/settings.svg",
};

class LinkWinActorChild extends JSWindowActorChild {
    actorCreated() {
        var docURI = this.document.documentURIObject, host;
        if (!/^(?:about|chrome|resource)$/.test(docURI.scheme))
            try {
                host = docURI.displayHost;
            } catch (e) {
                host = docURI.specIgnoringRef;
            }
        else
            host = docURI.specIgnoringRef;
        var icon = ICONS[host];
        if (!icon) {
            this.handleEvent = e => {};
            return;
        }
        this._icon = icon;
        this.onHeadParsed(this.document.head);
    }
    onHeadParsed(target) {
        for (let link of target.querySelectorAll(LINK_SELECTOR))
            link.remove();
        var link = this.document.createElement("link");
        link.setAttribute("rel", "icon");
        link.setAttribute("sizes", "any");
        link.setAttribute("href", this._icon);
        target.append(link);
    }
    onLinkEvent(link) {
        if (!link.matches(LINK_SELECTOR) || link.href == this._icon) return;
        link.href = this._icon;
        link.setAttribute("rel", "icon");
        link.setAttribute("sizes", "any");
        if (link.hasAttribute("type"))
            link.removeAttribute("type");
    }
    handleEvent(e) {
        switch (e.type) {
            case "DOMLinkAdded":
            case "DOMLinkChanged":
                this.onLinkEvent(e.target);
                break;
            case "pageshow":
                this.onHeadParsed(e.target.head);
                break;
        }
    }
}


sandro79 пишет

Я использую этот скрипт для отображения фавикона в строке адреса

Этот скрипт ужасен, что вы в нем нашли?

Vitaliy V. пишет

Ладно попробую но только потому что в Greasemonkey не сработают некоторые события.
Размеры например sizes="32x32" не учитываются, для всех одна иконка

Виталий, ну Вы Мастер!!! Я думал там попроще будет, как с иконкой поисковика примерно.
Огромное Вам Спасибо! Все с ходу заработало! Прописал остальные адреса, всё отлично!
Правда была проблема когда адреса добавлял, запятые забыл проставить и никак иконки не появлялись, но взял себя в руки и решил эту задачу.

скрытый текст
______2.PNG

Этот скрипт ужасен, что вы в нем нашли?

Да, я вижу его недостатки, скорее всего поверхностно, но плюс в  том, что он мне подходит тем, что на месте скрытой стилем лупы в строке адреса, он ставит значок [firefox] на странице about:newtab, также расположение фавикона мне привычней (ну этим можно и пожертвовать), с тех пор как пользуюсь этим скриптом, с 60 какой-то версии. И плюс ещё, что фавикон в строке адреса при навигации в пределах страницы, обновлении страницы - всегда отображается и не исчезает. Если бы в Вашем скрипте фавикон не менялся на identity-icon пока находишься на странице - обновляешь, по ссылкам ходишь, я бы его использовал конечно, но постоянное обновление фавикона, ну мне не подходит. Я вижу недостатки в используемом мной скрипте, насколько фавикон жёстко привязан к высоте адресной строки, чуть размер строки другой, растягивается или сжимается, подбирать вручную нужно правкой скрипта. Но я настроил под свой режим и пойдёт пока.

Vitaliy V.
Разреши попросить прояснить насчёт
событий "DOMHeadElementParsed" и "pageshow".


Если я правильно понимаю, то лисий LinkHandlerChild
слушает их на предмет того, что если соответствующий <link>
не нарисовался, то запросить дефолтный http://сайт/favicon.ico,
и для предотвращения сохранения фавиконок,
изменённых js-манипуляциями скриптами сайта.


А LinkWinActorChild зачем их слушает?

Dumby
DOMLinkAdded срабатывает не всегда при использовании matches: [ // адреса где работает скрипт ...
Это видно с яндексом если перейти со страницы поиска на главную нажав логотип Яндекс в слева от поиска
А DOMHeadElementParsed да возможно лишний, вариант скрипта не окончательный, есть ещё проблемка с ним

sandro79 пишет

Если бы в Вашем скрипте фавикон не менялся на identity-icon пока находишься на странице - обновляешь, по ссылкам ходишь, я бы его использовал конечно, но постоянное обновление фавикона, ну мне не подходит

Это не постоянное обновление, если говорить об этом то ваш скрипт обновляет её намного чаще, когда это и не нужно.
Это скрытие иконки сделано чтобы при переходе например на другой сайт она не отображалась некоторое время с адресом от другого сайта ,
и вообще то это можно изменить удалив например css селектор , #identity-faviconinurlbar[favbusy="true"]

sandro79 пишет

что на месте скрытой стилем лупы в строке адреса, он ставит значок [firefox] на странице about:newtab

что требуется удалить для этого
#identity-faviconinurlbar[faviconchrome="true"],
,.localResource
, #urlbar:not(.searchButton) #identity-box[pageproxystate="invalid"] #identity-faviconinurlbar
или добавить в конце css кода

Выделить код

Код:

#urlbar:not(.searchButton) #identity-box[pageproxystate="invalid"].localResource #identity-faviconinurlbar[faviconchrome="true"] {
                        display: -moz-inline-box !important;
                    }
Vitaliy V. пишет

DOMLinkAdded срабатывает не всегда при использовании matches

О как! Принято, тогда действительно стоит прогонять ещё раз, на всякий случай.
Я-то вообще был бы склонен к переопределению LinkHandlerParent.prototype.setIconFromLink

sandro79 пишет

но плюс в  том, что он мне подходит тем, что на месте скрытой стилем лупы в строке адреса, он ставит значок [firefox] на странице about:newtab,

Можно не скрывая подставить другую иконку, например так:

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

Выделить код

Код:

#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] #identity-icon {
    list-style-image: url("chrome://branding/content/about-logo.svg") !important;
}

Vitaliy V. пишет

и вообще то это можно изменить удалив например css селектор , #identity-faviconinurlbar[favbusy="true"]

Да, это сработало.

что требуется удалить для этого

#identity-faviconinurlbar[faviconchrome="true"],

А это не сработало. Добавление в конце css кода тоже нет. Да я может не совсем правильно поставил задачу, не знаю даже. Скрины выложу. Вот на about:newtab у него как и на служебных страницах тоже добавляются значки, может можно так сделать, а так теперь фавикон не мелькает

скрытый текст
______.PNG______2.PNG
Сам скрипт, что я правил, может где ошибся
скрытый текст

Выделить код

Код:

(this.faviconinurlbar = {
            init(that) {
                var identity = document.querySelector("#identity-icon");
                if (!identity)
                    return;
                var iconDefault = "chrome://branding/content/identity-icons-brand.svg"; // или свою иконку
                var style = "data:text/css;charset=utf-8," + encodeURIComponent(`
                    #identity-faviconinurlbar {
                        --v-faviconinurlbar-default: url("${iconDefault}");

                        list-style-image: var(--v-faviconinurlbar, none) !important;
                        pointer-events: none !important;
                        height: 16px !important;
                        width: auto !important;
                        margin-inline-start: 4px !important;
                        -moz-context-properties: fill, fill-opacity;
                        fill: currentColor;
                        fill-opacity: var(--urlbar-icon-fill-opacity, 1);
                    }
                    #identity-faviconinurlbar:not([faviconinurlbar="true"]) {
                        --v-faviconinurlbar: var(--v-faviconinurlbar-default) !important;
                    }
                    #urlbar[actiontype="extension"] #identity-faviconinurlbar,
                    #identity-box:is(.extensionPage,.chromeUI,.localResource) #identity-faviconinurlbar {
                        display: none !important;
                    }
                `);
                windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET);
                var faviconinurlbar = document.createXULElement("image");
                faviconinurlbar.id = "identity-faviconinurlbar";
                identity.after(faviconinurlbar);
                gBrowser.tabContainer.addEventListener("TabAttrModified", this);
                gBrowser.addProgressListener(this);
                that.unloadlisteners.push("faviconinurlbar");
                var {STATE_START, STATE_STOP, STATE_IS_NETWORK} = Ci.nsIWebProgressListener;
                var updatefavicon = image => {
                    if (image) {
                        faviconinurlbar.style.setProperty("--v-faviconinurlbar", `url("${image}")`);
                        faviconinurlbar.setAttribute("faviconinurlbar", "true");
                        faviconinurlbar.setAttribute("faviconchrome", `${image.startsWith("chrome:")}`);
                    } else {
                        faviconinurlbar.setAttribute("faviconinurlbar", "false");
                        faviconinurlbar.style.setProperty("--v-faviconinurlbar", "");
                    }
                };
                this.handleEvent = e => {
                    var tab = e.target, changed;
                    if (!tab.selected || !((changed = e.detail.changed).includes("image") || changed.includes("selected"))) return;
                    updatefavicon(tab.image);
                };
                this.onStateChange = (aWebProgress, aRequest, aStateFlags, aStatus) => {
                    if (aStateFlags & STATE_IS_NETWORK && aWebProgress?.isTopLevel) {
                        if (aStateFlags & STATE_START)
                            faviconinurlbar.setAttribute("favbusy", "true");
                        else if (aStateFlags & STATE_STOP) {
                            faviconinurlbar.setAttribute("favbusy", "false");
                            updatefavicon(gBrowser.selectedTab.image);
                        }
                    }
                };
            },
            destructor() {
                gBrowser.tabContainer.removeEventListener("TabAttrModified", this);
                gBrowser.removeProgressListener(this);
            }
        }).init(this);

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

kokoss пишет

Можно не скрывая подставить другую иконку, например так:

Да, спасибо. Я знаю как подобные иконки менять :D Но как вариант да, сойдет.

sandro79 пишет

Да, спасибо. Я знаю как подобные иконки менять

Я и не сомневался:D, но может кому нибудь ещё пригодится :)

sandro79 пишет

может где ошибся

я ещё писал про ,.localResource
но как я понял вообще скрывать нигде не нужно тогда удалите целиком правило относящееся к display: none !important;

Vitaliy V. пишет

я ещё писал про ,.localResource

Вот же ж, всё-таки недоглядел я, запутался.

но как я понял вообще скрывать нигде не нужно тогда удалите целиком правило относящееся к display: none !important;

Да, я неправильно сформулировал задачу, не упомянув о служебных страницах, извиняюсь.
Да, и это теперь сработало на служебных страницах. Но чтоб сработало на about:newtab, нужно удалить из кода правило, скрывающее лупу

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

Выделить код

Код:

#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] > #identity-icon-box {
  display: none !important;
}

И получается так. А если скрыть лупу, то лого [firefox] тоже пропадает. Если использовать этот код появляется два лого [firefox].
Ну я понял, тут дело в том как, к чему привязан что ли вафикон в разных скриптах, технически не знаю как сформулировать. Ну тут похоже надо больше переделывать.

kokoss пишет

но может кому нибудь ещё пригодится

Конечно, любой рабочий код будет полезен.

sandro79 пишет

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

Нет дело не в этом, просто нужно скрывать #identity-icon а не контейнер

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

Выделить код

Код:

#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] #identity-icon {
  display: none !important;
}

Vitaliy V. пишет

Нет дело не в этом, просто нужно скрывать #identity-icon а не контейнер

Огромное Вам спасибо! Теперь всё отлично!

скрытый текст
______.PNG______2.PNG______3.PNG
Оставил скрипт пока в [nightly], на ней привыкать буду некоторое время к расположению фавикона сайта. У Ариса он перед замком, у Вас после него.
Здесь оставлю коды скрипта и стиля, как резерв
скрытый текст

Выделить код

Код:

(this.faviconinurlbar = {
            init(that) {
                var identity = document.querySelector("#identity-icon");
                if (!identity)
                    return;
                var iconDefault = "chrome://global/skin/icons/info.svg"; // или свою иконку
                var style = "data:text/css;charset=utf-8," + encodeURIComponent(`
                    #identity-faviconinurlbar {
                        --v-faviconinurlbar-default: url("${iconDefault}");

                        list-style-image: var(--v-faviconinurlbar, none) !important;
                        pointer-events: none !important;
                        height: 16px !important;
                        width: auto !important;
                        margin-inline-start: 4px !important;
                        -moz-context-properties: fill, fill-opacity;
                        fill: currentColor;
                        fill-opacity: var(--urlbar-icon-fill-opacity, 1);
                    }
                    #identity-faviconinurlbar:not([faviconinurlbar="true"]) {
                        --v-faviconinurlbar: var(--v-faviconinurlbar-default) !important;
                    }
                `);
                windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET);
                var faviconinurlbar = document.createXULElement("image");
                faviconinurlbar.id = "identity-faviconinurlbar";
                identity.after(faviconinurlbar);
                gBrowser.tabContainer.addEventListener("TabAttrModified", this);
                gBrowser.addProgressListener(this);
                that.unloadlisteners.push("faviconinurlbar");
                var {STATE_START, STATE_STOP, STATE_IS_NETWORK} = Ci.nsIWebProgressListener;
                var updatefavicon = image => {
                    if (image) {
                        faviconinurlbar.style.setProperty("--v-faviconinurlbar", `url("${image}")`);
                        faviconinurlbar.setAttribute("faviconinurlbar", "true");
                        faviconinurlbar.setAttribute("faviconchrome", `${image.startsWith("chrome:")}`);
                    } else {
                        faviconinurlbar.setAttribute("faviconinurlbar", "false");
                        faviconinurlbar.style.setProperty("--v-faviconinurlbar", "");
                    }
                };
                this.handleEvent = e => {
                    var tab = e.target, changed;
                    if (!tab.selected || !((changed = e.detail.changed).includes("image") || changed.includes("selected"))) return;
                    updatefavicon(tab.image);
                };
                this.onStateChange = (aWebProgress, aRequest, aStateFlags, aStatus) => {
                    if (aStateFlags & STATE_IS_NETWORK && aWebProgress?.isTopLevel) {
                        if (aStateFlags & STATE_START)
                            faviconinurlbar.setAttribute("favbusy", "true");
                        else if (aStateFlags & STATE_STOP) {
                            faviconinurlbar.setAttribute("favbusy", "false");
                            updatefavicon(gBrowser.selectedTab.image);
                        }
                    }
                };
            },
            destructor() {
                gBrowser.tabContainer.removeEventListener("TabAttrModified", this);
                gBrowser.removeProgressListener(this);
            }
        }).init(this);

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

Выделить код

Код:

#urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] #identity-icon {
  display: none !important;
}

sandro79 пишет

У Ариса он перед замком, у Вас после него

Не думаете же вы что это сложно изменить, вот даже стилем можно
заменить
margin-inline-start: 4px !important;
на
-moz-box-ordinal-group: 0 !important;
margin-inline: 0 4px !important;


ну или вместо -moz-box-ordinal-group: 0 !important;
//identity.after(faviconinurlbar);
identity.before(faviconinurlbar);

Vitaliy V. пишет

Не думаете же вы что это сложно изменить, вот даже стилем можно

Да, я собирался вообще попробовать, но что-то подумал, что там жёстко у Вас фавикон привязан, и вообще решил не трогать, оставить оригинальное расположение.
Да, сработало стилем. Спасибо за подсказку! Теперь вообще супер!

ну или вместо -moz-box-ordinal-group: 0 !important; //identity.after(faviconinurlbar); identity.before(faviconinurlbar);

А так вообще великолепно! Спасибо! Только замок от фавикона чуть отодвину стилем, это я уже сам.

скрытый текст
______.PNG

Выделить код

Код:

#identity-icon {
    margin-inline-start: 4px !important;
}

Vitaliy V.
Ну всё, настроил я всё окончательно, теперь визуально один в один с Ариса скриптом.
В скрипте ещё для селектора #identity-faviconinurlbar сменил margin-inline-start: 2px !important;
Ниже скрины - верхняя панель 91 с Ариса скриптом, нижняя 92 [nightly] с этим

скрытый текст
Image_001.png
Теперь можно переходить на этот вариант окончательно. Ещё раз Большое Спасибо :beer:


Окончательный вариант скрипта, добавил в скрипт css-коды с предыдущих сообщений

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

Выделить код

Код:

(this.faviconinurlbar = {
            init(that) {
                var identity = document.querySelector("#identity-icon");
                if (!identity)
                    return;
                var iconDefault = "chrome://global/skin/icons/defaultFavicon.svg"; // или свою иконку
                var style = "data:text/css;charset=utf-8," + encodeURIComponent(`
                    #identity-faviconinurlbar {
                        --v-faviconinurlbar-default: url("${iconDefault}");

                        list-style-image: var(--v-faviconinurlbar, none) !important;
                        pointer-events: none !important;
                        height: 16px !important;
                        width: 16px !important;
                        margin-inline-start: 3px !important;
                        -moz-context-properties: fill, fill-opacity;
                        fill: currentColor;
                        fill-opacity: var(--urlbar-icon-fill-opacity, 1);
                    }
                    #identity-faviconinurlbar:not([faviconinurlbar="true"]) {
                        --v-faviconinurlbar: var(--v-faviconinurlbar-default) !important;
                    }
                    #identity-icon {
                        margin-inline-start: 4px !important;
                    }
                    .identity-box-button {
                        padding-inline: 2px !important;
                    }         
                    #urlbar[actiontype="extension"] #identity-faviconinurlbar,
                    #identity-box:is(.extensionPage,.chromeUI,.unknownIdentity:not(.mixedDisplayContent,.mixedDisplayContentLoadedActiveBlocked)) #identity-faviconinurlbar {
                        display: none !important;
                    }
                    #urlbar:not(.searchButton) > #urlbar-input-container > #identity-box[pageproxystate="invalid"] #identity-icon {
                        display: none !important;
                    }
                `);
                windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET);
                var faviconinurlbar = document.createXULElement("image");
                faviconinurlbar.id = "identity-faviconinurlbar";
                identity.before(faviconinurlbar);
                gBrowser.tabContainer.addEventListener("TabAttrModified", this);
                gBrowser.addProgressListener(this);
                that.unloadlisteners.push("faviconinurlbar");
                var {STATE_START, STATE_STOP, STATE_IS_NETWORK} = Ci.nsIWebProgressListener;
                var updatefavicon = image => {
                    if (image) {
                        faviconinurlbar.style.setProperty("--v-faviconinurlbar", `url("${image}")`);
                        faviconinurlbar.setAttribute("faviconinurlbar", "true");
                        faviconinurlbar.setAttribute("faviconchrome", `${image.startsWith("chrome:")}`);
                    } else {
                        faviconinurlbar.setAttribute("faviconinurlbar", "false");
                        faviconinurlbar.style.setProperty("--v-faviconinurlbar", "");
                    }
                };
                this.handleEvent = e => {
                    var tab = e.target, changed;
                    if (!tab.selected || !((changed = e.detail.changed).includes("image") || changed.includes("selected"))) return;
                    updatefavicon(tab.image);
                };
                this.onStateChange = (aWebProgress, aRequest, aStateFlags, aStatus) => {
                    if (aStateFlags & STATE_IS_NETWORK && aWebProgress?.isTopLevel) {
                        if (aStateFlags & STATE_START)
                            faviconinurlbar.setAttribute("favbusy", "true");
                        else if (aStateFlags & STATE_STOP) {
                            faviconinurlbar.setAttribute("favbusy", "false");
                            updatefavicon(gBrowser.selectedTab.image);
                        }
                    }
                };
            },
            destructor() {
                gBrowser.tabContainer.removeEventListener("TabAttrModified", this);
                gBrowser.removeProgressListener(this);
            }
        }).init(this);

скрытый текст
______.PNG

Обновил Замена фавиконок для сайтов
Добавил замену на служебных страницах и там где вообще отсутствует иконка, кстати DOMHeadElementParsed нужен для этого


P.S. Насчет иконок, в идеале лучше использовать svg, если др. форматов то размером от 32x32 px и более

Vitaliy V. пишет

кстати DOMHeadElementParsed нужен для этого

Но в LinkWinActorChild.jsm его нет.
UPD: А, понял, по нему может сам actor создаваться.

Vitaliy V. пишет

Обновил Замена фавиконок для сайтов
Добавил замену на служебных страницах и там где вообще отсутствует иконка, кстати DOMHeadElementParsed нужен для этого


P.S. Насчет иконок, в идеале лучше использовать svg, если др. форматов то размером от 32x32 px и более

Огромное Спасибо за обнову!!! Обновился, всё везде сработало, на закладках иконки тоже обновились, и в топе сайтов.
В about:config и about:user-chrome-files тоже иконка настроек появилась. Всё отлично!

скрытый текст
______.png
Image_001.png

Обновил Добавить кнопку Пауза/Продолжить в загрузки https://forum.mozilla-russia.org/viewto … 50#p776150

Vitaliy V. пишет

Обновил Добавить кнопку Пауза/Продолжить в загрузки https://forum.mozilla-russia.org/viewto … 50#p776150

Спасибо! Тоже обновился, кнопки иконки только старые оставил.

скрытый текст
Image_002.png
Только у меню кнопки круглые, правила из твиков для каждого окна:
скрытый текст

Выделить код

Код:

@-moz-document url("chrome://browser/content/places/places.xhtml") {
.downloadButton > .button-box {
	border-radius: 16px !important;
}
}
Выделить код

Код:

@-moz-document url(chrome://browser/content/downloads/contentAreaDownloadsView.xhtml) {
.downloadButton > .button-box {
	border-radius: 16px !important;
}
}

Блин, можно же добавить перед последней скобкой в стиль правило(без адреса) из кода выше и кнопки везде будут круглыми.

Не знаю, может кому пригодится.
Разбирался сегодня с конвертацией иконок в .svg формат, для подобных скриптов и стилей. С векторным редактором Inkscape не смог разобраться.
Не сразу удалось найти нормальный онлайн-конвертер, попадались все конвертирующие в base64 что ли в обвёртке svg, но не работали в упомянутых кодах, добавлял data:image/svg+xml;utf8, перед третьей строкой, строки 1 и 2 удалял, двойные кавычки менял на одинарные - ошибка синтаксиса и не работает

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

Выделить код

Код:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 16 16" enable-background="new 0 0 16 16" xml:space="preserve">  <image id="image0" width="16" height="16" x="0" y="0"
    xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJN
AAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAABiVBMVEUAAAAAAQoAF6wAChMA
AREAwN0AAAAAAQoAZXYADC0AEagAUtkAAAAAAAAALnAABCoATcgBDGoBAwUVXdkAKLAAABcAHn4A
U+kABAkAAAAAChwACTsAH3EAfY8AQHYAC0EAN7cEAQIAABcABjQAAEQAAlYANY8AoPMARqIAABMA
F2EAG3gKGVUAu/4AUZAACA4ACBAAHH0ABiAAAAAAAAB/9vswXFYAjY4AgagAAg4AAAEAicsPW1oA
AAAAAgQAlOwASnYAhM8As/gAXbcBQowAAgkAAAAAJ0IABRQAAQIAN+MABHoAfewAh/QAH9IAovUA
Tf4ALtoAwPsAjvcN8/8A+/8cms8+n8wO2v8AIcsAOOMgvP8O/v8BUdEABHQAH84Akf8Ahf8AH+QA
rvcCqvoA3P8By/8AVn8FAzkAGZ8AEJMAJewAP9EAffYAk/oAoP0Auv8AnNsAMJ0Ao/8BqvgLU+EA
uf8A7P8AQaMCVdsA+P8o/f8A/P8U0f5V+v8A8P8Aqf0Aof/////gm21KAAAASnRSTlMASfMnMfQI
Krpm+v0GAZdk8qlA/fJM1/wUDkGDrMSrZuXybnfO+OX+vETNxer+vRhC334UF/6Tq8EwOPyXAxL9
lfD76bYaGl0yB0c23wgAAAABYktHRIKLs/9EAAAAB3RJTUUH5QcYFgUmGgEtiwAAAK5JREFUGNNj
YGBkYmZAASxerGwoAuzePhwoApxcvtw8SHxePj//AH5kAYHAoGBBZC1CwiGhIkh8UbGw8AhxCQZe
SSlpGVk5eQaFyKjomFhFJWUV1bj4hMQkBrXklNS09IzMrOyc3Dx1DU0GrfyCQm2douKS0rJyXT19
BgaDCkMjY5PKqmpTM3MLS5CpxkBsZV1TW2dji3CfnX19Q6MDkt22jk7OLq7IrnNz9/CEsACxmSFY
BCmxVAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0wNy0yNFQyMjowNTozOCswMzowMJlJCfEAAAAl
dEVYdGRhdGU6bW9kaWZ5ADIwMjEtMDctMjRUMjI6MDU6MzgrMDM6MDDoFLFNAAAAAElFTkSuQmCC" />
</svg>

Ресурс нашёл, ссылка, можно выбрать качество, выше качество - больше размер кода/файла. Размер и качество конечно уступают base64 и другим форматам.
Сконвертировал бабочку из оригинальной .ico-иконки. Ещё, как я понял в ходе экспериментов, чтоб иконка отработала в упомянутых в ссылках выше кодах, нужно заменить все двойные кавычки на одинарные. Получился готовый для использования код с максимальным качеством(Detailed)
14,6 КБ кода

Выделить код

Код:

data:image/svg+xml;utf8,<svg width='16' height='16' version='1.1' xmlns='http://www.w3.org/2000/svg'><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0' d='M 0.5 0 L 1 3.5 L 0 3.5 L 0.5 0 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0' d='M 4.5 0 L 16 0 L 16 7 L 8.5 7 L 7.5 8 L 6 6.5 L 6 3.5 L 4 0.5 L 4.5 0 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0' d='M 0.5 6 L 0.5 7 L 0.5 6 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0' d='M 15.5 10 L 16 16 L 10 15.5 L 11 13 Q 14.25 13.5 15.5 10 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0' d='M 0.5 12 Q 1.5 14 2.5 12 Q 6.25 10.75 5 14.5 L 5.5 16 L 0 16 L 0.5 12 Z '></path><path fill='rgb(0,6,17)' stroke='rgb(0,6,17)' stroke-width='1' opacity='0.17647058823529413' d='M 3.5 0 L 3.5 1 L 3.5 0 Z '></path><path fill='rgb(0,6,17)' stroke='rgb(0,6,17)' stroke-width='1' opacity='0.17647058823529413' d='M 1.5 1 L 2 2.5 L 1 2.5 L 1.5 1 Z '></path><path fill='rgb(0,6,17)' stroke='rgb(0,6,17)' stroke-width='1' opacity='0.17647058823529413' d='M 13.5 11 L 13.5 12 L 13.5 11 Z '></path><path fill='rgb(0,6,17)' stroke='rgb(0,6,17)' stroke-width='1' opacity='0.17647058823529413' d='M 8.5 15 L 8.5 16 L 8.5 15 Z '></path><path fill='rgb(0,131,215)' stroke='rgb(0,131,215)' stroke-width='1' opacity='0.9764705882352941' d='M 6.5 12 L 6.5 13 L 6.5 12 Z '></path><path fill='rgb(0,131,215)' stroke='rgb(0,131,215)' stroke-width='1' opacity='0.9764705882352941' d='M 6.5 14 L 6.5 15 L 6.5 14 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.00392156862745098' d='M 0.5 4 L 1 5.5 L 0 5.5 L 0.5 4 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.00392156862745098' d='M 8.5 7 L 8.5 8 L 8.5 7 Z '></path><path fill='rgb(0,51,115)' stroke='rgb(0,51,115)' stroke-width='1' opacity='0.615686274509804' d='M 1.5 4 L 1.5 5 L 1.5 4 Z '></path><path fill='rgb(0,51,115)' stroke='rgb(0,51,115)' stroke-width='1' opacity='0.615686274509804' d='M 12.5 7 L 12.5 8 L 12.5 7 Z '></path><path fill='rgb(0,51,115)' stroke='rgb(0,51,115)' stroke-width='1' opacity='0.615686274509804' d='M 14.5 7 L 14.5 8 L 14.5 7 Z '></path><path fill='rgb(0,51,115)' stroke='rgb(0,51,115)' stroke-width='1' opacity='0.615686274509804' d='M 10.5 13 L 10.5 14 L 10.5 13 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 3.5 4 L 3.5 5 L 3.5 4 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 13.5 9 L 13.5 10 L 13.5 9 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 1.5 10 L 1.5 11 L 1.5 10 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 3.5 10 L 3.5 11 L 3.5 10 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 6.5 13 L 6.5 14 L 6.5 13 Z '></path><path fill='rgb(0,159,243)' stroke='rgb(0,159,243)' stroke-width='1' opacity='0.996078431372549' d='M 9.5 13 L 9.5 14 L 9.5 13 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 1.5 3 L 1.5 4 L 1.5 3 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 5.5 4 L 5.5 5 L 5.5 4 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 11.5 7 L 11.5 8 L 11.5 7 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 15.5 7 L 15.5 8 L 15.5 7 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 8.5 8 L 8.5 9 L 8.5 8 Z '></path><path fill='rgb(0,14,55)' stroke='rgb(0,14,55)' stroke-width='1' opacity='0.4196078431372549' d='M 7.5 15 L 7.5 16 L 7.5 15 Z '></path><path fill='rgb(1,2,7)' stroke='rgb(1,2,7)' stroke-width='1' opacity='0.25098039215686274' d='M 1.5 0 L 1.5 1 L 1.5 0 Z '></path><path fill='rgb(1,2,7)' stroke='rgb(1,2,7)' stroke-width='1' opacity='0.25098039215686274' d='M 1.5 6 L 1.5 7 L 1.5 6 Z '></path><path fill='rgb(1,2,7)' stroke='rgb(1,2,7)' stroke-width='1' opacity='0.25098039215686274' d='M 5.5 12 L 5.5 13 L 5.5 12 Z '></path><path fill='rgb(23,250,255)' stroke='rgb(23,250,255)' stroke-width='1' opacity='1' d='M 4.5 8 L 4.5 9 L 4.5 8 Z '></path><path fill='rgb(23,250,255)' stroke='rgb(23,250,255)' stroke-width='1' opacity='1' d='M 8.5 11 L 8.5 12 L 8.5 11 Z '></path><path fill='rgb(45,156,205)' stroke='rgb(45,156,205)' stroke-width='1' opacity='1' d='M 2.5 7 L 4 7.5 L 2.5 8 L 2.5 7 Z '></path><path fill='rgb(4,82,221)' stroke='rgb(4,82,221)' stroke-width='1' opacity='0.9882352941176471' d='M 4.5 3 L 5 4.5 L 4 4.5 L 4.5 3 Z '></path><path fill='rgb(4,82,221)' stroke='rgb(4,82,221)' stroke-width='1' opacity='0.9882352941176471' d='M 1.5 5 Q 4 6 2.5 7 Q 0 6 1.5 5 Z '></path><path fill='rgb(4,82,221)' stroke='rgb(4,82,221)' stroke-width='1' opacity='0.9882352941176471' d='M 5.5 7 L 6 8.5 L 5 8.5 L 5.5 7 Z '></path><path fill='rgb(4,82,221)' stroke='rgb(4,82,221)' stroke-width='1' opacity='0.9882352941176471' d='M 9.5 10 L 9.5 11 L 9.5 10 Z '></path><path fill='rgb(4,82,221)' stroke='rgb(4,82,221)' stroke-width='1' opacity='0.9882352941176471' d='M 6.5 11 L 6.5 12 L 6.5 11 Z '></path><path fill='rgb(0,11,25)' stroke='rgb(0,11,25)' stroke-width='1' opacity='0.2549019607843137' d='M 10.5 7 L 10.5 8 L 10.5 7 Z '></path><path fill='rgb(0,11,25)' stroke='rgb(0,11,25)' stroke-width='1' opacity='0.2549019607843137' d='M 0.5 11 L 0.5 12 L 0.5 11 Z '></path><path fill='rgb(0,15,98)' stroke='rgb(0,15,98)' stroke-width='1' opacity='0.7607843137254902' d='M 5.5 5 L 5.5 6 L 5.5 5 Z '></path><path fill='rgb(0,15,98)' stroke='rgb(0,15,98)' stroke-width='1' opacity='0.7607843137254902' d='M 9.5 8 L 9.5 9 L 9.5 8 Z '></path><path fill='rgb(0,15,98)' stroke='rgb(0,15,98)' stroke-width='1' opacity='0.7607843137254902' d='M 0.5 10 L 0.5 11 L 0.5 10 Z '></path><path fill='rgb(0,15,98)' stroke='rgb(0,15,98)' stroke-width='1' opacity='0.7607843137254902' d='M 4.5 10 L 4.5 11 L 4.5 10 Z '></path><path fill='rgb(0,87,137)' stroke='rgb(0,87,137)' stroke-width='1' opacity='0.7098039215686275' d='M 4.5 2 L 4.5 3 L 4.5 2 Z '></path><path fill='rgb(0,87,137)' stroke='rgb(0,87,137)' stroke-width='1' opacity='0.7098039215686275' d='M 14.5 9 Q 16 10 13.5 11 Q 12 10 14.5 9 Z '></path><path fill='rgb(0,87,137)' stroke='rgb(0,87,137)' stroke-width='1' opacity='0.7098039215686275' d='M 11.5 11 L 11.5 12 L 11.5 11 Z '></path><path fill='rgb(0,87,137)' stroke='rgb(0,87,137)' stroke-width='1' opacity='0.7098039215686275' d='M 9.5 14 L 9.5 15 L 9.5 14 Z '></path><path fill='rgb(0,47,180)' stroke='rgb(0,47,180)' stroke-width='1' opacity='0.9215686274509803' d='M 5.5 6 L 5.5 7 L 5.5 6 Z '></path><path fill='rgb(0,47,180)' stroke='rgb(0,47,180)' stroke-width='1' opacity='0.9215686274509803' d='M 0.5 8 L 0.5 9 L 0.5 8 Z '></path><path fill='rgb(0,47,180)' stroke='rgb(0,47,180)' stroke-width='1' opacity='0.9215686274509803' d='M 8.5 14 L 8.5 15 L 8.5 14 Z '></path><path fill='rgb(0,37,131)' stroke='rgb(0,37,131)' stroke-width='1' opacity='0.8705882352941177' d='M 1.5 7 L 1.5 8 L 1.5 7 Z '></path><path fill='rgb(0,37,131)' stroke='rgb(0,37,131)' stroke-width='1' opacity='0.8705882352941177' d='M 0.5 9 L 0.5 10 L 0.5 9 Z '></path><path fill='rgb(0,37,131)' stroke='rgb(0,37,131)' stroke-width='1' opacity='0.8705882352941177' d='M 2.5 11 L 2.5 12 L 2.5 11 Z '></path><path fill='rgb(0,170,250)' stroke='rgb(0,170,250)' stroke-width='1' opacity='0.996078431372549' d='M 1.5 9 L 3 9.5 L 1.5 10 L 1.5 9 Z '></path><path fill='rgb(0,170,250)' stroke='rgb(0,170,250)' stroke-width='1' opacity='0.996078431372549' d='M 7.5 10 L 9 10.5 L 7.5 11 L 7.5 10 Z '></path><path fill='rgb(0,170,250)' stroke='rgb(0,170,250)' stroke-width='1' opacity='0.996078431372549' d='M 8.5 13 Q 10 14 7.5 15 Q 6 14 8.5 13 Z '></path><path fill='rgb(5,213,255)' stroke='rgb(5,213,255)' stroke-width='1' opacity='1' d='M 4.5 7 L 4.5 8 L 4.5 7 Z '></path><path fill='rgb(5,213,255)' stroke='rgb(5,213,255)' stroke-width='1' opacity='1' d='M 3.5 9 L 5 9.5 L 3.5 10 L 3.5 9 Z '></path><path fill='rgb(0,86,127)' stroke='rgb(0,86,127)' stroke-width='1' opacity='1' d='M 5.5 9 L 5.5 10 L 5.5 9 Z '></path><path fill='rgb(0,20,161)' stroke='rgb(0,20,161)' stroke-width='1' opacity='0.9803921568627451' d='M 2.5 0 L 2.5 1 L 2.5 0 Z '></path><path fill='rgb(0,20,161)' stroke='rgb(0,20,161)' stroke-width='1' opacity='0.9803921568627451' d='M 2.5 3 L 2.5 4 L 2.5 3 Z '></path><path fill='rgb(0,20,161)' stroke='rgb(0,20,161)' stroke-width='1' opacity='0.9803921568627451' d='M 7.5 9 L 9 9.5 L 7.5 10 L 7.5 9 Z '></path><path fill='rgb(3,6,77)' stroke='rgb(3,6,77)' stroke-width='1' opacity='0.9725490196078431' d='M 2.5 2 L 2.5 3 L 2.5 2 Z '></path><path fill='rgb(3,6,77)' stroke='rgb(3,6,77)' stroke-width='1' opacity='0.9725490196078431' d='M 6.5 8 L 7 9.5 Q 6 12 5 10.5 L 6.5 8 Z '></path><path fill='rgb(3,6,77)' stroke='rgb(3,6,77)' stroke-width='1' opacity='0.9725490196078431' d='M 10.5 8 L 12 8.5 L 10.5 9 L 10.5 8 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 2.5 1 L 2.5 2 L 2.5 1 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 2.5 4 L 3 5.5 L 2 5.5 L 2.5 4 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 1.5 8 L 3 8.5 L 1.5 9 L 1.5 8 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 12.5 8 L 12.5 9 L 12.5 8 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 15.5 8 L 15.5 9 L 15.5 8 Z '></path><path fill='rgb(0,42,218)' stroke='rgb(0,42,218)' stroke-width='1' opacity='1' d='M 9.5 9 L 11 9.5 L 9.5 10 L 9.5 9 Z '></path><path fill='rgb(0,139,247)' stroke='rgb(0,139,247)' stroke-width='1' opacity='0.996078431372549' d='M 3.5 2 L 4 3.5 L 3 3.5 L 3.5 2 Z '></path><path fill='rgb(0,139,247)' stroke='rgb(0,139,247)' stroke-width='1' opacity='0.996078431372549' d='M 4.5 5 L 4.5 6 L 4.5 5 Z '></path><path fill='rgb(0,139,247)' stroke='rgb(0,139,247)' stroke-width='1' opacity='0.996078431372549' d='M 13.5 8 L 15 8.5 L 11.5 10 L 11.5 9 L 13.5 8 Z '></path><path fill='rgb(0,187,253)' stroke='rgb(0,187,253)' stroke-width='1' opacity='0.996078431372549' d='M 3.5 5 L 3.5 6 L 3.5 5 Z '></path><path fill='rgb(0,187,253)' stroke='rgb(0,187,253)' stroke-width='1' opacity='0.996078431372549' d='M 2.5 10 L 2.5 11 L 2.5 10 Z '></path><path fill='rgb(0,187,253)' stroke='rgb(0,187,253)' stroke-width='1' opacity='0.996078431372549' d='M 10.5 10 L 10.5 11 L 10.5 10 Z '></path><path fill='rgb(0,187,253)' stroke='rgb(0,187,253)' stroke-width='1' opacity='0.996078431372549' d='M 12.5 10 L 12.5 11 L 12.5 10 Z '></path><path fill='rgb(0,10,21)' stroke='rgb(0,10,21)' stroke-width='1' opacity='0.09411764705882353' d='M 14.5 10 L 14.5 11 L 14.5 10 Z '></path><path fill='rgb(0,0,22)' stroke='rgb(0,0,22)' stroke-width='1' opacity='0.32941176470588235' d='M 0.5 7 L 0.5 8 L 0.5 7 Z '></path><path fill='rgb(0,0,22)' stroke='rgb(0,0,22)' stroke-width='1' opacity='0.32941176470588235' d='M 7.5 8 L 7.5 9 L 7.5 8 Z '></path><path fill='rgb(0,0,22)' stroke='rgb(0,0,22)' stroke-width='1' opacity='0.32941176470588235' d='M 15.5 9 L 15.5 10 L 15.5 9 Z '></path><path fill='rgb(0,56,160)' stroke='rgb(0,56,160)' stroke-width='1' opacity='1' d='M 6.5 10 L 6.5 11 L 6.5 10 Z '></path><path fill='rgb(0,56,160)' stroke='rgb(0,56,160)' stroke-width='1' opacity='1' d='M 1.5 11 L 1.5 12 L 1.5 11 Z '></path><path fill='rgb(0,6,32)' stroke='rgb(0,6,32)' stroke-width='1' opacity='0.49411764705882355' d='M 3.5 11 L 3.5 12 L 3.5 11 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.08627450980392157' d='M 4.5 11 L 6 11.5 L 4.5 12 L 4.5 11 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.08627450980392157' d='M 1.5 12 L 1.5 13 L 1.5 12 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.08627450980392157' d='M 6.5 15 L 6.5 16 L 6.5 15 Z '></path><path fill='rgb(1,245,255)' stroke='rgb(1,245,255)' stroke-width='1' opacity='1' d='M 3.5 6 L 5 6.5 L 3.5 7 L 3.5 6 Z '></path><path fill='rgb(1,245,255)' stroke='rgb(1,245,255)' stroke-width='1' opacity='1' d='M 11.5 10 L 11.5 11 L 11.5 10 Z '></path><path fill='rgb(1,245,255)' stroke='rgb(1,245,255)' stroke-width='1' opacity='1' d='M 7.5 11 L 8 13.5 L 7 13.5 L 7.5 11 Z '></path><path fill='rgb(106,248,253)' stroke='rgb(106,248,253)' stroke-width='1' opacity='0.996078431372549' d='M 9.5 11 L 10 12.5 L 9 12.5 L 9.5 11 Z '></path><path fill='rgb(26,198,254)' stroke='rgb(26,198,254)' stroke-width='1' opacity='1' d='M 3.5 8 L 3.5 9 L 3.5 8 Z '></path><path fill='rgb(26,198,254)' stroke='rgb(26,198,254)' stroke-width='1' opacity='1' d='M 8.5 12 L 8.5 13 L 8.5 12 Z '></path><path fill='rgb(31,92,88)' stroke='rgb(31,92,88)' stroke-width='1' opacity='0.5843137254901961' d='M 10.5 11 L 11 12.5 L 10 12.5 L 10.5 11 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.03137254901960784' d='M 4.5 1 L 4.5 2 L 4.5 1 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.03137254901960784' d='M 5.5 3 L 5.5 4 L 5.5 3 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.03137254901960784' d='M 9.5 7 L 9.5 8 L 9.5 7 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.03137254901960784' d='M 12.5 12 L 12.5 13 L 12.5 12 Z '></path><path fill='rgb(0,25,25)' stroke='rgb(0,25,25)' stroke-width='1' opacity='0.047058823529411764' d='M 9.5 15 L 9.5 16 L 9.5 15 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.011764705882352941' d='M 11.5 12 L 11.5 13 L 11.5 12 Z '></path><path fill='rgb(0,0,0)' stroke='rgb(0,0,0)' stroke-width='1' opacity='0.011764705882352941' d='M 5.5 14 L 5.5 15 L 5.5 14 Z '></path><path fill='rgb(0,192,221)' stroke='rgb(0,192,221)' stroke-width='1' opacity='0.9568627450980393' d='M 3.5 1 L 3.5 2 L 3.5 1 Z '></path><path fill='rgb(0,116,165)' stroke='rgb(0,116,165)' stroke-width='1' opacity='0.8117647058823529' d='M 13.5 7 L 13.5 8 L 13.5 7 Z '></path><path fill='rgb(0,116,165)' stroke='rgb(0,116,165)' stroke-width='1' opacity='0.8117647058823529' d='M 12.5 11 L 12.5 12 L 12.5 11 Z '></path><path fill='rgb(0,10,10)' stroke='rgb(0,10,10)' stroke-width='1' opacity='0.09019607843137255' d='M 6.5 7 L 6.5 8 L 6.5 7 Z '></path><path fill='rgb(0,10,10)' stroke='rgb(0,10,10)' stroke-width='1' opacity='0.09019607843137255' d='M 5.5 13 L 5.5 14 L 5.5 13 Z '></path><path fill='rgb(0,10,10)' stroke='rgb(0,10,10)' stroke-width='1' opacity='0.09019607843137255' d='M 10.5 14 L 10.5 15 L 10.5 14 Z '></path></svg>

В общем буду использовать иконки в base64.


Ага, у них есть ещё оптимизатор, прогнал через него и файл уменьшился до 3,5КБ, а качество вроде бы и не пострадало. Это уже внушает оптимизм, можно дальше экспериментировать.


Нет, оптимизированный код выдал ошибку

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

Выделить код

Код:

data:image/svg+xml;utf8,<svg width='16' height='16' xmlns='http://www.w3.org/2000/svg'><path fill='#050919' stroke='#050919' opacity='.176' d='M3.5 0v1-1zM1.5 1L2 2.5H1L1.5 1zM13.5 11v1-1zM8.5 15v1-1z'/><path fill='#367BDC' stroke='#367BDC' opacity='.969' d='M6.5 14v1-1z'/><path stroke='#000' opacity='.004' d='M.5 4L1 5.5H0L.5 4zM8.5 7v1-1z'/><path fill='#1B3672' stroke='#1B3672' opacity='.627' d='M1.5 4v1-1zM12.5 7v1-1zM14.5 7v1-1zM10.5 13v1-1z'/><path fill='#3F9CF8' stroke='#3F9CF8' opacity='.996' d='M3.5 4v1-1zM13.5 9v1-1zM1.5 10v1-1zM7.5 10v1-1zM9.5 13v1-1z'/><path fill='#080E3A' stroke='#080E3A' opacity='.42' d='M1.5 3v1-1zM5.5 4v1-1zM11.5 7v1-1zM15.5 7v1-1zM8.5 8v1-1zM3.5 11v1-1zM7.5 15v1-1z'/><path fill='#02030A' stroke='#02030A' opacity='.251' d='M1.5 0v1-1zM1.5 6v1-1zM5.5 12v1-1z'/><path fill='#4DEFFE' stroke='#4DEFFE' d='M3.5 6v1-1zM11.5 10v1-1zM7.5 13v1-1z'/><path fill='#3F94CE' stroke='#3F94CE' opacity='.996' d='M2.5 7l1.5.5-1.5.5V7zM3.5 10v1-1zM6.5 12v1-1z'/><path fill='#3349DC' stroke='#3349DC' opacity='.988' d='M4.5 3L5 4.5H4L4.5 3zM1.5 5q2.5 1 1 2-2.5-1-1-2zM5.5 7L6 8.5H5L5.5 7zM10.5 9q1.5 1-1 2-1.5-1 1-2zM6.5 11v1-1z'/><path fill='#02051F' stroke='#02051F' opacity='.325' d='M.5 7v1-1zM7.5 8v1-1z'/><path fill='#150B62' stroke='#150B62' opacity='.761' d='M5.5 5v1-1zM9.5 8v1-1zM.5 10v1-1zM4.5 10v1-1z'/><path fill='#245A8B' stroke='#245A8B' opacity='.718' d='M4.5 2v1-1zM14.5 9q1.5 1-1 2-1.5-1 1-2zM11.5 11v1-1zM9.5 14v1-1z'/><path fill='#2726B1' stroke='#2726B1' opacity='.922' d='M5.5 6v1-1zM.5 8v1-1zM8.5 14v1-1z'/><path fill='#1D2182' stroke='#1D2182' opacity='.871' d='M1.5 7v1-1zM.5 9v1-1zM2.5 11v1-1z'/><path fill='#41A6F9' stroke='#41A6F9' opacity='.996' d='M1.5 9l1.5.5-1.5.5V9zM8.5 10v1-1zM8.5 13q1.5 1-1 2-1.5-1 1-2z'/><path fill='#4AD9FE' stroke='#4AD9FE' d='M4.5 7v1-1zM3.5 9v1-1z'/><path fill='#21557E' stroke='#21557E' d='M5.5 9v1-1z'/><path fill='#2600B2' stroke='#2600B2' opacity='.988' d='M2.5 0v1-1zM2.5 3L3 4.5H2L2.5 3zM1.5 8v1-1zM12.5 8v1-1zM7.5 9l1.5.5-1.5.5V9z'/><path fill='#15055D' stroke='#15055D' opacity='.976' d='M2.5 2v1-1zM10.5 8l1.5.5-1.5.5V8zM6.5 9q1.5 1-1 2-1.5-1 1-2z'/><path fill='#301ADF' stroke='#301ADF' d='M2.5 1v1-1zM2.5 5v1-1zM2.5 8v1-1zM15.5 8v1-1zM9.5 9v1-1z'/><path fill='#3C85F6' stroke='#3C85F6' opacity='.996' d='M3.5 2L4 3.5H3L3.5 2zM4.5 5v1-1zM13.5 8l1.5.5-3.5 1.5V9l2-1zM6.5 13v1-1z'/><path fill='#45B8FD' stroke='#45B8FD' opacity='.996' d='M3.5 5v1-1zM3.5 8v1-1zM2.5 10v1-1zM10.5 10v1-1zM12.5 10v1-1z'/><path fill='#051C21' stroke='#051C21' opacity='.059' d='M14.5 10v1-1zM9.5 15v1-1z'/><path fill='#030718' stroke='#030718' opacity='.263' d='M10.5 7v1-1zM15.5 9v1-1zM.5 11v1-1z'/><path fill='#24349E' stroke='#24349E' d='M6.5 10v1-1zM1.5 11v1-1z'/><path fill='#050414' stroke='#050414' opacity='.722' d='M6.5 8v1-1z'/><path stroke='#000' opacity='.086' d='M4.5 11l1.5.5-1.5.5v-1zM1.5 12v1-1zM6.5 15v1-1z'/><path fill='#51FCFE' stroke='#51FCFE' d='M4.5 6v1-1zM4.5 8v1-1zM7 11l2 .5q-1 2.5-2 1V11z'/><path fill='#7DF8FC' stroke='#7DF8FC' opacity='.996' d='M9.5 11l.5 1.5H9l.5-1.5z'/><path fill='#49CBFD' stroke='#49CBFD' d='M4.5 9v1-1zM8.5 12v1-1z'/><path fill='#2E5C58' stroke='#2E5C58' opacity='.584' d='M10.5 11l.5 1.5h-1l.5-1.5z'/><path stroke='#000' opacity='.031' d='M4.5 1v1-1zM5.5 3v1-1zM9.5 7v1-1zM12.5 12v1-1z'/><path fill='#0D0D13' stroke='#0D0D13' opacity='.075' d='M6.5 7v1-1zM5.5 13v1-1z'/><path stroke='#000' opacity='.012' d='M11.5 12v1-1zM5.5 14v1-1z'/><path fill='#40BEDB' stroke='#40BEDB' opacity='.957' d='M3.5 1v1-1z'/><path fill='#2B71A2' stroke='#2B71A2' opacity='.812' d='M13.5 7v1-1zM12.5 11v1-1z'/><path fill='#090913' stroke='#090913' opacity='.102' d='M10.5 14v1-1z'/></svg>

sandro79 пишет

Нет, оптимизированный код выдал ошибку

Так у вас повтор здесь ... </svg><svg width='16' height='16' xmlns='http://www.w3.org/2000/svg'> ...
и цвета нужно перевести в rgb(a) или заменить # на %23

А вообще конечно всякие там конверторы из растра в SVG ерунда полная, да и зачем иконок SVG тоже полно.
В крайнем случае можно конвертнуть из др. вектора в SVG, там качество не пострадает ну или не так сильно.

Vitaliy V. пишет

Так у вас повтор здесь ... ...
и цвета нужно перевести в rgb или заменить # на %23

Ну это, тот, что под первым спойлером в оптимизированном варианте, бабочка ихняя. В rgb(a) пока не пробовал, достаточно трудоёмкая для меня задача, заменил пакетно # на %23, всё-равно ошибку даёт. Может после %23 пробел должен быть, тоже пробовал, не прошло.

А вообще конечно всякие там конверторы из растра в SVG ерунда полная, да и зачем иконок SVG тоже полно

Да это верно, но хоть что-то, если не знаешь сам как и что делать. Да хотелось именно оригинальную иконку бабочки перегнать в svg. Зациклило меня на решении этой задачи.

В крайнем случае можно конвертнуть из др. вектора в SVG

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

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

Выделить код

Код:

<svg width="16" height="16" version="1.1" xmlns="http://www.w3.org/2000/svg"><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0" d="M 0.5 0 L 1 3.5 L 0 3.5 L 0.5 0 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0" d="M 4.5 0 L 16 0 L 16 7 L 8.5 7 L 7.5 8 L 6 6.5 L 6 3.5 L 4 0.5 L 4.5 0 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0" d="M 0.5 6 L 0.5 7 L 0.5 6 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0" d="M 15.5 10 L 16 16 L 10 15.5 L 11 13 Q 14.25 13.5 15.5 10 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0" d="M 0.5 12 Q 1.5 14 2.5 12 Q 6.25 10.75 5 14.5 L 5.5 16 L 0 16 L 0.5 12 Z "></path><path fill="rgb(5,9,25)" stroke="rgb(5,9,25)" stroke-width="1" opacity="0.17647058823529413" d="M 3.5 0 L 3.5 1 L 3.5 0 Z "></path><path fill="rgb(5,9,25)" stroke="rgb(5,9,25)" stroke-width="1" opacity="0.17647058823529413" d="M 1.5 1 L 2 2.5 L 1 2.5 L 1.5 1 Z "></path><path fill="rgb(5,9,25)" stroke="rgb(5,9,25)" stroke-width="1" opacity="0.17647058823529413" d="M 13.5 11 L 13.5 12 L 13.5 11 Z "></path><path fill="rgb(5,9,25)" stroke="rgb(5,9,25)" stroke-width="1" opacity="0.17647058823529413" d="M 8.5 15 L 8.5 16 L 8.5 15 Z "></path><path fill="rgb(54,123,220)" stroke="rgb(54,123,220)" stroke-width="1" opacity="0.9686274509803922" d="M 6.5 14 L 6.5 15 L 6.5 14 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.00392156862745098" d="M 0.5 4 L 1 5.5 L 0 5.5 L 0.5 4 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.00392156862745098" d="M 8.5 7 L 8.5 8 L 8.5 7 Z "></path><path fill="rgb(27,54,114)" stroke="rgb(27,54,114)" stroke-width="1" opacity="0.6274509803921569" d="M 1.5 4 L 1.5 5 L 1.5 4 Z "></path><path fill="rgb(27,54,114)" stroke="rgb(27,54,114)" stroke-width="1" opacity="0.6274509803921569" d="M 12.5 7 L 12.5 8 L 12.5 7 Z "></path><path fill="rgb(27,54,114)" stroke="rgb(27,54,114)" stroke-width="1" opacity="0.6274509803921569" d="M 14.5 7 L 14.5 8 L 14.5 7 Z "></path><path fill="rgb(27,54,114)" stroke="rgb(27,54,114)" stroke-width="1" opacity="0.6274509803921569" d="M 10.5 13 L 10.5 14 L 10.5 13 Z "></path><path fill="rgb(63,156,248)" stroke="rgb(63,156,248)" stroke-width="1" opacity="0.996078431372549" d="M 3.5 4 L 3.5 5 L 3.5 4 Z "></path><path fill="rgb(63,156,248)" stroke="rgb(63,156,248)" stroke-width="1" opacity="0.996078431372549" d="M 13.5 9 L 13.5 10 L 13.5 9 Z "></path><path fill="rgb(63,156,248)" stroke="rgb(63,156,248)" stroke-width="1" opacity="0.996078431372549" d="M 1.5 10 L 1.5 11 L 1.5 10 Z "></path><path fill="rgb(63,156,248)" stroke="rgb(63,156,248)" stroke-width="1" opacity="0.996078431372549" d="M 7.5 10 L 7.5 11 L 7.5 10 Z "></path><path fill="rgb(63,156,248)" stroke="rgb(63,156,248)" stroke-width="1" opacity="0.996078431372549" d="M 9.5 13 L 9.5 14 L 9.5 13 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 1.5 3 L 1.5 4 L 1.5 3 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 5.5 4 L 5.5 5 L 5.5 4 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 11.5 7 L 11.5 8 L 11.5 7 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 15.5 7 L 15.5 8 L 15.5 7 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 8.5 8 L 8.5 9 L 8.5 8 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 3.5 11 L 3.5 12 L 3.5 11 Z "></path><path fill="rgb(8,14,58)" stroke="rgb(8,14,58)" stroke-width="1" opacity="0.4196078431372549" d="M 7.5 15 L 7.5 16 L 7.5 15 Z "></path><path fill="rgb(2,3,10)" stroke="rgb(2,3,10)" stroke-width="1" opacity="0.25098039215686274" d="M 1.5 0 L 1.5 1 L 1.5 0 Z "></path><path fill="rgb(2,3,10)" stroke="rgb(2,3,10)" stroke-width="1" opacity="0.25098039215686274" d="M 1.5 6 L 1.5 7 L 1.5 6 Z "></path><path fill="rgb(2,3,10)" stroke="rgb(2,3,10)" stroke-width="1" opacity="0.25098039215686274" d="M 5.5 12 L 5.5 13 L 5.5 12 Z "></path><path fill="rgb(77,239,254)" stroke="rgb(77,239,254)" stroke-width="1" opacity="1" d="M 3.5 6 L 3.5 7 L 3.5 6 Z "></path><path fill="rgb(77,239,254)" stroke="rgb(77,239,254)" stroke-width="1" opacity="1" d="M 11.5 10 L 11.5 11 L 11.5 10 Z "></path><path fill="rgb(77,239,254)" stroke="rgb(77,239,254)" stroke-width="1" opacity="1" d="M 7.5 13 L 7.5 14 L 7.5 13 Z "></path><path fill="rgb(63,148,206)" stroke="rgb(63,148,206)" stroke-width="1" opacity="0.996078431372549" d="M 2.5 7 L 4 7.5 L 2.5 8 L 2.5 7 Z "></path><path fill="rgb(63,148,206)" stroke="rgb(63,148,206)" stroke-width="1" opacity="0.996078431372549" d="M 3.5 10 L 3.5 11 L 3.5 10 Z "></path><path fill="rgb(63,148,206)" stroke="rgb(63,148,206)" stroke-width="1" opacity="0.996078431372549" d="M 6.5 12 L 6.5 13 L 6.5 12 Z "></path><path fill="rgb(51,73,220)" stroke="rgb(51,73,220)" stroke-width="1" opacity="0.9882352941176471" d="M 4.5 3 L 5 4.5 L 4 4.5 L 4.5 3 Z "></path><path fill="rgb(51,73,220)" stroke="rgb(51,73,220)" stroke-width="1" opacity="0.9882352941176471" d="M 1.5 5 Q 4 6 2.5 7 Q 0 6 1.5 5 Z "></path><path fill="rgb(51,73,220)" stroke="rgb(51,73,220)" stroke-width="1" opacity="0.9882352941176471" d="M 5.5 7 L 6 8.5 L 5 8.5 L 5.5 7 Z "></path><path fill="rgb(51,73,220)" stroke="rgb(51,73,220)" stroke-width="1" opacity="0.9882352941176471" d="M 10.5 9 Q 12 10 9.5 11 Q 8 10 10.5 9 Z "></path><path fill="rgb(51,73,220)" stroke="rgb(51,73,220)" stroke-width="1" opacity="0.9882352941176471" d="M 6.5 11 L 6.5 12 L 6.5 11 Z "></path><path fill="rgb(2,5,31)" stroke="rgb(2,5,31)" stroke-width="1" opacity="0.3254901960784314" d="M 0.5 7 L 0.5 8 L 0.5 7 Z "></path><path fill="rgb(2,5,31)" stroke="rgb(2,5,31)" stroke-width="1" opacity="0.3254901960784314" d="M 7.5 8 L 7.5 9 L 7.5 8 Z "></path><path fill="rgb(21,11,98)" stroke="rgb(21,11,98)" stroke-width="1" opacity="0.7607843137254902" d="M 5.5 5 L 5.5 6 L 5.5 5 Z "></path><path fill="rgb(21,11,98)" stroke="rgb(21,11,98)" stroke-width="1" opacity="0.7607843137254902" d="M 9.5 8 L 9.5 9 L 9.5 8 Z "></path><path fill="rgb(21,11,98)" stroke="rgb(21,11,98)" stroke-width="1" opacity="0.7607843137254902" d="M 0.5 10 L 0.5 11 L 0.5 10 Z "></path><path fill="rgb(21,11,98)" stroke="rgb(21,11,98)" stroke-width="1" opacity="0.7607843137254902" d="M 4.5 10 L 4.5 11 L 4.5 10 Z "></path><path fill="rgb(36,90,139)" stroke="rgb(36,90,139)" stroke-width="1" opacity="0.7176470588235294" d="M 4.5 2 L 4.5 3 L 4.5 2 Z "></path><path fill="rgb(36,90,139)" stroke="rgb(36,90,139)" stroke-width="1" opacity="0.7176470588235294" d="M 14.5 9 Q 16 10 13.5 11 Q 12 10 14.5 9 Z "></path><path fill="rgb(36,90,139)" stroke="rgb(36,90,139)" stroke-width="1" opacity="0.7176470588235294" d="M 11.5 11 L 11.5 12 L 11.5 11 Z "></path><path fill="rgb(36,90,139)" stroke="rgb(36,90,139)" stroke-width="1" opacity="0.7176470588235294" d="M 9.5 14 L 9.5 15 L 9.5 14 Z "></path><path fill="rgb(39,38,177)" stroke="rgb(39,38,177)" stroke-width="1" opacity="0.9215686274509803" d="M 5.5 6 L 5.5 7 L 5.5 6 Z "></path><path fill="rgb(39,38,177)" stroke="rgb(39,38,177)" stroke-width="1" opacity="0.9215686274509803" d="M 0.5 8 L 0.5 9 L 0.5 8 Z "></path><path fill="rgb(39,38,177)" stroke="rgb(39,38,177)" stroke-width="1" opacity="0.9215686274509803" d="M 8.5 14 L 8.5 15 L 8.5 14 Z "></path><path fill="rgb(29,33,130)" stroke="rgb(29,33,130)" stroke-width="1" opacity="0.8705882352941177" d="M 1.5 7 L 1.5 8 L 1.5 7 Z "></path><path fill="rgb(29,33,130)" stroke="rgb(29,33,130)" stroke-width="1" opacity="0.8705882352941177" d="M 0.5 9 L 0.5 10 L 0.5 9 Z "></path><path fill="rgb(29,33,130)" stroke="rgb(29,33,130)" stroke-width="1" opacity="0.8705882352941177" d="M 2.5 11 L 2.5 12 L 2.5 11 Z "></path><path fill="rgb(65,166,249)" stroke="rgb(65,166,249)" stroke-width="1" opacity="0.996078431372549" d="M 1.5 9 L 3 9.5 L 1.5 10 L 1.5 9 Z "></path><path fill="rgb(65,166,249)" stroke="rgb(65,166,249)" stroke-width="1" opacity="0.996078431372549" d="M 8.5 10 L 8.5 11 L 8.5 10 Z "></path><path fill="rgb(65,166,249)" stroke="rgb(65,166,249)" stroke-width="1" opacity="0.996078431372549" d="M 8.5 13 Q 10 14 7.5 15 Q 6 14 8.5 13 Z "></path><path fill="rgb(74,217,254)" stroke="rgb(74,217,254)" stroke-width="1" opacity="1" d="M 4.5 7 L 4.5 8 L 4.5 7 Z "></path><path fill="rgb(74,217,254)" stroke="rgb(74,217,254)" stroke-width="1" opacity="1" d="M 3.5 9 L 3.5 10 L 3.5 9 Z "></path><path fill="rgb(33,85,126)" stroke="rgb(33,85,126)" stroke-width="1" opacity="1" d="M 5.5 9 L 5.5 10 L 5.5 9 Z "></path><path fill="rgb(38,0,178)" stroke="rgb(38,0,178)" stroke-width="1" opacity="0.9882352941176471" d="M 2.5 0 L 2.5 1 L 2.5 0 Z "></path><path fill="rgb(38,0,178)" stroke="rgb(38,0,178)" stroke-width="1" opacity="0.9882352941176471" d="M 2.5 3 L 3 4.5 L 2 4.5 L 2.5 3 Z "></path><path fill="rgb(38,0,178)" stroke="rgb(38,0,178)" stroke-width="1" opacity="0.9882352941176471" d="M 1.5 8 L 1.5 9 L 1.5 8 Z "></path><path fill="rgb(38,0,178)" stroke="rgb(38,0,178)" stroke-width="1" opacity="0.9882352941176471" d="M 12.5 8 L 12.5 9 L 12.5 8 Z "></path><path fill="rgb(38,0,178)" stroke="rgb(38,0,178)" stroke-width="1" opacity="0.9882352941176471" d="M 7.5 9 L 9 9.5 L 7.5 10 L 7.5 9 Z "></path><path fill="rgb(21,5,93)" stroke="rgb(21,5,93)" stroke-width="1" opacity="0.9764705882352941" d="M 2.5 2 L 2.5 3 L 2.5 2 Z "></path><path fill="rgb(21,5,93)" stroke="rgb(21,5,93)" stroke-width="1" opacity="0.9764705882352941" d="M 10.5 8 L 12 8.5 L 10.5 9 L 10.5 8 Z "></path><path fill="rgb(21,5,93)" stroke="rgb(21,5,93)" stroke-width="1" opacity="0.9764705882352941" d="M 6.5 9 Q 8 10 5.5 11 Q 4 10 6.5 9 Z "></path><path fill="rgb(48,26,223)" stroke="rgb(48,26,223)" stroke-width="1" opacity="1" d="M 2.5 1 L 2.5 2 L 2.5 1 Z "></path><path fill="rgb(48,26,223)" stroke="rgb(48,26,223)" stroke-width="1" opacity="1" d="M 2.5 5 L 2.5 6 L 2.5 5 Z "></path><path fill="rgb(48,26,223)" stroke="rgb(48,26,223)" stroke-width="1" opacity="1" d="M 2.5 8 L 2.5 9 L 2.5 8 Z "></path><path fill="rgb(48,26,223)" stroke="rgb(48,26,223)" stroke-width="1" opacity="1" d="M 15.5 8 L 15.5 9 L 15.5 8 Z "></path><path fill="rgb(48,26,223)" stroke="rgb(48,26,223)" stroke-width="1" opacity="1" d="M 9.5 9 L 9.5 10 L 9.5 9 Z "></path><path fill="rgb(60,133,246)" stroke="rgb(60,133,246)" stroke-width="1" opacity="0.996078431372549" d="M 3.5 2 L 4 3.5 L 3 3.5 L 3.5 2 Z "></path><path fill="rgb(60,133,246)" stroke="rgb(60,133,246)" stroke-width="1" opacity="0.996078431372549" d="M 4.5 5 L 4.5 6 L 4.5 5 Z "></path><path fill="rgb(60,133,246)" stroke="rgb(60,133,246)" stroke-width="1" opacity="0.996078431372549" d="M 13.5 8 L 15 8.5 L 11.5 10 L 11.5 9 L 13.5 8 Z "></path><path fill="rgb(60,133,246)" stroke="rgb(60,133,246)" stroke-width="1" opacity="0.996078431372549" d="M 6.5 13 L 6.5 14 L 6.5 13 Z "></path><path fill="rgb(69,184,253)" stroke="rgb(69,184,253)" stroke-width="1" opacity="0.996078431372549" d="M 3.5 5 L 3.5 6 L 3.5 5 Z "></path><path fill="rgb(69,184,253)" stroke="rgb(69,184,253)" stroke-width="1" opacity="0.996078431372549" d="M 3.5 8 L 3.5 9 L 3.5 8 Z "></path><path fill="rgb(69,184,253)" stroke="rgb(69,184,253)" stroke-width="1" opacity="0.996078431372549" d="M 2.5 10 L 2.5 11 L 2.5 10 Z "></path><path fill="rgb(69,184,253)" stroke="rgb(69,184,253)" stroke-width="1" opacity="0.996078431372549" d="M 10.5 10 L 10.5 11 L 10.5 10 Z "></path><path fill="rgb(69,184,253)" stroke="rgb(69,184,253)" stroke-width="1" opacity="0.996078431372549" d="M 12.5 10 L 12.5 11 L 12.5 10 Z "></path><path fill="rgb(5,28,33)" stroke="rgb(5,28,33)" stroke-width="1" opacity="0.058823529411764705" d="M 14.5 10 L 14.5 11 L 14.5 10 Z "></path><path fill="rgb(5,28,33)" stroke="rgb(5,28,33)" stroke-width="1" opacity="0.058823529411764705" d="M 9.5 15 L 9.5 16 L 9.5 15 Z "></path><path fill="rgb(3,7,24)" stroke="rgb(3,7,24)" stroke-width="1" opacity="0.2627450980392157" d="M 10.5 7 L 10.5 8 L 10.5 7 Z "></path><path fill="rgb(3,7,24)" stroke="rgb(3,7,24)" stroke-width="1" opacity="0.2627450980392157" d="M 15.5 9 L 15.5 10 L 15.5 9 Z "></path><path fill="rgb(3,7,24)" stroke="rgb(3,7,24)" stroke-width="1" opacity="0.2627450980392157" d="M 0.5 11 L 0.5 12 L 0.5 11 Z "></path><path fill="rgb(36,52,158)" stroke="rgb(36,52,158)" stroke-width="1" opacity="1" d="M 6.5 10 L 6.5 11 L 6.5 10 Z "></path><path fill="rgb(36,52,158)" stroke="rgb(36,52,158)" stroke-width="1" opacity="1" d="M 1.5 11 L 1.5 12 L 1.5 11 Z "></path><path fill="rgb(5,4,20)" stroke="rgb(5,4,20)" stroke-width="1" opacity="0.7215686274509804" d="M 6.5 8 L 6.5 9 L 6.5 8 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.08627450980392157" d="M 4.5 11 L 6 11.5 L 4.5 12 L 4.5 11 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.08627450980392157" d="M 1.5 12 L 1.5 13 L 1.5 12 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.08627450980392157" d="M 6.5 15 L 6.5 16 L 6.5 15 Z "></path><path fill="rgb(81,252,254)" stroke="rgb(81,252,254)" stroke-width="1" opacity="1" d="M 4.5 6 L 4.5 7 L 4.5 6 Z "></path><path fill="rgb(81,252,254)" stroke="rgb(81,252,254)" stroke-width="1" opacity="1" d="M 4.5 8 L 4.5 9 L 4.5 8 Z "></path><path fill="rgb(81,252,254)" stroke="rgb(81,252,254)" stroke-width="1" opacity="1" d="M 7 11 L 9 11.5 Q 8 14 7 12.5 L 7 11 Z "></path><path fill="rgb(125,248,252)" stroke="rgb(125,248,252)" stroke-width="1" opacity="0.996078431372549" d="M 9.5 11 L 10 12.5 L 9 12.5 L 9.5 11 Z "></path><path fill="rgb(73,203,253)" stroke="rgb(73,203,253)" stroke-width="1" opacity="1" d="M 4.5 9 L 4.5 10 L 4.5 9 Z "></path><path fill="rgb(73,203,253)" stroke="rgb(73,203,253)" stroke-width="1" opacity="1" d="M 8.5 12 L 8.5 13 L 8.5 12 Z "></path><path fill="rgb(46,92,88)" stroke="rgb(46,92,88)" stroke-width="1" opacity="0.5843137254901961" d="M 10.5 11 L 11 12.5 L 10 12.5 L 10.5 11 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.03137254901960784" d="M 4.5 1 L 4.5 2 L 4.5 1 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.03137254901960784" d="M 5.5 3 L 5.5 4 L 5.5 3 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.03137254901960784" d="M 9.5 7 L 9.5 8 L 9.5 7 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.03137254901960784" d="M 12.5 12 L 12.5 13 L 12.5 12 Z "></path><path fill="rgb(13,13,19)" stroke="rgb(13,13,19)" stroke-width="1" opacity="0.07450980392156863" d="M 6.5 7 L 6.5 8 L 6.5 7 Z "></path><path fill="rgb(13,13,19)" stroke="rgb(13,13,19)" stroke-width="1" opacity="0.07450980392156863" d="M 5.5 13 L 5.5 14 L 5.5 13 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.011764705882352941" d="M 11.5 12 L 11.5 13 L 11.5 12 Z "></path><path fill="rgb(0,0,0)" stroke="rgb(0,0,0)" stroke-width="1" opacity="0.011764705882352941" d="M 5.5 14 L 5.5 15 L 5.5 14 Z "></path><path fill="rgb(64,190,219)" stroke="rgb(64,190,219)" stroke-width="1" opacity="0.9568627450980393" d="M 3.5 1 L 3.5 2 L 3.5 1 Z "></path><path fill="rgb(43,113,162)" stroke="rgb(43,113,162)" stroke-width="1" opacity="0.8117647058823529" d="M 13.5 7 L 13.5 8 L 13.5 7 Z "></path><path fill="rgb(43,113,162)" stroke="rgb(43,113,162)" stroke-width="1" opacity="0.8117647058823529" d="M 12.5 11 L 12.5 12 L 12.5 11 Z "></path><path fill="rgb(9,9,19)" stroke="rgb(9,9,19)" stroke-width="1" opacity="0.10196078431372549" d="M 10.5 14 L 10.5 15 L 10.5 14 Z "></path></svg>

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

Выделить код

Код:

<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path fill="#050919" stroke="#050919" opacity=".176" d="M3.5 0v1-1zM1.5 1L2 2.5H1L1.5 1zM13.5 11v1-1zM8.5 15v1-1z"/><path fill="#367BDC" stroke="#367BDC" opacity=".969" d="M6.5 14v1-1z"/><path stroke="#000" opacity=".004" d="M.5 4L1 5.5H0L.5 4zM8.5 7v1-1z"/><path fill="#1B3672" stroke="#1B3672" opacity=".627" d="M1.5 4v1-1zM12.5 7v1-1zM14.5 7v1-1zM10.5 13v1-1z"/><path fill="#3F9CF8" stroke="#3F9CF8" opacity=".996" d="M3.5 4v1-1zM13.5 9v1-1zM1.5 10v1-1zM7.5 10v1-1zM9.5 13v1-1z"/><path fill="#080E3A" stroke="#080E3A" opacity=".42" d="M1.5 3v1-1zM5.5 4v1-1zM11.5 7v1-1zM15.5 7v1-1zM8.5 8v1-1zM3.5 11v1-1zM7.5 15v1-1z"/><path fill="#02030A" stroke="#02030A" opacity=".251" d="M1.5 0v1-1zM1.5 6v1-1zM5.5 12v1-1z"/><path fill="#4DEFFE" stroke="#4DEFFE" d="M3.5 6v1-1zM11.5 10v1-1zM7.5 13v1-1z"/><path fill="#3F94CE" stroke="#3F94CE" opacity=".996" d="M2.5 7l1.5.5-1.5.5V7zM3.5 10v1-1zM6.5 12v1-1z"/><path fill="#3349DC" stroke="#3349DC" opacity=".988" d="M4.5 3L5 4.5H4L4.5 3zM1.5 5q2.5 1 1 2-2.5-1-1-2zM5.5 7L6 8.5H5L5.5 7zM10.5 9q1.5 1-1 2-1.5-1 1-2zM6.5 11v1-1z"/><path fill="#02051F" stroke="#02051F" opacity=".325" d="M.5 7v1-1zM7.5 8v1-1z"/><path fill="#150B62" stroke="#150B62" opacity=".761" d="M5.5 5v1-1zM9.5 8v1-1zM.5 10v1-1zM4.5 10v1-1z"/><path fill="#245A8B" stroke="#245A8B" opacity=".718" d="M4.5 2v1-1zM14.5 9q1.5 1-1 2-1.5-1 1-2zM11.5 11v1-1zM9.5 14v1-1z"/><path fill="#2726B1" stroke="#2726B1" opacity=".922" d="M5.5 6v1-1zM.5 8v1-1zM8.5 14v1-1z"/><path fill="#1D2182" stroke="#1D2182" opacity=".871" d="M1.5 7v1-1zM.5 9v1-1zM2.5 11v1-1z"/><path fill="#41A6F9" stroke="#41A6F9" opacity=".996" d="M1.5 9l1.5.5-1.5.5V9zM8.5 10v1-1zM8.5 13q1.5 1-1 2-1.5-1 1-2z"/><path fill="#4AD9FE" stroke="#4AD9FE" d="M4.5 7v1-1zM3.5 9v1-1z"/><path fill="#21557E" stroke="#21557E" d="M5.5 9v1-1z"/><path fill="#2600B2" stroke="#2600B2" opacity=".988" d="M2.5 0v1-1zM2.5 3L3 4.5H2L2.5 3zM1.5 8v1-1zM12.5 8v1-1zM7.5 9l1.5.5-1.5.5V9z"/><path fill="#15055D" stroke="#15055D" opacity=".976" d="M2.5 2v1-1zM10.5 8l1.5.5-1.5.5V8zM6.5 9q1.5 1-1 2-1.5-1 1-2z"/><path fill="#301ADF" stroke="#301ADF" d="M2.5 1v1-1zM2.5 5v1-1zM2.5 8v1-1zM15.5 8v1-1zM9.5 9v1-1z"/><path fill="#3C85F6" stroke="#3C85F6" opacity=".996" d="M3.5 2L4 3.5H3L3.5 2zM4.5 5v1-1zM13.5 8l1.5.5-3.5 1.5V9l2-1zM6.5 13v1-1z"/><path fill="#45B8FD" stroke="#45B8FD" opacity=".996" d="M3.5 5v1-1zM3.5 8v1-1zM2.5 10v1-1zM10.5 10v1-1zM12.5 10v1-1z"/><path fill="#051C21" stroke="#051C21" opacity=".059" d="M14.5 10v1-1zM9.5 15v1-1z"/><path fill="#030718" stroke="#030718" opacity=".263" d="M10.5 7v1-1zM15.5 9v1-1zM.5 11v1-1z"/><path fill="#24349E" stroke="#24349E" d="M6.5 10v1-1zM1.5 11v1-1z"/><path fill="#050414" stroke="#050414" opacity=".722" d="M6.5 8v1-1z"/><path stroke="#000" opacity=".086" d="M4.5 11l1.5.5-1.5.5v-1zM1.5 12v1-1zM6.5 15v1-1z"/><path fill="#51FCFE" stroke="#51FCFE" d="M4.5 6v1-1zM4.5 8v1-1zM7 11l2 .5q-1 2.5-2 1V11z"/><path fill="#7DF8FC" stroke="#7DF8FC" opacity=".996" d="M9.5 11l.5 1.5H9l.5-1.5z"/><path fill="#49CBFD" stroke="#49CBFD" d="M4.5 9v1-1zM8.5 12v1-1z"/><path fill="#2E5C58" stroke="#2E5C58" opacity=".584" d="M10.5 11l.5 1.5h-1l.5-1.5z"/><path stroke="#000" opacity=".031" d="M4.5 1v1-1zM5.5 3v1-1zM9.5 7v1-1zM12.5 12v1-1z"/><path fill="#0D0D13" stroke="#0D0D13" opacity=".075" d="M6.5 7v1-1zM5.5 13v1-1z"/><path stroke="#000" opacity=".012" d="M11.5 12v1-1zM5.5 14v1-1z"/><path fill="#40BEDB" stroke="#40BEDB" opacity=".957" d="M3.5 1v1-1z"/><path fill="#2B71A2" stroke="#2B71A2" opacity=".812" d="M13.5 7v1-1zM12.5 11v1-1z"/><path fill="#090913" stroke="#090913" opacity=".102" d="M10.5 14v1-1z"/></svg>

sandro79 пишет

Да хотелось именно оригинальную иконку бабочки перегнать в svg. Зациклило меня на решении этой задачи.

Не помню уже откуда взял, но завалялась у меня эта бабочка в PNG, размером 170px на 170px.
Я попробовал поиграться с конвертором, однако без потери качества перегнать не удалось.
Попробуйте, может у вас что-то получится.
nnm-club-02.png

sandro79 пишет

Ну это, тот, что под первым спойлером в оптимизированном варианте

Под первым у вас вообще то png в обертке SVG, а там где 14,6 КБ кода, нет повтора как в последнем
Вот ещё раз, здесь заканчивается svg тег
...<path fill='#000A0A' stroke='#000A0A' opacity='.09' d='M6.5 7v1-1zM5.5 13v1-1zM10.5 14v1-1z'/></svg>
а дальше опять начинается
<svg width='16' height='16' xmlns='http://www.w3.org/2000/svg'>...
ну это видимо вы вставили два раза в этот пост?

sandro79 пишет

Вы имеете в виду из первого большого кода конвертнуть в нормальном неонлайн-редакторе?

Нет никаким редактором не получится нормально конвертировать растровое изображение в векторное SVG
разве что потом вручную подправлять и то если они простые и не слишком фотографические.
Почитайте в чем отличие вектора от растра, в векторе нельзя создать фото, зато его можно масштабировать как угодно без потери качества.
Я имел ввиду можно без проблем перевести векторные изображения (они кроме SVG бывают и в других форматах - EPS, AI и т.д.) в SVG

unter_officer пишет

Попробуйте, может у вас что-то получится.

Спасибо! Тоже пригодится, буду экспериментировать.

Vitaliy V. пишет

Под первым у вас вообще то png в обертке SVG, а там где 14,6 КБ кода, нет повтора как в последнем

Да-да, имелся в виду 14,6 КБ. Про тот забыл уже.

Вот ещё раз, здесь заканчивается svg тег... а дальше опять начинается

Да, точно, вот же ж, два раза вставил.

Нет никаким редактором не получится нормально конвертировать растровое изображение в векторное SVG...

Да-да, я так уже поверхностно понимаю суть, тут ещё вы говорили. Надо будет так, хоть в общем, ознакомится с этой темой. Огромное Спасибо за разъяснение.


Подправил тот код под третьим спойлером, убрал дубляж, хоть и не работает, но так, для порядка.

Vitaliy V.
Ну проясните пожалуйста один момент. Решил обновить кнопку вкл/откл звука на вкладке/вкладках на вариант из add_toolbar_buttons. Взял код этой кнопки из parent.js, внёс правки, добавил код иконки из sound.svg, всё работает, но только иконка не меняет цвет на белый на тёмном фоне, как в add_toolbar_buttons. Нужно внести ещё какие-то правки, но вот какие и возможно ли это в скрипте, не знаю. Можно использовать конечно старую иконку, она всегда белая. Вот как бы эту чёрную заставить менять цвет на тёмном фоне?

Новый код кнопки с новой иконкой
Image_001.png

Выделить код

Код:

try {
	CustomizableUI.createWidget({
		id: "b-sound-muted-all-tabs",
		type: "custom",
		label: "Переключить звук",
		tooltiptext: "ЛКМ: Переключить звук в выделенных вкладках\nСКМ: Закрыть другие вкладки с источником звука\nПКМ: Переключить звук во всех вкладках",
		defaultArea: CustomizableUI.AREA_NAVBAR,
		localized: false,
		onBuild(doc) {
			var trbn = doc.createXULElement("toolbarbutton"),
			win = doc.defaultView;
			trbn.id = "b-sound-muted-all-tabs";
			trbn.className = "toolbarbutton-1 chromeclass-toolbar-additional";
			trbn.setAttribute("label", "Переключить звук");
			trbn.setAttribute("tooltiptext", "ЛКМ: Переключить звук в выделенных вкладках\nСКМ: Закрыть другие вкладки с источником звука\nПКМ: Переключить звук во всех вкладках");
			trbn.setAttribute("context", false);
			trbn.setAttribute("image", "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 48 48'><g style='fill:context-fill;fill-opacity:context-fill-opacity;'><path d='M 22.5,4.49 15,12 H 10.5 C 6,12 3,16.5 3,21 L 3,27 C 3,31.5 5.99,36 10.5,36 H 15 L 22.5,43.5 C 24.9,45.9 27,45 27,43.5 V 4.49 C 27,2.99 24.9,2.09 22.5,4.49 Z'/><path d='M 39,24 C 39,19 35,15 30,15 28,15 28,18 30,18 33.3,18 36,20.7 36,24 36,27.3 33.3,30 30,30 28,30 28,33 30,33 35,33 39,29 39,24 Z'/><path d='M 30,9 C 28,9 28,12 30,12 36.6,12 42,17.4 42,24 42,30.6 36.6,36 30,36 28,36 28,39 30,39 38.4,39 45,32.4 45,24 45,15.6 38.4,9 30,9 Z'/></g></svg>");
			trbn.addEventListener("click", e => {
				if (e.button == 0) {
					win.gBrowser.toggleMuteAudioOnMultiSelectedTabs(win.gBrowser.selectedTab);
				} else if (e.button == 1) {
					for (let tab of win.gBrowser.visibleTabs.filter(tab => !tab.selected && (tab.muted || tab.soundPlaying)))
						win.gBrowser.removeTab(tab);
				} else if (e.button == 2) {
					e.preventDefault();
					e.stopPropagation();
					let tabsToToggle;
					if (win.gBrowser.selectedTab.activeMediaBlocked) {
						tabsToToggle = win.gBrowser.visibleTabs.filter(tab => tab.activeMediaBlocked || tab.linkedBrowser.audioMuted);
					} else {
						let tabMuted = win.gBrowser.selectedTab.linkedBrowser.audioMuted;
						tabsToToggle = win.gBrowser.visibleTabs.filter(tab => (tab.linkedBrowser.audioMuted == tabMuted && !tab.activeMediaBlocked) || (tab.activeMediaBlocked && tabMuted));
					}
					for (let tab of tabsToToggle)
						tab.toggleMuteAudio();
				}
			});
			return trbn;
		},
	});
} catch(e) {}

Вообще думаю использовать иконку, находящуюся по адресу chrome://global/skin/media/audio.svg
скрытый текст

Выделить код

Код:

data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' width='16' height='16' fill='context-fill' fill-opacity='context-fill-opacity'><path d='M7.245 1.35 4.117 5 2 5a2 2 0 0 0-2 2l0 2a2 2 0 0 0 2 2l2.117 0 3.128 3.65C7.848 15.353 9 14.927 9 14L9 2c0-.927-1.152-1.353-1.755-.65z'/><path d='M11.764 15a.623.623 0 0 1-.32-1.162 6.783 6.783 0 0 0 3.306-5.805 6.767 6.767 0 0 0-3.409-5.864.624.624 0 1 1 .619-1.085A8.015 8.015 0 0 1 16 8.033a8.038 8.038 0 0 1-3.918 6.879c-.1.06-.21.088-.318.088z'/><path d='M11.434 11.85A4.982 4.982 0 0 0 13.25 8a4.982 4.982 0 0 0-1.819-3.852l-.431 0 0 7.702.434 0z'/></svg>

sandro79 пишет

Вот как бы эту чёрную заставить менять цвет на тёмном фоне?

для иконок загруженных по data: -moz-context-properties не работает
если не включить svg.context-properties.content.enabled - true

sandro79 пишет

Вообще думаю использовать иконку, находящуюся по адресу chrome://global/skin/media/audio.svg

Ну так и впишите этот адрес вместо data: ...
Или как вариант добавить файл .svg в user_chrome_files
chrome://user_chrome_files/content/далее путь к иконке

Vitaliy V. пишет

если не включить svg.context-properties.content.enabled - true

Да, это пробовал. Но почему-то, как и с вариантом chrome://user_chrome_files/content/далее путь к иконке, иконка краснеет.
Ага, всё, разобрался, нашёл причину, так тоже работает нормально.

Ну так и впишите этот адрес вместо data: ...

Да, вот это сработало как надо. Да надо было сразу так сделать и проверить, зациклило меня, чтоб внутрь скрипта иконку встроить.
Спасибо за подсказку, это самый оптимальный вариант. В данном варианте svg.context-properties.content.enabled, как и с вариантом chrome://user_chrome_files/content/ - можно не включать

скрытый текст
Image_002.png

Выделить код

Код:

try {
	CustomizableUI.createWidget({
		id: "b-sound-muted-all-tabs",
		type: "custom",
		label: "Переключить звук",
		tooltiptext: "ЛКМ: Переключить звук в выделенных вкладках\nСКМ: Закрыть другие вкладки с источником звука\nПКМ: Переключить звук во всех вкладках",
		defaultArea: CustomizableUI.AREA_NAVBAR,
		localized: false,
		onBuild(doc) {
			var trbn = doc.createXULElement("toolbarbutton"),
			win = doc.defaultView;
			trbn.id = "b-sound-muted-all-tabs";
			trbn.className = "toolbarbutton-1 chromeclass-toolbar-additional";
			trbn.setAttribute("label", "Переключить звук");
			trbn.setAttribute("tooltiptext", "ЛКМ: Переключить звук в выделенных вкладках\nСКМ: Закрыть другие вкладки с источником звука\nПКМ: Переключить звук во всех вкладках");
			trbn.setAttribute("context", false);
			trbn.setAttribute("image", "chrome://global/skin/media/audio.svg");
			trbn.addEventListener("click", e => {
				if (e.button == 0) {
					win.gBrowser.toggleMuteAudioOnMultiSelectedTabs(win.gBrowser.selectedTab);
				} else if (e.button == 1) {
					for (let tab of win.gBrowser.visibleTabs.filter(tab => !tab.selected && (tab.muted || tab.soundPlaying)))
						win.gBrowser.removeTab(tab);
				} else if (e.button == 2) {
					e.preventDefault();
					e.stopPropagation();
					let tabsToToggle;
					if (win.gBrowser.selectedTab.activeMediaBlocked) {
						tabsToToggle = win.gBrowser.visibleTabs.filter(tab => tab.activeMediaBlocked || tab.linkedBrowser.audioMuted);
					} else {
						let tabMuted = win.gBrowser.selectedTab.linkedBrowser.audioMuted;
						tabsToToggle = win.gBrowser.visibleTabs.filter(tab => (tab.linkedBrowser.audioMuted == tabMuted && !tab.activeMediaBlocked) || (tab.activeMediaBlocked && tabMuted));
					}
					for (let tab of tabsToToggle)
						tab.toggleMuteAudio();
				}
			});
			return trbn;
		},
	});
} catch(e) {}


Наткнулся недавно на вроде бы полезный скрипт. Исправляет контекстное меню журнала.
Можно использовать с 11-ой строки, подключив в custom_script_win.js

Было|Cтало
Image_001.pngImage_002.png

ПАРОЛИ/КУКИ
https://forum.mozilla-russia.org/viewto … 86#p788786

FindBar для custom_script_all_win.js в секцию load
https://forum.mozilla-russia.org/viewto … 27#p777227

Код для CB, но отлично работает в ucf и в новых версиях FF
Если раскомментировать /* */ , то искомое будет на всех вкладках, а не только на исходной.

Туда же горячая клавиша для FindBar

Выделить код

Код:

addEventListener('keydown', e=> {
  if(e.ctrlKey&e.code=="KeyF"&&!gFindBar.hidden) {
    e.preventDefault()+gFindBar.close()
  }
});

Dumby
Поправь, пожалуйста, кнопку HTTP Request Logger для UCF.

rubel

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

Выделить код

Код:

(async self => CustomizableUI.createWidget(({
	label: "Unnamed",
	tooltiptext: "Unnamed",
	fileName: "http-request-log.txt",
	images: {
		true: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP/AwMD/AAAA/wAAAP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ==",
		false: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP/AwMD/AAAA/wAAAP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AACsQQAArEEAAKxBH/isQR/4rEEf+KxBH/isQR/4rEEf+KxBH/isQR/4rEEf+KxBH/isQQAArEEAAKxBAACsQQ=="
	},
	id: "ucf-httpRequestLogger",
	localized: false,
	init(pref) {
		var topic = "http-on-modify-request";
		this.toggle = () => Services.prefs.setBoolPref(pref, !this.active);
		var prefObs = () => {
			var val = Services.prefs.getBoolPref(pref, false);
			if (this.active ^ (this.active = val))
				Services.obs[`${val ? "add" : "remove"}Observer`](this, topic);
			this.setBtnsState();
		}
		prefObs();
		Services.prefs.addObserver(pref, prefObs);
		Services.obs.addObserver(function quit(s, t) {
			Services.obs.removeObserver(quit, t);
			Services.prefs.removeObserver(pref, prefObs);
			self.active && Services.obs.removeObserver(self, topic);
		}, "quit-application-granted");
		return self = this;
	},
	onCreated(btn) {
		btn._handleClick = this.toggle;
		btn.setAttribute("image", this.images[this.active]);
	},
	setBtnsState() {this.setBtnsState = () => {
		var img = this.images[this.active];
		var widget = CustomizableUI.getWidget(this.id);
		for(var win of CustomizableUI.windows)
			widget.forWindow(win).node?.setAttribute("image", img);
	}},
	log: "",
	observe(channel) {
		if (!(channel instanceof Ci.nsIHttpChannel)) return;
		this.log += `${
			channel.referrerInfo?.originalReferrer?.spec || "(none)"
		} ${
			channel.requestMethod 
		} ${
			channel.URI.spec
		}\r\n`;

		this.busy || this.write();
	},
	write() {
		var file = Services.dirsvc.get("Desk", Ci.nsIFile);
		file.append(this.fileName);
		var {path} = file;

		var {IOUtils} = Cu.getGlobalForObject(Cu);
		var modes = [{mode: "create"}, {mode: "append"}];
		var unbusy = () => {
			this.busy = false;
			this.log && this.write();
		}
		(this.write = () => {
			this.busy = true;
			var {log} = this;
			this.log = "";
			IOUtils.writeUTF8(path, log, modes[+file.exists()])
				.finally(unbusy);
		})();
	}
}).init("ucf.httpRequestLogger.enabled")))();

Dumby пишет

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

Выделить код

Код:

(async self => CustomizableUI.createWidget(({
	label: "Unnamed",
	tooltiptext: "Unnamed",
	fileName: "http-request-log.txt",
	images: {
		true: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/wAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/Zv+Z/2b/mf9m/5n/AAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP/AwMD/AAAA/wAAAP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ==",
		false: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/AwMD/AAAA/wAAAP/AwMD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wMDA/wAAAP8AAAD/wMDA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8DAwP8AAAD/AAAA/8DAwP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP/AwMD/AAAA/wAAAP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/8DAwP/AwMD/wMDA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AACsQQAArEEAAKxBH/isQR/4rEEf+KxBH/isQR/4rEEf+KxBH/isQR/4rEEf+KxBH/isQQAArEEAAKxBAACsQQ=="
	},
	id: "ucf-httpRequestLogger",
	localized: false,
	init(pref) {
		var topic = "http-on-modify-request";
		this.toggle = () => Services.prefs.setBoolPref(pref, !this.active);
		var prefObs = () => {
			var val = Services.prefs.getBoolPref(pref, false);
			if (this.active ^ (this.active = val))
				Services.obs[`${val ? "add" : "remove"}Observer`](this, topic);
			this.setBtnsState();
		}
		prefObs();
		Services.prefs.addObserver(pref, prefObs);
		Services.obs.addObserver(function quit(s, t) {
			Services.obs.removeObserver(quit, t);
			Services.prefs.removeObserver(pref, prefObs);
			self.active && Services.obs.removeObserver(self, topic);
		}, "quit-application-granted");
		return self = this;
	},
	onCreated(btn) {
		btn._handleClick = this.toggle;
		btn.setAttribute("image", this.images[this.active]);
	},
	setBtnsState() {this.setBtnsState = () => {
		var img = this.images[this.active];
		var widget = CustomizableUI.getWidget(this.id);
		for(var win of CustomizableUI.windows)
			widget.forWindow(win).node?.setAttribute("image", img);
	}},
	log: "",
	observe(channel) {
		if (!(channel instanceof Ci.nsIHttpChannel)) return;
		this.log += `${
			channel.referrerInfo?.originalReferrer?.spec || "(none)"
		} ${
			channel.requestMethod 
		} ${
			channel.URI.spec
		}\r\n`;

		this.busy || this.write();
	},
	write() {
		var file = Services.dirsvc.get("Desk", Ci.nsIFile);
		file.append(this.fileName);
		var {path} = file;

		var {IOUtils} = Cu.getGlobalForObject(Cu);
		var modes = [{mode: "create"}, {mode: "append"}];
		var unbusy = () => {
			this.busy = false;
			this.log && this.write();
		}
		(this.write = () => {
			this.busy = true;
			var {log} = this;
			this.log = "";
			IOUtils.writeUTF8(path, log, modes[+file.exists()])
				.finally(unbusy);
		})();
	}
}).init("ucf.httpRequestLogger.enabled")))();

Dumby, большое спасибо.

Dumby
Спасибо, прекрасно работает. :)

unter_officer, rubel
Парни, в какой custom_script, win или all_win его прописывать? И название должно быть ucf_httpRequestLogger?

добавлено   чорд возьми, нашел его в персонализации :dumb:

Новая версия UserChromeFiles со многими изменениями в коде, готова к использованию насколько могу судить,
но обновляться нужно осторожно и прочитав обновленную инструкцию,
из известных проблем, слетят ранее добавленные кнопки с панелей UserChromeFiles, если кому лень как мне лезть в персонализацию,
можно попробовать в консоле браузера выполнить код

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

Выделить код

Код:

var uiCustomization = "browser.uiCustomization.state";
Services.prefs.setCharPref(uiCustomization, Services.prefs.getCharPref(uiCustomization, "").replace(/"add-/g, "\"ucf-"));


врядли это затронет другие кнопки хоть и вероятность есть, или при закрытом браузере отредактируйте
настройку "browser.uiCustomization.state" в prefs.js заменив "add- на "ucf-


PS: Да и коды для загрузки доп. файлов скриптов теперь не требуются ...

Vitaliy V.
А с этим как... https://forum.mozilla-russia.org/viewto … 01#p788301 ?

kokoss
Для окна браузера - Включить скрипты: чекбокс "Для докум. окна браузера [ChromeOnly]"
и в CustomStylesScripts.jsm добавить в массив load: [ // По событию load    или domload: [ // По событию DOMContentLoaded
нужные вам скрипты, как видите здесь уже добавленны в закомментированном виде Special Widgets и Auto Hide Sidebar

скрытый текст
    scriptschrome: { // Для докум. окна браузера [ChromeOnly]
        domload: [ // По событию DOMContentLoaded

        ],
        load: [ // По событию load
            // { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets
            // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar
        ],
    },

Да и параметр ucfobj должен быть true для моих скриптов (если не указано), и false или отсутствовать для других (если автором скрипта не указано обратное)

PS: custom_script_win.js и custom_script_all_win.js не нужно подключать в CustomStylesScripts.jsm
только в интерфейсе настроек включить "Для докум. окна браузера [ChromeOnly]" или "Для докум. всех окон [ChromeOnly]" соответственно
эти файлы не переименовывать и не удалять.
А custom_script.js можно раскомментировать в CustomStylesScripts.jsm ну или удалить или добавить с другим именем.


И кстати коды загрузчиков скриптов для custom_script_win.js custom_script_all_win.js также будут работать можете использовать их если нравится

Vitaliy V. пишет

Для окна браузера - Включить скрипты: чекбокс "Для докум. окна браузера [ChromeOnly]"
и в CustomStylesScripts.jsm добавить в массив load: [ // По событию load    или domload: [ // По событию DOMContentLoaded
нужные вам скрипты, как видите здесь уже добавленны в закомментированном виде Special Widgets и Auto Hide Sidebar
скрытый текст

Да и параметр ucfobj должен быть true для моих скриптов (если не указано), и false или отсутствовать для других (если автором скрипта не указано обратное)

PS: custom_script_win.js и custom_script_all_win.js не нужно подключать в CustomStylesScripts.jsm
только в интерфейсе настроек включить "Для докум. окна браузера [ChromeOnly]" или "Для докум. всех окон [ChromeOnly]" соответственно
эти файлы не переименовывать и не удалять.
А custom_script.js можно раскомментировать в CustomStylesScripts.jsm ну или удалить или добавить с другим именем

Пока не ясно как это работает, но надеюсь разберусь :)


Vitaliy V. пишет

И кстати коды загрузчиков скриптов для custom_script_win.js custom_script_all_win.js также будут работать можете использовать их если нравится

Спасибо!

kokoss пишет

Пока не ясно как это работает

А что не ясно, как работает (алгоритм, непонятно объяснил) или это не работает для вас?

Vitaliy V. пишет

или это не работает для вас?

Я же не сказал что не работает, просто многовато изменений.

непонятно объяснил)

да вроде понятно, если что спрошу

kokoss пишет

просто многовато изменений

Возможностей тоже прибавилось и потому что для более новых версий [firefox], 78+ теперь
было для 52+

Vitaliy V.
Спасибо за обновлённый комплект. Почти всё сразу заработало на подопытной 92.
Возникли только проблемы со скриптами для всех окон. ucf_wheretoopenlink.js и скрипты окна загрузок у меня не получилось запустить. В настройках включены все стили и скрипты. startupCache чистил постоянно.
Прописывал в CustomStylesScripts.jsm, поочерёдно в секции: domload: [ // По событию DOMContentLoaded, в load: [ // По событию load, по аналогии { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, }, с другими именами. Запустить удалось только по-старинке с добавлением загрузчика в custom_script_all_win.js
Не знаю может чего недопонял, неправильно сделал, да вроде и вариантов не много. Хорошо бы без загрузчиков запустить, как я понял из вашего поста, это возможно. Полный код CustomStylesScripts.jsm, как изначально, ну примерно так, прописывал незапустившиеся скрипты. ucjsDownloadsManager.uc.js прописывал тоже выше ucjsDownloadsManager2.uc.js

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

Выделить код

Код:

var EXPORTED_SYMBOLS = ["UcfStylesScripts"];
var UcfStylesScripts = {
    /* ************************▼ Настройки ▼************************ */
    /**
    * Настройки стилей:
    *   path: путь к файлу от папки custom_styles
    *   type: права стиля AGENT_SHEET,  AUTHOR_SHEET или USER_SHEET
    */
    styleschrome: [ // Для докум. всех окон [ChromeOnly]
        // { path: "custom_styles_chrome_author.css", type: "AUTHOR_SHEET", sheet(f) { preloadSheet(this, f); }, },
        { path: "custom_styles_chrome_user.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, },
        { path: "special_widget.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Special Widgets
        { path: "auto_hide_sidebar.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Auto Hide Sidebar
    ],
    stylesall: [ // Для всех документов
        // { path: "custom_styles_all_agent.css", type: "AGENT_SHEET", sheet() { registerSheet(this); }, },
        // { path: "custom_styles_all_user.css", type: "USER_SHEET", sheet() { registerSheet(this); }, },
    ],
    /**
    * Настройки скриптов:
    *   path: путь к скрипту от папки custom_scripts
    *   urlregxp: Адрес где работает скрипт в регулярном выражении, только Для докум. всех окон [ChromeOnly]
    *   ucfobj: true - загружать скрипт в специально созданный объект либо в window, для скриптов В фоне [System Principal] не используется
    */
    scriptschrome: { // Для докум. окна браузера [ChromeOnly]
        domload: [ // По событию DOMContentLoaded

        ],
        load: [ // По событию load
            // { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets
            // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar
            { path: "scripts3/favicon_in_urlbar.js", ucfobj: true, },
            { path: "scripts3/restart_item_in_menu.js", ucfobj: true, },
            { path: "scripts3/urlbarhistorydropmarker.js", ucfobj: true, },
            { path: "scripts3/contextmenuopenwith.js", ucfobj: true, }, 
            { path: "scripts3/add_bookmark_to_bookmarks_menu.js", ucfobj: false, },
            { path: "scripts3/pageInfo.js", ucfobj: false, },
            { path: "scripts3/places_addBookmarks.js", ucfobj: false, },
            { path: "scripts3/search_engine_icon.js", ucfobj: false, },
            { path: "scripts3/tabs_focus.js", ucfobj: false, },
            { path: "scripts3/tabstoolbar_doubleclick_opennewtab.js", ucfobj: false, },
            { path: "scripts2/ucjsDownloadsManager.uc.js", ucfobj: false, },
        ],
    },
    scriptsallchrome: { // Для докум. всех окон [ChromeOnly]
        domload: [ // По событию DOMContentLoaded
            // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, },
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, },
            { path: "scripts2/ucjsDownloadsManager2.uc.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, },
        ],
        load: [ // По событию load
            // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, },
        ],
    },
    scriptsbackground: [ // В фоне [System Principal]
        { path: "custom_script.js", },
    ],
};
    /* ************************▲ Настройки ▲************************ */

var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var UcfSSS = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
var preloadSheet = (obj, func) => {
    try {
        let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`);
        let type = UcfSSS[obj.type];
        let preload = UcfSSS.preloadSheet(uri, type);
        (obj.sheet = f => {
            try {
                f(preload, type);
            } catch (e) {}
        })(func);
    } catch (e) {
        obj.sheet = () => {};
    }
};
var registerSheet = async obj => {
    try {
        let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`);
        let type = UcfSSS[obj.type];
        if (!UcfSSS.sheetRegistered(uri, type))
            UcfSSS.loadAndRegisterSheet(uri, type);
    } catch (e) {}
};

Окно загрузок работает частично при добавлении ucjsDownloadsManager.uc.js в секцию scriptschrome: { // Для докум. окна браузера [ChromeOnly], ну это и понятно.
Добавление второй части скрипта в эту же секцию результата не дало, ну это и было ожидаемо.

sandro79 пишет

ucf_wheretoopenlink.js

Ок добавил ещё параметр где можно указать функцию которая выполнится при загрузке скрипта
func: Функция в виде строки которая выполнится при загрузке скрипта ...


вот так это должно выглядеть для окна библиотеки

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

Выделить код

Код:

load: [ // По событию load
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.places();" },
        ],


и для CustomStylesScriptsChild.jsm если нужно в контенте
скрытый текст

Выделить код

Код:

pageshow: [ // По событию pageshow
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, func: "ucf_where_to_open_link.places();" },
        ],

sandro79 пишет

может чего недопонял, неправильно сделал

Да с чего вы взяли что ваш ucjsDownloadsManager это окно библиотеки? Там все вместе и заклади и загрузки...
Но и я накосячил с для события load, забыл передать url документа в фукцию
Однако по событию DOMContentLoaded у вас бы сработало с этим адресом

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

Выделить код

Код:

/chrome:\/\/browser\/content\/downloads\/contentAreaDownloadsView\.xhtml/

Vitaliy V. пишет

Ок добавил ещё параметр где можно указать функцию которая выполнится при загрузке скрипта

Я так понял, что это было добавлено в нижнюю секцию "Настройки", обновил в обоих файлах и обновил user_chrome.js. В окне библиотеке сработало, для CustomStylesScriptsChild.jsm не добавлял, в контенте не нужно. Но вот почему не работает из боковой панели, значка журнала на панели, журнала из панели меню, ну то есть, как я понимаю в окне браузера "Для докум. окна браузера"? Вот это самое главное, о чём я забыл упомянуть выше, что вообще нигде не работает, кроме как если добавить загрузчик в custom_script_all_win.js, хотя можно и в custom_script_win.js.

Да с чего вы взяли что ваш ucjsDownloadsManager это окно библиотеки?

Да, в ходе экспериментов я это понял, когда оставил в адресе в регулярном выражении только chrome:/ - так кажется и серипт заработал. Сейчас с вашим адресом тоже работает. Только вот с ucf_wheretoopenlink.js не могу до конца разобраться.
Код CustomStylesScripts.jsm на данный момент ниже. Добавил  { path: "scripts2/ucf_wheretoopenlink.js", ucfobj: false,  }, в секцию Для докум. окна браузера [ChromeOnly], не работает, это добавлял func: "ucf_where_to_open_link.places();", ни так ни так не идёт

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

Выделить код

Код:

var EXPORTED_SYMBOLS = ["UcfStylesScripts"];
var UcfStylesScripts = {
    /* ************************▼ Настройки ▼************************ */
    /**
    * Настройки стилей:
    *   path: путь к файлу от папки custom_styles
    *   type: права стиля AGENT_SHEET,  AUTHOR_SHEET или USER_SHEET
    */
    styleschrome: [ // Для докум. всех окон [ChromeOnly]
        // { path: "custom_styles_chrome_author.css", type: "AUTHOR_SHEET", sheet(f) { preloadSheet(this, f); }, },
        { path: "custom_styles_chrome_user.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, },
        { path: "special_widget.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Special Widgets
        { path: "auto_hide_sidebar.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Auto Hide Sidebar
    ],
    stylesall: [ // Для всех документов
        { path: "custom_styles_all_agent.css", type: "AGENT_SHEET", sheet() { registerSheet(this); }, },
        // { path: "custom_styles_all_user.css", type: "USER_SHEET", sheet() { registerSheet(this); }, },
    ],
    /**
    * Настройки скриптов:
    *   path: путь к скрипту от папки custom_scripts
    *   urlregxp: Адрес где работает скрипт в регулярном выражении, только Для докум. всех окон [ChromeOnly]
    *   ucfobj: true - загружать скрипт в специально созданный объект либо в window, для скриптов В фоне [System Principal] не используется
    *   func: Функция в виде строки которая выполнится при загрузке скрипта, только Для докум. всех окон [ChromeOnly]
    */
    scriptschrome: { // Для докум. окна браузера [ChromeOnly]
        domload: [ // По событию DOMContentLoaded

        ],
        load: [ // По событию load
            // { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets
            // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar
            { path: "scripts3/favicon_in_urlbar.js", ucfobj: true, },
            { path: "scripts3/restart_item_in_menu.js", ucfobj: true, },
            { path: "scripts3/urlbarhistorydropmarker.js", ucfobj: true, },
            { path: "scripts3/contextmenuopenwith.js", ucfobj: true, }, 
            { path: "scripts3/add_bookmark_to_bookmarks_menu.js", ucfobj: false, },
            { path: "scripts3/pageInfo.js", ucfobj: false, },
            { path: "scripts3/places_addBookmarks.js", ucfobj: false, },
            { path: "scripts3/search_engine_icon.js", ucfobj: false, },
            { path: "scripts3/tabs_focus.js", ucfobj: false, },
            { path: "scripts3/tabstoolbar_doubleclick_opennewtab.js", ucfobj: false, },
            { path: "scripts2/ucjsDownloadsManager.uc.js", ucfobj: false, },
            { path: "scripts2/ucf_wheretoopenlink.js", ucfobj: false,  },
        ],
    },
    scriptsallchrome: { // Для докум. всех окон [ChromeOnly]
        domload: [ // По событию DOMContentLoaded
            // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, },
            { path: "scripts2/ucjsDownloadsManager2.uc.js", urlregxp: /chrome:\/\/browser\/content\/downloads\/contentAreaDownloadsView\.xhtml/, ucfobj: false, },
        ],
        load: [ // По событию load
            // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, },
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.places();" },
        ],
    },
    scriptsbackground: [ // В фоне [System Principal]
        { path: "custom_script.js", },
    ],
};
    /* ************************▲ Настройки ▲************************ */

var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var UcfSSS = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
var preloadSheet = (obj, func) => {
    try {
        let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`);
        let type = UcfSSS[obj.type];
        let preload = UcfSSS.preloadSheet(uri, type);
        (obj.sheet = f => {
            try {
                f(preload, type);
            } catch (e) {}
        })(func);
    } catch (e) {
        obj.sheet = () => {};
    }
};
var registerSheet = async obj => {
    try {
        let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`);
        let type = UcfSSS[obj.type];
        if (!UcfSSS.sheetRegistered(uri, type))
            UcfSSS.loadAndRegisterSheet(uri, type);
    } catch (e) {}
};

sandro79
Вот так для браузера, но прежде обновите user_chrome.js я там поправил ещё

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

Выделить код

Код:

{ path: "scripts2/ucf_wheretoopenlink.js", ucfobj: false, func: "ucf_where_to_open_link.browser();" },


А это для других докум.
скрытый текст

Выделить код

Код:

{ path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/bookmarksSidebar\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.bookmarksSidebar();" },
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/historySidebar\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.historySidebar();" },
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.places();" },

Дело в том что нужно разные функции добавлять, а это "ucf_where_to_open_link.places();" только для библиотеки
Иначе этот скрипт пришлось бы делить на 4 части, или в скрипте снова проверять url, а так в каждом документе выполняется разный код при вызове этих функций

Vitaliy V.
Обновил user_chrome.js, пути с функциями прописал, заработало везде. Ну теперь всё в принципе настроено. Для контента тоже добавил, раз есть возможность лишним не будет.
custom_script.js с кнопками и скриптами LinkWinActor и UCFNewTabPage, сменой иконки поиковика, пока по-старинке с загрузчиком оставил. Вечером наверно тоже переподключу по-новому. Огромное Спасибо, буду тестировать.

CustomStylesScripts.jsm

Выделить код

Код:

var EXPORTED_SYMBOLS = ["UcfStylesScripts"];
var UcfStylesScripts = {
    /* ************************▼ Настройки ▼************************ */
    /**
    * Настройки стилей:
    *   path: путь к файлу от папки custom_styles
    *   type: права стиля AGENT_SHEET,  AUTHOR_SHEET или USER_SHEET
    */
    styleschrome: [ // Для докум. всех окон [ChromeOnly]
        // { path: "custom_styles_chrome_author.css", type: "AUTHOR_SHEET", sheet(f) { preloadSheet(this, f); }, },
        { path: "custom_styles_chrome_user.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, },
        { path: "special_widget.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Special Widgets
        { path: "auto_hide_sidebar.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, }, // <-- Auto Hide Sidebar
    ],
    stylesall: [ // Для всех документов
        { path: "custom_styles_all_agent.css", type: "AGENT_SHEET", sheet() { registerSheet(this); }, },
        // { path: "custom_styles_all_user.css", type: "USER_SHEET", sheet() { registerSheet(this); }, },
    ],
    /**
    * Настройки скриптов:
    *   path: путь к скрипту от папки custom_scripts
    *   urlregxp: Адрес где работает скрипт в регулярном выражении, только Для докум. всех окон [ChromeOnly]
    *   ucfobj: true - загружать скрипт в специально созданный объект либо в window, для скриптов В фоне [System Principal] не используется
    *   func: Функция в виде строки которая выполнится при загрузке скрипта, только Для докум. всех окон [ChromeOnly]
    */
    scriptschrome: { // Для докум. окна браузера [ChromeOnly]
        domload: [ // По событию DOMContentLoaded

        ],
        load: [ // По событию load
            // { path: "special_widgets.js", ucfobj: true, }, // <-- Special Widgets
            // { path: "auto_hide_sidebar.js", ucfobj: true, }, // <-- Auto Hide Sidebar
            { path: "scripts3/favicon_in_urlbar.js", ucfobj: true, },
            { path: "scripts3/restart_item_in_menu.js", ucfobj: true, },
            { path: "scripts3/urlbarhistorydropmarker.js", ucfobj: true, },
            { path: "scripts3/contextmenuopenwith.js", ucfobj: true, }, 
            { path: "scripts3/add_bookmark_to_bookmarks_menu.js", ucfobj: false, },
            { path: "scripts3/pageInfo.js", ucfobj: false, },
            { path: "scripts3/places_addBookmarks.js", ucfobj: false, },
            { path: "scripts3/search_engine_icon.js", ucfobj: false, },
            { path: "scripts3/tabs_focus.js", ucfobj: false, },
            { path: "scripts3/tabstoolbar_doubleclick_opennewtab.js", ucfobj: false, },
            { path: "scripts2/ucjsDownloadsManager.uc.js", ucfobj: false, },
            { path: "scripts2/ucf_wheretoopenlink.js", ucfobj: false, func: "ucf_where_to_open_link.browser();" },
        ],
    },
    scriptsallchrome: { // Для докум. всех окон [ChromeOnly]
        domload: [ // По событию DOMContentLoaded
            // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, },
            { path: "scripts2/ucjsDownloadsManager2.uc.js", urlregxp: /chrome:\/\/browser\/content\/downloads\/contentAreaDownloadsView\.xhtml/, ucfobj: false, },
        ],
        load: [ // По событию load
            // { path: "example_places.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, },
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.places();" },
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/bookmarksSidebar\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.bookmarksSidebar();" },
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/historySidebar\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.historySidebar();" },
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, ucfobj: false, func: "ucf_where_to_open_link.places();" },
        ],
    },
    scriptsbackground: [ // В фоне [System Principal]
        { path: "scripts/add-sound-realtek-app.js", },
        { path: "scripts/Close-Tabs-button.js", },
        { path: "scripts/downloadPauseResumeButton.js", },
        { path: "scripts/ExtensionOptionsMenu.js", },
        { path: "scripts/LinkWinActor.js", },
        { path: "scripts/PotPlayer.js", },
        { path: "scripts/To_switch_proxy.js", },
        { path: "scripts/ucf-copyURL.js", },
        { path: "scripts/UCFNewTabPage.js", },
        { path: "scripts/undo_closetab_button.js", },
        { path: "scripts/yandex@search.js", },
    ],
};
    /* ************************▲ Настройки ▲************************ */

var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var UcfSSS = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
var preloadSheet = (obj, func) => {
    try {
        let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`);
        let type = UcfSSS[obj.type];
        let preload = UcfSSS.preloadSheet(uri, type);
        (obj.sheet = f => {
            try {
                f(preload, type);
            } catch (e) {}
        })(func);
    } catch (e) {
        obj.sheet = () => {};
    }
};
var registerSheet = async obj => {
    try {
        let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`);
        let type = UcfSSS[obj.type];
        if (!UcfSSS.sheetRegistered(uri, type))
            UcfSSS.loadAndRegisterSheet(uri, type);
    } catch (e) {}
};

Переподключил скрипты scriptsbackground: [ // В фоне [System Principal] Всё подхватилось и работает. Код под спойлером обновил.


CustomStylesScriptsChild.jsm

Выделить код

Код:

var EXPORTED_SYMBOLS = ["UcfCustomStylesScriptsChild"];
var UcfStylesScripts = {
    /* ************************▼ Настройки ▼************************ */
    /**
    * Настройки стилей:
    *   path: путь к файлу от папки custom_styles
    *   type: права стиля AGENT_SHEET,  AUTHOR_SHEET или USER_SHEET
    */
    stylescontent: [
        // { path: "custom_styles_content_author.css", type: "AUTHOR_SHEET", sheet(f) { preloadSheet(this, f); }, },
        { path: "custom_styles_content_user.css", type: "USER_SHEET", sheet(f) { preloadSheet(this, f); }, },
    ],
    /**
    * Настройки скриптов:
    *   path: путь к скрипту от папки custom_scripts
    *   urlregxp: Адрес где работает скрипт, в регулярном выражении
    *   func: Функция в виде строки которая выполнится при загрузке скрипта
    */
    scriptscontent: {
        DOMWindowCreated: [ // По событию DOMWindowCreated
            // { path: "example_all_about.js", urlregxp: /about:.*/, },
        ],
        pageshow: [ // По событию pageshow
            // { path: "example_downloads.js", urlregxp: /about:downloads/, },
            { path: "scripts2/ucf_wheretoopenlink.js", urlregxp: /chrome:\/\/browser\/content\/places\/places\.xhtml/, func: "ucf_where_to_open_link.places();" },
            { path: "scripts2/ucjsDownloadsManager2.uc.js",  urlregxp: /about:downloads/, },
        ],
    },
};
    /* ************************▲ Настройки ▲************************ */
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var UcfSSS = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
var preloadSheet = async (obj, func) => {
    try {
        let uri = Services.io.newURI(`chrome://user_chrome_files/content/custom_styles/${obj.path}`);
        let type = UcfSSS[obj.type];
        let preload = await UcfSSS.preloadSheetAsync(uri, type);
        (obj.sheet = f => {
            try {
                f(preload, type);
            } catch (e) {}
        })(func);
    } catch (e) {
        obj.sheet = () => {};
    }
};
class UcfCustomStylesScriptsChild extends JSWindowActorChild {
    actorCreated() {
        var win = this.contentWindow;
        var href = this.href = win?.location.href;
        if (!href) return;
        var { addSheet } = win.windowUtils;
        for (let s of UcfStylesScripts.stylescontent)
            s.sheet(addSheet);
    }
    handleEvent(e) {
        var href = this.href;
        if (!href || href === "about:blank") return;
        for (let s of UcfStylesScripts.scriptscontent[e.type]) {
            try {
                if (s.urlregxp.test(href)) {
                    let win = this.contentWindow;
                    Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/custom_scripts/${s.path}`, win, "UTF-8");
                    if (s.func)
                        new win.Function(s.func).apply(win, null);
                }
            } catch (e) {}
        }
    }
}

Vitaliy V.
Спасибо за обновление. Уведомления пропали у этого скрипта, как их вернуть? Сейчас подключен в CustomStylesScripts.jsm, в scriptsbackground.

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

Выделить код

Код:

try {
    ((img, preventClearThumbs) => {
        CustomizableUI.createWidget({
            id: "bt-clear-part-history",
            label: "Очистить историю",
            tooltiptext: "Очистить историю",
            defaultArea: CustomizableUI.AREA_NAVBAR,
            onCreated: function(bt) {
                bt.image = img;
            },
            onCommand: function(event) {
                var win = event.target.ownerDocument.defaultView;
                var itemsToClear = [
                    "cookies",
                    "history",
                    "formdata",
                    "sessions",
                    "cache",
                 // "downloads",
                 // "offlineApps",
                 // "openWindows",
                    "pluginData",
                 // "siteSettings",
                ];
                var range = win.Sanitizer.getClearRange(0); // Диапазон очистки, 0 = все, 1,2,3 = часы, 4 = сегодня
                win.Sanitizer.sanitize(itemsToClear, {
                    ignoreTimespan: !range,
                    range,
                }).then(() => {
                    var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
                    alertsService.showAlertNotification(img, "Данные очищены!", "", false);
                    win.setTimeout(()=> alertsService.closeAlert(), 2000);
                });
            }
        });
    })("data:image/png;base64,i...", null);
} catch(e) {}


В CustomStylesScripts.jsm присутстуют раскомментированные строки:
            { path: "translatetextorpage.js", ucfobj: true, },
            { path: "contextproxy.js", ucfobj: true, },
но таких скриптов в комплекте нет.

_zt пишет

Уведомления пропали у этого скрипта, как их вернуть? ... "data:image/png;base64,i..."

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

_zt пишет

В CustomStylesScripts.jsm присутстуют раскомментированные строки:

Это я из FullTheme забыл убрать прежде чем отправить


Обновил в FullTheme файлы: common.css, CustomStylesScripts.jsm, CustomStylesScriptsChild.jsm
и в UserChromeFiles файлы: user_chrome.js, CustomStylesScripts.jsm, CustomStylesScriptsChild.jsm

Vitaliy V.

Error: Could not get children of file(...\LocalAppData\Temp\thumbnails) because it does not exist PromiseWorker.jsm:106

На старом то ucf этот скрипт уведомление выводит. Иконку я здесь из кода удалил так как много места занимает.
   
Проверил на старом ucf, уведомление есть. thumbnails отключаю уже много лет и уведомлениям это никогда не мешало, да и с удаленным browser.pagethumbnails.capturing_disabled, в этой версии ucf, уведомлений нет, а папка все равно по тому пути не создается.

_zt пишет

Error: Could not get children of file(...\LocalAppData\Temp\thumbnails) because it does not exist PromiseWorker.jsm:106

На старом то ucf этот скрипт уведомление выводит.

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

Vitaliy V. обновите пожалуйста вот эту кнопку

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

Выделить код

Код:

//Восстановить фавиконки закладок
try {
    (() => {
        var id = "ucf-loads-favicons",
        label = "Восстановить фавиконки",
        tooltiptext = "Восстановить фавиконки закладок",
        img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='32' width='16' viewBox='0 0 48 96'><g><path d='M 2.438,0 C 1.087,0 0,1.088 0,2.438 V 45.56 C 0,46.91 1.087,48 2.438,48 H 45.56 C 46.91,48 48,46.91 48,45.56 V 2.438 C 48,1.088 46.91,0 45.56,0 Z' style='fill:rgb(243, 135, 37);fill-opacity:1;' /><path style='opacity:0.25;fill:black;' d='M 14,45 17,48 H 45.5 C 47,47.9 47.9,47 48,45.5 V 17.6 L 33.9,3.5 Z'/><path style='fill:white;' d='M 15,3 C 14.4,3 14,3.4 14,4 V 45 L 24,35 34,45 V 4 C 34,3.4 33.6,3 33,3 Z' /><path d='M 2.44,48 C 1.09,48 0,49.1 0,50.4 V 93.6 C 0,94.9 1.09,96 2.44,96 H 45.6 C 46.9,96 48,94.9 48,93.6 V 50.4 C 48,49.1 46.9,48 45.6,48 Z' style='fill:rgb(209, 8, 3);fill-opacity:1;' /><path style='opacity:0.25;fill:black;' d='M 14,93 17,96 H 45.5 C 47,95.9 47.9,95 48,93.5 V 65.6 L 33.9,51.5 Z'/><path style='fill:white;' d='M 15,51 C 14.4,51 14,51.4 14,52 V 93 L 24,83 34,93 V 52 C 34,51.4 33.6,51 33,51 Z' /></g></svg>",
        alertimg = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='48' width='48' viewBox='0 0 48 48'><g><path d='M 2.438,0 C 1.087,0 0,1.088 0,2.438 V 45.56 C 0,46.91 1.087,48 2.438,48 H 45.56 C 46.91,48 48,46.91 48,45.56 V 2.438 C 48,1.088 46.91,0 45.56,0 Z' style='fill:rgb(243, 135, 37);fill-opacity:1;' /><path style='opacity:0.25;fill:black;' d='M 14,45 17,48 H 45.5 C 47,47.9 47.9,47 48,45.5 V 17.6 L 33.9,3.5 Z'/><path style='fill:white;' d='M 15,3 C 14.4,3 14,3.4 14,4 V 45 L 24,35 34,45 V 4 C 34,3.4 33.6,3 33,3 Z' /></g></svg>",
        maxrequests = 50, // Максимальное количество параллельных запросов
        maxtimeout = 30, // Длительность до прерывания запроса в секундах
        alertnotification = true; // Уведомление о завершении поиска фавиконок для закладок

        if (!("PlacesUtils" in this))
            ChromeUtils.defineModuleGetter(this, "PlacesUtils", "resource://gre/modules/PlacesUtils.jsm");
        var favicons = {
            running: false,
            async search() {
                if (this.running) return;
                this.running = true;
                for(let {node} of CustomizableUI.getWidget(id).instances)
                    node.style.setProperty("-moz-image-region", "rect(16px, 16px, 32px, 0px)", "important");
                var urlsList = [];
                var root = await PlacesUtils.promiseBookmarksTree(PlacesUtils.bookmarks.rootGuid);
                var convert = (node, url) => {
                    if (node.children)
                        node.children.map(child => convert(child));
                    else if ((url = node.uri) && /^(?:http|ftp|file)s?:/.test(url))
                        urlsList.push(url);
                }
                convert(root);
                Promise.all(urlsList.map(this.getFaviconForPage)).then(results => this.sliceResults(results.filter(url => url !== null)));
            },
            get AlertsService() {
                delete this.AlertsService;
                return this.AlertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
            },
            sliceResults(results) {
                var maxlength = results.length;
                this.favmaxtimeout = maxtimeout * 1000;
                var forPageFavicon = (start, end) => {
                    var endlength = maxlength - end, startend;
                    if (endlength > 0)
                        startend = results.slice(start, end);
                    else
                        startend = results.slice(start, maxlength);
                    Promise.all(startend.map(this.getPageFavicon, this)).then(() => {
                        if (endlength > 0)
                            forPageFavicon(end, end + maxrequests);
                        else {
                            for(let {node} of CustomizableUI.getWidget(id).instances)
                                node.style.setProperty("-moz-image-region", "rect(0px, 16px, 16px, 0px)", "important");
                            if (alertnotification) {
                                try {
                                    this.AlertsService.showAlertNotification(alertimg, "Поиск фавиконок", "Завершено!", false);
                                } catch(e) {}
                            }
                            this.running = false;
                        }
                    });
                };
                forPageFavicon(0, maxrequests);
            },
            getFaviconForPage(siteURI) {
                return new Promise(resolve => {
                    try {
                        siteURI = Services.io.newURI(siteURI);
                    } catch(e) {
                        resolve(null);
                    }
                    PlacesUtils.favicons.getFaviconURLForPage(siteURI, uri => {
                        if (uri === null)
                            resolve(siteURI);
                        else
                            resolve(null);
                    });
                });
            },
            getPageFavicon(siteURI) {
                return new Promise(resolve => {
                    var req = new XMLHttpRequest();
                    if (!req) {
                        resolve();
                        return;
                    }
                    req.mozBackgroundRequest = true;
                    req.open("GET", siteURI.spec, true);
                    req.responseType = "document";
                    req.overrideMimeType("text/html");
                    req.timeout = this.favmaxtimeout;
                    req.onload = () => {
                        resolve();
                        var favURI = `${siteURI.prePath}/favicon.ico`, doc = req.responseXML;
                        if (doc !== null) {
                            let link = doc.querySelector("head link[href][rel~='icon']");
                            if (link !== null)
                                favURI = link.href;
                        }
                        try {
                            PlacesUtils.favicons.setAndFetchFaviconForPage(siteURI, Services.io.newURI(favURI), false, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, null, Services.scriptSecurityManager.getSystemPrincipal());
                        } catch(e) {}
                    };
                    req.onabort = () => {
                        resolve();
                    };
                    req.onerror = () => {
                        resolve();
                        req.abort();
                    };
                    req.ontimeout = () => {
                        resolve();
                        req.abort();
                    };
                    req.send(null);
                });
            },
        };
        CustomizableUI.createWidget({
            id: id,
            label: label,
            tooltiptext: tooltiptext,
            localized: false,
            defaultArea: CustomizableUI.AREA_NAVBAR,
            onCreated: function(btn) {
                btn.style.setProperty("-moz-image-region", !favicons.running ? "rect(0px, 16px, 16px, 0px)" : "rect(16px, 16px, 32px, 0px)", "important");
                btn.style.setProperty("list-style-image", `url("${img}")`, "important");
            },
            onCommand: function(e) {
                favicons.search();
            },
        });
    })();
} catch(e) {}

Vitaliy V.
Профиль один и тот же, я только его собрал и тут вы со своим обновлением. :) (шутка) Я его пересобрал, на тех же скриптах, стилях, расширениях и с теми же конфигами, за исключением вашего config.js. Отвалился стиль для адресной строки из userChrome.css, пришлось его перенести в CustomStylesScripts.jsm в секцию styleschrome с правами USER_SHEET, никак по другому он не заработал. Скрипты из custom_script.js я все переподключил в CustomStylesScripts.jsm в секцию scriptsbackground, в том числе и обсуждаемый. Скрипты custom_script_win.js оставил на месте, так как решил не заморачиваться. Скриптов custom_script_all_win.js у меня не оказалось. Т.е. две проблемы стиль и этот скрипт. Ясен пень, что ucf виноват.
   
Но оказалось все проще, смотрите мультики:

Находим виновника

01.1632267720.gif

И отправляем его в ссылку

02.1632267763.gif
А вообще вы молодец, а виноват во всем я. Я же его выпросил. :)

Vitaliy V.
А можно как-то вернуть в новый UCF возможность использования стилей для веб-страниц через файл custom_styles_content_user.css?
Может опцией, если надо может, чтоб включить можно было в CustomStylesScriptsChild.jsm. У меня в старом комплекте в custom_style_user.css добавлено несколько кодов для страниц, в частности, очень нужный для меня :root { text-decoration-skip-ink: none;}, для этого форума стиль.
Можно конечно включить toolkit.legacyUserProfileCustomizations.stylesheets, добавить в папку chrome файл userContent.css и по-старинке использовать, но это не работает в безопасном режиме, да и вообще... Вообще удобно в старом UCF то, что стили и для интерфейса и для страниц можно использовать/подгонять в одном файле css.
Этот код, только с regexp, тоже использую для веб-страниц

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

Выделить код

Код:

@-moz-document regexp("(?:https?|ftp|file):\/\/.*") {
input, textarea {
    /* border: 1px solid rgba(131,137,150,.5); */
    outline: 1px solid transparent;
}
}

В новом комплекте непонятно как всё вышеперечисленное запустить...

sandro79 пишет

в старом комплекте в custom_style_user.css

А в новом в custom_styles_all_user.css

Dumby пишет

А в новом в custom_styles_all_user.css

Да, работает там, в трёх соснах заблудился. Спасибо за подсказку :beer: Вот надо же, так облажаться :dumb:


И chrome и content работает, как и в старом. Всё отлично.

egorsemenov06
У вас столько кнопок Add Toolbar Buttons
не проще его и использовать

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

Выделить код

Код:

(async () => {
    var id = "ucf-loads-favicons",
    label = "Восстановить фавиконки",
    tooltiptext = "Восстановить фавиконки закладок",
    img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M3.6.6v14.8L8 11l4.4 4.4V.6z'/></svg>",
    maxrequests = 50, // Максимальное количество параллельных запросов
    maxtimeout = 30, // Длительность до прерывания запроса в секундах
    alertnotification = true; // Уведомление о завершении поиска фавиконок для закладок

    var favicons = {
        _favrunning: false,
        get alertsService() {
            delete this.alertsService;
            return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
        },
        showAlert(title, val) {
            try {
                this.alertsService.showAlertNotification(img, title, val, false);
            } catch(e) {}
        },
        favSearchStart() {
            if (this._favrunning) return;
            this._favrunning = true;
            this.callWithEachWindow(id, {fill: "color-mix(in srgb, currentColor 20%, #e31b5d)"});
            PlacesUtils.promiseBookmarksTree(PlacesUtils.bookmarks.rootGuid).then(root => {
                var urlsList = [];
                var convert = (node, url) => {
                    if (node.children)
                        node.children.map(convert);
                    else if ((url = node.uri) && /^(?:https?|ftp|file):/.test(url))
                        urlsList.push(url);
                };
                convert(root);
                var favForPage = siteURI => {
                    return new Promise(resolve => {
                        try {
                            siteURI = Services.io.newURI(siteURI);
                        } catch(e) {
                            resolve(null);
                        }
                        PlacesUtils.favicons.getFaviconURLForPage(siteURI, uri => {
                            if (uri === null)
                                resolve(siteURI);
                            else
                                resolve(null);
                        });
                    });
                };
                Promise.all(urlsList.map(favForPage)).then(results => this.favSearchResults(results.filter(url => url !== null)));
            });
        },
        favComplete(favsuccesslength, favmaxlength) {
            this._favrunning = false;
            this.callWithEachWindow(id, {fill: ""});
            if (alertnotification)
                this.showAlert("Поиск фавиконок", `Успешно обработано - ${favsuccesslength}, не удалось обработать - ${favmaxlength - favsuccesslength}`);
        },
        favSearchResults(results) {
            var favmaxlength = results.length;
            var favsuccesslength = 0;
            if (!favmaxlength) {
                this.favComplete(0, 0);
                return;
            }
            var favmaxtimeout = maxtimeout * 1000;
            var _favmaxlength = favmaxlength;
            var splice = results.splice(0, maxrequests);
            var favSearchPage = siteURI => {
                (new Promise(resolve => {
                    try {
                        let req = new XMLHttpRequest();
                        req.mozBackgroundRequest = true;
                        req.open("GET", siteURI.spec, true);
                        req.responseType = "document";
                        req.overrideMimeType("text/html");
                        req.timeout = favmaxtimeout;
                        req.onload = () => {console.log(req)
                            try {
                                let doc = req.responseXML, favURI;
                                if (doc) {
                                    let links = doc.querySelectorAll("head link[href][rel~='icon']"), lastlink, is16, is32, isany;
                                    for (let link of links) {
                                        if (link.sizes.length === 1) {
                                            let size = link.sizes[0];
                                            if (/any/i.test(size))
                                                isany = link;
                                            else if (/32x32/i.test(size))
                                                is32 = link;
                                            else if (/16x16/i.test(size))
                                                is16 = link;
                                        }
                                        lastlink = link;
                                    }
                                    links = isany || is32 || is16 || lastlink;
                                    if (links)
                                        favURI = links.href;
                                }
                                if (!favURI)
                                    favURI = `${req.responseURL ? Services.io.newURI(req.responseURL).prePath : siteURI.prePath}/favicon.ico`;
                                let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
                                let request = PlacesUtils.favicons.setAndFetchFaviconForPage(siteURI, Services.io.newURI(favURI), false, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, {
                                    onComplete() {
                                        ++favsuccesslength;
                                        resolve();
                                        timer.cancel();
                                        timer = null;
                                        request = null;
                                    },
                                }, Services.scriptSecurityManager.getSystemPrincipal());
                                if (!request) {
                                    resolve();
                                    timer = null;
                                    return;
                                }
                                timer.initWithCallback(() => {
                                    resolve();
                                    try {
                                        request.cancel();
                                    } catch(e) {}
                                    timer = null;
                                    request = null;
                                }, favmaxtimeout, timer.TYPE_ONE_SHOT);
                            } catch(e) {
                                resolve();
                            }
                        };
                        req.onabort = () => {
                            resolve();
                        };
                        req.onerror = req.ontimeout = () => {
                            resolve();
                            req.abort();
                        };
                        req.send(null);
                    } catch(e) {
                        resolve();
                    }
                })).then(() => {
                    if (!(--_favmaxlength)) {
                        this.favComplete(favsuccesslength, favmaxlength);
                        return;
                    }
                    if (!results.length) return;
                    favSearchPage(results.shift());
                });
            };
            splice.map(favSearchPage);
        },
        callWithEachWindow(buttonID, atr) {
            var getW = CustomizableUI.getWidget(buttonID);
            if (getW.instances.length)
                for (let {node} of getW.instances) {
                    if (!node) continue;
                    for (let a in atr)
                        node.style.setProperty(a, atr[a]);
                }
            else
                for (let win of CustomizableUI.windows) {
                    let node = getW.forWindow(win).node;
                    if (!node) continue;
                    for (let a in atr)
                        node.style.setProperty(a, atr[a]);
                }
        },
    };
    CustomizableUI.createWidget({
        id: id,
        label: label,
        tooltiptext: tooltiptext,
        localized: false,
        defaultArea: CustomizableUI.AREA_NAVBAR,
        onCreated(btn) {
            btn.style.setProperty("list-style-image", `url("${img}")`, "important");
            if (favicons._favrunning)
                btn.style.setProperty("fill", "color-mix(in srgb, currentColor 20%, #e31b5d)");
        },
        onCommand(e) {
            favicons.favSearchStart();
        },
    });
})();

_zt пишет

А вообще вы молодец, а виноват во всем я. Я же его выпросил

Это вы молодец нашли баг
Я предполагал что DOMContentLoaded позновато для некоторых стилей (это касается только Для докум. всех окон [ChromeOnly]) однако проблем не обнаружил.
С тем же алертом у меня он появлялся, но как я заметил позже клики на нем не работают.


Вот теперь верните стиль в main_window.css
и обновите файлы: config.js, user_chrome.js, CustomStylesScripts.jsm, CustomStylesScriptsChild.jsm, custom_script_win.js
чтобы заменить DOMContentLoaded на MozBeforeInitialXULLayout

Vitaliy V. пишет

egorsemenov06
У вас столько кнопок Add Toolbar Buttons
не проще его и использовать

У меня их только три штуки из АТВ.Огромное Вам Спасибо!!!!!

Vitaliy V.
Починилось.
   
Нашел еще несколько проблем, давайте по порядку, так как возможно они взаимосвязаны:
2021.1632357561.png
Вот я просто слов без мата не нахожу, что бы описать этот цвет, именно в этом диалоге оно где, в common.css ?

@media (-moz-toolbar-prefers-color-scheme: dark) {
:root, dialog, menu-button, login-filter, login-item, login-intro, login-list, fxaccounts-button, remove-logins-dialog,
    import-error-dialog, import-summary-dialog, confirmation-dialog, info-item, message-bar, addon-updates-message {
>>
    --in-content-primary-button-background: var(--blue-50) !important;

   
Если да, то тогда оно не работает, цвет не меняется. В --blue-50 тоже.
   
После переноса в userChrome.css правило работает.

_zt
Поделись, пожалуйста этой закладкой Старый about:config
У меня даже нет такой папки chrome://user_chrome_files/content/aboutconfig/

rubel
https://forum.mozilla-russia.org/viewto … 75#p789675


Add,

скрин
e0101f473944.png

kokoss
OK, спасибо. все получилось.

_zt пишет

оно где, в common.css ?

Нет в common.css только контент.
В common_win.css я некоторые окна добавил, это туда же url("chrome://browser/content/places/bookmarkProperties.xhtml")
Ну я потом добавлю другие окна где есть <dialog>


Вроде готово, обновил FullTheme
и UserChromeFiles ещё раз обновил надеюсь пока больше не буду трогать если только баг всплывет.


upd: обновил Sidebar Tabs и Тултипы с URL https://forum.mozilla-russia.org/viewto … 02#p792702

Vitaliy V.
Починилось.Спасибо.
   
Можете объяснить?

Прошлая версия
02.1632481807.gif

_zt пишет

Можете объяснить?

А что тут объяснять
Отключили переменную в chrome://global/skin/in-content/common.css
для темной темы
@media (-moz-toolbar-prefers-color-scheme: dark)
Но переменная для светлой темы осталась именно она и дает этот синий цвет
а не от FullTheme. Ну или это вы там что-то наподключали, но такого цвета #2b71e4 в моей теме нет.
Впрочем gif же у вас цвет искажен скорее всего

Vitaliy V.
Искажен. В общем, ничего не понял, но спасибо что исправили. Я там ничего не менял в пространствах имен. В общем, спасибо.

Dumby
Помогите пожалуйста. Использую Ваш скрипт закрытия всех вкладок кроме активной, только со своей иконкой

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

Выделить код

Код:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACNUlEQVQ4jY2TT08aQRjG59LL7mk/gxdvXmw/QD+MX6AePNhk0jThMGljEzLpxio0arQWMGpqomXBP7TQ3YpQ5J8CQf65C7vUKK61Hp4eFhMwBPskc5iZzO9987zPENIV9WyOTkxMPCGPaJIxcdq7NdJ3SJcj4+/jdns+WvMPg1AqC+5vujKjdhrUEx4lhBDyciE0NqPZbU8G8BWAz9pgyCRj4oKqK0t5wJsF5MPr+rS8NkKmOJfc301tMQesl4BQFdhJ9UMolYX1pK5slYGNEuAvAF7VCFJKBUIIIS7OpYW4pX4pA/t14KgJRLMOhDEm7mZ1JaYDB3UgXAXWkkaQUlnoa9HFubSRMrXoOXBsAuVLIFGoBuJFXcn/BtIWkGgBoUxP5YdycS7tnVhqvg3UO0D7D9CygUbHAaoFI0hlefDje3HOpWTZ1Jo2cHMH2HeAeQMkS0Mq94oxJv4qG4p5A1z9ddb5NRDL1XyP5oTKshA71ZXiBVC5dFpv2kDlCshYwHZqCIQxJm4f64pmOGalLUAt6ErqzFKLF0CyBUQagO9wAIRSWViN68rOGRCqOeNSum5zzqUfRVP7aQDhGrBZAuaiPZBJxsS5mK6snDgB2SgBgUT/nDnnUjBnqV8rQKAIfMwCM3tdyOul/Wfuo9vObNqJqEcd7LaLc8mfNLVPp8CHNPBWta0X8qbzH+jq4fM32m3n3cGAhD2AzGuWyuO2RZcj432XU4u7T/9nzi7OpVcrobH7/T9AEdt1RBP8kgAAAABJRU5ErkJggg==

Недавно решил заменить её на svg из допротоновских версий chrome://browser/skin/panel-icon-cancel.svg
Закинул в папку svg комплекта эту иконку, чтоб белой была на тёмном фоне без надобности включения svg.context-properties.content.enabled.
Прописал путь к иконке chrome://user_chrome_files/content/custom_styles/svg/panel-icon-cancel.svg, иконка появилась, всё работает нормально
скрытый текст

Выделить код

Код:

CustomizableUI.createWidget({
	id: "Close-Tabs-button",
	label: "Закрыть другие вкладки",
	tooltiptext: "Закрыть другие вкладки",
	defaultArea: CustomizableUI.AREA_NAVBAR,
	localized: false,
	onCreated(btn) {
		btn._handleClick = this.close;
		btn.setAttribute("image", "chrome://user_chrome_files/content/custom_styles/svg/panel-icon-cancel.svg");
	},
	close() {
		var gb = this.ownerGlobal.gBrowser;
		gb.removeAllTabsBut(gb.selectedTab);
	}
});

Но вот только маленькая она стала, меньше чем та что была. Я её чуть увеличил стилем
скрытый текст
Image_001.png

Выделить код

Код:

#Close-Tabs-button > image {
    padding: 2px !important;
}

Может можно добавить как-то тоже стиль выше в код скрипта, чтоб всё в одном месте было?

sandro79
У меня снова предложение чуть поперёк просьбы.
Там <svg> 32x32, а <path> 20x20 по-центру,
то есть как бы отступ 6px со всех сторон (поэтому выглядит маленькой).


Но можно во viewBox подогнать x, y, width и height.
Допустим, максимально. Меняем в самой svg'ке viewBox="0 0 32 32"
на viewBox="6 6 20 20" и отступа не будет совсем, тогда будет выглядеть крупнее.
Если положительного результата не получится, дай знать, полезу в js-код.

Dumby пишет

Допустим, максимально. Меняем в самой svg'ке viewBox="0 0 32 32"
на viewBox="6 6 20 20" и отступа не будет совсем, тогда будет выглядеть крупнее

6 6 20 20 всё-же крупновато получается. Но попробовал подрегулировать до viewBox="5 5 22 22", почти как с оригинальной svg и стилем, но чуть всё-равно крупнее. А 6 6 23 23 попробовал - размер визуально вроде не отличается, но сдвигается вверх и влево. Никак не получается один к одному подогнать.
Dumby
Ну если можно, добавьте пожалуйста css в js-код, ну почти подогнал как с оригинальной и стилем, но крупновато всё же с viewBox="5 5 22 22".
А за метод правки и полезную информацию Большое Спасибо, а то я пытался только цифры 32 менять в коде svg, теперь буду хоть это знать.

sandro79 пишет

сдвигается вверх и влево

Вот все центрированные варианты

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

Выделить код

Код:

viewBox="0 0 32 32"
viewBox="1 1 30 30"
viewBox="2 2 28 28"
viewBox="3 3 26 26"
viewBox="4 4 24 24"
viewBox="5 5 22 22"
viewBox="6 6 20 20"


Хотя, может можно не целые числа, не проверял.

добавьте пожалуйста css в js-код

Допустим, в атрибут style. Может не сработать,
если user или agent стилями приколочено, тогда снова дай знать.

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

Выделить код

Код:

CustomizableUI.createWidget({
	id: "Close-Tabs-button",
	label: "Закрыть другие вкладки",
	tooltiptext: "Закрыть другие вкладки",
	defaultArea: CustomizableUI.AREA_NAVBAR,
	localized: false,
	onCreated(btn) {
		btn.render = this.render;
		btn._handleClick = this.close;
		btn.setAttribute("image", "chrome://user_chrome_files/content/custom_styles/svg/panel-icon-cancel.svg");
	},
	render() {
		delete this.render;
		this.render();
		this.icon.style.setProperty("padding", "2px", "important");
	},
	close() {
		var gb = this.ownerGlobal.gBrowser;
		gb.removeAllTabsBut(gb.selectedTab);
	}
});

Dumby пишет

Вот все центрированные варианты

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

Допустим, в атрибут style. Может не сработать, если user или agent стилями приколочено, тогда снова дай знать

Отлично всё, сработало! Теперь один в один. Огромное Вам Спасибо за помощь :beer:

sandro79
Всё таки проверил дробные числа. Похоже работает.
Вот с шагом в одну десятую. Ну, это я уже просто так, на интерес.

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

Выделить код

Код:

viewBox="0 0 32 32"
viewBox="0.1 0.1 31.8 31.8"
viewBox="0.2 0.2 31.6 31.6"
viewBox="0.3 0.3 31.4 31.4"
viewBox="0.4 0.4 31.2 31.2"
viewBox="0.5 0.5 31 31"
viewBox="0.6 0.6 30.8 30.8"
viewBox="0.7 0.7 30.6 30.6"
viewBox="0.8 0.8 30.4 30.4"
viewBox="0.9 0.9 30.2 30.2"
viewBox="1 1 30 30"
viewBox="1.1 1.1 29.8 29.8"
viewBox="1.2 1.2 29.6 29.6"
viewBox="1.3 1.3 29.4 29.4"
viewBox="1.4 1.4 29.2 29.2"
viewBox="1.5 1.5 29 29"
viewBox="1.6 1.6 28.8 28.8"
viewBox="1.7 1.7 28.6 28.6"
viewBox="1.8 1.8 28.4 28.4"
viewBox="1.9 1.9 28.2 28.2"
viewBox="2 2 28 28"
viewBox="2.1 2.1 27.8 27.8"
viewBox="2.2 2.2 27.6 27.6"
viewBox="2.3 2.3 27.4 27.4"
viewBox="2.4 2.4 27.2 27.2"
viewBox="2.5 2.5 27 27"
viewBox="2.6 2.6 26.8 26.8"
viewBox="2.7 2.7 26.6 26.6"
viewBox="2.8 2.8 26.4 26.4"
viewBox="2.9 2.9 26.2 26.2"
viewBox="3 3 26 26"
viewBox="3.1 3.1 25.8 25.8"
viewBox="3.2 3.2 25.6 25.6"
viewBox="3.3 3.3 25.4 25.4"
viewBox="3.4 3.4 25.2 25.2"
viewBox="3.5 3.5 25 25"
viewBox="3.6 3.6 24.8 24.8"
viewBox="3.7 3.7 24.6 24.6"
viewBox="3.8 3.8 24.4 24.4"
viewBox="3.9 3.9 24.2 24.2"
viewBox="4 4 24 24"
viewBox="4.1 4.1 23.8 23.8"
viewBox="4.2 4.2 23.6 23.6"
viewBox="4.3 4.3 23.4 23.4"
viewBox="4.4 4.4 23.2 23.2"
viewBox="4.5 4.5 23 23"
viewBox="4.6 4.6 22.8 22.8"
viewBox="4.7 4.7 22.6 22.6"
viewBox="4.8 4.8 22.4 22.4"
viewBox="4.9 4.9 22.2 22.2"
viewBox="5 5 22 22"
viewBox="5.1 5.1 21.8 21.8"
viewBox="5.2 5.2 21.6 21.6"
viewBox="5.3 5.3 21.4 21.4"
viewBox="5.4 5.4 21.2 21.2"
viewBox="5.5 5.5 21 21"
viewBox="5.6 5.6 20.8 20.8"
viewBox="5.7 5.7 20.6 20.6"
viewBox="5.8 5.8 20.4 20.4"
viewBox="5.9 5.9 20.2 20.2"
viewBox="6 6 20 20"

Dumby пишет

Всё таки проверил дробные числа. Похоже работает. Вот с шагом в одну десятую. Ну, это я уже просто так, на интерес

Да, это работает. viewBox="4.7 4.7 22.6 22.6" подошло идеально, ну я не увидел визуально разницы. Спасибо Большое за таблицу. Тоже пригодится в дальнейшем.
Я ещё вчера заменил кнопки для окна загрузок и соответственно библиотеки на эту же(panel-icon-cancel.svg) и panel-icon-retry.svg из 78 [firefox], и там они тоже мелковаты получились, да и в 78 такие же были. panel-icon-cancel.svg для нового скрипта сделаю дубликат с др. именем, а для окон загрузок подберу уже из дробных. Правда, чуть раньше уже пробовал с целыми, с кнопкой отмены нормально всё, а вот кнопку panel-icon-retry.svg начинает коробить - круглая стрелка квадратной становится. Ну буду экспериментировать, не получится, ну там и не столь важно в принципе. Спасибо за помощь!


Почти получилось с кнопкой повтора с viewBox="4.7 4.7 22.6 22.6", округлости чуть снизу не хватает, но попробую ещё с другими числами.


Да так и оставлю в окнах загрузок, нормально.

Vitaliy V.
А как теперь тултипы подключить №10124?

voqabuhe
раскомментируйте эту строку https://github.com/VitaliyVstyle/Vitali … ts.jsm#L16
стиль добавляйте соответственно в custom_styles_all_agent.css

Vitaliy V.
Спасибо, подключились.

Vitaliy V.
Спасибо за обновлённый вариант urlbarhistorydropmarker. Тоже его забрал.
В старом варианте пропал фон наведения в 92+ и значок сдвинулся чуть вправо(но я его вернул на место правда), а тут всё с этим в порядке.
Но скрипт для значка "Копировать ссылку" оставлю, привык к нему за три с лишним года.
Виталий, а нельзя ли ещё добавить в urlbarhistorydropmarker действие "Обновить текущую страницу" по СКМ? Вообще было бы супер - три в одном!

sandro79
Сомнительное удобство обновлять страницу колесом, но добавил
в принципе можно на другую функцию заменить здесь
                    if (e.button === 1) {
                        BrowserReload();
                        return;
                    }

Vitaliy V. пишет

Сомнительное удобство обновлять страницу колесом, но добавил...

Ну да. Но ничего так, вполне удобно. Колесо у меня работает отлично.
Да и хочется чего-то необычного испробовать. Всё работает отлично. Огромное Спасибо :beer:


Добавлю себе в пост, чтоб не потерять, три варианта скрипта: старый с правленным мной под Протон адресом для иконки, новый без обновления по СКМ, и новый с обновлением страницы по СКМ

скрытый текст
browser.urlbar.suggest.history - true
browser.urlbar.suggest.topsites - false
скрытый текст
Допротоновский адрес для иконки chrome://global/skin/icons/arrow-dropdown-16.svg В версиях 92+ этот скрипт лучше не использовать

Выделить код

Код:

(this.urlbarhistorydropmarker = {
            dropmarker: null,
            provider: null,
            get style() {
                delete this.style;
                return this.style = "data:text/css;charset=utf-8," + encodeURIComponent(`
                    #urlbar .urlbar-history-dropmarker {
                        list-style-image: url("chrome://global/skin/icons/arrow-down.svg");
                        transition: opacity 0.15s ease;
                    }
                    #urlbar[switchingtabs] > #urlbar-input-container > .urlbar-history-dropmarker {
                        transition: none;
                    }
                    #urlbar[usertyping] > #urlbar-input-container > .urlbar-history-dropmarker {
                        display: none;
                    }
                    #nav-bar:not([customizing="true"]) > #nav-bar-customization-target > #urlbar-container:not(:hover) > #urlbar:not([focused]) > #urlbar-input-container > .urlbar-history-dropmarker {
                        opacity: 0;
                    }
                `);
            },
            init(that) {
                Services.prefs.addObserver("browser.urlbar.suggest.history", this);
                Services.prefs.addObserver("browser.urlbar.suggest.topsites", this);
                that.unloadlisteners.push("urlbarhistorydropmarker");
                var {UrlbarProviderTopSites: provider} = {UrlbarProviderTopSites: this.provider} = ChromeUtils.import("resource:///modules/UrlbarProviderTopSites.jsm");
                if (!provider.orig_PRIORITY) {
                    provider.orig_PRIORITY = provider.ucf_PRIORITY = provider.PRIORITY;
                    delete provider.constructor.prototype.PRIORITY;
                    Object.defineProperty(provider.constructor.prototype, "PRIORITY", {
                        enumerable: true,
                        get() {
                            var priory = this.ucf_PRIORITY;
                            this.ucf_PRIORITY = this.orig_PRIORITY;
                            return priory;
                        },
                        set(val) {
                            this.ucf_PRIORITY = val;
                        },
                    });
                }
                if (Services.prefs.getBoolPref("browser.urlbar.suggest.history", false) && !Services.prefs.getBoolPref("browser.urlbar.suggest.topsites", true))
                   this.createDropmarker();
            },
            createDropmarker() {
                var fragment = MozXULElement.parseXULToFragment(`<image class="urlbar-history-dropmarker urlbar-icon chromeclass-toolbar-additional" role="button" tooltiptext="Показать историю"/>`);
                var dropmarker = this.dropmarker = fragment.firstElementChild;
                document.querySelector("#urlbar #page-action-buttons").before(fragment);
                dropmarker.addEventListener("mousedown", this);
                windowUtils.loadSheetUsingURIString(this.style, windowUtils.USER_SHEET);
            },
            removeDropmarker() {
                this.dropmarker.removeEventListener("mousedown", this);
                this.dropmarker.remove();
                this.dropmarker = null;
                windowUtils.removeSheetUsingURIString(this.style, windowUtils.USER_SHEET);
            },
            destructor() {
                if (this.dropmarker)
                    this.dropmarker.removeEventListener("mousedown", this);
                Services.prefs.removeObserver("browser.urlbar.suggest.history", this);
                Services.prefs.removeObserver("browser.urlbar.suggest.topsites", this);
            },
            observe() {
                if (Services.prefs.getBoolPref("browser.urlbar.suggest.history", false) && !Services.prefs.getBoolPref("browser.urlbar.suggest.topsites", true) && !this.dropmarker)
                    this.createDropmarker();
                else if (this.dropmarker)
                    this.removeDropmarker();
            },
            handleEvent(event) {
                event.preventDefault();
                event.stopPropagation();
                if (gURLBar.view.isOpen)
                    gURLBar.view.close();
                else {
                    this.provider.PRIORITY = 0;
                    gURLBar.focus();
                    gURLBar.startQuery({
                        allowAutofill: false
                    });
                }
            }
        }).init(this);

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

Выделить код

Код:

(this.urlbarhistorydropmarker = {
            // -- Настройки -->
            hide