Персональный сайт Дмитрия Журавлева

Связь: dmitriyzhuravlev@yandex.ru

Расширение для Firefox для переключения вкладок клавишами 1 и 2
Написал своё первое расширение для Firefox.

Долгое время моим самым любимым браузером была старая Opera, которая на движке Presto. Её последняя версия - Opera 12.18 - вышла аж в феврале 2016 года, т.е. она уже безнадёжно устарела. В старой Опере было невероятное количество фишек, которые до сих пор не реализовали современные браузеры.

Одна из таких возможностей - это переключение вкладок влево-вправо обычными клавишами 1 и 2. Так умеет делать очень хороший хромобраузер Вивальди, но это, повторюсь, хромобразуер со всеми вытекающими недоделками. Например, любой хромобраузер не имеет переключаться на другую вкладку, если на странице появился запрос HTTP-аутентификации.

У Firefox тоже масса хороших фишек, но его надо дорабатывать расширениями, чтобы приблизить его к возможностям Opera Presto, вышедшей много лет назад.

Среди массы расширений на addons.mozilla.org я так и не нашёл рабочего расширения, которое бы могло переключать страницы одиночными кнопками 1 и 2. Так что пришлось писать самому, а это интересный опыт, надо сказать.

Написал, отправил на модерацию, одобрили, вот ссылка: https://addons.mozilla.org/ru/firefox/addon/1-2-key-for-tab-switch/.
Или можно напрямую с моего сайта скачать: https://dmitriyzhuravlev.ru/js_files/firefox_ext/{91b52371-953d-4479-86e2-028720f293c1}.xpi

У расширения есть ограничения, на которые я повлиять не могу. Оно будет работать только на нормальных протоколах, вроде https://, т.е. не будет работать на странице about:preferences и тому подобных. Также оно не работает на сайте addons.mozilla.org, т.е. это какое-то внутреннее ограничение в коде браузера. Также DOM-дерево должно полностью загрузиться, чтобы можно было переключиться одиночной клавишей на другую вкладку.

Разумеется, добавил исключения, чтобы вкладка не переключалась на соседнюю, если пользователь печатает что-то в каком-нибудь <input> или <textarea>.

Вообще, хорошо знающему Javascript написать своё расширение нетрудно. Всё наконец-то более-менее стандартизировано, документация есть, с примерами. Скрипты браузерного расширения работают на двух уровнях: на "уровне браузера целиком" и на "уровне страницы". Они могут общаться между самой, посылая друг другу сообщения.

В общем, вот исходники.

background.js
let direction, idOfNowTab, idOfLeftTab, idOfRightTab, i;

if (typeof browser === 'undefined') { var browser = chrome; } // There is no 'browser' object in Chrome, there is only a 'chrome' object

browser.runtime.onMessage.addListener(handleMessageFromContentScript);

async function handleMessageFromContentScript(messageObj, sender) {
	direction = messageObj.goTo;
	idOfNowTab = sender.tab.id;
	let tabsArr = await browser.tabs.query({});
	for (i = 0; i < tabsArr.length; i++)
	{
		if (tabsArr[i].id === idOfNowTab)
		{
			// Getting the id of the tab on the left of the active tab
			if ( i === 0 )  { idOfLeftTab = tabsArr[tabsArr.length - 1].id; }
			else { idOfLeftTab = tabsArr[i - 1].id; }
			
			// Getting the id of the tab on the right of the active tab 
			if ( i === tabsArr.length - 1 )  { idOfRightTab = tabsArr[0].id; }
			else { idOfRightTab = tabsArr[i + 1].id; }

			break;
		}
	}
	
	if (direction === 'goToLeftTab') { browser.tabs.update( idOfLeftTab, { active: true} ); }
	if (direction === 'goToRightTab') { browser.tabs.update( idOfRightTab, { active: true} ); }
}

content.js
document.addEventListener('keydown', handleKeydownForSingleKeys, true);

// Adding handlers to iframes
for (let i = 0; i < window.frames.length; i++)
{
	if (window.frames[i].document)
	{
		window.frames[i].document.addEventListener('keydown', handleKeydownForSingleKeys, true);
	}
	else
	{
		window.frames[i].addEventListener('load', setHandlerForIframe);
	}
}

function setHandlerForIframe(e) {
	e.target.addEventListener('keydown', handleKeydownForSingleKeys, true);
}

function handleKeydownForSingleKeys(e) {
	let input,
	inputTypes = [ 'date', 'datetime-local', 'email', 'month', 'number', 'password', 'search', 'tel', 'text', 'time', 'url', 'week', 'datetime' ],
	i;

	if ( !(e.key === '1' || e.key === '2') ) { return; }
	if (e.target.closest('textarea')) { return; }
	
	input = e.target.closest('input');
	
	if (input !== null)
	{
		if (input.hasAttribute('type') === false) { return; } // 'input' tag without type attribute means type="text"
		
		for (i = 0; i < inputTypes.length; i++)
		{
			if ( inputTypes[i] === input.getAttribute('type') ) { return; }
		}
	}
	
	if (e.key === '1')
	{
		e.preventDefault();
		e.stopImmediatePropagation();
		browser.runtime.sendMessage( {goTo: 'goToLeftTab'} );
	}
	
	if (e.key === '2')
	{
		e.preventDefault();
		e.stopImmediatePropagation();
		browser.runtime.sendMessage( {goTo: 'goToRightTab'} );
	}
	
}

manifest.json
{
	"developer": {
	  "name": "Dmitriy Zhuravlev",
	  "url": "https://dmitriyzhuravlev.ru/"
	},

	"manifest_version": 2,
	"name": "1 2 single key shorcut for tab switching",
	"version": "1.1",

	"description": "Now you can go to the previous or to next tab via singe keybord keys 1 and 2. Switch your Firefox tabs like in old Opera 12 Presto!",

	"icons": {
	"48": "icons/icon.png"
	},

	"permissions": [
	  "<all_urls>",
	  "tabs"
	],

	"background": {
	  "scripts": ["background.js"]
	},

  "content_scripts": [
    {
		"matches": ["<all_urls>"],
		"js": ["content.js"]
    }
  ]

}
Раздел: JavaScript

Комментарии
(из-за чертовых спамеров урлы в коментах теперь писать нельзя)

Имя:

 
Комментарий:

 

Антиспам. Сколько будет двадцатка минус один?
Напишите только число:




Комментариев нет