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

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

№1627614-02-2022 01:45:18

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

Re: Custom Buttons

momo2000
Куда это ? У меня кнопка. Контекст не показывает.

Отсутствует

 

№1627714-02-2022 13:45:57

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

Re: Custom Buttons

unter_officer пишет

переделайте пожалуйста под UCF кнопку Reload user{Chrome, Content}.css

JSM'ка

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

Выделить код

Код:

var name = "UCF_userContentReloader", EXPORTED_SYMBOLS = [name + "Child"];
if (typeof Services != "object")
	var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");

var find = function(sheet) {
	return sheet.href == this;
}
var getSheet = (doc, href) =>
	InspectorUtils.getAllStyleSheets(doc).find(find, href);

if (!ChromeUtils.domProcessChild.childID) {
	var noop = () => {};
	ChromeUtils.import("resource:///modules/CustomizableUI.jsm").CustomizableUI.createWidget({
		label: "Reload user{Chrome, Content}.css",
		tooltiptext: "L: Reload userChrome.css\nR: Reload userContent.css",

		id: "798278",
		localized: false,
		onCreated(btn) {
			btn._handleClick = this.click;
			btn.oncontextmenu = oncontextmenu;
			btn.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAIpwAACKcBMsYCAwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMwSURBVEiJ5dbNb5RVFMfxz3mmrYgYE0IN4IaKb4n4UqOwMCYu2JCoQVDiwoUrQ4j0xao7ExITQxRoodEFK1cmRkSE8AeYYKpEFF0YY4SiUSMRQW0sLe0818U8nekwHe3U7vhtnnNOzj3f89znPvderjVFK8npaSWrPSjpElahQzhvyrF4y++t1GqbF7DHOvQLj6Ozrt2EDutYRHAasMK0vXgWWZO0SX/7DlJf6Skp3UWcFeVRV4zG235tCZx6rDPtKLqqAN4XPhROm3DJEiG3LA6aKkZ14jUSKaOd1Gsco6Qz8vRiDDvTFJz63S13AjdVAg7JvBxDzs2RfrE2MP9ijolZijvJXo/h8pmmb5z6LZf7qICWJQNxwP5mM1OnzNdy03V1U0oi2x77y+/Wp16t3CDWgvDKvKGIQZepfO+iWBIpKG9s7HGW0k7dKgsJjsSQffOF1or4srAuS04U9jOp14amYGGgiF2Re6llaEWnMSbPNyl5DtNFQzvnBKdd2oRNhXt4ZvW1rCwfkbInY9jHMeiscBiEJ9Lz2mfSaovgovXC8sI7siAoYsgnMy8JkmPYhhtdbwOV6a9NdVhT69qphYIblPl0FuO2WrimVVVrcu7dZkFqd75q525uBCelqj0tXzRwvSYbwWZ1doOVi4Yad0vVDj81gjPfV+2y9YsGLnlgFrj6p9TA405irPAemwmn/raNqc/D/wO9uXj+bMhXDeDihDledLYt9VmTektb5flxebYgcOpx+yzw0aic3vXgSqY9hdUuOUx6T+WWcX/LUELYh3ZMyqq1G8FxwCl8ULjdVFd6d6tgPQbMfLIwHIPONgVXWs1OFm3Mjt6Rdlg2X2bq0yfsLtzP/OHVq3PqzuPUm/Vj9xz9ZDrcg5F/Bb6gS8mbkq1F6EdlW+IdE03Baae1pEeJb1SuO0vrMvPsPvKRArDaChf8qWRal/BQccBsxnXFiBFTtjS7czW93qYdVurQJZW6SLeK+DaGyofSLh0uGUNHk6F/SfZI3ojh2k41b3DThnrdS+1/nAnjcxzR5mDsdeG/6szrXl2nJX4w4RFJJ3LhF7lzMey3lmtdU/oHaoj4Y/PDRWgAAAAASUVORK5CYII=");
		},
		get click() {
			var {file, spec} = getURI("hrome");
			var chromeSheet = getSheet(Services.wm.getMostRecentWindow(null).document, spec);
			delete this.click;
			return this.click = !chromeSheet ? noop : function() {
				var win = this.ownerGlobal;
				if (win.event?.detail < 2 && file.exists())
					reload(chromeSheet),
					win.setTimeout(restyle, 50);
			}
		}
	});
	var getURI = sub => {
		var file = Services.dirsvc.get("UChrm", Ci.nsIFile);
		file.append(`userC${sub}.css`);
		return Services.io.newFileURI(file).QueryInterface(Ci.nsIFileURL);
	}
	var oncontextmenu = e => e.ctrlKey || e.shiftKey || e.detail != 1 || contextmenu(e);

	var contextmenu = e => {
		var {file, spec} = getURI("ontent");
		var wb = Services.appShell.createWindowlessBrowser();
		var contentSheet = getSheet(wb.document, spec);
		wb.close();

		if (!contentSheet) return oncontextmenu = contextmenu = noop;

		ChromeUtils.registerProcessActor(name, {child: {moduleURI: __URI__}});
		(contextmenu = async e => {
			if (!file.exists()) return;
			e.preventDefault();
			var data = await reload(contentSheet, Object.create(null));
			if (data) for(var p in data) {
				for(var dp of ChromeUtils.getAllDOMProcesses())
					dp.remoteType && await dp.getActor(name).sendQuery(spec, data);
				restyle();
				return;
			}
		})(e);
	}

	var restyle = () => {
		var subst = "u_css_reloader_restyle_substitution";
		var rph = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
		rph.setSubstitution(subst, Services.io.newURI("data:text/css,:root{}"));

		var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
		var args = [Services.io.newURI(`resource://${subst}/`), sss.USER_SHEET];
		(restyle = () => {
			sss.loadAndRegisterSheet(...args);
			sss.unregisterSheet(...args);
		})();
	}
	var reload = async (sheet, obj) => {
		try {var style = await (await fetch(sheet.href)).text();}
		catch {return obj;}

		InspectorUtils.parseStyleSheet(sheet, style);
		if (obj) obj[sheet.href] = style;
		for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) {
			var rule = sheet.cssRules.item(ind);

			rule.type == rule.IMPORT_RULE
			&& rule.styleSheet.href.startsWith("file:///")
			&& await reload(rule.styleSheet, obj);
		}
		return obj;
	}
}
else var UCF_userContentReloaderChild = class extends JSProcessActorChild {
	receiveMessage(msg) {
		var {sheet} = this;
		if (!sheet) {
			var en = Services.ww.getWindowEnumerator(null);
			if (en.hasMoreElements()) sheet =
				this.sheet = getSheet(en.getNext().document, msg.name);
		}
		sheet && this.parse(sheet, msg.data);
	}
	parse(sheet, data) {
		var style = data[sheet.href];
		if (!style) return;

		InspectorUtils.parseStyleSheet(sheet, style);
		for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) {
			var rule = sheet.cssRules.item(ind);

			rule.type == rule.IMPORT_RULE
			&& rule.styleSheet.href.startsWith("file:///")
			&& this.parse(rule.styleSheet, data);
		}
	}
}

