Pull to refresh

Создание расширения для Google Chrome

Reading time8 min
Views118K
Тема создания расширений достаточно хорошо раскрыта в сети, есть множество статей, документации на эту тему. Но я не нашел ни одного ресурса, который бы описал процесс создания расширения от начала до конца. Я собираюсь исправить эту ситуацию, и рассказать о том как создать расширение, как хранить, читать настройки, как добавить поддержку нескольких языков.

Для работы с расширениями вам понадобится переключить канал обновлений на Dev или Beta.

Расширение будет иметь кнопку с иконкой на панели инструментов Chrome. При нажатии на кнопку будет появляться всплывающее окно (popup) со случайной картинкой из галлереи фотографий телескопа Hubble. В верхней части окна будут размещены кнопки: настроить (показать страницу настроек), обновить (показать другую фотографию), закрыть (закрыть всплывающее окно).

Расширение будет содержать страницу настроек (options), на которой можно будет выбрать язык интерфейса (русский, английский) и выбрать размер картинки (маленький, большой).



Создание расширения начинается с создания папки, в которой мы будет создавать все необходимы для работы расширения файлы. Созадим папку HubblePics. Далее создадим файл, который будет содержать описание нашего расширения — manifest.json. Данный файл является обязательным для каждого расширения. Именно из него Chrome получает всю необходимую информацию о расширении (название, версия, разрешения, страницы расширения и т.д.).

{
 "name": "Hubble pictures extension", // Название расширения
 "version": "1.0", // Номер версии
 "description": "Hubble pictures extension", // Описание расширения

 "permissions": [
  "tabs", // Разрешить расширению работать с вкладками
  "http://hubblesite.org/*" // Разрешить расширению обращаться к указанному адресу
 ],

 "browser_action": { // Элементы браузера
  "default_title": "Hubble", // Название кнопки
  "default_icon": "images/icon.png", // Иконка для кнопки
  "popup": "popup.html" // Всплывающее окно
 },

 "options_page": "options.html" // Страница настроек
}


* This source code was highlighted with Source Code Highlighter.

Подробное описание файла manifest.json вы можете получить здесь

Настройки


Создадим страницу настроек — options.html. Приводить полный код страницы я не буду, только интересные, на мой взгляд моменты, а именно сохранение, извлечение настроек и локализация.

Сохранять настройки можно в объекте localStorage, который, по сути, представляет из себя ассоциативный массив, хранящий пары «название», «значение». Например, для сохранения состояния радиокнопки «Размер картинки — Маленький», используется код:

localStorage["previewSmall"] = document.getElementById("previewSmall").checked;

Для восстановления состояния:

document.getElementById("previewSmall").checked = (localStorage["previewSmall"] == "true") ? true : false;

В своем проекте я обернул обращение к localStorage в функцию readProperty чтобы избавится от лишних проверок и получить возможность получения значения по умолчанию:

function readProperty(property, defValue)
{
  if(localStorage[property] == null)
  {
    return defValue;
  }

  return localStorage[property];
}

// Пример вызова
document.getElementById("previewSmall").checked = readProperty("previewSmall", true);


* This source code was highlighted with Source Code Highlighter.

Локализация


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

Идея простая — есть ряд элементов, которые нужно перевести. У них есть идентификаторы. Создается ассоциативный массив или объект, в котором идентификатору элемента соответствует локализованный текст. Функция, которая занимается локализацией «пробегает» по массиву, по идентификатору находит контрол и устанавливает ему текст.

Создадим файл с названием элементов и указанием языка. Язык «регистрируется», путем добавления элемента в выпадающий список «Язык». Например русский язык добавляет в список элемент с текстом «Russian» и значением «ru_RU».

Файл \locale\ru_RU\options.js

RegisterLang();

lang_ru_RU =
{
  lngLanguage: "Язык", // Пара - идентификатор (id) элемента, текст

  lngPreviewSize: "Размер картинки",
  lngPreviewSmall: "Маленький",
  lngPreviewBig: "Большой",
  
  lngSave: "Сохранить",
  lngExit: "Выход"
}

function RegisterLang()
{
  var ctrl = document.getElementById("language");

  ctrl.add(createOption("Russian", "ru_RU"));
}


* This source code was highlighted with Source Code Highlighter.


Этот скрипт добавляется на страницу настроек (options.html)

<script type="text/javascript" src="locale/ru_RU/options.js"></script>

На странице, все локализуемые элементы должны иметь соответствующие идентификаторы, например:

<span id="lngPreviewSmall">Small</span>

Локализацией занимается функция localize

function getSelectedLanguage()
{
  var lang = getSelectedValue("language"); // Возвращает значение выбранного элемента в выпадающем списке "Language"
  return eval("lang_" + lang);
}

