Журнал LinuxFormat - перейти на главную

LXF84:Hardcore Linux

Материал из Linuxformat
Перейти к: навигация, поиск
Hardcore Linux: Проверь себя на крутых проектах для умников

Greasemonkey: Обновим Сеть!

Не чесались ли у вас руки улучшить даже самые отличные web-сайты? Greasemonkey научит сайты работать так, как хочется Нику Вейчу, а то и вам.

Задача этого месяца ерундовая: всего-навсего создать собственный web-браузер, способный заново интерпретировать обветшавшие сайты и заставить их слушаться наших команд.

Думаете, пахать придется серьезно? Ну, мы ж не слабаки! Да и не забывайте: фишка нашей серии в том, что черная работа не для нас, главное, чтоб она была сделана. Так что мы и тут извернемся, как истые хакеры.

Firefox – хороший браузер, более чем хороший. Его нужно лишь чуть-чуть «обработать напильником», например, создать специальное расширение, позволяющее при помощи заготовленного сценария корректировать взятый HTML... Но нам не придется делать даже этого, поскольку – спасибо Аарону Брудману [Aaron Broodman] – на свете есть Greasemonkey! Итак, первый этап нашего хитрого плана завершен: мы превратили задачу по написанию миллионов строк кода в задачу состряпать небольшой сценарий JavaScript. Ура!

Хорошо, но прежде чем приступать к созданию сценария, нужно добыть Firefox и Greasemonkey (и то и другое находится на прилагаемом диске, но проще скачать их прямо из Сети, с сайта http://greasemonkey.mozdev.org). Кстати, в дальнейшем вам не повредит некоторое знакомство с JavaScript, так что взгляните на врезку.


Web-приложение, которое я собираюсь улучшать – менеджер фотографий Flickr, а вы можете выбрать любой другой сайт на ваш вкус. Хотя было бы неплохо, если бы этот сайт хорошо поддерживался и имел четкую, понятную иерархическую структуру страниц – например, попытайте счастья с новостным сайтом BBC, с Amazon или с Play. Я выбрал Flickr потому, что здесь есть простор для добавления новых функций, а также потому, что визит на этот сайт – повод оставить парочку глумливых комментариев к чужим фото.

Flickr позволяет пользователям помечать свои фотографии, то есть назначать для них ключевые слова-тэги, по которым затем можно выполнять поиск. Но со страницы каждой конкретной фотографии можно искать только по одному ключевому слову за раз. Если вы крупным планом (макро) засняли цветок наперстянки и выбрали ключевые слова «природа макро наперстянка» (“nature macro foxglove”), то найти похожие кадры, щелкая на метки по отдельности, будет сложновато. Я решил добавить возможность искать по всем имеющимся ключевым словам одновременно. Это хороший тестовый пример, поскольку нам потребуется считывать данные со страницы и записывать их обратно. Начнем с чтения.

Фокус с Flickr

Требуется найти на странице Flickr, где помещено наше фото и информацию о ключевых словах. У JavaScript хватает методов обработки DOM (внутренней иерархии HTML-документа), и все, что нужно сделать – это посмотреть, где в дереве документа находится нужная информация и как однозначно отличить ее от прочего. Проще всего использовать для этих целей встроенный в Firefox браузер DOM. Откройте его в Tools – меню инструментов Firefox – и пощелкайте по нему, чтобы увидеть дерево иерархии. Firefox любезно покажет мигающую красную рамочку вокруг того элемента, который вы выбрали в DOM Inspector.

Похоже, что нам повезло. Список ключевых слов на странице фотографии хранятся в элементе <div> и помечен как thetags. Это уникальный идентификатор. Таким образом, мы можем просто перетряхнуть все элементы <div> в документе, пока не найдем нужный. Вот кусочек JavaScript-кода, который это делает:

 var divs, tagsdiv
 divs = document.getElementsByTagName(‘div’);
 //Мы сохранили все элементы div как объекты
 //в массиве под названием ‘divs’
 for (var i=0; i<divs.length; i++) {
    if(divs[i].id == ‘thetags’){
        tagsdiv=divs[i];
    }
 }

Здесь использован метод, позволяющий создать массив всех эле- ментов <div>, а затем искать в нем тот, что нам требуется (thetags). Это не самый эффективный способ, но он годится в качестве примера, и его проще модифицировать для ситуаций, когда требуется найти более одного отмеченного элемента [в противном случае можно было бы использовать код var tagsdiv=document.getElementById(‘thetags’), – прим.ред.]. Более быстрый метод мы покажем в следующей части.

<div> вообще-то содержит много всего – заголовок, ссылки на иконки, плюс еще по одному <div> на каждый отдельный тэг. И снова мы можем, перебором в цикле, построить список тэгов. Извлечение собственно текста метки достигается выборкой HTML-элемента из нужного узла (какого именно – видно по DOM-структуре). А потом соберем полученные метки в список, который станет основой запроса, который мы передадим обратно на страницу в следующей фазе. Сосредоточьтесь, привожу этот кусок кода:

 if (tagsdiv) {
     tagsdiv = tagsdiv.getElementsByTagName(‘div’);
     tagslist =’’;
     for (var i = 0; i< tagsdiv.length; i++){
        if (i>0) {
            tagslist = tagslist ++;
        }
        tagslist = tagslist + tagsdiv[i].childNodes[3].innerHTML;
     }
 }

Метод childNodes любого из узлов дерева содержит список всех дочерних узлов, к которым мы можем обращаться по номерам, чтобы найти нужный и запросить для него значение innerHTML, в котором содержится HTML-представление этого узла. Оно полезно для прояснения непонятных моментов, но проследите за тем, чтобы запросить его для нужного узла, иначе получите описания совершенно посторонних тэгов.

Вернем долги

Итак, мы сумели достать нужную информацию из документа. Ура! Настало время поиграть с полученным результатом и записать немножко HTML-текста обратно на страницу. Разработчики JavaScript, видимо, предвидели такую необходимость, и припасли множество встроенных функций. Первый вопрос, который нужно решить – это в какое место страницы поместить наш текст. Подходящим местом выглядит список с информацией о снимке в правой части страницы, ниже списка ключевых слов. Вернувшись в DOM-браузер, мы увидим, что это первый на странице элемент ul. Так что мы просто создаем новый элемент списка и вставляем его в нужное место:


 var searchtagLi = document.createElement(“li”);
 searchtagLi.setAttribute(class”,”Stats”);
 searchtagText = ‘Search <a href=”http://www.flickr.com/search/
 ?w=all&q=+tagslist+’”style=”text-decoration: none;>similar tags</a> on
 Flickr’;
 searchtagLi.innerHTML = searchtagText;
 insertpoint = document.getElementsByTagName(“ul”)[0];
 insertpoint.appendChild(searchtagLi);

Метод setAttribute используется для указания, какого класса должен быть наш новый элемент, чтобы по CSS-стилю не отличаться от своих соседей.

Текст, который мы добавили – всего лишь ссылка на функцию продвинутого поиска Flickr, которой мы, вместо одного ключевого слова, передаем собранный нами список. Легко видеть, что потом использован метод innerHTML для записи данных в объект. Объект insertpoint указывает на ранее найденный элемент ul, так что остается только вызвать метод appendChild для добавления его в дерево (причем в самый конец списка, что очень правильно).

Вот и все, и этого достаточно. Чтобы загрузить скрипт Greasemonkey, просто активируйте это расширение и укажите браузеру на файл (назвав его как-нибудь вроде something.user.js) – Greasemonkey обнаружит файл и позволит вам его загрузить. LXF

Персональные инструменты
купить
подписаться
Яндекс.Метрика