Dobrov пишет

1) Для ссылок это не работает, поэтому не понятно, что будет делать данный жест для ссылки.
2) я дополнил код, но при показе текст в строке статуса быстро исчезает - пример в строке 6 скрипта.

2) showInStatus() не для того, чтобы им что-то дополнять,
это, скорее, для показа самих жестов.
1) У меня не воспроизводится, ну, если страница загружена,
то есть, если ничего от загрузки не вмешается.
Но, затем вспомнил, что у лисы для Linux что-то странное творится
вокруг драга ссылок, проверил, и да, там вижу.


Вот, ничего лучше не придумал, как на старте отключить StatusPanel.update(),
а на финише вернуть, и mouseup послать в окно, чтобы не залипало обновлять.
Может сам что-нибудь разумнее подкумекаешь. А это в конце метода drag()

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

Выделить код

Код:

…
		//init || win.StatusPanel.panel.setAttribute("inactive", true);

		var sp = win.StatusPanel;
		if (init) {
			var upd = sp.update;
			(sp.update = () => {}).upd = upd;
		} else {
			win.windowUtils.sendMouseEventToWindow("mouseup", -1, -1, 0, 1, 0);
			win.setTimeout(() => sp.update = sp.update.upd, 350);
			sp.panel.setAttribute("inactive", true);
		}

ВВП пишет

Не проверите?
ссылка то появляется, кнопка не реагирует...Уточняю, если перед вкладкой пустая,тогда и не реагирует на закрытие нормальной...

Проверил. Не получилось воспроизвести.
Под «реагирует», надо полагать, подразумевается переход
кнопки из статуса "disabled" в обычный, то есть видимая реакция иконки.
Ставил перед «нормальной» и вкладку "about:blank",
и лисью дефолтную новую, и даже новую, заказанную WebExtensions.

Ну,пипец, fission.autostart.session = false //Заблокировали...

А почему ппц, и почему false?
Это чисто служебная настройка, предназначенная только
для чтения дочерними процессами. А само значение вычисляется
(и затем блокируется) в родительском процессе.
Вычисляется по многим факторам, но, скажем так: если ничего не помешает,
и переключить fission.autostart в true, то при следующем старте заблокируется уже в true.

Куда это ?

«Это» здесь ничем не поможет, там вообще нет статуса "disabled".
А ещё, «это», при каждом запуске, создаёт виджет с новым id, что приводит
не только к тому, что кнопку нельзя расположить в нужном месте,
но и к добавлению очередных новых записей в browser.uiCustomization.state,
и, через какое-то время, там порядочно этого мусора накопиться.

Отсутствует

 

№1627814-02-2022 13:53:01

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

Re: Custom Buttons

Dumby
Там пропал контекст . В Undo close. Остальное не важно .

Отсутствует

 

№1627914-02-2022 16:03:15

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

Re: Custom Buttons

Dumby пишет

JSM'ка

Большое спасибо!


Dumby, просветите пожалуйста ещё по такому вопросу.
У меня в СВ есть вот такие простенькие коды:

1

Выделить код

Код:

gBrowser.tabContainer.addEventListener("wheel", e => {
	if (e.shiftKey || e.ctrlKey || e.altKey || e.metaKey) {
		return;
	}
	e.stopPropagation();
	e.preventDefault();
	setTimeout(function() {
		gBrowser.tabContainer.advanceSelectedTab(e.deltaY > 0 ? 1 : -1, true);
	}, 25);
}, true);

2

Выделить код

Код:

function closeTabEsc(e) {
	if (e.keyCode === 27 && window.fullScreen) {
		window.fullScreen = !window.fullScreen;
	}
	else if (e.keyCode === 27 && !window.fullScreen) {
		e.stopPropagation();
		e.preventDefault();
		setTimeout(function() { gBrowser.removeTab(gBrowser.selectedTab); }, 100);
	}
}
document.addEventListener("keydown", closeTabEsc, false);
addDestructor(()=> document.removeEventListener("keydown", closeTabEsc, false));

3

Выделить код

Код:

addEventListener("dblclick", function(e) {
  if ( e.button == 0 && e.target.matches("tab :scope:not(.tab-close-button):not(.tab-icon-sound), tab") ) {
    e.preventDefault();
    e.stopPropagation();
      var vert = `javascript:(function(d,scrT){scrT=d.documentElement.scrollTop||d.body.scrollTop;if(scrT>window.innerHeight){localStorage['bmk_'+d.location.href]=scrT;scrollTo(0,0)}else{scrollTo(0,localStorage['bmk_'+d.location.href]||0)}})(document)`;
      gBrowser.loadURI(vert, { triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal() });
  };
}, true, gBrowser.tabContainer);

4

Выделить код

Код:

if (WindowIsClosing()) {
	CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").closed);
}

5

Выделить код

Код:

addEventListener('keydown', e => {
	if (e.shiftKey && e.code=="KeyZ") {
		e.preventDefault();
		try { CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").collapsed) = !CustomizableUI.setToolbarVisibility("PersonalToolbar", document.querySelector("#PersonalToolbar").collapsed) } catch(e) { }
	}
});

Если эти коды подключить к UCF в:

Выделить код

Код:

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

то они в принципе работают. Но я не уверен, что это правильное решение.


Можно ли подключать эти коды таким способом или их надо как-то переделать под UCF?
И, если надо переделать под UCF, то как?


«The Truth Is Out There»

Отсутствует

 

№1628014-02-2022 18:20:27

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

Re: Custom Buttons

del

Отредактировано ВВП (15-02-2022 11:40:17)

Отсутствует

 

№1628114-02-2022 18:41:16

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

Re: Custom Buttons

Dumby - спасибо, теперь скрипт жестов мыши заработал отлично!


ещё может влиять расширение Link Status Redux, вывод в консоли: StatusPanel.update is not a function. В настройках этого расширения убрал отключение индикатора браузера.

Отредактировано Dobrov (14-02-2022 19:12:07)

Отсутствует

 

№1628215-02-2022 09:59:40

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

Re: Custom Buttons

unter_officer пишет

Можно ли подключать эти коды таким способом или их надо как-то переделать под UCF?
И, если надо переделать под UCF, то как?

Что-то слегка не связанные вещи.
Подключение — да, код кнопок исполняется в окне браузера,
так что — верно, «Для докум. окна браузера»,
и «По событию "load"» — ближе всего по моменту времени исполнения.
А вот что и как переделывать в самих кодах ...

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

1. Тут, и в других местах, где используется addEventListener(),
зависит от отношения к необходимости удалять добавленный листенер по выгрузке окна.


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


Если удаление тяжело дописывать, то, наверно, можно оставить как есть,
ну не съест же это всю память, в конце концов.


2. Вот здесь идёт вызов addDestructor(), которого нет (это от CB).
Должна образоваться ошибка, но поскольку это последняя строка, то всё работает.
Лучше убрать. Или заменить, если возвращаться к вышесказанному.


И, отвлекаясь на код, странная там какая-то конструкция проверки, избыточная,
и window.fullScreen = !window.fullScreen; выглядит как переключатель,
но таковым не является. Может лучше так, если без return (не проверял)

Выделить код

Код:

/*
	if (e.keyCode === 27 && window.fullScreen) {
		window.fullScreen = !window.fullScreen;
	}
	else if (e.keyCode === 27 && !window.fullScreen) {
		// .......
	}
*/
	if (e.keyCode == 27) {
		if (window.fullScreen)
			window.fullScreen = false;
		else {
			// .......
		}
	}

3. А вот здесь ещё один кусок CB-специфики, посерьёзнее.
В кнопках addEventListener определен как функция, и используется так:
addEventListener("eventType", listener, captureFlag, eventTarget);


А вне CB, это будет интерпретировано как вызов метода window.addEventListener(),
то есть, листенер уйдёт в окно, и событие "dblclick" будет отслеживаться,
(и, соответственно, обрабатываться) по всему окну, а не только там, где вкладки,
а это нехорошо и не нужно.


Следует использовать addEventListener() как метод eventTarget,
то есть, такую конструкцию:
eventTarget.addEventListener("eventType", listener, captureFlag);
В данном случае, eventTarget — это gBrowser.tabContainer


4. и 5. Это нечто совсем уже кривое.
Ошибку «cannot assign to function call» я, пожалуй, вообще впервые увидел.
Может как-то так, если я правильно понял. Оба два

Выделить код

Код:

(async bar => {
	var stv = CustomizableUI.setToolbarVisibility.bind(null, bar.id);
	bar.collapsed || stv();
	addEventListener("keydown", e =>
		e.shiftKey && !e.repeat && e.code == "KeyZ" &&
		!docShell.isCommandEnabled("cmd_insertText") &&
		(e.preventDefault(), stv(bar.collapsed))
	);
})(document.getElementById("PersonalToolbar"));

Отредактировано Dumby (15-02-2022 10:01:11)

Отсутствует

 

№1628315-02-2022 10:49:05

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

Re: Custom Buttons

Dumby пишет

Что-то слегка не связанные вещи.
Подключение — да, код кнопок исполняется в окне браузера,
так что — верно, «Для докум. окна браузера»,
и «По событию "load"» — ближе всего по моменту времени исполнения.
А вот что и как переделывать в самих кодах ...

Dumby, огромное спасибо за развёрнутый ответ.


«The Truth Is Out There»

Отсутствует

 

№1628417-02-2022 03:50:12

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

Re: Custom Buttons

Подскажите, как получить реальный ЮзерАгент, а не тот, что прописан в "general.useragent.override" ?
Иначе говоря, как получить значение опции по-умолчанию, то есть то значение, когда опция, например "general.useragent.override" сброшена?


Проблема в том, что если в "general.useragent.override" уже что-то прописано, то данный код вернёт пользовательское значение, а нужен ЮзерАгент по-умолчанию, который вшит в Firefox:

Выделить код

Код:

// вернёт строку из "general.useragent.override", а нужен реальный ЮзерАгент браузера:
Cc["@mozilla.org/network/protocol;1?name=http"].getService(Ci.nsIHttpProtocolHandler).userAgent

Отсутствует

 

№1628517-02-2022 19:32:12

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

Re: Custom Buttons

Dumby пишет

Допустим, под «предыдущей посещенной вкладкой»,
подразумевается предыдущая (по времени)
активировавшаяся вкладка, не скрытая и не закрытая.
Следует понимать, что такой может не быть,
тогда переход пойдёт туда, куда перейдёт сам браузер.

Добавьте пожалуйста в этот скрипт (p798193) такое же поведение при ЛКМ по активной вкладке, если возможно. [firefox] 78.
Спасибо.

Отредактировано Krtec (17-02-2022 21:22:48)

Отсутствует

 

№1628617-02-2022 20:40:54

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

Re: Custom Buttons

ВВП
Через скрипты, контекст показывает, только я сменил

Выделить код

Код:

CLIKS = {
			left:2,
			middle:0,
			right:1
		},

ивосстанавливает левой, меню средней, но иногда что то глючит, и если уже вкладку восстановил левой, то контекст не показывает по СКМ, тогда надо правой, а потом уже СКМ.

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

2022-02-17_223741.jpg

Отсутствует

 

№1628718-02-2022 17:04:53

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

Re: Custom Buttons

Dumby
Хочу чтобы чекер был снят всегда (с кэша)....Как ?
lo9yhfay.jpg

Отсутствует

 

№1628818-02-2022 21:00:52

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

Re: Custom Buttons

Пользуюсь такой кнопкой для перевода:

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

Выделить код

Код:

/*Initialization Code*/

var lc = navigator.lastClick = {};
addEventListener("mouseup", e => {
    if (e.button) return;
    lc.X = e.screenX - mozInnerScreenX;
    lc.Y = e.screenY - mozInnerScreenY;
}, false, gBrowser.tabpanels || 1);

var createWindow = function(text, status, title, id, pos, size){
var win = window, doc = win.document, wId = 'ujs_window'+(id || ''), w = doc.getElementById(wId);
    var keyDown = function(e){if(!e.shiftKey && !e.ctrlKey && !e.altKey && e.keyCode == 27)doc.getElementById(wId).closeWin()};

   // закрыть окно переводчика кликом мимо окна
   gBrowser.addEventListener("click", function c() {
      this.removeEventListener("click", c );
      try { doc.getElementById(wId).closeWin() } catch(e) {};
   }, true );
    
    if(w)w.closeWin();
    w = doc.createElementNS(xhtmlns, 'div');
     w.setAttribute('style', 'position:fixed;display:block;visibility:hidden;left:0;top:0;width:auto;height:auto;border:1px solid gray;padding:2px;margin:0;z-index:99999;overflow:hidden;cursor:move;'+(typeof w.style.borderRadius === 'string' ? 'background-color:#eaeaea;padding-top:0px;border-radius:4px;box-shadow:0 0 15px rgba(0,0,0,.4);' : 'background:-o-skin("Window Skin");'));
    w.id = wId;
    w.closeWin = function(){
        doc.removeEventListener('keydown', keyDown, false);
        this.parentNode.removeChild(this);
    };
    w.addEle = function(str, style){
        var ele = doc.createElementNS(xhtmlns, 'div');
        ele.setAttribute('style', style);
        if(str){
            ele.innerHTML = str;
            for(var el, all = ele.getElementsByTagName('*'), i = all.length; i--;){
                el = all[i];
                if(/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)){
                    el.parentNode.removeChild(el);
                }
                else{
                    for(var att = el.attributes, j = att.length; j--;){
                        if(/^on[a-z]+$/i.test(att[j].name))att[j].value = '';
                    }
                }
            }
        };
        return this.appendChild(ele);
    };
     w.addEle1 = function(str, style){
        var ele = doc.createElementNS(xhtmlns, 'textarea');
        ele.setAttribute('style', style);
        if(str){
            ele.innerHTML = str;
            for(var el, all = ele.getElementsByTagName('*'), i = all.length; i--;){
                el = all[i];
                if(/^(script|frame|iframe|applet|embed|object)$/i.test(el.nodeName)){
                    el.parentNode.removeChild(el);
                }else{
                    for(var att = el.attributes, j = att.length; j--;){
                        if(/^on[a-z]+$/i.test(att[j].name))att[j].value = '';
                    }
                }
            }
        };
        return this.appendChild(ele);
    };
    var img = doc.createElementNS(xhtmlns, 'div');
    img.setAttribute('style', 'display:block;float:right;width:20px;height:20px;padding:0;margin-top:1px;margin-right:0px;border:none;cursor:pointer;background-image:url("data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAAH6ji2bAAAACXBIWXMAAAAAAAAAAAHqZRakAAAEMklEQVQ4y6WUW2xUVRSG/305M51ppy0XgV60pUGgWkyggBIvITEpCYaIodGopSbElDRBQUPwyfiAJkQBTUFBohgUSUnEB1B8aCChCQQRgZpWiuXSDLRD6ZmWOXPO2Z1z2cuHQqnSGBLX49or317r3//aEuNCAgARUX/DurQEgBu1FZmE4EKOlfS+2mxWHPhiiiy6/Iu4UVuRkQBwbXOLDrUGAAjOR0nGj4evVJ5rmwUAZm1dj8QEIU8tr6fpTz1LdxOdu7edlK55S0VnlqKsoT7268rG4VToSWndMlVZQ/3ks9t2WPkF8ZF+PyR5Xg3EliyszMwggmAsngxyZyQAHCuptKavWJEAY/ddand1edmrFx+VACDnVuflR4vd+NIlhhYcqZ/bgvl7tsY6m99TpQuepvbLlw5KALBvmYp3d2d7L1zgi9sPl8x4cZnR8eU3braz05qaXxjcDAOSAGANDqqIFQzlky9OlFZnfSJMXlybV3A16USNiN8XeKMKtQYDi4546f0MTIw11/4TAGBE698PWfb6CVWbUMljJSUV8VnVPYnHaoz7TokwcORI9vlUb6G0mbG/qm6lJCKif9QQBOeIzV+YQKoXMqu15IOm8sIAs3Z+FD/ftFFNq1sqpWHAO37K95VjAIC0KQA3TRX4HgMQn79nawwAruxrVbF0WvmOw0YLNUikhxT8HP9r197s7OY1CQD4c9fX2UXFU72co0aJVhhCDqZVwby5sfLmNYlz23daC95dV7jidNs0s7auJ+c4cQCQWQoh0mnlHW/3Lr7UGAyf/s079snnN2OMUXUklssp1wcAmSF9VkwbWl1EBJU8weaU3ptcCEVdyWwUAOTe27ffzlwKKI/z2vtkBIUODxrG1gUATpbMrCCmNzIZeYIJEg/yWhSykIJcBxBsfaa/PzkGPDq9dEfwSPnaORs2GRN597+p9NylT7esPRqyXcsH+jaM2laIhYniKUJ1dPmaCEQETYRo+QzmXu8fbwDEHi5h6nqKOGOI3Nl6Pukhad9IPjnWoR1q+Lbj87SZo1BDVJbLivffid+FXDtwKEcAql5bFb2b6/7gY1ekBgMA8G0naof63pdj65A8x/ENc8ilUDN1c4CdWfaKU7zqhfjspsb8meNAnV99p65//4NbZER0cUFhCACe43BbhzQOqOE5TiBMU0kdMq41K3vj5aKypsb8f0tW8+bqmDGi/PS+VkuMeP4dYJ6tx3VoUYiccn1uDimuNRMUcua6cQDoadk9/Me2nZlAE3v8raZEzab1kyPEAjlsKeH4PgDklFtgUThuZNKBct1AjpgKIJZHxEY+/Ex1bd6e0gCqQAwA/C0tVseWlj4BRpMYJ8GdAACUdgObdHCvQ6ChTdud3TF3Xk2RETH4gznG10BXxveSTpjzuXx9DPjt8HASQCFuA+jD/4q/AYOlLA+pNh89AAAAAElFTkSuQmCC");background:-o-skin("Caption Close Button Skin");');
    img.title = (win.navigator.language.indexOf('ru') == 0) ? '\u0417\u0430\u043A\u0440\u044B\u0442\u044C' : 'Close';
    img.addEventListener('click', function(){this.parentNode.closeWin()}, false);
    w.appendChild(img);
    var title = w.addEle(title, 'display:table;color:#000;font:17px Times New Roman;width:auto;height:auto;padding:0;margin:0 2px;cursor:text;');
        title.onclick = e => {
        e.preventDefault();
        var url = e.target.href;
        // Здесь открываем url как хотим.
        var ctabpos = gBrowser.selectedTab._tPos +1;
        gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos);
        doc.getElementById(wId).closeWin();    
    }
    var cnt = w.addEle1(text, 'display:block;border:1px solid #aaa;padding-bottom:3px;padding-left:3px;background-color:#fafcfe;color:#000;font:17px Times New Roman;width:260px;height:100px;overflow:auto;cursor:text;-moz-user-focus:normal;');
    cnt.contentEditable="true";
    cnt.context="contentAreaContextMenu";
    w.addEle(status, 'display:table;font:12px Times New Roman;font-weight:bold;color:blue;width:auto;height:auto;padding-top:2px;margin:0 3px;cursor:pointer;');
    w.addEventListener('mousedown', function(e){
        if(e.target == w){
            e.preventDefault();
            var grabX = e.clientX, grabY = e.clientY, origX = parseInt(w.style.left), origY = parseInt(w.style.top);
            var mouseMove = function(ev){
                w.style.left = origX+ev.clientX-grabX+'px';
                w.style.top = origY+ev.clientY-grabY+'px';
            };
            doc.addEventListener('mousemove', mouseMove, false);
            doc.addEventListener('mouseup', function(){doc.removeEventListener('mousemove', mouseMove, false)}, false);
        }
    }, false);
    doc.documentElement.appendChild(w);
  
    if(size){
        cnt.style.height = 40*i+'px';
        cnt.style.width = 130*i+'px';
    }
    else{
        for(var i = 3; i < 10; i++){
            if(cnt.scrollHeight > cnt.offsetHeight || cnt.scrollWidth > cnt.offsetWidth){
                cnt.style.height = 40*i+'px';
                cnt.style.width = 130*i+'px';
            }
            else break;
        }
    };

    var docEle = (doc.compatMode == 'CSS1Compat' && win.postMessage) ? doc.documentElement : doc.body;
    var mX = docEle.clientWidth-w.offsetWidth, mY = docEle.clientHeight-w.offsetHeight;
    if(mX < 0){cnt.style.width = parseInt(cnt.style.width)+mX+'px'; mX = 0};
    if(mY < 0){cnt.style.height = parseInt(cnt.style.height)+mY+'px'; mY =0};
    var hW = parseInt(w.offsetWidth/2);
    w.style.left = (pos && pos.X < mX+hW ? (pos.X > hW ? pos.X-hW : 0) : mX)+'px';
    w.style.top = (pos && pos.Y+10 < mY ? pos.Y+10 : mY)+'px';
    w.style.visibility = 'visible';
    doc.addEventListener('keydown', keyDown, false);
    return w;
};

