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

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

№1515116-02-2021 01:03:57

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

Re: Custom Buttons

Dumby
Откровенно говоря и не надеялся на положительный ответ. Слишком сложная и действительно великолепная кнопка. Но что интересно, работает в предложенном варианте. Только со строкой меню "Восстановить последнюю сессию" проблема - пропадает после очистки списка закрытых вкладок. И после очистки по ПКМ в кнопке классическое меню CB. В общем, раз "малой кровью" не получается, буду использовать вариант CB. Спасибо за предложенный вариант, взял на заметку.
egorsemenov06
Эта у меня тоже есть из поста https://forum.mozilla-russia.org/viewtopic.php?pid=784332#p784332

Отсутствует

 

№1515216-02-2021 10:01:02

Garalf
Участник
 
Группа: Members
Зарегистрирован: 19-09-2017
Сообщений: 316
UA: Firefox 86.0

Re: Custom Buttons

solombala
Чето не могу победить стробоскоп в 86

Отсутствует

 

№1515316-02-2021 13:43:09

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 77.0

Re: Custom Buttons

Garalf
беты версии не обсуждаю.

Отсутствует

 

№1515416-02-2021 15:54:32

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

Re: Custom Buttons

Раньше в СВ были две удобные фичи. Первая: можно было открыть окно и запретить в нем загрузку нежелательного контента.

Выделить код

Код:

let win = open('','',param);
docShell = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation).QueryInterface(Ci.nsIDocShell);
docShell.allowImages = false;
docShell.allowJavascript = false;
docShell.allowPlugins = false;

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

Выделить код

Код:

loadURI(PlacesUtils.getURLAndPostDataForKeyword('keyword')[0]);

Есть сейчас замена этим двум фичам?

Отсутствует

 

№1515517-02-2021 12:19:57

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

Re: Custom Buttons

hartumov пишет

Есть сейчас замена этим двум фичам?

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

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

Выделить код

Код:

OpenBrowserWindow().addEventListener("XULFrameLoaderCreated", {
	async handleEvent(e) {
		if (!e.target.matches("[id^=panel-].browserSidebarContainer :scope"))
			return;
		await Promise.resolve();
		var func = type => {
			var restrict = () => {
				destroy();
				docShell.allowImages = docShell.allowJavascript
					= docShell.allowPlugins = false;
			}
			var destroy = () => {
				removeEventListener(type, restrict);
				removeEventListener("unload", destroy);
			}
			addEventListener(type, restrict);
			addEventListener("unload", destroy);
		}
		var url = "data:charset=utf-8," + encodeURIComponent(
			`(${func})("DOMDocElementInserted");`
		);
		var {type} = e, stack = e.target.parentNode;

		var unload = () => {
			stack.removeEventListener(type, this);
			tab.removeEventListener("TabClose", tabClose);
		}
		var win = e.target.ownerGlobal;
		win.addEventListener("unload", unload, {once: true});

		var tabClose = () => {
			stack.removeEventListener(type, this);
			win.removeEventListener("unload", unload);
		}
		var tab =  win.gBrowser.getTabForBrowser(e.target);
		tab.addEventListener("TabClose", tabClose, {once: true});

		win.removeEventListener(type, this);
		(this.handleEvent = e => e.target.messageManager.loadFrameScript(url, false))(e);
		stack.addEventListener(type, this);
	}
});


Вторая
скрытый текст

Выделить код

Код:

PlacesUtils.keywords.fetch("keyword").then(res => res && openLinkIn(res.url.href, "current", {
	postData: res.postData, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
}));

Отредактировано Dumby (18-02-2021 00:52:22)

Отсутствует

 

№1515617-02-2021 20:13:26

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

Re: Custom Buttons

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

Есть сейчас замена этим двум фичам?

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

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

Выделить код

Код:

OpenBrowserWindow().addEventListener("XULFrameLoaderCreated", {
	async handleEvent(e) {
		if (!e.target.matches("[id^=panel-].browserSidebarContainer :scope"))
			return;
		await Promise.resolve();
		var func = type => {
			var restrict = () => {
				destroy();
				docShell.allowImages = docShell.allowJavascript
					= docShell.allowPlugins = false;
			}
			var destroy = () => {
				removeEventListener(type, restrict);
				removeEventListener("unload", destroy);
			}
			addEventListener(type, restrict);
			addEventListener("unload", destroy);
		}
		var url = "data:charset=utf-8," + encodeURIComponent(
			`(${func})("DOMDocElementInserted");`
		);
		var {type} = e, stack = e.target.parentNode;

		var unload = () => {
			stack.removeEventListener(type, this);
			tab.removeEventListener("TabClose", tabClose);
		}
		var win = e.target.ownerGlobal;
		win.addEventListener("unload", unload, {once: true});

		var tabClose = () => {
			stack.removeEventListener(type, this);
			win.removeEventListener("unload", unload);
		}
		var tab =  win.gBrowser.getTabForBrowser(e.target);
		tab.addEventListener("TabClose", tabClose, {once: true});

		win.removeEventListener(type, this);
		(this.handleEvent = e => e.target.messageManager.loadFrameScript(url, false))(e);
		stack.addEventListener(type, this);
	}
});


Вторая
скрытый текст

Выделить код

Код:

PlacesUtils.keywords.fetch("keyword").then(res => res && openLinkIn(res.url, "current", {
	postData: res.postData, triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
}));

Dumby
Первый код открывает новое окно, у меня это настроено на домашнюю страницу. А как сделать, чтобы  в этом окне сразу открылся нужный адрес?


А со вторым кодом ничего не получается. В эту строчку PlacesUtils.keywords.fetch("keyword") вместо keyword я вставляю краткое имя закладки или просто веб адрес. Не происходит ничего, только в консоли пишет Promise { <state>: "pending" }

Отсутствует

 

№1515717-02-2021 21:19:17

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

Re: Custom Buttons

hartumov пишет

А как сделать, чтобы  в этом окне сразу открылся нужный адрес?

Можно заменить первую строку на

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

Выделить код

Код:

