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

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

№1547619-04-2021 12:50:56

mokujin
Участник
 
Группа: Members
Зарегистрирован: 17-02-2017
Сообщений: 494
UA: Firefox 68.0

Re: Custom Buttons

Подскажите, забыл, какая ф-ция в CB для окна выбора действий: "один" "два" "выход" ?   Там alertbox или как-то так...
Замена\аналог консольному choice:

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

Выделить код

Код:

echo ^    ------------------------------------------------------------
echo ^    ^|                                                          ^|
echo ^    ^|  ¤¤¤  TOR - (t), или UltraSurf (u) ?  (q) - Выход  ¤¤¤   ^|
echo ^    ^|                                                          ^|
echo ^    ------------------------------------------------------------
choice /c tuq /T 15 /d q
if  %ERRORLEVEL% == 1 goto :tor
if  %ERRORLEVEL% == 2 goto :usurf
if  %ERRORLEVEL% == 3 goto :EOF


...программисты словно войну какую-то ведут за свои обновления. Блин, почему сейчас повсюду мания ухудшать интерфейсы и делать их максимально неудобными?! Radiation

Отсутствует

 

№1547719-04-2021 13:09:15

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1700
UA: Firefox 78.0

Re: Custom Buttons

Dumby пишет

Если поиск пойдёт не в текущей вкладке, то можно, наверно

Класс, спасибо, да поиск открывается в новой вкладке
А можно ли добавить чтобы название для контейнера было такое же как и введенный текст в строке поиска?
Например если в строке поиска искать "солнечные панели" то и новый контейнер открывался с таким же названием

Отсутствует

 

№1547820-04-2021 06:59:25

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3231
UA: Firefox 88.0

Re: Custom Buttons

Dumby
Как бы в Суммарном жоре памяти уменьшить размер шрифта? А то она иконки от дополнений растягивает.

Отсутствует

 

№1547920-04-2021 09:55:09

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

Re: Custom Buttons

Dobrov пишет

Недостаток SaveHTML в том, что сохранённые .html файлы не появляются в "Показать все загрузки".
Это можно исправить или хотя бы после сохранения .html помигать кнопкой Загрузки, как после скачивания файла?…

Недостаток?, как невхождение чего-либо в сам замысел?
Тут, как-то, на нечто подобное для кнопки Save,
предлагал фейковый download, и оно, вроде как, мигает кнопкой.

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

Выделить код

Код:

...
			notify("Страница сохранена в:", path);

			var d = await Downloads.createDownload({
				source: "about:blank",
				target: FileUtils.File(path)
			});
			(await Downloads.getList(Downloads.ALL)).add(d);
			d.refresh(d.succeeded = true);

Ещё нужен код, чтобы показать свой текст в строке статуса. Я пробовал, но ничего не показывается

У меня, с консоли, так работает

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

Выделить код

Код:

StatusPanel._label = "свой текст в строке статуса";
setTimeout(() => StatusPanel.update(), 2000);

может сделаешь пример, скрывающий панель вкладок, если вкладка одна и показывающий для нескольких?

Для CB

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

Выделить код

Код:

(url => {
	var num = gBrowser.tabs.length;
	var bar = document.getElementById("TabsToolbar");
	if (num == 1) bar.collapsed = true;

	addEventListener("TabOpen", () => {
		if (++num == 2) bar.collapsed = false;
	}, false, gBrowser.tabContainer);

	addEventListener("TabClose", () => {
		if (--num == 1) bar.collapsed = true;
	}, false, gBrowser.tabContainer);

	var type = windowUtils.USER_SHEET;
	windowUtils.loadSheetUsingURIString(url, type);

	addDestructor(() => {
		windowUtils.removeSheetUsingURIString(url, type);
		if (num == 1) bar.collapsed = false;
	});
})("data:text/css;charset=utf-8,%23TabsToolbar[collapsed]:not([customizing]){visibility:collapse!important;}");

не получается поменять подсказку кнопки в зависимости от того, есть кнопка SingleSave или нет

Может, на момент исполнения кода, «кнопки SingleSave» ещё пока нет?
Просто запуск WebExtensions сильно тормозят (в угоду дражайшему стартап-перформансу).
Попробуй с таймаутом.


mokujin пишет

Подскажите, забыл, какая ф-ция в CB для окна выбора действий: "один" "два" "выход" ?   Там alertbox или как-то так...

Оно чтоле?

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

Выделить код

Код:

var result = custombuttons.confirmBox3(

	"Header",
	"Message",

	"TOR",
	"Выход",
	"UltraSurf"
);

var results = {

	0: "TOR",
	1: "Выход",
	2: "UltraSurf"
};

alert(results[result]);

Stkvsky пишет

А можно ли добавить чтобы название для контейнера было такое же как и введенный текст в строке поиска?
Например если в строке поиска искать "солнечные панели" то и новый контейнер открывался с таким же названием

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

Выделить код

Код:

