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

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

№1630121-02-2022 13:50:33

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

Re: Custom Buttons

Dumby пишет

Задержку при нажатии кнопок даёт не LongPress, а необходимость поддержки dblclick.
Нужно ведь подождать, что двойной клик случится (или не случится), правда же?

В других скриптах не было задержек для dblclick и обычных кликов - например в сохранить картинку колёсиком можно двойным кликом искать похожие фото.
То есть события addEventListener("dblclick" и "click" - срабатывают без задержек, видимо потому, что их обработка делается системой.

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

Отсутствует

 

№1630221-02-2022 18:14:17

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

Re: Custom Buttons

ВВП пишет

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

Можно, в круглых скобках и через запятую.
Можно, но не нужно. Лучше простая и понятная классика,
if (…) и {список выражений в фигурных скобках}

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

Выделить код

Код:

{
	if(Services.prompt.confirm(null, null, "???")) {
		this.undoCloseTabsList.clearAllLists();
		SessionStore.canRestoreLastSession = false;
	}
}

Dobrov пишет

и "click"

Это где там мог "click" померещиться?


Видимо, я что-то непонятное написал.
Хорошо, переформулирую. Попробуй написать код:
1. Одинарный клик левой кнопкой мыши — console.log(1);
2. Двойной (там же) клик левой кнопкой мыши — только console.log(2);
    (без предшествующего console.log(1) от одинарного клика, разумеется).


И чтобы никаких задержек при одинарном клике.
И не мухлевать, никакой "новейший чип «Телепат-3000»"
на комп не устанавливать.

Отсутствует

 

№1630321-02-2022 18:32:32

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 258
UA: Firefox 97.0

Re: Custom Buttons

Dumby
От же затупил я. Вроде так же и делал . Так да не так...

Отсутствует

 

№1630422-02-2022 02:03:29

Krtec
Участник
 
Группа: Members
Зарегистрирован: 17-02-2022
Сообщений: 6
UA: Firefox 78.0

Re: Custom Buttons

Dumby пишет

просто пощёкать подряд чтоб отмотать

Почему-то у меня не "отматывает", всё одно между двумя последними активными переключается. Открыл поочерёдно четыре вкладки, клацнул по четвёртой — переключился на третью, клацнул по третьей — обратно на четвёртую.

Dumby пишет

Как-то это поперёк концепции.

В данном случае похоже на то. А вообще — аналогично сворачиванию окон. В древней [opera] была такая настройка вкладок: "сворачивать щелчком по вкладке". В своё время привык к такому поведению и сейчас его несколько не хватает.
Если нет простого решения, поперёк концепции ломиться не стоит, мышиная замена ctrl+tab тоже вполне себе. Спасибо.

Отсутствует

 

№1630522-02-2022 02:25:19

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

Re: Custom Buttons

Dumby пишет

Попробуй написать код:………
И чтобы никаких задержек при одинарном клике.

Задержек нет в кнопке сохранения картинок для событий "auxclick" и "dblclick" – клик колёсиком и двойной действуют сразу. Значит, это возможно!
Сделал кнопку для "click" и "dblclick" - при двойном клике также срабатывет "click". Кроме того, в коде перехвата кликов задержка для "dblclick" желательна в 2 раза больше, чем на "LongPress", иначе может срабатывать одинарный клик вместе с "dblclick". Ещё после одинарного клика может сработать "LongPress". У меня так было, пока не изменил задержки в setTimeout(.
То есть, недостаток в том, что задержка реакции кнопки на действия не менее пол-секунды.


Просьба упростить тестовый ucf_hookClicks.js, убрать из него "dblclick". Возможно это ускорит в 2 раза реакцию на действия кнопки. Кроме того, на сенсорных экранах удобнее обычный тап (клик) и удержание на кнопке, чем двойной тап, поэтому для сенсорных экранов такая логика лучше. Ещё желательно при долгом клике воспроизвести звук. Встроенный короткий сигнал, если в браузере есть такой или внешний wav aac ogg файл…

Выделить код

Код:

if (++num in obj) //  задержка реакции кнопки на действия в 2 раза больше, чем "LongPress"
	this.mousedownTID = setTimeout(this.onLongPress, 250, trg, obj, num);
……………
dbl
	? obj[num](trg) // после однократного клика действие выполняется с данной задержкой в мс
	: this.clickTID = setTimeout(this.exec, 500, trg, obj, num); // время ожидания второго клика

Отредактировано Dobrov (22-02-2022 02:56:20)

Отсутствует

 

№1630622-02-2022 09:01:50

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

Re: Custom Buttons

Krtec пишет

Открыл поочерёдно четыре вкладки, клацнул по четвёртой — переключился на третью, клацнул по третьей — обратно на четвёртую

Не, должно переключиться на вторую.
Может кэш залип? Чтобы исключить такой вариант,
следует закрыть Firefox, и удалить папку startupCache
из Локального каталога профиля вручную.


Dobrov пишет

Просьба упростить тестовый ucf_hookClicks.js, убрать из него "dblclick".
Ещё желательно при долгом клике воспроизвести звук. Встроенный короткий сигнал, если в браузере есть такой или внешний wav aac ogg файл…

Хорошо, попробую. Как бы чего-нибудь не испортить.

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

Выделить код

Код:

(async (id) => { // для custom_script_win.js: дополнительные клики и подсказки кнопок © Dumby

	var dsym = Symbol(), j = (...args) => args.join("\n"), tooltips = {

	[dsym]: j(GetDynamicShortcutTooltipText("downloads-button"),
		`\nДвойной клик: открыть [Загрузки]`
	),
	get "downloads-button"() { var hint = this[dsym];
		try {var dw = Services.prefs.getComplexValue("browser.download.dir", Ci.nsIFile);}
			catch {dw = Services.dirsvc.get("DfltDwnld", Ci.nsIFile);} //отличается от ⇧
		if (dw) hint += "\n\n[Загрузки] — выбранная папка:\n" + dw.path;
		return hint;
	}
	}; /* end tooltips */

	var listener = { // дополнительные клики кнопок и перехват существующих
		filter(sel) {
			return this.closest(sel);
		},
		find(sel) {
			return data[sel][this] || data[sel][this + 1];
		},
		handleEvent(e) {
			if (this.skip || e.detail > 1) return;

			var trg = e.target;
			var sels = this.selectors.filter(this.filter, trg);
			var {length} = sels;
			if (!length) return;

			var wh = e.type.startsWith("w");

			var num = e.metaKey *32 + e.ctrlKey *16 + e.shiftKey *8 + e.altKey *4 + (wh ? 2 : e.button *64);

			var obj = data[
				length > 1 && sels.find(this.find, num) || sels[0]
			];
// wheel
			if (wh) return obj[num]?.(trg, e.deltaY < 0);
// mousedown
			if (e.type.startsWith("m")) {
				obj.mousedownTarget && this.stop(e);

				this.longPress = false;
				if (++num in obj)
					this.mousedownTID = setTimeout(this.onLongPress, 640, trg, obj, num);
				if (e.button == 2)
					this.ctx = trg.getAttribute("context"),
					trg.setAttribute("context", "");
				return;
			}
// click
			obj.mousedownTarget || this.stop(e);
			if (this.longPress) return this.longPress = false;

			this.mousedownTID &&= clearTimeout(this.mousedownTID);
	
			if (!obj[num]) {
				if (e.button == 1) return;
				if (e.button) {
					num = "context";
					for(var p in this.a) this.a[p] = e[p];
				} else
					num = "dispatch",
					this.mdt = obj.mousedownTarget;
				obj = this;
			}
			obj[num](trg);
		},
		get selectors() {
			this.onLongPress = (trg, obj, num) => {
				this.mousedownTID = null;
				this.longPress = true;
				obj[num](trg);
			}
			delete this.selectors;
			return this.selectors = Object.keys(data);
		},
		get mdEvent() {
			delete this.mdEvent;
			return this.mdEvent = new MouseEvent("mousedown", {bubbles: true});
		},
		context(trg) {
			this.ctx
				? trg.setAttribute("context", this.ctx)
				: trg.removeAttribute("context");
			trg.dispatchEvent(new MouseEvent("contextmenu", this.a));
		},
		dispatch(trg) {
			this.skip = true;
			this.mdt ? trg.dispatchEvent(this.mdEvent) : trg.click();
			this.skip = false;
		},
		stop: e => {
			e.preventDefault();
			e.stopImmediatePropagation();
		},
		a: {__proto__: null, bubbles: true, screenX: 0, screenY: 0}
	};

	var onMouseenter = e => {
		var trg = e.target;
		var hint = tooltips[trg.id] || tooltips[(trg = trg.parentNode).id];
		if (hint) trg.tooltipText = hint;
	}
	var keydown_win = e => { // нажатие клавиш
		log(e.keyCode);
	}
	window.addEventListener("keydown", keydown_win);
	var toolbars = ["nav-bar", "ucf-additional-vertical-bar"].map(i => document.getElementById(i)).filter(Boolean);
	var events = ["click", "mousedown", "wheel"]; // appMenu-protonMainView
	toolbars[0].addEventListener("mouseenter", onMouseenter, true);
	for(var bar of toolbars) for(var type of events)
		bar.addEventListener(type, listener, true);
	ucf_custom_script_win.unloadlisteners.push(id);
	ucf_custom_script_win[id] = {destructor() {
		window.removeEventListener("keydown", keydown_win);
		toolbars[0].removeEventListener("mouseenter", onMouseenter, true);
		for(var bar of toolbars) for(var type of events)
			bar.removeEventListener(type, listener, true);
	}};
	var addDestructor = nextDestructor => {
		var {destructor} = ucf_custom_script_win[id];
		ucf_custom_script_win[id].destructor = () => {
			try {destructor();} catch(ex) {Cu.reportError(ex);}
			nextDestructor();
		}
	} // end Hooks

	var {prefs, dirsvc} = Services, log = msg => Services.console.logStringMessage("[HC] "+ msg); // отладка
	prefs.setBoolPref("browser.download.autohideButton", false); // не скрывать кнопку Загрузки

	var showInStatusPanel = (info, time = 5000, StatusPanel = window.StatusPanel) => {
		if (StatusPanel.update.tid)
			clearTimeout(StatusPanel.update.tid)
		else {
			var {update} = StatusPanel;
			StatusPanel.update = () => {};
			StatusPanel.update.ret = () => {
				StatusPanel.update = update;
				StatusPanel.update();
			}
		}
		StatusPanel.update.tid = setTimeout(StatusPanel.update.ret, time);
		StatusPanel._label = info;
		log(info);
	},
	data = {
		"#downloads-button": { mousedownTarget: true, // + отправить текст в консоль

			2(trg, forward) {
				showInStatusPanel("DW Wheel " + (forward ? "forward" : "backward"));
			},
			8(btn) {
				showInStatusPanel("Shift + ЛКМ");
			},
			64() {
				showInStatusPanel("СКМ Click");
			},
			128() {
				showInStatusPanel("ПКМ Click");
			},
			132(btn) {
				showInStatusPanel("Alt + ПКМ");
			},

			1(btn) {
				showInStatusPanel("Left Long Press");
				var a = new Audio();
				a.volume = .3;
				a.src = "data:audio/wav;base64,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rWWuFauMYbnPOsbkweKayC8XtvJCabW1fX//pS3GlttbZIiBqogujCkEIFIVlQYlZFMMBiMbsIhpkSEDjsCUEDBkqUq4NA4sQVXSTTfX4mG7Mji9DCa0cpGTSy3Gk/wo1apV4z2R/BvbOIsGCrYmrT6izZ3bFq/TzTXvxyrwifCRMgLuqd0Gft/SI6XJZJGmiANUwBHYOiVIF//7oACugAOmL8jrGXrQakSo/WcvSk28pyOsZetBZBSj9ZyhaLr8OJe6IA4owoxrVSwwtYHGrsTGSSIQe1YBpqK3QQuOzD5MFpWz5MSWHQbNFSDQ7HWColaj/127v7ifiyY7Sj1PpUve2x55XiwRtFSSf1AGcFg41iKKxZp+AIKaUbfEwLeiDUcDdRhbQYkju3sRVUhb6CxWCtJMbIpItKRixIaC9FPhjRll6+VbI/gsT/SUFWnGhQFXKDrFAXqsWE//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////xbFLbZ/IAfSj1A0Go4giiYWKIJJkvUq99hHJX0HsEauwqnfpJyZgaAqaChYVmUTglYRVyTMB4qnBW28D6WyfXyT4M2V1r/2jWxbdbJL9IAdqHOT8VAS0pADk1JE9kTawUpMUaRzdmkna2p5apDbICcUwYmSGi2FF1g+bcPeFAkeJLyIsOqAT+v/7ogDOgAiqGsdjOXpASMO5DGcJSUfoVyGH5YcgxoqkMPwk5IW3a2R9AAHhAxhWi4nSfgIY/1VODSJHRxL+cdp/Yt3dl9x00vDKrZJdmyatz60h7wBWEssrbdIABtFIalKdOHp8i5J7ARfLN+BVaKECuBff/Hm7////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+6AA2oAOOAfIYW9gqhjBCMQd4iVAAAEuAAAAIBSAYxAAAAT///////////////////////8JNpEg4HAkxq4EyVpo2eggIVDbpf/4WULEAAgAAdT/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+6AA2wAPMABLgAAACAAACXAAAAEAAAEuAAAAIAAAJcAAAAT///////////////////////////////////////////////////////////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
				a.play();
			},
			129(btn) {
				showInStatusPanel("Right Long Press");
				Cc["@mozilla.org/sound;1"].getService(Ci.nsISound).beep();
			}
		},
	}; // end Clicks, HotKeys ==================================================

})("hookClicks-and-tooltips-test"); // END hookClicks

Отсутствует

 

№1630722-02-2022 13:35:48

Krtec
Участник
 
Группа: Members
Зарегистрирован: 17-02-2022
Сообщений: 6
UA: Firefox 78.0

Re: Custom Buttons

Dumby пишет

Может кэш залип?

Нет, это я в первую очередь проделал, не работает из секции по событию "load", переместил код в конец custom_script_win.js — заработало. Большое спасибо!

Отсутствует

 

№1630822-02-2022 17:00:11

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

Re: Custom Buttons

Krtec пишет

не работает из секции по событию "load"

Да, точно, я вижу это, мой косяк.


Дело в том, что из этой точки, стэк вызовов (Components.stack.formattedStack)
будет выглядеть иначе (прицепится "load/"). Заменил пока regexp.

Отсутствует

 

№1630923-02-2022 01:00:06

Krtec
Участник
 
Группа: Members
Зарегистрирован: 17-02-2022
Сообщений: 6
UA: Firefox 78.0

Re: Custom Buttons

Dumby, спасибо, теперь в секции по событию "load" работает. А в данном случае это имеет значение? Предыдущий вариант, перемещённый в конец custom_script_win ведь тоже работал.

Отсутствует

 

№1631023-02-2022 13:34:49

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 258
UA: Firefox 97.0

Re: Custom Buttons

Dumby
А по умолчанию никак заблокировать ?
7g6ge8tb.jpg

Отсутствует

 

№1631123-02-2022 21:18:42

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

Re: Custom Buttons

Krtec пишет

А в данном случае это имеет значение? Предыдущий вариант, перемещённый в конец custom_script_win ведь тоже работал.

Да нет, никакого особого значения это, надеюсь, не имеет,
просто нехорошо, что из "load" не работало.


ВВП пишет

А по умолчанию никак заблокировать ?

Если типа из предусмотренного, то, похоже, что никак.
Либо «Всегда спрашивать», либо «Разрешить» (что-то даже разницы не пойму).


resource:///modules/SitePermissions.jsm пишет
Выделить код

Код:

…
    install: {
      getDefault() {
        return Services.prefs.getBoolPref("xpinstall.whitelist.required")
          ? SitePermissions.UNKNOWN
          : SitePermissions.ALLOW;
      },
    },

Отредактировано Dumby (23-02-2022 21:19:12)

Отсутствует

 

№1631223-02-2022 23:30:48

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 258
UA: Firefox 97.0

Re: Custom Buttons

Dumby

Dumby пишет

resource:///modules/SitePermissions.jsm пишет

Да ставил там BLOCK  и xpinstall.whitelist.required - ? . Бесполезно,даже не предупреждает. ???

Отсутствует

 

№1631327-02-2022 22:29:34

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

Re: Custom Buttons

Dumby №15702
Куда этот "Текстовый редактор" определить то? В custom_script.js не заработал. Где ему место?

Отсутствует

 

№1631428-02-2022 00:30:19

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

Re: Custom Buttons

voqabuhe

voqabuhe пишет

В custom_script.js не заработал.

Попробуйте удалить папку startupCache, и так проверьте.


Win7

Отсутствует

 

№1631528-02-2022 02:33:05

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

Re: Custom Buttons

voqabuhe пишет

Где ему место?

В отдельном файле и load в custom_script.js. :) И проверить, как сказал kokoss.

Отсутствует

 

№1631628-02-2022 04:21:06

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

Re: Custom Buttons

kokoss, xrun1, спасибо. Вечно забываю, что кнопка Перезапустить и заново создать кэш быстрого запуска в таких случаях не всегда помогает.  А как бы ещё AkelPad заменить на notepad++?

Отредактировано voqabuhe (28-02-2022 04:21:45)

Отсутствует

 

№1631728-02-2022 13:56:04

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

Re: Custom Buttons

voqabuhe пишет

А как бы ещё AkelPad заменить на notepad++?

Не пробовали путь изменить?!


Win7

Отсутствует

 

№1631828-02-2022 17:28:34

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

Re: Custom Buttons

kokoss пишет

Не пробовали путь изменить?!

Ну как же, конечно пробовал. Но уж очень был вчерась невнимателен и не заметил, что слэш двойной. :dumb: Спасибо, завелась. :D

Отсутствует

 

№1631902-03-2022 04:31:32

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

Re: Custom Buttons

Dumby - ещё одно неудобство Simple Session Manager в дополнение к перечисленным:


При запуске браузера восстанавливается [boot]-сессия (выделанная красным). Прошло несколько дней, запускаю браузер на другой машине и не понимаю, откуда каждый раз берутся открываемые вкладки.
Удобнее, чтобы при запуске лис показал сообщение (пробовал добавлять showAlertNotification, но в observe(s, t, data… это не работает):
showAlertNotification(null, this.label, `Восстановление [boot]-сессии\n`+ ИМЯ восстанавливаемой сессии, false);

Отсутствует

 

№1632002-03-2022 22:33:55

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

Re: Custom Buttons

Dobrov пишет

в observe(s, t, data… это не работает

Конечно не работает, observe() вызывается по топику "quit-application",
там уже ни что подобное не возможно. Зачем вообще туда,
это ведь нечто противоположное «… чтобы при запуске лис показал …».


Тут нужно что-то в init() добавить, типа такого.
Не связанные, разумеется, напрямую вещи,
но не проверять же ещё что-то дополнительно.

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

Выделить код

Код:

…
		if (!Services.startup.wasRestarted && this.meta.boot != null) {
			var name = this.id + "-startup-notification";
			var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
			as.showAlertNotification(
				this.image, this.label,
				"Восстановление [boot]-сессии\n\n" + this.meta.order[this.meta.boot],
				false, null, null, name
			);
			setTimeout(() => as.closeAlert(name), 5e3);
		}


Bug 1734987 - Part 2: Refactor verifySignedState to not require AddonInternal


Антиподписячий код с поправкой.

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

Выделить код

Код:

//
try {(nsvo => {
	var g = Cu.getGlobalForObject(nsvo), o = g.Object, {freeze} = o, NEW;
	o.freeze = obj => {
		if (Components.stack.caller.filename != "resource://gre/modules/AppConstants.jsm")
			return freeze(obj);
		obj.MOZ_REQUIRE_SIGNING = false;
		if ((NEW = "MOZ_ALLOW_ADDON_SIDELOAD" in obj))
			lockPref("extensions.experiments.enabled", true);
		else
			obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true,
			lockPref("extensions.legacy.enabled", true);

		return (o.freeze = freeze)(obj);
	}
	lockPref("xpinstall.signatures.required", false);
	lockPref("extensions.langpacks.signatures.required", false);

	nsvo = Cu.import("resource://gre/modules/addons/XPIInstall.jsm", {});
	var shouldVerify = nsvo.shouldVerifySignedState;
	if (shouldVerify.length == 1)
		nsvo.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon);
	else {
		var {Services} = g.ChromeUtils.import("resource://gre/modules/Services.jsm");
		var subst = "pkg-proto-patch-tmp-script";
		var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
		var func = async proto => Object.assign(proto, eval(
			`({${proto.verifySignedState}})`.replace("(!", "(addonId || !")
		));
		var code = encodeURIComponent(`(${func})(Package.prototype);`);
		rph.setSubstitution(subst, Services.io.newURI("data:," + code));
		Services.scriptloader.loadSubScript(`resource://${subst}/`, nsvo);
		rph.setSubstitution(subst, null);
	}
	if (NEW) nsvo.XPIDatabase.isDisabledLegacy = () => false;
})(
	"permitCPOWsInScope" in Cu
		? Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}) : Cu
);}
catch(ex) {Cu.reportError(ex);}


