Темы



Разработка расширения для firefox, или мой первый опыт, на примере скриншотера

После написания статьи Системные скрипты на php для linux, пишем скриншотер, у меня появилась идея «А почему бы, не написать расширение которое завязать на мой скрипт, с возможностью автоматической выгрузки на яндекс диск.»… Почитав документацию о разработке расширений я решил всё же начать писать.
image

Вот это маленькая кнопочка и скриншот на яндекс диске, результат прототипа расширения, написаного за пару часов. О процессе его создание под катом…

Внимание: это первая версия приложения, в будущем в роли скриншотера будет выступать скрипт из предыдущей статьи…

Расширение которое я разработал имеет следующую файловую структуру:

Структура
-chrome.manifest
-install.rdf
--content
----browserOverlay.js
----browserOverlay.xul
----options.xul
--skin
----browserOverlay.css

Сейчас нас интересуют файлы: chrome.manifest и install.rdf. chrome.manifest содержит в себе описание структуры проекта:

chrome.manifest
content xulphpsrc content/
skin xulphpsrc classic/1.0 skin/

overlay chrome://browser/content/browser.xul chrome://xulphpsrc/content/browserOverlay.xul



Первые две строки хром манифеста содержат: тип данных, название пакета, путь к файлам пакета.
Третья строка регистрирует, так называемый, overlay (поверхностный слой) т.е. этот слой ложиться как бы по верх уже существующего, и добавляет элементы управления в браузер.

Файл install.rdf это манифест установки, который содержит информацию об добавляемом расширение:

install.rdf




  
    phpsrc@phpsrc.ru
    xulphpsrc
    PHP screenshoter extensions!
    0.1
    chrome://xulphpsrc/content/options.xul
    Naumov
    2

    
    
      
        {ec8030f7-c20a-464f-9b0e-13a3a9e97384}
        4.0
        10.*
      
    
  



Как вы видите. Он содержит в себе идентификатор, имя приложения, версию, создателя, тип приложения, URL панели настройки и д.р. информацию.
Я не думаю что стоит заострять внимание на этом файле, так как всё вполне очевидно. Мы можем только разобрать одну опцию optionsURL, это url который ведёт к настройкам расширения, настройки в свою очередь описываются файлом options.xul:
options.xul





    
        
            
        

        
            
        

        
            
    



В этом файле, мы описали всего 2-ва поля логин и пароль. Обратите внимание на имена «extensions.xulphpsrc.login» и «extensions.xulphpsrc.pass» они содержат как бы древовидную структуру, и их будет удобнее получать из общей массы записей, да и есть, некая гарантия уникальности ключей…
Далее рассмотрим фаил browserOverlay.xul:
browserOverlay.xul







  <script type="application/x-javascript"
    src="chrome://xulphpsrc/content/browserOverlay.js" />

  
    
    
    
  



Что он делает? он подключает два файла browserOverlay.css, browserOverlay.js и создаёт toolbar и единственную кнопку на нём «Скриншот»:
2eaf447005bbb4b26ceae32235706546.png
Вся логика приложения заложена в browserOverlay.js
browserOverlay.js
/**
 * XULPHPsrcChrome namespace.
 */
if ("undefined" == typeof(XULPHPsrcChrome)) {
    var XULPHPsrcChrome = {};
}

/**
 * Controls the browser overlay.
 */
XULPHPsrcChrome.BrowserOverlay = {
    /**
     * craete screen shot by rect
     * @param aEvent
     */
    makeScreen: function (aEvent) {
        var date = new Date();
        var fileScreen = date.getTime().toString() + '_screen.png';

        var args = ["-s", "/tmp/" + fileScreen];

        this.systemRequest(
            '/usr/bin/scrot',
            args
        );

        this.uploadToYandex(fileScreen);
    },

    /**
     * analog php system
     * @param shell
     * @param args
     */
    systemRequest: function (shell, args) {
        var file = Components.classes["@mozilla.org/file/local;1"]
            .createInstance(Components.interfaces.nsIFile);

        file.initWithPath(shell);

        var process = Components.classes["@mozilla.org/process/util;1"]
            .createInstance(Components.interfaces.nsIProcess);
        process.init(file);

        process.run(true, args, args.length);
    },

    /**
     * upload screen to yandex
     * @param name
     */
    uploadToYandex: function (name) {
        var xml = 'true';
        var auth = this.getPreference().login + ':' + this.getPreference().pass;

        this.systemRequest('/usr/bin/curl', [
            '-s',
            '--user', auth,
            '-T', '/tmp/' + name,
            '-X', 'PUT',
            'https://webdav.yandex.ru'
        ]);

        this.systemRequest('/usr/bin/curl', [
            '-s',
            '--user', auth,
            '-d', xml,
            '-X', 'PROPPATCH',
            'https://webdav.yandex.ru/' + name
        ]);

        alert("Скриншот сохранён");
    },

    /**
     * get system configuration
     * @returns {{login: *, pass: *}}
     */
    getPreference: function () {
        var prefs = Components.classes["@mozilla.org/preferences-service;1"]
            .getService(Components.interfaces.nsIPrefService);
        var myPrefs = prefs.getBranch("extensions.xulphpsrc.");

        return {
            login: myPrefs.getCharPref('login'),
            pass: myPrefs.getCharPref('pass')
        }
    }
};


