Cum să contribui la programe libere

Pentru că nu am reușit încă să mă descurc bine cu Gnus din Emacs, de câteva luni folosesc pragmatic RoundCube Webmail pentru contul meu @fii-liber.ro, pe care l-am găsit instalat de Andrei Nistor (codertux).

Utilitatea programului

Nu îmi pot citi corespondențele când nu sunt conectat la Internet, nu îmi pot folosi editorul preferat să răspund dar măcar nu trebuie să aștept să se încarce toată pagina pentru a-mi organiza căsuța poștală. RoundCube, spre deosebire de SquirrelMail, are o interfață prietenoasă ce folosește AJAX, ca Gmail și Yahoo! Mail (după cum știm, proprietare, țțțîî!).

Problema

Tot folosind aplicația asta, am observat o eroare în interfață: filtrul după mesaje {Toate, Necitite, Marcate, Fără răspuns, Șterse} rămâne selectat chiar dacă dau clic în tabelul cu mesajele filtrate, în versiunea 0.3.1-svn dar și în cea stabilă 0.4.2, după actualizare.

Efectele pot fi neplăcute dacă navighezi în sus și în jos cu săgețile prin tabelul mesajelor, pentru că se modifică în același timp și selecția filtrului. Te poți trezi apoi că RoundCube îți refiltrează mesajele după alt criteriu decât cel dorit.

Inițiativa

Pentru că e liber, deci pot vedea și modifica codul dacă am aplicația, m-am gândit să repar chiar eu problema. Niciodată nu mai scrisesem un petic la codul vreunui program liber cunoscut, decât raportasem probleme, așa că am tras sursele din depozitul svn, am inspectat pagina cu Firebug ca să aflu identificatorii filtrului (rcmlistfilter), tabelului (messagelist) și mesajelor (rcmrow + $id) și pe urmă am început să caut cu grep prin surse după ele.

Depanarea

Încercând să înțeleg cum interacționează componentele, am ajuns cu căutarea la fișierul JavaScript program/js/app.js. Căutând prin cod să văd ce funcție apelează pe care, am observat că set_message() apelează alte funcții ce operează asupra mesajelor, set_message_status() și set_message_icon(). Am încercat acolo să introduc:

alert('Mesaj');

pentru a verifica dacă atunci când dau clic pe un mesaj, rulează și linia mea de cod (dacă da, ar fi trebuit să-mi apară o fereastră de dialog cu mesajul dat ca argument). Dar nu rula.

Perseverența

O primă tentativă eșuată și o lecție învățată. Am mers mai departe.  Reluând căutarea prin cod după cuvinte cheie ca "list", "click", etc., am găsit și funcția msglist_click(). Am încercat și acolo alert('Mesaj') și surprizător (sau nu :-P) Firefox începuse să-mi arate o fereastră de dialog ori de câte ori dădeam clic pe un mesaj. Descoperisem locul unde puteam să apelez deselectarea filtrului.

Soluția

Dar cum se deselectează un element HTML din JavaScript? Printr-o simplă căutare pe Internet, am găsit funcția blur(), care are efect invers funcției focus(). Știam că pot obține elementul HTML după identificator cu document.getElementById(), așa că fără să mai stau pe gânduri, am scris după antetul funcției msglist_click() linia de cod:

document.getElementById("rcmlistfilter").blur(); 

Contribuția

Am testat și într-adevăr, problema se rezolvase. La selectarea unui mesaj, se deselecta filtrul, așa cum ar fi fost normal de la început. Dar cum să fac să fie rezolvată problema și în distribuția oficială de RoundCube?

Am căutat din nou pe Internet cum se face un petic folosind diff și am găsit un tutorial scurt și pe înțeles, numai bun.  Am creat peticul:

*** roundcube-svn/roundcubemail/program/js/app.js2010-11-14 13:14:02.430060359 +0200
--- roundcube-tct/roundcubemail/program/js/app.js2010-11-14 13:19:43.814058621 +0200
*** 1439,1444 ****
--- 1439,1447 ----
    // This allow as to re-select selected message and display it in preview frame
    this.msglist_click = function(list)
    {
+     // hack to unfocus list filter on GNOME and KDE
+     document.getElementById("rcmlistfilter").blur();

l-am testat și l-am adăugat raportului #1487123 de pe trac.roundcube.net, în care nu am uitat să specific în ce versiuni de RoundCube am depistat problema, ce navigatoare am folosit și ce sistem de operare:

  • Roundcube: 0.3.1, 0.4.2, svn-trunk
  • Browser: Firefox, Konquerer
  • GNU/Linux: Ubuntu (GNOME), Fedora (GNOME), Chakra (KDE)

Reacția comunității

De asemenea, nu am uitat să scriu cum se poate reproduce problema, pentru ca oricine altcineva să știe cum poate verifica problema și soluția. La câteva ore, unul dintre dezvoltorii principali (Aleksander Machniak) a scris că va aplica modificarea în versiunea 0.5-beta, iar după o zi a venit cu o soluție mai bună, care deselectează toate elementele selectate, pe care le obține cu $('*:focus'). Și a și aplicat modificarea în depozitul svn. Drăguț, nu?

--- /trunk/roundcubemail/program/js/list.js (revision 4221)
+++ /trunk/roundcubemail/program/js/list.js (revision 4224)
@@ -221,4 +222,7 @@
     }
   }
+
+  // Un-focus already focused elements
+  $('*:focus').blur();

Conculzia

Cu totul: documentare, modificare, testare și raportare, mi-a luat 4 ore, nefiind obișnuit cu JavaScript, dar eu zic că a meritat. Am reparat o problemă sâcâitoare a acelei interfețe, în rest, prietenoasă. Pentru mine și ceilalți utilizatori. Și tu poți să iei atitudine!