Обзор архитектуры

Расширения — это заархивированные пакеты HTML, CSS, JavaScript, изображений и других файлов, используемых на веб-платформе, которые настраивают возможности просмотра в Google Chrome. Расширения создаются с использованием веб-технологий и могут использовать те же API-интерфейсы, которые браузер предоставляет для открытой сети.

Расширения обладают широким набором функциональных возможностей. Они могут изменять веб-контент, который пользователи видят и с которым взаимодействуют, или расширять и изменять поведение самого браузера.

Рассмотрите расширения, которые помогут сделать браузер Chrome наиболее персонализированным браузером.

Файлы расширения

Расширения различаются по типам файлов и количеству каталогов, но все они должны иметь [манифест][docs-manifest]. Некоторые базовые, но полезные расширения могут состоять только из манифеста и его значка на панели инструментов.

Файл манифеста под названием manifest.json предоставляет браузеру информацию о расширении, например наиболее важные файлы и возможности, которые расширение может использовать.

{
  "name": "My Extension",
  "version": "2.1",
  "description": "Gets information from Google.",
  "icons": {
    "128": "icon_16.png",
    "128": "icon_32.png",
    "128": "icon_48.png",
    "128": "icon_128.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["background_script.js"]
  },
  "permissions": ["https://*.google.com/", "activeTab"],
  "browser_action": {
    "default_icon": "icon_16.png",
    "default_popup": "popup.html"
  }
}

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

Это расширение Google Mail Checker использует действие браузера :

Скриншот расширения Google Mail Checker

Это расширение Mappy использует скрипт действия страницы и содержимого :

Скриншот расширения Mappy

Обращение к файлам

К файлам расширения можно обращаться по относительному URL-адресу, как к файлам на обычной HTML-странице.

<img src="images/my_image.png">

Кроме того, к каждому файлу можно получить доступ по абсолютному URL-адресу.

chrome-extension://EXTENSION_ID/PATH_TO_FILE

В абсолютном URL-адресе EXTENSION_ID — это уникальный идентификатор, который система расширений генерирует для каждого расширения. Идентификаторы всех загруженных расширений можно просмотреть, перейдя по URL-адресу chrome://extensions . PATH_TO_FILE — это расположение файла в верхней папке расширения; он соответствует относительному URL-адресу.

Во время работы с распакованным расширением идентификатор расширения может меняться. В частности, идентификатор распакованного расширения изменится, если расширение загружено из другого каталога; идентификатор снова изменится, когда расширение будет упаковано. Если код расширения опирается на абсолютный URL-адрес, он может использовать метод chrome.runtime.getURL() чтобы избежать жесткого кодирования идентификатора во время разработки.

Архитектура

Архитектура расширения будет зависеть от его функциональности, но многие надежные расширения будут включать в себя несколько компонентов:

Фоновый скрипт

Фоновый скрипт — это обработчик событий расширения; он содержит прослушиватели событий браузера, которые важны для расширения. Он бездействует до тех пор, пока не будет запущено событие, а затем не выполнится заданная логика. Эффективный фоновый сценарий загружается только тогда, когда он необходим, и выгружается, когда он простаивает.

элементы пользовательского интерфейса

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

Страницы расширения пользовательского интерфейса, такие как всплывающее окно , могут содержать обычные HTML-страницы с логикой JavaScript. Расширения также могут вызывать tabs.create или window.open() для отображения дополнительных HTML-файлов, присутствующих в расширении.

Расширение, использующее действие страницы и всплывающее окно, может использовать API декларативного контента для установки правил в фоновом сценарии, когда всплывающее окно доступно пользователям. Когда условия выполняются, фоновый сценарий связывается со всплывающим окном, чтобы сделать его значок доступным для пользователей.

Окно браузера, содержащее действие страницы, отображающее всплывающее окно.

Скрипты контента

Расширения, которые читают или записывают веб-страницы, используют сценарий содержимого . Скрипт содержимого содержит код JavaScript, который выполняется в контексте страницы, загруженной в браузер. Скрипты контента считывают и изменяют DOM веб-страниц, которые посещает браузер.

Окно браузера с действием страницы и сценарием содержимого.

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

Показывает путь связи между сценарием содержимого и родительским расширением.

Страница параметров

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