Данный фаил мы разберём чуть подробнее хотя он тривиален и выполняет всего 2-ва действия: делает скриншот, и загружает его на yandex disk. Скриншот он делает с помощью вызова системной утилиты crot, и згружает результат с помощью curl. Обработчик «клика» на кнопку «скриншот» мы поставили метод makeScreen:
    /**
     * craete screen shot by rect
     * @param aEvent
     */
    makeScreen: function (aEvent) {
        var date = new Date();
        var fileScreen = date.getTime().toString() + '_screen.png';

        var args = ["-s", "/tmp/" + fileScreen];

        this.systemRequest(
            '/usr/bin/scrot',
            args
        );

        this.uploadToYandex(fileScreen);
    },

Это точка входа в приложение, здесь формируется имя будущего скриншота и происходит вызов, linux программы, scrot. Мы выбираем мышкой область экрана и делаем снимок, после этого программа переходит в следующий метод uploadToYandex, и передаёт имя файла для загрузки.
    /**
     * upload screen to yandex
     * @param name
     */
    uploadToYandex: function (name) {
        var xml = 'true';
        var auth = this.getPreference().login + ':' + this.getPreference().pass;

        this.systemRequest('/usr/bin/curl', [
            '-s',
            '--user', auth,
            '-T', '/tmp/' + name,
            '-X', 'PUT',
            'https://webdav.yandex.ru'
        ]);

        this.systemRequest('/usr/bin/curl', [
            '-s',
            '--user', auth,
            '-d', xml,
            '-X', 'PROPPATCH',
            'https://webdav.yandex.ru/' + name
        ]);

        alert("Скриншот сохранён");
    },

В этом методе, как вы видите нет ни чего экстраординарного, он делает 2-ва запроса с помощью curl в yandex.disk, один загружает созданный файл, другой его публикуют. Спасибо lexore за коментарий. В конце концов, мы получаем уведомление что скриншот сохранён.

Ну вот теперь у нас есть расширение как его установить? Для разработки мы можем, просто, создать файл под именем приложения в папке:
~/.mozilla/firefox/[id].[user]/extensions/
Где id — идентификатор, [user] — пользователь firefox к примеру у меня получилось так:
~/.mozilla/firefox/pta4nm6g.default/extensions/phpsrc@phpsrc.ru
И содержащий путь до директории с файлами расширения:~/extensions/phpsrc/ (к примеру у меня такой).
Последним штрихом, нам необходимо отключить проверку подписи расширений в firefox. Для этого необходимо перейти по адресу about: config найти опцию xpinstall.signatures.required и выставить значение false.
33ea83fd63045a9f8ce682e42333e915.png

Перезагружаем firefox и всё готово… Настройка расширения, заходим в дополнения и ищем своё расширение, нажимаем на кнопочку настроить, вводим логин и пароль от yandex’a и готово, теперь можно нажать кнопочку и сделать скриншот…

Выводы: Я в первый раз писал расширение для firefox, и времени у меня больше на написание статьи ушло. Это первая версия приложения в дальнейшем есть планы развиваться в направление, использования php в этой сфере. Все скриншоты сделаны разработанным расширением. Всем спасибо за внимание, всего хорошего…

Комментарии (1)

  • 23 сентября 2016 в 18:27

    0

    ↑

    ↓

    Вроде как использование XUL объявлено мозиллой устаревшим подходом. Сейчас предлагается переходить на Web Extensions. Правда, это началось недавно и будет работать только для последних версий Firefox… Поправьте пожалуйста, если я не прав.

© Habrahabr.ru