GreaseMonkey

индекс
148,13

Пишем свой первый скрипт для Greasemonkey

Greasemonkey — это расширение для Mozilla Firefox, и некоторых других браузеров на основе движка Gecko, которое позволяет пользователю добавлять JavaScript на любую страницу. Сам файл с JS должен быть оформлен соответствующим образом.

Для чего же пользователю, к примеру мне, или вам, нужно добавлять JS на страницы любых сайтов? Это чудесная возможность управлять внешним видом страницы и её функционалом. Естественно есть ограничения, которые накладывает сам язык JS. Однако и возможностей у него очень и очень много.

Как правило, большинство скриптов для Greasemonkey тесно «дружат» с CSS. Так что получается, этот пост несколько пересекается с темой User-CSS — однако я в название топика не стал выносить этот аспект.

Давайте же напишем пару очень простых скриптов для Greasemonkey, ну а жертвой для наших опытов возьмём, само собой, habrahabr.

Для начала хотелось бы уточнить одну деталь — ниже я рассматриваю написание самых простых скриптов для Greasemonkey, а не основы работы с этим расширением. Подразумевается, что вы уже пользуетесь/пользовались Greasemonkey и не имеете проблем с взаимопониманием.

Сначала разбёрём то, как должен быть оформлен скрипт, что бы Greasemonkey его понял и принял как родного.

К примеру, имеем скрипт, который на каждой странице, кроме habrahabr.ru и моего блога absolvo.ru будет выводить алертом «Hello World!»

Его код крайне простой (установить скрипт можно с этой страницы):
// ----------Куча комментариев----------------------------------------------
//
// ==UserScript==
// @name Hello World
// @namespace absolvo.ru/
// @version 0.01
// @source absolvo.ru/
// @description Этот скрипт покажет вам алерт с «hello word» на каждой странице, кроме исключений!
// @include *
// @exclude http://*.habrahabr.ru/*
// @exclude habrahabr.ru/*
// @exclude absolvo.ru/*
// ==/UserScript==


alert('Hello world!');

Рассмотрим детально:

Если перед строкой поставить две слеша «//» — то строка будет считаться закомментированной и будет игнорироваться обработчиком.

==UserScript== и ==/UserScript== — теги, которые сообщают обработчику о том, что между ними заключена служебная информация, обязательная для обработки.

@name — имя ваше скрипта для Greasemonkey;

@namespase — грубо говоря — это дополнительный способ идентификации скрипта. Согласитесь, скриптов с названием «Hello World» просто огромное количество, и возможно один из них уже установлен у вас, и Greasemonkey, благодаря @namespace, не ругнётся на дублирование, и молча установит его. К слову, тут можно написать что угодно, свой ник, адрес сайта, или просто абракадабру.

@description — описание скрипта. Рекомендуется писать латиницей, но если вы пишете его для себя, то можете поэкспериментировать и с кирилицей. Лично у меня всё прекрасно и с кирилицей работает (этот вариант как раз выложен выше), только не забудьте о том, что сохранять файлик со скриптом надо в UTF-8.

@include — адреса страниц, на которых будет выполнятся скрипт. Поддерживает маски, но без регулярок — только звёздочки. Строк «включений» может быть сколько угодно много.

@exclude — адреса страниц, на которых НЕ будет выполнятся скрипт. Поддерживает маски, но без регулярок — только звёздочки. Строк «исключений» может быть сколько угодно много. У меня в примере их три.

Строки @include или @exclude могут и отсутствовать. К примеру, если вы пишете
// @include *
и уверены, что исключения вам не нужны, то строку @exclude можно благополучно не писать.

@version — версия вашего скрипта.

@source — домашняя страница скрипта.

Ну а дальше сам JS — самый обыкновенный. Вот в общем то и всё.

Давайте ради примеру сделаем совершенно несложный, непрактичный, но всё-таки пример, который наверняка ещё раз докажет вам, что в скриптах для Greasemonkey можно использовать все преимущества JS (установить скрипт можно с этой страницы):
// ==UserScript==
// @name Hello habrahabr!
// @namespace absolvo.ru/
// @version 0.01
// @source absolvo.ru/
// @description example script to insert div with h1 on every page habrahabr.ru
// @include habrahabr.ru/*
// @include http://*.habrahabr.ru/*
// @exclude absolvo.ru/*
// ==/UserScript==


