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

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

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

Активируйте расширение на всех страницах

Используйте браузер_действие , если функции расширения работают в большинстве ситуаций.

Зарегистрировать действие браузера

Поле "browser_action" зарегистрировано в манифесте.

{
  "name": "My Awesome browser_action Extension",
  ...
  "browser_action": {
    ...
  }
  ...
}

Объявление "browser_action" сохраняет цвет значка, указывая, что расширение доступно пользователям.

Добавить значок

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

Используйте значки, чтобы указать состояние расширения. В примере события «Питьевая вода » отображается значок «ВКЛ», чтобы показать пользователю, что он успешно установил будильник, и ничего не отображается, когда расширение не используется.

Значок включен

Значок отключен

Установите текст значка, вызвав chrome.browserAction.setBadgeText , а цвет баннера, вызвав chrome.browserAction.setBadgeBackgroundColor .

chrome.browserAction.setBadgeText({text: 'ON'});
chrome.browserAction.setBadgeBackgroundColor({color: '#4688F1'});

Активируйте расширение на выбранных страницах

Используйте page_action , когда функции расширения доступны только при определенных обстоятельствах.

Объявить действие страницы

Поле "page_action" зарегистрировано в манифесте.

{
  "name": "My Awesome page_action Extension",
  ...
  "page_action": {
    ...
  }
  ...
}

Объявление "page_action" раскрасит значок только тогда, когда расширение доступно пользователям, в противном случае он будет отображаться в оттенках серого.

Значок действия на активной странице

Неиспользуемый значок действия на странице

Определите правила активации расширения

Определите правила использования расширения, вызвав chrome.declarativeContent в прослушивателе runtime.onInstalled в фоновом скрипте . Пример расширения « Действие страницы по URL-адресу» устанавливает условие, согласно которому URL-адрес должен содержать букву «g». Если условие выполнено, расширение вызывает declarativeContent.ShowPageAction() .

chrome.runtime.onInstalled.addListener(function() {
  // Replace all rules ...
  chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
    // With a new rule ...
    chrome.declarativeContent.onPageChanged.addRules([
      {
        // That fires when a page's URL contains a 'g' ...
        conditions: [
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { urlContains: 'g' },
          })
        ],
        // And shows the extension's page action.
        actions: [ new chrome.declarativeContent.ShowPageAction() ]
      }
    ]);
  });
});

Включить или отключить расширение

Расширения, использующие "page_action" можно активировать и отключать динамически, вызывая pageAction.show и pageAction.hide .

Пример расширения Mappy сканирует веб-страницу в поисках адреса и показывает его местоположение на статической карте во всплывающем окне . Поскольку расширение зависит от содержимого страницы, оно не может объявлять правила, позволяющие предсказать, какие страницы будут релевантны. Вместо этого, если на странице найден адрес, он вызывает pageAction.show чтобы раскрасить значок и сообщить, что расширение можно использовать на этой вкладке.

chrome.runtime.onMessage.addListener(function(req, sender) {
  chrome.storage.local.set({'address': req.address})
  chrome.pageAction.show(sender.tab.id);
  chrome.pageAction.setTitle({tabId: sender.tab.id, title: req.address});
});

Предоставьте значки расширений

Для расширения расширений требуется хотя бы один значок. Предоставление значков в формате PNG обеспечивает наилучшие визуальные результаты, хотя принимаются любые форматы, поддерживаемые WebKit, включая BMP, GIF, ICO и JPEG.

Назначение значков панели инструментов

Значки, относящиеся к панели инструментов, регистрируются в поле "default_icon" в разделе browser_action или page_action манифеста. Рекомендуется включать несколько размеров для масштабирования на 16-диапазонное пространство. Рекомендуется использовать как минимум размеры 16x16 и 32x32.

{
  "name": "My Awesome page_action Extension",
  ...
  "page_action": {
    "default_icon": {
      "16": "extension_toolbar_icon16.png",
      "32": "extension_toolbar_icon32.png"
    }
  }
  ...
}

Все значки должны быть квадратными, иначе они могут быть искажены. Если значки не указаны, Chrome добавит общий значок на панель инструментов.

Создание и регистрация дополнительных значков

Включите дополнительные значки следующих размеров для использования за пределами панели инструментов.

Размер значка Использование значка
16x16 фавикон на страницах расширения
32х32 Компьютерам под управлением Windows часто требуется этот размер. Использование этой опции предотвратит искажение размера при уменьшении параметра 48x48.
48x48 отображается на странице управления расширениями
128х128 отображается при установке и в интернет-магазине Chrome