Использование API Chrome

Помимо доступа к тем же API-интерфейсам, что и веб-страницы, расширения также могут использовать API-интерфейсы конкретных расширений , которые обеспечивают тесную интеграцию с браузером. Расширения и веб-страницы могут обращаться к стандартному методу window.open() для открытия URL-адреса, но расширения могут указать, в каком окне этот URL-адрес должен отображаться, используя вместо этого метод Chrome API tabs.create .

Асинхронные и синхронные методы

Большинство методов API Chrome являются асинхронными: они возвращаются немедленно, не дожидаясь завершения операции. Если расширению необходимо знать результат асинхронной операции, оно может передать в метод функцию обратного вызова. Обратный вызов выполняется позже, возможно, намного позже, после возврата метода.

Если расширению необходимо перейти с выбранной пользователем вкладки на новый URL-адрес, ему потребуется получить идентификатор текущей вкладки, а затем обновить адрес этой вкладки до нового URL-адреса.

Если бы метод tabs.query был синхронным, он мог бы выглядеть примерно так, как показано ниже.

//THIS CODE DOESN'T WORK
var tab = chrome.tabs.query({'active': true}); //WRONG!!!
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();

Этот подход потерпит неудачу, поскольку query() является асинхронным. Он возвращается, не дожидаясь завершения работы, и не возвращает значения. Метод является асинхронным, если в его сигнатуре доступен параметр обратного вызова.

// Signature for an asynchronous method
chrome.tabs.query(object queryInfo, function callback)

Чтобы правильно запросить вкладку и обновить ее URL-адрес, расширение должно использовать параметр обратного вызова.

//THIS CODE WORKS
chrome.tabs.query({'active': true}, function(tabs) {
  chrome.tabs.update(tabs[0].id, {url: newUrl});
});
someOtherFunction();

В приведенном выше коде строки выполняются в следующем порядке: 1, 4, 2. Функция обратного вызова, указанная в query() вызывается, а затем выполняет строку 2, но только после того, как станет доступна информация о выбранной в данный момент вкладке. Это происходит через некоторое время после возврата query() . Хотя update() является асинхронным, код не использует параметр обратного вызова, поскольку расширение ничего не делает с результатами обновления.

// Synchronous methods have no callback option and returns a type of string
string chrome.runtime.getURL()

Этот метод синхронно возвращает URL-адрес в виде string и не выполняет никакой другой асинхронной работы.

Подробнее

Для получения дополнительной информации изучите справочную документацию по API Chrome и посмотрите следующее видео.

Связь между страницами

Разным компонентам расширения часто необходимо взаимодействовать друг с другом. Различные HTML-страницы могут находить друг друга с помощью методов chrome.extension , таких как getViews() и getBackgroundPage() . Как только страница имеет ссылку на другие страницы расширения, первая из них может вызывать функции на других страницах и манипулировать их DOM. Кроме того, все компоненты расширения могут получать доступ к значениям, хранящимся с помощью API хранилища , и обмениваться данными посредством передачи сообщений .

Сохранение данных и режим инкогнито

Расширения могут сохранять данные с помощью API хранилища , API веб-хранилища HTML5 или путем выполнения запросов к серверу, которые приводят к сохранению данных. Когда расширению необходимо что-то сохранить, сначала подумайте, не из окна инкогнито. По умолчанию расширения не запускаются в окнах в режиме инкогнито.

Режим инкогнито обещает, что окно не оставит следов. При работе с данными из окон в режиме инкогнито расширения должны соблюдать это обещание. Если расширение обычно сохраняет историю просмотров, не сохраняйте историю из окон в режиме инкогнито. Однако расширения могут сохранять настройки настроек из любого окна, инкогнито или нет.

Чтобы определить, находится ли окно в режиме инкогнито, проверьте свойство incognito соответствующего объекта tabs.Tab или windows.Window .

function saveTabData(tab) {
  if (tab.incognito) {
    return;
  } else {
    chrome.storage.local.set({data: tab.url});
  }
}

Сделайте следующий шаг

Прочитав обзор и пройдя руководство «Начало работы» , разработчики должны быть готовы приступить к написанию собственных расширений! Погрузитесь глубже в мир кастомизированного Chrome с помощью следующих ресурсов.