var logo = document.createElement(«div»);
logo.innerHTML = '
<div style=«margin: 0pt auto; width: 800px; text-align: center;»>
<h1 style=«margin: 15px;»>' +
'Hello World habrahabr! ' +
'</h1>
</div>
';

document.body.insertBefore(logo, document.body.firstChild);

Объяснять что делает скрипт — я не буду, я думаю вы сможете его поставить, осмотреть и разобрать самостоятельно.

Средства для дебага скриптов:
Web Developer Extension;
Aardvark;
Venkman Javascript Debugger;
Web Development Bookmarklets;
JSUnit;
js-lint;

Не стоит изобретать велосипед, есть огромное количество скриптов, хотя бы на http://userscripts.org/ — вполне вероятно, что он уже написан за вас.

Ссылки по теме:
greasespot.net — страница проекта;
userscripts.org — самый большой сборник скриптов;
Страничка с примерами — страница для установки скриптов, которые выступили в роли примеров;
absolvo.ru & RSS — мой блог и мой RSS.
+13
8 сентября 2008, 05:32
43

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

0
JackFrost #
спасибо! ето мой первый скрипт к грейсманкей =)
+2
hlomzik #
Статья для совсем юных ;)
Лучше бы написали, как можно работать со страницей в процессе её загрузки или как можно включать css в userscript, если его чуть-чуть…
+1
Exabiche #
Кстати, да. Мне тоже интересно процесс загрузки страницы. Надеюсь, автор не оставит этот вопрос без внимания
–1
absolvo #
Не всё сразу -)
0
yolk #
Процесс обработки страницы скриптом Greasemonkey начинается по DOMContentLoaded. Возможно существуют хаки, которые позволяют включить обработку раньше, но врядли=)
0
hlomzik #
В том-то и дело, что DOMContentLoaded иногда слишком поздно…
Видел в одном из скриптов цикл, который обходил все уже существующие элементы (только нужные скрипту, конечно, но не суть), обрабатывал их и ставил специальный класс, чтобы на следующей итерации пропустить обработанные элементы. Прерывался скрипт как раз на DOMContentLoaded ;)
Вот только я в своём скрипте воссоздать это не смог :(
0
yolk #
Я это очень плохо представляю, сам цикл запускается по DOMContentLoaded, вообще всё что внутри скрипта GreaseMonkey можно условно запихнуть в addEventListener('DOMContentLoaded', function(){ /*code*/ }, false);

У Opera дела обстоят лучше, там обработку можно делать по ходу загрузки страницы, но есть свои подводные камни.
0
hlomzik #
Код userscript'а запускается как код указанный в head, если я ничего не путаю, т.е. фактически сразу после инициализации страницы.
Для этого и используют что-то вроде while(! document.body){} и т.п. ;) И это позволяет обрабатывать элементы, как только они появляются в DOM, а не после окончательной загрузки всего дерева. Если этим уметь пользоваться, конечно =)
0
yolk #
Проверил.
while (! document.body) alert('BeforeBody');
не работает.
0
yolk #
Да вот собственно тут всё и объясняется
wiki.greasespot.net/DOMContentLoaded
0
Sonar #
function addStyleSheet(url){
var style;
if (typeof url == 'undefined')
{
style = document.createElement('style');
}
else
{
style = document.createElement('link');
style.rel = 'stylesheet';
style.type = 'text/css';
style.href = url;
}
document.getElementsByTagName('head')[0].appendChild(style);
style = document.styleSheets[document.styleSheets.length — 1];
return style;
}

// пример
style.insertRule('.tbl-main_left-bg {background-image: url(../images/tbl-main_left-bottom.gif); background-repeat: repeat-y; width: 66px;}', style.cssRules.length);
0
GMM #
Раз уж пост о Greasemonkey, то у меня есть вопрос. Как получить в GreaseMonkey доступ к Mootools если сайт использует этот фреймворк(например Хабр)?
Когда я писал UserJS для Хабра, то в Опере все работало $, $$ правильно интерпретировалися. Под Greasemonkey ну никак не понимало, что я от него хочу.
+1
yolk #
0
GMM #
Спасибо, буду разбиратся.
+1
NickMitin #
0
NickMitin #
habrahabr.ru/blogs/GreaseMonkey/39431/ — тут есть ответ на ваш вопрос

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