Написать приложение для браузера. Создаём своё расширение для Google Chrome. Добавление расширения в браузер
- Tutorial
На хабре уже есть несколько статей о создании расширений для хрома, поделюсь своим опытом, затронув основные вещи и места, в которых у меня возникли трудности.
Что понадобится для создания расширения в двух словах:
1) Базовые знания Javascript
2) Базовые знания HTML
3) 5$
Покажу создание расширения для хрома на примере своего, созданного для подсчета «потерянного времени» в интернете. То есть это расширение считает время, проведенное на сайтах с возможностью определения посещенных сайтов по категориям: полезное время, либо потерянное время.
Итак, я начинаю создание расширения с создания папки самого расширения, в которую будем класть все создаваемые нами файлы. Назову её «losttime». Далее, я создаю файл manifest.json, выглядит он следующим образом:
manifest.json
{
"manifest_version": 2,
"name": "Lost Time",
"version": "1.0",
"icons": {
"128": ""
},
"content_scripts": [
{
"matches": [ "*://*/*" ],
"js": [ "content.js" ]
}
],
"background": {
"scripts": ["background.js"]
},
"permissions": [
"http://losttime.su/*"
],
"browser_action": {
"default_title": "LostTime",
"default_icon": "",
"default_popup": "popup.html"
}
}
Некоторые из строк должны быть интуитивно понятны, но что обязательно нужно знать:
- Значение manifest_version должно быть обязательно «2»;
- В content_scripts пишем, какой скрипт будет запускаться на всех страницах отдельно;
- В background пишем общий скрипт(фоновый скрипт), который запускается при запуске браузера;
- В permissions пишем адрес сайта, с которого будет браться информация.
Все, что буду использовать я, не обязательно использовать Вам, если вам это по логике просто не нужно. .
То самое окошко, которое Вы можете видеть по клику на иконку расширения - это страница: popup.html.
Она у меня выглядит следующим образом:
popup.html
Потерянное время LostTime
Чтобы было понятнее, описание кода вставил в самом HTML. Меню я организую просто: на картинку ставлю внутреннюю ссылку расширения.
Раз уж начал про popup.html, то расскажу сразу и о popup.js
Выглядит он у меня весьма просто:
popup.js
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://losttime.su/?tmpl=login&token="+localStorage["lostlogin"], true); // тут происходит ГЕТ запрос на указанную страницу
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) // если всё прошло хорошо, выполняем, что в скобках
{
var dannie = document.getElementById("dannie");
dannie.innerHTML = xhr.responseText; // добавляем в блок с id=dannie полученный код
}
}
xhr.send();
Описание кода также вставил.
Именно описанная выше конструкция позволяет вытащить и вывести содержание с Вашего, а может и не с Вашего сайта. Но, что важно знать:
- В файле манифеста обязательно в поле permissions пишем адрес сайта, с которого будет браться информация.
- Файл popup.js связан с фоновым скриптом background.js, т.к. данные, занесенные в локальное хранилище на background.js, видны и на popup.js.
Перед тем, как рассмотреть файл фонового скрипта background.js, рассмотрим файл скрипта, который запускается на каждой странице отдельно: content.js
У меня он выглядит так:
content.js
function onBlur() { // окно теряет фокус
chrome.runtime.sendMessage({site:sait,time:localStorage}); // отправка сообщения на background.js
localStorage = "0";
}
window.onblur = onBlur; // если окно теряет фокус
function sec() //выполняется каждую секунду
{
if(document.webkitVisibilityState == "visible")//если страница активна
{
localStorage = parseInt(localStorage,10) +1; // обновляем данные о сайте в локальном хранилище
}
}
var sait=location.hostname; // на каком сайте находится скрипт
localStorage = "0";
setInterval(sec, 1000);// запускать функцию каждую секунду
Наиболее интересный момент из моего скрипта, я считаю, должен быть:
chrome.runtime.sendMessage({site:sait,time:localStorage});
Тут происходит отправка сообщения background скрипту, а именно две переменные: site:sait - содержит адрес сайта, на котором скрипт
time:localStorage - количество времени, проведенное на этом скрипте.
background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
var a = request.site; // данные о сайте
var b = request.time; // данные о проведенном времени
// тут делаем с этими данными что хотим.
});
Вот, собственно, и она. Разбирать подробно ничего не стану, т.к. это в принципе и не нужно. Достаточно знать наглядный пример, чтобы осуществить задуманное. Если в скрипте background.js добавить какие-либо данные в локальное хранилище(а также куки, web sql), то эти же данные можно будет использовать и в popup.js скрипте.
Вот собственно всё, что я хотел поведать о создании расширения, но я затрону еще один момент, в котором у меня возникли трудности.
На странице настроек мне необходимо было организовать перетаскивание сайтов в разные колонки.