var getHash = function (txt) {
    TKK=eval('((function(){var a\x3d817046147;var b\x3d-335196159;return 410049+\x27.\x27+(a+b)})())');
    function sM(a) {
        var b;
        if (null !== yr)
            b = yr;
        else {
            b = wr(String.fromCharCode(84));
            var c = wr(String.fromCharCode(75));
            b = [b(), b()];
            b[1] = c();
            b = (yr = window[b.join(c())] || "") || ""
        }
        var d = wr(String.fromCharCode(116))
            , c = wr(String.fromCharCode(107))
            , d = [d(), d()];
        d[1] = c();
        c = "&" + d.join("") + "=";
        d = b.split(".");
        b = Number(d[0]) || 0;
        for (var e = [], f = 0, g = 0; g < a.length; g++) {
            var l = a.charCodeAt(g);
            128 > l ? e[f++] = l : (2048 > l ? e[f++] = l >> 6 | 192 : (55296 == (l & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (l = 65536 + ((l & 1023) << 10) + (a.charCodeAt(++g) & 1023),
                e[f++] = l >> 18 | 240,
                e[f++] = l >> 12 & 63 | 128) : e[f++] = l >> 12 | 224,
                e[f++] = l >> 6 & 63 | 128),
                e[f++] = l & 63 | 128)
        }
        a = b;
        for (f = 0; f < e.length; f++)
            a += e[f],
                a = xr(a, "+-a^+6");
        a = xr(a, "+-3^+b+-f");
        a ^= Number(d[1]) || 0;
        0 > a && (a = (a & 2147483647) + 2147483648);
        a %= 1E6;
        return c + (a.toString() + "." + (a ^ b))
    }

    var yr = null;
    var wr = function(a) {
        return function() {
            return a
        }
    }
        , xr = function(a, b) {
        for (var c = 0; c < b.length - 2; c += 3) {
            var d = b.charAt(c + 2)
                , d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d)
                , d = "+" == b.charAt(c + 1) ? a >>> d : a << d;
            a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d
        }
        return a
    }; 

    return sM(txt);
}; 
 
  
 