Зарегистрируйте значки в манифесте в поле "icons" .

{
  "name": "My Awesome Extension",
  ...
  "icons": {
    "16": "extension_icon16.png",
    "32": "extension_icon32.png",
    "48": "extension_icon48.png",
    "128": "extension_icon128.png"
  }
  ...
}

Дополнительные функции пользовательского интерфейса

Всплывающее окно — это HTML-файл, который отображается в специальном окне, когда пользователь щелкает значок на панели инструментов. Всплывающее окно работает очень похоже на веб-страницу; он может содержать ссылки на таблицы стилей и теги скриптов, но не поддерживает встроенный JavaScript.

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

Пример скриншота всплывающего окна

<html>
  <head>
    <title>Water Popup</title>
  </head>
  <body>
      <img src='./stay_hydrated.png' id='hydrateImage'>
      <button id='sampleSecond' value='0.1'>Sample Second</button>
      <button id='15min' value='15'>15 Minutes</button>
      <button id='30min' value='30'>30 Minutes</button>
      <button id='cancelAlarm'>Cancel Alarm</button>
    <script src="popup.js"></script>
  </body>
</html>

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

{
  "name": "Drink Water Event",
  ...
  "browser_action": {
    "default_popup": "popup.html"
  }
  ...
}

Всплывающие окна также можно настроить динамически, вызвав browserAction.setPopup или pageAction.setPopup .

chrome.storage.local.get('signed_in', function(data) {
  if (data.signed_in) {
    chrome.browserAction.setPopup({popup: 'popup.html'});
  } else {
    chrome.browserAction.setPopup({popup: 'popup_sign_in.html'});
  }
});

Подсказка

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

Скриншот примера всплывающей подсказки

Подсказки регистрируются в поле "default_title" browser_action или page_action в манифесте.

{
"name": "Tab Flipper",
  ...
  "browser_action": {
    "default_title": "Press Ctrl(Win)/Command(Mac)+Shift+Right/Left to flip tabs"
  }
...
}

Всплывающие подсказки также можно установить или обновить, вызвав browserAction.setTitle и pageAction.setTitle .

chrome.browserAction.onClicked.addListener(function(tab) {
  chrome.browserAction.setTitle({tabId: tab.id, title: "You are on tab:" + tab.id});
});

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

  • _locales/en/messages.json
  • _locales/es/messages.json

Форматируйте сообщения внутри messages.json каждого языка.

{
  "__MSG_tooltip__": {
      "message": "Hello!",
      "description": "Tooltip Greeting."
  }
}
{
  "__MSG_tooltip__": {
      "message": "Hola!",
      "description": "Tooltip Greeting."
  }
}

Включите имя сообщения в поле всплывающей подсказки вместо самого сообщения, чтобы включить локализацию.

{
"name": "Tab Flipper",
  ...
  "browser_action": {
    "default_title": "__MSG_tooltip__"
  }
...
}

Омнибокс

Пользователи могут вызывать функциональные возможности расширения через омнибокс . Включите в манифест поле "omnibox" и укажите ключевое слово. Пример расширения «Поиск новой вкладки» в омнибоксе использует «nt» в качестве ключевого слова.

{
  "name": "Omnibox New Tab Search",\
  ...
  "omnibox": { "keyword" : "nt" },
  "default_icon": {
    "16": "newtab_search16.png",
    "32": "newtab_search32.png"
  }
  ...
}

Когда пользователь вводит «nt» в омнибокс, расширение активируется. Чтобы сообщить об этом пользователю, он окрашивает предоставленный значок размером 16x16 в оттенки серого и включает его в омнибокс рядом с именем расширения.

Активное расширение омнибокса

Расширение прослушивает событие omnibox.onInputEntered . После запуска расширение открывает новую вкладку, содержащую поиск Google по записи пользователя.

chrome.omnibox.onInputEntered.addListener(function(text) {
  // Encode user input for special characters , / ? : @ & = + $ #
  var newURL = 'https://www.google.com/search?q=' + encodeURIComponent(text);
  chrome.tabs.create({ url: newURL });
});

Контекстное меню

Добавьте новые параметры контекстного меню , предоставив разрешение "contextMenus" в манифесте.

{
  "name": "Global Google Search",
  ...
  "permissions": [
    "contextMenus",
    "storage"
  ],
  "icons": {
    "16": "globalGoogle16.png",
    "48": "globalGoogle48.png",
    "128": "globalGoogle128.png"
  }
  ...
}

