Artykuł

gru 14 2011
0

Skrypty użytkownika Greasemonkey dla przeglądarek - tworzenie

W poprzednim wpisie, związanym z skryptami użytkownika Greasemonkey, zrobiłem małe wprowadzenie na ich temat, a następnie powiedziałem w jaki sposób korzystać z nich w popularnych przeglądarkach.

Dziś zgodnie z obietnicą drugi wpis na ten temat, w którym skupimy się na tym, jak takie skrypty się tworzy, a jest to w gruncie rzeczy całkiem prosty proces.

Do przetworzenia dalszej części wpisu, potrzebny będzie nam najzwyklejszy notatnik (polecam w tym przypadku Notepad++ oraz minimalna wiedza związana z tworzeniem skryptów w JavaScript.

Pierwszy skrypt

Tak jak wspomniałem wcześniej, tworzenie skryptów Greasemonkey jest proste. Dla przykładu, poniższy kod jest w pełni poprawnie napisanym skryptem:

alert('Hello World');

Prosty, prawda? Ale UWAGA. Zanim uruchomicie ten skrypt, przeczytajcie koniecznie kolejny akapit.

Ponieważ kod powyższego skryptu, nie zawiera żadnych dodatkowych informacji, to wykona się on zawsze, na każdej stronie (aby to zmienić, należy skorzystać z metadanych - o tym trochę później). Jeśli włączymy go np. Alt Control Delete, to alert ujrzymy kilkukrotnie na każdej podstronie, m.in. za sprawą użytych na stronie znaczników IFrame z których korzysta np. facebookowy fanpage. Można jednak przetestować skrypt, choćby na jednej podstronie by sprawdzić, że działa:)

A w jaki sposób zainstalować interesujący nas skrypt? Sposób postępowania uzależniony jest od przeglądarki:

  • Firefox - musicie spełnić wszystkie założenia, o których mówiłem w poprzednim wpisie. Następnie, wystarczy z katalogu w którym mamy zapisany skrypt, przeciągnąć go do otwartego okna przeglądarki
  • Chrome - przeciągamy plik skryptu z katalogu do okna przeglądarki, a następnie instalujemy w sposób opisany w poprzednim wpisie
  • Opera - konfigurujemy przeglądarkę w sposób opisany w poprzednim wpisie, a następnie umieszczamy plik we wskazanym w konfiguracji katalogu. W przypadku Opery, pamiętajcie o fakcie, że nie wszystkie skrypty Greasemonkey, mogą w tej przeglądarce działać poprawnie

Niezależnie od przeglądarki, skrypty użytkownika powinny znajdować się w plikach, których nazwa pasuje do maski *.user.js. W naszym przypadku może to być np. plik alert.user.js. Po instalacji, skryptami możecie zarządzać w sposób opisany w poprzednim wpisie.

Metadane

Napisaliśmy już pierwszy skrypt, ale w gruncie rzeczy nie ma się co oszukiwać, że jest on skrajnie bezużyteczny i tylko wkurzy przeciętnego użytkownika. Poza tym, nie niesie on ze sobą żadnej sensownej informacji np. jaka jest jego nazwa, przeznaczenie; na jakich stronach ma być uruchomiany itp..

Wszystkie tego typu informacje, możemy zdefiniować właśnie w metadanych. A czym tak właściwie one są? Metadane, to specjalna sekcja, którą umieszczamy na początku pliku i powinna się rozpoczynać oraz kończyć w następujący sposób:

// ==UserScript==
// metadane... 
// ==/UserScript==

Znacznik UserScript jest ważny i nie można go pominąć. W innym przypadku, metadane po prostu nie zadziałają i staną się zwykłym komentarzem - taki też oczywiście jest możliwy.

Spójrzmy teraz na kolejny przykład poprzedniego błyskotliwego skryptu, który w tym przypadku, będzie mieć wyjątkowo rozwinięte metadane:

// ==UserScript==
// @name        Alert
// @namespace	/www/
// @description	Wyświetla komunikat alert na określonych witrynach
// @include	    http://google.tld/*
// @exclude	    http://google.com/*
// @require     http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js
// ==/UserScript==
// Standardowy komentarz
alert('aaa');

Przeanalizujemy teraz, co się zmieniło w naszym skrypcie. Przede wszystkim, pojawiła się sekcja metadanych, która zgodnie z tym co napisałem wcześniej, rozpoczyna się specjalnym znacznikiem w linii 1 i kończy w linii 8.

W linii 2, widzimy dyrektywę @name, która pozwala określić nazwę skryptu jaka będzie się wyświetlać w przeglądarkach. Jeśli jej nie zdefiniujemy, to zostanie zastosowana wartość domyślna, a jest nią nazwa pliku skryptu bez rozszerzenia .user.js.

