GreaseMonkey

индекс
148,13

Укрощаем GreaseMonkey

За последние пару недель мне пришлось плотно поработать с системой управления пользовательскими скриптами для продуктов Mozilla — GreaseMonkey. И раз уж я сам себя назначил администратором одноименного блога, значит написать введение в вопрос — моя святая обязанность.



Введение



GreaseMonkey (далее GM) — система управления пользовательскими скриптами для продуктов Mozilla. В моей статье я буду говорить о браузере этой компании, о Firefox далее (FF). Так же в некоторых местах я коснусь его конкурентов, а именно Opera, Safari и конечно-же Internet Explorer (далее IE).

Пользовательский скрипт (User Script) — скрипт, написанный на языке JavaScript (далее JS), устанавливаемый пользователем в браузер и исполняющийся при загрузке веб-страниц. Используется для изменения их дизайна (в широком смысле этого слова).

Говоря проще, с помощью пользовательских скриптов, можно добавить/удалить/изменить элементы веб-страницы, изменить их поведение, улучшить User Experience.

Установка



GM легко ставится как расширение для FF с сайта дополнений. Так-же у GM есть официальный сайт, где можно найти массу полезной информации.

После установки и перезапуска у FF появится иконка:



И это значит что можно устанавливать пользовательские скрипты.

Самый большой склад пользовательских скриптов — это userscripts.org. Установка проиходит очень просто. GreaseMonkey просто перехватывает ответ на запрос JS-файла, и если он имеет специальный заголовок (расскажу о нем ниже), то вызывает диалог установки:



Обзор



Управлять GM и установленными скриптами можно через контекстное меню, которое вызывается правом щелчком по рожице обезьяны:



В верхней части меню отображается спискок активных для данной страницы скриптов. Любой скрипт можно отключить, убрав галочку.

С помощью API GM вы можете расширить это меню. Все действия, зарегистрированные через GM_registerMenuCommand, появятся в подменю «Команды скрипта».

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

«Управление скриптами» вызвывает следующее окно:



В этом окне вы можете сами поднастроить любой установленный пользовательский скрипт. Для этого выберите его в левом списке. Можно добавить удалить маски URL, для которых этот скрипт будет загружаться или НЕ загружаться (классический Allow/Deny), включить/выключить/удалить скрипт и, что самое важное для разработчика, отредактировать его вживую.

Для редактирования скрипта надо нажать кнопку «Изменить». В первый раз GM попросит выбрать редактор. В последующие будет автоматически открывать рабочую копию скрипта в выбранном редакторе.

На этом обзорная экскурсия по GM считается законченной и можно переходить непосредственно к тонкостям разработки пользовательских скриптов.

Пользовательские скрипты



GM-скрипты практически ничем (о некоторых особенностях, я расскажу в следующем разделе) не отличаются от обычных JS-скриптов, поэтому никаких специальных знаний для написания не нужно. Но для того чтобы GM могла распознать скрипт как пользовательский нужно добавить специальный заголовок:

// ==UserScript==
// @name Weborama Inline Player
// @namespace tbms.ru/weborama/inline/
// @description Includes weborama inline player
// @author Konstantin Shvydky, Nick Mitin
// @include *
// @exclude file://*
// ==/UserScript==
/*
This code is licenced under the GPL
www.fsf.org/licensing/licenses/gpl.html
*/


С name, author, description все понятно, надо остановиться на остальных параметрах

@namespace — любая URI (это не ссылка, а аналог HTML namespace). Можно считать этот параметр уникальным идентификатором скрипта.
@include — маска для страниц, которые будут активировать данный скрипт. Может быть несколько директив.
@exclude — маска для страниц, которые НЕ будут активировать данный скрипт. Может быть несколько директив.

Также хорошим тоном будет указать лицензию, под которой распространяется сам скрипт. Это можно сделать ниже метаданных.

* О метаданных на greasespot.net.

Вторым обязательным условием является окончание названия файла. Оно должно заканчиваться на «.user.js», иначе GM не будет распознавать скрипт.

