Динамически изменять content_scripts.matches в расширении FireFox

Итак, я пытаюсь следовать инструкциям для расширения Firefox с помощью WebExtensions и хочу прикрепить сценарий содержимого к определенным страницам (как обсуждается здесь: https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Modify_a_web_page).

Проблема в том, что я не хочу указывать набор страниц, на которых я хочу, чтобы content_script запускался в manifest.json, когда я пишу расширение, но загружаю его из локального хранилища, т. Е. У меня настроена страница параметров, где пользователь может указать страницы, на которых должен выполняться контентный скрипт. Можно ли динамически изменять список изменяемых страниц, который обычно устанавливается с помощью директивы content_script в файле manifest.json?

Спасибо


person Peter Gerdes    schedule 13.12.2016    source источник
comment
Вы задаете здесь два разных вопроса: могу ли я динамически изменять URL-адреса, на которые вводится manifest.json content_script? и Как я могу внедрить сценарии содержимого в URL-адреса, которые я определяю динамически? Несмотря на то, что они связаны, было бы намного лучше, если бы это были два отдельных Вопроса, а не объединенные в один Вопрос. Измените этот вопрос на один из них и задайте другой вопрос для другого.   -  person Makyen♦    schedule 13.12.2016
comment
Я решил, что задаю только первый вопрос. Перечитав, я вижу, что это было неясно, и изменил его так, как вы предложили.   -  person Peter Gerdes    schedule 14.12.2016


Ответы (2)


Нет, невозможно изменить URL-адреса, в которые будет происходить внедрение для manifest.json content_script (либо CSS, либо JavaScript). Указанный код будет внедрен во все соответствующие URL-адреса. Это по нескольким причинам.

Одной из причин, по которой это невозможно, является безопасность/прозрачность для пользователя. В файле manifest.json явно указано, какие URL-адреса будет изменять ваш сценарий контента, указано, что он будет изменять активную вкладку или что он будет иметь доступ ко всем URL-адресам/вкладкам. Если бы вам было разрешено изменять URL-адреса, вы фактически получили бы возможность доступа ко всем URL-адресам без явного объявления того, что вы это делаете.

Да, можно было бы заявить, что вы собираетесь это сделать. В Chrome есть экспериментальный способ сделать это с помощью chrome.declarativeContent. В Chrome это считается экспериментальным, даже после того, как он был доступен в течение пары/несколько лет. Он недоступен в Firefox. Когда он будет доступен и будет ли он доступен в Firefox, пока неясно. Кроме того, даже в Chrome отсутствуют некоторые функции, доступные для других методов внедрения скриптов (например, run_at/runAt).

Чтобы иметь полный контроль над внедрением или отказом от внедрения, вам необходимо выполнить внедрение через tabs.insertCSS() и/или tabs.executeScript(). Внедрение или отказ от внедрения скриптов и CSS с помощью этих методов полностью контролируется JavaScript в вашем расширении. Используя эти методы, можно получить функциональность, аналогичную той, которую вы получаете с помощью manifest.json content_script записей, но с большим контролем. Этот больший контроль достигается за счет большей сложности.

person Makyen♦    schedule 13.12.2016

Как насчет этого? Есть куча событий для прослушивания, вы можете выбрать любое, которое удовлетворит ваши требования:

  • onBeforeNavigate
  • onCommited
  • onDOMContentLoaded
  • onCompleted.

Документация находится здесь. А это пример того, как сделать красный фон на поддоменах example.com. Конечно, вы можете создавать список фильтров URL динамически, это просто PoC:

browser.webNavigation.onCommitted.addListener(
    function(details) {
        browser.tabs.insertCSS(details.tabId, {code: 'body {background:red}'})
    },
    {url: [{hostSuffix: '.example.com'}]}
);
person Grief    schedule 04.03.2017
comment
Выбор событий действительно не поможет варианту использования, который я имею в виду. Я хотел создать функциональность (запись комментариев, размещенных в блогах), которая будет работать только с теми URL-адресами, которые соответствуют шаблонам, заданным пользователем, т. Е. Если пользователь устанавливает enable_record_comment: stackoverflow.com/*, он также будет работать на stackoverflow. Но я предполагаю, что ответ заключается в том, что если я хочу такую ​​функциональность, мне просто нужно съесть любой удар по производительности из-за работы везде. - person Peter Gerdes; 08.03.2017
comment
@PeterGerdes не уверен, в чем проблема, маршрутизация событий выполняется внутри браузера, и она должна быть довольно эффективной. Вы можете попробовать добавить прослушиватель с тысячами различных фильтров — я не заметил заметного влияния на производительность. Когда пользователь изменяет настройки, вы можете легко удалить старый слушатель и добавить новый с обновленным набором фильтров (второй параметр addListener) - person Grief; 09.03.2017