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

Общайтесь со знакомыми и друзьями в нашей группе в Контакте.

№1462625-05-2020 05:09:40

katana
Участник
 
Группа: Members
Зарегистрирован: 04-09-2019
Сообщений: 25
UA: Firefox 76.0

Re: Custom Buttons

Dumby
А что надо сделать? там ничего не понятно по ссылке, да и как исправили походу, думал заработает баг какой-то был?

Отсутствует

 

№1462725-05-2020 07:24:08

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

Re: Custom Buttons

Dumby пишет

Что-то не соображу как сделать, чтобы favicon таба
не дёргался, если есть, но был скрыт, если нет.

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

Выделить код

Код:

({
	interval: 6e4,

	id: "cb-auto-reload",
	init(popup) {
		this.tabs(this.initTab, true) && this.addStyle();
		addDestructor(this.destroy, this);
		var dsp = e => this[e.type](e);
		for(var type of ["popupshowing", "TabClose", "SSTabRestored"])
			addEventListener(type, dsp, false, (
				type[0] == "p" ? this.popup = popup : gBrowser.tabContainer
			) || 1);
	},
	destroy(reason) {
		this.tabs(this.destroyTab, reason != "delete");
		this.menuitem?.remove();
	},
	tabs(callback, arg) {
		var res;
		for(var tab of gBrowser.tabs) {
			var has = SessionStore.getCustomTabValue(tab, this.id);
			has && callback.call(this, tab, arg, res = true);
		}
		return res;
	},
	initTab(tab, arg) {
		arg || SessionStore.setCustomTabValue(tab, this.id, "1");
		var img = document.createXULElement("hbox");
		img.className = this.id;
		img.setAttribute("onclick", 'linkedObject.destroyTab(this.closest("tab"))');
		img.linkedObject = this;
		tab.throbber.before(img);
		tab.setAttribute(this.id, setInterval(this.reload, this.interval, tab));
	},
	destroyTab(tab, arg) {
		clearInterval(tab.getAttribute(this.id));
		arg || SessionStore.deleteCustomTabValue(tab, this.id);
		tab.removeAttribute(this.id);
		tab.querySelector("." + this.id).remove();
	},
	addStyle() {
		this.addStyle = () => {};
		var css = `
			tab.tabbrowser-tab:not([pinned]) .${this.id} {
				width: 16px;
				height: 16px;
				margin-left: -5px;
				background-position: center;
				background-repeat: no-repeat;
				background-image: url("data:image/x-icon;base64,AAABAAEADAwAAAEAIACYAgAAFgAAACgAAAAMAAAAGAAAAAEAIAAAAAAAcAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAgIAAQECAAAAAAAAAAAAAAAAAAAAAAABAQIAAQICAAAAAAAAAAAAAAAAAAEBAQAAAAAEBggGDydSUhM6g40SOYONCyNRUgEDCAYAAAAAAAEBAQAAAAAAAQICAAAAAA4XIR4nXLvNJGnx/yNq9/0jaff9I2jx/x1Suc0FDh4eAAAAAAABAQIAAAAACAoGBDNluMopaOn/LWnf/jJnw90zacTdLmvf/Stq6v8jU7PJAQIEAwAAAAAAAAAAJDpVVTV27f8ta+H/Jkh9hAgJBAEGCAQAK09+gzJw4/8vb+v/ESdPVAAAAAAAAAAANFmJjDR7/P8tZcncBQcKCAAAAAAAAAAACQwLBzhyzNwyefv/HUKFjAAAAAAAAAAAOV+LjDyI//8wbc3bAgUJBgEBAAAAAAABCAsKBjx5z9s6hf//IkqIjAAAAAAAAAAAMEhcVk6c//8+ivH/J1GHigMEBAIBAAAALlV/f0SP8/9Flf//HDhZVgAAAAAAAAAACgoIBVqXzcpPqP//QHq5wBYgJR0/d7C0TJ/8/06j//9GiMzNBAYIBQAAAAABAQICAAAAABggIx5mqt/iOWiNiyAvNjBpv///Xbj//1KWz9ESHSUhAAAAAAEBAgIAAAAAAQEBAQAAAAAJCwoHOllqZRYgJR0mO0VANVVnZAcJCAYAAAAAAQEBAQAAAAAAAAAAAAAAAAECAgIBAQECAAAAAAEBAgEAAAEBAAAAAAABAQIBAQICAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=");
			}
			tab.tabbrowser-tab[${this.id}] :-moz-any(.tab-throbber, .tab-icon-pending) {
				display: none;
			}
			tab.tabbrowser-tab[${this.id}]/*[image]*/ .tab-icon-image {
				display: -moz-box;
			}
		`.replace(/;/g, " !important;");
		var args = ["data:text/css," + encodeURIComponent(css), windowUtils.USER_SHEET];
		windowUtils.loadSheetUsingURIString(...args);
		addDestructor(() => windowUtils.removeSheetUsingURIString(...args));
	},
	checked(tab = TabContextMenu.contextTab) {
		return tab.hasAttribute(this.id);
	},
	cmd(tab) {
		this.addStyle();
		(this.cmd = tab => this.checked(tab) ? this.destroyTab(tab) : this.initTab(tab))(tab);
	},
	reload(tab) {
		gBrowser.reloadTab(tab);
	},
	get shouldHide() {
		return !TabContextMenu.contextTab
			.linkedBrowser.currentURI.scheme.startsWith("http");
	},
	popupshowing(e) {
		if (this.shouldHide) return;

		var menuitem = this.menuitem = document.createXULElement("menuitem");
		menuitem.id = "context_cbAutoReloadTab";
		menuitem.setAttribute("type", "checkbox");
		menuitem.setAttribute("label", "Автоматически перезагружать");
		menuitem.setAttribute("oncommand", "linkedObject.cmd(TabContextMenu.contextTab)");
		menuitem.linkedObject = this;
		this.popup.querySelector("#context_duplicateTab").after(menuitem);

		(this.popupshowing = e => e.target == this.popup
			&& !(menuitem.hidden = this.shouldHide)
			&& menuitem.setAttribute("checked", this.checked())
		)(e);
	},
	TabClose(e) {
		var intervalId = e.target.getAttribute(this.id);
		if (!intervalId) return;
		clearInterval(intervalId);
		var tab = e.detail.adoptedBy;
		tab && SessionStore.setCustomTabValue(tab, this.id, "1");
	},
	SSTabRestored(e) {
		var tab = e.target;
		SessionStore.getCustomTabValue(tab, this.id)
			&& !tab.hasAttribute(this.id) && this.initTab(tab, true);
	}
}).init(document.getElementById("tabContextMenu"));

Dumby, большое спасибо.
Что касается favicon'а, то попробую поиграться со стилями, может что-то придумаю.


«The Truth Is Out There»

Отсутствует

 

№1462825-05-2020 20:56:29

Inko7
Участник
 
Группа: Members
Зарегистрирован: 09-11-2009
Сообщений: 1008
UA: Firefox 76.0

Re: Custom Buttons

Dumby пишет

Под скудное описание того, что он якобы делает,
возможно, в какой-то степени, подойдёт нечто вроде

Спасибо, устраивает на все сто!

Отсутствует

 

№1462925-05-2020 22:01:37

kazarin
Участник
 
Группа: Members
Зарегистрирован: 23-11-2016
Сообщений: 85
UA: Firefox 75.0

Re: Custom Buttons

Здравствуйте!
Подскажите, пожалуйста, что нужно изменить в коде кнопки Quick toggle for about:config preferences, чтоб браузер запускался с последним запущенным юзер-агентом, а не сбрасывал на дефолтный?

Отсутствует

 

№1463026-05-2020 02:20:21

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

Re: Custom Buttons

Dumby пишет

Что-то не соображу как сделать, чтобы favicon таба не дёргался.

Dumby.
Я попросил помощи со стилями для кнопки у Vitaliy V. Он, как всегда, оказался на высоте.
Вот код кнопки с исправленными стилями:

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

Выделить код

Код:

({
	interval: 6e4,

	id: "cb-auto-reload",
	init(popup) {
		this.tabs(this.initTab, true) && this.addStyle();
		addDestructor(this.destroy, this);
		var dsp = e => this[e.type](e);
		for(var type of ["popupshowing", "TabClose", "SSTabRestored"])
			addEventListener(type, dsp, false, (
				type[0] == "p" ? this.popup = popup : gBrowser.tabContainer
			) || 1);
	},
	destroy(reason) {
		this.tabs(this.destroyTab, reason != "delete");
		this.menuitem?.remove();
	},
	tabs(callback, arg) {
		var res;
		for(var tab of gBrowser.tabs) {
			var has = SessionStore.getCustomTabValue(tab, this.id);
			has && callback.call(this, tab, arg, res = true);
		}
		return res;
	},
	initTab(tab, arg) {
		arg || SessionStore.setCustomTabValue(tab, this.id, "1");
		var img = document.createXULElement("hbox");
		img.className = this.id;
		img.setAttribute("onclick", 'linkedObject.destroyTab(this.closest("tab"))');
		img.linkedObject = this;
		tab.throbber.before(img);
		tab.setAttribute(this.id, setInterval(this.reload, this.interval, tab));
	},
	destroyTab(tab, arg) {
		clearInterval(tab.getAttribute(this.id));
		arg || SessionStore.deleteCustomTabValue(tab, this.id);
		tab.removeAttribute(this.id);
		tab.querySelector("." + this.id).remove();
	},
	addStyle() {
		this.addStyle = () => {};
		var css = `
			tab.tabbrowser-tab[${this.id}] .${this.id} {
				width: 16px;
				height: 16px;
                position: relative;
                margin-top: 1px;
                margin-inline-start: -6px;
                margin-inline-end: -10px;
				background-position: top left;
				background-repeat: no-repeat;
				background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAkAAAAJCAYAAADgkQYQAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAEHSURBVHjaYmQAArWgflEglQrEgUCsAsR3gHg9EM++ta7wNSNIASMjQx/rr7fhEd6WrAbaygy3Hr1l2Hjw+u8Xbz+v/P+foYgFZIKEMG94foARKxfTDwZ3G3UGb6Cgj406a2rrhvDnbz5fZwJZ4W+vyRroacdw4MB+hjt37jA8e/aMYd/2NQzOxrKsIHmQIhU1OWGQ0xiSk5MZVFVVGdasWcPg4eHBYKglDxJWAVl3B+gGE5AV8vLyDLdv3wbTrKysDOuOHgMpugMyaT3IkbeBjgVJqKiogOnbUMeD5JmFNT1ufP3+S2b/mfua7z//YH778RvD1iO3GLoXHwH7DqionZGYcAIIMADkw2lofXkQ/wAAAABJRU5ErkJggg==");
            }
            tab.tabbrowser-tab[${this.id}]:-moz-locale-dir(rtl) .${this.id} {
				background-position: top right;
            }
            tab.tabbrowser-tab[${this.id}] .tab-icon-image {
				display: -moz-box;
            }
            tab.tabbrowser-tab[${this.id}][pendingicon] .tab-icon-image {
				visibility: hidden;
            }
            tab.tabbrowser-tab[${this.id}] .tab-icon-pending,
            tab.tabbrowser-tab[${this.id}] .tab-throbber {
				display: none;
			}
		`.replace(/;/g, " !important;");
		var args = ["data:text/css," + encodeURIComponent(css), windowUtils.USER_SHEET];
		windowUtils.loadSheetUsingURIString(...args);
		addDestructor(() => windowUtils.removeSheetUsingURIString(...args));
	},
	checked(tab = TabContextMenu.contextTab) {
		return tab.hasAttribute(this.id);
	},
	cmd(tab) {
		this.addStyle();
		(this.cmd = tab => this.checked(tab) ? this.destroyTab(tab) : this.initTab(tab))(tab);
	},
	reload(tab) {
		gBrowser.reloadTab(tab);
	},
	get shouldHide() {
		return !TabContextMenu.contextTab
			.linkedBrowser.currentURI.scheme.startsWith("http");
	},
	popupshowing(e) {
		if (this.shouldHide) return;

		var menuitem = this.menuitem = document.createXULElement("menuitem");
		menuitem.id = "context_cbAutoReloadTab";
		menuitem.setAttribute("type", "checkbox");
		menuitem.setAttribute("label", "Автоматически перезагружать");
		menuitem.setAttribute("oncommand", "linkedObject.cmd(TabContextMenu.contextTab)");
		menuitem.linkedObject = this;
		this.popup.querySelector("#context_duplicateTab").after(menuitem);

		(this.popupshowing = e => e.target == this.popup
			&& !(menuitem.hidden = this.shouldHide)
			&& menuitem.setAttribute("checked", this.checked())
		)(e);
	},
	TabClose(e) {
		var intervalId = e.target.getAttribute(this.id);
		if (!intervalId) return;
		clearInterval(intervalId);
		var tab = e.detail.adoptedBy;
		tab && SessionStore.setCustomTabValue(tab, this.id, "1");
	},
	SSTabRestored(e) {
		var tab = e.target;
		SessionStore.getCustomTabValue(tab, this.id)
			&& !tab.hasAttribute(this.id) && this.initTab(tab, true);
	}
}).init(document.getElementById("tabContextMenu"));