var ujs_google_translate = function (dir){
    var lng = window.navigator.language.slice(0, 2), txt = gContextMenu.selectionInfo.fullText, l = dir.split('|');
    var encTxt = encodeURIComponent(txt);
    var winWait = function(lng){createWindow('', (lng == 'ru' ? 'Подождите идет перевод' : 'Wait, is going Translating')+'\u2026', 'Google Translate', '_gt', window.navigator.lastClick)};
    if (txt) {
    winWait(lng);
        var xhr = new XMLHttpRequest();
         var url = 'https://translate.google.com/translate_a/single?client=gtx&sl=' + l[0] + '&tl=' + l[1] + '&hl=' + lng + '&eotf=0&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t' + getHash(txt);
        var urlt = "http://translate.google.com/translate_t?text="+encTxt+"&sl='  + langFrom_google_text + '&tl=' + langTo_google_text +'&hl=' + lng + '&eotf=0&ujs=gtt";
      
        xhr.open('POST', url, true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
        xhr.onreadystatechange = function() {
            try{
                if (xhr.readyState == 4 && xhr.status == 200) {
                    var result = '', status = '', tmp = JSON.parse(xhr.responseText.replace(/\[(?=,)/g, '[0').replace(/,(?=,|\])/g, ',0').replace(/\\n/g, "<br />"));
                    for(var i = 0, n; n = tmp[0][i]; i++){
                        if(n[0])result += n[0].toString();
                    };
                    status = tmp[8][0][0].toUpperCase() + ' -\u203A ' + l[1].toUpperCase();
                     createWindow(result, status, '<a href="'+urlt.replace(/&/g,'&amp;')+'" target="_blank" style="display:inline;padding:0;margin:0;text-decoration:none;border:none;color:blue;font:17px Arian;">Google Translate</a>', '_gt', window.navigator.lastClick);
                }
            } catch (x){LOG(x)};
        };
        xhr.send('q=' + encodeURIComponent(txt));
    } else {
        var urlt = gBrowser.currentURI.spec;  
        var url = "http://translate.google.com/translate?u="+encodeURIComponent(urlt)+"&hl="+lng+"&langpair="+dir+"&tbb=1";
        var ctabpos = gBrowser.selectedTab._tPos +1;
        gBrowser.moveTabTo(gBrowser.selectedTab = gBrowser.addWebTab(url), ctabpos);
    };
};

var contextMenu = document.getElementById("contentAreaContextMenu");
var nextEleMenu = document.getElementById("context-inspect");

var menuId = "context-ext-google-translate";
var menuItem = document.getElementById(menuId);
if (menuItem) {
    contextMenu.removeChild(menuItem.nextElementSibling);
    contextMenu.removeChild(menuItem.nextElementSibling);
    contextMenu.removeChild(menuItem);
};

menuItem = document.createXULElement("menuitem");
menuItem.setAttribute("id", menuId);
menuItem.setAttribute("label", "Перевести на русский");
menuItem.setAttribute("class", "menuitem-iconic");
menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAABBUlEQVR4Ac2RMU4DMRREB2MqihQpAkUaqnAduuQw4Sx03CGcJYIiDYqQ0lCsZ77535ZFcgAkRuPvV7zd/dLiz3N1PFb8hmRckrfELZrF9ONQ1B6Yz0MyM7S0O6zGkVprh/3+Kw/JzkHSpRpJKZkpr9fYbOx0cjVsCbWG31oHBM9mtt0q73ZcrdLhAMlYQKkUI22aqsNo8HKZAMQhvVaKSHWj2Q2aPU3mJQFY7nuHyvYFduP83WF3AJRfcPNYnr/Lp1G1uK4m9sno1LaUbnX/htf8BNzoneUD5NhjvLCMhURQSQ93QCZwXYjFwg3I0NZKrvoknQPMIHkt/jRAQKMeG2yX89/mB4EJbKbZxIhFAAAAAElFTkSuQmCC");
menuItem.addEventListener("command", function(){ujs_google_translate('auto|ru')}, false);
contextMenu.insertBefore(menuItem, nextEleMenu);

menuItem = document.createXULElement("menuitem");
menuItem.setAttribute("label", "Перевести на английский");
menuItem.setAttribute("class", "menuitem-iconic");
menuItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMAAAAAAABupgeRAAAB5UlEQVR4AWOgPZg0c9+Oq2+qpx9LaQaiw4mNB27efbs2uXFNQh2Q4Zm9zSNth23MhqjGnXMC86vnHmUS4udxv7OvOd2yPE7PTlfCTk9GVVEoyJA7WI8dyPA0k3U1l+jJMV7CeThpTZeoKDdDUsvBPSff/V+6/P/Bvf///2+bdvU/EKRm/k9IBNIlfZe+LFrzvbsbyJ636pKkyQyQhoUb7tZNvPpw3/0/TfX/ISAm5n94BIiRm/n/xYsLd946ei4vajoiqDuRAejQf//+o4PQ0P9+fmhiQGVnrr1kXJNYG2zEzXDxDsPv3wy/fkFJoOTPn39+/fr/69e/37//AUX+/mXRkO458wWHDba2f8wswCyQ3N+/f//8/fP7z5+TV18w2Mdt6plzPiptx5Wr7/+/ffMzOR6kysjkt74hWMPfp06O+2dulZCeFZKwnkE4m8E8bN3i9aCQ+dxY96GrK6bkGJD9R1v3l6Y20NVW9kt+/v//ZdbcFwkxTVPPMQimM8XEqkb7a/zoqLxkH9v4zVyI5+///wyMmtKMmhJAnbLqQjHxaw5r2orOmZN5uj470Zahat6BKS7JzpmLBHXm8GhM5lCdcP7ai1ZpixZxk9NXXjKIFzOIFjAI54oY1vXuue5qmscw+AAAW0tKxtPoicEAAAAASUVORK5CYII=");
menuItem.addEventListener("command", function(){ujs_google_translate('auto|en')}, false);
contextMenu.insertBefore(menuItem, nextEleMenu);

contextMenu.insertBefore(document.createXULElement("menuseparator"), nextEleMenu);


Очень не хватает вызова по сочетанию клавиш. В кнопке Алексея Рузанова для этого был такой код:

Выделить код

Код:

addEventListener('keydown', function (e){
 if(e.shiftKey && !e.ctrlKey && e.altKey && e.keyCode == 84)ujs_google_translate('auto|ru');
}, false);

Вставил его в конец кода "своей" кнопки — переводчик не вызывается. Подскажите пожалуйста как таки прикрутить горячие клавиши. [firefox] 78 ESR

В процессе ковыряния оказалось что при клике по кнопке переводчик тоже не вызывается, похоже она заточена только под контекстное меню (txt = gContextMenu.selectionInfo.fullText).

___
И ещё вопрос: кнопка Go plus² focus для поздних версий [firefox] переделывалась? Не нашёл в теме. Хотелось бы иметь такую для 78 версии.

Отредактировано Krtec (19-02-2022 01:44:38)

Отсутствует

 

№1628919-02-2022 10:59:06

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

Re: Custom Buttons

Dobrov пишет

нужен ЮзерАгент по-умолчанию, который вшит в Firefox

Нет такого. Он просто вычисляется из составляющих.

значение, когда опция, например "general.useragent.override" сброшена

Ну так если настройка есть, то читаем и сбрасываем.
Теперь получаем UA.
Затем возвращаем настройку, если была.


Krtec пишет

Добавьте пожалуйста в этот скрипт (p798193) такое же поведение при ЛКМ по активной вкладке, если возможно. [firefox] 78.

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

Выделить код

Код:

(async ucf => {
	await delayedStartupPromise;
	var set = new Set([gBrowser.selectedTab]);
	var bt = gBrowser._blurTab;
	gBrowser._blurTab = tab => tab.selected && blur(tab);
	var blur = (tab, click) => {
		set.delete(tab);
		var res; for(var t of set) t.hidden || (res = t);
		click && set.add(tab);
		res ? gBrowser.selectedTab = res : bt.call(gBrowser, tab);
	}
	var skip, arr = [
		["TabClose", e => set.delete(e.target)],
		["TabSelect", e => set.add(e.target, set.delete(e.target))],
	
		["mousedown", e => skip = e.button || !e.target.matches(
			"tab[selected] :scope:not(.tab-close-button):not(.tab-icon-sound), tab[selected]"
		), true],

		["click", e => skip || e.ctrKey || e.shiftKey || e.altKey
			|| e.detail != 1 || blur(e.target.closest("tab"), true)
		]
	];
	var id, tc = gBrowser.tabContainer;
	for(var args of arr) tc.addEventListener(...args);
	ucf.unloadlisteners.push(id = Symbol());
	ucf[id] = {destructor() {
		set.clear();
		for(var args of arr) tc.removeEventListener(...args);
	}};
})(ucf_custom_script_win);

ВВП пишет

Хочу чтобы чекер был снят всегда (с кэша)....Как ?

Как-то так

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

Выделить код

Код:

addEventListener("dialogopen", e => {
	var win = e.detail.dialog.frameContentWindow;
	if (win.location == "chrome://browser/content/preferences/dialogs/clearSiteData.xhtml") {
		var checkbox = win.document.getElementById("clearCache");
		checkbox.checked = false;
		checkbox.disabled = true;
	}
}, false, gBrowser.tabpanels);


Или саму xhtml'ку править, она небольшая, чекбокс найти легко.

Отсутствует

 

№1629019-02-2022 11:17:37

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

Re: Custom Buttons

Dumby

Dumby пишет

Или саму xhtml'ку править, она небольшая, чекбокс найти легко.

Да,так и сделал. Не знаю почему, но как на кэш нажмешь так око меняется commonDialogWindow или commonDialog

Добавлено 19-02-2022 11:20:27
momo2000
tabbrowser-tab.js там контекст запилили . Можно рихтануть и кнопка заработает
aspeglny.jpg

Отредактировано ВВП (19-02-2022 11:20:27)

Отсутствует

 

№1629119-02-2022 12:15:13

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

Re: Custom Buttons

ВВП пишет

как на кэш нажмешь так око меняется commonDialogWindow или commonDialog

Попробовал. Заменил checked на xhecked
(просто потому, что в текстовом редакторе правил, в смысле сам весь app omni.ja как один файл).
И чекер, при появлении диалога, снятый.
И нажатие на него не приводит ни к чему необычному.

Отсутствует

 

№1629219-02-2022 12:51:47

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

Re: Custom Buttons

Dumby

Dumby пишет

И нажатие на него не приводит ни к чему необычному.

Куда это вставить ? Версии 96-97 необычное происходит один черт. И не только там.
26pgyl9j.jpg
n4nb6oh5.jpg
И здесь убрал , тоже если быстро окно в предупреждением , то окно дергается аналогично...
89wy8lm3.jpg

Отредактировано ВВП (19-02-2022 12:55:11)

Отсутствует

 

№1629319-02-2022 13:46:50

ALEX_45_ORP
Участник
 
Группа: Members
Зарегистрирован: 18-01-2018
Сообщений: 162
UA: Firefox 93.0

Re: Custom Buttons

ВВП пишет

aspeglny.jpg

значит зелененький 97 будет - вот только скажи сейчас, что в 7х64 работать не будет? :dumb:

Отредактировано ALEX_45_ORP (19-02-2022 14:06:58)


Win 10х64

Отсутствует

 

№1629419-02-2022 14:25:36

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

Re: Custom Buttons

ALEX_45_ORP
Семера, значит комп старый. Без SSE , будет, но не так.

Отсутствует

 

№1629519-02-2022 14:33:42

ALEX_45_ORP
Участник
 
Группа: Members
Зарегистрирован: 18-01-2018
Сообщений: 162
UA: Firefox 93.0

Re: Custom Buttons

ВВП пишет

Семера, значит комп старый. Без SSE , будет, но не так.

лэптоп НР, конечно без SSE, главное чтоб работала, хоть и помедленней, ок, спс.

Отредактировано ALEX_45_ORP (19-02-2022 18:54:19)


Win 10х64

Отсутствует

 

№1629619-02-2022 22:37:31

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

Re: Custom Buttons

Dumby
Не могу толком вставить предупреждение на СКМ ...Отражается на другие клики.(UndoClose)

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

Выделить код

Код:

this.onclick = function(e) {
    if(e.target != this)
        return;
    if(e.button == 1 || e.button == 0 && (e.ctrlKey || e.shiftKey || e.altKey || e.metaKey))
        this.undoCloseTabsList.clearAllLists();
    else if(
        e.button == 0
        || e.button == 2 && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey
            && this.undoCloseTabsList.options.rightClickToUndoCloseTab
    ) {
        if(
            e.button == 0 && !this.undoCloseTabsList.options.useMenu
            || e.button == 2 && this.undoCloseTabsList.options.rightClickToUndoCloseTab
        ) {
            if(this.undoCloseTabsList.closedTabCount)
                this.undoCloseTabsList.undoCloseTab();
            else
                this.undoCloseTabsList.drawUndoList() && this.undoCloseTabsList.showMenu(e);
        }
        // Allow use "command" section only from hotkey:
        e.preventDefault();
        e.stopPropagation();
    }
};

Отсутствует

 

№1629720-02-2022 02:02:04

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

Re: Custom Buttons

Dumby пишет
Krtec пишет

...такое же поведение при ЛКМ по активной вкладке

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

Выделить код

Код:

(async ucf => {
	await delayedStartupPromise;
	var set = new Set([gBrowser.selectedTab]);
	var bt = gBrowser._blurTab;
	gBrowser._blurTab = tab => tab.selected && blur(tab);
	var blur = (tab, click) => {
		set.delete(tab);
		var res; for(var t of set) t.hidden || (res = t);
		click && set.add(tab);
		res ? gBrowser.selectedTab = res : bt.call(gBrowser, tab);
	}
	var skip, arr = [
		["TabClose", e => set.delete(e.target)],
		["TabSelect", e => set.add(e.target, set.delete(e.target))],
	
		["mousedown", e => skip = e.button || !e.target.matches(
			"tab[selected] :scope:not(.tab-close-button):not(.tab-icon-sound), tab[selected]"
		), true],

		["click", e => skip || e.ctrKey || e.shiftKey || e.altKey
			|| e.detail != 1 || blur(e.target.closest("tab"), true)
		]
	];
	var id, tc = gBrowser.tabContainer;
	for(var args of arr) tc.addEventListener(...args);
	ucf.unloadlisteners.push(id = Symbol());
	ucf[id] = {destructor() {
		set.clear();
		for(var args of arr) tc.removeEventListener(...args);
	}};
})(ucf_custom_script_win);

Так переключение зацикливается между двумя вкладками, хотелось бы по типу перемещения по истории вкладки назад при нажимании кнопки со стрелочкой — страница с которой переключаешся не становится предыдущей, а остаётся следующей по отношению к той, на которую переключился. Очень надеюсь что сие возможно и на вашу помощь.

Отсутствует

 

№1629820-02-2022 03:01:29

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

Re: Custom Buttons

Dumby - напомню вопрос в теме UCF - просьба упростить код перехват кликов, убрать LongPress,
он даёт задержку при нажатии кнопок, т.е. убрать задержку, переделать на системные click, dblclick, wheel


Сделал отладочный скрипт, в нём только кнопка Загрузки + сообщения в консоли и строке статуса:

ucf_hookClicks.js - почему-то ошибка: this.selectors is undefined

Выделить код

Код:

(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 > 2) return;

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

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

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

			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);
				if (dbl) return;

				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;
			dbl
				? this.clickTID &&= clearTimeout(this.clickTID)
				: 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;
			}
			dbl
				? obj[num](trg)
				: this.clickTID = setTimeout(this.exec, 300, trg, obj, num);
		},
		get selectors() {
			this.exec = (trg, obj, num) => {
				this.clickTID = null;
				obj[num](trg);
			}
			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));
	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);
	}}
	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

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

	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("[HC] "+ info);
	},
	data = {
		"#downloads-button": { mousedownTarget: true, // + отправить текст в консоль

			2(trg, forward) {
				showInStatusPanel("DW Wheel " + (forward ? "forward" : "backward"));
			},
			4() {
				showInStatusPanel("DW Double Left Click");
				Downloads.getSystemDownloadsDirectory().then(path => FileUtils.File(path).launch(), Cu.reportError);
			},
			16(btn) {
				showInStatusPanel("Shift + ЛКМ");
			},
			128() {
				showInStatusPanel("СКМ Click");
			},
			256() {
				showInStatusPanel("ПКМ Click");
			},
			260(btn) {
				showInStatusPanel("Double ПКМ Click");
			},
			264(btn) {
				showInStatusPanel("Alt + ПКМ");
			},
		},
	}; // end Clicks, HotKeys ==================================================

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