openDialog(
	AppConstants.BROWSER_CHROME_URL,
	"_blank", "chrome,all,dialog=no", "нужный_адрес"
).addEventListener("XULFrameLoaderCreated", {

hartumov пишет

вместо keyword я вставляю краткое имя закладки или просто веб адрес. Не происходит ничего, только в консоли пишет Promise { <state>: "pending" }

Интересно, откуда может взяться запись в консоли?
Разве что запускать, собственно, с консоли.


И что значит «или просто веб адрес»? Написано было чётко:

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

При чём тут «веб адрес»? Если приведённому тобой коду, на Firefox 56,
скормить вместо keyword «просто веб адрес», то он тоже ничего не откроет.
А по краткому имени — должен открывать. Может в keyword'е опечатка.

Отсутствует

 

№1515817-02-2021 22:45:03

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

Re: Custom Buttons

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

вместо keyword я вставляю краткое имя закладки или просто веб адрес. Не происходит ничего, только в консоли пишет Promise { <state>: "pending" }

Интересно, откуда может взяться запись в консоли?
Разве что запускать, собственно, с консоли.


И что значит «или просто веб адрес»? Написано было чётко:

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

При чём тут «веб адрес»? Если приведённому тобой коду, на Firefox 56,
скормить вместо keyword «просто веб адрес», то он тоже ничего не откроет.
А по краткому имени — должен открывать. Может в keyword'е опечатка.

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

Выделить код

Код:

loadURI(PlacesUtils.getURLAndPostDataForKeyword('keyword')[0]);

прекрасно с этим справлялся.

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


И еще вопрос, вот в этой строчке

Выделить код

Код:

openLinkIn(res.url, "current"

я меняю current на window - закладка открывается в новом окне. А если меняю на tab, не работает. Почему?

Отсутствует

 

№1515918-02-2021 00:48:37

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

Re: Custom Buttons

hartumov пишет

А не получалось потому, что я вставлял краткое имя букмарклета.

Да, вижу, интересный кейс.
Порылся немного, вот так, вроде, работает.

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

Выделить код

Код:

PlacesUtils.keywords.fetch("keyword").then(res => {
	if (!res) return;
	var {url: {href}, postData} = res;
	var allowPopups = href.startsWith("javascript:");
	openLinkIn(href, "current", {
		postData, allowPopups, allowInheritPrincipal: allowPopups,
		triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
	});
});

hartumov пишет

А если меняю на tab, не работает. Почему?

Потому, что res.url это объект, инстанция URL.
Легко превращается в строку, поэтому так и оставил.
А когда res.url отправляется открываться как tab, то, в цепочке вызовов,
на нём вызывается метод replace(), которого нет. Ошибка останавливает дальнейшее исполнение.
Код был расчитан на "current", но да, надо было, всё таки, передать строку, то есть res.url.href

Отсутствует

 

№1516018-02-2021 18:42:05

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

Re: Custom Buttons

Dumby
Всё получилось. Большое спасибо за помощь и разъяснения!

Отсутствует

 

№1516119-02-2021 14:18:16

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 85.0

Re: Custom Buttons

Dumby
network.proxy.socks_remote_dns -false ///А на простые прокси https подобное можно?
И код: куки delete ? Все очистить

Отредактировано solombala (19-02-2021 23:11:45)

Отсутствует

 

№1516220-02-2021 14:41:07

Ferguss114
Участник
 
Группа: Members
Зарегистрирован: 31-03-2012
Сообщений: 207
UA: Chrome 70.0

Re: Custom Buttons

Как  показать  список закрытых вкладок т. е. вот это menupop#historyUndoPopup
Чтобы не лазить через меню Журнал и т. д... а сразу и отдельно посередине экрана?

Отсутствует

 

№1516320-02-2021 18:01:29

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

Re: Custom Buttons

Ferguss114 пишет

Как  показать  список закрытых вкладок т. е. вот это menupop#historyUndoPopup
Чтобы не лазить через меню Журнал и т. д... а сразу и отдельно посередине экрана?

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

Выделить код

Код:

SessionStore.getClosedTabCount(window) && (this.hpopup || (this.hpopup = (() => {
	var popup = document.createXULElement("menupopup", {is: "places-popup"});
	for(var args of Object.entries({
		context: "",
		placespopup: true,
		tooltip: "bhTooltip",
		onpopupshowing: "fill()",
		id: _id + "-historyUndoPopup"
	}))
		popup.setAttribute(...args);

	popup.fill = () => {
		popup.textContent = "";
		popup.append(RecentlyClosedTabsAndWindowsMenuUtils.getTabsFragment(window, "menuitem"));
		var {width, height} = popup.getBoundingClientRect();
		popup.moveTo((screen.availWidth - width)/2, (screen.availHeight - height)/2);
	}
	return this.appendChild(popup);
})()))
	.openPopupAtScreen();

solombala пишет

Dumby
network

Может лучше пойди подрядить «агента Шифт»,
чтобы подвинуть урлбарский плейсхолдер,
вместо того, чтобы вопрошать про «network» не по адресу.

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

Выделить код

Код:

#urlbar #urlbar-input::placeholder {
	text-indent: 22px !important;
}

Отредактировано Dumby (20-02-2021 22:12:57)

Отсутствует

 

№1516420-02-2021 19:33:03

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 85.0

Re: Custom Buttons

Dumby

Dumby пишет

Может лучше пойди подрядить «агента Шифт»,

Не понял...Куда код вставлять? Явно не в userchrome.

Отсутствует

 

№1516520-02-2021 21:45:28

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

Re: Custom Buttons

solombala пишет

Не понял...Куда код вставлять? Явно не в userchrome.

Да, не userchrome.
Попробовал (по всякому) куда-то в omni.ja, и не получилось, видимо, руки кривые.


А вот в ucf custom_style_agent.css — работает. Ну и такие варианты, конечно, тоже.

CB

Выделить код

Код:

(css => {
	var type = windowUtils.AGENT_SHEET;
	var url = "data:text/css;charset=utf-8," + encodeURIComponent(css);
	windowUtils.loadSheetUsingURIString(url, type);
	addDestructor(() => windowUtils.removeSheetUsingURIString(url, type));
})(`
	#urlbar #urlbar-input::placeholder {
		text-indent: 22px !important;
	}
`);


config.js

Выделить код

Код:

(async css => Cc["@mozilla.org/content/style-sheet-service;1"]
	.getService(Ci.nsIStyleSheetService).loadAndRegisterSheet(
		Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService).newURI(
			"data:text/css;charset=utf-8," + encodeURIComponent(css)
		),
		Ci.nsIStyleSheetService.AGENT_SHEET
	)
)(`
	@-moz-document url(chrome://browser/content/browser.xhtml) {
		#urlbar #urlbar-input::placeholder {
			text-indent: 22px !important;
		}
	}
`);

Отсутствует

 

№1516620-02-2021 22:16:58

dezhnev
Участник
 
Группа: Members
Зарегистрирован: 21-04-2016
Сообщений: 72
UA: Edge 84.0

Re: Custom Buttons

https://github.com/xiaoxiaoflood/firefox-scripts/issues/64

как-то все молчат, а уже "security engineering team", аккуратно назвав тему "Compatability with Future Versions of Firefox", интересуются использованием autoconfig
пока к конкретному случаю привязано (load scripts off-the-main thread), но известно ж как мацарелла похерить все может
неужели 1% юзеров тоже выкинут? кто ж останется..

Отсутствует

 

№1516720-02-2021 23:50:41

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 77.0

Re: Custom Buttons

Dumby
Тонкий ход! Config.js не понадобился.   Тоже omni.ja весь перелопатил...Ну, ты , мастер...
А нельзя это же в польз.скрипт это запихать? Не надо. Вставил в custom_style_agent.css

Отредактировано solombala (21-02-2021 13:32:29)

Отсутствует

 

№1516821-02-2021 00:30:44

Ferguss114
Участник
 
Группа: Members
Зарегистрирован: 31-03-2012
Сообщений: 207
UA: Chrome 70.0

Re: Custom Buttons

Dumby
Список закрытых вкладок - класс, спасибо!!

Отсутствует

 

№1516923-02-2021 11:30:01

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

Re: Custom Buttons

Dumby объясни почему var nodeList = custombuttons.palette.getElementsByClassName("toolbarbutton-1 chromeclass-toolbar-additional"); выдает ошибку (в коде 204 строка)

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

Выделить код

Код:

var dialog; 
var defaultFavicon = "http://forum.mozilla-russia.org/uploaded/custombuttons_button.png";
var checkFavicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAltJREFUOMtt0l9olXUcx/HX8zzThHh07cLQJSZoozXNONMonYxI6zhwhnVnGQldqASZKN50USgWE0ThgCEiZV2JyNDpEnXMLhbuNBC7SOnfVHQj5p/Hmmw+53hxzo7T9bv5Xfy+78/v8/1+P4EnT7NqvIOMVEYkRF6q16hjegxBsVgMgiAoBk/AWRyQminyf2cguzi7veOrjg+xBD8H4+Cd2A7xNJLZxDUkMISrTH8QO7e3R/3z9TCKVSWBJitEOsFC1BOXpZOyfhzFOptPeW3O6wqFgh9Of7/7/bc/2BJoVi11CbVewXziMhiX4SSkY/lx2VktYOOejXJHcwOmeKlKqkWk1jTiholNJ/iu6VAF/iL/uVx3jsiz7lsdlqdNLcaNdMxF2+Jd1s5bB/Zd2qOt70tmVcoyoUijiPq6F7SvPGNp7fLK69b5m322YBs4fOVbn/R8WppJTbkgkqmSKsD+1gOWzmwyMDzgp+unrZm71q5X28Dxv9tt6N70uLsUkUIo0iuiMFIADc80aH7uLd8sOygQ6L7RZf3ZVoqJeAweqmjlSynDyH+joK76RUdWtJsUTvLLP3nvda4ynD5aJ6VMPBL41wmp/puDN0FVWGVyONnlO79pPbXS8IOkYhuSX3EL3JA6Frrgrsj6vit9Fdlr967KnnzTnfuDkrEwFUgu4iJK/X/svFulxP/lj5qG6hkL5r7c2D/Yb82Od12+9runUkYS/MnIhbL1IkJf65Lz+ObR5A0cFJld/kXlhtR1fOS8H8eQYEL0FpnqaS3IoBGhVK9IHid0uT2+/CEAYcfQrHKJYQAAAABJRU5ErkJggg==";
var uncheckFavicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAeJJREFUOMudk81qU1EUhb+7krYZaIkUhQQcqLVG30BKCyoOOtFROgiJZuxTXF/CcaEhhtyROCoO/C19BNOgM0mgk6IpGNN713WQUKMVU1yjczjrfJyz914Bf6hef5wbDn/clFTAFJVVAPTiOO4lSdKJouj7tD+Y3lQqletID7DPAwjwyakAjjLi5XajsX8KUK1W7xmvYTD0wR2hHgjjonAJVJjY95rN5s4JYHNz81o2m60BiWO/Kd0q7YZh6OnXhWGobvfTbfBdICNlnjca2/tBvV7PjYajJ4hF269brdZb/qFqpbpqfB84GgwGzzQajVaQFiUOkiT5wAwtryzvjb/IuXw+XxJQmJRqP4qiZBYgDENjdwDSlIKMixIEQabHGSWpB2DSooRSm/+SHaca00SaJMWzX3RxPBnqyXYfjKUb5XI5M7MGT0MBpQmor8PDwy7wFfvS3Nzc+ixA52NnVVJB0sCJO8G4t5WrhkeSbPv98XH8Lorav3WkXC5nFhZya3ayBmQcu9lqt7q/RrlSuWNYBwKkAxx34thfEGSz85eBEvbFiX232Wy+OhWmWq12JU3Th7bz0xHyZGX7mx2/aLfbn/+aRoCNjY2FpQtLK4gCdjE2QVb0YtPP5ea7W1tbw2n/Tyf84OJw4lGJAAAAAElFTkSuQmCC";
var uncheckStyle = 'background:white url("' + uncheckFavicon + '") no-repeat left center;color:black;padding-left:24px';
var checkStyle = 'background:red url("' + checkFavicon + '") no-repeat left center;color:black;padding-left:24px';

var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
    createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
    converter.charset = "UTF-8";
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 stream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
const text1 = "Активные кнопки";
const text2 = "Неактивные кнопки";
   
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, 0o666, 0);
    stream.write(fileContent, fileContent.length);
    stream.close();
  }
});
};