«The Truth Is Out There»

Отсутствует

 

№1463126-05-2020 08:35:03

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

Re: Custom Buttons

katana пишет

да и как исправили походу, думал заработает баг какой-то был?

Ровно наоборот.
Не было никакого бага, затем его придумали.
А когда "исправили", тогда и отвалилось.
Этот ещё ничего, имеет разумное обоснование.

Что надо сделать? Обновление надо сделать.
Хотя весьма странно чего-то ожидать от Nightly.
Она чтобы с чем-то возиться, а не чтобы чем-то пользоваться.
Если почему-то прям невтерпёж забрать снимок за неделю
до Merge Day, то вот, собери себе от двенадцатой

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

Выделить код

Код:

// CB-0.0.7.0.0.{12-14}-fx.js
(async re => {
	var gzip = "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";

	var sel = "Select";
	try {sel = Services.strings.createBundle("chrome://global/locale/commonDialogs.properties")
		.GetStringFromName(sel);} catch(ex) {}
	var picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
	picker.init(window, sel + " CB 0.0.7.0.0.12", picker.modeOpen);
	picker.appendFilter(null, "custom_buttons-0.0.7.0.0.12-fx-*.xpi");
	await new Promise(resolve => picker.open(resolve));
	var {file} = picker; if (!file) return;
	var ln = file.leafName;
	if (!re.test(ln)) return alert("???\n" + ln);
	var {fileURL} = picker;

	var xpi = file.parent.clone();
	xpi.append(ln = ln.replace("12-", "14-"));
	file.copyTo(file.parent, ln);

	var obs = {}, data;
	var td = new TextDecoder(), te = new TextEncoder();
	var scs = Cc["@mozilla.org/streamConverters;1"].getService(Ci.nsIStreamConverterService);
	var sis = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
	var sl =  Cc["@mozilla.org/network/stream-loader;1"].createInstance(Ci.nsIStreamLoader);

	sis.data = atob(gzip);
	obs.onStreamComplete = (a, b, c, d, result) => data = td.decode(new Uint8Array(result));
	sl.init(obs);
	var converter = scs.asyncConvertData("gzip", "uncompressed", sl, null);

	converter.onStartRequest(null, null);
	var args = [null, null, sis, 0, sis.data.length];
	if (converter.onDataAvailable.length == 4) args.shift();
	converter.onDataAvailable(...args);
	converter.onStopRequest(null, null, null);

	var zw = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter);
	var mt = Date.now() * 1000, cp = zw.COMPRESSION_DEFAULT;
	var bootstrap = ln.includes("bootstrap");
	var prefix = "jar:" + fileURL.spec + "!/";
	var lr = /^¦(?:\d+)?$/, sep1 = "£", sep2 = "¥";

	zw.open(xpi, 0x04); // PR_RDWR
	for(var item of data.split(sep1)) {
		var [entry, val] = item.split(sep2);
		if (bootstrap && (entry == "manifest.json" || entry == "startup.jsm")) continue;
		if (val == "+") {
			zw.addEntryDirectory(entry, mt, false); continue;
		}
		if (zw.hasEntry(entry)) {
			if (val.includes("¦")) {
				var lines = val.split("\n");
				var oldLines = (await (await fetch(prefix + entry)).text()).split("\n");

				lines.forEach((line, ind) => {
					if (lr.test(line)) lines[ind] = oldLines[
						line.length == 1 ? ind : +line.slice(1)
					];
				});
				val = lines.join("\n");
			}
			zw.removeEntry(entry, false);
			if (val == "-") continue;
		}
		var stream = Cc["@mozilla.org/io/string-input-stream;1"]
			.createInstance(Ci.nsISupportsCString);
		stream.data = String.fromCharCode(...new Uint8Array(te.encode(val)));
		zw.addEntryStream(entry, mt, cp, stream, false);
		stream.close();
	}
	zw.close(); xpi.reveal();
})(
	/^custom_buttons-0\.0\.7\.0\.0\.12-fx-(?:paxmod|bootstrap)\.xpi$/
);

kazarin пишет

что нужно изменить в коде кнопки

Очевидно же

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

Выделить код

Код:

/*
var ps = Components.classes["@mozilla.org/preferences-service;1"].getService (Components.interfaces.nsIPrefService).getBranch("general.");
    ps.setCharPref("useragent.override", useragent);
*/

unter_officer пишет

Вот код кнопки с исправленными стилями

Как-то я потерялся.
Да, улучшения вижу, типа компактное позиционирование,
показ индикатора и на закреплённых вкладках, поддержка rtl,
но я говорил о другом и, видимо, плохо сформулировал.
Попробую ещё раз:

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


Но если на странице favicon отсутствует вообще,
то и на (незакреплённой) вкладке он не показывается никакой.


А вот в режиме автоперезагрузки он, соответственно, вылезает,
красуется своим defaultFavicon.svg list-style-image, занимает место.


И это нехорошо. Ну разве что только не для тех, кто и так,
в повседневном обиходе, имеет, и как-то реализовал,
предпочтение видеть favicon на всех вкладках без исключения.

Отсутствует

 

№1463226-05-2020 11:43:11

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

Re: Custom Buttons

Dumby пишет

А вот в режиме автоперезагрузки он, соответственно, вылезает,
красуется своим defaultFavicon.svg list-style-image, занимает место.

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

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

Выделить код

Код:

tab.tabbrowser-tab[${this.id}]:not([pendingicon]) .tab-icon-image:not([src]):not([busy]):not([pinned]):not([crashed]):not([sharing]),


тогда там где нет иконок defaultFavicon.svg будет появлятся только во время загрузки, но там и по умолчанию текст дергается когда появляется индикатор загрузки.
Да кстати вчера надо было исправить замену
скрытый текст

Выделить код

Код:

.replace(/;\s*\n/g, " !important;\n");


а то странный тип данных получается data:image/png !important;base64,... или data:image/x-icon !important;base64,...

Отредактировано Vitaliy V. (26-05-2020 12:06:35)

Отсутствует

 

№1463326-05-2020 12:03:44

katana
Участник
 
Группа: Members
Зарегистрирован: 04-09-2019
Сообщений: 25
UA: Firefox 77.0

Re: Custom Buttons

Dumby
Пересел на бету, заметил с этим ночным одни проблемы, лучше подождать Merge Day, просто недопонял.


Может вам обьеденится с Vitaliy V.? и делать один продукт, легче будет да и там понятнее, а так 2 продукта и каждый в нем крутится.
Многие уже переходят смотрю на CustomizableUI.createWidget.
Не спорю тут есть свой плюсы, что можно сразу в окне редактировать, да и продукт который допиливали долго(но он морально устарел"наверно").

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

Есть сильные различия? чтобы продолжать чинить "все умирающий и никак не умрет".)
Хотя если только те кто остались на еср ветках, так там 2 пути или обновлять и приобрести проблемы, либо сидеть на итак рабочем.

Раньше в этой теме много кто сидел, Infocatcher пишет еще кнопки?
Да пишет походу, и еще какой-то код.
https://github.com/Infocatcher/Custom_Buttons/blob/master/code_snippets/customizableUI.js

Отсутствует

 

№1463426-05-2020 13:48:12

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

Re: Custom Buttons

Dumby пишет

Ну разве что только не для тех, кто и так,
в повседневном обиходе, имеет, и как-то реализовал,
предпочтение видеть favicon на всех вкладках без исключения.

Точно, у меня favicon'ы на всех вкладках без исключения. Не учел я этот момент.


Dumby, Vitaliy V.
Ещё раз огромное спасибо за помощь!


«The Truth Is Out There»

Отсутствует

 

№1463526-05-2020 19:51:48

FENIX-2020
Участник
 
Группа: Members
Зарегистрирован: 26-05-2020
Сообщений: 8
UA: Firefox 52.0

Re: Custom Buttons

Привет, Всем!

Подскажите пожалуйста существует ли кнопка сдвоенная Добавить страницу в закладки + Показать ваши закладки???
Либо что нибудь наподобие?

Спасибо за ответ!

Отсутствует

 

№1463627-05-2020 01:37:46

kazarin
Участник
 
Группа: Members
Зарегистрирован: 23-11-2016
Сообщений: 85
UA: Firefox 75.0

Re: Custom Buttons

Dumby пишет

Очевидно же

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

Выделить код

Код:

/*
var ps = Components.classes["@mozilla.org/preferences-service;1"].getService (Components.interfaces.nsIPrefService).getBranch("general.");
    ps.setCharPref("useragent.override", useragent);
*/

Нет, мне не очевидно, мои знания довольно поверхностны и, пока носом не ткнут, я не увижу:)
Большое спасибо за подсказку!

Отредактировано kazarin (27-05-2020 02:03:07)

Отсутствует

 

№1463727-05-2020 15:24:06

Duche
Участник
 
Группа: Members
Зарегистрирован: 07-02-2016
Сообщений: 208
UA: Firefox 38.0

Re: Custom Buttons

Добрый день. Просьба к специалистам . Починить старый код кнопки, под FF60.0 ESR . Открытие любой папки по прописанному в код пути. Заранее спасибо.

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

/*Initialization Code*/

this.onclick =e=> {
   e.button == 0 && runApp();   // ЛКМ
};       
function runApp() {
   var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
   file.initWithPath( getPath() );
   file.launch();
};
function getPath() {
   try { return gPrefService.getComplexValue(s, Ci.nsISupportsString).data; }
   catch(e) { return "С:\Мой путь к папке"; };
};

Отредактировано Duche (27-05-2020 15:34:19)

Отсутствует

 

№1463827-05-2020 18:37:02

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

Re: Custom Buttons

Duche пишет

Добрый день. Просьба к специалистам . Починить старый код кнопки, под FF60.0 ESR . Открытие любой папки по прописанному в код пути. Заранее спасибо.

:/

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

Выделить код

Код:

/*Initialization Code*/

    this.onclick =e=> {
       e.button == 0 && runApp();   // ЛКМ
    };       
    function runApp() {
       var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
       file.initWithPath( getPath() );
       file.launch();
    };
    function getPath() {
       try { return Services.prefs.getComplexValue(s, Ci.nsIPrefLocalizedString).data; }
       catch(e) { return "E:\\Download\\"; };
    };


«The Truth Is Out There»

Отсутствует

 

№1463927-05-2020 19:03:40

katana
Участник
 
Группа: Members
Зарегистрирован: 04-09-2019
Сообщений: 25
UA: Firefox 77.0

Re: Custom Buttons

Duche
//FileUtils.getFile("UChrm",["x.xxx"]).launch();
FileUtils.File("C:\\Windows\\notepad.exe").launch();

Отсутствует

 

№1464027-05-2020 21:07:58

Duche
Участник
 
Группа: Members
Зарегистрирован: 07-02-2016
Сообщений: 208
UA: Firefox 38.0

Re: Custom Buttons

unter_officer пишет
Duche пишет

Добрый день. Просьба к специалистам . Починить старый код кнопки, под FF60.0 ESR . Открытие любой папки по прописанному в код пути. Заранее спасибо.

:/

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

Выделить код

Код:

/*Initialization Code*/

    this.onclick =e=> {
       e.button == 0 && runApp();   // ЛКМ
    };       
    function runApp() {
       var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
       file.initWithPath( getPath() );
       file.launch();
    };
    function getPath() {
       try { return Services.prefs.getComplexValue(s, Ci.nsIPrefLocalizedString).data; }
       catch(e) { return "E:\\Download\\"; };
    };

Работает , спасибо.

Добавлено 27-05-2020 21:11:47

katana пишет

Duche
//FileUtils.getFile("UChrm",["x.xxx"]).launch();
FileUtils.File("C:\\Windows\\notepad.exe").launch();

При запуске FF автоматически открывает папку назначения ?

Отредактировано Duche (27-05-2020 21:11:47)

Отсутствует

 

№1464128-05-2020 12:34:25

kokoss
Участник
 
Группа: Members
Зарегистрирован: 15-02-2018
Сообщений: 1739
UA: Firefox 52.0

Re: Custom Buttons

Dumby
Что можно сделать, что бы этот скрипт_https://github.com/ardiman/userChrome.js/blob/master/autopopup/AutoPopup.uc.js, не реагировал на некоторые дополнения: ( конкретно на Clippings и... ) ?


Win7

Отсутствует

 

№1464228-05-2020 15:33:26

katana
Участник
 
Группа: Members
Зарегистрирован: 04-09-2019
Сообщений: 25
UA: Firefox 77.0

Re: Custom Buttons

Duche, нет, я только сейчас понял что делает ваш код)...


Кто знает, пробовал перенести кнопку с попапом в CustomizableUI.createWidget, один раз попап сработал с кликом, после перезапуска ничего не работает, просто висит кнопка, таких две кнопки.

пример

Выделить код

Код:

try{CustomizableUI.createWidget({
	label:"Insert_special_symbol",
	id:"ucf-cbbtn-Insertspecialsymbol",
	localized:false,
	get initCode(){
		this.event=Object.create(null);
		delete this.initCode;
		return this.initCode=Cu.readUTF8URI(Services.io.newURI("chrome://user_chrome_files/content/custom_scripts/CB/InsertSpecialSymbol[Fx].js"));},
	onCreated(btn){
		btn.setAttribute("image","data:image/png;base64,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");
		new btn.ownerGlobal.Function("self,event,_phase",this.initCode)
			.call(btn,btn,this.event,"init");}});}catch(ex){}


сам код в .js, может что не так?


Судя по этому, не все так просто... какой-то костыл прям) а если в uc.js не будет работать? если каждую кнопку так обделывать запариться..


И еще вопрос, вот в инициализаций меняешь код и сразу виден результат, а в CustomizableUI.createWidget как-то не удобно) да и в секций код тоже быстро можно протестировать, также он тоже склонен к проблемам как xulns или xul-xhtml.

Отредактировано katana (28-05-2020 18:54:31)

Отсутствует

 

№1464328-05-2020 21:53:14

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

Re: Custom Buttons

kokoss пишет

Что можно сделать, что бы этот скрипт_https://github.com/ardiman/userChrome.js/blob/master/autopopup/AutoPopup.uc.js, не реагировал на некоторые дополнения: ( конкретно на Clippings и... ) ?

Двадцать третья строка скрипта предоставляет слот игнорирования.
«конкретно на Clippings» — смотри сам. Возможно что-то типа

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

Выделить код

Код:

̣
	var BlackIDs = ["toolbarbutton[label=Clippings]"];

katana пишет

пример

Код InsertSpecialSymbol[Fx].js предлагается угадать?

Отсутствует

 

№1464428-05-2020 22:25:04

kokoss
Участник
 
Группа: Members
Зарегистрирован: 15-02-2018
Сообщений: 1739
UA: Firefox 52.0

Re: Custom Buttons

Dumby пишет

Двадцать третья строка скрипта предоставляет слот игнорирования.

var BlackIDs = ["toolbarbutton[label=Clippings]"];

Большое спасибо 61e02079e5fa.gif

Отредактировано kokoss (28-05-2020 22:26:46)


Win7

Отсутствует

 

№1464529-05-2020 07:36:01

katana
Участник
 
Группа: Members
Зарегистрирован: 04-09-2019
Сообщений: 25
UA: unknown 0.0

Re: Custom Buttons

Dumby
Да что-то подумал зачем она мне, удалил, хочу потихоньку перейти на user-chrome, а тут кнопка которая по идее только висит, легче блокнотом когда надо.. а так она тут.


Можно сделать чтобы работал во всех CustomizableUI.createWidget? просто везде подставлять "custombuttons.initAutoPopup(self);", еще знать надо куда закем, и что вместо "self" ставить, запарился вот вставил в Save он перестал работать(после одного запуска).

custom_script_win.js

Выделить код

Код:

// Based on // forum.mozilla-russia.org/viewtopic.php?pid=777188#p777188
// https://github.com/Infocatcher/Custom_Buttons/blob/master/code_snippets/autoOpenCloseMenu.js
// Automatically open menu on mouse over (and hide it on mouse out)
(AutoPopup=>custombuttons.initAutoPopup=(...args)=>new AutoPopup(...args))(class {
    constructor(btn,openDelay=200,closeDelay=350){
        this.btn=btn;
        this.openDelay=openDelay;
        this.closeDelay=closeDelay;
        this._openTimer=this._closeTimer=0;
        btn.onmouseover=e=>this.onmouseover(e);
        btn.onmouseout=e=>this.onmouseout(e);
    }
    open(btn){btn.open=true;}
    close(btn){
        for(var node=document.popupNode;node;node=node.parentNode)
            if(node==btn) // context opened
                return;
        btn.open=false;
    }
    onmouseover(e){
        clearTimeout(this._closeTimer);
        if(e.target==this.btn&&this.closeOtherMenus())
            this.btn.open=true;
        else
            this._openTimer=setTimeout(this.open, this.openDelay, this.btn);
    }
    onmouseout(e){
        clearTimeout(this._openTimer);
        this._closeTimer=setTimeout(this.close, this.closeDelay, this.btn);
    }
    maybeClose(node){
        if(
            node !=this.btn
            && XULElement.isInstance(node)
            && "open" in node
            && node.open
            && node.getElementsByTagName("menupopup").length
        ) {
            node.open=false;
            return true;
        }
        return false;
    }
    closeOtherMenus(){return Array.from(this.btn.parentNode.getElementsByTagName("*"))
            .some(this.maybeClose,this);}
});


Save

Выделить код

Код:

// Save, от 07.03.2017. .............

self.label = "Save";
self._handleClick =()=> menuPopup.openPopup(this, "after_start");custombuttons.initAutoPopup(menuPopup); //пробовал и self
self.image = "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==";



var folderpath="C:\\Users\\Firepox\\Desktop";         // папка для сохранения иконок для ярлыков и ярлыков сайтов