function localize()
{
  var lang = getSelectedLanguage();

  // Перебираем все элементы объекта lang_ru_RU
  for(var ctrlId in lang)
  {
    var value = lang[ctrlId];

    // Получить элемент с id
    var ctrl = document.getElementById(ctrlId);

    // Не найден, продолжаем перебор
    if(ctrl == null)
    {
      continue;
    }

    // Найден, определить тип и присвоить значение
    if(ctrl.tagName == "SPAN")
    {
      ctrl.innerText = value;
    }
    else if(ctrl.tagName == "INPUT")
    {
      ctrl.value = value;
    }
  }
}


* This source code was highlighted with Source Code Highlighter.

Теперь, если нам необходимо добавить новый язык, например английский, мы просто создаем папку \locale\en_US, в ней создаем скрипт options.js

RegisterLang();

lang_en_US =
{
  lngLanguage: "Language",
  
  ...

  lngExit: "Exit"
}

function RegisterLang()
{
  var ctrl = document.getElementById("language");

  if(ctrl != null)
  {
    ctrl.add(createOption("English", "en_US"));
  }
}


* This source code was highlighted with Source Code Highlighter.

И добавляем скрипт на страницу

<script type="text/javascript" src="locale/en_US/options.js"></script>

Всплывающее окно


Внутри файла popup.html простая разметка, в которой предусмотрено место для загружаемой картинки, кнопки управления и индикатор процесса загрузки.

<ul class="menu">
  <li><img src="images/options.png" onclick="showOptions();"/></li>
  <li><img src="images/update.png" onclick="getPicture();"/></li>
  <li><img src="images/close.png" onclick="closePopup();"/></li>
</ul>

<div id="loader">
  <img src="images/loader.gif" />
</div>

<div id="image" style="display: none;">
  <a href="#" id="hrefPlace" onclick="return openImage();"><img id="imgPlace"/></a>
</div>


* This source code was highlighted with Source Code Highlighter.

В общем ничего интересного. Все интересно вынесено в файл popup.js.

Данный скрипт, используя XMLHttpRequest загружает страницу hubblesite.org/gallery/wallpaper, находит ссылки на изображения, выбирает случайное и отображает в popup-е.

xhr = new XMLHttpRequest();

xhr.onreadystatechange = function() {
if (xhr.readyState == 4)
{
  if (xhr.responseText)
  {
    var xmlDoc = xhr.responseText;

    var imgs = xmlDoc.match(/http:\/\/imgsrc.hubblesite.org\/hu\/db\/images\/hs-[0-9]{4}-[0-9]{2}-[a-z]/g);
    var hrefs = xmlDoc.match(/gallery\/wallpaper\/pr[0-9]{4,}[a-z]/g);

    if (imgs.length > 0)
    {
      var randIdx = Math.floor(Math.random() * imgs.length);

      var imgSize = "-wallpaper_thumb.jpg";

      // Какую картинку показываем?
      if(readProperty("previewBig", "false") == "true")
      {
        imgSize = "-640_wallpaper.jpg";
      }

      showImage("http://hubblesite.org/" + hrefs[randIdx], imgs[randIdx] + imgSize);
    }
  }
}

xhr.open("GET", "http://hubblesite.org/gallery/wallpaper/", true);
xhr.send(null);

function showImage(url, imgSrc)
{
  var imgPlace = document.getElementById("imgPlace");
  imgPlace.setAttribute("src", imgSrc);

  var hrefPlace = document.getElementById("hrefPlace");
  hrefPlace.setAttribute("href", url);

  displayLoader(false);
}


* This source code was highlighted with Source Code Highlighter.

Установка и упаковка расширения


Расширение создано, теперь необходимо загрузить его в Chrome. Запускаем Chrome, нажимаем кнопку Настройка и управление , выбираем пункт меню Extensions.



На открывшейся вкладке нажимаем Load Extension..., указываем путь к папке и, если все сделано правильно, видим новую кнопку на панели инструментов.



А в списке расширений видим наше расширение.



Теперь упакуем наше расширение, для того, чтобы его можно было выложить на какой-нибудь ресурс и любой пользователь мог бы скачать и установить его в пару кликов. Для этого, на той же закладке Installed Extensions нажимаем кнопку Pack Extension..., указываем путь к папке, содержащей файлы расширения, поле Private key file в первый раз оставляем пустым.



Нажимаем OK, видим сообщение о том, что расширение упаковано.

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

Архив с исходниками расширения

Практически вся информация, необходимая для разработки расширений сосредоточена на странице Google Chrome Extensions: Developer Documentation. Если этого покажется мало, то всегда можно взять готовое расширение, изменить расширение с crx на zip, распаковать и посмотреть как это сделано «у них».

Так же источником информации, так сказать, из первых рук, может стать список изменений при выходе новых версий Google Chrome.
Tags:
Hubs:
Total votes 98: ↑93 and ↓5+88
Comments28

Articles