Т.к. данные вставляются посредством InnerHtml, то данная возможность просто так не появится. Вот, что пришлось организовать:
$("#dannie").on("mouseover", ".sait", function() {
$(this).css({"border":"3px solid #ffffff"});
});
$("#dannie").on("mouseout", ".sait", function() {
$(this).css({"border":"3px solid black"});
});
$("#dannie").on("mousedown", ".sait", function() {
$(this).css({"border":"3px solid black"});
});
$("#dannie").on("mouseover", ".sait", function() {
$(".sait").draggable({
helper:"clone"
});
});
вместо привычного:
$(".sait").mouseover(function(){
$("#"+this.id).css({"border":"3px solid #ffffff"});
});
$(".sait").mouseout(function(){
$("#"+this.id).css({"border":"3px solid black"});
});
$(".sait").mousedown(function(){
$("#"+this.id).css({"border":"0px solid black"});
});
$(".sait").draggable({
helper:"clone",
});
- Разработка веб-сайтов ,
- JavaScript ,
- Google Chrome
- Tutorial
На хабре уже есть несколько статей о создании расширений для хрома, поделюсь своим опытом, затронув основные вещи и места, в которых у меня возникли трудности.
Что понадобится для создания расширения в двух словах:
1) Базовые знания Javascript
2) Базовые знания HTML
3) 5$
Покажу создание расширения для хрома на примере своего, созданного для подсчета «потерянного времени» в интернете. То есть это расширение считает время, проведенное на сайтах с возможностью определения посещенных сайтов по категориям: полезное время, либо потерянное время.
Итак, я начинаю создание расширения с создания папки самого расширения, в которую будем класть все создаваемые нами файлы. Назову её «losttime». Далее, я создаю файл manifest.json, выглядит он следующим образом:
manifest.json
{
"manifest_version": 2,
"name": "Lost Time",
"version": "1.0",
"icons": {
"128": ""
},
"content_scripts": [
{
"matches": [ "*://*/*" ],
"js": [ "content.js" ]
}
],
"background": {
"scripts": ["background.js"]
},
"permissions": [
"http://losttime.su/*"
],
"browser_action": {
"default_title": "LostTime",
"default_icon": "",
"default_popup": "popup.html"
}
}
Некоторые из строк должны быть интуитивно понятны, но что обязательно нужно знать:
- Значение manifest_version должно быть обязательно «2»;
- В content_scripts пишем, какой скрипт будет запускаться на всех страницах отдельно;
- В background пишем общий скрипт(фоновый скрипт), который запускается при запуске браузера;
- В permissions пишем адрес сайта, с которого будет браться информация.
Все, что буду использовать я, не обязательно использовать Вам, если вам это по логике просто не нужно. .
То самое окошко, которое Вы можете видеть по клику на иконку расширения - это страница: popup.html.
Она у меня выглядит следующим образом:
popup.html
Потерянное время LostTime
Чтобы было понятнее, описание кода вставил в самом HTML. Меню я организую просто: на картинку ставлю внутреннюю ссылку расширения.
Раз уж начал про popup.html, то расскажу сразу и о popup.js
Выглядит он у меня весьма просто:
popup.js
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://losttime.su/?tmpl=login&token="+localStorage["lostlogin"], true); // тут происходит ГЕТ запрос на указанную страницу
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) // если всё прошло хорошо, выполняем, что в скобках
{
var dannie = document.getElementById("dannie");
dannie.innerHTML = xhr.responseText; // добавляем в блок с id=dannie полученный код
}
}
xhr.send();
Описание кода также вставил.
Именно описанная выше конструкция позволяет вытащить и вывести содержание с Вашего, а может и не с Вашего сайта. Но, что важно знать:
- В файле манифеста обязательно в поле permissions пишем адрес сайта, с которого будет браться информация.
- Файл popup.js связан с фоновым скриптом background.js, т.к. данные, занесенные в локальное хранилище на background.js, видны и на popup.js.
Перед тем, как рассмотреть файл фонового скрипта background.js, рассмотрим файл скрипта, который запускается на каждой странице отдельно: content.js
У меня он выглядит так:
content.js
function onBlur() { // окно теряет фокус
chrome.runtime.sendMessage({site:sait,time:localStorage}); // отправка сообщения на background.js
localStorage = "0";
}
window.onblur = onBlur; // если окно теряет фокус
function sec() //выполняется каждую секунду
{
if(document.webkitVisibilityState == "visible")//если страница активна
{
localStorage = parseInt(localStorage,10) +1; // обновляем данные о сайте в локальном хранилище
}
}
var sait=location.hostname; // на каком сайте находится скрипт
localStorage = "0";
setInterval(sec, 1000);// запускать функцию каждую секунду
Наиболее интересный момент из моего скрипта, я считаю, должен быть:
chrome.runtime.sendMessage({site:sait,time:localStorage});
Тут происходит отправка сообщения background скрипту, а именно две переменные: site:sait - содержит адрес сайта, на котором скрипт
time:localStorage - количество времени, проведенное на этом скрипте.
background.js
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
var a = request.site; // данные о сайте
var b = request.time; // данные о проведенном времени
// тут делаем с этими данными что хотим.
});
Вот, собственно, и она. Разбирать подробно ничего не стану, т.к. это в принципе и не нужно. Достаточно знать наглядный пример, чтобы осуществить задуманное. Если в скрипте background.js добавить какие-либо данные в локальное хранилище(а также куки, web sql), то эти же данные можно будет использовать и в popup.js скрипте.
Вот собственно всё, что я хотел поведать о создании расширения, но я затрону еще один момент, в котором у меня возникли трудности.
На странице настроек мне необходимо было организовать перетаскивание сайтов в разные колонки.

