Расширение для хрома на js. Как написать расширение для Google Chrome, Chromium (crx). Собираем расширение для Google Chrome

Эта статья предназначена для администраторов Chrome Enterprise и разработчиков, имеющих опыт создания пакетов приложений Chrome и их публикации.

Если в Интернет-магазине Chrome не оказалось продукта с нужной вам функциональностью, вы можете создать собственное приложение или расширение, а пользователи смогут добавить его на свои устройства с Chrome OS или в браузер Chrome. Например, как администратор, вы можете автоматически установить на устройствах пользователей частное приложение-закладку, ссылающееся на веб-сайт отдела кадров.

Подготовка
  • Если в файле манифеста указан целевой сайт, на который ссылается приложение или расширение, подтвердите право собственности на этот сайт .
  • Если приложение или расширение размещено на частном сервере, можно указать, кто имеет право публиковать его в Интернет-магазине Chrome. Вы можете отключить подтверждение права собственности на сторонние сайты, на которые ссылается приложение.
Шаг 1. Создайте приложение или расширение

Ниже в качестве примера используется приложение-закладка. Инструкции по созданию более сложных приложений и расширений Chrome приведены в руководстве по началу работы .

  • Создайте на компьютере папку, в которой будут храниться файлы приложения или расширения. Присвойте ей имя приложения.
  • Создайте файл манифеста.
  • Создайте в текстовом редакторе файл JavaScript ® Object Notation (JSON). Посмотрите пример файла JSON для приложения-закладки.
  • Проверьте, правильно ли отформатирован код в файле JSON, с помощью специального инструмента, например JSONLint .
  • Поместите файл manifest.json в папку приложения или расширения.
  • Создайте логотип.
  • Изображение должно иметь размер 128 х 128 пикселей.
  • Сохраните файл логотипа под названием 128.png в папке приложения.
  • Шаг 2. Протестируйте приложение или расширение

    Разработчики могут тестировать свои приложения и расширения в браузере Chrome или на устройствах Chrome OS.

    Чтобы устранить неполадки в приложении или расширении, воспользуйтесь журналами Chrome.

    Шаг 3. Создайте коллекцию приложений (необязательно)

    Администратор может создать для организации коллекцию приложений, чтобы рекомендовать пользователям приложения и расширения Chrome для установки.

    Шаг 4. Опубликуйте приложение или расширение в Интернет-магазине Chrome

    Разработчик может сделать приложение или расширение общедоступным либо ограничить доступ к нему. При публикации в Интернет-магазине Chrome можно выбрать один из трех вариантов.

    • Общедоступное : кто угодно может найти и установить приложение.
    • Доступ по ссылке : установить приложение или расширение можно только по ссылке. Оно не включается в результаты поиска в Интернет-магазине Chrome. Ссылку можно отправить пользователям как в домене организации, так и за его пределами.
    • Частное : найти и установить приложение или расширение могут только пользователи в вашем домене. Кроме этого, можно предоставить доступ к продукту только доверенным тестировщикам, чьи имена указаны в панели инструментов разработчика.

    Чтобы добавить приложение или расширение в Интернет-магазин Chrome, создайте ZIP-архив соответствующей папки, а затем опубликуйте продукт .

    Шаг 5. Настройте правила работы с приложением или расширением

    В панели администратора Google можно управлять использованием приложений и расширений на устройствах Chrome и в браузере Chrome на компьютерах Windows, Mac и Linux в вашей организации. Правила Chrome можно настраивать

    Все элементы в магазине Chrome Web Store делятся на приложения и расширения. Мы сделаем и то, и другое. Созданное нами приложение будет отображаться в виде значка на новой вкладке браузера и даст возможность быстро запустить ваш сайт. Расширение представляет собой специальную кнопку на панели инструментов, щелчок по которой вызовет появление панели с последними обновлениями сайта.

    Собираем приложение для Google Chrome

    1. Скачиваем архив с шаблоном расширения по этой ссылке .

    2. Разархивируем в любое удобное вам место. Внутри находится файл manifest.json и иконка icon.png .

    3. Открываем файл manifest.json в блокноте и редактируем его содержимое. Вам необходимо в строке 2 ввести имя своего сайта, в строке 3 — его описание (до 132 символов), в строке 5 и 7 — адрес сайта. Сохраняем сделанные изменения.

    4. Меняем иконку из архива на свое изображение в формате PNG, размером 128*128.

    Собираем расширение для Google Chrome

    Хотя расширение функционально существенно отличается от приложения, алгоритм его сборки не намного сложнее.

    1. Получаем заготовку расширения по этой ссылке .

    2. Разархивируем. Открываем в блокноте файл manifest.json и вставляем название своего сайта, его краткое описание и заголовок окна расширения (строки 2, 3 и 8).

    3. Открываем файл labnol.js и указываем адрес RSS потока своего сайта.

    4. Заменяем иконку из архива на свое изображение в формате PNG размером 128*128.

    Публикация

    Сделанные нами расширение и приложение можно использовать двумя способами. Если вы владелец сайта и хотите привлечь на него дополнительных пользователей, то можно опубликовать свои работы в Chrome Web Store. Для этого запаковываем файлы расширения и дополнения каждое в свой архив, идем на страницу Chrome Dashboard и загружаем свои работы в магазин Google. Здесь вас попросят загрузить скриншот, дать расширенное описание и указать некоторые другие параметры. Страница на русском языке, так что вы без труда разберетесь. Обратите только внимание, что для публикации расширения вы должны быть подтвержденным владельцем сайта, для которого сделали расширение. Кроме этого, от вас потребуется вступительный взнос в размере 5$ за публикацию.

    Если вы собрали расширения только для личного использования, например чтобы удобно следить за обновлениями любимого сайта, то просто откройте в браузере страницу расширений и включите Режим разработчика. Затем нажмите кнопку Загрузить распакованное расширение и укажите путь к папке с файлами.

    С помощью предложенного метода любой владелец сайта или блога сможет создать и разместить в каталоге расширений браузера Google Chrome фирменное расширение для своего ресурса. Это поможет посетителям быть всегда в курсе последних обновлений, что приведет дополнительных посетителей на ваш сайт и увеличит его популярность.

    23 октября 2013 в 13:21 Создаём своё расширение для Google Chrome
    • Разработка веб-сайтов ,
    • 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 (далее Хром).

    Расширение, которое мы будем разрабатывать на протяжении всей статьи можно найти в магазине Google Chrome Web Store , с той лишь разницей, что там присутствует расширенный функционал. Помимо этого, присутствует исходный код на GitHub , опять таки с оговоркой на то, что там всё написано на CoffeeScript , а здесь будет вестись повествование с JavaScript. Кстати, я не поклонник и не сторонник CoffeeScript, но штука довольно интересная и полезная - советую попробовать.

    Если вы когда-нибудь рассматривали идею создания расширения для Chrome, Firefox, Maxthon и прочих браузеров, то, наверное, уже успели заметить, что минимум усилий нужно приложить как раз таки для Хрома. Убедиться в этом можно, взглянув на документацию у соответствующих браузеров.

    Постановка задачи

    Написание расширения начинается с его описания и постановки задач, которое оно будет решать. Так как я сам себе хозяин и дедлайны срывать мне можно столько раз, сколько хочется, то ТЗ мне писать не нужно - достаточно уяснить, что:

    • Расширение должно скрывать все комментарии в социальной сети «VK»;
    • Расширение должно иметь возможность отображать комментарии;
    • Расширение должно иметь возможность отображать комментарии на конкретных страницах;

    С первого взгляда всё просто и нам по силам. Однако, в рамках статьи мы реализуем лишь первые два пункта.

    Предвижу вопросы, содержание которых может быть примерно таким: «Нафига скрывать комментарии, если в этом вся суть социальной сети?!». Что же, справедливый вопрос, заслуживающий развёрнутого ответа:

    Так сложились обстоятельства, что последнее время, когда я вижу комментарии в VK, мне хочется дарить горы фейспалмов комментаторам. Я подписан на большое количество различных пабликов, тематических (веб-разработка) и не очень. И как бы это не казалось странным, самым щедрым я становлюсь именно в группах с интересным для меня содержанием, а не котиками (в моём случае с пандами). Такого количества непрофессионального и безобразного потока информации в комментариях я не видел ещё нигде, да ещё и спорить думают. Помимо этого, комментарии в новостной ленте смотрятся не эстетично. В общем, сказано - сделано.

    Каркас расширения

    Наиприятнейшим для меня сюрпризом стало то, что в самом начале пути нас встречает описательный характер действий. Проще говоря, нам нужно описать наше приложение, его права и возможности - для этого служит файл manifest.json .

    Первым делом нужно заполнить три обязательных поля:

    { "manifest_version": 2, // Начиная с Chrome 18 ставим 2, иначе 1 (не поддерживается такое старьё) "name": "My Extension", // Название расширения "version": "versionString" // Версия расширения }

    Если с названием всё понятно, а с версией манифеста всё ещё проще, то поподробнее нужно остановиться с версией расширения.

    Итак, все мы привыкли, что версия чего-либо состоит из трёх чисел, разделённых точками - Мажорное.Минорное.Патч (Имеется в виду число). С npm, bower и прочими прелестями разговор короткий: либо так, либо никак. А вот Google предлагает следующие варианты:

    "version": "1" "version": "1.0" "version": "2.10.2" "version": "3.1.2.4567"

    Подробнее обо всех полях файла манифеста можно узнать из документации .

    В нашем случае, файл манифеста будет выглядеть следующим образом:

    { "manifest_version": 2, "name": "__MSG_app_name__", "short_name": "VKCommentBlocker", "description": "__MSG_app_description__", "version": "0.1.0", "default_locale": "ru", "permissions": [ "activeTab" ], "browser_action": { "default_icon": "icon_16.png", "default_title": "__MSG_browser_action__" }, "icons": { "16": "icon_16.png", "48": "icon_48.png", "128": "icon_128.png" }, "background": { "persistent": false, "page": "background.html" }, "content_scripts": [ { "matches": [ "http://vk.com/*", "https://vk.com/*" ], "css": [ "styles/commentblocker.css" ] } ], "web_accessible_resources": [ "styles/commentblocker_on.css" ] }

    Из того, что ранее не рассматривалось

    • __MSG_key__ - это вариация Chrome на тему интернационализации приложений (i18n). Можно применять как в файле манифеста, так и в других файлах (даже CSS).
    • web_accessible_resources - массив путей ресурсов, которые будут впоследствии использоваться в контексте веб-страниц. Без указания в нём пути - ничего не получится использовать на страницах сайтов, если такое поведение предполагается.
    Ресурсы расширения

    Огромный плюс в карму Chrome - мы уже сейчас можем подключить расширение, конечно, если созданы все ресурсы, указанные в manifest.json .

    Не думаю, что стоит заострять внимание на том, что содержится в файле commentblocker.css и commentblocker_on.css . Приведу лишь первый, в котором указаны все селекторы, в которых заключены комментарии:

    @charset "utf-8"; .wall_module .reply_link_wrap .reply_link { visibility: hidden !important; } .wall_module .replies_wrap, #wl_replies_wrap, #wl_reply_form_wrap, #mv_comments_wrap, #mv_your_comment, #pv_comments, #pv_comments_header, #pv_your_comment { display: none !important; visibility: hidden !important; } body:after { position: fixed; content: "__MSG_mode_enable__"; top: 5px; right: 5px; padding: 6px 12px; background-color: #ffc; border: 1px solid #ddd; z-index: 9999; }

    В файле commentblocker_on.css , как не трудно догадаться, всё наоборот. Обратите внимание, что прямо в CSS я использую строку с языковом ключом content: "__MSG_mode_enable__" . Самое время создать такой файл, где эти ключи будут храниться.

    В корне нашего расширения создаём директорию _locales и вложенные в неё директории en и ru . Далее в файле messages.json описываем наши ключи.

    { "app_name": { "message": "VK Comment Blocker" }, "app_description": { "message": "Удобный способ скрыть комментарии в новостной ленте и группах." }, "browser_action": { "message": "Переключить вид комментариев" }, "mode_enable": { "message": "Без комментариев!" }, "mode_disable": { "message": "С комментариями!" } }

    Помимо поля message есть и другие поля, о которых можно узнать из документации .

    Теперь создаём файлы background.html , для начала так:

    Background

    Тут всё так, как в обычном HTML - ничего необычного. Кстати, файл background.html можно не создавать, так как он генерируется автоматически, на основе полей в manifest.json .

    Запускаем расширение

    Запустить расширение можно, не написав ни одной строчки JavaScript. Чтобы сделать это, нужно пройтись по меню:

    • Настройка и управление Google Chrome (Гамбургер)
    • Дополнительные инструменты
    • Расширения
    • Поставить галочку напротив «режим разработчика»
    • Загрузить распакованное расширение
    • Выбрать папку с расширением

    Расширение загрузилось и показалось в меню. Да, да, это вот это вот «В».

    Казалось бы, у только что созданного нами расширения ничего нет в голове (нет никакой логики), а все комментарии на страницах социальной сети на букву «В» теперь скрыты. Ответ кроется в manifest.json , где в поле "content_scripts": {} мы указали на каких страницах (http://vk.com/* и https://vk.com/*) будет автоматически подключаться файл commentblocker.css , который и скрывает все комментарии. Советую подробнее почитать про mathes patterns . Он лишь с виду так прост, а под капотом чуть ли не сивый мерин, да с прибамбасами.

    Вот так, не написав ни одной строчки кода, у нас уже получилось расширение, выполняющее основную возложенную на него задачу.

    Оживляем расширение

    Осталось выполнить второй пункт задачи, а именно реализовать возможность отображения комментариев. Вкратце, нам нужно запихнуть файл commentblocker_on.css , который отменит правила файла commentblocker.css . И тут к нам на помощь спешит наш всемогущий JavaScript.

    Помните, что я говорил про background.html ? Да, да, про то, что его можно не создавать. Давайте слегка изменим manifest.json:

    ... "background": { "persistent": false, "scripts": [ "scripts/commentblocker.js" ] }, ...

    Просто подключили JavaScript файл. Ничего особенного. Переходим к этому файлу.

    Просто так запихнуть JS на страницу нельзя. И такая же проблема имеется не только со скриптами. Поэтому нам нужно воспользоваться специальной инъекцией executeScript .

    Сначала нужно добавить обработчик события клика на иконку расширения:

    Chrome.browserAction.onClicked.addListener(function(tab) { chrome.tabs.executeScript(tab.id, { code: "(" + toggleComments.toString() + ")();" }); });

    Где toggleComments - это функция, которая и будет производить инъекцию нашего CSS файла на страницу:

    Var toggleComments = function() { var extensionLink; (document.getElementById("extension") == null) ? (extensionLink = document.createElement("link"), extensionLink.href = chrome.extension.getURL("/styles/commentblocker_on.css"), extensionLink.id = "extension", extensionLink.type = "text/css", extensionLink.rel = "stylesheet", document.getElementsByTagName("head").appendChild(extensionLink)) : (document.getElementsByTagName("head").removeChild(document.getElementById("extension"))) };

    Думаю, что слов о том, что этот кусок кода проверяет наличие подключения нашего CSS на странице и делает выводы о необходимости его подключения или отключения, будет достаточно.

    Между прочим, доступно не так много событий , которые покрывают различный спектр потребностей. Например, есть такие события:

    • onCreated - создание вкладки.
    • onUpdated - обновление вкладки.
    • onRemoved - закрытие вкладки.

    Стоит заметить, что событие onUpdated вызывается дважды:

    • Обновление страницы;

    На StackOverflow советуют проверять статус страницы:

    Chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { if (changeInfo && changeInfo.status === "complete") { ... } });

    Теперь при нажатии на иконку будет происходить подключение файла стилей, которые будут отображать комментарии, а повторный клик на иконку - вновь их скрывать.

    Выводы

    Как нельзя кстати, стоит упомянуть мою полную версию расширения VK Comment Blocker, которая доступна в

    Написать расширение для 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