Пишем своё Chrome расширение. Основной код и упаковка расширения. Часть 2.


Привет! В прошлый раз мы узнали, что нужно писать в манифесте нашего расширения, а сегодня разберем основной код, который и будет выполнять почти всю работу. Писать мы его будем в файле content.js, который будет выполняться на страницах голосах.



В начале мы получим ID нашего расширения. Он будет необходим нам,чтобы создавать уникальные ID элементов, которые мы будем добавлять на Голос.

var ID = chrome.runtime.id;

Теперь перейдем к получению списка постов, за которые голосовал пользователь.

chrome.storage.sync.get(['login'], function(items) {
    var tabURL = window.location.href;
    if ((tabURL.indexOf('@') > -1) && (items.login === undefined)) {
        login = tabURL.substring(tabURL.indexOf('@')+1);
        login = login.substring(0,login.indexOf('/'));

        chrome.storage.sync.set({'login': login}, function() {
                console.log('Login saved');
        });
    }

    socket = new WebSocket('wss://ws.golos.io'); 

    socket.onopen = function(event) {
        console.log("сокет открыт!");
        socket.send(JSON.stringify({ // Делаем запрос на возвращение глобальных динамических данных
                id: 1,
             method: 'get_account_votes',
             params: [items.login]
        }));
    }

    socket.onmessage = function(event) {
        data = JSON.parse(event.data)
        data = data.result;

               document.getElementById(ID+"-voted-link").innerHTML = 'Понравившиеся';

        socket.close();

        console.log("найдено "+ data.length +" понравившихся постов");

        var inner = document.getElementById("golos-voted-list");
        inner.innerHTML = '<h3>Понравившиеся посты</h3>';

        for (var i=data.length-1;i>=0;i--) {
            var s = data[i].authorperm.split("/");
            inner.innerHTML = inner.innerHTML + '<p >'+ s[0] + ' | <font style="color:#1a5099";>' + s[1] +'</font></p>';  
        }
    };

});

Разберем, что происходит в коде выше.

chrome.storage.sync.get - эта функция возвращает сохраненные данные из локального хранилища. В нашем случае мы запрашиваем данные, сохраненные под ключом "login".

var tabURL = window.location.href; - таким образом мы узнаем текущий адрес страницы, откуда и будем вытаскивать ник.

Если в ссылке есть символ @, с которого начинается логин и в локальном хранилище нет сохраненного логина, то мы вытаскиваем логин из адреса страницы

chrome.storage.sync.set - функция, которая сохранит логин в локальном хранилище.

Отлично, мы узнали логин пользователя! Теперь с помощью строчки socket = new WebSocket('wss://ws.golos.io'); создаем вебсокет соединение и когда оно будет открыто, отправляем запрос на получение постов, за которые голосовал пользователь. С помощью события socket.onmessage получаем ответ в виде нужного нам списка.

Далее мы убираем индикатор загрузки у ссылки "Понравившиеся" и во вкладку добавляем "ссылки" на посты. На самом деле это не совсем ссылке, но об этом чуть позже.

Отлично, мы создали список постов в нашей вкладке, но вот проблема, саму вкладку мы еще не создали. Код создания находится ниже.

var menu = document.getElementsByClassName('HorizontalMenu')[0];
menu.innerHTML = menu.innerHTML +  '<li>  Понравившиеся  </li>';

var floatWindow = document.createElement('div');
floatWindow.className = 'float-window';
floatWindow.setAttribute('id',ID + '-float-window');
floatWindow.style.display = 'none';

var close = document.createElement('div');
close.setAttribute('align','right');
close.innerHTML = '<font id="'+ID+'-">закрыть</font>';

floatWindow.appendChild(close);

var floatWindowInner = document.createElement('div');
floatWindowInner.className = 'float-window-inner';
floatWindowInner.setAttribute('id',ID + '-float-window-inner');

var list = document.createElement('div');
list.setAttribute('id','golos-voted-list');
list.className = 'golos-voted-list';
list.innerHTML = 'Загрузка...';

floatWindowInner.appendChild(list);

floatWindow.appendChild(floatWindowInner);

document.body.appendChild(floatWindow);

В начале мы находим элемент, где располагаются основные ссылки на Голосе и добавляем к ним собственную ссылку. После этого создается основное окно и его содержимое: кнопка "закрыть", блок, в котором будут располагаться посты и т.д.

Теперь добавим обработчики для ссылки Понравившиеся и закрыть

document.getElementById(ID+"-voted-link").onclick = function () {
    document.getElementById(ID+"-float-window").style.display="";
    return false;
}

document.getElementById(ID+"-close").onclick = function () {
    document.getElementById(ID+"-float-window").style.display="none";
    return false;
}

Все что они делают - это показывают или скрывают нашу вкладку.

Хорошо мы реализовали почти все необходимые функции, но осталась ещё одна - переход по "ссылкам" в нужный нам пост. Поскольку голос возвращает нам данные, где отсутствует прямая ссылка на пост, то необходимо самим создать её.

Конструкция ссылки следующая: '/'+{категория}+'/@'+{логин автора}+'/'+{пермлинк}. Из всего этого нам не хватает категории, поэтому придется прибегнуть к трюку. Напишем в content.js код:

var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.extension.getURL('script.js');
s.onload = function() {
    this.remove();
};
(document.head || document.documentElement).appendChild(s);

С помощью него script.js будет добавлен на Голос. Это необходимо, поскольку мы не сможем с сайта обращаться к функциям, описанным в content.js.

Код script.js:

function getContent (login,permlink,el) {

    var inner = el.innerHTML;
    el.innerHTML = '(загрузка..) '+el.innerHTML;

    socket = new WebSocket('wss://ws.golos.io'); 

    socket.onopen = function(event) {
        console.log("сокет открыт!");
        socket.send(JSON.stringify({
            id: 1,
            method: 'get_content',
            params: [login,permlink]
        }));
    }

    socket.onmessage = function(event) {
        data = JSON.parse(event.data);
        data = data.result;

        url = '/'+data.category+'/@'+data.author+'/'+data.permlink;

        el.innerHTML = inner;

        window.open(url, '_blank');

        socket.close();

    }
}

В скрипте описана всего одна функция, в которую мы передаем логин пользователя, пермлинк и сам элемент, чтобы в него добавить надпись "загрузка..".

В самой функции мы вновь открываем вебсокет соединение и запрашиваем контент определенной статьи пользователя. Из полученных данных создаем ссылку на пост и с помощью window.open(url, '_blank'); открываем её.

Упаковка расширения

Для того чтобы обычные пользователи могли установить ваше расширение из магазина или же просто из файла, его необходимо упаковать.
Делается это очень просто! Переходим во вкладку "Расширения" и находим кнопку "Упаковать расширение...".

В появившемся окне выбираем корневой каталог расширения, т.е. папку, в которой лежат все файлы нашего расширения, и упаковываем расширение. В папке, в которой хранится тот самый каталог создастся два файла.

Первый .crx - сам файл расширения, его вы можете использовать для распространения.

Второй .pem - файл закрытого ключа, который необходим для того, чтобы обновить файл расширения, если вы внесли в файлы какие-либо правки.

Вот и всё! Наше расширение готово!

Cкачать готовое расширение можно здесь

Скачать исходники расширения

Заглавное фото с сайта energysmi.ru

Данный материал о создании расширений для Google Chrome подготовлен автором @mo3golom.


Comments 1