W linii 3, definiujemy przestrzeń nazw. Dzięki temu, Greasemonkey jest wstanie odróżnić skrypty, które mają takie same nazwy, ale różnych autorów. Jeśli mamy swoja domenę, będzie to świetny sposób na unikalną przestrzeń nazw. Jak widzicie, osobiście skorzystałem z domeny blogu dodając fikcyjny katalog www - chodzi tylko o unikalną przestrzeń dla naszych skryptów. Pamiętajcie jednak o tym, że dla wszystkich Waszych skryptów (o ile tylko różnią się nazwami) wystarczy jedna przestrzeń nazw. Jeśli nie macie własnej domeny, możecie skorzystać z tag URI.

W linii 4, definiujemy opis skryptu, czyli notabene możemy tu napisać krótko i zwięźle, jakie jest jego przeznaczenie.

W linii 5 i 6, widoczne są dwie dyrektywy, które pozwalają na dołączanie adresów, na których skrypt ma działać (@include) oraz wyłączanie innych adresów, na których skrypt NIE ma działać (@exclude). Każda z tych dyrektyw może pojawić się dowolną ilość razy. W moim przypadku, postanowiłem że skrypt będzie działać na wszystkich top level domains (stąd skrót tld użyty w dyrektywie) z wyłączeniem domeny www.google.com.

Trick z użyciem .tld w nazwie domeny jest bardzo pożyteczny. Dzięki temu unikniemy wypisywania kolejnych domen z rodziny Google, czyli np. www.google.pl, www.google.de, www.google.co.uk itd., ponieważ .tld zabiera sobie wszystkie domeny głównego poziomu.

Zwróćcie jeszcze uwagę na gwiazdkę. Gwiazdką oznacza dopasowanie wszystkiego, czyli jeśli podajemy dyrektywę:

// @include http://www.google.pl/*

Oznacza to, że zostaną dopasowane wszelkie elementy w obrębie domeny www.google.pl.

Gwiazdka ma jednak jeszcze większą moc, aniżeli z pozoru by się wydawało . Jeśli skorzystamy np. z takiej konstrukcji:

// @include *

Oznacza to, że chcemy korzystać z naszego skryptu na każdej stronie. Gwiazdkę możemy również zastosować w @exclude. Pamiętajcie, że w tym przypadku kolejność zapisywania dyrektyw ma znacznie. Popularnym rozwiązaniem jest również załączenie gwiazdki w dyrektywie @include oraz kilku wybranych domen w obrębie @exclude, dla których skrypt nie będzie działać.

Ostatnią dyrektywę (@require) widzimy w linii 7. Dyrektywa ta, pojawiła się dopiero w wersji 0.8 skryptów Greasemonkey i pozwala na import dodatkowych zasobów do naszego skryptu. Głównie używana jest np. celem podpięcia zewnętrznych bibliotek. Dyrektywa ta, działa w sposób przemyślany, ponieważ plik z zadanego adresu pobierany jest tylko raz, podczas instalacji skryptu, co jest bardzo wygodnym i efektywnym rozwiązaniem i wykorzystywanym np. do importu biblioteki jQuery. Niestety, z tego co czytałem na stronie projektu, nie wszystkie biblioteki jQuery. działają. Działa np. 1.3.2, ale występowały problemy z 1.4.1. Nie wiem jak jest z obecnymi wersjami.

Bardziej praktyczny przykład

W przykładzie praktycznym, wrócimy do problemu jednego z czytelników, który pojawił się na Google+ i który brzmiał następująco:

Zna ktoś sposób, aby domyślnie/na stałe włączyć wyświetlanie rozdzielczości na każdym z obrazków podczas wyszukiwania obrazów Google?

Rozwiązanie za pomocą skryptów Greasemonkey jest bardzo proste i możecie je znaleźć na poniższym listingu:

// ==UserScript==
// @name          Obrazy Google
// @namespace     /userscripts/
// @description	  Pozwala na ustawienie wymiarów obrazu za pomocą okienka prompt
// @include       http://google.tld/*
// @include       http://www.google.tld/*
// ==/UserScript==

var oImgSearchButton = document.getElementById('iszex_btn');
if(null != oImgSearchButton){
	var sSize = prompt("Wprowadź szerokość oraz wysokość obrazka rozdzielone " + 
		"średnikiem, bądź wprowadź jedną wartość jeśli obrazek ma być kwadratem."
	);
	if((null != sSize) && ('' != sSize)){
		anSizes = sSize.split(';');
		if(anSizes.length > 1){
			document.getElementById('iszw').value = anSizes[0];
			document.getElementById('iszh').value = anSizes[1];
		} else {
			document.getElementById('iszw').value = anSizes[0];
			document.getElementById('iszh').value = anSizes[0];		
		}
		oImgSearchButton.click();
	}
}