(async (sel, self) => ({

	icon: "circle",
	colors: [
		"mediumseagreen",
		"silver",
		"crimson",
		"blue",
		"peru",
	],

	initColors() {
		var colorName = "ucf-gen";
		var css = "@-moz-document url(about:preferences#containers),"
			+ " url-prefix(chrome://browser/content/browser.x) {\n";
		this.colors.forEach((color, ind) => {
			var [ic, tc] = color.split(/\s*\|\s*/);
			css += `\t.identity-color-${colorName}${ind} {\n`
				+ `\t\t--identity-tab-color: ${tc || ic};\n`
				+ `\t\t--identity-icon-color: ${ic};\n\t}\n`
		});
		var url = "data:text/css;charset=utf-8," + encodeURIComponent(css + "}");
		var sss = Cc["@mozilla.org/content/style-sheet-service;1"]
			.getService(Ci.nsIStyleSheetService);
		sss.loadAndRegisterSheet(Services.io.newURI(url), sss.USER_SHEET);

		var len = this.colors.length;
		var pref = "ucf.openInGeneratedContainer.lastColor";
		var ind = Math.min(Services.prefs.getIntPref(pref, -1), len - 1);
		this.nextColor = () => {
			var next = ind + 1;
			Services.prefs.setIntPref(pref, ind = next == len ? 0 : next);
			return colorName + ind;
		}
	},
	init(topic) {
		Services.obs.addObserver(self = this, topic);
		Services.obs.addObserver(function quit(s, t) {
			Services.obs.removeObserver(self, topic);
			Services.obs.removeObserver(quit, t);
		}, "quit-application-granted");
		this.initColors();
		this.newUsercontext = name => this.cis.create(
			name || `[ ${this.cis._lastUserContextId + 1} ]`, this.icon, this.nextColor()
		).userContextId;
	},
	observe(doc) {
		var list = doc.querySelectorAll(sel);
		if (!list.length) return;

		var menuitem = doc.createXULElement("menuitem");
		for(var args of Object.entries({
			selectiontype: "single",
			oncommand: "cmd(window)",
			nodetype: "folder|query",
			selection: "folder|query",
			label: "Открыть всё в контейнере",
			id: "placesContext_openContainer:tabs:newUsercontext"
		}))
			menuitem.setAttribute(...args);
		menuitem.cmd = this.cmd;
		menuitem.rnd = menuitem.constructor.prototype.render;
		menuitem.render = this.render;
		var [m1, m2] = menuitem.list = Array.from(list);
		(m2 || m1).after(menuitem);

		if (doc.documentElement.getAttribute("windowtype") != "navigator:browser") return;

		for(var btn of [
			doc.getElementById("tabs-newtab-button"),
			doc.getElementById("new-tab-button") ||
				doc.ownerGlobal.gNavToolbox.palette.querySelector("#new-tab-button")
		])
			if (btn) btn.checkForMiddleClick = this.click;

		var win = doc.ownerGlobal;
		this.redefDoSearch(win, win.customElements.get("searchbar").prototype);
	},
	redefDoSearch(win, proto) {
		this.cis = win.ContextualIdentityService;
		var code = `(openTrustedLinkIn => [
			{${proto.doSearch}}, openTrustedLinkIn
		])(
			function otl(url, where, params) {
				if (where != "current")
					params.userContextId = otl.newUsercontext(
						document.getElementById("searchbar").value
					);
				openTrustedLinkIn(url, where, params);
			}
		);`;
		(this.redefDoSearch = (win, proto) => {
			var [obj, func] = win.eval(code);
			Object.assign(proto, obj);
			func.newUsercontext = this.newUsercontext;
		})(win, proto);
	},
	click(btn, e) {
		if (!(e.button != 2 || e.ctrlKey || e.shiftKey)) {
			var txt = e.view.readFromClipboard();
			if (txt) {
				var urls = txt.split("\n").map(self.map).filter(Boolean);
				if (urls.length) return e.preventDefault(),
					self.openFromClipboard(e.view, urls);
			}
		}
		e.view.checkForMiddleClick(btn, e);
	},
	eo: Object.create(null),
	map(str) {
		str = str.trim();
		try {
			var scheme = Services.io.extractScheme(str);
			var ph = Services.io.getProtocolHandler(scheme);
			if (ph.scheme == scheme)
				return Services.io.newURI(str) && {uri: str};
		} catch {}
	},
	openFromClipboard(win, urls) {
		if (win.OpenInTabsUtils.confirmOpenInTabs(urls.length, win))
			urls.load = true,
			this.open(win, this.eo, urls);
	},
	async render() {
		this.rnd();
		await new Promise(this.ownerGlobal.requestAnimationFrame);
		this.hidden || (this.hidden = this.list.every(self.every));
	},
	every: node => node.disabled || node.hidden,
	cmd(win) {
		var view = this.parentNode._view;
		var node = win.document.popupNode;
		node = node._placesView && node._placesView.result.root;
		self.open(win, node || view.selectedNode || view.result.root);
	},
	open(win, node, list) {
		var gbw = Cu.import("resource:///modules/PlacesUIUtils.jsm", {}).getBrowserWindow;
		var w = gbw(win);
		this.pu = w.PlacesUIUtils;
		this.fs = w.PlacesUtils.favicons;
		this.cis = w.ContextualIdentityService;
		this.sysp = w.E10SUtils.SERIALIZED_SYSTEMPRINCIPAL;

		(this.open = (win, node, list) => {
			this.openURLs(gbw(win), list || win.PlacesUtils.getURLsForContainerNode(node));
			node.bookmarkGuid && this.pu.doCommand(win, "placesCmd_delete");
		})(win, node, list);
	},
	async openURLs(win, urls) {
		var userContextId = this.newUsercontext();
		var mark = !win.PrivateBrowsingUtils.isWindowPrivate(win);
		var {load} = urls, gb = win.gBrowser, pos = gb.selectedTab._tPos;

		for(var {uri, title, isBookmark} of urls) try {
			if (mark) isBookmark
				? this.pu.markPageAsFollowedBookmark(uri)
				: this.pu.markPageAsTyped(uri);

			if (load) {
				gb.addTrustedTab(uri, {index: ++pos, userContextId});
				continue;
			}
			var state = {userContextId, entries: [{
				url: uri,
				title: title || uri,
				triggeringPrincipal_base64: this.sysp
			}]};
			var [,, data, mime] = await new Promise(
				resolve => this.fs.getFaviconDataForPage(
					Services.io.newURI(uri), (...args) => resolve(args), 16
				)
			);
			if (data.length) state.image = `data:${
				mime || "image/x-icon"
			};base64,${
				btoa(String.fromCharCode(...data))
			}`;
			var tab = gb.addTrustedTab(null, {index: ++pos, userContextId});
			win.SessionStore.setTabState(tab, state);
		} catch {};
	}
}).init("chrome-document-loaded"))(
	"#placesContext_openBookmarkContainer\\:tabs,#placesContext_openContainer\\:tabs"
);

voqabuhe пишет

размер шрифта

font-size

иконки от дополнений

???

Отсутствует

 

№1548020-04-2021 12:05:34

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1700
UA: Firefox 78.0

Re: Custom Buttons

Dumby
Фантастика, благодарю

Отсутствует

 

№1548120-04-2021 14:09:48

mokujin
Участник
 
Группа: Members
Зарегистрирован: 17-02-2017
Сообщений: 494
UA: Firefox 68.0

Re: Custom Buttons

Dumby пишет

Оно чтоле?

Оно! Половина кнопок на батниках завязаны, вот решил перевести кой-чего в CB, а забыл название. Пасиб.
В итоге получилось так:

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

Выделить код

Код:

const prof = Services.dirsvc.get('ProfD', Ci.nsIFile),
      tor = prof.path + "\\SOFT_PM\\tor\\Tor\\tor.exe",
      usurf = prof.path + "\\SOFT_PM\\UltraSurf_Proxi\\u1902.exe";

 let choice = custombuttons.confirmBox3( "Proxy utils", "Запустить что ", "TOR", "Выход", "UltraSurf" ),
     result = { 0: tor, 1: "Выход", 2: usurf };
     //console.log("result of choise " + result[choice]);
 
 if(result[choice] == "Выход") return;
   else startProcess(result[choice], []); // ф-ция где проверяется аргументы и путь... ну и запускает прогу.


...программисты словно войну какую-то ведут за свои обновления. Блин, почему сейчас повсюду мания ухудшать интерфейсы и делать их максимально неудобными?! Radiation

Отсутствует

 

№1548220-04-2021 15:28:07

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1700
UA: Firefox 78.0

