Чтобы сделать расширение достаточно минимальных знаний Javasctipt, HTML и CSS. Давайте добавим на хабр догрузку следующей страницы, а также систематическую проверку новых постов на текущей. Примерно как на twitter.
Полностью готовый экстеншн можно установить и проверить в работе через Chrome Web Store, а здесь разберемся как написать основной код с нуля (полный занимает всего 6 KB).
Для начала необходимо создать отдельную папку нашего экстеншна и положить в нее файл manifest.json с таким содержанием:
{
"name":"Habrahabr Demo",
"version":"0.1",
"description":"Demo plugin",
"content_scripts":[
{
"matches":["http://habrahabr.ru/*"],
"css":["style.css"],
"js":["jquery.js", "script.js"]
}
]
}
Экстеншн будет активирован только на habrahabr.ru. Подгрузит из своей папки пока еще отсутствующие style.css, script.js и библиотеку jQuery. Chrome будет ругаться на отсутствие этих файлов, поэтому положим рядом пустые style.css и script.js, а также скачаем самый свежий jquery (который всегда находится по адресу http://code.jquery.com/jquery.js) и тоже положим в папку.
Теперь подключим наш экстеншн. Идем в настройки расширений хрома (chrome://settings/extensions), ставим там галочку «Developer mode» и нажам «Load unpacked extension...» указываем местоположение папки с нашими файлами. Модуль добавлен:
Перезагружаем хабр, убеждаемся что всё действительно работает. Точнее ничего, конечно, не изменится. Для проверки же добавим в style.css что-то вроде:
#layout {
max-width: none !important;
}
А в script.js, скажем:
$(function(){
var username = $("#header .username").text();
$("#header .bottom").append(
'<a href="/users/' + username + '/topics/">топики</a>'+
'<a href="/users/' + username + '/qa/questions/">вопросы</a>'+
'<a href="/users/' + username + '/comments/">комментарии</a>'
);
});
Перезагрузите расширение в кликнув на ссылку Reload (треугольничек слева от иконки расширения открывает ее), затем перезагрузим хабр и убедимся что верстка стала резиновой, а под никнеймом добавились новые ссылки (если вы зарегистрированы).
Приступим к AJAX загрузке. Для начала навесим обработчик клика на ссылку «Туда»:
$(document).on("click", "#next_page", function () {
var nextPrevBlock = $(".next-prev"); // блок с кнопками Сюда/Туда
var href = $(this).attr("href"); // ссылка кнопки Туда
$.ajax({
url:href,
success:function (response) {
nextPrevBlock.removeClass("started"); // убираем флаг
$(".posts").append($(response).find(".posts").html()); // добавляем посты в конец списка
$(".page-nav").html($(".page-nav", response).html()); // и заменяем ссылки туда/сюда/страницы на новые
stopTrackingScrollToBottom = false; // описание флага будет ниже
}
});
return false; // отменяем переход по ссылке
});
Теперь при клике по ссылке посты с новой страницы будут добавляться к постам на текущей (cнова не забываем перезагрузить экстеншн и хабр). Хорошим тоном считается показывать индикатор загрузки, здесь же опустим, простоты ради.
Далее делаем так чтобы ссылка нажимала сама себя когда мы доскроллим до конца страницы
var stopTrackingScrollToBottom = false;
$(window).scroll(function () {
if ($(window).scrollTop() + 10 >= ($(document).height() - ($(window).height()))) { // за 10 пикселов до конца страницы
if (stopTrackingScrollToBottom == false) { // проверяем не инициирован ли уже процесс дозагрузки
stopTrackingScrollToBottom = true; // отключаем этот уловитель скролла на время дозагрузки
$("#next_page").click(); // загибаем пальцы за пользователя :)
}
}
if ($(window).scrollTop() == 0) { // юзер доскроллил до верха
checkForNewPosts();
}
});
И заодно заложили начало второй части скрипта — вызов checkForNewPosts() при скролле до начала страницы. Функция должна проверять наличие новых постов на текущей странице и сообщать бэйджиком:
function checkForNewPosts(andLoadThem) {
if ($(".posts").length == 0) {
// это вообще не страница с постами, уходим
return;
}
$(".posts").prepend('<div class="new-posts-ajax"><img src="http://isbeauty.ru/images/icon_ajax_loader.gif"/></div>');
$.ajax({
url:window.location.href,
success:function (response) {
$(".new-posts-ajax").remove();
// Находим все айдишники постов на текущей странице и сравниваем с айишниками в ответе
var newPosts = getPostIds(response).diff(getPostIds());
Tinycon.setBubble(newPosts.length);
}
});
}
Array.prototype.diff = function (a) {
return this.filter(function (i) {
return !(a.indexOf(i) > -1);
});
};
function getPostIds(where) {
var postIds = [];
$(".post", where).each(function () {
var postId = $(this).attr("id");
postIds.push(postId);
});
return postIds;
}
Пока еще нет результата, потому что Tinycon.setBubble() не существует. Она должна выставлять бэйджик на фавиконке и реализована в библиотеке Tinycon. Чтобы ее подключить скачайте tinycon.js из github, положите в папку расширения и не забудьте подключить tinycon.js в manigest.json.
Чтобы проверить что бэйджик работает — зайдем на http://habrahabr.ru/posts/top/daily/ (вообще лучше тренироваться на страницах топа, они по всей видимости кэшируются и не создают большой нагрузки). Откроем инспектр кода (F12), удалим пару дивов внутри <div class="posts">...</div> и проскроллим на начало страницы. Бэйджик должен показать количество отсутствующих топиков.
Сделаем еще так, чтобы эта проверка происходила регулярно, раз в минуту:
var MAX_CHECKS_FOR_NEW_POSTS = 60; // введем ограничение на количество запросов, на случай если надо выйти за пельменями
var CHECK_FOR_NEW_POSTS_EACH = 60; // через сколько секунд проверять наличие новых
$(function () {
window.checkNewPostsTimer = setInterval(function () {
MAX_CHECKS_FOR_NEW_POSTS--;
if (MAX_CHECKS_FOR_NEW_POSTS <= 0) {
// self-destroy timer
clearInterval(window.checkNewPostsTimer);
} else {
checkForNewPosts();
}
}, CHECK_FOR_NEW_POSTS_EACH * 1000);
});
Не так уж много кода осталось, но на этом закончу. Не охвачена эстетическая сторона вопроса, а также возможность дозагрузить найденные новые посты, отменить автоматическую дозагрузку следующей страницы (по кнопке и по <Esc>). Всё это реализовано в готовом экстеншне, а исходный код доступен после установки где-то в папке:
C:Users%USERNAME%AppDataLocalGoogleChromeUser DataDefaultExtensionsglaccbllkhielccdhfbbpilnlbemgaji
(если там нет, ищите папку glaccbllkhielccdhfbbpilnlbemgaji где-то еще).
Осталось выложить расширение для публичного доступа. Для этого нужно получить приватный файл ключа, он требуется чтобы заливать эту и новые версии вашего экстеншна в дальнейшем. В настройках расширений кликаем кнопку «Pack extention», указываем путь к папке и оставляем путь к ключу пустым:
После упаковки хром создаст файл DemoExtension.crx и DemoExtension.pem, последний вам нужно переименовать в key.pem и кинуть в папку экстеншна (не теряйте его, а то не сможете обновлять это расширение). После чего всю папку расширения нужно заархивировать в DemoExtension.zip и залить в вашу панель управления. CRX файл при этом вообще не участвует.
После заливки архива нужно будет заполнить анкетные данные расширения и можно публиковать. Публичным расширение в Chrome Web Store можно сделать после единоразового пожертвования корпорации $5, врочем это необязательно, полученный ранее DemoExtension.crx (не zip) можно выложить хоть на Dropbox, Chrome даст установить его после подтверждения безопасности.
Вот как выглядит залитый в Web Store модуль:
Данное расширение не добавляет кнопок на панель, ни диалоговых окон, ни пунктов в контекстное меню, не имеет настроек, но вы сами разберетесь как это всё делать.
Теперь же вперед, делать сайты лучше, удобнее, красивее! :)
Автор: denver