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

Что понадобится для создания расширения в двух словах:
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.

2eb94202ab82e4302d71541baf336348

Она у меня выглядит следующим образом:

popup.html

<!doctype html>
<html>
  <head>
    <title>Потерянное время LostTime</title>
        <script src="jquery.js" type="text/javascript"></script> <!-- Подключаю jquery -->
    <link href="css.css" rel="stylesheet" type="text/css"/><!-- Подключаю стили-->
  </head>
  <body>
  <div id="options"><!-- меню -->
<a  href="/popup.html"><img class='img' src="" Title = "Короткая статистика за сегодня"></a>
<a href="/options.html"><img class='img' src="images/options.png" Title="Настройки программы"></a>
<a href="/stat.html"><img class='img' src="images/stat.png" Title="Подробная статистика о посещаемости"></a>
</div>
<div id="dannie"></div> <!-- в этот блок буду загружать данные, которые будут показываться пользователю-->
    <script src="popup.js"></script><!-- скрипт, выполняющийся при нажатии на иконку расширения-->
  </body>
</html>

Чтобы было понятнее, описание кода вставил в самом 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[sait]}); // отправка сообщения на background.js
    localStorage[sait] = '0';	
}
    window.onblur = onBlur; // если окно теряет фокус
    function sec() //выполняется каждую секунду
    { 
      if(document.webkitVisibilityState == 'visible')//если страница активна
        {
           localStorage[sait] =  parseInt(localStorage[sait],10) +1; // обновляем данные о сайте в локальном хранилище
        }
    }			 	
var sait=location.hostname; // на каком сайте находится скрипт
localStorage[sait] = '0';
    setInterval(sec, 1000);// запускать функцию каждую секунду

Наиболее интересный момент из моего скрипта, я считаю, должен быть:
chrome.runtime.sendMessage({site:sait,time:localStorage[sait]});
Тут происходит отправка сообщения background скрипту, а именно две переменные: site:sait — содержит адрес сайта, на котором скрипт
time:localStorage[sait] — количество времени, проведенное на этом скрипте.

Далее, рассмотрим фоновый скрипт background.js, где и происходит приём данных, а точнее рассмотрим саму функцию приёма данных.

background.js

chrome.runtime.onMessage.addListener(
  function(request, sender, sendResponse) {
var a = request.site; // данные о сайте
var b = request.time; // данные о проведенном времени
// тут делаем с этими данными что хотим.
  });

Вот, собственно, и она. Разбирать подробно ничего не стану, т.к. это в принципе и не нужно. Достаточно знать наглядный пример, чтобы осуществить задуманное. Если в скрипте background.js добавить какие-либо данные в локальное хранилище( а также куки, web sql), то эти же данные можно будет использовать и в popup.js скрипте.

Вот собственно всё, что я хотел поведать о создании расширения, но я затрону еще один момент, в котором у меня возникли трудности.

На странице настроек мне необходимо было организовать перетаскивание сайтов в разные колонки.

6e3132f2190d273419e1eda223d09277

Т.к. данные вставляются посредством 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',
    });

Думаю, объяснять не нужно. Почитать подробнее можете по ссылке

Тестирование расширения

Заходим в Настройки — Инструменты — Расширения, жмем на «Загрузить распакованное расширение»

Публикация расширения
Заходим на страницу оплачиваем 5$, публикуем.
Я не останавливаюсь на моментах, с которыми у меня не возникли трудности. А трудности возникли при оплате карточкой:
— В моём случае должен быть подключен 3д пароль.
Если Вам при оплате пишет ошибку, звоните своему банку и узнавайте. Мне за минуту помогли и всё гуд.

Источники:
Документация
Об отправке сообщений
О манифесте
Форум javascript

А также само расиширниеae7da0daa725de6cef3e2773912d18a5.

Спасибо за прочтение. Всем удачи.