Re: Custom Buttons

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

Отсутствует

 

№1548321-04-2021 07:40:51

bugmenot
Участник
 
Группа: Members
Зарегистрирован: 29-01-2012
Сообщений: 35
UA: Firefox 89.0
Веб-сайт

Re: Custom Buttons

Не скачиваются, можно выложить еще раз?

Отсутствует

 

№1548421-04-2021 08:28:15

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

Re: Custom Buttons

Stkvsky пишет

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

Не смог понять что это значит.


bugmenot пишет

можно выложить еще раз?

Оба.

Отсутствует

 

№1548521-04-2021 12:47:02

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1700
UA: Firefox 78.0

Re: Custom Buttons

Dumby
Ну вот например открывается в контенере несколько вкладок
Потом все вкладки закрываются а контейнер созданный остается существовать
Можно ли сделать чтобы после закрытия последней вкладки контейнера он удалялся?

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

Отредактировано Stkvsky (22-04-2021 16:50:11)

Отсутствует

 

№1548621-04-2021 22:56:20

Пострел
Участник
 
Группа: Members
Зарегистрирован: 08-04-2021
Сообщений: 51
UA: Firefox 88.0

Re: Custom Buttons

Ребят, если есть у кого рабочая кнопка
Добавить пункт подменю "Увеличить изображение".
Поделитесь пожалуйста. У меня на 88й не работает.

Отсутствует

 

№1548721-04-2021 23:12:54

egorsemenov06
Участник
 
Группа: Members
Зарегистрирован: 12-06-2018
Сообщений: 378
UA: Firefox 88.0

Re: Custom Buttons

Пострел пишет

Ребят, если есть у кого рабочая кнопка
Добавить пункт подменю "Увеличить изображение".
Поделитесь пожалуйста. У меня на 88й не работает.

для custom_script_win.js

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

Выделить код

Код:

(this.ucf_img_scroll_zoom = {
            imgZoom: 190,   // на сколько увеличить изображение из меню
            scrollZoom: 20, // на сколько увеличивать/уменьшать колесиком мыши
            scrollTop: 1,   // или -1, переключение направление прокрутки для увеличение колёсиком
            init(that) {
                var popup = this.popup = document.querySelector("#contentAreaContextMenu");
                if (!popup) return;
                popup.addEventListener("popupshowing", this);
                that.unloadlisteners.push("ucf_img_scroll_zoom");
            },
            receiveMessage(msg) {
                var container = document.documentElement
                    .appendChild(document.createElement("div"));
                var image = container.appendChild(document.createXULElement("image"));
                image.style.cssText = "width: 100% !important; height: 100% !important;";
                image.setAttribute("validate", "never");

                var st = container.style;
                var dz = this.scrollZoom/100 * this.scrollTop;
                var currScale = 1, x, y, initialZoom = this.imgZoom/100 - 1;

                var hide, props = ["width", "height", "left", "top"], p = n => n + "px";
                var set = (...args) => props.forEach((prop, ind) => st[prop] = p(args[ind]));

                (hide = () => {
                    st.cssText = "position: fixed; display: none; z-index: 2147483647;";
                    currScale = 1;
                    image.src = null;
                })();
                container.onwheel = (e, ds = e.deltaY > 0 ? -dz : dz) => {
                    if (currScale < .15 && ds < 0) return;
                    st.transform = `scale(${currScale += ds})`;
                    var {width, height, left, top, bottom, right} = container.getBoundingClientRect();

                    if (height < innerHeight) {
                        if (top < 0) st.top = p(y -= top);
                        if (bottom > innerHeight) st.top = p(y -= bottom - innerHeight);
                    }
                    if (width < innerWidth) {
                        if (left < 0) st.left = p(x -= left);
                        if (right > innerWidth) st.left = p(x -= right - innerWidth);
                    }
                }
                (this.receiveMessage = msg => {
                    var {src, width, height, left, top} = msg.data;
                    image.src = src;
                    left -= mozInnerScreenX;
                    top -= mozInnerScreenY;

                    set(width, height, x = left, y = top);
                    st.display = "block";
                    container.onwheel(null, initialZoom);
                    window.addEventListener("mousedown", hide, {once: true, capture: true});
                })(msg);
            },
            handleEvent(e) {
                if (!gContextMenu.onImage) return;
                var menuitem = document.createXULElement("menuitem");
                menuitem.setAttribute("label", "Увеличить размер");
                menuitem.className = "menuitem-iconic";
                menuitem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADZElEQVR42oXSe0xbVRwH8N8597a35e7SAmUFukGhY66AMiNzw4GvTCQLCssc4pQsmTOa+ERMlrktW1zigpnEuWn8x2eMmiVGMBDCFjS+cJHEDIk8RoSNV1+3tLWX3t72nnO8sETJFrfvP7/k5Pw+Ob9fDoLrYi8ow9GFUbq+5aRLrGraqQcX6hlF2wkFEWn6EDIJAyQy9+3VT58cWb6PrmvmjGZS/FSHlxbXtbtLobGqJlPKMhNepWb0V8hKpi8FNd/gzCCogbdmvtg/8C9gz9+Eor5x5nn2tDOZ98Dx2i3C/uYai9mOGCxiDQIIg1/PgUCEhyvDMox9PXYBkPzaaoAzAFL0yle7ShtqO/eWJ9w1vJ1oGsVzYhTNATMQG4Q1G40ldDw6PB339fs7VgMmA0jnHfioo6F9Z3tDYYJzKSZKMYcDvAILiICfZUNYEYFixMKpKBk8MfTTasBsACnngU/6Wg4+VL/VFSOmBHAYY1BAhzAvgmyMEIkh0EUOBD1Eu49eStwA5D3z4TcPv9TYdHvxEhXSGgaEIMkJkKAS+ONmSKYolOVqMBlRSd8bv8v/AQXlJoiHUE5rZ1tFa/Nhj1uVrCaNMoQxYSaIqDxAGqAuQ2XZ1iS8HUTpkZMXe1eATOdtiCcJblGe1a3PnWp0uEvfv3tbeX5RhSet/q3wxh6xgAncZUmw2hxEryQx9/LHE7I2RV5HNudGFAtcZsuQd919u/kiz56JOwobcjd6xerqKnB4HIB4RvMzCM1DGj8X0GD64pL2Xdf850z+4djKC8wl24XUpj1P75sdfe/+sSHoq3uQnSuwa+s2Vy5uubd2jQWUTAYchJK8HpyIzvv7p/rMkV/OzPeeGEWi+x6LufiR573h8VO7Zr4n9fEZNeiqXHOofFvPsKPkS1fKsX5JU6uNZQh8Wh/hRcuvOC3/fLXrcGj52yOo7zzU9udvbzbN9uglggK2MhsnvfiE0tY9tfed7vM98D+x53tx1DdG0Z2b97Ejf3SRSiGGCysyENvdoipZa4+/8NmPp8+N+Ei2ZEVpQhG71rdcqFFozD+xcoQugFUvlDS8wWsl8Uebk5C79ujjHwyc6R/309ysDBRauEzhJkG9ErAdG0xEe6yVkwqcr+549/zZgcmQ7pAEkH2TDG6RfwCoJI0uEWJP5QAAAABJRU5ErkJggg==");
                menuitem.setAttribute("oncommand", "handleCommand();");
                e.target.append(menuitem);
                menuitem.handleCommand = () => this.cmd();

                this.handleEvent = () => menuitem.hidden = !gContextMenu.onImage;
            },
            cmd() {
                var msg = this.msg = "UCF:GetImageScreenRectForMosuseZoom";
                var code = `(targetIdentifier => {
                    var image = ChromeUtils.import("resource://gre/modules/ContentDOMReference.jsm")
                        .ContentDOMReference.resolve(targetIdentifier);
                    var mm = image.ownerGlobal.docShell.messageManager;
                    var rect = image.getBoundingClientRect();
                    var win = image.ownerGlobal;
                    var x = rect.left, y = rect.top;
                    var parentFrame = win.frameElement;
                    while (parentFrame) {
                      win = parentFrame.ownerGlobal;
                      let cstyle = win.getComputedStyle(parentFrame);
                      let framerect = parentFrame.getBoundingClientRect();
                      x +=
                        framerect.left +
                        parseFloat(cstyle.borderLeftWidth) +
                        parseFloat(cstyle.paddingLeft);
                      y +=
                        framerect.top +
                        parseFloat(cstyle.borderTopWidth) +
                        parseFloat(cstyle.paddingTop);
                      parentFrame = win.frameElement;
                    }
                      x += win.mozInnerScreenX;
                      y += win.mozInnerScreenY;
                    var fullZoom = win.windowUtils.fullZoom;
                    mm.sendAsyncMessage("${msg}",
                        {
                            src: image.currentSrc,
                            left: x * fullZoom,
                            top: y * fullZoom,
                            width: rect.width * fullZoom,
                            height: rect.height * fullZoom,
                        }
                    );
                })(`;
                messageManager.addMessageListener(msg, this);

                (this.cmd = () => {
                    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(
                        code + JSON.stringify(gContextMenu.targetIdentifier) + ")"
                    ), false);
                })();
            },
            destructor() {
                this.popup.removeEventListener("popupshowing", this);
                if (this.msg)
                    messageManager.removeMessageListener(this.msg, this);
            },
        }).init(this);

