Тема создания расширений достаточно хорошо раскрыта в сети, есть множество статей, документации на эту тему. Но я не нашел ни одного ресурса, который бы описал процесс создания расширения от начала до конца. Я собираюсь исправить эту ситуацию, и рассказать о том как создать расширение, как хранить, читать настройки, как добавить поддержку нескольких языков.
Для работы с расширениями вам понадобится переключить канал обновлений на Dev или Beta.
Расширение будет иметь кнопку с иконкой на панели инструментов Chrome. При нажатии на кнопку будет появляться всплывающее окно (popup) со случайной картинкой из галлереи фотографий телескопа Hubble. В верхней части окна будут размещены кнопки: настроить (показать страницу настроек), обновить (показать другую фотографию), закрыть (закрыть всплывающее окно).
Расширение будет содержать страницу настроек (options), на которой можно будет выбрать язык интерфейса (русский, английский) и выбрать размер картинки (маленький, большой).
Создание расширения начинается с создания папки, в которой мы будет создавать все необходимы для работы расширения файлы. Созадим папку HubblePics. Далее создадим файл, который будет содержать описание нашего расширения — manifest.json. Данный файл является обязательным для каждого расширения. Именно из него Chrome получает всю необходимую информацию о расширении (название, версия, разрешения, страницы расширения и т.д.).
Подробное описание файла manifest.json вы можете получить здесь
Создадим страницу настроек — options.html. Приводить полный код страницы я не буду, только интересные, на мой взгляд моменты, а именно сохранение, извлечение настроек и локализация.
Сохранять настройки можно в объекте localStorage, который, по сути, представляет из себя ассоциативный массив, хранящий пары «название», «значение». Например, для сохранения состояния радиокнопки «Размер картинки — Маленький», используется код:
Для восстановления состояния:
В своем проекте я обернул обращение к localStorage в функцию readProperty чтобы избавится от лишних проверок и получить возможность получения значения по умолчанию:
С настройками разобрались, приступим к локализации. Способ, который я предлагаю, возможно, не самый лучший, но на данный момент ничего лучше я придумать не смог. Если кто-то подскажет другой, более простой вариант — буду рад.
Идея простая — есть ряд элементов, которые нужно перевести. У них есть идентификаторы. Создается ассоциативный массив или объект, в котором идентификатору элемента соответствует локализованный текст. Функция, которая занимается локализацией «пробегает» по массиву, по идентификатору находит контрол и устанавливает ему текст.
Создадим файл с названием элементов и указанием языка. Язык «регистрируется», путем добавления элемента в выпадающий список «Язык». Например русский язык добавляет в список элемент с текстом «Russian» и значением «ru_RU».
Файл \locale\ru_RU\options.js
Этот скрипт добавляется на страницу настроек (options.html)
На странице, все локализуемые элементы должны иметь соответствующие идентификаторы, например:
Локализацией занимается функция localize
Теперь, если нам необходимо добавить новый язык, например английский, мы просто создаем папку \locale\en_US, в ней создаем скрипт options.js
И добавляем скрипт на страницу
Внутри файла popup.html простая разметка, в которой предусмотрено место для загружаемой картинки, кнопки управления и индикатор процесса загрузки.
В общем ничего интересного. Все интересно вынесено в файл popup.js.
Данный скрипт, используя XMLHttpRequest загружает страницу hubblesite.org/gallery/wallpaper, находит ссылки на изображения, выбирает случайное и отображает в popup-е.
Расширение создано, теперь необходимо загрузить его в Chrome. Запускаем Chrome, нажимаем кнопку Настройка и управление , выбираем пункт меню Extensions.
На открывшейся вкладке нажимаем Load Extension..., указываем путь к папке и, если все сделано правильно, видим новую кнопку на панели инструментов.
А в списке расширений видим наше расширение.
Теперь упакуем наше расширение, для того, чтобы его можно было выложить на какой-нибудь ресурс и любой пользователь мог бы скачать и установить его в пару кликов. Для этого, на той же закладке Installed Extensions нажимаем кнопку Pack Extension..., указываем путь к папке, содержащей файлы расширения, поле Private key file в первый раз оставляем пустым.
Нажимаем OK, видим сообщение о том, что расширение упаковано.
Если мы собираемся выпускать обновленные версии расширения — сохраним созданный файл с ключем HubblePics.pem и будем указывать путь к нему при каждой последующей упаковке расширения, иначе, каждый раз будет генерироваться новый файл, что приведет к назначению нового идентификатора для нашего расширения, а это, в свою очередь приведет к тому, что вместо обновления, пользователь будет устанавливать новую копию расширения.
Архив с исходниками расширения
Практически вся информация, необходимая для разработки расширений сосредоточена на странице Google Chrome Extensions: Developer Documentation. Если этого покажется мало, то всегда можно взять готовое расширение, изменить расширение с crx на zip, распаковать и посмотреть как это сделано «у них».
Так же источником информации, так сказать, из первых рук, может стать список изменений при выходе новых версий Google Chrome.
Для работы с расширениями вам понадобится переключить канал обновлений на 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.