Chiudi

 

Blog ad Improbabilità Infinita

L'unico blog che può trasformarvi in una balena o in un vaso di petunie

Feed RSS / Commenti RSS APML

Il Panda Rosso e il Meccanico

Scritto il 16 September 2006 alle 15:36

Greasemonkey (tradotto significa meccanico) è un'extension scritta per il browser Mozilla Firefox (per chi non lo sapesse, la parola Firefox è una traduzione letterale dal cinese e significa panda rosso) che permette di utilizzare degli script che modificano "al volo" determinate pagine web tramite l'utilizzo di Javascript.

Di per sè, questa estensione non fa altro che eseguire del codice Javascript contenuto in quelli che vengono definiti user script. Gli user script contengono un riferimento alle pagine web al caricamento delle quali deve essere eseguito il codice Javascript contenuto negli stessi.


Gli utilizzi classici possono essere:

  • rimuovere annunci pubblicitari e/o popup;
  • dare la possibilità di salvare video presenti su YouTube o Google Video;
  • aggiungere o rimuovere caratteristiche legate all'accessibilità (come link per raggiungere più velocemente una pagina o rimuovere link mai utilizzati);
  • modificare la struttura (layout) e la presentazione (skin) di una pagina a proprio piacimento;
  • riempire automaticamente dei form;
  • visitando un sito commerciale, dare la possibilità di vedere i prezzi degli stessi prodottti presenti su altri siti;
  • ...e l'elenco può essere infinito.

I passi fondamentali da seguire per installare questa estensione sono descritti in modo molto user-friendly sul sito ufficiale http://greasemonkey.mozdev.org/, quindi non mi dilungo.

Piuttosto passerei ad analizzare lo scheletro di uno user script, utilizzando come esempio uno semplice che ho scritto per modificare il sito Repubblica.it reperibile all'indirizzo:

http://gboccard.web.cs.unibo.it/js/greasemonkey/repubblicaMOD.user.js

Innanzittuto, il nome dello script deve terminare con l'estensione ".user.js". Questo fa sì che, una volta installata l'extension, Firefox riconosca la natura dello script e aggiunga in alto a destra nella pagina un bottone (Install) che permette semplicemente di installare lo script.

La prima parte dello script contiene i metadati che descrivono lo script stesso:

// ==UserScript==
// @name Repubblica.it MOD
// @namespace http://gboccard.web.cs.unibo.it
// @description Alcune modifiche al sito Repubblica.it
// @include http://*.repubblica.it
// ==/UserScript==