function createURI(node) {
  var name = node.getAttribute("name") || node.getAttribute("label") || "";
  var image = node.getAttribute("image") || node.getAttribute("cb-stdicon") || "";
  var mode = node.getAttribute("cb-mode") || 0;
  var initcode = node.getAttribute("cb-init") || "";
  var code = node.getAttribute("cb-oncommand") || "";
  var accelkey = node.getAttribute("cb-accelkey") || "";
  var help = node.getAttribute("Help") || "";
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "chrome://custombuttons/content/nbftemplate.xml", false);
  xhr.send(null);
  var doc = xhr.responseXML;
  setText(doc, "name", name, 0);
  setText(doc, "image", image, 1);
  setText(doc, "mode", mode, 0);
  setText(doc, "initcode", initcode, 1);
  setText(doc, "code", code, 1);
  setText(doc, "accelkey", accelkey, 1);
  setText(doc, "help", help, 1);
  var ser = new XMLSerializer();
  var data = ser.serializeToString(doc);
  return "custombutton://" + escape(data);
}

function setText(doc, nodeName, text, make_CDATASection) {
  var node = doc.getElementsByTagName(nodeName)[0], cds;
  if (!node) return;
  if (make_CDATASection) {
    try {
      cds = doc.createCDATASection(text || "");
    } catch(e) {
      cds = doc.createTextNode(text || "");
    }
    node.appendChild(cds);
  } else {
    node.textContent = text;
  }
}

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=y+"г."+" "+d+" "+m+" "+h+":"+min;
 var myfilename=curdate;
 return myfilename;
}

function bDate() {
var curdate=y+" "+"год"+" "+d+" "+m+" "+h+":"+min;
var myfilename=converter.ConvertFromUnicode(curdate);
return myfilename;
}

this.close = function() {
dialog.close();
}

var data = '<?xml version="1.0"?>';
 data += '<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>';
 data += '<window title="' + this.label + '" onload="self.load()" xmlns="' + xulns + '">';
 data += '<keyset>';
 data += '<key keycode="VK_ESCAPE" oncommand="close()"/>';
 data += '</keyset>';
 data += '<vbox flex="1">';
 data += '<richlistbox flex="1" id="listbox" height="555" width="600" context="menupopup" onclick = "self.handle(event)" tooltiptext = "L=Выбрать \nM=Выбрать все \nR=Копировать/Сохранить как… " > ';
 data += '  <listhead>';
 data +=          '<treecol label="Label"  width="342" tooltiptext = "Активные кнопки выделены жирным шрифтом"/>';
 data +=          '<treecol label="Id" width="300" ';
 data +=          'tooltiptext = "Активные кнопки выделены жирным шрифтом"/>';
 data +=    '</listhead>';
 data += '</richlistbox>';
 data += '<popupset>';
 data += '<menupopup id="menupopup">';
 data +=    '<menuitem class="menuitem-iconic" image="data:application/file;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///8A////AESqAABHpgAASKAAAEukAQxMpQMYR6MAAEepAQ9MpgOLRKgACUenAABHpgAARKoAAP///wD///8A////AP///wBEqgAARaIAAFS2FVBj0jS3Y9AzyVG0EUROrwt8TKcDs0ikAANInwAAR6YAAESqAAD///8A////AP///wD///8ARKQAAVvJKJtj0jX/SaAJ/0abCv9UtSH/U7QX8lW5IMddwyfQW8Iii0mqBQ1DqQAA////AP///wD///8A////AEWlAAFYwB6YXsYc5F7GFt9bwA+vVbgWvU6rAKBRrgf0RZgA/02oDP9ezCzJR6UBA////wD///8A////AP///wBFrAAASKIAADiGNQAeYIIpF1iJHVa4GKEve0tFLHl1Pla7J51exRnUWL8VjEetAAP///8A////AP///wD///8AC0WuAAk/tAAANdpIAFD6/wA+7f8gd6jqBlPX+QBE9PIGS8uDLnZLADqNJwAzjDMA////AP///wD///8A////AAAw0QAALc0AAEPdegBI4f8AK8P/ADHX/wAwzf8AL8b/AEno/gAz2zYALtEQAC3VAP///wD///8A////AP///wAAMssAADjSMwBA2pIATen/ADG9/wBe1v8ATcz/ADHK/wBN5/4ASeH/AEvl6wA10DP///8A////AP///wD///8AADnTSQBO5/8ANc7/ADnR/xC+9/8C0f//AMj//wCP8P8ALcX/ACrC/wBE3f8ASeOf////AP///wD///8A////AABI4Z4ARN3/ACvG/wJAxP8Z5v//AMT//wDE//8Axv7/AETM/wA51P8AUervADjSPP///wD///8A////AP///wAAOdRiAFry+QBS6/QATOP/H+P8/xDe//8J1///E9H4/wFE2f8AReC6ADTOEwAyywD///8A////AP///wD///8AADDNAAAyzCcARN7WACvG/wVfzf8d0vf/HM30/whf0/8AI7n/ADzV+AA40kUAMswA////AP///wD///8A////AAAwywAAPNdTAEfg/wAsw/8AOdb/ADLP/wAswv8AReP/AC7H/wA40f8AR+GfADDKAP///wD///8A////AP///wAAMswAADfRQgBY8f8AT+j/AE7o7AA+1/8AK8T/AE7o/wBN5f8AVe7/AD/ZbAAwywD///8A////AP///wD///8AADPMAAAyywAANM4vADjSUQA0zikAU+z3AEff/wBJ4sMAN9EtADjROQAyywAAM8wA////AP///wD///8A////AAAzzAAAM8wAADHLAAAwywAAMcsAAD/YXQBK4pYAN9AxAC/KAAAwygAAM8wAADPMAP///wD///8A+R8AAPAfAADABwAAwAMAAPgDAADwHwAA8AcAAOADAADAAwAAwAMAAMAHAADgBwAA4AcAAOAHAADwDwAA/j8AAA==" label="Копировать изображение кнопки в base64" ';
 data +=      'oncommand = "self.copyIMG()"/>';  
 data +=   '<menuitem class ="menuitem-iconic" image="chrome://custombuttons/skin/copy.png" label="Копировать кнопку в буфер обмена" ';
 data +=      'oncommand = "self.copyURI()"/>';
 data +=   '<menuitem class="menuitem-iconic" image="data:application/file;base64,AAABAAEAEBACAAEAAQCwAAAAFgAAACgAAAAQAAAAIAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAD/8AAA//AAAP/wAAA/wAAAP8AAA" label="Копировать кнопку как BBcode ссылку" ';
 data +=      'oncommand="self.copyBBCode()"/>';
 data +=   '<menuitem class="menuitem-iconic" image="data:application/file;base64,AAABAAEAEBACAAEAAQCwAAAAFgAAACgAAAAQAAAAIAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAADbAAADpcAAA//AAANVwAAD/8AAAKsAAAD/AAAP//AAAP8AAAD/AAAD/8AAAwDAAAP/wAAA/wAAAP8AAA" label="Копировать кнопку как текст" '; 
 data +=      'oncommand="self.copyButtonsCodeText()"/>';
 data +=   '<menuitem class="menuitem-iconic" image="data:image/x-icon;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAA/wAAAP8AAAD/AAAA/wAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAA/wAAAP8AAAD/AAAAAAAAAP8AAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP8AAAD/AAAA/wAAAAAAAAD/AAAA/wAAAP8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//+sQf//rEH4j6xB8IesQeHDrEHD4axBh/CsQYf4rEGH8KxBw+GsQeHDrEHwh6xB+I+sQf//rEH//6xB//+sQQ==" label="Копировать кнопку как HTML ссылку" ';
 data +=       'oncommand="self.copyHTML()"/>';
 data +=   '<menuseparator id="separator"/>';
 data +=   '<menuitem class="menuitem-iconic" image="data:application/file;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAABILAAASCwAAAAAAAAAAAAD///8A////AESqAABHpgAASKAAAEukAQxMpQMYR6MAAEepAQ9MpgOLRKgACUenAABHpgAARKoAAP///wD///8A////AP///wBEqgAARaIAAFS2FVBj0jS3Y9AzyVG0EUROrwt8TKcDs0ikAANInwAAR6YAAESqAAD///8A////AP///wD///8ARKQAAVvJKJtj0jX/SaAJ/0abCv9UtSH/U7QX8lW5IMddwyfQW8Iii0mqBQ1DqQAA////AP///wD///8A////AEWlAAFYwB6YXsYc5F7GFt9bwA+vVbgWvU6rAKBRrgf0RZgA/02oDP9ezCzJR6UBA////wD///8A////AP///wBFrAAASKIAADiGNQAeYIIpF1iJHVa4GKEve0tFLHl1Pla7J51exRnUWL8VjEetAAP///8A////AP///wD///8AC0WuAAk/tAAANdpIAFD6/wA+7f8gd6jqBlPX+QBE9PIGS8uDLnZLADqNJwAzjDMA////AP///wD///8A////AAAw0QAALc0AAEPdegBI4f8AK8P/ADHX/wAwzf8AL8b/AEno/gAz2zYALtEQAC3VAP///wD///8A////AP///wAAMssAADjSMwBA2pIATen/ADG9/wBe1v8ATcz/ADHK/wBN5/4ASeH/AEvl6wA10DP///8A////AP///wD///8AADnTSQBO5/8ANc7/ADnR/xC+9/8C0f//AMj//wCP8P8ALcX/ACrC/wBE3f8ASeOf////AP///wD///8A////AABI4Z4ARN3/ACvG/wJAxP8Z5v//AMT//wDE//8Axv7/AETM/wA51P8AUervADjSPP///wD///8A////AP///wAAOdRiAFry+QBS6/QATOP/H+P8/xDe//8J1///E9H4/wFE2f8AReC6ADTOEwAyywD///8A////AP///wD///8AADDNAAAyzCcARN7WACvG/wVfzf8d0vf/HM30/whf0/8AI7n/ADzV+AA40kUAMswA////AP///wD///8A////AAAwywAAPNdTAEfg/wAsw/8AOdb/ADLP/wAswv8AReP/AC7H/wA40f8AR+GfADDKAP///wD///8A////AP///wAAMswAADfRQgBY8f8AT+j/AE7o7AA+1/8AK8T/AE7o/wBN5f8AVe7/AD/ZbAAwywD///8A////AP///wD///8AADPMAAAyywAANM4vADjSUQA0zikAU+z3AEff/wBJ4sMAN9EtADjROQAyywAAM8wA////AP///wD///8A////AAAzzAAAM8wAADHLAAAwywAAMcsAAD/YXQBK4pYAN9AxAC/KAAAwygAAM8wAADPMAP///wD///8A+R8AAPAfAADABwAAwAMAAPgDAADwHwAA8AcAAOADAADAAwAAwAMAAMAHAADgBwAA4AcAAOAHAADwDwAA/j8AAA==" label="Сохранить изображение кнопки" ';
 data +=      'oncommand="self.saveIMG()"/>';
 data +=   '<menuitem class="menuitem-iconic" image="data:application/file;base64,AAABAAEAEBAAAAAAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAD///8BAAAAFwAAAGkAAABzAAAAdQAAAHUAAAB1AAAAdQAAAHUAAAB1AAAAdQAAAHUAAAB1AAAAdQAAADkAAAAP////AQAAAIdgZmj/YWlt/2FobP9haGz/YGhr/2Boa/9fZ2v/X2dr/15mav9dZWn/XGRo/0ZNUP8AAACdAAAAFf///wEAAACr2tzc/9ve4P/a3t//1dnZ/7S2tf+foJz/m5ya/6apqP/O0tP/09fZ/9DV1v+hqq//AAAAuQAAABX///8BAAAAq+3u7//e4eL/ub29/2hnXv9oVUX/U0As/zgxGf83Lx3/YWBX/7a5uv/S1tj/o6yx/wAAALkAAAAV////AQAAAKv29/f/19na/1dUQf9jXDv/dmtJ/4FoSP9VQiL/V0Ek/008Iv9HQTP/yc3P/6Wus/8AAAC5AAAAFf///wEAAACr+Pj4/5uamP9tY0L/g31b/6GLa/+McVH/eFY5/4xwUv9yXkD/RTki/4uMiv+nsLT/AAAAuQAAABX///8BAAAAq/n6+v+FfXL/waSM/8qznf/DrZP/ooFi/7WfhP+qh2//blk9/1A+Iv9aWlH/pK2x/wAAALkAAAAV////AQAAAKv6+/v/d3Rr/9zCsP/RxbH/z8Wu/9fJt//Qvab/qItv/5iOb/9tYUH/VVJK/6Wtsf8AAAC5AAAAFf///wEAAACr+/z8/4mHff+3pI//3NK//+HXxf/m3Mz/5trJ/9rMuf+bgWT/d14//2hnYP+osbX/AAAAuQAAABX///8BAAAAq/z9/f/FxL7/j4l+//Xw5f/29ez/8/Dl/+DMuv/VuaP/poZn/2dFKv+srav/oamt/wAAALkAAAAV////AQAAAKv+/v7/+/z8/5iZjf+5uqr/6+PW/+3i1P/kzL3/vZR+/4NhSf+Qh3z/z9HS/4qQkv8AAAC1AAAAFf///wEAAACr/v7+//7+/v/u7u3/tbiv/5WSgP+DfGj/e25Z/29gTv+sppz/vr6+/5aYmP90eHr/AAAApwAAABP///8BAAAAq/////////////////7+/v/9/f3//f39//v8/P/5+fn/1dXV/2pqav9TU1P/QUFB/wEBAYkAAAAJ////AQAAAKv7+/v//////////////////v7+//7+/v/+/v7/+vr6/9fY2P/V1tb/7Ozs/4KCgv8EBAQrAAAAA////wEAAACFlJSU/6ioqP+qqqr/qqqq/6qqqv+qqqr/qKio/6anp/2kpaX9o6Oj/4qKitUZGRk9////Af///wH///8BAAAAFQAAAFUAAABVAAAAVQAAAFUAAABVAAAAVQAAAFUAAABTBAQEUx8fH1dfX18z////Af///wH///8BAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//w==" label="Сохранить кнопку как HTML файл" ';
 data +=      'oncommand="self.SaveButton()"/>';
 data +=   '<menuitem class="menuitem-iconic" image="data:image/gif;base64,R0lGODlhGAAQALMAAH9AAP+AAP/AgP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAGAAQAAAEUFDISaudIevNu/9gKH5SVmIBVnLDILVBO2RyPHOAPAC2K9SwTm5H0wFvnJ+raJwFN8qWwDYc2lZFgBXGddY02kx4zCOHR+i0eg3Wut/wuDsCADs=" label="Сохранить кнопку как XML файл" ';      
 data +=      'oncommand="self.save1XML()"/>';
 data += '</menupopup>';
 data += '</popupset>';
 data += '<hbox>';
 data +=  '<spacer flex="1"/>';
 data +=     '<button label="Сохранить избранное" oncommand="self.exportHTML()" ';
 data +=     'oncontextmenu="self.exportHTML(),self.close()" ';
 data +=     'tooltiptext = "Left - Сохранить выбранные кнопки  Right - Сохранить выбранные кнопки и закрыть окно"/>';
 data +=     '<button label="Сохранить все" oncommand="self.archiveall()" ';
 data +=     'oncontextmenu="self.archiveall(),self.close()" ';
 data +=     'tooltiptext = "Left - Сохранить все кнопки ';
 data +=     ' Right - Сохранить все кнопки и закрыть окно"/>';
 data +=     '<button label="Выбрать все" oncommand="self.handle1()" ';
 data +=     'tooltiptext = "Выбрать все кнопки"/>';
 data +=  '<spacer flex="1"/>';
 data +=  '</hbox>';
 data +=  '<hbox>';
 data +=  '<spacer flex="1"/>';
 data +=     '<button label="Удалить" oncommand="self.delete()" ';
 data +=     'tooltiptext = "Удалить выбранную кнопку"/>';
 data +=     '<button label="Клонировать" oncommand="self.clone()" ';
 data +=     'tooltiptext = "Клонировать рядом с собой выбранную кнопку"/>';
 data +=     '<button label="Редактировать" oncommand="self.edit()" ';
 data +=     'tooltiptext = "Редактировать выбранную кнопку"/> ';
 data +=     '<button label="Просмотр" oncommand="self.view()" ';
 data +=     'oncontextmenu="self.view(),self.close()" ';
 data +=     'tooltiptext = "Left - Просмотреть в новой вкладке код,свойтва, атрибуты';
 data +=     'Right - Просмотреть в новой вкладке код,свойтва,атрибуты и закрыть окно"/>';
 data +=  '<spacer flex="1"/>';
 data +=  '</hbox>';
 data += '</vbox>';
 data += '</window>';