Przejdźmy teraz do analizy kodu. W liniach 1-7, znajdziecie opisywane wcześniej metadane - tutaj raczej bez niespodzianek. Chcemy by skrypt działał w obrębie domeny Google każdego kraju.

Właściwy kod, zaczynamy od linii 9. W tym momencie, odszukujemy na stronie przycisk Szukaj widoczny na ekranie wyszukiwania grafiki dla obrazków o znanym rozmiarze (patrze screen 2).

Dzięki temu, że znaleźliśmy przycisk Szukaj, będziemy mogli zrobić wiele pożytecznych rzeczy:

  • Poznać identyfikator tego przycisku za pomocą Firebuga, lub narzędzi dla programistów Chrome
  • Uzależnić możliwość działania naszego skryptu od obecności tego przycisku na aktualnie wyświetlanej stronie (na nie każdej stronie w obrębie domeny Google będzie on widoczny, w ten sposób unikniemy zbędnych błędów lecących do konsoli)
  • Zrealizować wyszukiwanie według naszych kryteriów

Wszystko jednak po kolei. Wróćmy do linii 9. Jak udało mi się ustalić za pomocą Firebuga, przycisk Szukaj widoczny na screenie 2, posiada identyfikator iszex_btn. Pobieramy go zatem i zapisujemy do zmiennej - przyda się później.

Jeśli w linii 10, okaże się że nie udało się pobrać elementu o takim identyfikatorze (czytaj - nie istnieje on na aktualnie wyświetlanej stronie), to kończymy działanie naszego skryptu. W przeciwnym przypadku, realizujemy wnętrze instrukcji if.

W 11-13, wykazujemy się interaktywnością i wyświetlamy użytkownikowi okienku typu prompt, w którym będzie mógł wprowadzić szerokość i wysokość miniaturki. Wymiary zwracamy do zmiennej sSize.

W zadanym okienku, możemy wprowadzić wymiary w następujący sposób:

  • Podając szerokość i wysokość obrazka rozdzielone średnikiem, czyli np. 400;300
  • Podając długość krawędzi jednego boku np. 400 (przydatne gdy obrazek jest kwadratem)
  • Nie podając nic - zakończy to przetwarzanie

Musimy zatem sprawdzić, czy wartość od użytkownika, nie jest pusta i nie jest nullem. Jeśli nasz warunek (14) zostanie spełniony, to zostanie nam obsługa 1 i 2 wariantu z listy, którą przedstawiłem powyżej.

W linii 15, korzystamy z funkcji split (założyłem, że moim separatorem będzie średnik). Nawet jeśli użytkownik podał jedną wartość, to tak ona zadziała w sposób prawidłowy.

W liniach 16-22 ustawiamy wymiary obrazka. Jeśli użytkownik podał szerokość i wysokość, to korzystamy z linii 17 oraz 18. Zwróćcie tutaj uwagę na identyfikatory pól - te również pozyskałem Firebugiem (pola nad przyciskiem szukaj widocznym na screenie 2).

Jeśli nasza tablica jest jednoelementowa (czytaj - użytkownik podał jeden wymiar), to podstawiamy go zarówno dla pola związanego z szerokością jak i wysokością (linie 20-21).

Na zakończenie, symulujemy zdarzenie kliknięcia na przycisku Szukaj, do którego referencję wcześniej umieściliśmy w zmiennej.

Docelowy rezultat, będzie się prezentować mniej więcej tak, jak na screenie 2.

Podsumowanie

Wszystkie przedstawione skrypty w niniejszym wpisie, zostały przetestowane w Firefoksie i funkcjonowały poprawnie. Skrypty testowałem również na Chrome, jednak na jednej z instalacji tej przeglądarki, występowały problemy z poprawną interpretacją dyrektyw @include oraz @exclude - nie wiem czym jest to spowodowane..

Ukazane w tym wpisie aspekty, to zasadniczo tylko podstawy tego, co można zrobić za pomocą skryptów użytkownika. Jeśli będzie zainteresowanie tematem, mogę napisać kolejne wpisy na ten temat. Wkrótce, prawdopodobnie pojawi się kolejny wpis związany z tą tematyką, w którym postaram się zaprezentować ciekawe skrypty dla szerszego grona odbiorców.

W razie pytań/sugestii/zażaleń, zapraszam do komentarzy.

Skrypt można zainstalować dla testów stąd.

Przydatne linki

Data ostatniej modyfikacji: 27.03.2012, 08:50.

Komentarze

blog comments powered by Disqus