// Создать меню для кнопки .............
var array = [
   { label: "Сохранить значок веб-сайта", func: "saveFavicon()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAACPVBMVEX09ff////C3L+Uq8+Vq8+Uqs+Zr9CZrtCZr9Gfu+ear8+mt9JRf8ORxl3t8vfF06+Twojs8/d9otl8o9s+aquZrs/X9KLp8Pft8fZhisf//+DBzN2hveihv+pii8hti9pgicl6oNlojs1zncNsi836/P2duebx8/eYyWqBp+Gn0IKBvlKHsm9qmaVuk8zt7/FEbauEv1Tp7/JdhL9oi9Pl8e2LwlmdsdD7/P76+/3H7ofo8+peh8eHwFaSteZ0pkp2gl7q8/Ohy5OApt2by2eZuOqbuOWaezWuvtd7nN2HvWxul9Ty9feQxV5ljcqBp+JEcLCVtOOo0nR7odx5n9suX6Z1mtBzmtSXyGPv9PewzfOzx+O6zu/s8fd9o95Xfrthi8lYhMN5oNnw9ffw9Pjw9Pf8/f6ewO/m8O9zmdE6aapsjdyUwouPxWPDzd6XteOSs9B5nNVpnpqHt7h/s6F6n9d7ntSTttGHwVh4qp+Ev1HH7ox6qk5wj+Hm8e3t9fOm0IKAtqOBpNrx+P9ljcyhs9FpkM2hv+/u8/fF0eOLu4N+vFKgzX3p9OSFqN13qExekIl4n9j7/P3x9PhxmNDm8e9Vg8Zfkozr8veq0YTX9qL//92AtamOwnHFz96Fot1diMh+pd13ntmatu+YyW/3+/+Tqs5UgcShzJNbhsdTf8GHs7bo8PaXtuqMr+Ty8/SZt+SUqs7r7Ox3ndb9/f7t8feZyXGYyWWCpNbz9PRuiteNtNDn7/V4ntjx8fGo3JqNAAAAv3RSTlP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AEVuhDkAAAD+SURBVBhXY5jHzcUMAqxAICq9bx8D96adDFAgaGQOFOBaH7h7zoqZDTlFyptncAAFWBjyi52CXCI0unRLxcECPhsatbbzmlXMnS60hg0kkOxW0uNrq93tNaFpD1ggUm21QK532ZQdSm1hmXKdDCwdnOWVOi1RjNGMQCCrwMDMJ8NZ4LAynVGPkXFp8zpJBubYmn579wXtqhZb0iwn9a1iWLaViYmJ3891obOwYtLEvcYMGyWAAkwJdv6accEhi8LjGVr11SenpC5f61g3NcO0vjCAIc+DjZ2dnWexddWSbYa9nlkM+8BgWsxsK7FZ1VLzRaACNokmtdnyu1QMQgF7Rlh4zWWTAwAAAABJRU5ErkJggg=="},
   { label: "Запомнить значок веб-сайта как base64", func: "copyFaviconData()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAI2bv/9RVpf/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAACIkvD/Jia6/ywpq/8AAAAAAAAAAAAAAAAAAAD/AAAA/wbwAf90qpv/Ymic/1RWqP9OUKr/W2Ch/2dumf9YYKT/Ly/B/xQP3/8MB9P/JCGb/wAAAAAAAAAAAAAAAAAAAP8G8AH/U5ea/ycr8f8VIP3/HiP4/ywo8v8sIvb/LCL2/ywi9v8KBOj/BQDe/wQAtv8tK4P/AAAAAAAAAAAAAAD/BvAB/3Sqm/9iaJz/Tim3/0UuuP9GPrT/R0ex/zk8uf8gIMz/FRDe/xEMzv8jIJz/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8AAAD/SqOR/yImvP8sLKj/AAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/BvAB/3Sqm/9KW5r/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAABvAB/wbwAf8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/BvAB/wbwAf8G8AH/AAAAAAAAAAAAAAAAAAAAAAAAAAAG8AH/AAAAAAAAAP8G8AH/AAAAAAAAAAAAAAAAAAAA/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAP8G8AH/BvAB/wbwAf8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/BvAB/wbwAf8AAAAAAAAA/wAAAP8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/AAAAAAAAAAAG8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wbwAf8G8AH/BvAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOesQQBjrEGAAaxBwACsQcABrEHDg6xBwAesQcAPrEHAD6xBw8+sQcPprEHD8axBwAGsQQABrEGAAaxB//+sQQ=="},  
   { separator: ''},
   { label: "Сохранить ярлык страницы как…", func: "saveShortcuts()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADzqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/BP8k/wT/JP8E/yT/BP8k/5XLDv/zqgD/86oA//I1///yNf//86oA//OqAP/zqgD/86oA//OqAP+Vyw7/lcsO/wT/JP8E/yT/BP8k/5XLDv+Vyw7/86oA//OqAP/yNf//8jX///OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA//02AP/9NgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP/9NgD//TYA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/wT/JP+Vyw7/86oA//OqAP/zqgD/86oA/wA31v8AN9b/86oA//9If///SH//86oA//OqAP/zqgD/86oA/5XLDv8E/yT/lcsO//OqAP/zqgD/86oA//OqAP8AN9b/ADfW//OqAP//SH///0h///OqAP/zqgD/86oA//OqAP+Vyw7/BP8k/5XLDv/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/lcsO/5XLDv+Vyw7/86oA//OqAP/zqgD/86oA/0CA//9AgP//86oA/07+9f9O/vX/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP9AgP//QID///OqAP9O/vX/Tv71//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/86oA//OqAP/zqgD/AACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQAArEEAAKxBAACsQQ=="},
   { separator: ''},  
   { label: "Кодировать изображение(текст.файл) в base64", func: "copyFaviconbase()", image: "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AIAQ/wCAEf8AgA//AIAR/wCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AgBX/AIAVAAAAAAAAAAD/AIAo/wCA//8AgP//AID//wCA//8AgP//AIAoAAAAAAAAAAAAAAAAAAAAAP8AgBL/AID//wCA//8AgA3/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgBAAAAAAAAAAAAAAAAD/AIAR/wCA//8AgP//AIAK/wCACv8AgP//AID//wCAIf8AgAX/AIAh/wCA//8AgP//AIAQAAAAAAAAAAAAAAAA/wCACv8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAUAAAAA/wCABf8AgP//AID//wCACgAAAAD/AIAQ/wCADP8AgCH/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCABf8AgCH/AID//wCA//8AgAv/AIAh/wCA//8AgP//AID//wCA//8AgP//AIAH/wCAB/8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AIAg/wCA//8AgP//AID//wCA//8AgP//AID//wCAB/8AgAf/AID//wCA//8AgP//AID//wCA//8AgP//AIAh/wCAC/8AgP//AID//wCAHP8AgBz/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCACf8AgA7/AIAMAAAAAP8AgAj/AID//wCA//8AgAP/AIAD/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCABQAAAAAAAAAA/wCADf8AgAr/AIAL/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCAB/8AgAr/AID//wCA//8AgCH/AIAH/wCAJf8AgP//AID//wCAI/8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAf/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgCT/AID//wCA//8AgAr/AIAK/wCA//8AgP//AIAKAAAAAP8AgCj/AID//wCA//8AgP//AID//wCA//8AgCP/AIAM/wCA//8AgP//AIAN/wCADf8AgP//AID//wCADQAAAAAAAAAA/wCAEP8AgBH/AIAP/wCAEf8AgBAAAAAAAAAAAP8AgBT/AIAVAAAAAAAAAAD/AIAV/wCAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQcH5rEGA8KxBAHCsQQBwrEEIQKxBAACsQQAArEEAAKxBAQCsQQwArEEAAKxBAACsQYAArEHBmaxB//+sQQ=="},
   { separator: ''},
   { label: "Сохранить всю страницу как PDF", func: "savePageToPDF()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYUw4pJt3V/+Rb1D8lnFP/55zTf+VcVH/lXJS/5VyUv+VclL/lXJS/5VyUv+VclL/k3BR/J56Wv9cRzSkAAAAAJNvUKTto2L/4ppe/uehZf/Pmmr/noZv/9Scav/Wl17/1plh/9eZYf/XmWH/15lh/9eZYf/WmGD/2Jlg/suRXP9mRiuk8rWA/397dP1akKn/rqqi/3LF3f8Mntj/4dLJ///+9f/48u3/9e7n//bt5v/47+f/+O/n//jv5//rvZP/1ZJX/a9/VP9+lrD8AIvz/xOt+f8Douv/ALb6/wC28/9tmar/z8jJ//Lq5/////7//v////n9///6/P3//////+Ta0P/PjVP/pnpT/IWds/+aiXj/5efl/8Px//951/3/LMz//wCx8/8GltL/NIu3/4ycqf/l29L////+//n6+//8/v//3tXM/8+OVP+oe1P/6K57/86QWP/r6Ob////////++v/r9/z/oOb9/zDL//8Arf//AI/r/ydysv+hpqr//PTr///////d1Mz/0I5U/6h7U//osH//wo5g/+fm5P/7/f//9vf5//z7+////vv/9/r8/5Dc/P8Oqv7/AJf//wF02v9ffZ7/8Ojh/+Ha1P/NjFL/qHtT/+ewf//Ej1//7O3r///////+/v7//v7+//f5+v/6+vv////8/8Tq/f8hp/7/AJH//wB18/8/bqj/1MGu/9mXXv+leVH/569+/8iSYv+/tKn/wLew/8O5sf/P0M////////7+/v/3+fv////7/9Hv/v8hoP3/AIn//wB4/v84ZqL/w4NH/619VP/nsYD/x45c/9W5of/bv6j/0Jxt/6J/YP+spqD/2N3i//7////6+/3///76/8vr/v8Slv7/AIb+/wBz//83VH7/nW1B/+ewfv/Fjl7/7Ozr///////9+/r/9d7K/9Ghdv+jd1D/pJ6Y/+jt8f/9///////7/6fb/v8Ahv7/AYD//wRp6f95YlT/57B//8SOXv/n5uT//v7///r7/P/8/v////////XRsv/DhEv/loBu/9DX3P/9/v/////7/2O6/f8Afv//FnTU/5JtTf/nsH//xY9e/+jn5f/+/f//+fj5//n4+P/5+Pn/+/////Xbxf/Wj1D/nX1h/+Ll6P////7/3+/3/w+V//8tcbP/qHJB/+WuffzCjV7/5efn///////+/v7//////////////v7///////XRsP/TnW3/8fT3//////////z/ddD//0Nxl/+zdkH88LmH/9CRWP2+qJT/0M7N/8/Jxv/Pysf/z8rH/8/Kxv/Py8n/zsO6/7+pmP/PzMv/zsnG/9bNyP+nsK7/h4R3/b2BT/+Sb1Ck7qxw/9GSW/69hlb/wYhX/8CIV//AiFf/wIhX/8CIVv/BiVj/xI1d/8CIVv/BiFf/vYZW/9STW/7ppmv/bE80pAAAAACUd16k+sui/+7AmPzwwpr/8MKa//DCmv/wwpr/8MKa//DCmf/vwZj/8MKa//DCmv/uwJj8+cui/5N3XaQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
   { label: "Сохранить всю страницу или выбранное как HTML", func: "savePageToHTML()", image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAACzElEQVQ4jV2STW8bZRDHf/Psrr11nZhgVKcKaSmUiArRKBRVIMgH4BKJ7xAp5MSFiA+Rc28ckBAoipC4koJQLyAaVFChIlQllDRWmjRev8Qvu14/+wwHx6ZlpNFcZn7zn79GVJW1tbXc6urqijHGqKoAPF3TgcVaq8owXJbphx99fOOnWzcHoqqsr68/t7y83BARVBXnHHraXo3a3HoUU8gFAHRTS2Bg/7C2Zx7vXPIBwjA0p3BU9Zns9i3vvVrhr6MWzlpee+EsRqAbHc3+/Pee7wPkcrkx4P+g0IMvb/5Iv5/iXEaWZQS+By578MaVy9YH8H3fE5FnANZajqMmgcAnH7yN73mICMYMd21sbLy7srKiPkA+n3/qBLhzv8p+EuOfTUjShPbODvOVWa5fnRsvKBaLAcAIMFbw+bc/EBVn8At7SPcQ60LSiVm++P0fGu0e7y++yalvHoABCILAiAj7hzU+vfcVT6zPVGmR3x4/xJoLSH6BVu4cN777nnQwQETI5XL/AYwxRkS4ff8BEk6Q2pBfq3dxUuHMmWt0kgFGStTDY/7YrTLybQwYPU2cpgzsCd1OgmSzWHeOR7VjWicxaT9lxn+HfjoYmWnGHgAiIsydf5HKnUXiThehQDG4Tr3e5KR7hN8XilnGKxfOoyrDgZECwIgIb125xIxxTGVdgjRG4pR2+zbG/sIkD7l2cYJyaYLMOZxzjBV4nueLCI1GnaWFab65t4OXt4gUuFqYJ8gGuPYBCxdLHNciys9PkaapjAHGGM8YQ7lcZv71OaYmC/xZPaJHTN4cUgpDXrr8MtOVaUqTRXzfY3t7u7O0tDR82a2trfkkSTSOY+31etrpdLTZbGoURRpFkdbrTY3qTW00mhrHse7u7t4tl8uhqg4VxHHcPDg4+ExVHeBU1YmIU1WnisucZtamLszn01ar9WRzc/PrWq2WAPwLJ7l2ULfXOAMAAAAASUVORK5CYII="},
   { label: "Сохранить выделенный текст как txt файл", func: "saveSelectionToTxt()", image: "data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAQE6AAAAZAAAAGgAAAJmAAACZgAAAGYAAABmAAAAZgAAAGYAAABmAAAAZgAAAGYAAABlAAAAaQABAmYAAQEjAAAAADlVkOdVcKHxVXKi8kdklPJLZpfyU3Cg8lJvn/JRbZ7yUW+g8lFun/JRbp/yUG6e8lVyofFVdKjzLkV45wAAAFABAQEAaIzF/3y34v9wsuL/cJe0/0lpgv9bjLP/dLLh/2+v3v9sq9v/cK3d/3Gv3v9sqtv/b7Df/4G77P9VcqT2AAAAVAMDAQBnir/+ZqfU/pDB4/7a3uD+j46N/kxYXv6To6/+1er4/tXp+P7J3/D+1ej4/svg8v6Gut/9aqzd/lhxnvAAAABSAwIBAGaIvv9pptX/ocfj//f4/P/P0tX/g4CA/1xZWf+Woqr/2uz8/9Hl+f/W5fT/2Of3/5fC4v5tq93/Vm+e8QAAAFIDAgEAaYm+/3mw2/+iyeX/9Pn8/+z0+//IzNL/d3h5/0tMTv+Mkpn/xdvs/9Hp/f/O4PL/msXk/nmz4/9XcJ/xAAAAUgMDAQBti7//k7/h/6fL5v/v9fn/4u73/9Dk9P+8wMT/YGpx/zJJWv94iJf/ztzo/9Pp/P+ZwuD+gLfk/1dwnvEAAABSAwMBAHOPwf+myub/sNHp//j7/P/6/P3/8fr///r39P+sxdP/IXWq/xJJcv+NjZD/0+Lu/6TN7f6Ft+L/WXGf8QAAAFIDAwEAd5LD/7PR6/+ZxOP/0ePx/97r9f/Y5/L/3e32/8Tc7f9gseT/CHK3/zBYdv+HiY7/lL/f/pLE7/9bcJ3xAAAAUgMDAQB4k8P/xNvx/5/F5f+kyOX/qMrn/6TH5f+kyOX/sM/q/5e51P9Mm83/GHm3/xxIav9fdYf+pMvs/1x1pfIAAABTAwMBAHmSxf/O4/T/y9/y/8Hb9P/C3PX/wNv0/7vW7/+93ff/utDm/42fsf9Gjbn/EXS2/ytSbv6Fj5r/WnGc8gAAAFICAwEBepPE/tHk9f/S5PX/vMjV/7fCzP+3w8//uMPP/7XBzP+6ytf/qa+4/3h/hv9Ghaz/JoO+/jNXdP82PVnyAAAAVgACAgCBmcb/2+r3/dHh8fyPkpX/kI6N/5yam/+dnJ3/paWk/6enpf+sr6//mpSR/3Bubf9SjbD8H4C+/QsrSvcCAAB/AAAAA3yVx//j8///3u/7/52gpf6pqKf+uLm5/rq7u/7Ly8v+ycnI/paWlf6LjY/+np2f/Xh+g/5gnL7/MX+y/xcgJ80BAgNNN1OUs6W84fDA1O73mJyj/ainpv+2trb/t7e4/8fHyP/Fxsb/kZGQ/4eGhP+vucT/j6G+/W53k/NlkbnwNoOv/AgiNb8CCBsQDRo/YwsaO3B0d33arKyp9q2trfWvr6/2u7u79ru7vPawr7H1sbCt9nJ2gOQIGD6bFCFEYB0qPE1Bf6SpEz9cggAAAAMCAQEBAQAAADIyMmlDQ0ONQUFBhUFBQYVCQkGFQkJBhUhISIRNTU2OKysrZAEAAAUBAQAAAgEAAAkEAAEDAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="},
   { separator: ''},
   { label: "Запомнить изображение как base64, в контекстном меню", value: "Save.WebScreenShotOnImage"},
   { label: "Сохранить выделенный текст в файл, в контекстном меню", value: "Save.SelectionToFile" },
   { label: "Открыть выделенный текст в внешнем редакторе, в контекстном меню", value: "Save.TextToEditor"},
];

var menuPopup = self.appendChild(document.createXULElement("menupopup"));
array.forEach((m,i)=> {
   if ("separator" in m) { menuPopup.appendChild(document.createXULElement("menuseparator")); return };
   var mItem = menuPopup.appendChild(document.createXULElement("menuitem"));
   mItem.setAttribute("label", m.label);
   mItem.setAttribute("class", "menuitem-iconic");
   if ("image" in m) mItem.setAttribute("image", m.image || array[i-1].image); 
   if ("value" in m) { 
       mItem.setAttribute('type', 'checkbox');
       mItem.setAttribute('checked', cbu.getPrefs(m.value) );
       mItem.onclick =()=> cbu.setPrefs(m.value, !cbu.getPrefs(m.value));
       }
   if ("func" in m) mItem.addEventListener("command", ()=> eval(m.func.toString()));
});
menuPopup.setAttribute("onclick", "event.stopPropagation()");


function aDate() {
 var t=new Date();
 var y=1900+t.getYear();
 var min=t.getMinutes(); if (min<10){min="0"+min};
 var h=t.getHours();
 var m=t.getMonth();switch(m){case 0: m="января";break;case 1: m="февраля";break;case 2: m="марта";break;case 3: m="апреля";break;case 4: m="мая";break;case 5: m="июня";break;case 6: m="июля";break;case 7: m="августа";break;case 8: m="сентября";break;case 9: m="октября";break;case 10: m="ноября";break;default: m="декабря";}
 var d=t.getDate();
 var curdate=d+" "+m+" "+y+" "+"г";
 var myfilename=curdate;
 return myfilename;
}
 

function WebScreenShotonImage(image) {
      var canvas = document.createElementNS(xhtmlns, 'canvas');
      canvas.width = image.naturalWidth;
      canvas.height = image.naturalHeight;
      var ctx = canvas.getContext('2d');
      ctx.drawImage(image, 0, 0);
      var base64 = canvas.toDataURL();
      gClipboard.write(base64);
   
      // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
      
     // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { 
     Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается
      }, "");
};



var saveToFile = function (fileContent, fileName) {
    var uc = Components.classes['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
    uc.charset = 'utf-8';
    fileContent = uc.ConvertFromUnicode(fileContent);

    var nsIFilePicker = Components.interfaces.nsIFilePicker;
    var fp = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
    fp.init(window, '', fp.modeSave);
    fp.defaultString = fileName;
    fp.appendFilters(fp.filterHTML);
    fp.appendFilters(fp.filterAll);
    fp.open(function (rv) {
  if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
    var stream = Components.classes['@mozilla.org/network/file-output-stream;1'].createInstance(Components.interfaces.nsIFileOutputStream);
    stream.init(fp.file, 0x02|0x20|0x08, 0666, 0);
    stream.write(fileContent, fileContent.length);
    stream.close();
  }
});
};