data = data.replace(/self/g, "opener.document.getElementById(&quot;" + self.id + "&quot;)");
var pv = parseInt(Services.appinfo.platformVersion);
var url = `data:application/${pv >= 73 ? "xhtm" : "vnd.mozilla.xu"}l+xml,${encodeURIComponent(data)}`;
if (pv >= 69 && Services.appinfo.browserTabsRemoteAutostart) {
    var chromeURL = `chrome://custombuttons/content/cbdialog${Date.now()}.xul`;
    Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup).registerChrome(
        Services.io.newFileURI(Services.dirsvc.get("ProfD", Ci.nsIFile)), [["override", chromeURL, url]]
    );
    url = chromeURL;
}
dialog = window.openDialog(url,  "_blank", "chrome,centerscreen,resizable=yes");

this.reopen = function() {
  dialog.close();
 dialog = window.openDialog(url, "_blank", "chrome,centerscreen,resizable=yes");
}

this.load = function() {
var aList = [], node = /custombuttons-button\d+/;
var nodeList = document.getElementsByClassName("toolbarbutton-1 chromeclass-toolbar-additional");
for(var i = 0; i < nodeList.length; i++) if(nodeList[i].id.match(node)) aList.push(nodeList[i]);

aList.sort(function (a, b) {
a = a.getAttribute("label");
b = b.getAttribute("label");
if(a < b) return -1;
if(a > b) return 1;
return 0;
})
for(var i = 0; i < aList.length; i++) createItem(aList[i]);


var bList = [], node = /custombuttons-button\d+/;
var nodeList = custombuttons.palette.getElementsByClassName("toolbarbutton-1 chromeclass-toolbar-additional");
for(var i = 0; i < nodeList.length; i++) if(nodeList[i].id.match(node)) bList.push(nodeList[i]);
bList.sort(function (a, b) {
a = a.getAttribute("label");
b = b.getAttribute("label");
if(a < b) return -1;
if(a > b) return 1;
return 0;
})
for(var i = 0; i < bList.length; i++) createItem(bList[i]);


function createItem(button) {
   var {document} = dialog;
   var item = document.createXULElement("richlistitem");

    item.checked = false;
    item.setAttribute("style", uncheckStyle);
    item.setAttribute("value", button.id);
    item.setAttribute("selected", "false");

    var cell = document.createXULElement("image"); 
    cell.setAttribute("src", button.getAttribute("image") || getImage(button.getAttribute("cb-stdicon")));
    item.appendChild(cell);
    var cell = document.createXULElement("label");
    cell.style.width = "300px";
    cell.setAttribute("value", button.getAttribute("name") || button.getAttribute("label") || "");
     // Style these three
    if(button.getAttribute("initialized")) cell.style.fontWeight = "bold";
    if(button.getAttribute("initialized")) cell.style.fontSize = "12px";
    if(button.getAttribute("initialized")) cell.style.textShadow = "#999 2px 2px 2px";
    if(!button.getAttribute("initialized")) cell.style.color = "#666";
    if(!button.getAttribute("initialized")) item.setAttribute("initialized", true);
    item.appendChild(cell);

      var cell = document.createXULElement("label");
      cell.setAttribute("value", nodeList[i].id);
      item.appendChild(cell);
    dialog.document.getElementById("listbox").appendChild(item);
  }
  function getImage(s) {
    if (s == "custombuttons-stdicon-1") return "chrome://custombuttons/skin/button.png";
    if (s == "custombuttons-stdicon-2") return "chrome://custombuttons/skin/stdicons/rbutton.png";
    if (s == "custombuttons-stdicon-3") return "chrome://custombuttons/skin/stdicons/gbutton.png";
    if (s == "custombuttons-stdicon-4") return "chrome://custombuttons/skin/stdicons/bbutton.png";
    return defaultFavicon;
  }
  dialog.document.getElementById("listbox").focus();
  dialog.document.getElementById("listbox").selectAll();
}

