Доброе время суток. В своей статье я расскажу о написании расширения для браузера Google Chrome. В ней мы затронем основные моменты написания расширения, более глубокие моменты будут в последующих статьях.
После прочтения статьи вы сможете делать следующее:
1) Создать простое расширение.
2) Работать с контекстным меню браузера.
3) Работать с локальным хранилищем.
Предыстория
Недавно мне понадобилось написать какой-нибудь проект. У меня был выбор между программой на VB или веб разработкой, и я выбрал расширение для Google Chrome. Для тех, кто не знает:
Расширения – это дополнительные функции, которые легко подключить к Google Chrome. Расширения позволяют добавлять в Google Chrome только нужные функции, избегая тех, которые вам не требуются.
Главное преимущество расширений - то, что они выполняются прямиком в браузере и это упрощает их использование. Также хотелось разобраться в расширениях, так как документации на русском языке нет, а в интернете не так уж много полезных статей. В этой статье я затрону одну из возможностей моего расширения - галерея изображений. Допустим, мы нашли интересную картинку и сохранили ее, но она потерялась в
бесконечном большом количестве папок. Еще гораздо легче получить все сохраненные изображения одним кликом а не искать по папкам.
Работать наше расширение будет таким способом:
1) При клике на изображении будет появляться контекстное меню с нашей функцией “Добавить в галерею”.
2) При клике на иконку расширения (возле адресной строки) будет открываться галерея.
3) В галерее можно будет удалить ненужные изображения.
В конечном виде окно галереи будет выглядеть так:
Структура расширения
Расширение для Google Chrome – html, JavaScript, css файлы и manifest.json.
Примечание: manifest.json- обычный текстовый документ, желательно в UTF-8.
Для начала нужно сказать об архитектуре расширения, которая условно делит его на 2 части: то, что работает в контексте просматриваемой страницы, и то, что работает в контексте браузера. Связь между ними происходит через сообщения. Забегая наперед, скажу, что мы будем использовать фоновую страницу для добавления в контекстное меню изображений своей функции.
В manifest.json мы указываем: имя, разрешения, иконку, версию расширения и другие необходимые сведения. Следует внимательно следить за кавычками в этом файле, потому что если пропущен хоть один символ, то расширение не установится.
Важные для нас параметры это background_page и default_popup - фоновая и всплывающая (будет появляться при клике на иконку расширения возле адресной строки) страницы. В отличии от страницы default_popup, которая выполняется при нажатии на иконку расширения, страница background_page выполняется только 1 раз при старте браузера или расширения. В разрешениях мы укажем работу с контекстным меню, вкладками, нелимитированное локальное хранилище и разрешение обращаться к любому адресу. Для тех, кто не знает:
Локальное хранилище — это база данных, которая находится на стороне и клиента и в которой хранятся пары ключ — значение. Данные этой базы данных хранятся на вашем компьютере в браузере. У каждого баузера на компьютере свое локальное хранилище.
Весь файл manifest.json что получился у меня:
{
"background_page": "background.html",
"description": "Галерея для изображений",
"icons": {
"16": "search-s.png",
"48": "search-m.png"
},
"name": " Галерея ",
"permissions": [ "contextMenus" , "tabs", "http://*/*" , "https://*/*","unlimitedStorage"],
"version": "1",
"browser_action": {
"default_title": " Галерея ",
"default_icon": "search-m.png",
"popup": "popup.html"
}
}
Примечание: Приведенные параметры в примере - основные. Есть и другие параметры, но они нам покато не понадобятся. Иконки должны быть размера 16*16 и 48*48.
Установка расширения
Чтобы устанавливать расширение открытием файла надо упаковать расширение, о чем я расскажу в конце статьи т.к. после этого нельзя ничего добавлять и изменять в расширении. Все файлы нашего расширения будут находиться в одной папке. Поэтому установка будет чуть больше чем открытие файла:
1) Нажимаем на кнопку “Настройка и управление Google Chrome”(гаечный ключ).
2) Из появившегося выбираем “Параметры”.
3) Выбираем в меню “Расширения”.
4) Кликаем по чекбоксу “Режим разработчика”, затем “Загрузить распакованное расширение”.
5) Выбираем папку с расширением и кликаем ОК.
Если вылетает ошибка, то скорее всего вы допустили ошибку в файле manifest.json и в окошке ошибки должна быть указана строка в файле, содержащая ошибку. Дальше в статье мы будем добавлять новые файлы, и дописывать в них код. Расширение должно “обновляться” автоматически, если этого не происходит перезайдите в браузер.
Тело галереи
Чтобы не писать галерею самому можно скачать уже готовый вариант, благо красивые jQuery галереи можно найти при помощи Google. Я скачал уже готовый вариант с сайта smoothgallery.jondesign.net. Это бесплатная галерея, использующая jQuery и мы можем добавлять и изменять ее. Отлично, мы можем с ней спокойно работать. После загрузки я распаковал ее и удалил все файлы примеры и изображения к ним кроме demo.html. Теперь можно переместить файлы в папку с нашим расширением.
background.html
Как уже сказано, это фоновая страница, запишем в ней javascript код для добавления функции в контекстное меню изображения:
chrome.contextMenus.create({"title": "Добавить в галерею",
"contexts": ["image"],
"onclick": addImage});
Должно получиться так:
Структура расширения
При клике будет выполняться функция addImage, в которой будем сохраняться URL изображения. Мы будем создавать локальные хранилища chimggali0, chimggali1 , chimggali2 и т.д.
0,1,2,..,n – ссылки на сохраненные изображения, где n-последняя ссылка.
Также мы будем получать и сохранять дату, когда пользователь сохранил изображение. Локальные хранилища для дат: chdate0, chdate1, chdate2 и т.д. Делаем локальное хранилище для переменной i, которая отвечает за нумерацию изображений. Если локального хранилища не существует, то i=0, в противоположном случае присваиваем значение из хранилища. После выполнения функции i увеличивается на 1 и сохраняется в хранилище.
Сам код функции:
function addImage(info,tab) {
if ( ! localStorage['chgali'])
{
i = 0;
}
else
{
i = readProperty("chgali");
}
imggal = info.srcUrl;
localStorage["chimggali"+i+""]=imggal ;
var currentTime = new Date()
var month = currentTime.getMonth() + 1
var day = currentTime.getDate()
var year = currentTime.getFullYear()
var fordate = day+ "." + month + "." + year;
localStorage["chdate"+i+""]=fordate;
i++;
localStorage["chgali"]=i ;
}
Чтобы получить значение “ячейки” я использовал функцию readProperty для удобства. Эту функцию я буду использовать и далее.
Ее код:
function readProperty(property, defValue)
{
if(localStorage[property] == null)
{
return defValue;
}
return localStorage[property];
}
demo.html
Это файл нашей галереи, зайдя в который можно будет увидеть добавленные изображения. Если сразу открыть этот файл то в нем будут стандартные изображения, добавленные автором при помощи HTML. Нам же надо динамически их генерировать. Первое что надо сделать это убрать статические изображения. Удаляем все <div class="imageElement"> и код в них. Если сейчас открыть этот файл то в галерее ничего не будет, так что надо написать JavaScript код для отображения добавленных картинок.
Функция будет называться load и выполняться при загрузке страницы, для этого допишем в теге body onload="load()". В функции получаем значение chgali из локального хранилища и организовываем цикл. В цикле создаем div контейнер с id="imageElement", в котором будет изображение. Получаем значения ссылки на изображения и дату его добавления, в теге h3 будет дата, а в теге будет ссылка на изображения. При помощи innerHTML добавляем наш контейнер в div контейнер с id="myGallery".
Теперь можно запустить галерею, дописав в конце функции window.addEvent('domready',startGallery);. Если вам не нравятся пропорции, в которых выводятся дата добавления и URL-адрес страницы, то можно поэкспериментировать с файлом jd.gallery.css в папке css. Там записаны стили всех элементов нашей галереи и, потратив немного времени, можно подобрать идеальные на свое усмотрение значения. Одна задача решена, в галерее уже есть добавленные изображения, но их нельзя удалять. Для возможности удаления создадим функцию idelete, в которую будем аргументом передавать номер изображения. Функция будет в цикле перезаписывать соответствующую “ячейку” в локальном хранилище на последующую, пока не дойдет до последней, и уменьшит chgali (количество всех изображений) на 1. То же самое надо сделать и с датой добавления изображения. В конце допишем перезарузку вкладки.
Код функции idelete
var func = function idelete(asd)
{
for(var f=asd;f<team-1;f++){
var fgh=f+1;
var rty = readProperty("chimggali"+fgh+"");
localStorage["chimggali"+f+""]=rty;
var rtu = readProperty("chdate"+fgh+"");
localStorage["chdate"+f+""] = rtu;
}
var close=readProperty("chgali");
localStorage["chgali"] = close-1;
window.location.reload();
}
Примечание: team-1 – кол-во изображений.
Допишем в функции load код, получающий кол-во миниатюр. Организуем цикл добавляющий маленький крестик в углу для удаления к каждой миниатюре картинки. Добавим событие: при клике на маленький крестик выполнять функцию idelete с аргументом – порядковым номером миниатюры.
Код:
var close = document.getElementsByClassName('thumbnail');
for(var t=0;t<close.length;t++)
{
close[t].innerHTML='<img src="http://www.upyourfiles.com/templates/default/images/x.gif" id="cl'+t+'" onclick="func('+t+')">';
}
popup.html
В этой части есть два способа. Так как мы должны просто открыть галерею, то можно не использовать popup, а при клике на иконку сразу открывать галерею. В обратном случае будет появляться окно с кнопкой “Галерея”.
Для наглядности приведу снимок получившегося всплывающего окна:
Первый вариант (без использования popup)
Если использовать этот вариант надо удалить из файла manifest.json строчку "popup": "popup.html".
Пишем в background.html
chrome.browserAction.onClicked.addListener (function() {
chrome.tabs.create({"url":”demo.html”});
}
Примечание: chrome.browserAction.onClicked исключает использование popup и наоборот.
Этим кодом мы при клике на иконку открываем новую вкладку с галереей.
Второй вариант (с popup)
В файле popup.html создаем кнопку и при клике выполняем функцию click. Для создания красивых кнопок при помощи css можно использовать эти сайты (мне больше всего нравится первый):
•
http://www.cssbuttongenerator.com/
•
http://css3buttongenerator.com/
•
http://css-tricks.com/examples/ButtonMaker/
В функции click запишем создание новой вкладки с галереей (то же что и в верхнем примере):
chrome.tabs.create({"url":”demo.html”});
Упаковка расширения
1) Нажимаем на кнопку “Настройка и управление Google Chrome” (гаечный ключ).
2) Из появившегося выбираем “Параметры”.
3) Выбираем в меню “Расширения”.
4) Кликаем по чекбоксу “Режим разработчика”, затем по “Упаковка раширения”.
5) В поле “Корневой каталог расширения” выбираем папку с расширением. Второе поле оставляем пустым.
6) В появившемся окне указано местонахождение упакованного расширения и файла ключей. Файл ключей понадобится для установки обновлений расширения, а не его копий. При упаковке новой версии расширения просто укажите файл ключей во втором поле при упаковке.
Примечание: Хоть упакованное расширение и имеет расширение crx, но это обычный zip архив указанной папки с добавлением уникального идентификатора.
Теперь наше расширение можно распространять!
Концовка
Спасибо за внимание! Написание расширение на самом деле довольно увлекательное занятие. В следующей статье я думаю затронуть темы: хромовский API, XMLHttpRequest и регулярные выражения.
P.S. Вот
ссылка для желающих почитать официальную документацию.
P.P.S. Вот
ссылка на исходники расширения.
P.P.P.S.Обсуждаем в
этой теме.