function savePageToHTML() {
var vert=`javascript:(function(){var getSelWin=function(w){if(w.getSelection().toString())return w;for(var i=0,f,r;f=w.frames[i];i++){try{if(r=getSelWin(f))return r}catch(e){}}};var selWin=getSelWin(window),win=selWin||window,doc=win.document,loc=win.location;var qualifyURL=function(url,base){if(!url||/^([a-z]+:|%23)/.test(url))return url;var a=doc.createElement('a');if(base){a.href=base;a.href=a.protocol+(url.charAt(0)=='/'%3F(url.charAt(1)=='/'%3F'':'//'+a.host):'//'+a.host+a.pathname.slice(0,(url.charAt(0)!='%3F'&&a.pathname.lastIndexOf('/')+1)||a.pathname.length))+url}else{a.href=url};return a.href};var encodeImg=function(src,obj){var canvas,img,ret=src;if(/^https%3F:%5C/%5C//.test(src)){canvas=doc.createElement('canvas');if(!obj||obj.nodeName.toLowerCase()!='img'){img=doc.createElement('img');img.src=src}else{img=obj};if(img.complete)try{canvas.width=img.width;canvas.height=img.height;canvas.getContext('2d').drawImage(img,0,0);ret=canvas.toDataURL((/%5C.jpe%3Fg/i.test(src)%3F'image/jpeg':'image/png'))}catch(e){};if(img!=obj)img.src='about:blank'};return ret};var toSrc=function(obj){var strToSrc=function(str){var chr,ret='',i=0,meta={'%5Cb':'%5C%5Cb','%5Ct':'%5C%5Ct','%5Cn':'%5C%5Cn','%5Cf':'%5C%5Cf','%5Cr':'%5C%5Cr','%5Cx22':'%5C%5C%5Cx22','%5C%5C':'%5C%5C%5C%5C'};while(chr=str.charAt(i++)){ret+=meta[chr]||chr};return'%5Cx22'+ret+'%5Cx22'},arrToSrc=function(arr){var ret=[];for(var i=0;i<arr.length;i++){ret[i]=toSrc(arr[i])||'null'};return'['+ret.join(',')+']'},objToSrc=function(obj){var val,ret=[];for(var prop in obj){if(Object.prototype.hasOwnProperty.call(obj,prop)&&(val=toSrc(obj[prop])))ret.push(strToSrc(prop)+': '+val)};return'{'+ret.join(',')+'}'};switch(Object.prototype.toString.call(obj).slice(8,-1)){case'Array':return arrToSrc(obj);case'Boolean':case'Function':case'RegExp':return obj.toString();case'Date':return'new Date('+obj.getTime()+')';case'Math':return'Math';case'Number':return isFinite(obj)%3FString(obj):'null';case'Object':return objToSrc(obj);case'String':return strToSrc(obj);default:return obj%3F(obj.nodeType==1&&obj.id%3F'document.getElementById('+strToSrc(obj.id)+')':'{}'):'null'}};var ele,pEle,clone,reUrl=/(url%5C(%5Cx22%3F)(.+%3F)(%5Cx22%3F%5C))/g;if(selWin){var rng=win.getSelection().getRangeAt(0);pEle=rng.commonAncestorContainer;ele=rng.cloneContents()}else{pEle=doc.documentElement;ele=(doc.body||doc.getElementsByTagName('body')[0]).cloneNode(true)};while(pEle){if(pEle.nodeType==1){clone=pEle.cloneNode(false);clone.appendChild(ele);ele=clone};pEle=pEle.parentNode};var sel=doc.createElement('div');sel.appendChild(ele);for(var el,all=sel.getElementsByTagName('*'),i=all.length;i--;){el=all[i];if(el.style&&el.style.backgroundImage)el.style.backgroundImage=el.style.backgroundImage.replace(reUrl,function(a,b,c,d){return b+encodeImg(qualifyURL(c))+d});switch(el.nodeName.toLowerCase()){case'link':case'style':case'script':el.parentNode.removeChild(el);break;case'a':case'area':if(el.hasAttribute('href')&&el.getAttribute('href').charAt(0)!='%23')el.href=el.href;break;case'img':case'input':if(el.hasAttribute('src'))el.src=encodeImg(el.src,el);break;case'audio':case'video':case'embed':case'frame':case'iframe':if(el.hasAttribute('src'))el.src=el.src;break;case'object':if(el.hasAttribute('data'))el.data=el.data;break;case'form':if(el.hasAttribute('action'))el.action=el.action;break}};var head=ele.insertBefore(doc.createElement('head'),ele.firstChild);var meta=doc.createElement('meta');meta.httpEquiv='content-type';meta.content='text/html; charset=utf-8';head.appendChild(meta);var title=doc.getElementsByTagName('title')[0];if(title)head.appendChild(title.cloneNode(true));head.copyScript=function(){if('$'in win)return;var f=doc.createElement('iframe');f.src='about:blank';f.setAttribute('style','position:fixed;left:0;top:0;visibility:hidden;width:0;height:0;');doc.documentElement.appendChild(f);var str,script=doc.createElement('script');script.type='text/javascript';for(var name in win){if(name in f.contentWindow||!/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name))continue;try{str=toSrc(win[name]);if(!/%5C{%5Cs*%5C[native code%5C]%5Cs*%5C}/.test(str)){script.appendChild(doc.createTextNode('var '+name+' = '+str.replace(/<%5C/(script>)/ig,'<%5C%5C/$1')+';%5Cn'))}}catch(e){}};f.parentNode.removeChild(f);if(script.childNodes.length)this.nextSibling.appendChild(script)};head.copyScript();head.copyStyle=function(s){if(!s)return;var style=doc.createElement('style');style.type='text/css';if(s.media&&s.media.mediaText)style.media=s.media.mediaText;try{for(var i=0,rule;rule=s.cssRules[i];i++){if(rule.type!=3){if((!rule.selectorText||rule.selectorText.indexOf(':')!=-1)||(!sel.querySelector||sel.querySelector(rule.selectorText))){style.appendChild(doc.createTextNode(rule.cssText.replace(reUrl,function(a,b,c,d){var url=qualifyURL(c,s.href);if(rule.type==1&&rule.style&&rule.style.backgroundImage)url=encodeImg(url);return b+url+d})+'%5Cn'))}}else{this.copyStyle(rule.styleSheet)}}}catch(e){if(s.ownerNode)style=s.ownerNode.cloneNode(false)};this.appendChild(style)};var sheets=doc.styleSheets;for(var j=0;j<sheets.length;j++)head.copyStyle(sheets[j]);head.appendChild(doc.createTextNode('%5Cn'));var doctype='',dt=doc.doctype;if(dt&&dt.name){doctype+='<!DOCTYPE '+dt.name;if(dt.publicId)doctype+=' PUBLIC %5Cx22'+dt.publicId+'%5Cx22';if(dt.systemId)doctype+=' %5Cx22'+dt.systemId+'%5Cx22';doctype+='>%5Cn'};var href = 'data:text/html;charset=utf-8,' + encodeURIComponent(doctype + sel.innerHTML + '\n<!-- This document saved from ' + (loc.protocol != 'data:' ? loc.href : 'data:uri') + ' -->');var a = document.documentElement.appendChild(document.createElement("a"));a.setAttribute("href", href);var name = selWin ? win.getSelection().toString() : (title && title.text ? title.text : loc.pathname.split('/').pop());name=name.replace(/[:\\\/<>?*|"]+/g, '_').replace(/\s+/g, ' ').slice(0, 100).replace(/^\s+|\s+$/g, '');name += (function () {var d = new Date(), z=function(n){return '_' + (n < 10 ? '0' : '') + n};return z(d.getHours()) + z(d.getMinutes()) + z(d.getSeconds());})();a.setAttribute("download", name + ".html");a.click();a.remove();})();`;
gBrowser. loadURI(vert, {triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()});
};


function saveShortcuts() {
var file = Components.classes["@mozilla.org/file/local;1"].
           createInstance(Components.interfaces.nsIFile);
file.initWithPath(folderpath);

if( !file.exists() || !file.isDirectory() ) {   file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0x1B6);}

var savetodir=folderpath+"\\"; 
var urllink=gBrowser.currentURI.spec;
var out=getTabLabel();
var filename=savetodir+out+'.url';
var data="[InternetShortcut]\r\nURL="+urllink+"\r\n";

saveToFile(data, filename);
 // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
   // подсказка
   var notific = 'Сохранил в: ' + folderpath;
   var image = gBrowser.selectedBrowser.mIconURL;
   Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(image, filename, notific);
};

// Кодировать изображение или текстовой файл в base64 .............
function copyFaviconbase(){
var fp = window.makeFilePicker();
fp.init(window, "Открыть файл", fp.modeOpen);
fp.appendFilter("Text and images", "*.txt; *.text; *.css; *.js; *.ini; *.rdf; *.xml; *.html; *.htm; *.shtml; *.xhtml; *.jpe; *.jpg; *.jpeg;\
                                    *.gif; *.png; *.bmp; *.ico; *.svg; *.svgz; *.tif; *.tiff; *.ai; *.drw; *.pct; *.psp; *.xcf; *.psd; *.raw");
  fp.open(re=> { 
  if ( re != fp.returnOK ) return;
   var file = fp.file;
   var inputStream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
   inputStream.init(file, 0x01, 0600, 0);
   var stream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIBinaryInputStream);
   stream.setInputStream(inputStream);
   var encoded = btoa(stream.readBytes(stream.available()));
   var contentType = Cc["@mozilla.org/mime;1"].getService(Ci.nsIMIMEService).getTypeFromFile(file);
   var dataURI = "data:" + contentType + ";charset=utf-8;base64," + encoded;
   gClipboard.write(dataURI);
   //Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Скопировал файл как base64");
    // стиль для изображение в сплывающей подсказке ....
      var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
      var uri = makeURI('data:text/css,'+ encodeURIComponent('#alertImage { height: 25px !important; width: 25px !important; }'));
      sss.loadAndRegisterSheet(uri, 0);
      
     // alertsService.showAlertNotification(base64, self.label, "Запомнил изображение как base64", false, "", (s, t)=> { 
     Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService).showAlertNotification(dataURI, self.label, "Запомнил изображение как base64", false, "", (s, t)=> {
         if (t == 'alertfinished')
             sss.unregisterSheet(uri, 0); // удалить стиль когда подсказка закрывается
      }, "");
});
};

// Сохранить страницу как PDF файл через сервис 'pdfmyurl.com' .............
function savePageToPDF() {
      var loc = gBrowser.currentURI.spec;
   var vert = "http://pdfmyurl.com?url=" + loc;
  
   gBrowser. loadURI(vert, {
   triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
   });
}; 

// Сохранить иконку текущего сайта с диалогом сохранения .............
function saveFavicon() {
       var uri = gBrowser.currentURI;
       function getSiteName() {
                  try { var domain = uri.host.split('.') } catch(e) { return "" };
                   domain = (domain.length == 2) ? domain[0] : domain[1]
                   return domain.charAt(0).toUpperCase() + domain.slice(1).split('.')[0] + " ";  
            };
    var url = gBrowser.selectedTab.image;
    url && saveImageURL(
        url, getSiteName(), null, false, false, null, null,
        /^data:(image\/[^;,]+)/i.test(url) ? RegExp.$1.toLowerCase() : Cc["@mozilla.org/mime;1"]
            .getService(Ci.nsIMIMEService).getTypeFromURI(Services.io.newURI(url)),
        null, PrivateBrowsingUtils.isContentWindowPrivate(content || window), document.nodePrincipal
    );
};


// Скопировать иконку текущего сайта как base64 код .............
function copyFaviconData() {
   var img = new Image();
   img.src = gBrowser.selectedTab.image;
   WebScreenShotonImage(img);
};