function toggleChoice(item) {
    item.checked = !item.checked;
    if (item.checked) item.setAttribute("style", checkStyle);
    else item.setAttribute("style", uncheckStyle) ;
  }

this.handle = function(event) {
  var listbox = dialog.document.getElementById("listbox");
  if (event.button == 0)
    toggleChoice(listbox.selectedItem);
  if (event.button == 1)
    for (var i = 0; i < listbox.itemCount; i++)
      toggleChoice(listbox.getItemAtIndex(i));
}

this.handle1 = function(event) {
  var listbox = dialog.document.getElementById("listbox");
      for (var i = 0; i < listbox.itemCount; i++)
      toggleChoice(listbox.getItemAtIndex(i));
}

this.copyURI = function() {
  var listbox = dialog.document.getElementById("listbox");
  var button = document.getElementById(listbox.selectedItem.getAttribute("value"));
  var href, text;
  if (button) {
    href = button.URI;
    text = button.name;
  } else {
    var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
    for (var i = 0; i < nodeList.length; i++) {
      if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) {
        href = createURI(nodeList[i]);
        text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
        break;
      }
    }
  }
  custombuttons.cbService.writeToClipboard(href);
  custombuttons.alertSlide(text, "Код был скопирован в буфер обмена");
}

this.copyBBCode = function() {
  var listbox = dialog.document.getElementById("listbox");
  var button = document.getElementById(listbox.selectedItem.getAttribute("value"));
  var href, text;
  if (button) {
    href = button.URI;
    text = button.name;
  } else {
    var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
    for (var i = 0; i < nodeList.length; i++) {
      if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) {
        href = createURI(nodeList[i]);
        text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
        break;
      }
    }
  }
  custombuttons.cbService.writeToClipboard("Install [url=" + href + "][img]" + defaultFavicon + "[/img][B] " + text + "[/B][/url]");
  custombuttons.alertSlide(text, "BBCode был скопирован в буфер обмена");
}

this.copyButtonsCodeText = function copyButtonsCodeText() {
   var listbox = dialog.document.getElementById("listbox");
  var btn = document.getElementById(listbox.selectedItem.getAttribute("value"));
 if (!btn) return;
  var code = ((btn.cbCommand == "") || (btn.Command == "/*CODE*/"))
              ? ""
              : ("\n/*CODE*/\n" + btn.cbCommand + "\n");
	var init = ((btn.cbInitCode == "") || (btn.cbInitCode == "/*Initialization Code*/"))
              ? ""
              : ("\n/*Initialization Code*/\n" + btn.cbInitCode);
	cbu.gClipboard.write(code + init);
	custombuttons.alertSlide(btn.name, "Code + INIT Code скопированы в буфер обмена");
}

this.copyHTML = function() {
  var listbox = dialog.document.getElementById("listbox");
  var button = document.getElementById(listbox.selectedItem.getAttribute("value"));
  var href, src, text;
  if (button) {
    href = button.URI;
    src = button.image;
    text = button.name;
  } else {
    var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
    for (var i = 0; i < nodeList.length; i++) {
      if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) {
        href = createURI(nodeList[i]);
        src = nodeList[i].getAttribute("image");
        text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
        break;
      }
    }
  }
  if (!src) src = defaultFavicon;
  custombuttons.cbService.writeToClipboard('<a href="' + href + '"><img alt="" src="' + src + '">' + " " + text + "</a>");
  custombuttons.alertSlide(text, "HTML был скопирован в буфер обмена");
}

this.copyIMG = function() {
  var listbox = dialog.document.getElementById("listbox");
  var button = document.getElementById(listbox.selectedItem.getAttribute("value"));
  var href, src, text;
  if (button) {
    src = button.image;
    text = button.name;
  } else {
    var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
    for (var i = 0; i < nodeList.length; i++) {
      if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) {
        src = nodeList[i].getAttribute("image");
        text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
        break;
      }
    }
  }
  if (!src) custombuttons.alertBox(text + "\n" + "Эта кнопка не имеет изображения!");
  else {custombuttons.cbService.writeToClipboard(src);
        custombuttons.alertSlide(text, "Изображение кнопки было скопировано в буфер обмена");
  }
}

this.saveIMG = function() {
  var listbox = dialog.document.getElementById("listbox");
  var button = document.getElementById(listbox.selectedItem.getAttribute("value"));
  var href, src, text;
  if (button) {
    src = button.image;
    text = button.name;
  } else {
    var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
    for (var i = 0; i < nodeList.length; i++) {
      if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) {
        src = nodeList[i].getAttribute("image");
        text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
        break;
      }
    }
  }
  if (!src) custombuttons.alertBox(text + "\n" + "Эта кнопка не имеет изображения!");
  else if(button.image != "") {
     var br = gBrowser;
      var tab = br.selectedTab;   
      gBrowser.selectedTab = gBrowser.addTab(button.image, {
    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
      setTimeout( function() {   window.content.document.title = button.name;
                  saveDocument(window.content.document);
                 // br.removeCurrentTab();   br.selectedTab = tab;
      }, 200);
   }
}

this.SaveButton = function() {
  var listbox = dialog.document.getElementById("listbox");
  var id = listbox.selectedItem.getAttribute("value");
  var btn = document.getElementById(id);
  var btnname, btnimage, btnURI, btncbInitCode, btncbCommand, btnHelp;
  if (btn) {
    btnname = btn.name;
    btnimage = btn.image;
    btnURI = btn.URI;
    btncbInitCode = btn.cbInitCode;
    btncbCommand = btn.cbCommand;
    btnHelp = btn.Help;
  } else {
    var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
    for (var i = 0; i < nodeList.length; i++) {
      if (nodeList[i].id == listbox.selectedItem.getAttribute("value")) {
        btnimage = nodeList[i].getAttribute("image");
        btnname = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
        btnURI = createURI(nodeList[i]);
        btncbInitCode = nodeList[i].getAttribute("cb-init");
        btncbCommand = nodeList[i].getAttribute("cb-oncommand");
        btnHelp = nodeList[i].getAttribute("Help");
        break;
      }
    }
  }
  if (!btnimage) btnimage = defaultFavicon;

  var xml = '<html xmlns="' + e4xConv_encodeHTML(xhtmlns, true) + '">\n\
    <head>\n\
    <meta http-equiv=\'Content-Type\' content=\'text/html; charset=utf-8\'/>\n\
      <title>' + e4xConv_encodeHTML(btn.name + ' for Custom Buttons') + '</title>\n\
      <link rel=\'icon\' type=\'image/vnd.microsoft.icon\' href="' + e4xConv_encodeHTML(btn.image, true) + '"/>\n\
             <style type="text/css">\n\
.button a{\n\
  background-color: rgb(85, 168, 2);\n\
  background-image: linear-gradient(to bottom, rgb(147, 200, 94), rgb(85, 168, 2));\n\
  background-image: -moz-linear-gradient(top, rgb(147, 200, 94), rgb(85, 168, 2));\n\
  border: 1px solid rgb(58, 116, 4);\n\
  border-radius: .5em;\n\
  -webkit-border-radius: .5em;\n\
  padding: 0;\n\
  margin-bottom: 1em;\n\
  box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\
  -o-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\
  -webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, .25);\n\
    color: #000;\n\
  text-shadow: -1pt -1px 0pt rgba(255, 255, 255, .5);\n\
  padding: 0.5em;\n\
  text-decoration: none;\n\
}\n\
pre { border: 1px inset rgb(170, 170, 170); \n\
     background-color: rgb(255, 255, 255);}\n\
body { background-color: rgb(245, 245, 220);} \n\
</style> \n\
    </head>\n\
    <body>\n\
     <section id=\'install\'><h1>' + e4xConv_encodeHTML(btn.name) + '</h1>\n\
      </section>\n\
      <div class="button"><a href="' + e4xConv_encodeHTML(btn.URI, true) + '">Установить кнопку</a></div>\n\
      <section id=\'init\'><h2>Инициализация</h2><pre>' + e4xConv_encodeHTML(btn.cbInitCode) + '</pre></section>\n\
      <section id=\'code\'><h2>Код</h2><pre>' + e4xConv_encodeHTML(btn.cbCommand) + '</pre></section>\n\
      <section id=\'help\'><h2>Справка</h2><pre>' + e4xConv_encodeHTML(btn.Help) + '</pre></section>\n\
    </body>\n\
  </html>';
  var html1 = '<!DOCTYPE html>\n' + xml;

  name = btn.name + ".HTML";
  var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
    createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  converter.charset = "UTF-8";
  var html = converter.ConvertFromUnicode(html1);

  saveToFile(html, name);
  custombuttons.alertSlide("Кнопка: " + btn.name, "сохранена");
}

this.edit = function() {
  var out = new Array();
  var listbox = dialog.document.getElementById("listbox");
  for (var i = 0; i < listbox.itemCount; i++) {
    if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
       custombuttons.editButton(document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")));
    }
  }
}

this.save1XML = function() {
 var btn = null; 
  var btns = document.querySelectorAll("toolbarbutton[cb-init]");
  for (var i = 0; i < btns.length; i++) {
    if ("saveXML" in  btns[i]) {
      btn = btns[i];
      break;
    }
  }
  if (!btn) {
    custombuttons.alertBox(this.label, "Кнопка XML Exporter/Importer не установлена");
    return;
  }
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
btn.saveXML(document.getElementById(id).URI);
}

this.clone = function() {
  var out = new Array();
  var listbox = dialog.document.getElementById("listbox");
  for (var i = 0; i < listbox.itemCount; i++) {
    if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
       custombuttons.cloneButton(document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")));
       this.reopen();
    }
 }
}

this.delete = function() {
  var out = new Array();
  var listbox = dialog.document.getElementById("listbox");
  for (var i = 0; i < listbox.itemCount; i++) {
    if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
      var id = listbox.getItemAtIndex(i).getAttribute("value");
      var oRemovedButton = document.getElementById(id);
      var sParentToolbarId = oRemovedButton.parentNode.id;
      var sRemovedButtonId = oRemovedButton.getAttribute("id");
      var cButtonsToRemove = document.getElementsByAttribute("id", sRemovedButtonId);
      var bRemoveFromOverlay = cButtonsToRemove.length == 1;
      custombuttons.cbService.removeButton(oRemovedButton, bRemoveFromOverlay);
      custombuttons.persistCurrentSets(sParentToolbarId, sRemovedButtonId, null);
      this.reopen();
    }
  }
}
this.view = function() {
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
   var box = custombuttons.confirmBox3("CB TOOLS", "Просмотр в новой вкладке:", "Код", "Свойства", "Атрибуты");
	if (box == 0)  this.link();
	if (box == 2)  this.attr();
	if (box == 1)  this.prop();
  this.reopen();
}

