Mozilla AccountManager

Ciekawostka dla wszystkich web developerów.

Mozilla chce nam ułatwić automatyczne logowanie na stronach. Kojarzycie pewnie ten checkbox “zapamiętaj mnie” gdy logujesz się do portalu – dzięki temu teoretycznie nie musisz za każdym razem logować się, gdy Twoja sesja wygaśnie. Czasem to działa, czasem nie ;)

Jednak już niedługo portal będzie mógł wystawić specjalnie spreparowany dokument (JSON) w którym powiemy przeglądarce jak spreparować żądanie (np. POST) aby wchodząc na stronę zalogowała się za nas przed samym wyświetleniem strony.

Myślę, że nie jest to jakiś killer feature, ale wygląda to na krok w dobrą stronę jeśli chodzi o wygodę. W momencie, gdy działa mechanizm który opisałem na początku implementowany już teraz na stronach – tak naprawdę nie zauważymy różnicy. Jeśli jednak cookie, w którym są przechowywane informacje o tym, że jesteś zalogowany z jakichś powodów zniknie – przed nami taki scenariusz (optymistyczny)

  1. zauważam, że na stronie jestem niezalogowany
  2. klikam jakiś link zaloguj
  3. znów zaloguj, tym razem button formularza
  4. ląduję na stronie, którą od początku chciałem zobaczyć

A teraz wariant pesymistyczny:

  1. Wchodzę na stronę (np. forum)
  2. czytam ciekawy wątek i chcę odpowiedzieć (albo gorzej – już odpowiadam)
  3. jestem zaskoczony, bo nie jestem zalogowany
  4. klikam zaloguj
  5. wysyłam formularz
  6. ląduję na głównej stronie i nie mogę znaleźć wątku na który odpisywałem
  7. opuszczam stronę zirytowany
  8. wychodzę na ulicę i szukam zaczepki
  9. trafiam na mistrza sztuk walki i dostaję srogi łomot
  10. ląduję w szpitalu i zarażam się żółtaczką typu C…
  11. która powoduje raka wątroby
  12. umieram i już nigdy nie wracam na ten nieszczęsny portal

Nie wiem jak Tobie, ale mnie nie brzmi to jak dobre usability… szczególnie od ósmego punktu jest naprawdę kiepski User eXperience, który może zaważyć na być, albo nie być Twojego portalu.

Na razie jest ten ficzer dostępny jako dodatek – mozilla pracuje nad specyfikacja i zachęca do współpracy.

Ciekawa lektura filozoficzno-matematyczna, w sam raz na popołudnie

Ciekawy wywiad zamieszczony w dodatku Polityki (niezbędnik inteligenta) – zachęcam Was do niego, z tego względu, że wiele programistów, których znam, lubi tego typu rozważania.

A co Ty uważasz? Czy za wszystkimi zjawiskami stoi model matematyczny? Czy wszechświat jest nieskończonym komputerem obliczających w każdym momencie swój kolejny stan? Czy liczby całkowite są bardziej rzeczywiste niż, ekhm, rzeczywiste?

Jak zrobić callback w javascript – minitutorial.

Jedną z największych magicznych mocy wszystkich frameworków i pluginów javascript jest możliwość rozszerzenia ich działania poprzez tak zwane callbacks. Pokażę Wam jak wykonać własny obiekt javascript, który będzie potrafił je obsłużyć.

Po pierwsze potrzebujesz zdefiniować swoją klasę:

function myClass(params){
}

Prościzna ;) Spróbujmy teraz obsłużyć callback beforeInit, który odpali się “najsampierw” przy tworzeniu obiektu:

function myClass(params){
    if(params.beforeInit){
        console.log("beforeInit");
        params.beforeInit();
    }
    console.log("Init complete")
}
console.log("=============");
var a = new myClass(
  {
    beforeInit: function(){console.log("My message!");}
  }
);

Włącz firebuga i sprawdź działanie ;)

=============
beforeInit
My message!
Init complete

Oczywiście Twoja klasa może zechcieć coś zrobić oprócz stworzenia siebie samej ;) Callbacki mogą zachowywać się różnie w zależności od stanu obiektu. Do klasy dodałem metodę doSth i callback beforeRun (który wykonuje się przed wykonaniem metody doSth)

Wypróbuj następujący kod:

function myClass(params){
    if(params.beforeInit){
        console.log("#beforeInit");
        params.beforeInit();
    }

    this.doSth = function() {
        if(params.beforeRun){
            params.beforeRun(this.state);
        }
        console.log("#doSth");
    }

    if(params.state) {
        this.state = params.state;
    }else{
        this.state = false;
    }

    console.log("Init complete")
}
console.log("=============");
var a = new myClass(
  {
    state: 1,
    beforeRun: function(state){
        if(state != false) {
            console.log("Extended! state = " + state);
        }else {
            //do nothing
        }
    }
  }
);
a.doSth();
console.log("=============");
var b = new myClass(
  {
    beforeRun: function(state){
        if(state != false) {
            console.log("Extended! state = " + state);
        }else {
            //do nothing
        }
    }
  }
);
b.doSth();

wynik:

=============
Init complete
Extended! state = 1
#doSth
=============
Init complete
#doSth

Możesz też uzależnić wykonanie metody doSth w zależności od warunków wewnętrznych (parametr state) lub zewnętrznych:

function myClass(params){
    if(params.beforeInit){
        console.log("#beforeInit");
        params.beforeInit();
    }

    this.doSth = function() {
        if(params.beforeRun){
            if(!params.beforeRun(this.state)){
                return;
            }
        }
        console.log("#doSth");
    }

    if(params.state) {
        this.state = params.state;
    }else{
        this.state = false;
    }

    console.log("Init complete")
}
console.log("=============");
var a = new myClass(
  {
    state: 1,
    beforeRun: function(state){
        if(state != false) {
            console.log("Extended! state = " + state);
        }else {
            return false
        }
    }
  }
);
a.doSth();
console.log("=============");
var b = new myClass(
  {
    beforeRun: function(state){
        if(state != false) {
            console.log("Extended! state = " + state);
        }else {
            return false
        }
    }
  }
);
b.doSth();
console.log("=============");
var c = new myClass(
  {
    beforeRun: function(state){
        if( (new Date().getTime())%2  ) {
            console.log("Extended! state = " + state);
        }else {
            return false
        }
    }
  }
);
c.doSth();

Wynik (zależy od aktualnego czasu, więc może okazać się konieczne uruchomienie go kilka razy, zanim otrzymasz identyczny):

=============
Init complete
Extended! state = 1
=============
Init complete
=============
Init complete
Extended! state = false

W przypadku obiektu c metoda run odpali się tylko, jeśli aktualny timestamp jest podzielny przez 2 ;)

To tyle. Mam nadzieję, że pozwoli Wam to wymyślać ciekawsze i bardziej użyteczne fragmenty kodu javascript, nawet tego używanego prywatnie.

Sprytnie zaprojektowana klasa ze sprytnymi callbackami jest bardzo przyjemna – możliwe jest modyfikowanie jej zachowania bez modyfikacji klasy bazowej. To samo podejście znacie pewnie z Behaviors cake’a.