Отсутствует

 

№1629921-02-2022 09:25:41

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

Re: Custom Buttons

ВВП пишет

Не могу толком вставить предупреждение на СКМ ...Отражается на другие клики.

Можно, например, так

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

Выделить код

Код:

…
		//this.undoCloseTabsList.clearAllLists();
		Services.prompt.confirm(null, null, "???") && this.undoCloseTabsList.clearAllLists();

Krtec пишет

хотелось бы по типу перемещения по истории

Как-то это поперёк концепции.
Сомневаюсь, что такое мне в голову поместится.
Ладно, если просто пощёкать подряд чтоб отмотать, то можно, но если активировать вкладку
не таким образом (кликом по активной), то сброс, возвращение к цепочке основного трекера.

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

Выделить код

Код:

(async ucf => {
	await delayedStartupPromise;
	var set = new Set([gBrowser.selectedTab]);
	var bt = gBrowser._blurTab;
	gBrowser._blurTab = tab => tab.selected && blur(tab,/* flipset ||*/ set);
	var blur = (tab, s) => {
		s.delete(tab);
		var res; for(var t of s) t.hidden || (res = t);
		res ? gBrowser.selectedTab = res : bt.call(gBrowser, tab);
	}
	var re = /\nblur@[^\n]+?\n(?:[^\n]+?\/)?arr<@/;
	var skip, flipset, arr = [
		["TabClose", e => {
			set.delete(e.target);
			flipset?.delete(e.target);
		}],
		["TabSelect", e => {
			set.delete(e.target);
			set.add(e.target);
			if (flipset && !re.test(Components.stack.formattedStack)) flipset = null;
		}],
		["mousedown", e => skip = e.button || !e.target.matches(
			"tab[selected] :scope:not(.tab-close-button):not(.tab-icon-sound), tab[selected]"
		), true],

		["click", e => skip || e.ctrKey || e.shiftKey || e.altKey || e.detail != 1
			|| blur(e.target.closest("tab"), flipset || (flipset = new Set(set)))
		]
	];
	var id, tc = gBrowser.tabContainer;
	for(var args of arr) tc.addEventListener(...args);
	ucf.unloadlisteners.push(id = Symbol());
	ucf[id] = {destructor() {
		set = flipset = null;
		for(var args of arr) tc.removeEventListener(...args);
	}};
})(ucf_custom_script_win);

Dobrov пишет

просьба упростить код перехват кликов, убрать LongPress,
он даёт задержку при нажатии кнопок, т.е. убрать задержку, переделать на системные click, dblclick, wheel…

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

Отредактировано Dumby (22-02-2022 16:59:04)

Отсутствует

 

№1630021-02-2022 12:31:18

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

Re: Custom Buttons

Dumby

Dumby пишет

Можно, например, так

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

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

Выделить код

Код:

{ Services.prompt.confirm(null, null, "Удалить список вкладок и сесий ?") && this.undoCloseTabsList.clearAllLists();  SessionStore.canRestoreLastSession = false;}

Отсутствует

 

Board footer

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