Значок размером 16x16 отображается рядом с новым пунктом меню.

Значок контекстного меню

Создайте контекстное меню, вызвав contextMenus.create в фоновом скрипте . Это должно быть сделано в рамках события прослушивателя runtime.onInstalled .

chrome.runtime.onInstalled.addListener(function() {
  for (let key of Object.keys(kLocales)) {
    chrome.contextMenus.create({
      id: key,
      title: kLocales[key],
      type: 'normal',
      contexts: ['selection'],
    });
  }
});
const kLocales = {
  'com.au': 'Australia',
  'com.br': 'Brazil',
  'ca': 'Canada',
  'cn': 'China',
  'fr': 'France',
  'it': 'Italy',
  'co.in': 'India',
  'co.jp': 'Japan',
  'com.ms': 'Mexico',
  'ru': 'Russia',
  'co.za': 'South Africa',
  'co.uk': 'United Kingdom'
};

В примере контекстного меню глобального поиска Google создается несколько параметров из списка в locales.js . Если расширение содержит более одного контекстного меню, Google Chrome автоматически сворачивает их в одно родительское меню.

Несколько контекстных меню свернутся

Команды

Расширения могут определять определенные команды и привязывать их к комбинации клавиш. Зарегистрируйте одну или несколько команд в манифесте в поле "commands" .

{
  "name": "Tab Flipper",
  ...
  "commands": {
    "flip-tabs-forward": {
      "suggested_key": {
        "default": "Ctrl+Shift+Right",
        "mac": "Command+Shift+Right"
      },
      "description": "Flip tabs forward"
    },
    "flip-tabs-backwards": {
      "suggested_key": {
        "default": "Ctrl+Shift+Left",
        "mac": "Command+Shift+Left"
      },
      "description": "Flip tabs backwards"
    }
  }
  ...
}

Команды можно использовать для предоставления новых или альтернативных ярлыков браузера. Пример расширения Tab Flipper прослушивает событие commands.onCommand в фоновом сценарии и определяет функциональные возможности для каждой зарегистрированной комбинации.

chrome.commands.onCommand.addListener(function(command) {
  chrome.tabs.query({currentWindow: true}, function(tabs) {
    // Sort tabs according to their index in the window.
    tabs.sort((a, b) => { return a.index < b.index; });
    let activeIndex = tabs.findIndex((tab) => { return tab.active; });
    let lastTab = tabs.length - 1;
    let newIndex = -1;
    if (command === 'flip-tabs-forward')
      newIndex = activeIndex === 0 ? lastTab : activeIndex - 1;
    else  // 'flip-tabs-backwards'
      newIndex = activeIndex === lastTab ? 0 : activeIndex + 1;
    chrome.tabs.update(tabs[newIndex].id, {active: true, highlighted: true});
  });
});

Команды также могут создавать привязку клавиш, которая работает специально с ее расширением. Пример Hello Extensions дает команду для открытия всплывающего окна.

{
  "name": "Hello Extensions",
  "description" : "Base Level Extension",
  "version": "1.0",
  "browser_action": {
    "default_popup": "hello.html",
    "default_icon": "hello_extensions.png"
  },
  "manifest_version": 2,
  "commands": {
    "_execute_browser_action": {
      "suggested_key": {
        "default": "Ctrl+Shift+F",
        "mac": "MacCtrl+Shift+F"
      },
      "description": "Opens hello.html"
    }
  }
}

Поскольку расширение определяет browser_action оно может указать "execute_browser_action" в командах для открытия всплывающего файла без включения фонового сценария . Если вы используете page_action , его можно заменить на "execute_page_action" . В одном расширении можно использовать как команды браузера, так и расширения.

Переопределить страницы

Расширение может переопределить и заменить веб-страницу «История», «Новая вкладка» или «Закладки» пользовательским HTML-файлом. Как и всплывающее окно , оно может включать специализированную логику и стиль, но не поддерживает встроенный JavaScript. Одно расширение ограничено переопределением только одной из трех возможных страниц.

Зарегистрируйте страницу переопределения в манифесте в поле "chrome_url_overrides" .

{
  "name": "Awesome Override Extension",
  ...

  "chrome_url_overrides" : {
    "newtab": "override_page.html"
  },
  ...
}

Поле "newtab" следует заменить на "bookmarks" или "history" при переопределении этих страниц.

<html>
  <head>
  <title>New Tab</title>
  </head>
  <body>
    <h1>Hello World</h1>
  <script src="logic.js"></script>
  </body>
</html>