Меню сайта
Наш опрос
Оцените мой сайт
Всего ответов: 6
Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Главная » 2014 » Июль » 22 » Пишем расширение для Mozilla Firefox
15:15
Пишем расширение для Mozilla Firefox

В прошлой статье я рассказывал, как написать расширение для браузера Google Chrome. Моя попытка перейти с Mozilla Firefox на Google Chrome, в силу моих личных пристрастий, не увенчалась успехом, поэтому я вернулся на свой любимый браузер. Итак, в этой статье я постараюсь рассказать о том, как написать add-on для Mozilla Firefox.Для написания дополнений Firefox существуют два подхода: использование XUL и новый, рекомендуемый подход, с использованием легковесного JavaScript SDK.В этой статье речь пойдёт об использовании второго подхода -- JavaScript SDK. Сразу же приведу ссылки на tutorial`ы и guide`ы, где Вы сможете найти много полезной информации.По заверениям Mozilla, новые API имеют ряд преимуществ:простота в использовании высокоуровневого API;Mozilla обещает обратную совместимость для всех будущих версий API;тот же API будет использоваться в мобильной версии браузера; повышенная безопасность;использование опыта наработок Mozilla для повышения юзабилити;больше нет необходимости перезапускать браузер после установки дополнения.Однако, у XUL подхода есть свои собственные плюсы:поддержка локализации;прямой доступ XPCOM;расширяемый пользовательский интерфейс.Нужно отметить, что SDK поддерживает базовую локализацию, а доступ к XPCOM может осуществляться через низкоуровневый API.Итак, я надеюсь вернуться к XUL как-нибудь в другой раз, а сейчас приступим к написанию расширения.Сегодняшнее расширение будет помечать просмотренные видео на youtube`е.SDK Для того, чтобы писать расширения для Firefox нам понадобится пакет SDK, который можно скачать здесь. Кроме того, Вы можете воспользоваться онлайн IDE -- Add-on Builder. На видео ниже приведена демонстрация Add-on Builder`а. Your browser does not support the video tagЯ буду пользоваться скачанным пакетом SDK. После загрузки SDK Вам нужно распаковать архив в удобное место. В архиве, по большому счёту, нас интересует только файл bin/cfx (для пользователей UNIX-подобных ОС) или bin\cfx.bat для пользователей MS Windows. Я пользуюсь операционной системой Debian GNU/Linux. Я создал символьную ссылку на файл cfx в каталоге /usr/bin, чтобы не писать полный путь к скачанной папке.Для того, чтобы ознакомиться со справкой программы cfx нужно запустить её без параметров (из консоли). Нас интересует секцияSupported Commands: docs - view web-based documentation init - create a sample addon in an empty directory test - run tests run - run program xpi - generate an xpiЗдесь перечислены допустимые команды. Для того, чтобы создать заготовку проекта нужно запустить cfx с параметром init:$ cfx init* lib directory created* data directory created* test directory created* doc directory created* README.md written* package.json written* test/test-main.js written* lib/main.js written* doc/main.md writtenYour sample add-on is now ready.Do "cfx test" to test it and "cfx run" to try it. Have fun!В текущем каталоге будет создана структура пакета дополнения: youtubemarker+-- data+-- doc¦   L-- main.md+-- lib¦   L-- main.js+-- package.json+-- README.mdL-- test L-- test-main.jsСейчас нас интересуют два файла: package.json и lib/main.js. В первом файле сосредоточена информация о нашем дополнении { "name": "youtubemarker", "fullName": "youtubemarker", "description": "a basic add-on", "author": "", "license": "MPL 2.0", "version": "0.1"}Мы можем вписать свои данные и дополнить объект необходимыми полями. Спецификация объекта приведена здесь.Поле id будет создано при первом запуске нашего add-on`а. $ cfx runNo 'id' in package.json: creating a new ID for you.package.json modified: please re-run 'cfx run'{ "name": "youtubemark", "license": "MPL 2.0", "author": "brainstream", "version": "0.1", "fullName": "YouTube Marker", "id": "jid1-02UvWxeWz56WUA", "description": "Marks viewed videos"}Если при запуске cfx run программа не смогла найти Ваш Firefox, то путь к его исполняемому файлу нужно указать в опции -b, например так:$ cfx run -b /opt/firefox/firefoxКроме опции -b нам понадобится использовать опцию -p, которая задаёт профиль, с которым запускается Firefox. Дело в том, что по умолчанию, Firefox запускается каждый раз со временным профилем и вся сохранённая информация теряется. Запустив cfx следующим образом: $ cfx run -p profileмы создадим новый профиль в каталоге profile, который будет располагаться в текущем каталоге. Все последующие запуски $ cfx run -p profileбудут использовать этот профиль. Сюда Вы можете поставить те дополнения, которые Вам нужны для работы с Вашим дополнением, здесь же будут храниться куки и все данные, которые мы сохраним в процессе работы нашего дополнения.Встраиваемый скриптПрейдём непосредственно к коду дополнения. В add-on`ах Firexox используется два вида скриптов: код в дополнении и встраиваемый в страницу код. Различия между ними состоят в доступе к тем или иным API.Начнём со скрипта, который будет работать на странице youtube`а:youTubeMarker = { start: function() { youTubeMarker.runListing(); youTubeMarker.processPage(); }, runListing: function() { self.on("message", function(message) { if(message mark": youTubeMarker.markElement(message.id); break; } }); }, processPage: function() { if(document.getElementById("watch-video-container") feed") feed-item-container", "feed-video-title"); } else if(document.getElementById("browse-main-column") browse-item", "yt-uix-sessionlink"); } else if(document.getElementById("search-main") result-item-video", "yt-uix-sessionlink"); } }, processWatch: function() { self.postMessage({ type: "watch", url: document.URL }); }, processPane: function(itemClass, linkClass) { var items = document.getElementsByClassName(itemClass); for(var i in items) { var links = items[i].getElementsByClassName(linkClass); if(links.length > 0) { var url = links[0].getAttribute("href"); var id = "youtube-marker-" + youTubeMarker.lastId++; items[i].id = id; youTubeMarker.requestMarking(url, id); } } }, lastId: 0, requestMarking: function(url, id) { self.postMessage({ type: "mark", url: url, id: id }); }, markElement: function(id) { var element = document.getElementById(id); if(element page-mod");var data = require("self").data;var simpleStorage = require("simple-storage");var querystring = require("api-utils/querystring");pageMod.PageMod({ include: ["*.youtube.com"], contentScriptFile: data.url("content.js"), contentScriptWhen: "end", onAttach: function(worker) { worker.on("message", function(message) { processMessage(worker, message); }); }});function processMessage(worker, message) { if(message mark": if(!isVideoWatched(message.url)) return; worker.postMessage({ type: "mark", id: message.id, }); return; case "watch": saveWatchedUrl(message.url); return; }}function unifyUrl(url) { var query = querystring.parse(url.split("?")[1]); return query.v;}function isVideoWatched(url) { return simpleStorage.storage[unifyUrl(url)] start": скрипт выполнится сразу же, как элемент документа будет вставлен в DOM;"ready": скрипт будет выполнен после полной загрузки DOM;"end": запуск скрипта произойдёт после загрузки всего контента (DOM, JavaScript`ы, таблицы стилей и картинки).Так же объект позволяет подписаться на события, которые происходят при аттаче скрипта и при ошибке. В примере приведён первый случай. На обработчике onAttach мы запускаем прослушивание сообщений от встроенного скрипта. В сообщении о подключении скрипта нам приходит объект Page модуля page-worker, через который возможна коммуникация со встроенным скриптом. Здесь нам доступны методы on и postMessage полностью идентичные тем, что мы использовали во встраиваемом скрипте из объекта self.Адрес скрипта, хранящегося в каталоге data можно получить, использовав объект data из модуля self. Метод data.url() вернёт ссылку, которую мы вставляем в свойство contentScriptFile объекта PageMod.Низкоуровневый модуль api-utils/querystring позволяет распарсить строку запроса в URL страницы.Теперь наше дополнение готово к первому запуску. Запустите$ cfx run -p profileи посмотрите на youtube.com пару видео с вашего фида или из обзора. Вернитесь на страницу со списком и увидите, что просмотренные видео полупрозрачны.Добавляем интерактивностьAdd-on работает. Теперь нам хочется интерактивности. Давайте добавим пункт в контекстное меню, который будет отображаться при правом щелчке на блок с видео в списках.Прежде чем приступить к описанию процесса создания меню, необходимо провести небольшой рефакторинг уже написанного кода: вынесем переменную worker из обработчика события onAttach в глобальную область видимости.var globalWorker;pageMod.PageMod({ include: ["*.youtube.com"], contentScriptFile: data.url("content.js"), contentScriptWhen: "end", onAttach: function(worker) { globalWorker = worker; worker.on("message", function(message) { processMessage(message); }); }});function processMessage(message) { if(message mark": if(!isVideoWatched(message.url)) return; globalWorker.postMessage({ type: "mark", id: message.id, }); return; case "watch": saveWatchedUrl(message.url); return; }}Строки, в которые нужно внести правки, выделены полужирным шрифтом.Теперь добавим пункт меню. var menu = require("context-menu");function createMenu() { var containers = [ "feed-item-container", "browse-item", "result-item-video" ]; for(var i in containers) { menu.Item({ label: "Mark/unmark as viewd", context: [ menu.URLContext("*.youtube.com"), menu.SelectorContext("." + containers[i] + " *") ], data: containers[i], contentScriptFile: data.url("markmenu.js"), onMessage: function (message) { processMenuMessage(message); } }); }}createMenu();function processMenuMessage(message) { if(message mark": saveWatchedUrl(message.url); break; case "unmark": removeWatchedUrl(message.url); break; } globalWorker.postMessage({ type: message.type, id : message.id, });}Кроме меню, нам понадобится функция для удаления записей из simpleStorage. Для того, чтобы удалить запись из simpleStorage достаточно применить к этой записи оператор delete. function removeWatchedUrl(url) { var unifiedUrl = unifyUrl(url); if(simpleStorage.storage[unifiedUrl] mark" и "unmark".Для того, чтобы снять метку, нужно немного дописать метод markElement в файле content.js: markElement: function(id, mark) { var element = document.getElementById(id); if(element message", function(message) { if(message mark": youTubeMarker.markElement(message.id, true); break; case "unmark": youTubeMarker.markElement(message.id, false); break; } });},При создании пункта меню, в поле contentScriptFile мы указали новый файл -- markmenu.js. Давайте взглянем на него. youTubeMarkerMarkMenu = { start: function() { self.on("click", function(source, data) { for(var element = source; element unmark" : "mark", id: element.id, url: url }); return; } }); }, findUrl: function(className, container) { var linkclass = null; switch(className) { case "feed-item-container": linkclass = "feed-video-title"; break; case "browse-item": case "result-item-video": linkclass = "yt-uix-sessionlink"; break; default: return null; } var links = container.getElementsByClassName(linkclass); if(links.length < 1) return null; return links[0].getAttribute("href"); }};youTubeMarkerMarkMenu.start();Здесь мы видим уже знакомый нам метод self.on. Теперь он принимает сообщение click и два параметра: элемент, на котором произошёл клик и данные, записанные в параметр data при создании элемента меню. В эти данные мы записали класс контейнера, который необходимо найти. С помощью цикла ищем этот контейнер вверх по дереву. Найдя элемент, получаем URL видео и отправляем сообщение основному скрипту. Что происходит дальше Вы уже видели.Создание пакета После того, как Ваш add-on закончен, Вы можете создать *.xpi файл для установки его в браузер. Для этого введите команду $ cfx xpiи в Вашем рабочем каталоге появится файл с расширением xpi. Для команды $ cfx xpiтак же можно использовать опцию -b, если cfx не смогла найти Вашего браузера. ЗаключениеВ этой статье я показал лишь очень малую часть того, что можно сделать с помощью Add-on SDK. Но надеюсь этого будет достаточно для того, чтобы понять общий подход к написанию дополнений для Mozilla Firefox.Исходные тексты примера можно скачать отсюда.


онлайн-консультант QuickChat
Просмотров: 451 | Добавил: admin | Рейтинг: 0.0/0
Всего комментариев: 0
avatar
Форма входа
Календарь
«  Июль 2014  »
ПнВтСрЧтПтСбВс
 123456
78910111213
14151617181920
21222324252627
28293031
Архив записей