Расширение Google Chrome — корзина вкладок
Доброго времени суток, уважаемый посетитель ХабраХабра! В этот очередной в нашей с Вами жизни день знаний (который я, однако, провел исключительно за работой, а не учебой), под влиянием данной статьи, пишу повествование о моем опыте создания расширения для Google Chrome – TabBasket (не знаю, как Вы, но я на названия неказист). Статья оформлена в смешанном стиле – перекликаются элементы урока, а так же пояснения по коду и описание ключевых моментов. Прежде чем перейти непосредственно к главному, замечу, что мои знания CSS немного сумбурны, опыта было совсем немного, поэтому какое-то мое решение может показаться слегка странным.
Что мы имеемДля написания расширения нам практически не нужны никакие инструменты, всю работу можно провести хоть в блокноте или gedit. Выбираем редактор на свой вкус (лично я в таких случаях пользуюсь либо Notepad++, либо NetBeans; первое легче, второе функциональнее, выбор как всегда за Вами).
Ближе к делуПредполагается, что с основами создания расширений читатель уже знаком (опять же из упомянутой выше статьи), поэтому живенько начнем с манифеста:
* This source code was highlighted with Source Code Highlighter .
Два элемента back.html и popup.html будут постепенно рассмотрены (созданы, написаны) далее. Никаких неожиданной в манифесте нет, все достаточно прозрачно. Для большего понимания процесса, кратенько изложу идею. Замечательная страничка back.html работает в тени, не имеет внешнего вида, её код стартует сразу после установки расширения или запуска браузера, если расширение уже было установлено. Ее роль – установить обработчики для событий создания, удаления или обновления вкладок. Popup.html непосредственно формирует список закрытых вкладок, позволяет восстановить какую – либо из них.
Двигаемся дальше. Разбираем файл back.html:
/* Tab constructor function. */ function AnyTab() < this .id = 0 this .url = "" this .name = "" this .favicon = "" >
* This source code was highlighted with Source Code Highlighter .
Функция-конструктор для объекта, хранящего информацию о вкладке. Язык позволяет создать инициализированный значениями по умолчанию объект разными методами, я выбрал именно этот. Хранится id вкладки (выдается самим браузером), url(что это о_О?), name (название сайта) и favicon (иконка сайта, с ней отдельная свистопляска). Далее по коду
var active = [] var closedTabs = [] var maxTabCount = 15
* This source code was highlighted with Source Code Highlighter .
Нам понадобятся два массива – активных (открытых) вкладок и закрытых. Максимальное число вкладок я выбрал (по-моему мнению) оптимальное. Вешаем обработчики на события
chrome.tabs.onUpdated.addListener(onTabUpdated) chrome.tabs.onRemoved.addListener(onTabRemoved) chrome.tabs.onCreated.addListener(onTabCreated)
* This source code was highlighted with Source Code Highlighter .
В таком случае onTabUpdated, onTabRemoved И onTabCreated – имена функций обработчиков. Теперь немного приоткроем завесу тайны – когда вкладка создается, необходимо запомнить необходимые нам характеристики (ссылку, название и др.). Делается это потому, что в функцию onTabRemoved приходит только id закрытой вкладки, а ее самой уже и в помине нет. Поэтому при закрытии вкладки она ищется по своему id в массиве active(кстати ее там может и не быть – если расширение было установлено в момент, когда в программе уже были открытие вкладки), данные копируются в массив closedTabs и, соответственно, удаляются из массива active. Теперь мы имеем полную информацию о закрытой вкладке и без труда можем ее восставить! Внимательный читатель, однако, обратит внимание на то, что я не упомянул про функцию onTabUpdated. У нее особенная роль, вызванная следующей особенностью (читай проблемой) – в функцию onTabCreated совсем не сразу приходит вся информация о вкладке. Невооруженным глазом видно, как у новоиспеченной вкладки меняется заголовок, прогружается иконка. Эти данные позднее дотекают в функцию onTabUpdated.
Роль рабочей лошадки играет функция updateTab. Если первым параметром передать -1, то просто напросто создастся новая вкладка. В другом случае туда передается id вкладки, информацию о которой обновилась.
function updateTab(index, tab)
* This source code was highlighted with Source Code Highlighter .
Самая сложная часть позади, теперь немного о внешнем виде и popup.html? Интерфейс данного расширения – всплывающее окошко со списком сайтов, слева иконка для более интуитивного использования. Так же сверху имеется div класса toolArea – это область инструментов, пока там почетно красуется одна единственная кнопочка – очистка списка.
JavaScript’овая начинка данной странички достаточно типична и прозрачна, ключевой момент здесь – доступ к back.html, то бишь ко всем функциям и переменным, объявленным там, через вызов метода chrome.extension.getBackgroundPage().
- Создание списка
- Задание обработчиков mouseover и mouseout
- Реализация функций клика по элементу списка, а так же наведения курсора
var back = chrome.extension.getBackgroundPage() for ( var k = back.closedTabs.length - 1; k >= 0; k--) < document .write ( "<div > + back.closedTabs[k].id + "' onclick='divClick(this)' >" ) document .write ( "<img src #A31515">" >" ) var txtName = back.closedTabs[k].name if (txtName.length > 40) txtName = txtName.substr(0, 35) + ". " document .write ( "<span >" + txtName + "</span>" ) document .write ( "</div>" ) >
* This source code was highlighted with Source Code Highlighter .
var divs = document .getElementsByTagName( "div" ); for ( var i = 0; i < divs.length; i++)
* This source code was highlighted with Source Code Highlighter .
В определенный момент разработки подловил себя на мысли, что при создании новой вкладки в divClick с помощью функции chrome.tabs.create (которая, кстати, принимает объект аргументов, которые легче подсмотреть в документации, чем запоминать из статьи), вкладка автоматически попадает в onTabCreated, так что не нужно беспокоиться о добавлении в массив active вкладок, созданных программно!
Пишите предложения по улучшению! Пока только очевидным кажется сделать страницу опций с выбором количества вкладок максимального, но из-за одного такого пунктика страницу не хочется (читай ленюсь) создавать!