var br = gBrowser;

function openTab(arr) {
  for (var i = 0; i < arr.length; i++) {
    arr[i] = converter.ConvertFromUnicode(arr[i]);
    arr[i] = arr[i].replace(/&/g, "&amp;");
    arr[i] = arr[i].replace(/>/g, "&gt;");
    arr[i] = arr[i].replace(/</g, "&lt;");
    arr[i] = arr[i].replace(/"/g, "&quot;");
    arr[i] = arr[i].replace(/'/g, "&apos;");
  }
  var data = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//En">';
  data += "<html><head><title>" + arr[1] + "</title>";
  data += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">';
  data += "</head><body><pre>" + arr.join("\n\n") + "</pre></body></html>";
  var info = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULAppInfo);
  if (info.name == "Firefox" || info.name == "SeaMonkey") {
  var tret = "data:text/html;charset=utf-8;base64," + btoa(data);
    br.selectedTab = br.addTab(tret, {
    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal()
});
  }
  if (info.name == "Thunderbird") {
    openContentTab("data:text/html;charset=utf-8;base64," + btoa(data));
  }
}

this.attr = function() {
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
   var node = document.getElementById(id);
  var out = new Array();
  out.push('windowtype="' + document.documentElement.getAttribute("windowtype") + '" id="' + id + '"');
  out.push("Атрибуты");
  for (var i = 0; i < node.attributes.length; i++) {
    if (node.attributes[i].nodeName == "cb-oncommand" ||
        node.attributes[i].nodeName == "cb-init"      ||
        node.attributes[i].nodeName == "Help") {
      out.push(node.attributes[i].nodeName + " " + typeof node.attributes[i].nodeValue + "\n" + "[omitted]");
    } else {
      out.push(node.attributes[i].nodeName + " " + typeof node.attributes[i].nodeValue + "\n" + node.attributes[i].nodeValue);
    }
  }
  openTab(out);
}

this.prop = function() {
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
   var node = document.getElementById(id);
  var out = new Array();
  out.push('windowtype="' + document.documentElement.getAttribute("windowtype") + '" id="' + id + '"');
  out.push("Свойства");
  for (var i in node) {
    if (i == "cbCommand"  ||
        i == "cbInitCode" ||
        i == "Help"       ||
        i == "URI") {
      out.push(i + " " + typeof node[i] + "\n" + "[omitted]");
    } else {
      out.push(i + " " + typeof node[i] + "\n" + node[i]);
    }
  }
  openTab(out);
}

this.link = function() {
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
  var out = new Array();
  out.push('windowtype="' + document.documentElement.getAttribute("windowtype") + '" id="' + id + '"');
  out.push("Код");
  out.push(unescape(document.getElementById(id).URI));
  openTab(out);
}

this.inspect = function() {
  if (typeof(inspectDOMDocument) == "undefined") {
    custombuttons.alertBox(this.label, "DOM Инспектор не установлен.");
    return;
  }
var listbox = dialog.document.getElementById("listbox");
var id = listbox.selectedItem.getAttribute("value");
inspectDOMNode(document.getElementById(id));
}

this.setFolder1 = function(){
BrowserOpenFileWindow();
}

this.exportHTML = function () {
  var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].
    createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
  converter.charset = "UTF-8";
  var out = new Array();
  var listbox = dialog.document.getElementById("listbox");
  for (var i = 0; i < listbox.itemCount; i++) {
    if (listbox.getItemAtIndex(i).checked && document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
      var href = button.URI;
      var src = button.image;
      var text = button.name;
      if (!src) src = defaultFavicon;
      out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>');
      }
  }
  var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
  for (var i = 0; i < nodeList.length; i++) {
    if (nodeList[i].id.search("custombuttons-button") == 0 && document.getElementById(nodeList[i].id) == null) {
      for (var j = 0; j < listbox.itemCount; j++) {
        if (listbox.getItemAtIndex(j).checked && nodeList[i].id == listbox.getItemAtIndex(j).getAttribute("value")) {
          var href = createURI(nodeList[i]);
          var src = nodeList[i].getAttribute("image");
          var text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
          if (!src) src = defaultFavicon;
         out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>');
        }
      }
    }
  }
     var data = document.getElementById(this.id).getAttribute("Help").
    replace("<ol>", bDate() + "\n" + "<ol>" + "\n" + out.join("\n"));
  name = "CB buttons " + aDate().replace(/:/g, ".") + ".html"
// name = "CB buttons " + new Date().toLocaleFormat("%d.%m.%Y. %H·%M·%S") + ".html"
  saveToFile(data, name);

  custombuttons.alertSlide("Кнопки", "сохранены");
}

this.archiveall = function() {
   var out = new Array();
      out.push('<a><hr><strong>' + converter.ConvertFromUnicode(text1) + '</strong><hr></a>');
  var listbox = dialog.document.getElementById("listbox");
    for (var i = 0; i < listbox.itemCount; i++) {
   if (document.getElementById(listbox.getItemAtIndex(i).getAttribute("value")) != null) {
      var button = document.getElementById(listbox.getItemAtIndex(i).getAttribute("value"));
      var href = button.URI;
      var src = button.image;
      var text = button.name;
      if (!src) src = defaultFavicon;
      out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>');
   }
  }
    var nodeList = custombuttons.palette.getElementsByTagName("toolbarbutton");
    out.push('<a><hr><strong>' + converter.ConvertFromUnicode(text2) + '</strong><hr></a>');
    for (var i = 0; i < nodeList.length; i++) {
    if (nodeList[i].id.search("custombuttons-button") == 0 && document.getElementById(nodeList[i].id) == null) {
      var href = createURI(nodeList[i]);
      var src = nodeList[i].getAttribute("image");
      var text = nodeList[i].getAttribute("name") || nodeList[i].getAttribute("label") || "";
      if (!src) src = defaultFavicon;
      out.push('<li><a href="' + href + '"><img alt="" src="' + src + '">' + converter.ConvertFromUnicode(text) + '</a></li>');
    }
  }
var data = document.getElementById(this.id).getAttribute("Help").
    replace("<ol>", bDate() + "\n" + "<ol>" + "\n" + out.join("\n"));
  name = "CB buttons " + aDate().replace(/:/g, ".") + ".html"
  saveToFile(data, name);
}

function readFile(file) {
  var data = "";
  var fstream = Cc["@mozilla.org/network/file-input-stream;1"].
                createInstance(Ci.nsIFileInputStream);
  fstream.init(file, -1, 0, 0);
  var charset = "UTF-8";
  const replacementChar = Ci.nsIConverterInputStream
                            .DEFAULT_REPLACEMENT_CHARACTER;
  var is = Cc["@mozilla.org/intl/converter-input-stream;1"].
           createInstance(Ci.nsIConverterInputStream);
  is.init(fstream, charset, 1024, replacementChar);
  var str = {};
  while (is.readString(4096, str) != 0) {
    data += str.value;
  }
  is.close();
  return data;
}