// Сохранить выделенный текст или весь текст на странице как txt файл .............
function saveSelectionToTxt() {

let browserMM = gBrowser.selectedBrowser.messageManager;
        browserMM.addMessageListener('getSelection', function listener(message) {
        var sel = message.data;
       !sel && document.getElementById("cmd_selectAll").doCommand(); 
     
   // создать название файла из заголовка страницы и текущего времени и сохранить текст ....
   var fileTitle = getTabLabel() + '  ' + aDate().replace(/:/g, ".");
   saveURL("data:text/plain," + encodeURIComponent(gBrowser.currentURI.spec + ("\r\n\r\n" + sel)), 
                                fileTitle + ".txt", null, false, false, null, window.document);
   !sel && goDoCommand("cmd_selectNone"); 
 browserMM.removeMessageListener('getSelection', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelection", content.document.getSelection().toString())', false);
};

//Добавыть в контекстное меню страницы пункт "Запомнить изображение как base64"..........................................................................................
(popup => addEventListener("popupshowing", {
    handleEvent(e) {
        if (this.shouldHide) return;

        var menuitem = document.createXULElement("menuitem");
        menuitem.id = "content-baseItem";
        menuitem.className = "menuitem-iconic";
        menuitem.setAttribute("oncommand", "copyImageAsBase64()");
        menuitem.setAttribute("label", "Запомнить изображение как base64");
        menuitem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AIAQ/wCAEf8AgA//AIAR/wCAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AgBX/AIAVAAAAAAAAAAD/AIAo/wCA//8AgP//AID//wCA//8AgP//AIAoAAAAAAAAAAAAAAAAAAAAAP8AgBL/AID//wCA//8AgA3/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgBAAAAAAAAAAAAAAAAD/AIAR/wCA//8AgP//AIAK/wCACv8AgP//AID//wCAIf8AgAX/AIAh/wCA//8AgP//AIAQAAAAAAAAAAAAAAAA/wCACv8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAUAAAAA/wCABf8AgP//AID//wCACgAAAAD/AIAQ/wCADP8AgCH/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCABf8AgCH/AID//wCA//8AgAv/AIAh/wCA//8AgP//AID//wCA//8AgP//AIAH/wCAB/8AgP//AID//wCA//8AgP//AID//wCA//8AgP//AIAg/wCA//8AgP//AID//wCA//8AgP//AID//wCAB/8AgAf/AID//wCA//8AgP//AID//wCA//8AgP//AIAh/wCAC/8AgP//AID//wCAHP8AgBz/AID//wCA//8AgAf/AIAH/wCA//8AgP//AIAh/wCACf8AgA7/AIAMAAAAAP8AgAj/AID//wCA//8AgAP/AIAD/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCABQAAAAAAAAAA/wCADf8AgAr/AIAL/wCA//8AgP//AIAH/wCAB/8AgP//AID//wCAB/8AgAr/AID//wCA//8AgCH/AIAH/wCAJf8AgP//AID//wCAI/8AgP//AID//wCAB/8AgAf/AID//wCA//8AgAf/AIAL/wCA//8AgP//AID//wCA//8AgP//AID//wCA//8AgCT/AID//wCA//8AgAr/AIAK/wCA//8AgP//AIAKAAAAAP8AgCj/AID//wCA//8AgP//AID//wCA//8AgCP/AIAM/wCA//8AgP//AIAN/wCADf8AgP//AID//wCADQAAAAAAAAAA/wCAEP8AgBH/AIAP/wCAEf8AgBAAAAAAAAAAAP8AgBT/AIAVAAAAAAAAAAD/AIAV/wCAFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQcH5rEGA8KxBAHCsQQBwrEEIQKxBAACsQQAArEEAAKxBAQCsQQwArEEAAKxBAACsQYAArEHBmaxB//+sQQ==");
        popup.append(menuitem);
        addDestructor(() => menuitem.remove());

        menuitem.copyImageAsBase64 = () => {
            var {osPid} = gContextMenu.actor.manager.browsingContext.currentWindowGlobal;
            if (osPid == -1) osPid = Services.appinfo.processID;
            for(var ind = 0, len = Services.ppmm.childCount; ind < len; ind++) {
                var pmm = Services.ppmm.getChildAt(ind);
                if (pmm.osPid == osPid) break;
            }
            pmm.loadProcessScript("data:;charset=utf-8," + encodeURIComponent(this.code()), false);
        }
        this.handleEvent = () => menuitem.hidden = this.shouldHide;
    },
    get shouldHide() {
        return !gContextMenu.onImage;
    },
    code: () => `(targetIdentifier => {

        var image = ChromeUtils.import("resource://gre/modules/ContentDOMReference.jsm")
            .ContentDOMReference.resolve(targetIdentifier);

        var canvas = image.ownerDocument.createElementNS("${xhtmlns}", "canvas");
        canvas.width = image.naturalWidth;
        canvas.height = image.naturalHeight;
        var ctx = canvas.getContext("2d");
        ctx.drawImage(image, 0, 0);
        var base64 = canvas.toDataURL();

        Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
            .copyStringToClipboard(base64, Ci.nsIClipboard.kGlobalClipboard);

        Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
            .showAlertNotification(base64, "${self.label}", "Запомнил изображение как base64");
    })(${
        JSON.stringify(gContextMenu.targetIdentifier)
    })`
}, false, popup || 1))(document.getElementById("contentAreaContextMenu"));


// Добавляем в контекстного меню страницы новые пункты .............
((contextMenu, el)=> {

   // в контекстного меню выделенного текста ....
   var saveItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el);
   saveItem.id = "content-saveItem";
   saveItem.setAttribute("label", "Сохранить выделенный текст в файл");
   saveItem.setAttribute("class", "menuitem-iconic");
   saveItem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAADAgBEDRIXnwxQjKQNWp6pDFWXqAxXm6gMV5moDFeaqAxXmqgMV5qoDFebqAxVlqgNW5+pCkyIogwSFqgDAgBHDQoFhyszOv8hheP+IJH7/x+L8v8fjfb/H433/x+N9v8fjfb/H432/x+N9/8fi/L/IJH7/yGF5P0kLTTvDAcDgwgICIQ8Ojf/0czA+Oji1fzh18r85NzO/OTbz/zj287849vO/OPbzvzk3M/84dfK++ji1f3Sy8D5NDIvywYGB3kKCgqFQ0A8/+XXw/v979f/9uTO//rp0f/66NH/+ujR//rn0f/66NH/+ujR//bkzv/979f/5tfD/UZBPv8KCwqEDQwMhUVDQP/f08X7+OrZ/+zf0P/v5NP/8OPT/+/j0//v4tP/8OPT/+/j0//s39D/+OrZ/+DTxfxEQj//DAwMhA8PD4VKR0T/4dXG+/rr2v/v4tH/9OXU//Ll1P/z5dT/8+XU//Pl1P/05NT/7+DR//rr2v/i1cX7SkhE/w8PD4USEhKFT0xI/+XXxfv97tr/9ePR//no1P/459T/+OfU//jn1P/459T/+OfU//Xk0f/97tr/5dfF+09MSf8SEhGFFRQUhVNQTv/j2cv7+u/g//Hm2P/169v/9Orb//Tq2//06tv/9erb//br3P/x5tf/+e/g/+PZzPtTUU7/FBQUhRgXF4VXU1D/2828+/Lk0f/q2sf/7d3K/+3dyv/t3cr/7N3K/+rayP/r28n/69vI//Ll0v/azbv7VlNP/xgXF4UfHh6FTktJ/1JOTPtZVFL/Uk5L/1FNSv9RTUr/UU1K/1JPTP9YVVD/VVJP/09NSv9WUk//UU1L+05LSf8fHh2FIR8fhVVTUP9FQkD7UlBM/6Wlj/+4uJ7/sLCX/7S0mv+xsJn/oKCQ/6+vmv+hoYv/TEtH/0NCQPtVUk//IR8fhSMhIIVcWVb/SEVF+19dVv/f3sP////e//X10v///93/2di8/1lYWP+eno//5+fG/19dV/9JRkb7W1hV/yMhIYUkJCOFXltZ/0tJSPtdW1f/0NC4/+/u1P/h4cj/8PDV/7++q/8vLC7/e3lw/9fWv/9eXVf/TElJ+15bWf8lJCKEJSQjhF9cWf9LSUf5XVtX/tbVwf/5+OL/6enV//j54v/GxrX/QD0+/42Kgv/d3cr/YF5a/k5LSvlhXlv/JSUjhCkoKIZpZWT/VVJR/WNhXP/V1cT//f3s/+3t3v/8/Or/zc2//01LSf+VlIz/4eDS/2hmYv9YVVT8aWVj/ycmJoIaGRlYSEVE1DYzM8NKSUfP0dHG9/X16P/n59v+7e3g/+jo3f/X2M3+6uve/9bWzPdOTUvNOjg3y0RBQLwPDw8lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="); 
   saveItem.onclick =()=> saveSelectionToFile();

   var editorItem = contextMenu.insertBefore(document.createXULElement("menuitem"), el);
   editorItem.id = "content-editorItem";
   editorItem.setAttribute("label", "Открыть выделенный текст в внешнем редакторе");
   editorItem.setAttribute("class", "menuitem-iconic");
   editorItem.setAttribute("image", "data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAQAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAA////AIiafwC85K4AS1ZGANLsyABKU0UAy+m+AL/lsQC14aQAn9WMAJ/QjQCsrKwAqNyXAOPz3ADe8dcA2e/QANPtyQDM68EAxei4AL7lrwC14aUArt6dAJfOhACdz4sAgICAALThpQDg8doA3vHVANjuzgDR7MYAyum+AMLmtQC7460AsuCjAK3dmgCUy4AArdedANDsxQDL6sAAz+PIAMviwwDH4L4Awd62ALvbrwC02KcArdafAKbTlgCEu3EAtNWoANPqywDa8NIA1u7NANHtxwDK6cAAw+e3ALzkrwC14aYAr9+dAKXbkQCJwnMA1+3QAKncmADd8dQAyuLBAMbgvAC6264AttmoAK/XoACn1JYAotKPAJbNgwB9tWgA4+zfANju0ADT7coAz+vFAMPntgC95K8Art6eAKndlQCa1IYAi8R3AP3+/QDD37kAvt2yALjarACz2KYArdaeAKHRjwCXzoUAj8V6AI6/ewDu8e4Awea2AMrqwQDG6LoAweazALnjqwCz4KQAr9+cAKbbkwCd2IkAlc1/AKbTlQC73K8At9qqALDXowCp1ZsApdOVAKDRjQCYzoUAksx7AIi+cwCu0aEAp9yUAMXougDC5rYAveSuALfipwCw4J8AqdyXAKLajwCd2IcAlNR9AI3FdwDU6ssAqdWZAKPSkgCe0YsAmc6GAJDLfQB/tmoA3enZAJfWhACc2IkApNuRAKTbkACj2pAAodqOAKHZjgCl25IAotmOAIzHdgAPAAAA2JIKAAAA9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOzARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcrkUA9CUMAAAAAAAAAAAAAAAAAAAAAAAAAA8AAQAAAAEAAAAAAAAAVCIMAAAAAAABAAAAuwP/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAACZDSMAAQAAAAAAAAAAAAAAAAAAAP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAABAEAABHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZGRkZGRkZGRkZAAAAAAAZAQEBAQEBAQEBARkAAIeHiImKi4yNjY5+AQEZAD4mJlZXRH+AgYKDhIVdGQBzJnR1dnd4eXp7fH1+ARkAGiYnaWprbG1ub3Bxcl0ZACdeJl9gYWJjZGVmZ2gBGQAAAyZUVVZXWEVZWltcXRkAAA1KS0wfTU45T1BRUlMZAAA+P0BBK0JDREVGR0hJGQAAAzIzNDU2Nzg5Ojs8PRkAACYnKCkqKywtLi8YMDEZAAAAGhscHR4fICEiIyQlGQAAAA0ODxAREhMUFRYXGBkAAAADBAUGBwYIBgkGChkAAAAAAAACAAIAAgACAAIAAPgBAADwAAAAwAAAAIAAAACAAAAAgAAAAIAAAADAAAAAwAAAAMAAAADAAAAAwAAAAOAAAADgAAAA4AEAAPqrAAA="); 
   editorItem.onclick =()=> textToEditor();


    // устанавливаем где и при каких настройках показывать новые пункты ....
   addEventListener('popupshowing', e=> {
      if (e.target != e.currentTarget) return;
      var sel = gContextMenu.isTextSelected;
      saveItem.hidden = !sel || !cbu.getPrefs("Save.SelectionToFile");
      editorItem.hidden = !sel || !cbu.getPrefs("Save.TextToEditor"); 
      }, false, contextMenu);

   // удалять новые пункти при изминениях ....
   addDestructor(()=> {
      saveItem.remove(); editorItem.remove();
   });   
})(document.getElementById("contentAreaContextMenu"), document.getElementById("context-sep-open"));


// Сохранить выделенный текст в файл на рабочем столе .............
function saveSelectionToFile() {

 let browserMM = gBrowser.selectedBrowser.messageManager;
 browserMM.addMessageListener('getSelect', function listener(message) {
   // создать текст для записи
   var url = gBrowser.currentURI.spec;
   if (/\.рф/.test(url.host)) url = convertFromUnicode("UTF-8", url);
   
   var time = convertFromUnicode("UTF-8", aDate().replace(/:/g, "."));
   var text = convertFromUnicode("UTF-8", message.data); 
   var title = convertFromUnicode("UTF-8", getTabLabel());
   
   var text = "..............................................................\n"
            + title + " - " + time + "\n" + url + "\n\n" + text + "\n\n\n";
   var text = text.replace(/\u000A/g, "\u000D\u000A").replace(/\u000D\u000D\u000A/g, "\u000D\u000A");

   // путь к файлу и название файла
   var file = Services.dirsvc.get("Desk", Ci.nsIFile); 
   file.append("Save - " + (aDate().replace(/:/g, ".")) + ".txt");
          
   // создать файл с текстом или добавлять текст в файл
   var foStream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
   file.exists() ? foStream.init(file, 0x02 | 0x10, 0664, 0) : foStream.init(file, 0x02|0x08|0x20, 0666, 0);
   foStream.write(text, text.length);
   foStream.close();
    // всплывающая подсказка дает возможность открыть файл если кликнуть на подсказке
       var notificat = 'Сохранил выделенный текст в файл на рабочий стол'; 
   var image = gBrowser.selectedTab.image || self.image;
   Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
    .showAlertNotification(image, notificat, "Кликни чтобы открыть файл", true, "", (s, t)=> { 
      if (t == 'alertclickcallback') file.launch();
   }, "");
 browserMM.removeMessageListener('getSelect', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false);

};


// Создать текстовой файл с выделенным текстом в папке профиля и открыть в редакторе .............
function textToEditor() {


 let browserMM = gBrowser.selectedBrowser.messageManager;
 browserMM.addMessageListener('getSelect', function listener(message) {
   // создать текст для записи
    var text = convertFromUnicode("UTF-8", message.data); 
    var file = Services.dirsvc.get('ProfD', Ci.nsIFile);
   file.append("TextToEditor.txt");
   custombuttonsUtils.writeFile(file.path, text);
   file.launch(); 
          

 browserMM.removeMessageListener('getSelect', listener, true);
});
        browserMM.loadFrameScript('data:,sendAsyncMessage("getSelect", content.document.getSelection().toString())', false);
};


// Конвертировать текст в юникод .............
function convertFromUnicode(charset, str) {
     var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
     converter.charset = charset;
     str = converter.ConvertFromUnicode(str);
     return str + converter.Finish();
 
};

// Получить название вкладки без не сохраняемых символов и лишних пробелов ..............
function getTabLabel() { 
   var label = gBrowser.selectedTab.label;      
   var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
   return label.substring(0, 50);
};
 ((main, parts) => this.onmousedown = e => {
    if (e.button) return;
    this.onmousedown = null;

    var df = MozXULElement.parseXULToFragment(`
        <menugroup orient="vertical">
            <menuseparator/>
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить всю страницу как PNG"
                value="all"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAzAAAAiAcFBa4KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwoJCa8KCQmvCgkJrwsJCaECAQE/BQMDAAAAAJUgICD4V1ZW/2FhYf5hYWH/YmFh/2BgYP9fX1//X19f/19fX/9gYGD/YmFh/2FhYf9gYGD+ZmVl/1RSUuIVFBQtCgkJy1paWv+Li4v9h4eH/oiIiP6FhYX+i4uL/pKSkv6Sk5P+kpKS/ouLi/6FhYX+iIiI/oiIiP6Hh4f7lZaW/25tbYQNDQ3OcHBw/5KSkv6Li4v/i4uL/5mZmf+EhIT/ZGRk/1tbWv9kZGT/hISE/5mZmf+Li4v/jY2N/4yMjPyWl5f/iomJjQ4NDc13d3f/m5ub/pWVlf+goKD/XFxc/ygoKP8fHyD/GBsb/yAhIv8pKSn/W1tb/6CgoP+Wlpb/lpaW/J6env+Jh4eMDg4OzX1+fv+ioqL+qqqq/1hYWP8ZGRn/Ghwb/x4dHP8mIh//FhQR/xUWF/8aGhr/WFhY/6urq/+cnJz8pKSk/4qJiYwPDg7Ng4OD/7W1tf6MjIz/Ghoa/xYYGP8uKCb/ZEAo/5xyOP++saL/RD45/xISE/8bGxv/jY2N/6+vr/ypqan/ioiIjA8PD82IiIj/xMTE/l1cXP8LDAz/JiId/1o3LP9ADgD/mGog//Dt6P/VysX/Ih4Z/wsMDf9eXl7/v7+//K6urv+KiYmMEA8PzY+Pj//Kysr+SEhH/wEDBv9MPi7/hlES/3dCAP+VZAn/tJVO/7eVXf9OQTL/AAIE/0pJSf/FxcX8tLS0/4qJiYwQEBDNm5ub/9/e3/5SUlL/AAAA/0M7Mf/aya7/ybiO/5RmEf9aIAD/cjkX/z80KP8AAAD/U1JS/9nZ2fzAwMD/i4qKjBEREc2oqKn/8O/w/oeGhv8AAAD/DAsK/6qkof/17uj/nW8l/14eCf9hPTr/ExUU/wAAAP+Hh4f/6urq/MzMzf+Mi4uMERERzbCwsv/r6uz+3Nzd/yoqKv8AAAD/ExEP/2heU/9yWjv/UD0u/xcXFv8AAAD/Kioq/93d3v/l5eb81NTV/4yLi4wSERHNuLm5/+/v8P7z8/P/xsbG/yAgIP8AAAD/AQEB/wAAAP8BAQH/AAAA/yAgIP/Gxsb/9PT0/+np6vzb29v/jIuLjBIREc2+vb7/+Pj5/uvr7P/7+/v/4ODg/3Nyc/8uLi7/Hh4d/y0sLP9zc3P/4ODg//v7+//s7O3/8/P0/OHg4f+Mi4uLFBMTyMPDw//////7+Pj4/ff29v38/Pz9/////fr6+v3u7u79+vr6/f////38/Pz99/b2/fn5+f37+/v53t7e/5KSko4GBgZ7m5yc//j4+P/w8fH/8fLy//Dw8P/u7u7/8vLy//X19f/y8vL/7u7u//Dw8P/x8vL/8vLy/uXl5f/BwcH+k5GRUAAAAAQeHR1yb25uxn59fcZ9fHzGfXx8xn18fMZ9e3vGfHt7xn17e8Z9fHzGfXx8xn18fMZ9fHzGgH9/xYmIiGVaV1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить видимую часть страницы как PNG"
                value="page"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAIBkAAAEAIAAMDQAAFgAAACgAAAAgAAAAMgAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD29fT/2tra/8jIyP/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8XFxf/FxcX/xcXF/8jIyP/a2tr/9vX0/+zs7P/ak0b/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/9qTRv/s7Oz/7Ozs/+J9Dv/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+//7+/v/+/v7//v7+/6SdmP/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/+vn4//z7+v/6+fj/4n0O/+zs7P/s7Oz/4n0O//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r//Pv6//z7+v/8+/r/aFtT//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//j39v/ifQ7/7Ozs/+zs7P/ifQ7/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P9oW1P/7+zq/+/s6v/v7Or/8O3r//Dt6//w7ev/8O3r//Dt6//w7ev/8O3r/+/s6v/w7ev/9fTy/+J9Dv/s7Oz/7Ozs/+J9Dv/49/b/+Pf2//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4/2hbU//q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/y8O//4n0O/+zs7P/s7Oz/4n0O//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/+Pf2//j39v/49/b/aFtT/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe//Dt6//ifQ7/7Ozs/+zs7P/ifQ7/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P/29fT/9vX0//b19P9oW1P/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/7uro/+J9Dv/s7Oz/7Ozs/+J9Dv/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx//Ty8f/08vH/9PLx/2hbU//x7+3/8vDv//Hv7f/x7+3/8e/t//Lw7//x7+3/8e/t//Lw7//x7+3/8vDv//Hv7f/29fT/4n0O/+zs7P/s7Oz/4n0O//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//8vDv//Lw7//y8O//aFtT/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/6igmP+ooJj/qKCY/8vGwf/ifQ7/7Ozs/+zs7P/ifQ7/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f/x7+3/8e/t//Hv7f9nWlL/aFtT/2hbU/9nWlL/Z1pS/2hbU/9oW1P/Z1pS/2daUv9oW1P/aFtT/2hbU/9nWlL/pJyX/+J9Dv/s7Oz/7Ozs/+J9Dv/w7ev/8O3r//Dt6//w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Hv7f/w7ev/8O3r//Dt6//x7+3/8O3r//Dt6//w7ev/8e/t//Dt6//w7ev/8O3r//Dt6//w7ev/4n0O/+zs7P/s7Oz/4n0O/+/s6v/v7Or/7uro/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/v7Or/7+zq/+/s6v/u6uj/7+zq/+/s6v/ifQ7/7Ozs/+zs7P/ifQ7/7uro/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7uro/+zo5v/u6uj/7uro/+7q6P/s6Ob/7uro/+7q6P/u6uj/7Ojm/+7q6P/u6uj/7Ojm/+J9Dv/s7Oz/7Ozs/+J9Dv/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/7Ojm/+zo5v/s6Ob/4n0O/+zs7P/s7Oz/4n0O/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/q5uT/6ubk/+rm5P/ifQ7/7Ozs/+zs7P/ifQ7/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+nl4v/p5eL/6eXi/+J9Dv/s7Oz/7Ozs/+J9Dv/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/5uHe/+bh3v/m4d7/6eXi/+bh3v/m4d7/5uHe/+nl4v/m4d7/5uHe/+bh3v/p5eL/4n0O/+zs7P/s7Oz/4n0O/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/m4d7/5uHe/+bh3v/ifQ7/7Ozs/+zs7P/ifQ7/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+bh3v/k39z/5uHe/+Tf3P/m4d7/5N/c/+J9Dv/s7Oz/7Ozs/+J9Dv/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/i3Nn/4tzZ/+Lc2f/k39z/4n0O/+zs7P/s7Oz/4n0O/+Lc2f/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/h29j/4dvY/+Hb2P/ifQ7/7Ozs/+zs7P/ifQ7/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+DZ1v/g2db/4NnW/+J9Dv/s7Oz/9fTy/+J9Dv/8+/r/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/+vn4//r5+P/6+fj/4n0O//X08v/8+/r/6KFU/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ifQ7/4n0O/+J9Dv/ooVT//Pv6/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить выбранный элемент страницы как PNG"
                value="click"/>
    
            <menuitem class="menuitem-iconic"
                image="data:image/x-icon;base64,AAABAAEAEREAAAEAIADwBAAAFgAAACgAAAARAAAAIgAAAAEAIAAAAAAAyAQAAAAAAAAAAAAAAAAAAAAAAADDn2Hfz5pE/8eVQP7IlkH/yJZB/8iWQf/IlUH/yJVA/8iVQP/IlED/yJQ//8iUP//IlD//yJM+/8iTPv/Hkj3/nI1w//bDbP//8OH//+zW///s1///69b//+rV///p1P//59L//+XQ///izf//38n//9vG///ZxP//1b///dG////Prf/KlkX/88N4/v37///99Pj//fT6//vy9v/68fT/+u/y//rt8P/66u3/+ufq//rl6P/64eT/+93h//3a3//71d7//9LK/86XR//0xHb//vv////18///9fT///f5///4////9f7///P8///v+f//7Pb//+nz///m8f//4eb//9vZ//3Y2v//1Mb/zphH//TGd//+/////Pj1///7///Q58r/m9aV/6TZnv+i15r/otWY/6LTlv+j0pb/mc6M/9DXuf//3+P//Nnc///Wyf/OmUf/9MZ3//7////8+/j//////53WnP+Y5pn/rvGv/6PvpP+e7p//me6b/5nvm/95533/mM+L///j7f/629z//9jL/86ZR//0xnf//v////z9+v//////qtup/8Xzxf/a/tn/z/vO/8n7yf/D+sL/xPvD/6Hzo/+j05b//+Tu//re3///2cz/zplI//XGeP/+/////P36//////+n26f/uvC6/9T71P/K+Mr/xvjG/8D3wP+/+L//nfCf/6LTlf//5u//+t/g///cz//OmUj/9MZ3//7////8/fr//////6rcqv/G9MX/3//f/9n92f/V/NX/0PzQ/9H+0P+s9a7/pdSY///o8f/64OL//9zP/86aSP/0xnf//v////z9+f//////ndid/5TjlP+v7q//qeyp/6jsqf+k7KX/p+6n/4Tlh/+Z0Y7//+r0//rh4v//3tH/zppI//TGd//+/////v77///////Y8Nj/p9+n/6/jr/+t4a3/rd2p/67bpv+u2ab/p9Wc/9jgx///6Oz//OPl///e0f/Omkj/9MV1//7//////fr///78///+/f///////////////////P////j////0+///8fn//+vu///m4v/94+P//97P/86ZSP/zx3v//v/////+/f///////f////v////7////+/////v+///7+///+/f///vz/P/98Pr//+33//3p9///5OL/zppL//a1Sv/0xoL/9cR7//XEfP/1xHz/9cR8//XEfP/1xH3/9cR8//XCev/1wXr/9b94//W9d//1u3X/87l0//y6bP/Llj7/+pMA/vWBAP/1gwD/9YMA//WDAP/1gwD/9YMA//WDAP/1gwD/9YQA//WEAP/1hAD/9YQA//WEAP/zhAH//okA/8qLIv3xpzP/4ptV/+OdU//jnVP/451T/+OdU//jnVP/451T/+OdU//jnVL/451S/+OdUv/jnVL/451S/+GdVf/qnUf/2aRJ/9q0c9/8yn7/98V5/vjGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6//jGev/4xnr/+MZ6/vrIe/+jj2y4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
                label="Сохранить выбранную область страницы как PNG"
                value="clipping"/>
        </menugroup>
    `);
    var menugroup = df.firstChild;
    menugroup.setAttribute("context", "");
    menugroup.setAttribute("oncommand", "handleCommand(event);");
    menugroup.handleCommand = e => {
        var name = _id + ":DataURLReady";
        main = main.replace("%MESSAGE_NAME%", name);

        var urls = {}, configurable = true, enumerable = true;
        Object.entries(parts).forEach(([key, part]) => Object.defineProperty(urls, key, {
            configurable, enumerable, get() {
                var value = `data:;charset=utf-8,({${
                    encodeURIComponent(main + part)
                }%0A}).init("${key}")`;
                Object.defineProperty(urls, key, {configurable, enumerable, value});
                return value;
        }}));
        var getTabLabel = () => {
            var label = gBrowser.selectedTab.label;      
            var label = label.replace(/[:+.\\\/<>?*|"]+/g, " ").replace(/\s\s+/g, " ");
            return label.substring(0, 50);
        }
        var listener = msg => {
            var fp = makeFilePicker();
            fp.init(window, "Сохранить как…", fp.modeSave);
            fp.appendFilter("", "*.png");
            fp.defaultString = getTabLabel() + ".png";
            fp.open(res => {
                if (res == fp.returnCancel || !fp.file) return;
                var wbp = makeWebBrowserPersist(), args = [
                    Services.io.newURI(msg.data), document.nodePrincipal,
                    null, null, null, null, fp.file, null
                ];
                wbp.saveURI.length == 9 && splice(args);
                wbp.saveURI(...args);
            });
        }
        var splice = arr => {
            var fox74 = parseInt(Services.appinfo.platformVersion) >= 74;
            var args = [fox74 ? 7 : 2, 0, fox74 ? Ci.nsIContentPolicy.TYPE_IMAGE : null];
            (splice = arr => arr.splice(...args))(arr);
        }		
        messageManager.addMessageListener(name, listener);
        addDestructor(() => messageManager.removeMessageListener(name, listener));

        (menugroup.handleCommand = e => gBrowser.selectedBrowser.messageManager
            .loadFrameScript(urls[e.target.value], false)
        )(e);
    }
    menuPopup.querySelector('menuitem[label*="ярлык"]').after(df);
})(`
    init(cmd) {
        cmd.startsWith("c")
            ? this[cmd].init(this[cmd].parent = this)
            : this[cmd]();
    },
    capture(win, x, y, width, height) {
        var canvas = win.document.createElementNS("${xhtmlns}", "canvas");
        canvas.width = width;
        canvas.height = height;
        var ctx = canvas.getContext("2d");
        var tryDraw = ind => {
            try {ctx.drawWindow(win, x, y, canvas.width, canvas.height, "white")}
            catch(ex) {canvas.height = ind * canvas.width; tryDraw(--ind);}
        }
        tryDraw(17);
        sendAsyncMessage("%MESSAGE_NAME%", canvas.toDataURL("image/png"));
    },
    `, {

    all: `all() {
        var win = content;
        this.capture(win, 0, 0, win.innerWidth + win.scrollMaxX, win.innerHeight + win.scrollMaxY);
    }`,
    page: `page() {
        var win = content, doc = win.document, body = doc.body, html = doc.documentElement;
        var scrX = (body.scrollLeft || html.scrollLeft) - html.clientLeft;
        var scrY = (body.scrollTop || html.scrollTop) - html.clientTop;
        this.capture(win, scrX, scrY, win.innerWidth, win.innerHeight);
    }`,
    clipping: `clipping: {
        handleEvent(e) {
            if (e.button) return false;
            e.preventDefault();
            e.stopPropagation();
            switch(e.type) {
                case "mousedown":
                    this.downX = e.pageX;
                    this.downY = e.pageY;
                    this.bs.left = this.downX + "px";
                    this.bs.top = this.downY + "px";
                    this.body.appendChild(this.box);
                    this.flag = true;
                    break;
                case "mousemove":
                    if (!this.flag) return;
                    this.moveX = e.pageX;
                    this.moveY = e.pageY;
                    if (this.downX > this.moveX) this.bs.left = this.moveX + "px";
                    if (this.downY > this.moveY) this.bs.top  = this.moveY + "px";
                    this.bs.width = Math.abs(this.moveX - this.downX) + "px";
                    this.bs.height = Math.abs(this.moveY - this.downY) + "px";
                    break;
                case "mouseup":
                    this.uninit();
                    break;
            }
        },
        init() {
            var win = {};
            Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager)
                .getFocusedElementForWindow(content, true, win);
            this.win = win.value;

            this.doc = this.win.document;
            this.body = this.doc.body;
            if (!HTMLBodyElement.isInstance(this.body)) {
                Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService)
                    .showAlertNotification("${self.image}", ${JSON.stringify(self.label)}, "Не удается захватить!");
                return false;
            }
            this.flag = null;
            this.box = this.doc.createElement("div");
            this.bs = this.box.style;
            this.bs.border = "#0f0 dashed 2px";
            this.bs.position = "absolute";
            this.bs.zIndex = "2147483647";
            this.defaultCursor = this.win.getComputedStyle(this.body, "").cursor;
            this.body.style.cursor = "crosshair";
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            var pos = [this.win, parseInt(this.bs.left), parseInt(this.bs.top), parseInt(this.bs.width), parseInt(this.bs.height)];
            this.body.style.cursor = this.defaultCursor;
            this.body.removeChild(this.box);
            this.parent.capture.apply(this, pos);
            ["click", "mouseup", "mousemove", "mousedown"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`,
    click: `click: {
        getPosition() {
            var html = this.doc.documentElement;
            var body = this.doc.body;
            var rect = this.target.getBoundingClientRect();
            return [
                this.win,
                Math.round(rect.left) + (body.scrollLeft || html.scrollLeft) - html.clientLeft,
                Math.round(rect.top) + (body.scrollTop || html.scrollTop) - html.clientTop,
                parseInt(rect.width),
                parseInt(rect.height)
            ];
        },
        highlight() {
            this.orgStyle = this.target.hasAttribute("style") ? this.target.style.cssText : false;
            this.target.style.cssText += "outline: red 2px solid; outline-offset: 2px; -moz-outline-radius: 2px;";
        },
        lowlight() {
            if (this.orgStyle) this.target.style.cssText = this.orgStyle;
            else this.target.removeAttribute("style");
        },
        handleEvent(e) {
            switch(e.type){
                case "click":
                    if (e.button) return;
                    e.preventDefault();
                    e.stopPropagation();
                    this.lowlight();
                    this.parent.capture.apply(this, this.getPosition());
                    this.uninit();
                    break;
                case "mouseover":
                    if (this.target) this.lowlight();
                    this.target = e.target;
                    this.highlight();
                    break;
            }
        },
        init() {
            this.win = content;
            this.doc = content.document;
            ["click", "mouseover"].forEach(type=> this.doc.addEventListener(type, this, true));
        },
        uninit() {
            this.target = false;
            ["click", "mouseover"].forEach(type=> this.doc.removeEventListener(type, this, true));
        }
    }`
});

Отредактировано katana (29-05-2020 10:12:53)

Отсутствует

 

№1464629-05-2020 15:36:03

kokoss
Участник
 
Группа: Members
Зарегистрирован: 15-02-2018
Сообщений: 1739
UA: Firefox 52.0

Re: Custom Buttons

Dumby
Как изменить иконку "DOM Inspector" в about:addons,  или хотя бы цвет ? А то так не очень...

скрин
167f62b21a40.png

Add, в FF 76

Отредактировано kokoss (29-05-2020 16:18:36)


Win7

Отсутствует

 

№1464729-05-2020 20:17:39

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

Re: Custom Buttons

katana пишет

Можно сделать чтобы работал во всех CustomizableUI.createWidget? просто везде подставлять "custombuttons.initAutoPopup(self);"

Ну, если собрался удалить Custom Buttons (или, даже если нет), то замени
custombuttons.initAutoPopup=
на
ucf_custom_script_win.initAutoPopup=

еще знать надо куда закем, и что вместо "self" ставить

Да просто (тогда) допиши в код кнопки, в какое-нибудь top-level место
(например, в самый конец) ucf_custom_script_win.initAutoPopup(this);


kokoss пишет

Как изменить иконку "DOM Inspector" в about:addons

Смотри в сторону object-position/background хака.
Плюс избегать data: адресов, поскольку about:addons целиком инфицирован csp.


Или, внеси свой вклад:
выложи предпочитаемую иконку (32×32, можно несколько, на выбор),
и, если мне не непонравится, тогда попробую втащить её внутрь расширения
и выложить обновку, к тому же, 7.0.6, наверно, уже подрасклеился.

Отредактировано Dumby (29-05-2020 20:19:11)

Отсутствует

 

№1464829-05-2020 21:44:22

kokoss
Участник
 
Группа: Members
Зарегистрирован: 15-02-2018
Сообщений: 1739
UA: Firefox 52.0

Re: Custom Buttons

Dumby пишет

Смотри в сторону object-position/background хака.
Плюс избегать data: адресов, поскольку about:addons целиком инфицирован csp.

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

Или, внеси свой вклад:
выложи предпочитаемую иконку (32×32, можно несколько, на выбор)

Хорошо, поищу что нибудь подходящее!
Add, кое что нашёл:

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

Выделить код

Код:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAACXBIWXMAAAsSAAALEgHS3X78AAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAMAUExURV+KtxlGclmIvV+OwhxGehhCdBdBdR1JgSBJgiNXjyRNhiZYiiZfmCdRjCdclCtknCxXkzBblzBonzNklDRsozVfnTlxpzpkoztqmT51qj9qqEN5rkRxrUh9skl3sk2Ctk59uFKGuVODvVeKvVyOwV6PxmGTxXafzHihzJa32Ze42djY2Nzc3ODg4OPj4+fn5+vr6+/v7/Pz8/f39/v7+zU1NTY2Njc3Nzg4ODk5OTo6Ojs7Ozw8PD09PT4+Pj8/P0BAQEFBQUJCQkNDQ0REREVFRUZGRkdHR0hISElJSUpKSktLS0xMTE1NTU5OTk9PT1BQUFFRUVJSUlNTU1RUVFVVVVZWVldXV1hYWFlZWVpaWltbW1xcXF1dXV5eXl9fX2BgYGFhYWJiYmNjY2RkZGVlZWZmZmdnZ2hoaGlpaWpqamtra2xsbG1tbW5ubm9vb3BwcHFxcXJycnNzc3R0dHV1dXZ2dnd3d3h4eHl5eXp6ent7e3x8fH19fX5+fn9/f4CAgIGBgYKCgoODg4SEhIWFhYaGhoeHh4iIiImJiYqKiouLi4yMjI2NjY6Ojo+Pj5CQkJGRkZKSkpOTk5SUlJWVlZaWlpeXl5iYmJmZmZqampubm5ycnJ2dnZ6enp+fn6CgoKGhoaKioqOjo6SkpKWlpaampqenp6ioqKmpqaqqqqurq6ysrK2tra6urq+vr7CwsLGxsbKysrOzs7S0tLW1tba2tre3t7i4uLm5ubq6uru7u7y8vL29vb6+vr+/v8DAwMHBwcLCwsPDw8TExMXFxcbGxsfHx8jIyMnJycrKysvLy8zMzM3Nzc7Ozs/Pz9DQ0NHR0dLS0tPT09TU1NXV1dbW1tfX19jY2NnZ2dra2tvb29zc3N3d3d7e3t/f3+Dg4OHh4eLi4uPj4+Tk5OXl5ebm5ufn5+jo6Onp6erq6uvr6+zs7O3t7e7u7u/v7/Dw8PHx8fLy8vPz8/T09PX19fb29vf39/j4+Pn5+fr6+vv7+/z8/P39/f7+/v///7NhU6sAAAC4SURBVHjanJPBCsIwDIa/dMXTbh487DYQfP/XEbyKJy8TRNrUw8Zo5mTRHH7aFD7yJ41AQ896XMgENkICRwKy8lRQzg5Czw798hh4bROikhapAWgnVRehLFJ74Dmpj7D0IIBO+ithAKAFlKvbRaaZL918Ujrg7pmmqUEqgt9FIhrCjUNFSA5CIRtCNlpcfbAuHmYW+Q/CyfQhO/+kfHRydJE8nZRIQ6gmSkVx1SBCXN3McTsds3gPAKAnRWxUOHeZAAAAAElFTkSuQmCC

Отредактировано kokoss (29-05-2020 22:28:25)


Win7

Отсутствует

 

№1464929-05-2020 23:23:56

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

Re: Custom Buttons

Dumby пишет

Или, внеси свой вклад:
выложи предпочитаемую иконку (32×32, можно несколько, на выбор),

32x32.png

Выделить код

Код:

data:image/png;charset=utf-8;base64,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

Отредактировано unter_officer (29-05-2020 23:24:35)


«The Truth Is Out There»

Отсутствует

 

№1465029-05-2020 23:43:13

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

Re: Custom Buttons

kokoss пишет

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

Вот для примера может для др. расширений пригодится

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

Выделить код

Код:

@-moz-document url-prefix("chrome://mozapps/content/extensions/") {
addon-card[addon-id="add_toolbar_buttons@vitaliy.ru"] .card-heading-icon {
    object-position: var(--addon-icon-size, 32px) center !important;
    background-color: transparent !important;
    background-repeat: no-repeat !important;
    background-size: var(--addon-icon-size, 32px) !important;
    background-image: url("chrome://user_chrome_files/content/vertical_top_bottom_bar/svg/configure-toolbars-16.svg") !important;
}
}

Отсутствует

 

Board footer

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