Т.к. данные вставляются посредством InnerHtml, то данная возможность просто так не появится. Вот, что пришлось организовать:
$("#dannie").on("mouseover", ".sait", function() {
$(this).css({"border":"3px solid #ffffff"});
});
$("#dannie").on("mouseout", ".sait", function() {
$(this).css({"border":"3px solid black"});
});
$("#dannie").on("mousedown", ".sait", function() {
$(this).css({"border":"3px solid black"});
});
$("#dannie").on("mouseover", ".sait", function() {
$(".sait").draggable({
helper:"clone"
});
});
вместо привычного:
$(".sait").mouseover(function(){
$("#"+this.id).css({"border":"3px solid #ffffff"});
});
$(".sait").mouseout(function(){
$("#"+this.id).css({"border":"3px solid black"});
});
$(".sait").mousedown(function(){
$("#"+this.id).css({"border":"0px solid black"});
});
$(".sait").draggable({
helper:"clone",
});
Написать расширение для google chrome несложно. Но при написании первого раширения могут возникнуть (и возникают) вопросы. Большинство мануалов по написанию первого расширения расчитаны на использования манифеста первой версии, поддержка которого в скором будущем прекратится.
В этой статье будет рассмотрено:
- Как составлять манифест v.2
- Как работать с удаленными ресурсами
- Как работать с cookies
- Как работать с local storage
- Как работать с уведомлениями
К концу статьи у нас будет готово расширение-органайзер, в котором будет поле для добавления новой задачи, а так же список задач на текущий день. Обозначим все требования к органайзеру:
- Должен иметь поле для добавления события (дата, время, событие)
- Должен отображать все задачи на текущий день, отсортированные по времени
- Все прошедшие события должен отображать зачеркнутыми
- Должен иметь поле для ввода времени, за сколько надо показывать уведомление, а так же чекбокс разрешающий и запрещающий показывать уведомления
- За указанное время до события должен отображать уведомление о приближающемся событии
Начнем создавать расширение с самого начала, то есть с манифеста. Манифест – это тот самый файл, в котром прописываются все параметры расширения. Название, описание, версия, разрешение на доступ к сайтам, разрешение на использование кук, уведомлений, локального хранилища. В общем, манифест – это мозг расширения. Создаем файл manifest.json. Манифест – единственный файл, который должен иметь заранее предопределенное имя, все остальные файлы можно будет называть как угодно. В этом файле есть три обязательных поля:
manifest.json
{ “name”: “Organizer extension”, // Название расширения “version”: “1.0”, // Версия расширения. “manifest_version”: 2 // Версия манифеста }
Тут есть пара правил:
- Версия манифеста должна быть целочисленной, то есть должна писаться как 2, а не “2”.
- Версия расширения должна быть строковой, но содержать только числа и точки, то есть “1.0” - хорошо, а 1.0 и “0.9 beta” - плохо.
С обязательными полями – все, перейдем к созданию всплывающего окна расширения. Для того, чтобы по нажатию на пиктограмму, открывалось окно, необходимо добавить в манифест поле “browser_action”
manifest.json
{ … "browser_action": { "default_title": "Open organizer", // Заголовок. Его видно если навести курсор на иконку в браузере "default_icon": "icon_small.png", // Путь к иконке расширения "default_popup": "popup.html" // Путь к странице с попапом } }
Теперь создадим всплывающее окно. Это обычная html страница, которая может быть любого размера и цвета, никаких фокусов. Назовем файл “popup.html”. Создать этот файл мало – его надо указать в манифесте. Так мы и сделали: «default_popup»: «popup.html».
popup.html
It works!
Добавление расширения в браузерТеперь пришло время проверить работоспособность нашего расширния. Для этого загрузим расширение в браузер. Открываем в хроме меню расширений. Ставим птицу на “Developer mode”.
После этого появятся три кнопки. Нажимаем “Load unpacked extension...”. Выбираем папку с файлами расширения. После этого появится наше расширение. Если все правильно, то по нажатию на иконку – повится окно:
Теперь можно приступить к интересному. Подключим два javascript файла. Первый – popup.js, второй – jquery. С первым проблем не возникнет, но jquery будем подключать не локальный, а удаленный, взятый по адресу ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js . Проблемы возникнут от того, что по умолчанию расширение не имеет доступа к сторонним ресурсам. Чтобы получить доступ, надо его указать в манифесте. Доступ к чему-либо указывается в поле “permissions”. Так же, для удаленных скриптов и css надо указывать доступные удаленные ресурсы.
manifest.json
{ … "permissions": [ "https://ajax.googleapis.com/*" ], "content_security_policy": "script-src "self" https://ajax.googleapis.com; object-src "self"" }
Теперь подключим эти скрипты в popup.html
popup.html
StorageПри помощи storage в хроме можно хранить пользовательские данные. И именно в storage наше расширение и будет хранить грядущие события. На то есть две причины. Во-первых, данные, хранищиеся в storage можно синхронизировать, если залогиниться в браузере. А во-вторых, данные можно хранить не только в виде строки, как в cookies, а в любом виде, то есть можно хранить и массивы и объекты. Чтобы это заработало, откроем доступ к storage в манифесте.
manifest.json
{ ... "permissions": [ … "storage" ] ... }
Теперь переделаем всплавающее окно. Во всплывающем окне будет поле с сегодняшней датой, три инпута для даты, времени и описания нового события, кнопка для добавления нового события, а так же список всех событий на сегодня.
popup.html
Date
| Дата | Время | Задача |
И сразу же добавим отображение даты в блоке #today_date.
popup.js
$(function(){ var today = new Date(); $("#today_date").html(today.getDate()+"."+(parseInt(today.getMonth())+1)+"." + today.getFullYear()); }
Выглядеть должно так:
Итак, при нажатии на кнопку “+” у нас должно добавляться событие. Вначале файла объявим глобальную переменную storage – объект для работы с storage, а так же глобальный массив tasks для хранения событий.
popup.js
Var storage = chrome.storage.sync; var tasks = new Array(); $(function(){ … $("#add_task").click(function(){ var new_task = new Object(); new_task.date = validateField($("#new_date").val(), "date"); new_task.time = validateField($("#new_time").val(), "time"); new_task.task = $("#new_task").val(); if(!new_task.task || !new_task.date || !new_task.task){ return false; } tasks = new_task; storage.set({ tasks:tasks }); }); });
Функция валидации проверяет, что дата записана в формате d.m.yyyy, а время в формате hh:mm, а так же, что в описании события не меньше трех символов.
popup.js
Var validateField = function(val, type){ if(type == "date"){ var date = val.split("."); var year = new Date(); year = year.getFullYear(); if(date.length == 3 && parseInt(date) == date && date = 3){ return val; } return null; }
С добавлением разобрались, переходим к получению событий на сегодня. Для этого надо получить все события из базы, выбираем из всех только сегодняшние события и сортируем их по времени по возрастанию.
popup.js
$(function(){ … var now_hours = today.getHours() < 10 ? "0" + today.getHours() : today.getHours(); var now_minutes = today.getMinutes() < 10 ? "0" + today.getMinutes() : today.getMinutes(); var now_time = now_hours + "" + now_minutes; storage.get("tasks",function(items){ if(items.tasks){ tasks = items.tasks; var today_tasks = getTodayTasks(tasks); if(today_tasks.length >0){ for(var i in today_tasks){ var this_time = today_tasks[i].time.replace(":", ""); var add = this_time > now_time ? "" : " class="done""; var add_html = ""+today_tasks[i].time+" "+today_tasks[i].task+""; $("ul").append(add_html); } } } }); … });
Функция getTodayTasks() возвращает из общего списка только события с сегодняшней датой.
popup.js
Var getTodayTasks = function(tasks){ var today_tasks = new Array(); var today = new Date(); var today_date = today.getDate()+"."+(today.getMonth() + 1)+ "." + today.getFullYear(); for(var i in tasks){ if(tasks[i].date == today_date){ today_tasks = tasks[i]; } } if(today_tasks.length > 0){ today_tasks = sortTasks(today_tasks); } return today_tasks; }
Функция sortTasks() сортирует события по возрастанию времени.
popup.js
Var sortTasks = function(tasks){ if(tasks.length > 0){ var swapped = true; while (swapped) { swapped = false; for (var i=0; i < tasks.length-1; i++) { var this_time = tasks[i].time.replace(":", ""); var next_time = tasks.time.replace(":", ""); if (this_time > next_time) { var temp = tasks[i]; tasks[i] = tasks; tasks = temp; swapped = true; } } } } return tasks; }
УведомленияПришло время настроить отображение уведомлений на экране. Добавим во всплывающее окно специальный чекбокс. Если этот чекбокс будет отмечен – уведомлениея будут показываться, если не будет отмечен – не будут. Так же добавим текстовый инпут. Цифра в этом инпуте будет показывать, за какое время до событя будет показываться уведомление. То есть если у нас событие назначено на 19:00, в этом текстовом инпуте будет 5, значит в 18:55 появится уведомление. Добавим в popup.html код с этими инпутами
popup.html
Показывать уведомления
Теперь давайте разберемся с тем, как это будет работать. При нажатии на чекбокс, будет проверяться его атрибут checked, значение атрибута будет записываться в cookie “show_notifications”. Перейдем к текстовому инпуту. По изменению его значения, новое значение будет валидироваться, если оно целочисленное и не больше 120, записываем новое значение в cookie “when_to_notify”.
Но для того, чтобы у нас это заработало, надо открыть доступ к cookies. Для этого заходим в manifest.json и добавляем в “permissions”
manifest.json
{ ... "permissions": [ … “cookies” ] ... }
Теперь можно приступать к скрипту. Заходим в popup.js. Для начала установим первоначальные значения в инпутах. По-умолчанию чекбокс не отмечен, то есть уведомления не показываются, а время равно 0. При клике на чекбокс, будет меняться значение cookie “show_notifications”. При изменении значения в тектовом поле, будет меняться значение cookie “when_to_notify”.
popup.js
$(function(){ setCheckbox(); setWhenToNotify(getCookie("when_to_notify")); ... $("#show_notifications").click(function(){ setCookie("show_notifications", document.getElementById("show_notifications").checked); }); $("#when_to_notify").change(function(){ setWhenToNotify($(this).val()); }); });
Рассмотрим подробнее функции. Начнем с функций работы с cookies. В данном случае были взяты готовые функции с w3schools.com.
popup.js
Var setCookie = function(c_name,value,exdays){ /* *Взято с http://www.w3schools.com/js/js_cookies.asp */ var exdate=new Date(); exdate.setDate(exdate.getDate() + exdays); var c_value=escape(value) + ((exdays==null) ? "" : "; expires="+exdate.toUTCString()); document.cookie=c_name + "=" + c_value; } var getCookie = function(c_name){Позвонить Васе П. /* *Взято с http://www.w3schools.com/js/js_cookies.asp */ var i,x,y,ARRcookies=document.cookie.split(";"); for (i=0;i= 20. В манифесте (manifest.json) нужно написать следующее:
"premissions": [ "storage" ]
Как пишут в google group "Chromium HTML5", "I turned my attention to Web SQL Database but it seems Web SQL is no longer in "active maintenance" which leads me to believe that it will be dropped from HTML spec". См. подробнее W3C Web SQL Database, note. Можно попробовать использовать Basic concepts - для расширения места под базу можно использовать permissions: unlimitedStorage в manifest.json. Для использования "Unlimited storage" есть следующие Offline APIs: 1) App Cache; 2) File System; 3) IndexedDB; 4) WebSQL (deprecated). Пример использования IndexedDB в Chrome см. . Пример работы с IndexedDB см. на gist.github.com:
window.indexedDB = window.indexedDB || window.webkitIndexedDB; var req = indexedDB.open("my db") req.onerror = function() { console.log("error"); }
Расположение файлов IndexedDB,
Windows: C:\Users\\AppData\Local\Google\Chrome\User Data\Default\IndexedDB,
Linux: /home//.config/google-chrome/Default/IndexedDB/chrome-xxx.indexeddb.leveldb/:
$ sudo ls -la /home/anonymous/.config/google-chrome/Default/IndexedDB/chrome-extension_ojeihbjghbabiocoglbfhdebhhckdnol_0.indexeddb.leveldb/ total 24 drwx------ 2 anonymous anonymous 4096 Фев 7 03:08 . drwx------ 3 anonymous anonymous 4096 Фев 7 03:08 .. -rw-r--r-- 1 anonymous anonymous 285 Фев 7 03:08 000003.log -rw-r--r-- 1 anonymous anonymous 16 Фев 7 03:08 CURRENT -rw------- 1 anonymous anonymous 0 Фев 7 03:08 LOCK -rw-r--r-- 1 anonymous anonymous 46 Фев 7 03:08 LOG -rw-r--r-- 1 anonymous anonymous 32 Фев 7 03:08 MANIFEST-000002
Можно посмотреть на примеры использования IndexedDB в Mozilla Developer Network.
Вставка большого числа записей в IndexedDB рассмотрена на stackoverflow.com.
Для добавления элементов в IndexedDB, надо использовать
indexedDB.db.transaction().objectStore().put({})
В папке базы IndexedDB-данных старые базы хранятся как.sst-файлы, а новые (текущие) - как.log-файлы.
setVersion() is Deprecated. Но тут есть одна хитрость [про onupgradeneeded()]: ...
Как сказано в блоге Parashuram Narasimhan, "For Chrome: In case of chrome, the onupgradeneeded function is not called. The database"s onsuccess function is called. Here, the existence of the setVersion method is checked. If the method exists, and the specified version is greater than the database version, a the setVersion method is called. The onsuccess of the setVersion"s request call invokes the user"s onupgradeneeded method with the version transaction. Once the method completes, the versionTrasnaction is committed by closing the database. The database is opened again with the latest version and this is passed to the onsuccess defined by the user." (поэтому для вызова onupgradeneeded(), я делаю db.setVersion("3")).
Как делать выборку данных в content.js:
dbreq.onupgradeneeded = function(event) { console.log("dbreq.onupgradeneeded"); var db = event.target.result; var tx = db.transaction(["test_db"], "readonly"); var store = tx.objectStore("todo");
Для открытия базы, используйте код от axemclion+jepp (функцию openReqShim).
Когда открываем IndexedDB-базу, которая не существует, она создаётся (will be created) с номером версии, version = 0. При этом, вызываются onupgradeneeded() и onsuccess() последовательно. При первом вызове onupgradeneeded(), version уже = 1. Когда открываем второй раз [существующую базу], onupgradeneeded() уже не вызывается, а номер версии = 1. (?не увеличивается) Вызывается только dbreq.onsuccess().
Ещё один момент. Тут сказано, что "With Chrome prior to 23 you need to create such a transaction manually by calling setVersion() - an API that has been removed from the spec. The older spec can be found at: http://www.w3.org/TR/2011/WD-IndexedDB-20110419/", то есть для того чтобы не было ошибки "NotFoundError: DOM IDBDatabase Exception 8" в логах хрома, требуется вызвать setVersion().
В Chromium 6.0.472.63 (59945) реализация IndexedDB не является stable, поэтому отключена и не работает =)
В общем, надо использовать background.js + iframe + обмен с контент-скриптами через messages
Как отрабатывать событие об открытии страницы?"content_scripts": [ { "matches": [ "*://*/*" ], "js": [ "content.js" ], "run_at": "document_start" } ], ...
Content.js:
document.addEventListener("DOMContentLoaded", function () { alert("Abc "+document.location.href); });
Как оформлять HTML-код страницы? См. написание расширений Firefox . Как упаковать расширение, и где его расположить?Чтобы расположить расширение на Chrome WebStore, нужно заплатить гуглю вступительный взнос 5$ (затем можно будет помещать любое количество расширений). Заплатить можно через VISA, MasterCard, AMEX или DISCOVER (дополнительно, при оплате, надо указать свой полный почтовый адрес и Имя-Фамилию).
Для размещения расширения нужен Google-аккаунт, и далее. Там понадобятся скриншот и рекламная картинка. Обновлять код расширения надо будет вручную, через тот же Chrome WebStore (как я понял, тут нет автоматического обновления по URL, как в Firefox). В файле manifest.json нужно обновить версию расширения. Спустя несколько минут после добавления, расширение будет доступно в поиске по расширениям Chrome.
Упаковка расширения под Linux:
#!/bin/bash 7z a -tzip ../domainck-chromium.zip ./* mv ../domainck-chromium.zip ../domainck-chromium.crx
Ключевые слова: Chromium builds for windows HOWTO, Google Chrome download page, Google Chrome sample extensions.
В интернете много сайтов на которых реализована возможность пролистывать страницу вверх без помощи мыши или полосы прокрутки. Но в то же время еще есть сайты где такой реализации нет. "Почему бы не попробовать написать скрипт который бы добавлял такую кнопку на все сайты?" - подумал я и принялся за реализацию. Такие скрипты называются пользовательскими и имеют расширение *.user.js . Почитать к примеру можно на хабре . К сожалению без "подводных камней" не обходится. Существуют некоторые различия в реализации userjs под разные браузеры. Я остановлюсь на описании реализации нашего userjs скрипта как расширения для браузера Google Chrome .
manifest.jsonОбязательным для расширения Google Chrome является файл manifest.json в котором описываются параметры, пути к внешним файлам (*.js, *.css и др.), поддержка версии и т.п. для расширения. Подробнее о файле можно почитать . В нашем случае файл manifest.json выглядит следующим образом:
{ "manifest_version": 2, "content_scripts": [ { "exclude_globs": , "include_globs": [ "*" ], "js": [ "jquery.js", "backTopUserJS.user.js" ], "css": [ "css/style.css" ], "matches": [ "http://*/*", "https://*/*" ], "run_at": "document_end" } ], "converted_from_user_script": true, "description": "Back top userscript extension for google chrome", "name": "backTopUserJS", "version": "1" }
Для удобства мы используем библиотеку JQuery которую положили рядом с файлом manifest.json и основным файлом скрипта (в нашем случае это backTopUserJS.user.js). Его содержимое следующее:
// ==UserScript== // @name backTopUserJS // @author Aleksandr Filatov // @license MIT // @version 1.0 // ==/UserScript== function main() { var disp = $(window).scrollTop() > 400 ? "block" : "none"; var $upButton = $("
"); $(document).find("body").append($upButton); $upButton.click(function () { $("html, body").animate({ scrollTop: 0 }, "slow"); }); $(window).scroll(function () { if ($(window).scrollTop() > 400) $upButton.fadeIn("slow"); else $upButton.fadeOut("slow"); }); }; var script = document.createElement("script"); script.appendChild(document.createTextNode("("+ main +")();")); (document.body || document.head || document.documentElement).appendChild(script);
Думаю скрипт достаточно понятен, чтобы его подробно рассматривать. Пояснить стоит лишь последние 3 строчки. На самом деле это мелкий хак, который вставляет наш скрипт в код страницы сайта. Если кто-то из вас найдет способ лучше можете написать к комментах свои фиксы:)
Установка расширения в браузереВ Google Chrome можно устанавливать пользовательские скрипты, аналогично другим браузерам, но поскольку Google печется о нашей с вами безопасности, то их приходится оборачивать в расширения для браузера. Разберем установку по шагам.
Создаем папку для нашего расширения например так C:\MyChromeExtensionUserJS
Для каждого расширения создаем свою директорию например в нашем случае назовем ее так C:\MyChromeExtensionUserJS\backTopUserJS . Добавляем файлы расширения в эту директорию.
Заходим "О браузере Google Chrome" -> вкладка "Расширения" или в адресной строке пишем chrome://extensions/
Ставим галочку "Режим разработчика"
Нажимаем кнопку "Загрузить распакованное расширение" и выбираем директорию нашего расширения. Нажимаем "OK".
Расширение установлено и готово к работе. Чтобы обновить расширения после того как вы внесли в него изменения достаточно просто нажать кнопку "Обновить расширение" или в режиме разработчика сочетание клавиш Ctrl+R .
ИтогПосмотреть исходники скрипта можно на github . Скрипт не претендует на звание идеального, а служит лишь примером и толчком к написанию собственных пользовательских скриптов для Google Chrome .


