Учитывая URL-адрес moz-extension://, открытый закладкой, как я могу переключиться на вкладку с помощью кода расширения?

Это связано с некоторыми другими вопросами, над которыми я работаю.

Скажем, по какой-то причине пользователь добавил в закладки страницу (назовем ее pageURL шаблона moz-extensions://MY-OWN-WEBEXT-ID/*), предназначенную для открытия из контекстного меню действия браузера, и открыл ее на вкладке, а затем открыл множество других вкладок и, возможно, других окон. Пользователь знает, что вкладка расширения где-то существует, и не хочет открывать новые закладки, поэтому хочет использовать контекстное меню действий браузера надстройки, чтобы найти вкладку страницы расширения. Точно так же я не хочу, чтобы мое дополнение открывало повторяющуюся вкладку.

Проблема в том, что надстройка не создала вкладку (создала закладка), у меня нет идентификатора вкладки для перехода на browser.tabs.update( WebExtTab.id, { active: true } ) или идентификатор окна для перехода к browser.windows.update( WebExtWindow.id, { focused: true } ). (WebExtWindow ссылка на объект WebExtensions browser.windows.Window , а не объект окна браузера.

Я могу использовать browser.extension.getViews( ) для создания списка объектов окна браузера (также известных как вкладки) и проверка каждого window.location.href находит, что URL-адрес (и, следовательно, вкладка) действительно существует (где-то), но я не могу использовать этот объект окна, чтобы сосредоточиться на вкладке или получить идентификатор вкладки для browser.tabs.update().

В случае нескольких окон браузера я даже не могу заставить правильное окно браузера подняться, учитывая этот объект окна, потому что объекты window, возвращаемые getViews, не имеют свойства id, с помощью которого можно вызвать browser.windows.update(). Аналогично проблеме с вкладками.

Наконец, я не могу использовать browser.tabs.query( { 'url': pageURL } ) чтобы найти идентификатор вкладки, поскольку параметр url должен соответствовать соответствовать шаблонам, которые ЗАПРЕЩАЮТ использовать схему moz-extension://.

Что было бы исключительно полезно, так это если бы API WebExtensions позволял расширению находить вкладки и окна всех страниц, которые принадлежат ему, независимо от того, были ли эти страницы открыты надстройкой, введены вручную, закладкой или переходом по ссылке.

Например, если URL-адрес страницы соответствует moz-extension://MY-OWN-WEBEXT-ID/*, можно указать browser.tabs.query и/или browser.windows.query для URL-адреса, соответствующего приведенному выше шаблону, и вернуть объект вкладки/окна WebExt соответственно. Если такая вкладка/окно не была открыта WebExt API (т. е. закладка), то сгенерируйте новый объект (т. е. псевдо-создание), чтобы заполнить существующими данными (т. е. location.href, флаги состояния и т. д.) и сгенерировать новый данные по мере необходимости (т. е. идентификационные номера), чтобы возвращаемый объект можно было использовать в контексте API.

Это заполнило бы пробел в охвате API, когда определенные методы (например, getViews) возвращают тупиковые объекты браузера, которые не имеют перехватчиков и связи с API WebExt и поэтому в основном бесполезны.


person Community    schedule 13.01.2017    source источник


Ответы (1)


Простой ответ: ++RTFM. browser.windows.getAll() позволит вам заполнить окна объекты с информацией о вкладках. Вам нужно permissions: [ "tabs" ] в manifest.json, чтобы получить свойство tab.url. Но кроме этого, все окна и объекты вкладок будут иметь идентификатор, так что вы можете тривиально сфокусировать окно и переключить активную вкладку!

Примечание. Для использования функции async/await требуется Firefox 52.0+. В противном случае вам просто нужно использовать генераторы функций и промисы. Кроме того, я пропустил какие-либо проверки ошибок в демонстрационных целях, но может быть хорошей идеей вернуть их позже.

async function tabCreate ( opts ) {
    var pageURL = browser.runtime.getURL( opts.page + '.html' );
    var extWins = await browser.windows.getAll( { populate: true, windowTypes: [ 'normal' ] } );

    // Look for tab by comparing url, if url matches (i.e. tab exists), then focus window and make tab active.
    for ( var extWin of extWins ) {
        for ( var extTab of extWin.tabs ) {
            if ( pageURL === extTab.url ) {
                console.log( `My Extension->tabCreate(): Window ${extWin.id}, Tab ${extTab.id}:\n\t${extTab.url}` );
                browser.windows.update( extWin.id, { focused: true } );
                browser.tabs.update( extTab.id, { active: true } );
                return;
            }
        }
    }

    // Otherwise, create tab.
    browser.tabs.create( { url: pageURL } );
}

Мнение: я бы хотел, чтобы мне не приходилось отдавать доступ к вкладкам только для этой функции. Было бы неплохо, если бы у нас всегда были свои собственные URL-адреса moz-extension://MY-OWN-WEBEXT-ID/* и URL-адреса null для других вкладок, без разрешений на доступ ко всем вкладкам, но да ладно.

Пример использования:

function myWebExt_Options ( ) {
    tabCreate( {
        'page': 'options',
        'panel': 1
    } );
}

browser.contextMenus.create( {
    title: 'Options',
    contexts: [ 'browser_action' ],
    onclick: myWebExt_Options
} );

Примечание. Я реализовал это, чтобы ожидать параметры в объекте opts, который имеет свойство page, которое я использую в качестве сокращения для создания полного URL-адреса страницы. Это связано с другим вопросом, который требует передачи сообщения на страницу, которую я храню в opts.panel. Но ничего из этого не нужно. Его можно изменить на плоскую строку или использовать в качестве параметра полный 'getURL', сгенерированный в другом месте. Измените в соответствии с вашими потребностями и стилем.

person Community    schedule 13.01.2017