function stringToDOM(aString) {
  var parser = new DOMParser();
  var dom = parser.parseFromString(aString, "text/xml");
  if (dom.documentElement.nodeName == "parsererror") {
    return null;
  } else {
    return dom;
  }
}


function e4xConv_encodeHTML(s, isAttr) {
	s = String(s)
		.replace(/&/g, "&amp;")
		.replace(/</g, "&lt;")
		.replace(/>/g, "&gt;")
		.replace(/"/g, "&quot;");
	if(isAttr) {
		s = s
			.replace(/\t/g, "&#x9;")
			.replace(/\n/g, "&#xA;")
			.replace(/\r/g, "&#xD;");
	}
	return s;
};

Отсутствует

 

№1517023-02-2021 15:02:58

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

Re: Custom Buttons

Andrey_Krropotkin
Ну как почему, потому что образуется ошибка.
В данном выражении, скобки — это оператор вызова функции.
Если идёт попытка вызова этого оператора на чём-то, не являющимся функцией,
то будет ошибка «TypeError: ... is not a function».


getElementsByClassName() — это метод Element'а или Document'а.
А custombuttons.palette, он же gNavToolbox.palette, ни тем, ни другим не является,
соответственно, метода getElementsByClassName() не имеет. Вот и ошибка.


Раньше был элементом, но затем, в Firefox 78+, превратили в HTMLTemplateElement.content,
то есть в DocumentFragment. Таким образом, можно записать
var nodeList = custombuttons.palette.querySelectorAll(".toolbarbutton-1.chromeclass-toolbar-additional");

Отсутствует

 

№1517124-02-2021 00:10:12

toxa
Участник
 
Группа: Members
Зарегистрирован: 11-04-2012
Сообщений: 261
UA: Chrome 88.0

Re: Custom Buttons

А вот этот код, копирующий адрес табов, можно приспособить под современные реалии?

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

Выделить код

Код:

(function() {
// выходим, если функция уже выполнялась
    if (document.getElementById("copyTabInfo")) return;

    var htmlEscape = function(s) {
        s = s.replace(/&/g, "&");
        s = s.replace(/>/g, ">");
        s = s.replace(/</g, "<");
        s = s.replace(/"/g, """);
        return s;
    };
    
    var copyTabInfo = function (event) {
        var tab = document.popupNode;
        var url = gBrowser.getBrowserForTab(tab).contentWindow.location.href;
        Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper).copyString(url);
    };
    
    var copyTabBBC = function (aAsBBC) {
        var tab = document.popupNode;
        var title = tab.label;
        var url = gBrowser.getBrowserForTab(tab).contentWindow.location.href;
        var txt = aAsBBC ?
                  '[url=' + htmlEscape(url) + ']' + htmlEscape(title) + '[/url]' :
                  title + "\n" + url;
        Cc["@mozilla.org/widget/clipboardhelper;1"]
        .getService(Ci.nsIClipboardHelper)
        .copyString(title);
    };
    
        
    var menuitem1 = document.createElement("menuitem");
    menuitem1.setAttribute("label", "Копировать адрес"); menuitem1.setAttribute("id", "copyTabInfo");
    menuitem1.addEventListener("command", function() { copyTabInfo(event); }, false);
    
    var menuitem2 = document.createElement("menuitem");
    menuitem2.setAttribute("label", "Копировать Title");
    menuitem2.addEventListener("command", function() { copyTabBBC(true); }, false);
    
    setTimeout(function() {
        gBrowser.mStrip.childNodes[1].appendChild(document.createElement("menuseparator"));
        gBrowser.mStrip.childNodes[1].appendChild(menuitem1);
        gBrowser.mStrip.childNodes[1].appendChild(menuitem2);
    }, 0);
})();

Отсутствует

 

№1517224-02-2021 23:12:37

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 86.0

Re: Custom Buttons

Dumby
Я в шоке , опять проблема с поисковиками... Правил SearchService.jsm , теперь и это не помогает...Или помогает, так в настойках поиск отсутствует...
Откуда теперь тянет поисковики? main из default убрал ...прет ozon, price.ru, mail.ru  и т.д. Откуда? Из локали? не вижу. В SearchService.jsm  вставлять lisr.json ?
Еще и яндекс по умолчанию...На черта он нужен?
Как это и куда вставить?

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

Выделить код

Код:

{
 "default": {                                                                                   
    "searchDefault": "Startpage",
    "searchOrder": ["Startpage", "Google", "Bing", "Yandex-Ua", "Yandex", "Yahoo", "Teoma"],
    "visibleDefaultEngines": [ 
      "google", "bing", "yandex", "ask", "aol", "Bigcinema", "boardreader", "mailru", "Dogpile", "Teoma", "hotline-ua", "Seasonvar", "Rambler", "firefox", "youtube", "yahoo", "wikipedia", "Startpage", "ecosta", "hdrezka"]
   
  }
}


В принципе, вставляю кнопками , как ваша Esocia...А дефолт как выставить? По русскому алфавиту становятся...И Яндекс - всегда впереди...Где поганка зарыта?
Да, и я извиняюсь, хотел как раньше в скрипт вставить это  и не фига..
скрытый текст

Выделить код

Код:

Services.search.addPolicyEngine({

	iconURL: "data:image/x-icon;charset=utf-8;base64,AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAQAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdK7CwSU+x9B0rslQhL7bAHSuy2B0rstgdK7LAGSeusBknrewZJ6z0HSuyQBknrGgAAAAAAAAAAAAAAAAdK7CcHSuzIAADeYgZJ63IHSuz/CEvt/wdK7P8IS+3/B0rsyAZJ6xMHSuyfBknrfgVI6gEAAAAAAAAAAAAAAAAGSetgB0rsngAAAAAGSeujCEvt/ghL7fcIS+35B0rs/QdK7OQGSes2B0rssAZJ6w4AAAAAAAAAAAAAAAAAAAAABknrNQdK7I6GqPgVB0rs3QdK7P8IS+39Ck3v+whL7f8HSuzXBUjqmgZJ67YGSesFAAAAAAAAAAAAAAAAAAAAAAdK7AQGSet2ACvmKQdK7d0IS+3/Ck3t/AhL7fwIS+3+CEvt5wdK7PIGSeuQAAAAAAdK7AEAAAAAAAAAAAdK7AIAAAAABknrRg1P7FsHSuzQCEvt/ghL7fwIS+3+Ck3v/QdK7P0IS+3/B0rsfAAAAAAIS+0CAAAAAAAAAAAAAAAAAAAAAAZJ6yEFSOpaB0rrkwhL7P8KTe/4B0rs/gpN7/4IS+36Ck3v/gdK7KUAAAAAAAAAAAAAAAAAAAAAAAAAAAVI6gkAAAAABEfqUwVJ60oHSuvuCEvt/whL7fcIS+38B0rs/AhL7f4GSevwx9j+JgAAAAAAAAAAAAAAAAAAAAAFSOpzBknrdgVI6l0LSuwSB0rsVQZJ6+8HSuz/CEvt/QhL7f0IS+37B0rs/wAw54EAAAAABknrBAAAAAAAAAAABUjqJwZK7HsITe8zC0rsAQAAAAAFSOo9BknrvwhL7fUIS+39Ck3v+ghL7f8KTeyJAAAAAAdK7AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaXf8DAAAAAAVI6gwFSOqOB0rs/wpN7/sHSuz4B0rsNgAAAAAIS+0BAAAAAAAAAAAAQ+UBAUrsAgAAAAEAAAAAAAAAAAdK7AQAAAAACEvtPwZJ6/MIS+36Bknr+QVI6qQFSOo0AAAAAAVI6gEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkXnAQRH6QQGSeumB0rs/whL7fUHSuz/BknrtgRH6QQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAARH6QIAAAAABUjqWQdK7PEIS+34B0rs5QZJ61AAAAAAB0rsAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0rsAgAAAAAGSeuYBknr/whL7TkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZJ6wEAAAAABUjqJAZJ634AAAAAB0rsAQAAAAAAAAAAwAMAAIADAACQBwAAgAcAAIALAABACwAAwA8AAKAHAACABQAAhAUAAPoFAACNAgAA/gEAAP6CAAD/RwAA/0sAAA==",
	chrome_settings_overrides: {
		search_provider: {
			name: "Seasonvar.Ru",
			search_url: "http://seasonvar.ru/search",
			search_form: "http://seasonvar.ru/",
			search_url_get_params: "q={searchTerms}"
			
		}
	}
});

Так делал:

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

Выделить код

Код:

//
try {
    Services.search.init().then(() => {
        if (!Services.search.getEngineByName("Seasonvar.ru")) {
          //Services.search.addEngine("data:text/xml," + encodeURIComponent(`
(Services.search.addOpenSearchEngine || Services.search.addEngine)("data:text/xml," + encodeURIComponent(`
                <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/">
                <ShortName>Seasonvar.ru</ShortName>
                <Description>Сериалы ТУТ! Сериалы онлайн смотреть бесплатно. Смотреть онлайн.</Description>
                <InputEncoding>UTF-8</InputEncoding>
                <Image width="16" height="16">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAADvklEQVRYhb1XTYgcRRR+JtNVr0ail0gUPLkehBwEVwgakMHNdr1XKwQ8RFQwF39uOXnxtkIwieAhetWLeoh7VVBE3IPgYY1gCIFA0OzOdL0aMYoH4y5xZsrDdjUzk91sz8BsQTFU09Pfz3uvXhXAjEax2FjoWP34MsCBWWHsDm7VKWGMwrh+7SiofScQnAlC+j9xeHvfwQvSbwnpO4FxIKTveKs+2TcXCsKF4EwMjINqOhODM1Fs9tRMwX9fgCPCGIX0oLvUjNV0ZhCciZ7wh5stwJkR6OTq1aR+hMBSs3LEW/3tzAh4q04OExj+DYwDYYxi8fWZgLcXG7kwbg6rT2S2y1H3hPRXMwEHABBnLgeH/cA46DozSLEvc+LrmQGn4UlfGY99cuD6cTg0U/B23nhOGO9OvtKB4PD7iT/qc/PsXu8I45vC2E3gaQ470HVmIKT/XgE4WAt4I89OF6S2PKnPA+ON3xbgyPg7geGhwPidMMauM4NU5+Oll1zwpLc6z4Cpp5zwlif9MwDAagsaweEXI6pz9YQn1R9Rm5Juh7ldBbp3JYf7axEorLoa2HwEALACcLCwahMA7gMA2DiBjw3bvRvoeAg84a3aIbg8D9ly2b9XW9DwrP8FAFi38Ig47EsqtaGNZjflVRISnq4FPj6uH4dDnvESAIA4c7FUFMO9Yj629QpjmAocAKCTq/eFtF0GODCJ9SkptxuQvjg1AWGMNxgeEMazeyneKfbBmbg+bQsubPakt7oLACCEa7XVjzlwswUPT6ee8LOCcAEAILCRWolXKq+2YWeitODw5ODz0PSkN9M6LDX/qhuC6gRUdsGC4dEp1OszwmatWrP5sxaBdPKx+K6w7gVnYnsxe3oKAihC+oO09ozFXvYPh6G92MiFUIQxetZvTwTeZj3nScci1y8MEVqrcuAeTlSll6uXOqReFMZYkFqZiMC2fRglz+bTs8KqT9PH99r3gzOxsOoUAIA4vO1J/zIZAdIfCmP0uV5Mzzp5dqzqfLspT1sv6UEnz44BAHjGS5701kQEpLTO8+jptTxY9HcsvSo/TN9b9U/6T5vUy9v3AfXKZC6w/rK81/306wl4sHTm4+FsHwF3JnaXTF8YY/t5mFttQWO5bGjCGAurrso8NKHsqjWd0Gc84x/pRBsc9kZuPCknqqOX7gVnup5xQxi3POGPJfFvSjEjeVVrXDsKqs16zlt1smOzN4TUO8J41hOe86wveNYXvFXnPalzBeF7aXqL54s8q1qwkLaFzV5Lbo6P/wEF7JeDr5SEggAAAABJRU5ErkJggg==</Image>
                <Url type="text/html" method="GET" template="http://seasonvar.ru/search">
                    <Param name="q" value="{searchTerms}"/>
                </Url>
                <SearchForm>http://seasonvar.ru/</SearchForm>
                </SearchPlugin>
            `), null, null);
        }
    });
} catch(e) {}

Отредактировано solombala (25-02-2021 16:23:38)

Отсутствует

 

№1517325-02-2021 02:22:01

beggrr
Участник
 
Группа: Members
Зарегистрирован: 04-02-2014
Сообщений: 128
UA: Firefox 85.0

Re: Custom Buttons

del

Отредактировано beggrr (25-02-2021 02:22:57)

Отсутствует

 

№1517425-02-2021 17:57:59

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

Re: Custom Buttons

toxa пишет

код, копирующий адрес табов, можно приспособить под современные реалии?

Никакой адрес табов код не копирует.
Код добавляет в контекстное меню табов свои пункты, вернее, добавлял бы,
если бы в бесполезной функции htmlEscape не было бы синтаксической ошибки.
Если есть сомнение, возможно ли в «современных реалиях» добавление,
тогда пишем что-нибудь, и смотрим, добавляется или нет.

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

Выделить код

Код:

(popup => {
	var prfx = `cb${_id.slice(20)}-tabCopy-`;
	var menuitem = popup.appendChild(document.createXULElement("menuitem"));
	menuitem.id = prfx + "url";
	addDestructor(() => popup.querySelectorAll(`[id^="${prfx}"]`)
		.forEach(n => n.remove())
	);
	menuitem.render = () => {
		var node = document.createXULElement("menuseparator");
		node.id = prfx + "sep";
		menuitem.before(node);

		menuitem.setAttribute("oncommand", "tcopy(this.id)");

		node = menuitem.cloneNode(false);
		node.id = prfx + "bbc";
		node.setAttribute("label", "2");
		menuitem.after(node);

		menuitem.setAttribute("label", "1");

		menuitem.tcopy = node.tcopy = id => {
			var tab = TabContextMenu.contextTab;
			var uri = gBrowser.getBrowserForTab(tab).currentURI;
			var url = gURLBar.makeURIReadable(uri).displaySpec;
			gClipboard.write(id.endsWith("l") ? url : `[url=${url}]${tab.label}[/url]`);
		}
		delete menuitem.render;
		menuitem.render();
	}
})(document.getElementById("tabContextMenu"));

solombala пишет

опять проблема с поисковиками... Правил SearchService.jsm

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

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

1. Кладём папку search-extensions с нужными поисковиками
в папку установки, то есть, рядом с firefox.exe


2. Чтобы поисковики брались из этой папки, добавляем код в config.js
(будет перечислено всё, поэтому держим в папке только нужные).
В коде можно указать дефолтный поисковик.
Также, включён и http-патч (правка omni.ja на предмет этого тоже не требуется).

Выделить код

Код:

//
(async cso => {

	var defaultEngine = "google";
	
	var rph = Cc["@mozilla.org/network/protocol;1?name=resource"].getService(Ci.nsIResProtocolHandler);
	var uri = rph.getSubstitution("gre").QueryInterface(Ci.nsIJARURI).JARFile.QueryInterface(Ci.nsIFileURL);
	var se, dir = uri.file.parent;
	dir.append(se = "search-extensions");
	if (!dir.exists() || !dir.isDirectory()) return;

	var u = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService).newURI;
	var json = Cu.readUTF8URI(u(cso)).replace(/https(?!\?)/g, "$&?");
	var jsonURL = "data:application/json;charset=utf-8," + encodeURIComponent(json);
	var ams = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
	globalThis[Symbol("http mod")] = ams.registerChrome(uri, [["override", cso, jsonURL]]);

	rph.setSubstitution(se, u(uri.spec.replace(/omni\.ja$/, se)));
	
	var sel = {engines: []};
	for(var {leafName} of dir.directoryEntries) sel.engines[
		leafName == defaultEngine ? "unshift" : "push"
	]({webExtension: {id: leafName + "@search.mozilla.org", locale: "default"}});

	Cc["@mozilla.org/browser/search-service;1"].getService(Ci.nsISearchService)
		.wrappedJSObject._fetchEngineSelectorEngines = async () => sel;
	
})("chrome://browser/content/schemas/chrome_settings_overrides.json");

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

Выделить код

Код:

(async () => {
	var ss = Services.search.wrappedJSObject;
	var engines = Array.from(ss._sortedEngines);
	for(var engine of engines) {
		if (!engine._isAppProvided) continue;
		engine._isAppProvided = false;
		var addon = await AddonManager.getAddonByID(engine._extensionID);
		await addon.uninstall();
	}
	Object.defineProperty(ss._settings, "_currentSettings", {
		configurable: true, enumerable: true, set(val) {
			val.engines.length || Object.defineProperty(val, "engines", {
				configurable: true, enumerable: true, get(val) {
					delete this.engines;
					this.engines = [];
					return " ";
				}
			});
			delete this._currentSettings;
			this._currentSettings = val;
		}
	});
	Services.obs.addObserver(function obs(s, topic, data) {
		if (data != "write-settings-to-disk-complete") return;
		Services.obs.removeObserver(obs, topic);
		Services.startup.quit(Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart);
	}, "browser-search-service");
})();

Всё. Если перезапустилось, поисковики должны подхватиться из этой папки search-extensions.
Разумеется, если экспериментировать, то только на отдельной чистой сборке,
и не только потому, что возможны конфликты с (неизвестно как) «правленным SearchService.jsm»,
но и просто из осторожности, а то мало ли, что у меня работает, ещё испортится что-нибудь.

Отсутствует

 

№1517525-02-2021 18:20:51

solombala
Забанен
 
Группа: Members
Зарегистрирован: 20-07-2019
Сообщений: 652
UA: Firefox 86.0

Re: Custom Buttons

Dumby
Тонкий ход...Нет слов...Осталось допилить , все остальные по алфавиту ...
var defaultEngine = "Startpage";  Как бы другие выставить , как мне надо? Типа, как в list.json было:
"searchOrder": ["Startpage", "Google", "Bing", "Yandex-Ua", "Yandex", "Yahoo", "Teoma"],
Добавлять , в принципе, итак получалось, но таскать после очистки профиля неохота...Лезут вверх всякие AOl , Ask ..алфавит ...

Отредактировано solombala (25-02-2021 20:59:39)

Отсутствует

 

Board footer

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