Запускатор для CB остаётся прежним.

Отсутствует

 

№1632103-03-2022 15:20:54

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 258
UA: Firefox 97.0

Re: Custom Buttons

Dumby
Как бы предупреждение сделать на удаление закладки на панели закладок ? Копал в controller.js , не то. Код бы IS...
zq3wabp3.jpg
Вставил в controller.js... Не фуфло ? Хотелось бы в скрипт и желательно без закладок из popup/
if (bmGuidsToRemove.length) {
if(Services.prompt.confirm(null, null, "Удалить ?"))
      transactions.push(PlacesTransactions.Remove({ guids: bmGuidsToRemove }));
    }
    return totalItems;
  },

Отредактировано ВВП (03-03-2022 19:01:46)

Отсутствует

 

№1632204-03-2022 21:23:01

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

Re: Custom Buttons

ВВП пишет

Вставил в controller.js... Не фуфло ?

Зависит от того, что ты хочешь.
Так ведь и на папки будет confirm, и на квери,
и не только на панели закладок.

Хотелось бы в скрипт и желательно без закладок из popup/

Что значит «без закладок из popup/»?
Возможно, имеются в виду закладки, находящиеся
непосредственно на панели закладок, а не в её папках,
но это не значит, что таковые не могут появиться где-то в popup.