Запуск скрипта для GM производится в порядке очередности по наступлению события DOMContentLoaded у обрабатываемой веб-страницы. Имейте это ввиду.

Tips & Tricks



Мы уже выяснили, что пользовательские скрипты обычно меняют дизайн веб-страниц. Поэтому основные задачи, которые встают перед разработчиками связаны с DOM-программированием, а именно манипуляциями с DOM-моделью веб-страниц. Проблема здесь в том, что порой очень сложно добиться адекватной работы скрипта на антисемантических сайтах. И я бы хотел дать несколько наводок для GM-разработчиков.

В Опере, Сафари и Файерфоксе есть встроенная поддержка XPath, через функцию document.evaluate(). Хорошее описание этой функции есть в MDC. Тем кто не в курсе, XPath (XML Path Language) является языком для обращения к частям XML-документа. В случае веба это определение верно и для HTML. Отличный туториал есть на ZVON.org. Суть метода в том, что вы создаете и посылаете «запрос» в DOM-модель, а в ответ вам приходит итератор со всеми нодами, которые удовлетворяют этому запросу.

Важно знать, что нельзя напрямую изменять эти ноды в итераторе, так как любое изменение перестраивает DOM, таким образом делая итератор невалидным. Поэтому сначала создайте массив и скопируйте туда ссылки на эти ноды, а потом уже работайте с ними. В примере в MDC все это рассмотрено.

В IE тоже есть частичная поддержка evaluate, которая реализуется черех хак, созданный Dimitri Glazkov и Mehdi Hassan.

Мы внесли его в свой JS-Extender, поправив в нем некоторые баги. Тем не менее, у нас не получилось выполнять сложные XPath запросы, поэтому мы не пользуемся этой функцией в IE.

Еще один важный момент, который стоит отметить, это то что при использовании свойства element.childNodes, FF считает текстовыми нодами переносы строки между тегами. Например у div с id = container будет не три, а пять дочерних нод:

<div id=«container»>
<div>content1</div>
<div>content2</div>
</div>

Будьте бдительны!

И последнее, но самое важное. В JS есть объект window, который как-бы является глобальным неймспесом для всех глобальных сущностей JS. если мы пишем

var myVar = 1;

то она будет доступна через

window.myVar или window['myVar'].

Так вот, в GM тоже есть window, но он является оболочкой вокруг самого window веб-страницы. это сделано для того, чтобы ваш код не пересекался с оригинальным кодом страницы и не мешал ему. Но существуют ситуации, когда нужно напрямую обратиться к тому самому window, чтобы, например, получить значение переменной сайта. На помощь приходит глобальное свойство unsafeWindow, которое и предоставляет к нему доступ.

Если вы пишете кросс-браузерный пользовательский скрипт, то имейте ввиду, что unsafeWindow есть только в GM, в Опере его нет. Поэтому лучше сразу завести глобальную переменную и положить в нее нужный вам window, например так:

var aWindow = (typeof unsafeWindow != 'undefined')? unsafeWindow: window;

Ложка дегтя



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

Существует несколько попыток решить эту проблему:

yoast.com/greasemonkey-auto-update-notification/
splintor.wordpress.com/2007/05/01/greasemonkey-wish-auto-update-user-scripts/
userscripts.org/scripts/show/2296

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

В общем можно сказать, что GreaseMonkey — это частный случай механизма управления пользовательскими скриптами. В Опере они поддерживаются без всяких расширений, по информации, поступисшей от pepelsbey сушествует плагин для Safari, который позволяет запускать эти скрипты — GreaseKit, по информации поступившей от jursovet уже реализована поддержка скриптов и для Chrome

На этом считаю свой доклад законченным. Спасибо, что дочитали.
+38
10 сентября 2008, 16:58
48

комментарии (27)

+2
XaocCPS #
смутило ваше определение XPath, на самом деле это, мягко говоря, не совсем ««язык запросов» к DOM-модели»
статья понравилась жду продолжения
+1
NickMitin #
Поэтому написано в кавычках.
+1
NickMitin #
В википедии написано очень похожее определение:

«XPath (XML Path Language) является языком для обращения к частям XML-документа.»

