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

Apr 30, 2021 10:52

Написал своё первое расширение для 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-дерево должно полностью загрузиться, чтобы можно было переключиться одиночной клавишей на другую вкладку.

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

Вообще, хорошо знающему 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": [
"",
"tabs"
],

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

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

}

javascript, софт

Previous post Next post
Up