Плюс, через controller проходят операции множественного удаления, и чего угодно,
так что не понятно, что требуется.
Ладно, допустим так: если удаляется закладка с панели закладок (не из папок),
то выскакивает предупреждение.
Если «OK» — операция продолжается без изменений,
если «Отмена» — из операции удаления будут исключены все такие закладки.
Код для custom_script.js

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

Выделить код

Код:

(async repl => {
	var obj = `{\n  ${
		(await (await fetch("chrome://browser/content/places/controller.js")).text())
			.match(/async _removeRange\(.+?\n\ +}(?=,\n)/s)[0]
			.replace("bmGuidsToRemove.push", repl)
	}\n}`
	var ps = await ChromeUtils.compileScript("data:,(" + encodeURIComponent(`${obj => {
		var patch = async ctor => {
			var proto = ctor.prototype, meth = proto?._removeRange;
			meth && Object.assign(proto, obj);
		}
		var key = "PlacesController";
		var desc = Object.getOwnPropertyDescriptor(window, key);
		if (!desc) return;

		var {get} = desc;
		if (get)
			desc.get = () => {
				var val = get();
				patch(val);
				return val;
			},
			Object.defineProperty(window, key, desc);
		else
			patch(desc.value);
	}})(${obj});`));

	var obs = doc => "PlacesController" in doc.ownerGlobal && ps.executeInGlobal(doc);
	var topic = "chrome-document-loaded";
	Services.obs.addObserver(obs, topic);
	Services.obs.addObserver(function quit(s, t) {
		Services.obs.removeObserver(quit, t);
		Services.obs.removeObserver(obs, topic);
	}, "quit-application-granted");
})(
        `else if (!removedFolders.ignore && PlacesUtils.nodeIsBookmark(node)) {
          let info = await PlacesUtils.bookmarks.fetch(
            node.bookmarkGuid, null, {includePath: true}
          );
          if (
            info?.path.length == 1 &&
            info.path[0].guid == "${PlacesUtils.bookmarks.toolbarGuid}" &&
            !(removedFolders.ignore ??= Services.prompt.confirm(
              null, null, "Удалять закладки с панели закладок?"
            ))
          ) {
            totalItems--;
            continue;
          }
        }
        $&`
);

Отсутствует

 

№1632304-03-2022 21:51:08

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 258
UA: Firefox 98.0

Re: Custom Buttons

Dumby
Скрипт не работает...

Отсутствует

 

№1632404-03-2022 22:52:02

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

Re: Custom Buttons

ВВП пишет

Скрипт не работает...

Ну не знаю, проверил на Firefox 98.0 RC build2 — у меня работает.
Может controller.js сильно изменился от предыдущих копаний?

Отсутствует

 

№1632504-03-2022 23:48:21

ВВП
Участник
 
Группа: Members
Зарегистрирован: 13-03-2021
Сообщений: 258
UA: Firefox 98.0

Re: Custom Buttons

Dumby
Да где то мой косяк. И не в controller.js... в SessionFile.jsm. Кстати , папки на панели тоже надо предупреждать. Из-за них и геммор этот замутил.

Отредактировано ВВП (05-03-2022 01:45:47)

Отсутствует

 

Board footer

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