ru.wikipedia.org/wiki/XPath
+2
XaocCPS #
тогда, посмотрите там же что такое DOM
+2
NickMitin #
Вас понял. :) Сейчас исправлю. Спасибо.
+3
XaocCPS #
и, кстати, раз уж вы сами нашли то, как правильно нужно было написать, то может измените текст статьи?
+3
NickMitin #
Поменял.
+3
blo #
насколько я помню обязательным условием для GM скриптов является окончание имени файла на .user.js, в статье нигде про это не нашел
+1
NickMitin #
О! это ценное замечание.
+2
moloko #
Я не знаток JavaScript и т.п. Но GreaseMonkey очень удобная штука. Занимаюсь фотографией и размещаю свои работы на Flickr. С пол года назад обнаружил, что под Фликер написано много скриптов, меняющих интерфейс, добавляющих различные «вкусности» и «полезности». Установил GM и с тех пор наслаждаюсь жизнью, чего и всем желаю.
+1
pepelsbey #
В качестве постскриптума было бы хорошо упомянуть про плагин для Safari, который позволяет запускать эти скрипты — GreaseKit. Ну, чтобы не возникало иллюзии, что это работает только под Firefox ;)
+1
NickMitin #
Честно — не знал, сейчас добавлю. Спасибо!
0
jursovet #
Тогда можно добавить и Greasemetal — для Google Chrome :)
Как раз днем про него написал.
+1
NickMitin #
Ого, если кто-то знает как эти скрипты запускать в IE, то будет 99% покрытие.
0
jursovet #
Например, Trixie. Есть еще IE7Pro, который предоставляет возможность исполнения пользовательских скриптов (но насчет совместимости со скриптами Greasemonkey не знаю).
0
konfuze #
Ещё есть Grease Monkey 4 IE. Правда, его использование представляет из себя некоторый геморрой.

Полного «покрытия» не получится, т. к. нет решения для Safari / Win.
0
blo #
кстати и в опере эти скрипты должны работать
www.opera.com/support/tutorials/userjs/examples/#greasemonkey
0
NickMitin #
Да, про оперу я даже в тексте писал, там единственная проблема с нативным GM функциями и window.
–9
ZooLooK #
Почему на хабре небыло еще ниодного поста о запуске БАК?????
0
shuba #
Мне каждую неделю приходится закачивать много объявлений с фотографиями на один портал.
Сделал пользовательский скрипт который заполняет форму — экономлю кучу времени.
Но вот только фотографии приходится аплоадить всё равно вручную, по одной штуке, т.к. значение поля file из скрипта изменить нельзя.

Читал что-то про свойство netscape.security.PrivilegeManager.enablePrivilege(«UniversalFileRead»);
но не работает.

Не подскажите, может есть какие нибудь способы, хаки чтобы получить доступ к этому полю. (только на своеё машине, конечно)
0
stroncium #
«Firefox» правильно сокращается как «Fx», хотя это, наверное, не особо грубая ошибка, потому что большинство этого не знает.
0
dendron #
А дружит ли Greasemonkey с NoScript?
0
jursovet #
В большинстве случаев все работает нормально. См. здесь
–3
zelenin #
ребят, а не поможет мне никто с моим запросом? Надо написать маленький скриптик
operafan.net/forum/index.php? topic=5563.0
0
Power #
unsafeWindow настоятельно рекомендуют не использовать из-за потенциальной небезопасности.
0
NickMitin #
Я сегодня пока ехал в офис пытался придумать сценарий, при котором использование unsafeWindow будет опасно. Ничего на 100% опасного я не придумал. Может у вас есть примеры?
0
bersz #
Как можно воспользоваться функциями и объектами самого сайта?
Потому что оболочка какая-то обрезанная.
Например там есть фреймворк, хотелось бы его функциями все и удалить.
Или же вставить свой фреймворк и заставить заработать?
Пробовал на free-lance.ru воспользоваться mootools. Не получилось. Даже с unsafeWindow. Наверное что-то не так делаю.
Если вставить mootools как исполняемый скрипт, то ругается на объект. Непонятная обрезанность.

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