Le differenti parti sono:

  • il cosiddetto wrapper è la sezione che contiene tutti gli altri metadati; può essere introdotta in qualsiasi posizione sensata nello script, ma è buona norma metterla all'inizio; inoltre deve rispettare esattamente la seguente sintassi:
  • // ==UserScript==
    // ...
    // ==/UserScript==

  • @name permette di indicare il nome dello script, così come verrà mostrato quando lo si installa o lo si gestisce in un'apposita finestra. Benché sia opzionale, è assolutamente consigliato specificare un nome, possibilmente corto, altrimenti di default viene utilizzato il nome del file privato dell'estensione ".user.js";
  • @namespace consente di fornire un URL per differenziare script aventi lo stesso nome, ma creati da autori differenti. Nonostante sia opzionale, conviene specificarlo, altrimenti di default si assume quello del dominio da cui viene scaricato lo script;
  • @description è una descrizione delle funzionalità dello script. Pur essendo opzionale, è buona norma inserirla per dar modo all'utente di capire la funzione che svolge lo script: non si può assumere che l'utente debba capire dal codice cosa è in grado di fare lo script;
  • @include serve a specificare alla visita di quali siti deve essere eseguito lo script; per specificare più URL (senza l'uso di wildcard) bisogna ripetere il metadato su più righe; inoltre, è possibile utilizzare la wildcard "*" per indicare un match con una qualsiasi sequenza di caratteri (anche nulla): ad esempio, http://*.repubblica.it fa match con tutte le pagine aventi un URL che inizia con "http://", che prosegue con una qualsiasi sequanza di caratteri (quindi, ad esempio, www, multimedia, finanza, ecc.) e che termina con la stringa ".repubblica.it". Anche questo metadato è opzionale, ma se non lo si mette assume di default il valore "*", causando l'esecuzione dello script su tutti i siti;
  • @exclude utilizza la stessa sintassi di @include, ma serve, come dice il nome, ad escludere uno o più siti dall'esecuzione dello script.

La parte restante dello script non è altro che codice Javascript con l'aggiunta di nuove API introdotte da Greasemonkey, che facilitano alcune operazioni comuni.

Per chi è alle prime armi con Javascript, una riflessione fondamentale: gli user script vengono eseguiti mentre viene caricata la pagina, quindi non è detto necessariamente che tutti gli elementi su cui compiono le operazioni per cui sono scritti siano presenti nella pagina nel momento dell'esecuzione. Questo naturalmente causa il malfunzionamento dello user script stesso. Il problema si risolve semplicemente associando all'evento onload della pagina una chiamata a funzione: tale funzione verrà invocata solamente quando l'intera pagina è stata caricata completamente. Per fare ciò consiglio di utilizzare questa funzione (utilizzabile anche in altri contesti, poiché cross-browser):

function addEvent(obj, evType, fn){
   if(obj.addEventListener) 
       obj.addEventListener(evType, fn, false);
   else if(document.addEventListener && obj == window) 
       document.addEventListener(evType, fn, false);
   else {
       if(!obj[evType]) obj[evType] = new Array;
       if(!obj[fn]) obj[fn] = fn;
       obj[evType][obj[evType].length] = obj[fn];
       obj["on" + evType] = function(){
           for(var i = 0; i < obj[evType].length; i++){
               obj[obj[evType][i]](window.event);
           }
       };
   }
}

Come si può veder dal mio user script di esempio, tale funzione viene invocata così:

addEvent(window, "load", jackallOnLoad);

e l'unico parametro da modificare per i propri scopi è il terzo, che deve essere il nome della funzione da invocare quando la pagina è completamente caricata.

Per chi non avesse intuito cosa fa il mio user script, le azioni sono semplici, ovvero si limita a centrare il contenuto della pagina principale del sito:

document.getElementsByTagName("body")[0].
     getElementsByTagName("table")[0].style.margin="auto";

e modificare il logo principale in tutte le pagine che lo contengono:

document.getElementById("brand").
     getElementsByTagName("img")[0].src=newLogo;

Per chi fosse curioso, quella roba strana assegnata alla variabile newLogo è una immagine jpeg convertita in base64, in modo da poter essere embedded nel codice Javascript.

Uno script carino e più utile è questo:

http://gboccard.web.cs.unibo.it/js/greasemonkey/googleX.user.js

viene applicato alle pagine di Google e sostituisce la barra contenente i radio button Web, Immagini, Gruppi, ecc. con una barra stile Mac:

greasemonkey-googlex.png

Non è una mia idea, ma ho speso un po' di tempo per adattare la versione che avevo trovato per farla funzionare con le nuove pagine di Google. Sicuramente da provare.

Eccovi una linkografia dei siti più o meno strettamenti correlati all'argomento:


Post attinenti:

5 commenti ↓

  • 1 giovannaNo Gravatar ~ 16/09/2006 @ 22:47:37

    Fire = fuoco
    Fox = volpe

    Firefox= panda rosso??????
    -.-

  • 2 JhacKNo Gravatar ~ 16/09/2006 @ 23:05:40

    Beh, al limite è peggio:

    Grease: grasso (sostantivo)
    Monkey: scimmia
    Greasemonkey: meccanico
    😀

    Comunque "firefox" significa davvero "panda rosso"; per convincerti ho fatto una piccola ricerca su Google e ti segnalo il primo link ad un sito che reputo autorevole (quindi non, ad esempio, la Wikipedia, che compare prima tra i risultati): http://www.wellingtonzoo.com/animals/animals/mammals/panda.html

    Se cerchi in quella pagina la parola "firefox" vedrai che è la traduzione in inglese del nome cinese che indica il panda rosso.

    Ciauz.

  • 3 SteNo Gravatar ~ 18/09/2006 @ 09:14:02

    Ma allora, se Firefox = Panda rosso, come mai l'icona di Firefox assomiglia più a una volpe in mezzo a fiamme!?!?

    :-PP

  • 4 parideNo Gravatar ~ 18/09/2006 @ 09:17:56

    La traduzione e' stata fatta dal cinese all'inglese e non dall'inglese all'italiano.

  • 5 JhacKNo Gravatar ~ 18/09/2006 @ 10:25:38

    @Ste: beh, dai, visto di spalle può essere tranquillamente un panda rosso 😛

    @paride: dove ho scritto che fosse la traduzione dall'inglese all'italiano?

Commentami!

Puoi utilizzare i seguenti tag XHTML <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>