Отсутствует

 

№1548822-04-2021 18:16:14

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3231
UA: Firefox 88.0

Re: Custom Buttons

Dumby

font-size

Намекаешь, что надо через userChrome.css регулировать? Эт я  сделал, шрифт уменьшил, иконки приобрели нормальный вид. А в саму кнопку не можешь добавить регулировку шрифта, или сделать, чтоб она не влияла на другие иконки?

Dumby пишет

иконки от дополнений

???

Ну иконки от дополнений, которые их пихают в адресную строку. У меня это Scroll Up Folder и Save-To-Read

Отсутствует

 

№1548922-04-2021 20:33:29

Пострел
Участник
 
Группа: Members
Зарегистрирован: 08-04-2021
Сообщений: 51
UA: Firefox 88.0

Re: Custom Buttons

egorsemenov06
Предложеный вами вариант кнопки работает.
Очень выручили. Спасибо.

Отсутствует

 

№1549023-04-2021 09:50:39

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

Re: Custom Buttons

Stkvsky пишет

Ну вот например открывается в контенере несколько вкладок
Потом все вкладки закрываются а контейнер созданный остается существовать
Можно ли сделать чтобы после закрытия последней вкладки контейнера он удалялся?

Что-то я сомневаюсь, что смогу это записать.

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

Выделить код

Код:

(async (sel, self) => ({

	icon: "circle",
	colors: [
		"mediumseagreen",
		"silver",
		"crimson",
		"blue",
		"peru",
	],

	initColors() {
		var colorName = "ucf-gen";
		var css = "@-moz-document url(about:preferences#containers),"
			+ " url-prefix(chrome://browser/content/browser.x) {\n";
		this.colors.forEach((color, ind) => {
			var [ic, tc] = color.split(/\s*\|\s*/);
			css += `\t.identity-color-${colorName}${ind} {\n`
				+ `\t\t--identity-tab-color: ${tc || ic};\n`
				+ `\t\t--identity-icon-color: ${ic};\n\t}\n`
		});
		var url = "data:text/css;charset=utf-8," + encodeURIComponent(css + "}");
		var sss = Cc["@mozilla.org/content/style-sheet-service;1"]
			.getService(Ci.nsIStyleSheetService);
		sss.loadAndRegisterSheet(Services.io.newURI(url), sss.USER_SHEET);

		var len = this.colors.length;
		var pref = "ucf.openInGeneratedContainer.lastColor";
		var ind = Math.min(Services.prefs.getIntPref(pref, -1), len - 1);
		this.nextColor = () => {
			var next = ind + 1;
			Services.prefs.setIntPref(pref, ind = next == len ? 0 : next);
			return colorName + ind;
		}
	},
	quit: false,
	init(topic) {
		Services.obs.addObserver(self = this, topic);
		Services.obs.addObserver(function quit(s, t) {
			self.quit = true;
			Services.obs.removeObserver(self, topic);
			Services.obs.removeObserver(quit, t);
		}, "quit-application-granted");
		this.initColors();
		this.newUsercontext = name => {
			var id = this.cis.create(
				name || `[ ${this.cis._lastUserContextId + 1} ]`, this.icon, this.nextColor()
			).userContextId;
			this.saveGens(this.gens.add(id));
			return id;
		}
		var cpref = "ucf.openInGeneratedContainer.containers";
		this.gens = new Set(
			Services.prefs.getStringPref(cpref, "").split(",").map(Number).filter(Boolean)
		);
		this.saveGens = () => Services.prefs.setStringPref(cpref, Array.from(this.gens).join(","));
	},
	observe(doc) {
		var list = doc.querySelectorAll(sel);
		if (!list.length) return;

		var menuitem = doc.createXULElement("menuitem");
		for(var args of Object.entries({
			selectiontype: "single",
			oncommand: "cmd(window)",
			nodetype: "folder|query",
			selection: "folder|query",
			label: "Открыть всё в контейнере",
			id: "placesContext_openContainer:tabs:newUsercontext"
		}))
			menuitem.setAttribute(...args);
		menuitem.cmd = this.cmd;
		menuitem.rnd = menuitem.constructor.prototype.render;
		menuitem.render = this.render;
		var [m1, m2] = menuitem.list = Array.from(list);
		(m2 || m1).after(menuitem);

		if (doc.documentElement.getAttribute("windowtype") != "navigator:browser") return;

		for(var btn of [
			doc.getElementById("tabs-newtab-button"),
			doc.getElementById("new-tab-button") ||
				doc.ownerGlobal.gNavToolbox.palette.querySelector("#new-tab-button")
		])
			if (btn) btn.checkForMiddleClick = this.click;

		var win = doc.ownerGlobal;
		this.redefDoSearch(win, win.customElements.get("searchbar").prototype);

		win.gBrowser.tabContainer.addEventListener("TabClose", this.tabClose);
		win.addEventListener("unload", this.winUnload, {once: true});
	},
	winUnload(e) {
		var win = e.target.ownerGlobal;
		win.removeEventListener("TabClose", self.tabClose);
		if (self.quit) return;
		var gb = win.gBrowser;
		if (gb) for(var tab of gb.tabs) self.tabClose(null, tab);
	},
	closed: new Set(),
	cis: ChromeUtils.import("resource://gre/modules/ContextualIdentityService.jsm")
		.ContextualIdentityService,
	tabClose(e, tab = e.target) {
		var id = +tab.getAttribute("usercontextid");
		id && self.gens.has(id) && self.closed.add(id);
		self.closed.size == 1 && ChromeUtils.idleDispatch(self.meaybeRemove);
	},
	meaybeRemove() {
		var ids = Array.from(self.closed);
		self.closed.clear();
		for(var id of ids) self.meaybeRemoveById(id);
	},
	meaybeRemoveById(id) {
		for(var win of CustomizableUI.windows)
			if (win.document.querySelector(`tab.tabbrowser-tab[usercontextid="${id}"]`))
				return;
		this.saveGens(this.gens.delete(id));
		this.cis.remove(id);
	},
	redefDoSearch(win, proto) {
		var code = `(openTrustedLinkIn => [
			{${proto.doSearch}}, openTrustedLinkIn
		])(
			function otl(url, where, params) {
				if (where != "current")
					params.userContextId = otl.newUsercontext(
						document.getElementById("searchbar").value
					);
				openTrustedLinkIn(url, where, params);
			}
		);`;
		(this.redefDoSearch = (win, proto) => {
			var [obj, func] = win.eval(code);
			Object.assign(proto, obj);
			func.newUsercontext = this.newUsercontext;
		})(win, proto);
	},
	click(btn, e) {
		if (!(e.button != 2 || e.ctrlKey || e.shiftKey)) {
			var txt = e.view.readFromClipboard();
			if (txt) {
				var urls = txt.split("\n").map(self.map).filter(Boolean);
				if (urls.length) return e.preventDefault(),
					self.openFromClipboard(e.view, urls);
			}
		}
		e.view.checkForMiddleClick(btn, e);
	},
	eo: Object.create(null),
	map(str) {
		str = str.trim();
		try {
			var scheme = Services.io.extractScheme(str);
			var ph = Services.io.getProtocolHandler(scheme);
			if (ph.scheme == scheme)
				return Services.io.newURI(str) && {uri: str};
		} catch {}
	},
	openFromClipboard(win, urls) {
		if (win.OpenInTabsUtils.confirmOpenInTabs(urls.length, win))
			urls.load = true,
			this.open(win, this.eo, urls);
	},
	async render() {
		this.rnd();
		await new Promise(this.ownerGlobal.requestAnimationFrame);
		this.hidden || (this.hidden = this.list.every(self.every));
	},
	every: node => node.disabled || node.hidden,
	cmd(win) {
		var view = this.parentNode._view;
		var node = win.document.popupNode;
		node = node._placesView && node._placesView.result.root;
		self.open(win, node || view.selectedNode || view.result.root);
	},
	open(win, node, list) {
		var gbw = Cu.import("resource:///modules/PlacesUIUtils.jsm", {}).getBrowserWindow;
		var w = gbw(win);
		this.pu = w.PlacesUIUtils;
		this.fs = w.PlacesUtils.favicons;
		this.sysp = w.E10SUtils.SERIALIZED_SYSTEMPRINCIPAL;

		(this.open = (win, node, list) => {
			this.openURLs(gbw(win), list || win.PlacesUtils.getURLsForContainerNode(node));
			node.bookmarkGuid && this.pu.doCommand(win, "placesCmd_delete");
		})(win, node, list);
	},
	async openURLs(win, urls) {
		var userContextId = this.newUsercontext();
		var mark = !win.PrivateBrowsingUtils.isWindowPrivate(win);
		var {load} = urls, gb = win.gBrowser, pos = gb.selectedTab._tPos;

		for(var {uri, title, isBookmark} of urls) try {
			if (mark) isBookmark
				? this.pu.markPageAsFollowedBookmark(uri)
				: this.pu.markPageAsTyped(uri);

			if (load) {
				gb.addTrustedTab(uri, {index: ++pos, userContextId});
				continue;
			}
			var state = {userContextId, entries: [{
				url: uri,
				title: title || uri,
				triggeringPrincipal_base64: this.sysp
			}]};
			var [,, data, mime] = await new Promise(
				resolve => this.fs.getFaviconDataForPage(
					Services.io.newURI(uri), (...args) => resolve(args), 16
				)
			);
			if (data.length) state.image = `data:${
				mime || "image/x-icon"
			};base64,${
				btoa(String.fromCharCode(...data))
			}`;
			var tab = gb.addTrustedTab(null, {index: ++pos, userContextId});
			win.SessionStore.setTabState(tab, state);
		} catch {};
	}
}).init("chrome-document-loaded"))(
	"#placesContext_openBookmarkContainer\\:tabs,#placesContext_openContainer\\:tabs"
);

voqabuhe пишет

Ну иконки от дополнений, которые их пихают в адресную строку. У меня это Scroll Up Folder и Save-To-Read

Вот так у меня выглядит на нестилизированном профиле (сверху).
Но, если принудительно выкрутить font-size, то да, вытягивает (снизу).

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

Выделить код

Код:

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

А в саму кнопку не можешь добавить регулировку шрифта, или сделать, чтоб она не влияла на другие иконки?

Ну, я же не владею какой-то высокой CSS-магией,
но, чтобы не влияла, вроде как работает min-height.

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

Выделить код

Код:

(async id => ({

	style: `@-moz-document url(chrome://browser/content/browser.xhtml) {
		#${id} {
			min-height: 0 !important;
		}
		#${id}-label {
			font-size: 22px !important;
		}
	}`,
	delay: 2e3,

	val: "",
	init(topic, mm) {
		Services.obs.addObserver(mm = this, topic);
		Services.obs.addObserver(function quit(s, t) {
			this.timer?.cancel();
			Services.obs.removeObserver(mm, topic);
			Services.obs.removeObserver(quit, t);
		}, "quit-application-granted");
	},
	observe(win) {
		var df = win.MozXULElement.parseXULToFragment(
			`<hbox id="${id}"><label id="${id += "-label"}"/></hbox>`
		);
		Cc["@mozilla.org/content/style-sheet-service;1"]
			.getService(Ci.nsIStyleSheetService)
			.loadAndRegisterSheet(Services.io.newURI(
				"data:text/css;charset=utf-8," + encodeURIComponent(this.style)
			), Ci.nsIStyleSheetService.USER_SHEET);
		delete this.style;

		this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
		(this.observe = async win => {
			this.timer.cancel();
			await new Promise(ChromeUtils.idleDispatch);
			win.document.getElementById("star-button-box")
				.after(win.document.importNode(df, true));
			this.notify();
		})(win);
	},
	async notify() {
		var info = await ChromeUtils.requestProcInfo();
		var bytes = info.residentSetSize;
		for(var child of info.children) bytes += child.residentUniqueSize;
		this.timer.initWithCallback(this, this.delay, this.timer.TYPE_ONE_SHOT);

		var prev = this.val;
		if ((this.val = this.mgb(bytes)) != prev)
			for(var win of CustomizableUI.windows) {
				var lab = win.document.getElementById(id);
				if (lab) lab.value = this.val;
			}
	},
	mgb: bytes => bytes < 1073741824
		? Math.round(bytes / 1048576) + "MB"
		: (bytes / 1073741824).toFixed(2) + "GB"
}).init("browser-delayed-startup-finished"))("ucf-mem-indicator");

Отсутствует

 

№1549123-04-2021 11:55:22

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1700
UA: Firefox 78.0

Re: Custom Buttons

Dumby пишет

Что-то я сомневаюсь, что смогу это записать.

Так работает же, класс, спасибо, благодарю!


UPD
Блин, после перезагрузки браузера контейнеры удаляются даже те в которых открыты вкладки

Отредактировано Stkvsky (23-04-2021 15:31:20)

Отсутствует

 

№1549223-04-2021 14:08:17

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

Re: Custom Buttons

Многие сайты показывают Картинки под div, которые нельзя сохранить.
Посоветуйте, каким расширением или user-скриптом сохранять такие картинки или убрать перекрывающий элемент страницы?


На данном сайте (https://mose.live) при клике по постеру открываются фото, которые нельзя сохранить.

Отредактировано Dobrov (23-04-2021 14:10:20)

Отсутствует

 

№1549323-04-2021 15:49:09

vending_machine
Участник
 
Группа: Members
Зарегистрирован: 10-01-2020
Сообщений: 522
UA: unknown 0.0

Re: Custom Buttons

Dobrov пишет

Многие сайты показывают Картинки под div, которые нельзя сохранить.
Посоветуйте, каким расширением или user-скриптом сохранять такие картинки или убрать перекрывающий элемент страницы?


На данном сайте (https://mose.live) при клике по постеру открываются фото, которые нельзя сохранить.

Можно сделать скрин.

Отсутствует

 

№1549424-04-2021 06:49:55

voqabuhe
Участник
 
Группа: Members
Зарегистрирован: 06-12-2011
Сообщений: 3231
UA: Firefox 88.0

Re: Custom Buttons

Dumby пишет

Ну, я же не владею какой-то высокой CSS-магией,
но, чтобы не влияла, вроде как работает min-height.

Спасибо. Теперь иконки пришли в норму.

Отсутствует

 

№1549524-04-2021 10:13:01

momo2000
Участник
 
Группа: Members
Зарегистрирован: 03-09-2015
Сообщений: 228
UA: Firefox 88.0

Re: Custom Buttons

Подскажите по кнопе AutoCopy. Может кто всё лишнее убрать из кода, нужна только функция автокопирования в буфер.

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

Выделить код

Код:

this.closest("toolbarpaletteitem") || (script => {
    var id = `CB${_id.slice(20)}:Autocopy`, pid = id + "Parent";
    var nsvoStr = `Components.utils.import("resource://gre/modules/Services.jsm", {})`;
    var nsvo = eval(nsvoStr), {Services} = nsvo, parent = nsvo[pid];
    if (!parent) {
        var cid = id + "Child", u = code => "data:," + encodeURIComponent(code);
        var pref = "CB.Autocopy.settings", topic = "quit-application-granted";
        var PREF_ENABLED = 1;

        (parent = nsvo[pid] = {
            init() {
                this.readSettings();
                if (!this[PREF_ENABLED]) return;
                this.initChild();
            },
            destroy(reason) {
                var ud = reason[5] == "e";
                if (ud || !this.obsAdded) this.saveSettings();
                delete nsvo[pid];
                if (reason == "delete") Services.prefs.clearUserPref(pref);
                if (!this[PREF_ENABLED]) return;
                this.destroyChild();
            },
            get processURL() {
                delete this.processURL;
                this.frameURL = u(`${nsvoStr}["${cid}"].init(this);`);
                return this.processURL = u(script.replace(/%ID%/g, cid)
                    .replace("%NSVO%", nsvoStr)
                );
            },
            get frameURLDestroy() {
                delete this.frameURLDestroy;
                this.processURLDestroy = u(`${nsvoStr}["${cid}"].forget();`);
                return this.frameURLDestroy = u(`${nsvoStr}["${cid}"].destroy(this);`);
            },
            initChild() {
                Services.ppmm.loadProcessScript(this.processURL, true);
                Services.mm.loadFrameScript(this.frameURL, true);
            },
            destroyChild() {
                Services.mm.removeDelayedFrameScript(this.frameURL);
                Services.mm.loadFrameScript(this.frameURLDestroy, false);
                Services.ppmm.removeDelayedProcessScript(this.processURL);
                Services.ppmm.loadProcessScript(this.processURLDestroy, false);
            },
            readSettings() {
                this.prefVal = Services.prefs.getIntPref(pref, 3);
                for(var setting of [PREF_ENABLED])
                    this[setting] = Boolean(this.prefVal & setting);
            },
            saveSettings() {
                var settings = 0;
                for(var setting of [PREF_ENABLED])
                    if (this[setting]) settings += setting;
                if (this.prefVal != settings)
                    Services.prefs.setIntPref(pref, settings);
            },
            obsAdded: false,
            setObserver(set) {this.obsAdded = set
                ? Services.obs.addObserver(this, topic, false)
                : Services.obs.removeObserver(this, topic);
            },
            observe() {
                Services.obs.removeObserver(this, topic);
                this[PREF_ENABLED] = false;
                this.saveSettings();
            }
        }).init();
    }
    parent.register(this);
    addDestructor(reason => parent.unregister(this, reason), parent);
})

(`(nsvo => (nsvo["%ID%"] = {
    x: -1, y: -1, d: false,
    handleEvent(e) {e.button || this[e.type](e);},
    mousedown(e) {this.x = e.screenX; this.y = e.screenY, this.down = true;},
    mouseup(e) {
        var {down} = this; this.down = false; if (!down) return;
        if (e.screenX == this.x && e.screenY == this.y && (e.detail == 1 || e.target.matches(
            "textarea[disabled],input[disabled],button,select,summary"
        )))
            return;
        var name = e.originalTarget.nodeName;
        if (/^(?:(?:xul:)?(?:slider|scrollbarbutton)|resizer)$/.test(name))
            return;
        this.x = this.y = -1;
        var win = this.getFocusedWin(e.target.ownerGlobal);
        var sel = win.getSelection();
        if (sel.toString()) {
            (win.docShell || win.document.docShell).doCommand("cmd_copy", null, win);
        }
    },
    get fm() {
        delete this.fm;
        return this.fm = Components.classes["@mozilla.org/focus-manager;1"]
            .getService(Components.interfaces.nsIFocusManager);
    },
    getFocusedWin(win) {
        var focusedWin = {};
        var elm = this.fm.getFocusedElementForWindow(win.top, true, focusedWin);
        return focusedWin.value;
    },
    count: 0,
    init(cfmm) {
        this.count += 1;
        cfmm.addEventListener("mousedown", this);
        cfmm.addEventListener("mouseup", this);
        if (this.count == 1)
            this.cpmm.addMessageListener("%ID%:FromParent", this);
    },
    destroy(cfmm) {
        this.count -= 1;
        cfmm.removeEventListener("mousedown", this);
        cfmm.removeEventListener("mouseup", this);
        if (!this.count)
            this.cpmm.removeMessageListener("%ID%:FromParent", this);
    },
}).cpmm = this)(%NSVO%);`)

Это я уже всё что мог лишнее убрал, но иконка кнопки стала мутной, значит что то не то.

Или может скрипт есть?

Отредактировано momo2000 (24-04-2021 10:29:53)

Отсутствует

 

№1549624-04-2021 12:05:50

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

Re: Custom Buttons

momo2000
https://forum.mozilla-russia.org/viewto … 93#p785193


Add, или такой вариант

Отредактировано kokoss (24-04-2021 16:36:45)


Win7

Отсутствует

 

№1549724-04-2021 16:45:00

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

Re: Custom Buttons

momo2000 пишет

Или может скрипт есть?

Можно попробовать создать JSM'ку
и импортировать её из custom_script.js

AutoCopyChild.jsm

Выделить код

Код:

var EXPORTED_SYMBOLS = ["AutoCopyChild"];

ChromeUtils.domProcessChild.childID || ChromeUtils.registerWindowActor("AutoCopy", {
	messageManagerGroups: ["browsers"], allFrames: true,
	child: {moduleURI: __URI__, events: {DOMDocElementInserted: {}}}
});
var re = /\S/;
var QueryInterface = ChromeUtils.generateQI(["nsISelectionListener"]);

var reasons = ["MOUSEUP", "KEYPRESS", "SELECTALL"]
	.map(reason => Ci.nsISelectionListener[reason + "_REASON"]);

class AutoCopyChild extends JSWindowActorChild {
	constructor() {
		super();
		this.listener = {
			QueryInterface,
			notifySelectionChanged: (d, sel, reason) =>
				reasons.includes(reason) && re.test(sel)
					&& this.docShell.doCommand("cmd_copy")
		};
	}
	async handleEvent() {
		await new Promise(ChromeUtils.idleDispatch);
		(this.sel = this.contentWindow.getSelection())
			.addSelectionListener(this.listener);		
	}
	didDestroy() {
		this.sel.removeSelectionListener(this.listener);
		this.sel = this.listener = null;
	}
}

Отредактировано Dumby (25-04-2021 22:12:52)

Отсутствует

 

№1549824-04-2021 17:36:05

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1700
UA: Firefox 78.0

Re: Custom Buttons

Dumby

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

Выделить код

Код:

(async (sel, self) => ({

	icon: "circle",
	colors: [
		"mediumseagreen",
		"silver",
		"crimson",
		"blue",
		"peru",
	],

	initColors() {
		var colorName = "ucf-gen";
		var css = "@-moz-document url(about:preferences#containers),"
			+ " url-prefix(chrome://browser/content/browser.x) {\n";
		this.colors.forEach((color, ind) => {
			var [ic, tc] = color.split(/\s*\|\s*/);
			css += `\t.identity-color-${colorName}${ind} {\n`
				+ `\t\t--identity-tab-color: ${tc || ic};\n`
				+ `\t\t--identity-icon-color: ${ic};\n\t}\n`
		});
		var url = "data:text/css;charset=utf-8," + encodeURIComponent(css + "}");
		var sss = Cc["@mozilla.org/content/style-sheet-service;1"]
			.getService(Ci.nsIStyleSheetService);
		sss.loadAndRegisterSheet(Services.io.newURI(url), sss.USER_SHEET);

		var len = this.colors.length;
		var pref = "ucf.openInGeneratedContainer.lastColor";
		var ind = Math.min(Services.prefs.getIntPref(pref, -1), len - 1);
		this.nextColor = () => {
			var next = ind + 1;
			Services.prefs.setIntPref(pref, ind = next == len ? 0 : next);
			return colorName + ind;
		}
	},
	quit: false,
	init(topic) {
		Services.obs.addObserver(self = this, topic);
		Services.obs.addObserver(function quit(s, t) {
			self.quit = true;
			Services.obs.removeObserver(self, topic);
			Services.obs.removeObserver(quit, t);
		}, "quit-application-granted");
		this.initColors();
		this.newUsercontext = name => {
			var id = this.cis.create(
				name || `[ ${this.cis._lastUserContextId + 1} ]`, this.icon, this.nextColor()
			).userContextId;
			this.saveGens(this.gens.add(id));
			return id;
		}
		var cpref = "ucf.openInGeneratedContainer.containers";
		this.gens = new Set(
			Services.prefs.getStringPref(cpref, "").split(",").map(Number).filter(Boolean)
		);
		this.saveGens = () => Services.prefs.setStringPref(cpref, Array.from(this.gens).join(","));
	},
	observe(doc) {
		var list = doc.querySelectorAll(sel);
		if (!list.length) return;

		var menuitem = doc.createXULElement("menuitem");
		for(var args of Object.entries({
			selectiontype: "single",
			oncommand: "cmd(window)",
			nodetype: "folder|query",
			selection: "folder|query",
			label: "Открыть всё в контейнере",
			id: "placesContext_openContainer:tabs:newUsercontext"
		}))
			menuitem.setAttribute(...args);
		menuitem.cmd = this.cmd;
		menuitem.rnd = menuitem.constructor.prototype.render;
		menuitem.render = this.render;
		var [m1, m2] = menuitem.list = Array.from(list);
		(m2 || m1).after(menuitem);

		if (doc.documentElement.getAttribute("windowtype") != "navigator:browser") return;

		for(var btn of [
			doc.getElementById("tabs-newtab-button"),
			doc.getElementById("new-tab-button") ||
				doc.ownerGlobal.gNavToolbox.palette.querySelector("#new-tab-button")
		])
			if (btn) btn.checkForMiddleClick = this.click;

		var win = doc.ownerGlobal;
		this.redefDoSearch(win, win.customElements.get("searchbar").prototype);

		win.gBrowser.tabContainer.addEventListener("TabClose", this.tabClose);
		win.addEventListener("unload", this.winUnload, {once: true});
	},
	winUnload(e) {
		var win = e.target.ownerGlobal;
		win.removeEventListener("TabClose", self.tabClose);
		if (self.quit) return;
		var gb = win.gBrowser;
		if (gb) for(var tab of gb.tabs) self.tabClose(null, tab);
	},
	closed: new Set(),
	cis: ChromeUtils.import("resource://gre/modules/ContextualIdentityService.jsm")
		.ContextualIdentityService,
	tabClose(e, tab = e.target) {
		var id = +tab.getAttribute("usercontextid");
		id && self.gens.has(id) && self.closed.add(id);
		self.closed.size == 1 && ChromeUtils.idleDispatch(self.meaybeRemove);
	},
	meaybeRemove() {
		var ids = Array.from(self.closed);
		self.closed.clear();
		for(var id of ids) self.meaybeRemoveById(id);
	},
	meaybeRemoveById(id) {
		for(var win of CustomizableUI.windows)
			if (win.document.querySelector(`tab.tabbrowser-tab[usercontextid="${id}"]`))
				return;
		this.saveGens(this.gens.delete(id));
		this.cis.remove(id);
	},
	redefDoSearch(win, proto) {
		var code = `(openTrustedLinkIn => [
			{${proto.doSearch}}, openTrustedLinkIn
		])(
			function otl(url, where, params) {
				if (where != "current")
					params.userContextId = otl.newUsercontext(
						document.getElementById("searchbar").value
					);
				openTrustedLinkIn(url, where, params);
			}
		);`;
		(this.redefDoSearch = (win, proto) => {
			var [obj, func] = win.eval(code);
			Object.assign(proto, obj);
			func.newUsercontext = this.newUsercontext;
		})(win, proto);
	},
	click(btn, e) {
		if (!(e.button != 2 || e.ctrlKey || e.shiftKey)) {
			var txt = e.view.readFromClipboard();
			if (txt) {
				var urls = txt.split("\n").map(self.map).filter(Boolean);
				if (urls.length) return e.preventDefault(),
					self.openFromClipboard(e.view, urls);
			}
		}
		e.view.checkForMiddleClick(btn, e);
	},
	eo: Object.create(null),
	map(str) {
		str = str.trim();
		try {
			var scheme = Services.io.extractScheme(str);
			var ph = Services.io.getProtocolHandler(scheme);
			if (ph.scheme == scheme)
				return Services.io.newURI(str) && {uri: str};
		} catch {}
	},
	openFromClipboard(win, urls) {
		if (win.OpenInTabsUtils.confirmOpenInTabs(urls.length, win))
			urls.load = true,
			this.open(win, this.eo, urls);
	},
	async render() {
		this.rnd();
		await new Promise(this.ownerGlobal.requestAnimationFrame);
		this.hidden || (this.hidden = this.list.every(self.every));
	},
	every: node => node.disabled || node.hidden,
	cmd(win) {
		var view = this.parentNode._view;
		var node = win.document.popupNode;
		node = node._placesView && node._placesView.result.root;
		self.open(win, node || view.selectedNode || view.result.root);
	},
	open(win, node, list) {
		var gbw = Cu.import("resource:///modules/PlacesUIUtils.jsm", {}).getBrowserWindow;
		var w = gbw(win);
		this.pu = w.PlacesUIUtils;
		this.fs = w.PlacesUtils.favicons;
		this.sysp = w.E10SUtils.SERIALIZED_SYSTEMPRINCIPAL;

		(this.open = (win, node, list) => {
			this.openURLs(gbw(win), list || win.PlacesUtils.getURLsForContainerNode(node));
			node.bookmarkGuid && this.pu.doCommand(win, "placesCmd_delete");
		})(win, node, list);
	},
	async openURLs(win, urls) {
		var userContextId = this.newUsercontext();
		var mark = !win.PrivateBrowsingUtils.isWindowPrivate(win);
		var {load} = urls, gb = win.gBrowser, pos = gb.selectedTab._tPos;

		for(var {uri, title, isBookmark} of urls) try {
			if (mark) isBookmark
				? this.pu.markPageAsFollowedBookmark(uri)
				: this.pu.markPageAsTyped(uri);

			if (load) {
				gb.addTrustedTab(uri, {index: ++pos, userContextId});
				continue;
			}
			var state = {userContextId, entries: [{
				url: uri,
				title: title || uri,
				triggeringPrincipal_base64: this.sysp
			}]};
			var [,, data, mime] = await new Promise(
				resolve => this.fs.getFaviconDataForPage(
					Services.io.newURI(uri), (...args) => resolve(args), 16
				)
			);
			if (data.length) state.image = `data:${
				mime || "image/x-icon"
			};base64,${
				btoa(String.fromCharCode(...data))
			}`;
			var tab = gb.addTrustedTab(null, {index: ++pos, userContextId});
			win.SessionStore.setTabState(tab, state);
		} catch {};
	}
}).init("chrome-document-loaded"))(
	"#placesContext_openBookmarkContainer\\:tabs,#placesContext_openContainer\\:tabs"
);


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

Отредактировано Stkvsky (24-04-2021 18:13:02)

Отсутствует

 

№1549924-04-2021 17:56:08

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

Re: Custom Buttons

Stkvsky
Я пробовал поперезапускать, и ничего не удаляется.
Наверно нужен какой-то хитрый STR, а взять негде.

Отсутствует

 

№1550024-04-2021 18:13:52

Stkvsky
Участник
 
Группа: Members
Зарегистрирован: 26-06-2012
Сообщений: 1700
UA: Firefox 78.0

Re: Custom Buttons

Dumby
Блин, извиняюсь, не точно выразился, не при перезапуске, а при закрытии
Если закрыть браузер и запустить заново, контейнер удаляется

Отредактировано Stkvsky (24-04-2021 19:08:27)

Отсутствует

 

Board footer

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