<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><title>Zapiski na Koszulce</title><link>http://blog.koszulinski.pl/</link><description>Wpisy z dziennika internetowego Jogger, wspomaganego przez Jabbera</description><lastBuildDate>Thu, 29 Jul 2010 14:41:00 +0200</lastBuildDate><generator>JoggerPL</generator><item><title>Dwukolumnowa lista definicji (edit: w HTML5 lista opisów (?))</title><link>http://blog.koszulinski.pl/2010/04/04/dwukolumnowa-lista-definicji/</link><description>&lt;p&gt;Będzie krótko, bo jutro święto jakieś :)&lt;/p&gt;
&lt;p&gt;Od bardzo dawna przy wielu stronach natrafiałem na problem w jaki sposób ostylować listę &lt;del&gt;definicji&lt;/del&gt; &lt;ins&gt;opisów (patrz komentarze)&lt;/ins&gt; &lt;code&gt;dl&lt;/code&gt;, tak aby elementy &lt;code&gt;dt&lt;/code&gt; wyświetlały się na lewo od elementów &lt;code&gt;dd&lt;/code&gt;. Przy czym kod musiał spełniać warunki:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;lista musiała się nie rozsypywać w przypadku różnej wysokości elementów &lt;code&gt;dt&lt;/code&gt; i &lt;code&gt;dd&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;szerokość listy mogła być zmienna,&lt;/li&gt;
&lt;li&gt;ustaloną szerokość miały elementy &lt;code&gt;dt&lt;/code&gt;. Elementy &lt;code&gt;dd&lt;/code&gt; miały się rozszerzać do maksymalnej dostępnej szerokości.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nigdy nie miałem ochoty się w ten problem zagłębiać i jeśli już stałem pod ścianą to każdy &quot;wiersz&quot; takiej listy pakowałem do osobnego elementu &lt;code&gt;dl&lt;/code&gt;, co rozwiązywało najtrudniejszy problem, czyli odpowiedniego ułożenia elementów w pionie. W sumie, to z tego niezbyt pięknego rozwiązania korzystałem często, bo w ten sposób używam listy definicji do tworzenia formularzy.&lt;/p&gt;
&lt;p&gt;Ostatnio postanowiłem jednak rozwiązać swój odwieczny problem i po wielu próbach — między innymi z różnymi kombinacjami &lt;code&gt;float&lt;/code&gt;ów, &lt;code&gt;display:inline-block&lt;/code&gt; i wieloma dziwactwami — udało mi się znaleźć kilka rozwiązań, które działały, ale np. do momentu kiedy nie rozszerzyło się całej listy do sporej szerokości, albo nie nastąpił jakiś przypadek stosunków szerokości. Wpadłem jednak przed chwilą na rozwiązanie, które działa w każdym interesującym mnie przypadku i aż chcę się pochwalić :).&lt;/p&gt;
&lt;p&gt;Skrócony kod HTML:&lt;/p&gt;
&lt;p&gt;{geshi lang=html}&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Widelec&lt;/dt&gt;
&lt;dd&gt;Jest biały i leży na moim biurku.&lt;/dd&gt;
&lt;dt&gt;Widelec&lt;/dt&gt;
&lt;dd&gt;Jest biały i leży na moim biurku.&lt;/dd&gt;
&lt;dt&gt;...&lt;/dt&gt;
&lt;/dl&gt;
&lt;p&gt;{/geshi}&lt;/p&gt;
&lt;p&gt;I skrócony kod CSS:&lt;/p&gt;
&lt;p&gt;{geshi lang=css}dl { width: 70%; min-width: 40em; overflow: hidden; ... } dt { float: left; width: 15em; clear: both; ... } dd:after { content: '\00a0'; display: block; clear: left; float: right; height: 0; width: 0; } dd { margin: 0 0 0.5em 18em; clear: right; ... }{/geshi}&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://pacman.mulabs.org/ts/dlls3.html&quot;&gt;Działający przykład&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cała magia zawiera się w regule dla &lt;code&gt;dd:after&lt;/code&gt;. To ona powoduje, że jeśli element &lt;code&gt;dt&lt;/code&gt; jest wyższy od następującej po nim definicji, to następna definicja jest wyświetlana w odpowiednim miejscu (nie przeskakuje ponad swój temat).&lt;/p&gt;
&lt;p&gt;Wesołego jajka. Idę spać :)&lt;/p&gt;
</description><pubDate>Sun, 04 Apr 2010 01:36:01 +0200</pubDate><guid>http://blog.koszulinski.pl/2010/04/04/dwukolumnowa-lista-definicji/</guid><category>CSS</category><category>Frontend</category><category>HTML</category><category>Ogólne</category><category>Techblog</category></item><item><title>WTFJS - rozjaśnienie umysłu</title><link>http://blog.koszulinski.pl/2010/03/06/wtfjs-rozjasnienie-umyslu/</link><description>&lt;p&gt;&lt;a href=&quot;http://wtfjs.com/&quot;&gt;Blog WTFJS o dziwactwach w JavaScriptcie&lt;/a&gt; widział już pewnie każdy. Niektóre przykłady są naprawdę fajne :) Co więcej — niektóre działają mi w sposób przedstawiony przez autorów tylko czasami, choć to pewnie nie problem JavaScriptu, a Firebuga :).&lt;/p&gt;
&lt;p&gt;Jako, że lubię wiedzieć dlaczego tak to działa, a nie inaczej, staram się wyjaśnić sobie o co chodzi w każdym przykładzie. Niektórych nadal nie rozumiem, część jest oczywista, część ma rozwiązania podane na stronie, a te ciekawsze postaram się wyjaśnić w tym (i może następnych) wpisach.&lt;/p&gt;
&lt;h3&gt;Jestem prawie obiektowy&lt;/h3&gt;
&lt;p&gt;{geshi lang=javascript}typeof &quot;abc&quot; == &quot;string&quot; // true typeof String(&quot;abc&quot;) == &quot;string&quot; // true String(&quot;abc&quot;) == &quot;abc&quot; // true -- same types get casted to equal each other String(&quot;abc&quot;) instanceof String // false -- hmmm... (new String(&quot;abc&quot;)) instanceof String // true String(&quot;abc&quot;) == (new String(&quot;abc&quot;)) // true -- wait, wtf?{/geshi}&lt;/p&gt;
&lt;p&gt;&lt;code&gt;new String()&lt;/code&gt; to nie &lt;code&gt;String()&lt;/code&gt;, a &lt;code&gt;&quot;string&quot;&lt;/code&gt; to nie &lt;code&gt;&quot;object&quot;&lt;/code&gt;. Proste? :) Trochę wolniej:&lt;/p&gt;
&lt;p&gt;Pierwsza linia jest oczywista, ale warta zapamiętania — typem literału stringa jest &lt;code&gt;&quot;string&quot;&lt;/code&gt;. W drugiej mogłoby się wydawać że tworzymy obiekt, ale nie — konstruktor &lt;code&gt;String&lt;/code&gt; wywołany bez &lt;code&gt;new&lt;/code&gt; po prostu rzutuje na stringa. Trzecia linia tylko to potwierdza.&lt;/p&gt;
&lt;p&gt;Czwarta linia to nawiązanie do tytułu jaki nadałem tej sekcji — &lt;q&gt;Jestem prawie obiektowy&lt;/q&gt;. Autor tego przykładu zdziwił się skąd takie zachowanie, ponieważ pewnie nie wiedział o &lt;a href=&quot;http://pl.wikibooks.org/wiki/JavaScript/Konwersje_typ%C3%B3w_prostych&quot;&gt;typach prostych w JavaScriptcie&lt;/a&gt;. Otóż wartości: &lt;code&gt;1, &quot;a&quot;, true&lt;/code&gt; nie są typu &lt;code&gt;&quot;object&quot;&lt;/code&gt; tylko odpowiednio &lt;code&gt;&quot;number&quot;, &quot;string&quot;, &quot;boolean&quot;&lt;/code&gt;. Nie są z tego powodu instancjami swoich podobnie brzmiących z nazwy klas (ale &lt;em&gt;uwaga&lt;/em&gt; — czerpią z ich prototypów). Jest to zachowanie całkiem uzasadnione (choć niefajne w działaniu), ponieważ w innym przypadku (gdyby typy proste nie istniały) nie działało by porównanie &lt;code&gt;===&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Wyobraźmy sobie sytuację, w której pisząc &lt;code&gt;&quot;a&quot;&lt;/code&gt; tworzymy nowy obiekt typu &lt;code&gt;&quot;string&quot;&lt;/code&gt;. Porównanie dwóch zmiennych, które są obiektami za pomocą operatora &lt;code&gt;===&lt;/code&gt; sprawdza, czy zmienne te odnoszą się do dokładnie tego samego obiektu w pamięci. Tak więc w naszej hipotetycznej sytuacji otrzymalibyśmy:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}&quot;a&quot; === &quot;a&quot;; // -&amp;gt; false{/geshi}&lt;/p&gt;
&lt;p&gt;Uups. Po lewej obiekt, po prawej obiekt, ale to nie te same obiekty. Na szczęście teraz jest tak:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}&quot;a&quot; === &quot;a&quot;; // -&amp;gt; true new String(&quot;a&quot;) === new String(&quot;a&quot;); // -&amp;gt; false true === true; // -&amp;gt; true new Boolean(true) === new Boolean(true); // -&amp;gt; false{/geshi}&lt;/p&gt;
&lt;p&gt;Nie twierdzę, że jestem fanem takiego rozwiązania. Nie jestem pewien, ale chyba w Javie jest podobnie, za to na przykład już w Rubym jest to rozwiązane lepiej (ktoś potwierdzi?). Cóż — nic nie jest idealne ;).&lt;/p&gt;
&lt;p&gt;Wróćmy jednak do przykładu. W piątej linii wreszcie tworzymy obiekt typu &lt;code&gt;String&lt;/code&gt;. Dla przypomnienia:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}typeof new String(&quot;a&quot;); // -&amp;gt; &quot;object&quot; typeof String(&quot;a&quot;); // -&amp;gt; &quot;string&quot;{/geshi}&lt;/p&gt;
&lt;p&gt;Ostatnia linia powinna być już oczywista jeśli powiem, że operator &lt;code&gt;==&lt;/code&gt; przeprowadza konwersję zmiennych stojących po obu jego stronach do jednego typu (którego, tego nie wiem — pewnie zmiennej po lewej — kto ma ochotę niech sprawdzi w specyfikacji i napisze w komentarzu :). Tak więc z porównania &lt;code&gt;String(&quot;abc&quot;) == (new String(&quot;abc&quot;))&lt;/code&gt; otrzymujemy porównanie &lt;code&gt;&quot;a&quot; == &quot;a&quot;&lt;/code&gt;. Dla porównania:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}String(&quot;abc&quot;) === (new String(&quot;abc&quot;)); // -&amp;gt; false{/geshi}&lt;/p&gt;
&lt;p&gt;Widać więc, że trzeba uważać na krótki operator porównania i stosować go z głową. Polecam przyzwyczajenie się do używania potrójnego operatora i tylko w szczególnych wypadkach, kiedy na przykład znamy typy zmiennych (&lt;code&gt;typeof x == &quot;string&quot;&lt;/code&gt;), używanie podwójnego.&lt;/p&gt;
&lt;h3&gt;Jestem prawie obiektowy, ale umiem porównywać&lt;/h3&gt;
&lt;p&gt;Kolejny przykład będzie tylko rozwinięciem poprzedniej części. Oto on:&lt;/p&gt;
&lt;p&gt;{geshi lang=javacript}(1) === 1; // true Number.prototype.isOne = function () { return this === 1; } (1).isOne(); // false! Number.prototype.reallyIsOne = function () { return this - 1 === 0; } (1).reallyIsOne(); // true{/geshi}&lt;/p&gt;
&lt;p&gt;Pierwsza linia powinna być oczywista — nawias nie ma znaczenia. Druga i trzecia to ścisłe nawiązanie do poprzedniej części. W &lt;code&gt;isOne&lt;/code&gt; &lt;code&gt;typeof this; // -&amp;gt; &quot;object&quot;&lt;/code&gt;. Mimo, że wywołujemy metodę na zmiennej typu &lt;code&gt;&quot;number&quot;&lt;/code&gt;, to jest ona po cichu rzutowana na &lt;code&gt;&quot;object&quot;&lt;/code&gt; — dziwne, ale do zrozumienia — ciężko żeby &lt;code&gt;this&lt;/code&gt; nie było obiektem.&lt;/p&gt;
&lt;p&gt;Dwie ostatnie linie, to dynamiczne rzutowanie. Operacja odejmowania stara się rzutować obie zmienne na typ liczbowy. &lt;code&gt;this&lt;/code&gt; jest rzutowane na &lt;code&gt;1&lt;/code&gt; i reszta jest jasna. Równie dobrze można byłoby zapisać &lt;code&gt;reallyIsOne&lt;/code&gt; w ten sposób:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}Number.prototype.reallyIsOne = function () { return +this === 1; };{/geshi}&lt;/p&gt;
&lt;h4&gt;Używaj średników!&lt;/h4&gt;
&lt;p&gt;Poprzedni przykład przekleiłem na czysto z &lt;a href=&quot;http://wtfjs.com/post/409374681/rcanine-shows-us-this-interesting-this-coerce&quot;&gt;WTFJS&lt;/a&gt;. Jeśli będziecie go w tej postaci wklejać do Firebuga, to możecie się spotkać z latającymi wyjątkami. Skąd ten problem? Na końcu drugiej i czwartej linii brakuje średników i przynajmniej firefoksowy silnik wysiada. Rada na przyszłość — średniki dobre są.&lt;/p&gt;
&lt;h3&gt;Niezrozumiałe dla mnie&lt;/h3&gt;
&lt;p&gt;Tego już nie wytłumaczę :). Choć — obstawiałbym, że problem leży gdzieś w standardzie reprezentacji liczb zmiennoprzecinkowych, ale to tylko mój domysł.&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}Number.MAX_VALUE*1.0000000000000001 === (1/0) // false Number.MAX_VALUE*1.0000000000000002 === (1/0) // true{/geshi}&lt;/p&gt;
</description><pubDate>Sat, 06 Mar 2010 01:34:06 +0100</pubDate><guid>http://blog.koszulinski.pl/2010/03/06/wtfjs-rozjasnienie-umyslu/</guid><category>Frontend</category><category>Javascript</category><category>Techblog</category><category>wtf</category></item><item><title>Obiektowy JavaScript cz.2. - klasa sama w sobie</title><link>http://blog.koszulinski.pl/2010/02/28/obiektowy-javascript-cz-2-klasa-sama-w-sobie/</link><description>&lt;p class=&quot;top_img&quot;&gt;&lt;img src=&quot;http://pacman.mulabs.org/ts/oojs-2.jpg&quot; alt=&quot;Gąsienica&quot;&gt;Opublikowane na licencji CC przez &lt;a href=&quot;http://www.flickr.com/photos/trufflepig/&quot;&gt;Trufflepig&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;W poprzednim artykule o &lt;a href=&quot;http://blog.koszulinski.pl/2010/02/06/obiektowy-javascript-cz-1-obiekt-twoim-przyjacielem/&quot;&gt;obiektach w JavaScriptcie&lt;/a&gt; poruszyłem kwestię ich tworzenia, dostępu do właściwości, kontekstu wywoływania metod oraz wspomniałem o kilku cechach. Czyste literały obiektów same w sobie są już w tym języku bardzo przydatne — przekonał się pewnie o tym każdy kto korzystał z jakiejś biblioteki typu &lt;a href=&quot;http://mootools.net/&quot;&gt;MooTools&lt;/a&gt; czy &lt;a href=&quot;http://prototypejs.org&quot;&gt;Prototype&lt;/a&gt;. Pozwalają na przykład w dość wygodny sposób na podanie dowolnej liczby nazwanych argumentów funkcji:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}new Ajax.Request('/your/url', { parameters: { id: 12, action: 'sth' }, onSuccess: function (transport) { alert(transport.responseText); }, evalJS: false });{/geshi}&lt;/p&gt;
&lt;p&gt;Pisałem ostatnio o tym, że w JavaScriptcie nie ma klas. Skąd więc w przykładzie słówko kluczowe &lt;code&gt;new&lt;/code&gt;, które w typowym języku służy do tworzenia instancji obiektu na bazie jakiejś klasy? Otóż okazuje się, że w JavaScriptcie wprowadzono twór zwany &lt;em&gt;konstruktorami obiektów&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;Konstruktor obiektu&lt;/h3&gt;
&lt;p&gt;Zwyczajnie zaczyna się od definiowania klasy jakiegoś kotka, samochodu, czy figury geometrycznej. Nudy. Chciałem wymyślić coś bardziej konstruktywnego i spośród wszystkich dostępnych na moim biurku obiektów wybrałem butelkę po miodzie pitnym (pustą niestety). Myślę, że konstruktory dla napoju alkoholowego i butelki będą wystarczająco oryginalne :). Do dzieła:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var Alkohol = function (nazwa, ilosc_procentow, kolor) { this.nazwa = nazwa; this.ilosc_procentow = ilosc_procentow; this.kolor = kolor; }; var ButelkaAlkoholu = function (alkohol, pojemnosc, rok_produkcji, kraj_produkcji) { this.alkohol = alkohol; this.pojemnosc = pojemnosc; this.rok_produkcji = rok_produkcji; this.kraj_produkcji = kraj_produkcji; };{/geshi}&lt;/p&gt;
&lt;p&gt;Oj tak. JavaScript to dziwoląg. Miały być konstruktory obiektów, a tu znowu pojawiły się funkcje. Z drugiej strony pojawiło się też słowo kluczowe &lt;code&gt;this&lt;/code&gt;, więc cały przykład przypomina dwa wycięte z definicji klas napisanych w normalnym języku konstruktory. Na szczęście obiekty tworzymy już normalnie:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var miod = new Alkohol('Miód pitny', 13, '#850'); var butelka_miodu = new ButelkaAlkoholu(miod, 750, 2009, 'Polska'); console.dir(miod); // -&amp;gt; screenshot poniżej console.dir(butelka_miodu); // -&amp;gt; screenshot poniżej butelka_miodu.alkohol.nazwa; // -&amp;gt; &quot;Miód pitny&quot;{/geshi}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://pacman.mulabs.org/ts/oojs_ss1.png&quot; alt=&quot;Obiekty miód i butelka miodu&quot; height=&quot;127&quot;&gt;&lt;/p&gt;
&lt;p&gt;Utworzyliśmy w ten sposób dwa obiekty, których struktura została wylistowana przy pomocy &lt;a href=&quot;http://getfirebug.com/&quot;&gt;Firebuga&lt;/a&gt; i którą przedstawiłem na screenie.&lt;/p&gt;
&lt;p&gt;W poprzedniej części artykułu pisałem o tym, że obiekt może mieć swoje metody (inaczej funkcje przypisane jako właściwości obiektu). Musi więc być sposób aby w konstruktorze obiektu zdefiniować takie metody. Dodajmy więc kilka linii do konstruktora &lt;code&gt;ButelkaAlkohol&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var ButelkaAlkoholu = function (alkohol, pojemnosc, rok_produkcji, kraj_produkcji) { //... this.pelna = true; this.oproznij = function () { this.pelna = false; }; }; var butelka_miodu = new ButelkaAlkoholu(miod, 750, 2009, 'Polska'); butelka_miodu.pelna; // -&amp;gt; true butelka_miodu.oproznij(); butelka_miodu.pelna; // -&amp;gt; false{/geshi}&lt;/p&gt;
&lt;p&gt;Jak widać, aby utworzyć coś co możemy nazwać metodą, musimy przypisać funkcję do właściwości przyszłego obiektu. Uczulam znowu na działanie słowa &lt;code&gt;this&lt;/code&gt;, o czym pisałem już poprzednim razem.&lt;/p&gt;
&lt;h3&gt;Alternatywna metoda tworzenia konstruktorów obiektów&lt;/h3&gt;
&lt;p&gt;Naszym celem jest utworzenie obiektu o zadanych przez nas wartościach właściwości. Pamiętając, że najprostszym sposobem na utworzenie obiektu jest skorzystanie z literału możemy dojść do następującej konstrukcji: stwórzmy funkcję zwracającją obiekt zapisany za pomocą literału:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var Alkohol2 = function (nazwa, ilosc_procentow, kolor) { var obj = { nazwa: nazwa, ilosc_procentow: ilosc_procentow, kolor: kolor, pelna: true, oproznij: function () { this.pelna = false; } }; return obj; }; var piwo = Alkohol2('piwo Tyskie', 5.6, '#FE3'); piwo; // -&amp;gt; Object nazwa=piwo Tyskie ilosc_procentow=5.6 kolor=#FE3{/geshi}&lt;/p&gt;
&lt;p&gt;Tak więc skorzystaliśmy z funkcji w jej czysto funkcyjnym wymiarze. To jednak nie koniec. Dawno już nie było mowy o żadnym JavaScriptowym dziwactwie. Pora na następne. Otóż ten zapis również zadziała:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var piwo2 = new Alkohol2('piwo Tyskie', 5.6, '#FE3'); piwo2; // -&amp;gt; Object nazwa=piwo Tyskie ilosc_procentow=5.6 kolor=#FE3{/geshi}&lt;/p&gt;
&lt;p&gt;Zonk.&lt;/p&gt;
&lt;h4&gt;Anegdota o użyciu &lt;code&gt;new&lt;/code&gt; z funkcją&lt;/h4&gt;
&lt;p&gt;Kiedy dowiedziałem się o powyższym od razu zacząłem się zastanawiać jak w zasadzie JavaScript traktuje &lt;code&gt;new&lt;/code&gt; w kontekście funkcji. Pierwsze co ciśnie się na palce, to modyfikacja przykładu z konstruktorem &lt;code&gt;Alkohol2&lt;/code&gt; tak by zwracał &quot;nieobiekt&quot;:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var Cons = function () { return 5; }; var obj = new Cons(); obj; // -&amp;gt; Object{/geshi}&lt;/p&gt;
&lt;p&gt;Nic ciekawego — jakiś pusty obiekt otrzymaliśmy. Dodajmy więc właściwość (pierwszy sposób tworzenia konstruktorów):&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var Cons = function () { this.a = 'a'; return 5; }; var obj = new Cons(); obj; // -&amp;gt; Object a=a{/geshi}&lt;/p&gt;
&lt;p&gt;Ciekawe, choć do wytłumaczenia — &lt;code&gt;return 5&lt;/code&gt; jest pomijane. Połączmy teraz dwa sposoby tworzenia konstruktorów:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var Cons = function () { this.a = 'a'; return { b: 'b' }; }; var obj = new Cons(); obj; // -&amp;gt; Object b=b{/geshi}&lt;/p&gt;
&lt;p&gt;Uups. JavaScript pomija właściwości zadeklarowane przy użyciu słowa &lt;code&gt;this&lt;/code&gt;. W ten sposób dochodzimy do algorytmu, którym kieruje się ten język (a przynajmniej Firefox — może komuś się chce zajrzeć do specyfikacji? :):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Jeśli zwracana przez funkcję wartość jest obiektem, to wyrażenie &lt;code&gt;new Cons()&lt;/code&gt; zwraca ten obiekt.&lt;/li&gt;
&lt;li&gt;W przeciwnym wypadku wyrażenie to zwraca obiekt z właściwościami ustalonymi przy pomocy słowa &lt;code&gt;this&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Porównując obydwa sposoby pisania konstruktorów można dojść do wniosku, że lepsza jest ta druga, (ze zwracaniem gotowego obiektu), ponieważ działa na obydwa sposoby: &lt;code&gt;new Cons()&lt;/code&gt; i &lt;code&gt;Cons()&lt;/code&gt;. Osobiście uważam jednak, że ta metoda jest gorsza — dlaczego? O tym później w tej i w następnej części artykułu.&lt;/p&gt;
&lt;h3&gt;Elementy programowania obiektowego&lt;/h3&gt;
&lt;p&gt;Umiemy już tworzyć konstruktory obiektów, które można porównać do klas w zwyczajnym języku. Obiekty tworzone za ich pomocą posiadały do tej pory jednak tylko publiczne właściwości i metody. JavaScript nie udostępnia mechanizmu modyfikatorów dostępu, można jednak skorzystać z jego cech aby oprogramować w prosty sposób podobne konstrukcje.&lt;/p&gt;
&lt;h4&gt;Właściwości prywatne&lt;/h4&gt;
&lt;p&gt;{geshi lang=javascript}var Cons = function () { var private = 'jestem prywatna'; this.getPrivate = function () { return private; }; }; var obj = new Cons(); obj.getPrivate(); // -&amp;gt; &quot;jestem prywatna&quot; obj.private; // -&amp;gt; undefined{/geshi}&lt;/p&gt;
&lt;p&gt;Dlaczego to działa? Wszystko opiera się o kolejny dziwoląg, czyli JavaScriptowego scope'a, a także o closures (BTW. fajne tematy na kolejne artykuły). W skrócie — funkcja zadeklarowana w innej funkcji ma dostęp do zmiennych dostępnych w swoim &quot;rodzicu&quot;. Do tego mechanizm domknięć powoduje, że funkcja &lt;code&gt;getPrivate&lt;/code&gt; &quot;zapamiętuje&quot; środowisko, w którym została zadeklarowana.&lt;/p&gt;
&lt;h4&gt;Właściwości statyczne&lt;/h4&gt;
&lt;p&gt;{geshi lang=javascript}var Cons = function () { this.nonstatic = 'nie jestem statyczna'; }; Cons.static = 'jestem statyczna'; Cons.static; // -&amp;gt; &quot;jestem statyczna&quot; Cons.nonstatic; // -&amp;gt; undefined{/geshi}&lt;/p&gt;
&lt;p&gt;Chyba nic nie trzeba wyjaśniać. Konstruktor &lt;code&gt;Cons&lt;/code&gt; jak każda funkcja jest obiektem, więc można dodawać mu właściwości, co robimy w czwartej linii.&lt;/p&gt;
&lt;p&gt;Dla jasności dodam, że w identyczny sposób tworzymy prywatne i statyczne metody obiektów i klas.&lt;/p&gt;
&lt;h4&gt;Dostęp z obiektu do konstruktora&lt;/h4&gt;
&lt;p&gt;Każdy obiekt posiada właściwość &lt;code&gt;constructor&lt;/code&gt;, która daje dostęp do konstruktora (porównywalne do Javowego &lt;code&gt;Object.getClass()&lt;/code&gt;):&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var Cons = function () { this.sth = 'sth'; }; var obj = new Cons(); obj.constructor; // -&amp;gt; function() obj.constructor.toString(); // -&amp;gt; &quot;function () { this.sth = &quot;sth&quot;; }&quot;{/geshi}&lt;/p&gt;
&lt;p&gt;A teraz niespodzianka. Dlaczego drugi sposób tworzenia konstruktorów (przez literał obiektu) uważam za gorszy? O to jeden z powodów:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var Cons2 = function () { return { sth: 'sth' }; }; var obj2 = Cons2(); var obj3 = new Cons2(); obj2.constructor; // -&amp;gt; Object() obj3.constructor; // -&amp;gt; Object() obj2.constructor.toString(); // -&amp;gt; &quot;function Object() { [native code] }&quot; obj3.constructor.toString(); // -&amp;gt; &quot;function Object() { [native code] }&quot;{/geshi}&lt;/p&gt;
&lt;p&gt;Zdefiniowaliśmy konstruktor, który teoretycznie działa jak ten z poprzedniego przykładu (zwraca obiekt o tej samej właściwości). Okazuje się jednak, że kiedy spróbujemy dostać się do konstruktora tego obiektu, to nie jest nim funkcja &lt;code&gt;Cons2&lt;/code&gt;, a zwykła, natywna &lt;code&gt;Object&lt;/code&gt;. Dla porównania:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}({}).constructor.toString(); // -&amp;gt; &quot;function Object() { [native code] }&quot;{/geshi}&lt;/p&gt;
&lt;h3&gt;Co dalej?&lt;/h3&gt;
&lt;p&gt;Umiemy już posługiwać się obiektami. Umiemy też tworzyć ich konstruktory. Pora więc na dziedziczenie. O tym za czas jakiś w następnej części :)&lt;/p&gt;
</description><pubDate>Sun, 28 Feb 2010 03:10:25 +0100</pubDate><guid>http://blog.koszulinski.pl/2010/02/28/obiektowy-javascript-cz-2-klasa-sama-w-sobie/</guid><category>Frontend</category><category>Javascript</category><category>Ogólne</category><category>Techblog</category><category>programowanie</category><category>obiektowość</category><category>oop</category></item><item><title>Dlaczego iPhone też już ssie?</title><link>http://blog.koszulinski.pl/2010/02/09/dlaczego-iphone-tez-juz-ssie/</link><description>&lt;p class=&quot;top_img&quot;&gt;&lt;img src=&quot;http://pacman.mulabs.org/ts/iphone_1.jpg&quot; alt=&quot;Ślimak&quot;&gt; Opublikowane na licencji CC przez &lt;a href=&quot;http://www.flickr.com/photos/14degrees/&quot;&gt;Roberta Thomsona&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tytułem tym chciałem nawiązać do ubiegłotygodniowego wpisu &lt;a href=&quot;http://blog.koszulinski.pl/2010/01/29/dlaczego-frameworki-css-ssa/&quot;&gt;Dlaczego frameworki CSS ssą?&lt;/a&gt;. Niech tradycją się stanie, że kiedy używam słowa &quot;ssać&quot; to chcę coś nieobiektywnie pojechać. Piszę &quot;nieobiektywnie&quot;, żeby mnie ktoś znowu nie próbował przekonać, że wpis ten w mych oczach miał pretendować do bycia obiektywnym. Nie — to jest blog i publikuję tu moje odczucia, a nie badania naukowe (które notabene, po wpadce klimatologów, wiemy już jak są prowadzone).&lt;/p&gt;
&lt;p&gt;Wpis ten zacząłem pisać wczoraj wieczorem, jeszcze zanim miałem okazję przeżyć dzisiejsze przygody (które wymieniam na liście). Tak więc czara goryczy przelała się już wcześniej, a to co stało się dzisiaj tylko mnie przekonało, że bardzo chcę opublikować ten tekst.&lt;/p&gt;
&lt;p&gt;Żeby było jasne — iPhone (wersja 3G) jest oryginalny, zakupiony w Erze półtora roku temu, nigdy nie jailbrake'owany, nigdy nie przytrafiło mu się też nic strasznego. Windows do którego go podłączam włączany jest tylko w celu synchronizacji telefonu z iTunesem, bądź odpalenia kilku gier (kupionych w sklepie, nie ściąganych). Można więc przyjąć, że jest w miarę czysty.&lt;/p&gt;
&lt;p&gt;Co przydarzyło mi się dzisiaj:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dwukrotnie miałem już następującą sytuację — iPhone staje się trochę niestabilny (coś tam pada, coś tam laguje), postanawiam więc go wyłączyć i włączyć — wiadomo, że czasami dobrze jest odśmiecić pamięć. Wyłączam iPhone'a, włączam... nie — nie włączam — słodki ekran z jabłuszkiem zawisa na czas nieskończony (ostatnio jak zawisł mi przed seansem w kinie, to po seansie nadal się włączał). Wtedy trzeba pokombinować jakoś żeby go na twardo zresetować, ale &lt;strong&gt;stop&lt;/strong&gt; — nie da się do cholery wyciągnąć baterii. Wciskam więc wszystkie jego dwa klawisze i za którymś razem (żeby nie było zbyt prosto — kilka razy mogę dusić te przyciski po kilka minut i nie ma reakcji) udaje mi się go wyłączyć. Ponowna próba włączenia kończy się sukcesem, o ile sukcesem można nazwać stan, w którym przestają działać wszystkie doinstalowane aplikacje i wymagana jest synchronizacja z iTunesem,&lt;/li&gt;
&lt;li&gt;tak jak pisałem — sytuacja ta przytrafiła mi się dwukrotnie. Za pierwszym razem udało mi się przy pomocy iTunesa przywrócić słuchawkę do normalnego stanu. Dzisiaj jednak czterokrotnie już zawiesił mi się iTunes, wgrywanie nowego softu na telefon zostało przerwane, później synchronizacja, później nie udało mi się w 100% przywrócić iPhone'a z kopii zapasowej (to po kiego grzyba ta urocza, trwająca wieki synchronizacja przy każdym podłączeniu do komputera?). W skrócie — telefon po kilku godzinach działa, ale nie mogę wgrać na niego muzyki, bo po 3 minutach od podłączenia i rozpoczęcia synchronizacji iTunes nagle stwierdza, że jednak dzisiaj nie ma na nią siły i bez jakiegokolwiek komunikatu kończy (nie powiadamiając o tym iPhone'a) synchronizację,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To wszystko zabolało mnie jednak w głównej mierze dzisiaj. Poprzednia akcja ze zwiechą podczas włączania telefonu zakończyła się udaną synchronizacją i przywróceniem akceptowalnego stanu. Tak więc co natchnęło mnie wczoraj do rozpoczęcia pisania tego wpisu?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ten sprzęt jest niemożliwie, czasami aż do bólu groteskowo wolny&lt;/strong&gt;,&lt;/li&gt;
&lt;li&gt;na początek, przez pierwszy rok (to tak jak w małżeństwie ;), było naprawdę spoko — nie miałem telefonowi nic do zarzucenia. Jednak po każdym upgradzie softu system staje się wolniejszy. Najgorzej było kiedy dziadek Dżobs postanowił wypuścić iPhone'a 3GS — wtedy odczułem bardzo duży spadek wydajności. Jeśli dziadunio myśli, że nakłoni mnie tym do kupienia jego młodszego dziecka, to grubo się myli — nie cierpię takiego cwaniactwa,&lt;/li&gt;
&lt;li&gt;wyciszenie iPhone'a czasami trwa ponad 4s — mam na myśli czas od zmiany ustawienia suwaka do jakiejkolwiek reakcji telefonu (wibracja, ekran),&lt;/li&gt;
&lt;li&gt;odblokowanie iPhone'a (takie codzienne — z trybu uśpienia) czasami trwa ponad 10s — najpierw trzeba poczekać aż pojawi się suwak, później aż zareaguje na ruch palca, później pojawia się klawiatura, która też potrzebuje czasu żeby sobie przypomnieć, że jest klikalna, a na koniec ikonki, które muszą sobie wyskoczyć z wszystkich rogów ekranu, zamiast po ludzku się pokazać,&lt;/li&gt;
&lt;li&gt;włączenie smsów, książki kontaktowej, ostatnich telefonów, czy listy alarmów... nawet nie chce mi się myśleć ile to potrafi zabrać czasu, ale i tak wielcy jabłkowi programiści &quot;zoptymalizowali&quot; te programy, bo było gorzej,&lt;/li&gt;
&lt;li&gt;iPhone lubi sobie co jakiś czas (tak raz na miesiąc) zgubić sieć — czasem podczas rozmowy, czasem podczas stanu uśpienia,&lt;/li&gt;
&lt;li&gt;czasem ten stan zgubienia sieci zamienia się w stan niemożliwości dodzwonienia się do mnie i zadzwonienia ode mnie (operator się buntuje) przez dłuższy czas,&lt;/li&gt;
&lt;li&gt;paczka z iTunesem ma 90MB. Co oni tam za przeproszeniem ładują? Zestaw animowanych emotek w formacie 128px na 128px na każdą porę dnia i nocy?,&lt;/li&gt;
&lt;li&gt;Synchronizacja trwa pół godziny (fakt faktem, że robię ją rzadko),&lt;/li&gt;
&lt;li&gt;iTunes jest niestabilny, nieużyteczny, &lt;strong&gt;ekstremalnie&lt;/strong&gt; powolny, zasobożerny (wolę słuchać muzyki z Youtube'a — mniej ciągnie z proca) i nie rozumie oggów. Na dodatek zamiast napisać, że coś mu się nie podoba, że czegoś nie może znaleźć, czy że ma zły dzień, to milczy,&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wszystko to co mnie irytuje w tym telefonie nie zmienia jednak jednego — Apple ma niesamowitych projektantów interfejsów. Kiedy wreszcie pozbędę się tego bezużytecznego narzędzia, to nie sądzę żebym w jakimkolwiek innym systemie czuł się tak dobrze. Szkoda.&lt;/p&gt;
&lt;p&gt;Powstrzymałem się w tym tekście od użycia naprawdę wielu brzydkich wyrazów, więc na koniec tylko podsumuję całą sytuację — kurwa, nigdy więcej sprzętu, którego nazwa zaczyna się od &quot;ip&quot;.&lt;/p&gt;
&lt;p&gt;Ciekawy jestem czy tylko ja mam takie problemy z tym telefonem. Przeszło mi rzecz jasna przez myśl, że słuchawka może być uszkodzona. Wolę jednak wierzyć, że pozostali też mają problemy, ale boją się to przyznać, bo przecież tak kiedyś zachwalali iPhone'a ;). Szkoda tylko, że kiedyś to był naprawdę fajny sprzęt.&lt;/p&gt;
</description><pubDate>Tue, 09 Feb 2010 21:28:42 +0100</pubDate><guid>http://blog.koszulinski.pl/2010/02/09/dlaczego-iphone-tez-juz-ssie/</guid><category>Offtopic</category><category>Ogólne</category><category>Użyteczność</category><category>iphone</category><category>apple</category></item><item><title>Obiektowy JavaScript cz.1. - obiekt Twoim przyjacielem</title><link>http://blog.koszulinski.pl/2010/02/06/obiektowy-javascript-cz-1-obiekt-twoim-przyjacielem/</link><description>&lt;p class=&quot;top_img&quot;&gt;&lt;img src=&quot;http://pacman.mulabs.org/ts/oojs-1.jpg&quot; alt=&quot;Gąsienica&quot;&gt;Opublikowane na licencji CC przez &lt;a href=&quot;http://www.flickr.com/photos/trufflepig/&quot;&gt;Trufflepig&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Do tego czteroczęściowego (jak zapowiem, to może napiszę :) artykułu natchnęło mnie szkolenie z zaawansowanego JavaScriptu które, w miniony weekend, zorganizował we Wrocławiu &lt;a href=&quot;http://ferrante.pl/&quot;&gt;Damian Ferrante Wielgosik&lt;/a&gt;. Już na początku chciałbym mu podziękować za wiedzę, którą się podzielił, ponieważ przed szkoleniem byłbym wstanie napisać tylko część tego artykułu.&lt;/p&gt;
&lt;h3&gt;JavaScript to dziwoląg&lt;/h3&gt;
&lt;p&gt;Tego nie da się ukryć. JavaScript należy do wąskiej grupy języków z rodziny &lt;a href=&quot;http://en.wikipedia.org/wiki/ECMAScript&quot;&gt;ECMAScriptu&lt;/a&gt; (JS, &lt;a href=&quot;http://en.wikipedia.org/wiki/ActionScript&quot;&gt;ActionScript&lt;/a&gt;, &lt;a href=&quot;http://en.wikipedia.org/wiki/E4X&quot;&gt;E4X&lt;/a&gt;), którą cechuje to, że ich obiektowość oparta jest na &lt;a href=&quot;http://en.wikipedia.org/wiki/Prototype-based_programming&quot;&gt;prototypach&lt;/a&gt;. Oznacza to, że w JavaScriptcie nie istnieje pojęcie klasy. Nie oznacza to jednak tego, że w JavaScriptcie nie da się programować obiektowo z wykorzystaniem np. konkretyzacji, dziedziczenia, czy właściwości prywatnych. Da się. Co więcej — da się uzyskać dużo więcej funkcjonalności klasycznego języka obiektowego, choć, o czym na sam koniec, niekoniecznie jest po co.&lt;/p&gt;
&lt;h3&gt;Obiekt&lt;/h3&gt;
&lt;p&gt;W języku z obiektowością klasową wypada zacząć od definicji klasy. Tak przynajmniej zaczynali autorzy książek, które czytałem. W przypadku JavaScriptu mielibyśmy jednak pewien problem, bo klas tutaj nie ma. Trzeba więc zacząć od utworzenia obiektu. Oto najprostszy:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var obj = {}; typeof obj; // -&amp;gt; &quot;object&quot;{/geshi}&lt;/p&gt;
&lt;p&gt;Tak, to w JavaScriptcie jest najprostszy obiekt. Zadeklarowany w przykładzie jest pusty i dziedziczy po obiekcie &lt;code&gt;Object&lt;/code&gt;. Możemy sprawdzić to za pomocą poniższego kodu (jak działa i co to znaczy, o tym później):&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var obj = {}; obj.__count__; // -&amp;gt; 0, działa tylko w Firefoksie obj.__proto__.constructor; // -&amp;gt; Object(){/geshi}&lt;/p&gt;
&lt;p&gt;Obiekt możemy również utworzyć za pomocą konstruktora &lt;code&gt;Object()&lt;/code&gt;. Nie jest to jednak sposób polecany, ponieważ... zmienną &lt;code&gt;Object&lt;/code&gt; można nadpisać. Lepiej pozostać przy literałach obiektów, które są bezpieczniejsze i ładniejsze.&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var obj = new Object(); // -&amp;gt; Object Object = 5; var obj2 = Object(); // -&amp;gt; TypeError: Object is not a constructor{/geshi}&lt;/p&gt;
&lt;h3&gt;Właściwości obiektu&lt;/h3&gt;
&lt;p&gt;Nic nam jednak z pustego obiektu. Pora dodać do niego dane i metody. Możemy skorzystać ze składni literału obiektu:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var obj = { text: 'Jestem obiektem', saySth: function () { alert(this.text); } };{/geshi}&lt;/p&gt;
&lt;p&gt;Bądź stworzyć pusty obiekt i dodać mu właściwości:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var obj = {}; obj.text = 'Jestem obiektem'; obj.saySth = function () { alert(this.text); };{/geshi}&lt;/p&gt;
&lt;p&gt;W obu przypadkach efekt będzie ten sam. Kiedy wywołamy &lt;code&gt;obj.saySth();&lt;/code&gt; dostaniemy alerta z tekstem &lt;q&gt;Jestem obiektem&lt;/q&gt;.&lt;/p&gt;
&lt;p&gt;Jeszcze słowo wtrącenia o literałach. Trzeba uważać na przecinek po ostatniej właściwości. Firefox i chyba wszystkie normalne przeglądarki trzymają się specyfikacji &lt;a href=&quot;http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf&quot;&gt;ECMAScript 5 pkt 11.1.5&lt;/a&gt; (bądź to specyfikacja trzyma się tych przeglądarek ;), a kochany IE6, który zawsze musi być inny (&quot;inny nie znaczy gorszy&quot; w tym wypadku nie działa ;) trzyma się specyfikacji &lt;a href=&quot;http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf&quot;&gt;ECMAScript 3 pkt 11.1.5&lt;/a&gt;. Tak więc przecinek po ostatniej właściwości zostanie zaakceptowany przez przeglądarki z rodziny normalnych, zaś IE6 wywali cichaczem błąd. Nie wiem co prawda jak sprawa wygląda w IE7 i IE8, ale radzę po prostu tego przecinka nie stawiać. Koniec dygresji.&lt;/p&gt;
&lt;p&gt;W Javie, czy PHP metoda obiektu jest czymś zupełnie innym niż jego właściwość. W JavaScriptcie metoda jest po prostu funkcją przypisaną do właściwości obiektu. Widać to najlepiej w trzeciej linii ostatniego przykładu: &lt;code&gt;obj.saySth = function () {};&lt;/code&gt;. Wynika to z tego, że w JavaScriptcie funkcja też jest obiektem. Dzięki temu możemy ją przypisywać do zmiennych, zwracać w innych funkcjach, czy... wywoływać na niej metody. Ta właściwość JavaScriptu jest naprawdę potężna i myślę, że język ten sporo teraz zyskał w oczach osób lubiących Rubiego, Pythona, czy jakiś język funkcyjny :).&lt;/p&gt;
&lt;h4&gt;Uwaga na &lt;code&gt;this&lt;/code&gt;&lt;/h4&gt;
&lt;p&gt;{geshi lang=javascript}typeof obj.saySth; // -&amp;gt; &quot;function&quot; var sayNothing = obj.saySth; typeof sayNothing; // -&amp;gt; &quot;function&quot; sayNothing(); // -&amp;gt; alert undefined{/geshi}&lt;/p&gt;
&lt;p&gt;Z pierwszych trzech linii widać, że możemy sobie dowolnie operować funkcją. Czwarta może być zaskoczeniem. Dlaczego &lt;code&gt;this.text === undefined&lt;/code&gt;? Zauważcie, że funkcja &lt;code&gt;sayNothing&lt;/code&gt; nie została wywołana w kontekście obiektu &lt;code&gt;obj&lt;/code&gt;, tylko w kontekście... no właśnie — czego? Żeby to sprawdzić dodajmy dwie linie kodu do poprzednich przykładów:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}window.text = 'Jestem globalnym scopem'; sayNothing(); // -&amp;gt; alert &quot;Jestem globalnym scopem&quot;{/geshi}&lt;/p&gt;
&lt;p&gt;Teraz widać, że funkcja &lt;code&gt;sayNothing();&lt;/code&gt; wywołana jest w globalnym kontekście. Możemy ją także wywołać w odpowiednim kontekście używając metody &lt;code&gt;call()&lt;/code&gt; działającej na funkcji (tak jak pisałem wcześniej — funkcja też jest obiektem, więc ma też swoje metody):&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}sayNothing.call(obj); // -&amp;gt; alert &quot;Jestem obiektem&quot;{/geshi}&lt;/p&gt;
&lt;p&gt;Więcej na ten temat u Ferrante w &lt;a href=&quot;http://ferrante.pl/2010/02/02/this-w-javascript/&quot;&gt;&quot;this&quot; w JavaScript&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Jeszcze trochę o obiektach&lt;/h4&gt;
&lt;p&gt;Do właściwości obiektu możemy się również dostać za pomocą operatora &lt;code&gt;[]&lt;/code&gt;, czyli w taki sposób jak do elementów tablicy. Jest to przydatne kiedy chcemy uzyskać właściwość, której nazwa trzymana jest w zmiennej:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var obj = { a: 'A', b: 'B', m: function () { return 'M'; } }; obj['a']; // -&amp;gt; &quot;A&quot; var name = 'b'; obj[name]; // -&amp;gt; &quot;B&quot; obj['m'](); // -&amp;gt; &quot;M&quot;{/geshi}&lt;/p&gt;
&lt;p&gt;Po właściwościach obiektu można też iterować za pomocą konstrukcji &lt;code&gt;for (i in obj)&lt;/code&gt;. Trzeba jednak uważać, bo, w zależności od tego jakim obiektem dysponujemy, możemy dostać niespodziewane (przynajmniej na razie) rezultaty. Póki co jednak wystarczy nam:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var obj = { a: 'A', b: 'B', c: 'C', d: 'D' }; for (i in obj) { alert('obj[' + i + '] = ' + obj[i]); }{/geshi}&lt;/p&gt;
&lt;p&gt;Obiekty można też zagłębiać. Jest to własność oczywista, ale wypada dla jasności o niej wspomnieć.&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}var obj = { obj: { obj: { hidden: 'Zonk' } } }; obj.obj.obj.hidden; // -&amp;gt; &quot;Zonk&quot;{/geshi}&lt;/p&gt;
&lt;h3&gt;Co dalej?&lt;/h3&gt;
&lt;p&gt;Samym obiektem programista żyć nie może. Klas jednak w JavaScripcie nie uświadczymy, trzeba więc wymyślić coś innego. Z pomocą przyjdą nam konstruktory obiektów, ale zrobią to dopiero w &lt;a href=&quot;http://blog.koszulinski.pl/2010/02/28/obiektowy-javascript-cz-2-klasa-sama-w-sobie/&quot;&gt;następnej części&lt;/a&gt; :).&lt;/p&gt;
&lt;p&gt;Poza tym w trzeciej części mam zamiar napisać o prototypach, czyli JavaScriptowym dziedziczeniu. W czwartej chciałbym zebrać wszystko do kupy, pokazać może jakieś wzorce i napisać kilka uwag o programowaniu w JavaScriptcie. W zasadzie to uwagi mam już napisane, bo zacząłem od końca :D&lt;/p&gt;
</description><pubDate>Sat, 06 Feb 2010 13:16:09 +0100</pubDate><guid>http://blog.koszulinski.pl/2010/02/06/obiektowy-javascript-cz-1-obiekt-twoim-przyjacielem/</guid><category>Frontend</category><category>Javascript</category><category>Ogólne</category><category>Techblog</category><category>web</category><category>programowanie</category><category>obiektowość</category></item><item><title>Dlaczego frameworki CSS ssą?</title><link>http://blog.koszulinski.pl/2010/01/29/dlaczego-frameworki-css-ssa/</link><description>&lt;p&gt;Sesja się już dla mnie skończyła, można więc coś napisać. Dzisiaj będzie jednak krótko, bo i temat prosty.&lt;/p&gt;
&lt;h4&gt;Cóż to takiego framework CSS?&lt;/h4&gt;
&lt;p&gt;No właśnie. Każdy wie co to są frameworki programistyczne, ale CSSowy? Według &lt;a href=&quot;http://en.wikipedia.org/wiki/CSS_framework&quot;&gt;wiki&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A CSS framework, also known as a web design framework is a pre-prepared library that is meant to allow for easier, more standards-compliant styling of a webpage using the Cascading Style Sheets language. Just like programming and scripting language libraries, CSS frameworks (usually packaged as external .css sheets inserted into the header) package a number of ready-made options for designing and outlaying a webpage.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Czyli, tak jak w językach programowania, framework jest biblioteką (w tym wypadku grupą reguł CSS) która ułatwia implementowanie jakichś standardowych, często powtarzających się funkcjonalności (w tym wypadku pewnych schematów w layoutcie).&lt;/p&gt;
&lt;p&gt;Co, według mnie, frameworkiem CSS nie jest? Pisałem w listopadzie o &lt;a href=&quot;http://blog.koszulinski.pl/2009/11/26/write-less-do-more-czyli-pimp-my-css/&quot;&gt;parserze/kompilatorze/procesorze CSS - LESS&lt;/a&gt;, który rozszerza składnię CSS o kilka świetnych rzeczy. Między innymi - zmienne, zagnieżdżone reguły, obliczenia, wielokrotne wykorzystywanie reguł. Jakby nie było - nie podchodzi to pod definicję z &lt;a href=&quot;http://en.wikipedia.org/wiki/CSS_framework&quot;&gt;Wikipedii&lt;/a&gt;, ale niestety znajduje się w linkach do przykładowych frameworków. Dla ustalenia uwagi - &lt;a href=&quot;http://lesscss.org/&quot;&gt;LESS&lt;/a&gt; nie jest frameworkiem.&lt;/p&gt;
&lt;h4&gt;Czemuż ssie?&lt;/h4&gt;
&lt;p&gt;Pod mą lupę wziąłem pierwsze linki zwrócone przez Google. Przyjrzałem się chwilkę frameworkom: &lt;a href=&quot;http://www.blueprintcss.org/&quot;&gt;Blueprint&lt;/a&gt;, &lt;a href=&quot;http://elasticss.com/&quot;&gt;Elastic CSS&lt;/a&gt;, &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;YUI 2 Grids&lt;/a&gt;. Prawdopodobnie są lepsze rozwiązania od tych i z chęcią się im przyjrzę jeśli linki pojawią się w komciach :).&lt;/p&gt;
&lt;h5&gt;Słówko o nieudanym porodzie&lt;/h5&gt;
&lt;p&gt;Wypada jeszcze wtrącić, dla niezorientowanych, co to za poroniony pomysł ten &lt;a href=&quot;http://960.gs/&quot;&gt;Grid system&lt;/a&gt;. Otóż wpadł ktoś na pomysł, że wygodnie będzie wszystkim (grafikom, programistom) jak ustalimy sobie, że strona składa się z X kolumn po Ypx szerokości każda, między którymi są marginesy po Zpx. Przyznam, że obaj z grafikiem byliśmy zachwyceni, aż do... pierwszego projektu. Życzę np. sporo zabawy z cieniami wychodzącymi poza granice kolumn, w przypadku kiedy nie możemy użyć &lt;code&gt;box-shadow&lt;/code&gt;. Szlag trafia wszystkie piękne, okrągłe wartości.&lt;/p&gt;
&lt;h5&gt;Koniec wtrącenia&lt;/h5&gt;
&lt;p&gt;Najpierw kawałek kodu z &lt;a href=&quot;http://developer.yahoo.com/yui/examples/grids/grids-gg.html&quot;&gt;YUI 2 Grids&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;{geshi lang=xml}&lt;/p&gt;
&lt;div id=&quot;yui-main&quot;&gt;
&lt;div class=&quot;yui-b&quot;&gt;
&lt;div class=&quot;yui-g&quot;&gt;
&lt;div class=&quot;yui-g first&quot;&gt;
&lt;div class=&quot;yui-u first&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;yui-u&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class=&quot;yui-g&quot;&gt;
&lt;div class=&quot;yui-u first&quot;&gt;&lt;/div&gt;
&lt;div class=&quot;yui-u&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;{/geshi}&lt;/p&gt;
&lt;p&gt;Tyle się kiedyś mówiło o semantyce kodu i oddzieleniu wyglądu od treści. Ponad pięć lat temu, kiedy zaczynałem naukę HTMLa i CSSa, trwała walka o to aby programiści zaczęli pisać porządny kod. Wydawało mi się, że teraz już nie powinno być z tym problemów, a tu zonk. Patrzę na ten przykład i co widzę?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Prezentacja zbita razem z HTMLem - żeby zmienić układ strony zmieniamy HTMLa, a nie CSS,&lt;/li&gt;
&lt;li&gt;Kompletnie bezznaczeniowe nazwy klas i identyfikatorów - jedno wielkie semantyczne szambo. Wybrałem akurat framework od YUI, bo jest w tym najgorszy (choć Blueprint mu nie ustępuje). Elastic CSS wygląda trochę lepiej,&lt;/li&gt;
&lt;li&gt;Divitis. W przypadku YUI można chyba akurat dowolnie zmieniać użyte tagi, bo framework resetuje marginesy i paddingi dla wszystkich elementów (co też, tak na marginesie, uważam za kiepską praktykę). Kiedy jednak używając Blueprinta postanowimy zawrzeć którąś kolumnę w listę, to wszystko szlag trafia, bo uwaga... niektóre selektory zawierają nazwę tagu :O&lt;/li&gt;
&lt;li&gt;Narzucona struktura i kolejność elementów w kodzie HTML. Ja akurat poświęcam sporo uwagi temu aby każdy element nawigacyjny był w sensownym miejscu, aby nie używać niepotrzebnych tagów, a wykorzystując framework nie mam tej elastyczności,&lt;/li&gt;
&lt;li&gt;I wreszcie - przecież to wszystko co oferuje framework można w czasie, który jest bez znaczenia w stosunku do całego projektu, napisać ręcznie. To jest kilka reguł, które doświadczona osoba pisze na raz i to od razu z ewentualnym hackiem dla IE6. Tak, wiem, że nie wszyscy mają taką wiedzę, ale wykorzystując framework nigdy jej nie pogłębią.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tak więc w żadnym wypadku nie widzę sensu w używaniu frameworków do budowy układu strony. Żeby jednak nie było, że w ogóle nie umiem wykorzystywać zewnętrznego kodu - uważam, że przydatne są frameworki poprawiające typografię, bądź też pod niektórymi względami formularze. Muszą jednak bazować na selektorach używających tagów, a nie klas, czy nie daj Boże identyfikatorów.&lt;/p&gt;
</description><pubDate>Fri, 29 Jan 2010 11:45:21 +0100</pubDate><guid>http://blog.koszulinski.pl/2010/01/29/dlaczego-frameworki-css-ssa/</guid><category>CSS</category><category>Frontend</category><category>HTML</category><category>Ogólne</category><category>Techblog</category><category>framework</category><category>grid</category></item><item><title>Wybiła 15stka</title><link>http://blog.koszulinski.pl/2010/01/24/wybila-15stka/</link><description>&lt;p&gt;Od teraz KK pozwala mi się żenić bez zgody rodziców, wpuszczą mnie wreszcie do niektórych pubów i w ogóle :P Teraz dopiero czuję się dorosły. No i w końcu to oczko — więc to musi być szczęśliwy rok.&lt;/p&gt;
</description><pubDate>Sun, 24 Jan 2010 12:48:30 +0100</pubDate><guid>http://blog.koszulinski.pl/2010/01/24/wybila-15stka/</guid><category>Offtopic</category><category>Ogólne</category><category>urodziny</category><category>21</category><category>oczko</category></item><item><title>O tym jak wydłużyłem sobie dobę (cz. 2)</title><link>http://blog.koszulinski.pl/2010/01/10/o-tym-jak-wydluzylem-sobie-dobe-cz-2/</link><description>&lt;p&gt;Minął już zdecydowanie ponad miesiąc od kiedy &lt;a href=&quot;http://blog.koszulinski.pl/2009/11/21/o-tym-jak-wydluzylem-sobie-dobe/&quot;&gt;&quot;wydłużyłem sobie dobę&quot;&lt;/a&gt;, pora więc na jakieś podsumowanie.&lt;/p&gt;
&lt;p&gt;Pierwsza rzecz o której wypada mi wspomnieć, to to, że udało mi się utrzymać zmianę w swoim dobowym grafiku. Poniedziałek, wtorek i czasami środa stawiam się w pracy na 7:00-7:15, co uważam za swój spory sukces. Szczególnie teraz, w tym burym okresie, daje mi to kopa, bo więcej czasu działam przy świetle dziennym. Muszę przyznać, że nie było dla mnie w święta nic gorszego, niż wstać o 14stej i do końca dnia nic nie robić, bo &quot;przecież już wieczór, ciemno i w ogóle&quot;. No ale właśnie - przechodzimy do porażki.&lt;/p&gt;
&lt;p&gt;Porażką jest absolutny brak zmian w pozostałych dniach tygodnia i dniach świątecznych. Ciągle wstaję pomiędzy 9tą - 12stą, ekstremalnie 14stą. Spowodowane jest to tym, że chodzę późno spać, bo godziny 0:00 - 2:00 to dla mnie wciąż najproduktywniejszy okres. Ucisza się komunikator, ucisza się dom, mam święty spokój i mogę spokojnie skończyć to co danego dnia zacząłem robić.&lt;/p&gt;
&lt;p&gt;Plan na najbliższy miesiąc, który akurat będzie miesiącem kolokwiów, jest taki aby trochę ograniczyć czas kiedy mam włączony komunikator. &lt;a href=&quot;http://blip.pl&quot;&gt;Blip&lt;/a&gt;, mimo swoich niewątpliwych zalet, ma jednak też poważną wadę - rozprasza. Zobaczymy jak zadziała metoda nie wprost :).&lt;/p&gt;
&lt;p&gt;PS. wziąłem się ostatnio na poważnie, za projekt, który wisiałem koledze. Oznacza to, że pisać będę raczej rzadko. Trzeba zakończyć kiedyś tę otwartą pętlę :)&lt;/p&gt;
</description><pubDate>Sun, 10 Jan 2010 19:04:39 +0100</pubDate><guid>http://blog.koszulinski.pl/2010/01/10/o-tym-jak-wydluzylem-sobie-dobe-cz-2/</guid><category>Offtopic</category><category>Ogólne</category></item><item><title>Słów kilka o projektowaniu</title><link>http://blog.koszulinski.pl/2009/12/23/slow-kilka-o-projektowaniu/</link><description>&lt;p&gt;Zadałem jakiś czas temu na blipie pytanie dotyczące artykułu &lt;a href=&quot;http://www.uxmatters.com/mt/archives/2006/07/label-placement-in-forms.php&quot;&gt;Label Placement in Forms&lt;/a&gt;. Interesowało mnie czy może jest jakiś powód dla którego niektórzy (np. Marek Kasperski w swojej książce &lt;a href=&quot;http://helion.pl/ksiazki/wwprot.htm&quot;&gt;Projektowanie stron WWW&lt;/a&gt;) piszą aby labele do pól formularzy umieszczać na lewo od samych pól i wyrównane do prawej, a dlaczego inni (choćby autor tego artykułu) uważają, że najlepiej opis pola umieścić ponad polem, zmniejszając tym samym liczbę fiksacji wzroku? Czy Ci pierwsi nie znają badań? Czy kierują nimi jakieś inne przesłanki (np. praktyczne), o których ja nie wiem? Rzecz jasna, nie udało mi się tak doprecyzować pytania (ciężko się było w 160 znakach zmieścić :D).&lt;/p&gt;
&lt;p&gt;Dostałem dwie odpowiedzi. Skopiowałem sobie kiedyś tylko ich treść, nie podam niestety linka, bo w blipowym archiwum nie mam szansy tego znaleźć. Tak wyglądała rozmowa:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;reinmar&lt;/b&gt;: #usability labele nad inputami, czy na lewo od nich (wyrównane do prawej)? Za każdym razem piszą inaczej (choć to pewnie bez znaczenia)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;PanA &amp;gt; reinmar&lt;/b&gt;: nie bez znaczenia, zależy co chcesz osiągnąć. U góry się szybciej czyta niż obok, mniej fiksacji&lt;/p&gt;
&lt;p&gt;&lt;b&gt;PanB &amp;gt; reinmar&lt;/b&gt;: [blip] tak jak mówi ^PanA, najlepiej nad ale pola muszą być udzielone, mogą też być po lewej ale z wyrównaniem do prawej&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Zaciekawiło mnie co miał PanA na myśli pisząc: &lt;q&gt;zależy co chcesz osiągnąć&lt;/q&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;reinmar &amp;gt; PanA&lt;/b&gt;: To co mogę osiągnąć umieszczając je po lewej? Więcej fiksacji, więc umieszczać je tam jak chcę zniechęcić użytkownika? ;P&lt;/p&gt;
&lt;p&gt;&lt;b&gt;PanA &amp;gt; reinmar&lt;/b&gt;: czasami użytkownikowi nie ma być łatwiej - możemy chcieć zmusić go do zastanowienia się nad tym co wpisuje, etc.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;reinmar &amp;gt; PanA&lt;/b&gt;: Dlatego odciągamy go od zastanawiania utrudniając ogarnięcie formularza? Czy dajemy mu więcej czasu na zastanowienie się&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Uhh... Urocze powtarzanie usłyszanych od branżowych guru i wyczytanych z książek zdań. Zresztą - już moje pytanie było zadane złośliwie, bo po &lt;q&gt;zależy co chcesz osiągnąć&lt;/q&gt; w miarę wiedziałem czego się mogę spodziewać.&lt;/p&gt;
&lt;p&gt;Jednak nie do samej rozmowy chciałem bić w tym wpisie (dlatego też ocenzurowałem rozmówców - nie chcę tu dyskusji :P), a do dwóch błędów, które moim zdaniem wiele osób popełnia podczas projektowania.&lt;/p&gt;
&lt;h4&gt;Jestem specjalistą - przeczytałem 20 książek&lt;/h4&gt;
&lt;p&gt;Generalnie sytuacja ta odnosi się do każdej branży. Młodzi adepci Czegoś siadają do książek, chłoną, chłoną i napuchli wiedzą stają się w ich mniemaniu pełnowartościowymi specjalistami od Czegoś. Znają dziesiątki strasznie brzmiących terminów, mogą toczyć poważne dyskusje z ważnymi osobami ze świadka Czegoś. Zabawa kończy się jednak kiedy &quot;specjalista&quot; wkracza w granice praktyki. I tutaj, w zależności od osobowości i życiowej mądrości, z pokorą zbiera doświadczenie i weryfikuje posiadaną już wiedzę, bądź też dalej wygłasza znaną sobie teorię, która zupełnie nie ma zastosowania w praktyce.&lt;/p&gt;
&lt;p&gt;Żeby była jasność - nie neguję wartości znajomości teorii i nie twierdzę, że ktoś kto poznał teorię może być dobrym praktykiem.&lt;/p&gt;
&lt;h4&gt;Tort, znaczek Nike i płyta DVD&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;b&gt;PanB &amp;gt; reinmar&lt;/b&gt;: osobiście nad daje gdy jest mało pól, przy większej ilości daje z lewej&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;O. I to jest ciekawa odpowiedź. Rzeczywiście - ciężko przy 20 polowym formularzu dawać opisy ponad pola, ponieważ formularz ten rośnie nam do ogromnych rozmiarów. Przypomniała mi się jednak przenośnia (?), którą kiedyś wymyśliłem aby zobrazować w firmie jaki popełniamy błąd projektując funkcjonalności jednego serwisu. Wiele osób działa tak:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Weźmy tort, bo przecież każdy lubi tort. Tort jest fajny!&lt;/p&gt;
&lt;p&gt;Weźmy znaczek Nike. Przecież jest teraz trendy, na pewno każdemu się spodoba.&lt;/p&gt;
&lt;p&gt;Ja chcę jeszcze płytę DVD. Przecież jest taka funkcjonalna. Płyta DVD jest fajna!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I co dostajemy? &lt;em&gt;Tort z przyklejonym z boku znaczkiem Nike i wbitą na sztorc płytą DVD&lt;/em&gt;. Dzieło sztuki po prostu. Niestety tak działa wiele osób - dobierając funkcjonalności serwisu wybierają (np. z konkurencyjnych rozwiązań) te, które są fajne, nie myśląc o tym, czy razem będą tworzyły spójną całość. Projektując interfejs zagłebiąją się w statystyki, badania, wybierają atomowo najlepsze, najszybsze, najczytelniejsze rozwiązania i nie patrzą na ogół serwisu. Nagminne.&lt;/p&gt;
&lt;h3&gt;Nim mnie zjedziesz&lt;/h3&gt;
&lt;p&gt;Nie, nie uważam się za specjalistę od użyteczności, nie przeczytał nawet 5 książek. Co więcej - możliwe, że PanA ma rację, a ja jestem zbyt ograniczony by go zrozumieć.&lt;/p&gt;
&lt;p&gt;Tak samo - sam nie jestem wolny od wyśmiewanych przeze mnie błędów. Niestety ;)&lt;/p&gt;
&lt;p&gt;BTW. muszę wreszcie stworzyć sobie jakiś design do tego blogaska.&lt;/p&gt;
</description><pubDate>Wed, 23 Dec 2009 15:21:10 +0100</pubDate><guid>http://blog.koszulinski.pl/2009/12/23/slow-kilka-o-projektowaniu/</guid><category>Ogólne</category><category>Techblog</category><category>Użyteczność</category><category>usability</category><category>projektowanie</category></item><item><title>Przegląd prasy</title><link>http://blog.koszulinski.pl/2009/12/08/przeglad-prasy/</link><description>&lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/41263047@N08/3888554427/&quot; title=&quot;Zdjęcie autorstwa Armitage77, opublikowane na licencji CC&quot;&gt;&lt;img src=&quot;http://blog.koszulinski.pl/files/hydraulic_press.jpg&quot; alt=&quot;Zdjęcie prasy hydraulicznej&quot; style=&quot;float:left; margin:0 0.5em 0.5em 0;&quot; width=&quot;200&quot; height=&quot;302&quot;&gt;&lt;/a&gt; Przez mój czytnik i mojego &lt;a href=&quot;http://reinmar.blip.pl&quot;&gt;blipa&lt;/a&gt; przewija się masa linków. Część ze znalezionych informacji dodaję do swojego &lt;a href=&quot;http://del.icio.us/reinevan&quot;&gt;del.icio.us&lt;/a&gt;, jednak mimo to o tych najważniejszych / wartych najwięcej uwagi czasem zapominam. Pomyślałem więc, że będę publikował co jakiś czas najciekawsze moim zdaniem znaleziska z zakresu web developowania i usability. Raz, że samemu będzie mi łatwiej do tych informacji wrócić, dwa, że może komuś zaoszczędzę trochę czasu i podsunę coś czego jeszcze nie czytał.&lt;/p&gt;
&lt;p&gt;Wiele z poniższych linków macie szansę znać, wiele to starsze informacje, ale to pierwszy wpis w tym cyklu (tak, jeśli będę miał o czym pisać, to może zacznę to robić regularnie :) - następne będą aktualniejsze i zgrabniejsze. Na dodatek aby znaleźć te linki niestety musiałem przeglądać historię i wiele ciekawych rzeczy mogłem pominąć.&lt;/p&gt;
&lt;h4&gt;Usability vel użyteczność&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.abtests.com/&quot;&gt;AB Tests&lt;/a&gt; – strona zbiera wyniki testów A/B podsyłane przez czytelników. Nie zawsze są to wiarygodne testy (ze względu na zbyt małe próbki), ale jest też wiele wartościowych badań, z których można nauczyć się czegoś na przyszłość.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.smashingmagazine.com/2009/09/24/10-useful-usability-findings-and-guidelines/&quot;&gt;10 przydatnych wskazówek związanych z użytecznością&lt;/a&gt; – jak to w &lt;a href=&quot;http://www.smashingmagazine.com/&quot;&gt;Smashing Magazine&lt;/a&gt; – krótko, treściwie, ładnie i z głową.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.webaudit.pl/blog/2009/jak-wyglada-raport-z-audytu-uzytecznosci-zobacz-przyklad/&quot;&gt;Jak wygląda raport z audytu użyteczności&lt;/a&gt; – by Robert Drózd.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wireframes.linowski.ca/2009/09/ui-flow-shorthand-notation/&quot;&gt;UI Flow Shorthand Notation&lt;/a&gt; – prosty sposób na graficzne przedstawienie &quot;flow&quot; serwisu. Czyli podstrony, akcje użytkownika i ścieżki między nimi.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://paulbakaus.com/2009/10/06/why-i-would-hire-game-developers-for-my-startup/&quot;&gt;Dlaczego zatrudnię do mojego startupu programistę gier&lt;/a&gt; – trochę mniej związane z usability, ale nadal.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.webaudit.pl/blog/2009/prezentacja-o-analytics-z-world-usability-day-tour-2009/&quot;&gt;Google Analytics w kontekście użyteczności&lt;/a&gt; – prezentacja przeprowadzona przez Roberta Drózda na &lt;a href=&quot;http://www.worldusabilitydaytour.pl/&quot;&gt;WUD Tour&lt;/a&gt;. O tym, że nie wystarczy odpalenie statystyk - trzeba jeszcze umieć ich użyć.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://offline.pl/blog/lista-lektur.html&quot;&gt;Lista lektur o użyteczności&lt;/a&gt; – wrzucam ją chyba sam dla siebie, żeby się motywować do czytania :).&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Łebowe i niełebowe programowanie&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://nwp.jogger.pl/2009/11/26/python-pomoce-kursy-cwiczenia/&quot;&gt;Python - pomoce, kursy, ćwiczenia&lt;/a&gt; – zacząłem się ostatnio uczyć Pythona i tu znalazłem sporo ciekawych materiałów. Polecam &lt;a href=&quot;http://www.pythonchallenge.com/&quot;&gt;Python Challenge&lt;/a&gt; – najbardziej praktyczna nauka języka :).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dostepny.net/2009/jak-to-schowac-i-dlaczego-nie-displaynone/&quot;&gt;O tym dlaczego chowanie elementów interfejsu przez &lt;code&gt;display:none&lt;/code&gt; jest złe&lt;/a&gt; – Sam odpowiedzi nie znałem. Artykuł o tym jak to zrobić lepiej.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ferrante.pl/2009/09/05/falsy-values-i-operatory-porownania/&quot;&gt;Falsy values i operatory porównania w Javascriptcie&lt;/a&gt; – dla mnie same falsy values były oczywiste, gorzej jednak z operatorami porównania - warto zapamiętać.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mail.mozilla.org/pipermail/es-discuss/2009-December/010215.html&quot;&gt;ECMA zatwierdza ECMAScript 5 jako standard&lt;/a&gt; – &lt;a href=&quot;http://drawlogic.com/2009/04/09/javascript-standard-ecmascript-fifth-edition-es5-published/&quot;&gt;więcej informacji na ten temat&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://html5doctor.com/glossary/&quot;&gt;Słownik HTMLa 5&lt;/a&gt; – bardzo wygodny i przejrzysty spis tagów. Do każdego elementu mamy opis i przykładowy kod (brakuje mi listy atrybutów). Warto do niego zaglądać (jak i na całego &lt;a href=&quot;http://html5doctor.com/&quot;&gt;HTML5 Doctora&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.slideshare.net/s1emon/html5-wtf&quot;&gt;HTML5 WTF?&lt;/a&gt; – prezentacja w komiksowym stylu o HTMLu 5. W sam raz dla szefa :)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://css-tricks.com/what-beautiful-html-code-looks-like/&quot;&gt;Jak powinien wyglądać śliczny kod HTML&lt;/a&gt; – nie z każdym elementem się zgadzam, ale to temat na osobny wpis. W skrócie - HTML5 w praktyce.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://pentester.jogger.pl/2009/10/29/js-ninja/&quot;&gt;JS Ninja&lt;/a&gt; – kilka przykładów ataków &lt;abbr title=&quot;Cross Site Scripting&quot;&gt;XSS&lt;/abbr&gt;. Przydatne do samokontroli podczas pisania Javascriptu.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Inne&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://bradcolbow.com/&quot;&gt;Komiksy o świecie twórców stron&lt;/a&gt; – z humorem o naszej pracy i środowisku :)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://clientsfromhell.tumblr.com/&quot;&gt;Klienci z piekła rodem&lt;/a&gt; – bez komentarza. Trzeba poczytać. W każdą z tych sytuacji jestem w stanie uwierzyć :P&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Póki co na tym koniec. Od teraz co ciekawszy znaleziony link będę sobie odkładał, więc następne wydanie przeglądu prasy będzie aktualniejsze.&lt;/p&gt;
</description><pubDate>Tue, 08 Dec 2009 00:47:43 +0100</pubDate><guid>http://blog.koszulinski.pl/2009/12/08/przeglad-prasy/</guid><category>CSS</category><category>HTML</category><category>Javascript</category><category>Ogólne</category><category>Techblog</category><category>Użyteczność</category></item><item><title>Write LESS, do more - czyli pimp my CSS</title><link>http://blog.koszulinski.pl/2009/11/26/write-less-do-more-czyli-pimp-my-css/</link><description>&lt;p&gt;Uwaga: wyszedł mi &quot;odrobinkę&quot; przydługi wstęp. Zabieganych zapraszam od razu do &lt;a href=&quot;http://blog.koszulinski.pl/2009/11/26/write-less-do-more-czyli-pimp-my-css/#write-less-do-more-main&quot;&gt;konkretów&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;CSS rady nie daje&lt;/h4&gt;
&lt;p&gt;Nie da się ukryć że frontend developerzy (czy inaczej &quot;ci od cięcia grafiki&quot; :) łatwego życia nie mają. Pierwsza sprawa to niedoskonałości samych języków (CSS, xHTML, Javascript+DOM), druga to różnice i bugi (zwane inaczej ficzerami) w obsłudze przez przeglądarki. Każdy z tych języków na szczęście się rozwija (CSS3, HTML5, ECMAScript 5), a implementacja standardów jest, nawet w Internet Explorerze, sukcesywnie polepszana. Trwa to jednak strasznie długo, dlatego warto pokombinować samemu.&lt;/p&gt;
&lt;p&gt;Ostatnio opisałem &lt;a href=&quot;http://blog.koszulinski.pl/2009/11/22/zen-coding-snippety-nie-maja-szans/&quot;&gt;plugin do edytorów tekstów dzięki któremu można przyspieszyć pisanie HTMLa&lt;/a&gt;. Dzisiaj pod lupę chciałbym wziąć CSS. Osobiście na tempo pisania listy właściwości nie narzekam - mam własny zestaw snippetów, który umila mi życie. Inaczej ma się sprawa w stosunku do selektorów. Już w niedużym projekcie potrafią się zrobić cuda typu:&lt;/p&gt;
&lt;p&gt;{geshi lang=css}#content .news_list .item .title {...} #content .news_list .item .date {...} #content .news_list .item .date .day {...}{/geshi}&lt;/p&gt;
&lt;p&gt;Albo:&lt;/p&gt;
&lt;p&gt;{geshi lang=css}.s1 { width:120px; float:left; font-size:1.1em; margin-left:10px; color:#FA0; } /*gdzieś kawałek dalej:*/ .s2 { width:120px; float:left; font-size:1.1em; margin-left:10px; color:#C14; }{/geshi}&lt;/p&gt;
&lt;p&gt;Gdzie wypada to połączyć do pary selektorów i dla każdego z osobna jeszcze kolor ustawić. Niestety to najprostszy przypadek z tej rodziny, czasami trzeba znaleźć części wspólne dla kilku reguł po kilkunaście właściwości, albo olać wszystko.&lt;/p&gt;
&lt;p&gt;Dalej można wymieniać:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Powtarzające się wartości kolorów, rozmiarów, marginesów, itd. Zmiana jednej wymaga zmiany pozostałych, bo np. tekst ma mieć ten sam kolor w nagłówkach newsów co gdzieś w sidebarze i górnym menu. I jak pozapamiętywać te wszystkie kluczowe wartości, żeby później nie szukać &lt;q&gt;co to był za kod tego pomarańczowego, który używam do podkreśleń&lt;/q&gt;?&lt;/li&gt;
&lt;li&gt;Obliczenia - dopełnianie się marginesów, paddingów i borderów, kolor lekko ciemniejszy, kolor lekko jaśniejszy. Ja zawsze do cięcia siadałem z kartką A4, która już po kilku godzinach była zapisana do pełna wartościami i obliczeniami.&lt;/li&gt;
&lt;li&gt;{geshi lang=css}-moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px;{/geshi}&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Co więcej - to są problemy które pojawiają się już na etapie stron o średniej wielkości i kodowania w pojedynkę. W przypadku sporych serwisów (długo i wieloetapowo rozwijanych) i większego zespołu potrafią urosnąć do &lt;q&gt;&amp;amp;*$#$%. To jest jak rzeźba w gównie. Trzeba przepisać cały ten bajzel&lt;/q&gt;. Sam ostatnio tak opisałem jeden commit do bazy.&lt;/p&gt;
&lt;h4 id=&quot;write-less-do-more-main&quot;&gt;Wysyp wspomagaczy&lt;/h4&gt;
&lt;p&gt;Jakiś czas temu dostałem od kogoś link do &lt;a href=&quot;http://lesscss.org/&quot;&gt;LESS CSS&lt;/a&gt; - parsera/kompilatora (nie wiem jak to nazwać) rozszerzającego możliwości CSSa o kilka interesujących rzeczy typu: zmienne, obliczenia, reguły zagnieżdżone, itd. O temacie jednak zapomniałem (mało ostatnio koduję) i przypomniał mi kilka dni temu o nim &lt;a href=&quot;http://occulkot.jogger.pl/&quot;&gt;Occulkot&lt;/a&gt;, który podrzucił mi &lt;a href=&quot;http://sass-lang.com/&quot;&gt;Sassa&lt;/a&gt;. Obydwa kompilatory napisane są w Rubym. Zrobiłem mały research i znalazłem jeszcze podobne cudo, tyle że w Pythonie - &lt;a href=&quot;http://sandbox.pocoo.org/clevercss/&quot;&gt;Clever CSS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Po krótkim wczytywaniu się w przykłady zdecydowałem się na LESSa. Dodaje do CSSa trochę mniej ficzerów, ale przynajmniej nie zmienia jego składni (plik CSS jest poprawnym plikiem LESS) i nie wymusza na mnie jedynego, właściwego formatowania kodu (Sass i Clever CSS mają składnię czerpiącą z języków w jakich zostały napisane - odpowiednio Ruby i Python - wymagają więc wcięć).&lt;/p&gt;
&lt;p&gt;Polecam przeczytać &lt;a href=&quot;http://sigma.inf.ug.edu.pl/~kbelau/rails3/2009/10/31/haml/&quot;&gt;Haml-sass, czyli tragedia w dwóch aktach&lt;/a&gt;. Przy okazji tej lektury ja również odradzam &lt;a href=&quot;http://haml-lang.com/&quot;&gt;Hamla&lt;/a&gt;, który jest w teorii cudownym (zen i te sprawy) systemem szablonów HTMLa. Tylko, że kompletnie to nieczytelne, brzydkie i bez sensu.&lt;/p&gt;
&lt;h4&gt;Instalacja&lt;/h4&gt;
&lt;p&gt;Po tym przydługim wstępie (chciałem usunąć, ale żal jak się już napisało) przejdźmy do konkretów.&lt;/p&gt;
&lt;p&gt;Instalacja, dla posiadających &lt;a href=&quot;http://docs.rubygems.org/read/book/1&quot;&gt;gema&lt;/a&gt; (ci nieposiadający najlepiej niech go zainstalują), jest banalna:&lt;/p&gt;
&lt;p&gt;{geshi lang=bash}$ sudo gem install less{/geshi}&lt;/p&gt;
&lt;p&gt;Ewentualnie jeśli ktoś koduje w Railsach, to może go zainteresować &lt;a href=&quot;http://github.com/cloudhead/more&quot;&gt;ten plugin&lt;/a&gt;.Najprostszym sposobem skorzystania z LESSa jest jednak przy pomocy konsoli:&lt;/p&gt;
&lt;p&gt;{geshi lang=bash}$ lessc style.less{/geshi}&lt;/p&gt;
&lt;p&gt;Wykonanie tego polecenia spowoduje utworzenie pliku &lt;code&gt;style.css&lt;/code&gt; zawierającego wynik działania kompilatora.&lt;/p&gt;
&lt;h4&gt;Ficzery&lt;/h4&gt;
&lt;dl&gt;
&lt;dt&gt;Zmienne&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;Kompilując taki kod:&lt;/p&gt;
{geshi lang=css}@brand_color: #4D926F; #header { color: @brand_color; } h2 { color: @brand_color; }{/geshi}
&lt;p&gt;Otrzymamy:&lt;/p&gt;
{geshi lang=css}#header, h2 { color: #4d926f; }{/geshi}
&lt;p&gt;Jak widać, poza podstawieniem zmiennej, LESS połączył też reguły o tej samej liście właściwości. To informacja dla miłośników oszczędzania na bajtach transferu :).&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Wielokrotne wykorzystanie reguł&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;CSSowe &lt;acronym title=&quot;Don't repeat yourself&quot;&gt;DRY&lt;/acronym&gt; :).&lt;/p&gt;
{geshi lang=css}.rounded_corners (@radius: 5px) { -moz-border-radius: @radius; -webkit-border-radius: @radius; border-radius: @radius; } h1 .stronger { font-weight:bold; font-size:1.1em; } #header { .rounded_corners; h1 .stronger; } #footer { .rounded_corners(10px); }{/geshi}
&lt;p&gt;Po kompilacji:&lt;/p&gt;
{geshi lang=css}h1 .stronger { font-weight: bold; font-size: 1.1em; } #header { -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; font-weight: bold; font-size: 1.1em; } #footer { -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; } {/geshi}
&lt;p&gt;Przy czym definicja reguły musi wystąpić przed jej użyciem. Przykład z wykorzystaniem &lt;code&gt;h1 .stronger&lt;/code&gt; nie ma uzasadnienia w praktyce (jest w zasadzie błędny), ale chciałem tylko pokazać, że można wykorzystywać ponownie dowolne reguły.&lt;/p&gt;
&lt;/dd&gt;
&lt;dt&gt;Zagnieżdżone reguły&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;To chyba mój ulubieniec. Dzięki temu rozszerzeniu unikniemy pisania co chwilę mega długich selektorów. Dziwię się w ogóle, że nie ma tego w oficjalnym CSSie.&lt;/p&gt;
{geshi lang=css}#header { color: red; a { font-weight: bold; text-decoration: none; } &amp;gt; p { color: blue; } }{/geshi}
&lt;p&gt;Po kompilacji:&lt;/p&gt;
{geshi lang=css}#header { color: red; } #header a { font-weight: bold; text-decoration: none; } #header &amp;gt; p { color: blue; }{/geshi}&lt;/dd&gt;
&lt;dt&gt;Obliczenia&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;Chyba nie muszę tłumaczyć.&lt;/p&gt;
{geshi lang=css}@the-border: 1px; @base-color: #111; #header { color: @base-color * 3; border-left: @the-border; border-right: @the-border * 2; } #footer { color: (@base-color + #111) * 2; }{/geshi}
&lt;p&gt;Po kompilacji:&lt;/p&gt;
{geshi lang=css}#header { color: #333333; border-left: 1px; border-right: 2px; } #footer { color: #444444; }{/geshi}&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;To by było na tyle. Jeśli kogoś temat zainteresował to zapraszam do &lt;a href=&quot;http://lesscss.org/docs.html&quot;&gt;specyfikacji&lt;/a&gt;, gdzie autor omawia jeszcze kilka dodatków.&lt;/p&gt;
&lt;p&gt;W każdym razie - cztery małe ficzery, a jak cieszą, prawda? :)&lt;/p&gt;
&lt;h4&gt;Praca z LESSem&lt;/h4&gt;
&lt;p&gt;Zastanawiałem się tylko jak usprawnić kompilację po wprowadzeniu zmian do pliku LESS. Najfajniej gdyby udało mi się w moim VIMie podłączyć wykonanie &lt;code&gt;$ lessc&lt;/code&gt; pod operację zapisania, ale to nie na moje umiejętności. &lt;a href=&quot;http://mcv.jogger.pl&quot;&gt;Mcv&lt;/a&gt; zaproponował mi takiego Makefile'a:&lt;/p&gt;
&lt;p&gt;{geshi lang=bash}%.css: %.less lessc $&amp;lt;{/geshi}&lt;/p&gt;
&lt;p&gt;Wykonujemy go uruchamiając: &lt;code&gt;$ make plik1.css plik2.css&lt;/code&gt;. To już powinno mi się udać podpiąć w VIMie pod zapis pliku. Ewentualnie można spróbować tak:&lt;/p&gt;
&lt;p&gt;{geshi lang=bash}all: *.css %.css: %.less lessc $&amp;lt;{/geshi}&lt;/p&gt;
&lt;p&gt;Co zadziała automatycznie dla wszystkich istniejących już plików CSS po wykonaniu prostego &lt;code&gt;$ make&lt;/code&gt;. Przy czym, jeśli się mylę, to proszę mnie poprawić, bo nigdy żadnego makefile'a sam nie napisałem.&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;EDIT: w komentarzach pojawiły się rozwiązania mojego problemu.&lt;/ins&gt;&lt;/p&gt;
</description><pubDate>Thu, 26 Nov 2009 01:20:01 +0100</pubDate><guid>http://blog.koszulinski.pl/2009/11/26/write-less-do-more-czyli-pimp-my-css/</guid><category>CSS</category><category>Frontend</category><category>Ogólne</category><category>Techblog</category><category>VIM</category><category>css less sass</category></item><item><title>Zen Coding - snippety nie mają szans</title><link>http://blog.koszulinski.pl/2009/11/22/zen-coding-snippety-nie-maja-szans/</link><description>&lt;p&gt;Snippety do htmla? Nieeee. Zobaczcie &lt;a href=&quot;http://www.smashingmagazine.com/2009/11/21/zen-coding-a-new-way-to-write-html-code/&quot;&gt;Zen Coding&lt;/a&gt;. W skrócie działa to tak. Wpisuję w edytorze CSSową składnią:&lt;/p&gt;
&lt;p&gt;{geshi lang=css}div#content&amp;gt;h1+p{/geshi}&lt;/p&gt;
&lt;p&gt;Wciskam jakąś kombinację klawiszy i dostaję:&lt;/p&gt;
&lt;p&gt;{geshi lang=xml}&lt;/p&gt;
&lt;div id=&quot;content&quot;&gt;
&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;{/geshi}&lt;/p&gt;
&lt;p&gt;Sprytne, nie? :) Ale to jeszcze mało. Spróbujcie tego:&lt;/p&gt;
&lt;p&gt;{geshi lang=css}div#top&amp;gt;h1&amp;gt;a[title=Do strony głównej]{Moja strona}&lt;/p&gt;
&lt;div style=&quot;margin-left: 2em&quot; menu=&quot;&quot;&gt;li.pos$*3&amp;gt;a{/geshi} {geshi lang=xml}
&lt;div id=&quot;top&quot;&gt;
&lt;h1&gt;&lt;a href=&quot;&quot; title=&quot;Do strony głównej&quot;&gt;Moja strona&lt;/a&gt;&lt;/h1&gt;
&lt;ul id=&quot;menu&quot;&gt;
&lt;li class=&quot;pos1&quot;&gt;&lt;a href=&quot;&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;pos2&quot;&gt;&lt;a href=&quot;&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li class=&quot;pos3&quot;&gt;&lt;a href=&quot;&quot;&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
{/geshi}
&lt;p&gt;Chyba nie muszę mówić jak bardzo taka pomoc przyspiesza pracę. Napisanie z palca kodu z drugiego przykładu zajęłoby mi przypuszczalnie więcej niż 2 minuty. Gdybym użył snippetów (do których przy HTMLu nie mogę się przyzwyczaić) może skróciłbym ten czas dwukrotnie. Zaś używając wynalazku Zen Coding całość naklepałem w 20s (i to nie mając wprawy). Tak więc gorąco polecam.&lt;/p&gt;
&lt;p&gt;Gdyby ktoś szukał wtyczki do VIMa, to powstał &lt;a href=&quot;http://github.com/rstacruz/sparkup&quot; title=&quot;VIM zen coding plugin&quot;&gt;plugin&lt;/a&gt;, którego twórca zainspirował się Zen Codingiem.&lt;/p&gt;
&lt;/div&gt;
</description><pubDate>Sun, 22 Nov 2009 23:58:11 +0100</pubDate><guid>http://blog.koszulinski.pl/2009/11/22/zen-coding-snippety-nie-maja-szans/</guid><category>CSS</category><category>Frontend</category><category>HTML</category><category>Ogólne</category><category>Techblog</category><category>VIM</category></item><item><title>O tym jak wydłużyłem sobie dobę</title><link>http://blog.koszulinski.pl/2009/11/21/o-tym-jak-wydluzylem-sobie-dobe/</link><description>&lt;p&gt;Tym razem będzie krótko i o życiu.&lt;/p&gt;
&lt;p&gt;Do niedawna mój przykładowy dzień wyglądał tak:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;8:30-9:00 pobudka&lt;/li&gt;
&lt;li&gt;10:00 pojawiam się w pracy (albo zasiadam do niej w domu)&lt;/li&gt;
&lt;li&gt;16:00-17:00 kończę robotę (tak - to nie 8h; pracuję na 1/2 etatu, a w pracy jestem 3dni/tyg.)&lt;/li&gt;
&lt;li&gt;18:00 po godzinnym staniu w korkach jestem w domu&lt;/li&gt;
&lt;li&gt;19:00 zjadłem, odpocząłem, mogę zabrać się do pracy i biegania&lt;/li&gt;
&lt;li&gt;2:00 damn - pora iść spać - nie za dużo tego czasu miałem&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Dało się tak żyć w lecie. Teraz niestety prawie całą moją dobę było ciemno za oknem, co zaczęło dodatkowo działać depresyjnie. Do tego stałem sobie codziennie w pięknych koreczkach tracąc dodatkowe godziny doby i denerwując się, co działa demotywująco.&lt;/p&gt;
&lt;h4&gt;Zmiana&lt;/h4&gt;
&lt;p&gt;Całkiem przez przypadek założyłem się z siostrą, że wyjdę z domu przed nią (czyli przed ok. 8:00). Budziki nastawiłem już od 6:20, bo potrzebuję minimum pięciu żeby się obudzić. Fartem - złapał mnie już pierwszy i... pierwszy raz od... uh - roku? dwóch? wyszedłem z domu o 6:50. I mój dzień wyglądał tak:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;7:10 w pracy - korków jeszcze nie było&lt;/li&gt;
&lt;li&gt;15:00 wychodzę - zrobiłem całe 8h, więc jeden z 3 dni roboczych będę miał luźny. Dodatkowo widziałem wschód słońca, skończyłem jak ciągle było jasno na dworze&lt;/li&gt;
&lt;li&gt;15:20 w domu - koreczków nie było, wróciłem ekspresowo&lt;/li&gt;
&lt;li&gt;16:20 kończę bieganie - wreszcie udało mi się pobiegać przy świetle dziennym&lt;/li&gt;
&lt;li&gt;17:20 zabieram się do pracy, nauki, itd.&lt;/li&gt;
&lt;li&gt;1:00 już zasypiam, żeby następnego dnia powtórzyć historię&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I tak żyłem przez kilka dni. Efekt niesamowity. Zrobiłem rzeczy, które wcześniej zajęłyby mi kilka tygodni. Dodatkowo psychika lepiej znosi zimę, bo nie przesypiam połowy dnia. No i w jeden z 3 dni pracuję tylko 4h.&lt;/p&gt;
&lt;h4&gt;Co dalej?&lt;/h4&gt;
&lt;p&gt;Co prawda dzisiaj (co widać po godzinie) idę spać późno, ale to wypadek przy pracy. Zamierzam i tak wstać o 7:00, bo najważniejsze, to wyrobić sobie nawyk. Dobranoc i życzcie mi powodzenia :)&lt;/p&gt;
</description><pubDate>Sat, 21 Nov 2009 02:39:47 +0100</pubDate><guid>http://blog.koszulinski.pl/2009/11/21/o-tym-jak-wydluzylem-sobie-dobe/</guid><category>Offtopic</category><category>Ogólne</category></item><item><title>WUD Tour 2009 - Wrocław - relacja i przemyślenia</title><link>http://blog.koszulinski.pl/2009/11/18/wud-tour-2009-wroclaw-relacja-i-przemyslenia/</link><description>&lt;p&gt;&lt;img src=&quot;http://reinmar.jogger.pl/files/logo_wud09.gif&quot; alt=&quot;Logo WUD Tour&quot; style=&quot;float:left; margin:0 0.5em 0.5em 0&quot;&gt;W zeszły czwartek (tj. 12 listopada) odbyła się Wrocławska część &lt;a href=&quot;http://www.worldusabilitydaytour.pl/index.xml&quot;&gt;&lt;acronym title=&quot;World Usability Day&quot;&gt;WUD&lt;/acronym&gt; Tour&lt;/a&gt;, na której miałem przyjemność być. Nawiasem mówiąc była to pierwsza konferencja poświęcona usability, na którą dotarłem, bo naście poprzednich albo przegapiłem, albo z przyczyn niezależnych dotrzeć nie mogłem. Tym razem też nie było idealnie, bo po kilku pierwszych prezentacjach musiałem udać się na zajęcia.&lt;/p&gt;
&lt;h4&gt;W skrócie co widziałem&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;q&gt;Wprowadzenie do tematyki usability&lt;/q&gt; - nic szczególnego, ani tym bardziej zaskakującego - raczej dla tych, którzy pomylili salę i potrzebowali wprowadzenia od zera.&lt;/li&gt;
&lt;li&gt;&lt;q&gt;&lt;a href=&quot;http://www.araw.pl/artykuly/7647/Informacje-ogolne/&quot;&gt;Akcelerator Designu&lt;/a&gt;&lt;/q&gt; - prezentacja pracowników Urzędu Miasta Wrocławia dotycząca inicjatywy mającej na celu promowanie idei wzornictwa przemysłowego i użyteczności wśród przedsiębiorców (itd., itd.). Temat póki co mnie nie prawie nie dotyczący, więc było trochę nudno. Sytuację poprawił dopiero trzeci z prowadzących będący z pochodzenia Włochem, który swoją łamaną polszczyzną bardzo zgrabnie przedstawił nam pewnego włoskiego designera. Kto był ten wie o czym mówię ;D&lt;/li&gt;
&lt;li&gt;&lt;q&gt;Co chcą zobaczyć klienci sklepów elektronicznych?&lt;/q&gt; - O tej prezentacji za chwilę. W skrócie powiem tylko, że była całkiem ciekawa i tak &quot;politechnikowo&quot; przedstawiona :P&lt;/li&gt;
&lt;li&gt;&lt;q&gt;Możliwość używania&lt;/q&gt; - drugi biegun względem poprzedniej ekipy (prosta graficznie prezentacja, ale ładnie opracowana typograficznie versus prezentacja &quot;specyfikacyjna&quot; :). Prelekcja przeprowadzona przez Krzysztofa Kubaska - pracownika ASP i projektanta wzornictwa zawodu, dotycząca łączenia użyteczności z designem. Krzysztof z powodzeniem pokazywał, że te dwie rzeczy mogą iść ze sobą w parze i współpraca designera z inżynierem jest jedną z podstaw dobrego produktu. Przy okazji pokazał kilka przykładów zabawnie zaprojektowanych przedmiotów codziennego użytku, jak np. widelec w kształcie samolotu (leci samolocik... AM! :P), czy kubków z dziobami/pyskami zwierząt. Krzysztof zrobił dobre wrażenie i myślę, że taki był główny cel tej prezentacji. Według mojej spiskowej teorii - śmiech -&amp;gt; dobre wrażenie -&amp;gt; więcej klientów ;). Zwróciłem też uwagę, że specjalistów od usability uważa za informatyków. Ciekawe :)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Później niestety musiałem już sobie iść. Najciekawsze prelekcje opuściłem i czekam z niecierpliwością na video z konferencji.&lt;/p&gt;
&lt;h4&gt;Czy użytkownik jest złym projektantem?&lt;/h4&gt;
&lt;p&gt;Wracając do prelekcji dotyczącej sklepów internetowych. Marcin Kuliński przedstawił nam narzędzie służące do badania preferencji użytkowników dotyczących rozmieszczenia elementów interfejsów (w tym przypadku sklepów internetowych). Narzędzie to składało się z dwóch części - pierwszej - bardzo prostej, pozwalajacej za pomocą drag&amp;amp;dropa zaprojektować z dostępnych elementów własny interfejs. Druga służyła do przeglądania wyników tego badania. Nie pamiętam wszystkich funkcji tego narzędzia, ale na pewno można było filtrować badanych, porównywać wyniki dla grup, itd.&lt;/p&gt;
&lt;p&gt;Drugą część prezentacji prowadziła Katarzyna Jach, która przedstawiła wyniki badań na grupie, jeśli dobrze pamiętam, 500 studentów &lt;acronym title=&quot;Informatyki i Zarządzania&quot;&gt;IZetu&lt;/acronym&gt;. Zostali oni zapytani gdzie umieściliby przedstawione im elementy interfejsu. Dla każdego z predefioniowanych elementów serwisu (logo, kategorie, zdjęcie produktu, itd) zobaczyliśmy &quot;mapę cieplną&quot; gdzie badani widzieli tę funkcjonalność. Wyników nie pamiętam i nie udało mi się ich znaleźć. Dotarłem tylko do &lt;a href=&quot;http://www.ergonomia.ioz.pwr.wroc.pl/download/eLab%20microSzu%201.0%20Demo.html&quot;&gt;screenów i dema aplikacji nazwanej pieszczotliwie microSzu&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Na zakończenie z sali padły dwa pytania. Jedno dotyczyło tego po co powstała ten system skoro można przeprowadzić testy A/B przy pomocy &lt;a href=&quot;http://www.google.com/websiteoptimizer&quot;&gt;Google Website Optimizera&lt;/a&gt; (który jest bezpłatny, w przeciwieństwie do microSzu). Dla mnie odpowiedź jest oczywista (a pytanie bez sensu) - testy A/B pozwalają nam jedynie udoskonalać istniejącą już stronę i tylko element po elemencie. Wcześniej trzeba przecież tę stronę zaprojektować, czyli między innymi rozmieścić na niej elementy interfejsu. Badanie przeprowadzone przez microSzu pozwala nam na optymalne dla użytkowników zaprojektowanie strony. No właśnie - czy na pewno optymalne?&lt;/p&gt;
&lt;p&gt;Tego dotyczyło kolejne pytanie, a w zasadzie stwierdzenie - &lt;q&gt;&quot;użytkownik nie jest dobrym projektantem&quot;&lt;/q&gt;. W pierwszym momencie stwierdziłem, że i to pytanie jest bez sensu. Nie dajemy przecież użytkownikowi projektować, tylko badamy jego preferencje. To przecież część &lt;acronym title=&quot;User centered design&quot;&gt;UCD&lt;/acronym&gt;. Później (między innymi po przeczytaniu &lt;a href=&quot;http://www.szostek.net/BlogAga/?p=110&quot;&gt;relacji Agnieszki Matysiak-Szóstek&lt;/a&gt;, której prelekcji nie widziałem, czego bardzo żałuję) zacząłem się zastanawiać, czy na pewno mam rację. W końcu badanie polegało nie tylko na odpowiedzi na pytanie &lt;q&gt;gdzie szukałaby Pani/Pan listy kategorii?&lt;/q&gt;, ale na zaprojektowaniu całej strony na raz, czyli zmierzeniu się np. z problemem - &lt;q&gt;ten róg mam już zajęty, gdzie ja teraz ciapnę to to?&lt;/q&gt;.&lt;/p&gt;
&lt;p&gt;Myślę, że właśnie w treści pytania i zadaniu do wykonania leży cały problem. Gdyby udało się uzyskać od badanego wszystkie informacje, bez zmierzenia go z problemem całej strony jednocześnie, to uzyskane dane byłyby bardzo przydatne. Możnaby stworzyć proste wytyczne, w którym miejscu (bądź miejscach) możemy umieścić dany element by był łatwo znajdowalny (jeśli chodzi o region, bo pozostają użyte nazwy, czy kolor/wielkość/etc.) przez użytkownika. I nie musi to od razu ograniczać inwencji i talentu projektanta, który może zawsze zaryzykować jakąś zmianę względem szablonu. To jest tylko propozycja, a czy skorzystam, to zależy np. od ilości czasu jaką mogę projektowaniu poświęcić.&lt;/p&gt;
&lt;p&gt;Tak przynajmniej myślę ja u początków mojej przygody z użytecznością :)&lt;/p&gt;
</description><pubDate>Wed, 18 Nov 2009 23:28:17 +0100</pubDate><guid>http://blog.koszulinski.pl/2009/11/18/wud-tour-2009-wroclaw-relacja-i-przemyslenia/</guid><category>Frontend</category><category>Ogólne</category><category>Techblog</category><category>Użyteczność</category></item><item><title>Adobe AIR podstaw podstawy</title><link>http://blog.koszulinski.pl/2009/04/25/adobe-air-podstaw-podstawy/</link><description>&lt;p&gt;Generalnie, jako bardziej linuksowe wydanie geeka, nie patrzyłem na newsy związane z Adobe AIR zbyt przychylnym okiem. Jakieś zamknięte rozwiązanie, pewnie trzeba mieć adobowskie środowisko za 1k$ od stanowiska i na bank zrobią obsługę na Linuksie za dwa lata, jak zacznie im się tam nudzić. Tak więc skłaniałem się bardziej ku rozwiązaniom pokroju Mozilli Prism, czy Google Gears. Byłem jednak przez Darka Juszczuka namiętnie atakowany linkami o AIRze i kiedyś jeden otworzyłem. Na stronie znalazłem przycisk &quot;install&quot;, po kliknięciu którego, jak zrozumiałem, miała zainstalować mi się jakaś aplikacja.Z uśmiechem politowania na twarzy, bo w końcu nie mam AIRa na swoim Linuksie, więc się musi wysypać, kliknąłem w ów przycisk. No i zonk. Z poziomu wtyczki Flash zainstalował mi się Adobe AIR, po czym zaczął się instalować program, którego stronę przed chwilą oglądałem. Z pewną dozą nieufności podałem swoje hasło &quot;administratora&quot; (jedyny minus - nie wystarczą uprawnienia szarego usera do instalacji softu - na szczęście sam instalator jest zaufany) i gotowe. Aplikacja się odpala, śmiga jak marzenie, ładnie wygląda i w ogóle jakbym się na Windowsa przeniósł. No cóż. To skoro panowie z Adobe się tak postarali pora dać im szansę :).&lt;/p&gt;
&lt;h3&gt;AIR - was ist das?&lt;/h3&gt;
&lt;p&gt;Za &lt;a href=&quot;http://pl.wikipedia.org/wiki/Adobe_Integrated_Runtime&quot; title=&quot;Adobe Itegreted Runtime&quot;&gt;wikipedią&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Adobe Integrated Runtime, w skrócie AIR (nazwa kodowa Apollo) – wieloplatformowe środowisko wykonawcze dla RIA (ang. Rich Internet Application) zbudowanych za pomocą Flash, Flex, lub HTML i AJAX.&lt;/p&gt;
&lt;p&gt;Programy AIR mogą być aplikacjami pulpitu.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Czyli? Środowisko dla efektownych i bogatych aplikacji internetowych. Aplikacje te mogą być odpalane jak normalne desktopowe programy. A co to w praktyce? Jeszcze nie do końca wiem, bo w zasadzie, to na bieżąco się uczę pisząc ten artykuł (dla tego proszę o poprawianie jak bym jakoś naginał czasoprzestrzeń), ale na pewno integracja z systemem plików, lokalna baza danych, kontrolki jakie oferuje &lt;a href=&quot;http://pl.wikipedia.org/wiki/Adobe_Flex&quot;&gt;Flex&lt;/a&gt; (o nim pewnie w przyszłości), itd.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Co ważne&lt;/strong&gt; dla geeków ortodoksów. AIR != Flash. Aplikacje Flashowe mogą używać AIRa by powiększać swe możliwości. Ale Flasha w aplikacji AIRowej może w ogóle nie być. Zamiast niego można z powodzeniem użyć XHTMLa+JS, czy Fleksa+Actionscripta (który to kompiluje się już do obiektu SWF, ale za to ma wolne &lt;a href=&quot;http://www.adobe.com/devnet/flex/&quot; title=&quot;Flex&quot;&gt;SDK&lt;/a&gt; i nie potrzeba do niego żadnych płatnych narzędzi).&lt;/p&gt;
&lt;p&gt;Co trochę znamienne dla strony Adobe - miałem przed chwilą spory problem z podlinkowaniem SDK Fleksa. Niestety nie potrafię się poruszać płynnie po ich stronie i w ogóle nie znalazłem podstrony samego SDK. Ale spokojnie - może trochę dziwnie i niespójnie połączone, ale na stronie(nach) znajduje się cała potrzebna dokumentacja, którą do tej pory oceniam raczej dobrze.&lt;/p&gt;
&lt;p&gt;Aha - &lt;a href=&quot;http://opensource.adobe.com/wiki/display/flexsdk/Flex+SDK&quot;&gt;Flex, jeśli dobrze rozumiem, jest open source'owy&lt;/a&gt; :O&lt;/p&gt;
&lt;h3&gt;Moja pierwsza aplikacja AIR oparta o HTML&lt;/h3&gt;
&lt;p&gt;Czego potrzebujemy? Na pewno przyda nam się &lt;a href=&quot;http://www.adobe.com/go/getairsdk&quot;&gt;AIR SDK&lt;/a&gt;. Co prawda można skorzystać także z darmowej &lt;a href=&quot;http://www.aptana.com/air/&quot;&gt;Aptany&lt;/a&gt;, albo płatnego &lt;a href=&quot;http://www.adobe.com/go/devcenter_dw_try&quot;&gt;Adobe Dreamweaver CS3/CS4&lt;/a&gt; z &lt;a href=&quot;http://www.adobe.com/go/getair_dreamweaver&quot;&gt;Adobe AIR Extension for Dreamweaver&lt;/a&gt;, ale my skupimy się na najniższym poziomowo rozwiązaniu, czyli AIR SDK (który rzecz jasna należy pobrać). Do tego na pewno będzie nam potrzebna zainstalowana &lt;a href=&quot;http://www.adobe.com/go/getair&quot;&gt;biblioteka uruchomieniowa (czyt. plugin) Adobe AIR&lt;/a&gt;. No i na koniec zwykły edytor tekstu (najlepiej gvim :).&lt;/p&gt;
&lt;p&gt;Mało odkrywczo zaczniemy od przywitania się ze światem. Nie pokazuje to ani trochę możliwości AIRa, ale w tym wpisie już nic więcej nie zmieszczę - za długi się robi :). Stwórzmy więc sobie katalog &lt;code&gt;HelloWorld&lt;/code&gt;, w którym będziemy potrzebowali kilku plików.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;HelloWorld.html&lt;/dt&gt;
&lt;dd&gt;plik obowiązkowy - główna strona naszej aplikacji,&lt;/dd&gt;
&lt;dt&gt;HelloWorld-app.xml&lt;/dt&gt;
&lt;dd&gt;również obowiązkowy - konfiguracja aplikacji (z ang. descriptor) w którym między innymi można ustawić ścieżkę instalacji, nazwę, ikony, ustawienia okna, czy ścieżkę do głównego pliku HTML,&lt;/dd&gt;
&lt;dt&gt;AIRAliases.js&lt;/dt&gt;
&lt;dd&gt;plik przydatny - tworzy proste aliasy do JSowych obiektów dostępnych dzięki AIR. Np. zamiast &lt;code&gt;window.runtime.flash.filesystem.File&lt;/code&gt; otrzymujemy &lt;code&gt;air.File&lt;/code&gt;. Plik ten przekopiowujemy z &lt;code&gt;sciezka_do_AdobeAIRSDK/frameworks/libs/air/&lt;/code&gt;.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Na początek HelloWorld.html. Zakładam, że składnię HTMLa znasz i nie muszę nic tłumaczyć. Jakby ktoś chciał więcej szczegółów odnośnie zawartości plików, to odsyłam do &lt;a href=&quot;http://help.adobe.com/en_US/AIR/1.5/devappshtml/WS5b3ccc516d4fbf351e63e3d118666ade46-7ecc.html&quot; title=&quot;Creating your first HTML-based AIR application with the AIR SDK&quot;&gt;źródła skąd cały ten przykład zaczerpnąłem&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;{geshi lang=xml}&lt;/p&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;AIRAliases.js&quot;&gt;
&lt;/script&gt;&lt;script type=&quot;text/javascript&quot;&gt;
 
        function appLoad() { 
            air.trace(&quot;Jakis trace&quot;); 
        }  
&lt;/script&gt;
&lt;h1&gt;Hello World&lt;/h1&gt;
&lt;p&gt;{/geshi}&lt;/p&gt;
&lt;p&gt;Jak widać - żadnych rewolucji. Pora na HelloWorld-app.xml:&lt;/p&gt;
&lt;p&gt;{geshi lang=xml} examples.html.HelloWorld 0.1 HelloWorld HelloWorld.html true 400 200 {/geshi}&lt;/p&gt;
&lt;p&gt;Wydaje mi się, że wszystko powinno być jasne. Jedynie wartość elementu &lt;code&gt;&amp;lt;filename&amp;gt;&lt;/code&gt; była dla mnie niejasna, więc tłumaczę - jest to nazwa aplikacji w systemie (czyli po zainstalowaniu). Wchodzi w to: katalog instalacyjny, plik wykonywalny oraz nazwa w menu systemowym (każdą z tych rzeczy można jeszcze ustawić osobno).&lt;/p&gt;
&lt;h3&gt;Testowanie aplikacji&lt;/h3&gt;
&lt;p&gt;Do testowego uruchamiania (i debugowania) stworzonej aplikacji służy odpalany z wiersza poleceń AIR Debug Launcher (ADL). Znajduje się on w &lt;code&gt;sciezka_do_AdobeAIRSDK/bin/&lt;/code&gt;. Włączamy więc konsolę, przechodzimy do katalogu HelloWorld i startujemy:&lt;/p&gt;
&lt;pre&gt;
p@d:/air/HelloWorld$ &lt;kbd&gt;/air/AdobeAIRSDK/bin/adl HelloWorld-app.xml&lt;/kbd&gt;
&lt;samp&gt;Jakis trace&lt;/samp&gt;
p@d:/air/HelloWorld$
&lt;/pre&gt;
&lt;p&gt;Powinniśmy obejrzeć takie o to, piękne okienko:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://protazy.lo3.wroc.pl/~d04/jogger_files/air1/air1.png&quot; alt=&quot;Wynik działania programu HelloWorld&quot;&gt;&lt;/p&gt;
&lt;p&gt;Jak widać program wydrukował nam też na konsoli &quot;&lt;samp&gt;Jakis trace&lt;/samp&gt;&quot; co jest wynikiem działania &lt;code&gt;air.trace(&quot;Jakis trace&quot;)&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Tworzenie pliku instalacyjnego .air&lt;/h3&gt;
&lt;p&gt;Pora teraz spakować do jednego pliku instalacyjnego (paczka zip) naszą aplikację dzięki której zapanujemy nad światem. Służy do tego narzędzie ADT.&lt;/p&gt;
&lt;p&gt;Pierwsze co trzeba wiedzieć, to że wszystkie AIRowskie aplikacje są cyfrowo podpisane. Temat ten jest mi kompletnie obcy i za pierwszym razem męczyłem się 3h żeby wygenerować jakiś swój klucz. Otóż poszedłem w stronę javowego keytoola, co było dla mnie ślepą uliczką ;). Co prawda nauczyłem się generować wszystkie typy kluczy, ale żaden nie działał :D. Na szczęście jest o wiele prostsza (i przede wszystkim działająca) ścieżka, którą przegapiłem. O niej za chwilę, a teraz cytat ze &lt;a href=&quot;http://help.adobe.com/en_US/AIR/1.5/devappshtml/WS5b3ccc516d4fbf351e63e3d118666ade46-7ecc.html&quot;&gt;strony Adobe&lt;/a&gt; o bezpieczeństwie:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;To ensure application security, all AIR installation files must be digitally signed. For development purposes, &lt;em&gt;you can generate a basic, self-signed certificate with ADT&lt;/em&gt; or another certificate generation tool. You can also buy a commercial code-signing certificate from a commercial certificate authority such as VeriSign or Thawte. When users install a self-signed AIR file, the publisher is displayed as “unknown” during the installation process. This is because a self-signed certificate only guarantees that the AIR file has not been changed since it was created. There is nothing to prevent someone from self-signing a masquerade AIR file and presenting it as your application. For publicly released AIR files, a verifiable, commercial certificate is strongly recommended. For an overview of AIR security issues, see AIR security.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Oczywiście przegapiłem zaznaczony fragment i cały akapit poniżej :) A w zasadzie to mam wrażenie, że go tam wcześniej nie było. Ale koniec płaczu nad straconym czasem. Generujemy własny klucz:&lt;/p&gt;
&lt;pre&gt;
p@d:/air/HelloWorld$ &lt;kbd&gt;/air/AdobeAIRSDK/bin/adt -certificate -cn &lt;var&gt;AIRBegginer&lt;/var&gt; 1024-RSA &lt;var&gt;my_key_file&lt;/var&gt; &lt;var&gt;dupa.8&lt;/var&gt;&lt;/kbd&gt;
&lt;/pre&gt;
&lt;p&gt;W ten o to sposób wygenerowaliśmy klucz na nazwę podmiotu (company name) &lt;var&gt;AIRBegginer&lt;/var&gt;, zabezpieczony hasłem &lt;var&gt;dupa.8&lt;/var&gt;, który został zapisany do pliku &lt;var&gt;my_key_file&lt;/var&gt;. Można go podejrzeć javowym narzędziem &lt;code&gt;keytool&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;
p@d:/air/HelloWorld$ keytool -list -v -keystore my_key_file -storetype pkcs12
Enter keystore password:  

Keystore type: PKCS12
Keystore provider: SunJSSE

Your keystore contains 1 entry

Alias name: 1
Creation date: 2009-04-25
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=AIRBegginer
Issuer: CN=AIRBegginer
Serial number: 36373061626165333a31323064646264383133663a2d38303030
Valid from: Sat Apr 25 16:46:05 CEST 2009 until: Fri Apr 25 16:46:05 CEST 2014
(...)
&lt;/pre&gt;
&lt;p&gt;Tak utworzonym kluczem możemy teraz podpisać naszą aplikację:&lt;/p&gt;
&lt;pre&gt;
p@d:/air/HelloWorld$ &lt;kbd&gt;/air/AdobeAIRSDK/bin/adt -package -storetype pkcs12 -keystore my_key_file HelloWorld.air HelloWorld-app.xml HelloWorld.html AIRAliases.js&lt;/kbd&gt;
&lt;/pre&gt;
&lt;p&gt;Zostaniemy poproszeni o hasło i jeśli nic nie skopaliśmy, to ADT stworzy nam plik HelloWorld.air, który jest naszą pierwszą spakowaną i gotową do instalacji aplikacją AIR.&lt;/p&gt;
&lt;h3&gt;Instalacja&lt;/h3&gt;
&lt;p&gt;Najprostszy sposób jeśli mamy w systemie zmapowane rozszerzenie .air z instalatorem Adobe AIR (ja standardowo tak miałem) to instalacja jak na Windowsie - przez podwójnego klika w HelloWorld.air. Jeśli nie to wpisujemy:&lt;/p&gt;
&lt;pre&gt;
p@d:/air/HelloWorld$ /opt/Adobe AIR/Versions/1.0/airappinstaller ./HelloWorld.air 
unexpected error: ArgumentError: Error #2004
p@d:/air/HelloWorld$ /opt/Adobe AIR/Versions/1.0/airappinstaller /air/HelloWorld/HelloWorld.air
&lt;/pre&gt;
&lt;p&gt;Jak widać skrypt jest zbyt &quot;głupi&quot; żeby sobie poradzić ze ścieżką względną i trzeba podać absolutną. Chwila czekania i zium:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://protazy.lo3.wroc.pl/~d04/jogger_files/air1/air2.png&quot; alt=&quot;Instalowanie aplikacji AIR&quot;&gt;&lt;/p&gt;
&lt;p&gt;Znów hasło roota i wszystko działa.&lt;/p&gt;
&lt;h3&gt;Zarządzanie zainstalowanymi aplikacjami na Linuksie&lt;/h3&gt;
&lt;p&gt;Programy niestety na moim Ubuntu pojawiają się w menu systemowym w sekcji &quot;Akcesoria&quot;. Zainstalowałem już kilka na próbę i zaczął mi się tam robić bałagan. Ustawienie w pliku konfiguracyjnym aplikacji pola &lt;code&gt;&amp;lt;programMenuFolder&amp;gt;&lt;/code&gt; zdaje się działać tylko na Windowsach.&lt;/p&gt;
&lt;p&gt;Przed chwilą znalazłem także informację o tym jak można zarządzać już zainstalowanymi programami. Otóż są one instalowane jak paczki odpowiednio deb albo rpm. Dzięki temu np. w moim Ubuntu mogłem odinstalować programy z poziomu Synaptica. Nazwa programu składa się z z pola applicationId (np. examples.html.helloworld) oraz publisherID.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://protazy.lo3.wroc.pl/~d04/jogger_files/air1/air3.png&quot; alt=&quot;Program AIR w Synapticu&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Uwaga&lt;/strong&gt; dla każdego, kto nie znalazł swojej aplikacji - ja musiałem zrestartować system żeby Synaptic się odświeżył.&lt;/p&gt;
&lt;h3&gt;Koniec&lt;/h3&gt;
&lt;p&gt;To by było na tyle. Miałem jeszcze w tym artykule (ależ to ładnie brzmi ;P) pokazać jakiś ciekawszy przykład aplikacji, ale wydaje mi się, że byłby to już zbyt długi wpis. Postaram się więc dość szybko zmajstrować następną notkę. I będzie ona albo przedstawiała możliwości jakie daje AIR, albo skrobnę coś o Fleksie. A najpewniej i jedno, i drugie w krótkim czasie :).&lt;/p&gt;
&lt;p&gt;Jeśli chodzi o ten wpis, to wszelkie sugestie, uwagi, czy pytania mile widziane. Jak zaznaczyłem gdzieś po drodze - moja wiedza na temat Adobe AIR jest nikła i mogłem popełnić sporo błędów.&lt;/p&gt;
&lt;h3&gt;Źródło i inne przydatne linki&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://help.adobe.com/en_US/AIR/1.5/devappshtml/WS5b3ccc516d4fbf351e63e3d118666ade46-7ecc.html&quot;&gt;Źródło, którego ten tekst jest w zasadzie bardzo luźnym tłumaczeniem&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.adobe.com/support/documentation/pl/air/1_5/AIR_1_5_linux_release_notes.pdf&quot;&gt;Więcej informacji o Adobe AIR na Linuksie&lt;/a&gt;,&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.adobe.com/devnet/air/&quot;&gt;AIR Developer Center&lt;/a&gt; - sam czubek góry lodowej. Stąd chyba dobrze zaczynać poszukiwania czegokolwiek,&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://help.adobe.com/en_US/AIR/1.5/devappshtml/&quot;&gt;Dokumentacja Adobe AIR&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Wpis ten ukazał się równolegle na &lt;a href=&quot;http://code42.pl/2009/04/25/adobe-air-podstaw-podstawy/&quot;&gt;moim blogu firmowym&lt;/a&gt;.&lt;/p&gt;
</description><pubDate>Sat, 25 Apr 2009 23:19:15 +0200</pubDate><guid>http://blog.koszulinski.pl/2009/04/25/adobe-air-podstaw-podstawy/</guid><category>Adobe AIR</category><category>Ogólne</category><category>Techblog</category></item><item><title>Walidacja jednego pola formularza w symfony</title><link>http://blog.koszulinski.pl/2009/03/31/walidacja-jednego-pola-formularza-w-symfony/</link><description>&lt;p&gt;Natknąłem się ostatnio na problem. Otóż wszystkie formularze walidujemy przy wykorzystaniu &lt;a href=&quot;http://www.symfony-project.org/book/forms/1_2/en/&quot;&gt;symfoniowych Formsów&lt;/a&gt;. Standardowe użycie podczas aktualizacji obiektu &lt;code&gt;Place&lt;/code&gt; wygląda następująco:&lt;/p&gt;
&lt;p&gt;{geshi lang=php}$this-&amp;gt;form = new PlaceForm ($place); $this-&amp;gt;form-&amp;gt;bind ($request-&amp;gt;getParameter ('place')); if ($this-&amp;gt;form-&amp;gt;isValid()) { $place = $this-&amp;gt;form-&amp;gt;updateObject(); $place-&amp;gt;save(); }{/geshi}&lt;/p&gt;
&lt;p&gt;Co jednak kiedy nie chcemy walidować całego formularza? Np. w przypadku kiedy używając &lt;a href=&quot;http://wiki.github.com/madrobby/scriptaculous/ajax-inplaceeditor&quot;&gt;InPlaceEditora&lt;/a&gt; zmieniamy jedno pole. Podpowiem, że próba wysłania tylko tego jednego pola i wykorzystaniu tej samej akcji skończy się wyzerowaniem pozostałych pól.&lt;/p&gt;
&lt;p&gt;Dokumentacja symfony niestety milczy na ten temat (choć przyznam się, że nie szukałem jakoś strasznie dokładnie), a wiemy chyba wszyscy co jest jej największą bolączką - opisanie tylko kilku funkcjonalności poszczególnych modułów. Jak się chce czegoś więcej, to droga wolna - szukajcie sobie sami w kodzie.&lt;/p&gt;
&lt;p&gt;Tak też postąpiłem. I po koszmarnie długim czasie odkryłem, że do walidowania każdego z pól służy metoda o intuicyjnej nazwie... &lt;code&gt;clean()&lt;/code&gt;. Przykład walidacji jednego pola:&lt;/p&gt;
&lt;p&gt;{geshi lang=php}$form = new PlaceForm($place); try { $cleaned = $form-&amp;gt;getValidator($field_name)-&amp;gt;clean($value); #1 $place-&amp;gt;setByName($field_name, $cleaned, BasePeer::TYPE_FIELDNAME); #2 $place-&amp;gt;save(); } catch (sfValidatorError $e) #3 { #Obsługa błędu }{/geshi}&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Pobranie odpowiedniego walidatora oraz wywołanie na nim metody &lt;code&gt;clean()&lt;/code&gt;, która w przypadku, gdy pole ma poprawną wartość zwraca je. A w przypadku błędu wyrzuca wyjątek &lt;code&gt;sfValidatorError&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;Zapisanie wyczyszczonej wartości tego pola do obiektu,&lt;/li&gt;
&lt;li&gt;Kod obsługujący przypadek niewalidującego się pola.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Mam nadzieję, że ten krótki artykuł pozwoli komuś zaoszczędzić trochę czasu.&lt;/p&gt;
&lt;p&gt;Wpis opublikowałem także na &lt;a href=&quot;http://code42.pl/2009/03/31/walidacja-jednego-pola-formularza-w-symfony/&quot;&gt;firmowym blogu code42&lt;/a&gt;.&lt;/p&gt;
</description><pubDate>Tue, 31 Mar 2009 15:34:02 +0200</pubDate><guid>http://blog.koszulinski.pl/2009/03/31/walidacja-jednego-pola-formularza-w-symfony/</guid><category>Ogólne</category><category>PHP</category><category>Symfony</category><category>Techblog</category><category>symfony sfvalidator basepropelform walidacja formularze php</category></item><item><title>Ideowo o HTMLu i CSSie</title><link>http://blog.koszulinski.pl/2009/03/18/ideowo-o-htmlu-i-cssie/</link><description>&lt;p&gt;Nie, nie będzie to wpis o tym jak moim zdaniem powinien wyglądać HTML5 i CSS3 (a w zasadzie to 4 już). Popełnienie takiego tekstu mam w planach i jak trochę powrócę do żywych, to może mi się uda :).&lt;/p&gt;
&lt;p&gt;Jak pewnie niektórzy wiedzą - zostałem zatrudniony na etacie w firmie, z którą od dłuższego czasu (~dwa lata) współpracowałem jako freelancer. Na pierwszy ogień poszedł mały, wewnętrzny projekt, przy którym współpracuję między innymi z &lt;a href=&quot;http://mcv.jogger.pl&quot;&gt;mcvłem&lt;/a&gt;. Do tej pory obaj sporo tworzyliśmy HTMLa i CSSów, ale żaden z nas, a na pewno nie ja, nie musiał przy tym z nikim ściśle współpracować.&lt;/p&gt;
&lt;p&gt;Każdy programista na pewno rozumie to, że w nowym zespole zawsze trzeba ustalić konwencje dotyczące stylu kodowania. My apropo HTMLa ustaliliśmy, że używamy pojedynczych cudzysłowów (do tej pory zawsze korzystałem z podwójnych i herezją było dla mnie używanie pojedynczych, ale w zasadzie nie jest źle :). Z CSSem było gorzej, bo musiałem zmusić mcvała żeby pisać całe selektory i wszystkie właściwości w jednej linii, ale dało radę.&lt;/p&gt;
&lt;p&gt;I tak z pierwszymi ustaleniami zasiedliśmy do pracy. Popracowaliśmy całe 4 dni i okazało się, że te krótkie ustalenia to stanowczo za mało.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;&amp;lt;address&amp;gt;&lt;/code&gt;&lt;/h3&gt;
&lt;dl&gt;
&lt;dt&gt;Interpretacja mcvała&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;Tagu &lt;code&gt;address&lt;/code&gt; możemy używać jedynie zgodnie ze &lt;a href=&quot;http://www.w3.org/TR/1999/REC-html401-19991224/struct/global.html#h-7.5.6&quot;&gt;specyfikacją HTMLa 4.01&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;ADDRESS&lt;/code&gt; element may be used by authors to supply contact information for a document or a major part of a document such as a form.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Czyli możemy w tym tagu zawrzeć informacje dotyczące kontaktu z &lt;strong&gt;autorem&lt;/strong&gt; (prawdopodobnie jedynie drogą elektroniczną). Mogą to być linki, maile, ale co ciekawe - ulica i miasto już raczej nie. Wydaje się to potwierdzać dość dziwny przykład podany dalej w specyfikacji:&lt;/p&gt;
{geshi lang=html}
&lt;address&gt;&lt;a href=&quot;../People/Raggett/&quot;&gt;Dave Raggett&lt;/a&gt;, &lt;a href=&quot;../People/Arnaud/&quot;&gt;Arnaud Le Hors&lt;/a&gt;, contact persons for the &lt;a href=&quot;Activity&quot;&gt;W3C HTML Activity&lt;/a&gt;&lt;br&gt;
$Date: 1999/12/24 23:37:50 $&lt;/address&gt;
{/geshi}&lt;/dd&gt;
&lt;dt&gt;Moja interpretacja&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;Nie ma potrzeby trzymać się co do słowa niedoskonałej specyfikacji HTMLa sprzed prawie 10 lat. Użyjmy taga &lt;code&gt;address&lt;/code&gt; jako taga semantycznego nadającego znaczenie każdemu zawartemu w środku adresowi (czy to pocztowemu, czy mailowemu, czy też stronie firmowej). Dodatkowo - nie oznaczajamy nim jedynie danych kontaktowych z autorem strony, ale także z każdym innym podmiotem, który na stronie opisujemy (np. we wszelakich bazach miejsc).&lt;/p&gt;
&lt;p&gt;Dodatkowo uważam, że nazwa &lt;code&gt;address&lt;/code&gt; jest bardzo niefortunna, jeśli mamy tam umieszczać linki. Gdyby ktoś miał na myśli jedynie informacje o kontakcie, to tag nazywałby się &lt;code&gt;contact&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I tutaj chciałbym wesprzeć się przetłumaczonym przez &lt;a href=&quot;http://grabun.com/&quot;&gt;&lt;cite&gt;Łukasza Grabunia&lt;/cite&gt;&lt;/a&gt; artykułem pt. &lt;a href=&quot;http://grabun.com/teksty/zapomniane-znaczniki/&quot;&gt;Zapomniane znaczniki&lt;/a&gt;, który od lat służy mi pomocą w walce ze sklerozą :).&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;
&lt;h3&gt;Inne moje nadinterpretacje&lt;/h3&gt;
&lt;p&gt;Istnieje jeszcze kilka innych tagów, przy których interpretacji nie uważam za sensowne ściśle trzymać się specyfikacji. Od razu podkreślam, że nie mam na myśli zupełnego oderwania się od niej. Nie chcę używać &lt;code&gt;table&lt;/code&gt; jako tagu do opisu stołu w restauracji, albo tabelkowego layoutu. Uważam natomiast, że na przykład lista definicji to nie tylko stricte:&lt;/p&gt;
&lt;p&gt;{geshi lang=html}&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Kura&lt;/dt&gt;
&lt;dd&gt;Stworzenie boskie, o dwóch nogach i opierzonym ciele&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;{/geshi}&lt;/p&gt;
&lt;p&gt;Ale także inne konstrukcje zawierające jakiś temat i jego zawartość. Na przykład lista użyta przeze mnie wcześniej trochę z premedytacją:&lt;/p&gt;
&lt;p&gt;{geshi lang=html}&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;Interpretacja mcvała&lt;/dt&gt;
&lt;dd&gt;(...)&lt;/dd&gt;
&lt;dt&gt;Moja interpretacja&lt;/dt&gt;
&lt;dd&gt;(...)&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;{/geshi}&lt;/p&gt;
&lt;p&gt;Oczywiście mogłaby też wyglądać tak:&lt;/p&gt;
&lt;p&gt;{geshi lang=html}&lt;/p&gt;
&lt;h3&gt;Interpretacja mcvała&lt;/h3&gt;
&lt;div class='section'&gt;(...)&lt;/div&gt;
&lt;h3&gt;Moja interpretacja&lt;/h3&gt;
&lt;div class='section'&gt;(...)&lt;/div&gt;
&lt;p&gt;{/geshi}&lt;/p&gt;
&lt;p&gt;I w pewnym przypadkach jest to zdecydowanie poprawniejsze rozwiązanie. Jednak kiedy nagłówki sekcji nie są wyraźne (mam tu na myśli rzecz jasna znaczenie wynikające z treści strony, a nie jej wyglądu :P) i są jedynie opisami tego co znajduje się niżej, to wolę użyć rozwiązania pierwszego. Ale akurat w specyfikacji listy definicji twórcy HTMLa podali więcej przykładów, które w pewnym sensie tłumaczą moją nadinterpretację.&lt;/p&gt;
&lt;p&gt;Przypomina mi się także, że kiedyś był mały ruch przekonujący by całą stronę (poza treścią typowo akapitowo - nagłówkową) opisywać listami uporządkowanymi, nieuporządkowanymi i listami definicji. W pewnym sensie zgadzałem się z tym, że cała strona jest jakąś listą i sporą większość jej elementów da się zrozumieć jako jakąś część listy. Zdaje się jednak, że to już przesada w drugą stronę :)&lt;/p&gt;
&lt;h3&gt;Na HTMLu nie koniec&lt;/h3&gt;
&lt;p&gt;Żeby nie było za miło posprzeczaliśmy się także o niektóre rozwiązania w CSSie :)&lt;/p&gt;
&lt;h4&gt;Styl mcvała&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;zostawiamy przeglądarkowe paddingi i marginesy, bądź ustalamy ich początkowe wartości (ale nie na zero),&lt;/li&gt;
&lt;li&gt;aby odsunąć w pionie zawartość rodzica od dziecka nadajemy dziecku marginesy pionowe i jeśli potrzeba rodzicowi &lt;code&gt;padding:0.1px&lt;/code&gt;. Jeśli trzeba, czyli w przypadku braku obramowania, bądź paddingu,&lt;/li&gt;
&lt;li&gt;wszystkie marginesy i paddingi ustalamy według emów - aby zwiększona w kodzie wielkość czcionki miała wpływ na te wielkości.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Mój styl&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;zerujemy za pomocą &lt;code&gt;* {padding:0; margin:0}&lt;/code&gt; wszystkie niepotrzebne odstępy, aby móc nad nimi dokładnie zapanować. Nadajemy je z powrotem dopiero w treściach strony,&lt;/li&gt;
&lt;li&gt;aby odsunąć w pionie zawartość rodzica od dziecka używamy paddingów dla tego pierwszego. A poprzez &lt;code&gt;:last-child&lt;/code&gt; zerujemy margines ostatniemu dziecku (dzieci mają marginesy aby je od siebie odsunąć),&lt;/li&gt;
&lt;li&gt;marginesy i paddingi w 90% przypadków podajemy w pikselach, by mieć większą kontrolę nad ich wartościami (i nie mieć zonka że coś się rozjeżdża bo zmieniłem wielkość czcionki)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Oczywiście żaden z nas nie był w stanie przekonać drugiego do swoich racji :). Niestety - obaj w swoim życiu już za dużo layoutów pocieliśmy i zbyt wyrobione mamy zdanie na niektóre tematy. Ale i tak uważam, że można się sporo ciekawych rzeczy dowiedzieć pracując z drugą osobą. Ja na przykład dowiedziałem się o własciwości &lt;a href=&quot;http://www.css3.info/preview/box-sizing/&quot;&gt;box-sizing&lt;/a&gt; i wreszcie zapanuję nad &lt;code&gt;{width:100%; padding:10px}&lt;/code&gt; :).&lt;/p&gt;
</description><pubDate>Wed, 18 Mar 2009 02:28:32 +0100</pubDate><guid>http://blog.koszulinski.pl/2009/03/18/ideowo-o-htmlu-i-cssie/</guid><category>CSS</category><category>Frontend</category><category>HTML</category><category>Ogólne</category><category>Techblog</category></item><item><title>&quot;Echowanie&quot; Javascriptu przy pomocy Firebuga</title><link>http://blog.koszulinski.pl/2009/03/08/echowanie-javascriptu-przy-pomocy-firebuga/</link><description>&lt;h3&gt;Rys historyczny, można pomijać&lt;/h3&gt;
&lt;p&gt;Tak, wiem, że istnieje coś takiego jak debugger :). Nigdy się jednak z żadnego porządnie nie nauczyłem korzystać. Po trochu dlatego, że wymaga to zazwyczaj poświęcenia dodatkowego czasu na naukę nowego narzędzia, po trochu dlatego, że najwięcej kodu tworzę w PHP i JS w gVimie, który chyba nie posiada żadnego zintegrowanego narzędzia, ale głównie dlatego, że to często armata na komara. Niejednokrotnie wystarczy podejrzeć przecież zawartość jednej zmiennej aby rozwiązać problem. I tak prawdopodobnie każdy programista nauczył się &quot;echowania&quot; (kłania się zapewne PHP ;).&lt;/p&gt;
&lt;p&gt;Problem pojawia się jednak kiedy zaczynamy tworzyć w Javascriptcie, który to nie posiada żadnego wyjścia, jakieś proste skrypciki. Pierwszym pomysłem jaki przychodzi do głowy jest wykorzystanie funkcji &lt;code&gt;alert()&lt;/code&gt;. Często to dobre rozwiązanie, choć mało wygodne - wyskakujące okienko bywa naprawdę denerwujące. Szczególnie jak zaczyna pokazywać się coraz częściej i w większych ilościach. Dodatkowo, Firefox z którego korzystam, ma tę niezrozumiałą dla mnie własność, że kiedy wyskoczył jakiś alert nie dopuszcza mnie do okna przeglądarki. Co więcej - nie pozwala (a przynajmniej mi się nigdy nie udało) wyłączyć Javascriptu z poziomu tegoż okienka (co potrafi np. Opera). Kończy się więc to killem przeglądarki kiedy jakiś dowcipniś wrzuci &lt;code&gt;alert(&quot;joke&quot;);&lt;/code&gt; w niekończącą się pętle. A samemu podczas &quot;echowania&quot; też zdarzyło mi się zabić takim alertem, więc trzeba uważać :) (&lt;code&gt;setInterval()&lt;/code&gt;, czy niefortunne powiązanie z jakimś zdarzeniem).&lt;/p&gt;
&lt;p&gt;W związku z &lt;a href=&quot;http://blip.pl/s/7668450&quot;&gt;pytaniem&lt;/a&gt;, które ktoś rzucił dzisiaj na blipa zacząłem zastanawiać się czy nie ma lepszego rozwiązania. Pierwszy pomysł jaki mi przyszedł do głowy to napisanie prostej klasy &lt;code&gt;Console&lt;/code&gt;, która będzie dodawała swoje okno na stronie i za pomocą jakiejś metody &lt;code&gt;out()&lt;/code&gt;, &lt;code&gt;push()&lt;/code&gt;, czy jakiejś pozwalała ładnie wypisywać zawartość danej zmiennej. Szybko jednak okazało się, że twórcy &lt;a href=&quot;http://getfirebug.com/&quot;&gt;Firebuga&lt;/a&gt; wpadli na ten pomysł pierwsi :).&lt;/p&gt;
&lt;h3&gt;Konsola Firebuga, część właściwa wpisu&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://getfirebug.com/console.html&quot;&gt;Konsola Firebuga&lt;/a&gt; udostępnia nam kilka ciekawych funkcjonalności. Pierwszą z nich jest &lt;code&gt;console.log()&lt;/code&gt;, która pozwala formatować wyjście na kilka sposobów:&lt;/p&gt;
&lt;p&gt;{geshi lang=javascript}console.log(&quot;Ten kod powinien się wykonać&quot;); var foo = &quot;bar&quot;, x = 12.34, i = 122; console.log(&quot;foo: %s, (int) i: %d, (float) x: %f&quot;, foo, i, x); function Kopytko() { this.palec1 = 11.12; this.palec2 = &quot;qń&quot;; }; kopyto = new Kopytko(); console.log(kopyto); console.log(kopyto.brak);{/geshi}&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://protazy.lo3.wroc.pl/~d04/jogger_files/scr1.png&quot; alt=&quot;Przykład działania console.log w Firebugu&quot; width=&quot;642&quot; height=&quot;195&quot;&gt;&lt;/p&gt;
&lt;p&gt;Jednak to nie wszystko. Możemy także pokolorować i nadać znaczenia naszej radosnej twórczości. I tak mamy dostępne metody &lt;code&gt;console.debug()&lt;/code&gt;, &lt;code&gt;console.info()&lt;/code&gt;, &lt;code&gt;console.warn()&lt;/code&gt;, &lt;code&gt;console.error()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://protazy.lo3.wroc.pl/~d04/jogger_files/scr2.png&quot; alt=&quot;Przykład formatowania informacji na konsoli Firebuga&quot; width=&quot;642&quot; height=&quot;195&quot;&gt;&lt;/p&gt;
&lt;p&gt;Dodatkowo, przydatne (np. przy pracy z Ajaksem, czy manipulacjach w drzewie DOM) może się okazać również drukowanie HTMLa oraz XMLa. Służy do tego metoda &lt;code&gt;console.dirxml(DOMElement)&lt;/code&gt;. Wyświetla ona drzewo znane nam z zakładki &quot;HTML&quot; Firebuga.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://protazy.lo3.wroc.pl/~d04/jogger_files/scr3.png&quot; alt=&quot;Przykład działania console.dirxml() w Firebugu&quot; width=&quot;642&quot; height=&quot;395&quot;&gt;&lt;/p&gt;
&lt;p&gt;To chyba na tyle o &quot;echowaniu&quot; na konsolę Firebuga. Więcej informacji możecie znaleźć w &lt;a href=&quot;http://getfirebug.com/console.html&quot;&gt;Console API&lt;/a&gt; oraz &lt;a href=&quot;http://getfirebug.com/logging.html&quot;&gt;Rejestrowaniu Javascriptu&lt;/a&gt; (damn - nie mogę lepszego tłumaczenia znaleźć :). I tak z poziomu kodu można mierzyć czas wykonania bloku instrukcji &lt;code&gt;console.time(&quot;name&quot;); {..} console.timeEnd(&quot;name&quot;);&lt;/code&gt;, czy tworzyć asercje (a jak to się tłumaczy?).&lt;/p&gt;
&lt;h3&gt;Rys historyczny cz. 2, też można pominąć&lt;/h3&gt;
&lt;p&gt;Wpis ten napisałem głównie dla ludzi, którzy tak jak ja, jakimś cudem przeoczyli tę funkcjonalność Firebuga. Nie mylili się &lt;a href=&quot;http://zergu.jogger.pl&quot;&gt;Zergu&lt;/a&gt; i &lt;a href=&quot;http://mcv.jogger.pl&quot;&gt;mcv&lt;/a&gt; mówiąc, że o rzeczach oczywistych się nie pisze bo są... oczywiste. Jak jednak często się okazuje - nie dla każdego :). A właśnie taka demotywująca myśl spowodowała, że od tak dawna nic nie pisałem.&lt;/p&gt;
&lt;p&gt;Wpis ten ukazał się w okrojonej (mniej osobistej) formie na &lt;a href=&quot;http://code42.pl&quot;&gt;moim blogu firmowym&lt;/a&gt;&lt;/p&gt;
</description><pubDate>Sun, 08 Mar 2009 00:04:44 +0100</pubDate><guid>http://blog.koszulinski.pl/2009/03/08/echowanie-javascriptu-przy-pomocy-firebuga/</guid><category>Frontend</category><category>Javascript</category><category>Ogólne</category><category>Techblog</category><category>firebug</category><category>console</category><category>output</category></item><item><title>Przenosiny cz. 2</title><link>http://blog.koszulinski.pl/2009/03/06/przenosiny-cz-2/</link><description>&lt;p&gt;Tych co nie czytali części poprzedniej zapraszam tu: &lt;a rel=&quot;prev&quot; href=&quot;http://reinmar.jogger.pl/2009/03/06/przenosiny/&quot;&gt;&lt;cite&gt;Przenosiny cz. 1&lt;/cite&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Akt trzeci - czekanie&lt;/h3&gt;
&lt;p&gt;Tak więc od początku stycznia czekaliśmy na otwarcie Systemu, by móc złożyć podanie. Przypomnę, że za załatwianie sprawy z wiadomych względów zabraliśmy się na półtora miesiąca przed sesją. I... ku naszej niebywałej uciesze, jakoś tuż przed końcem semestru System uruchomiono. Czad po prostu.&lt;/p&gt;
&lt;h3&gt;Akt czwarty - podanie&lt;/h3&gt;
&lt;p&gt;Cóż - nie ma co marudzić, zabieramy się za wypełnianie podania. Wpisuję miasto, reszta moich danych jest. Wybieram kierunek na który chcę się przenieść. Do wyboru mam ciągi w stylu &lt;code&gt;P0-W08-INF---ST-I-WRO------PWR1-DWU&lt;/code&gt;. Uroczo. Szukam pomocy, znajduję &lt;em&gt;coś&lt;/em&gt; niestety i tak muszę zgadywać. Wybieram jak cytowałem, w końcu &lt;code&gt;I&lt;/code&gt; musi oznaczać pierwszy rok. Teraz pora uzupełnić dorobek. Tutaj sprawa komplikuje się jeszcze bardziej. Mam przepisać wszystkie kursy (ponad 30)? Co to są te dziwaczne pola CNPS, ZZU? I które z 15 pól na kurs mam uzupełniać? Na te pytania jednak nie znajduję odpowiedzi, więc uzupełniam wszystko według uznania. I tak przepisanie indeksu zabiera mi ponad 2h.&lt;/p&gt;
&lt;p&gt;Wypada mi jeszcze sparować kursy, jednak dla IZetu pojawiają mi się jakieś dziwactwa, których wiem, że nie mieli. Uznaję to za błąd systemu i umawiam się ze znajomym przy dziekanacie dnia następnego.&lt;/p&gt;
&lt;h3&gt;Akt piąty - podanie drugie&lt;/h3&gt;
&lt;p&gt;Jako że już blisko sesji, wystajemy godzinkę pod dziekanatem. Poraża nas jednak kultura ludzi. I tu pora na dygresję o kolejkach na Elektronice.&lt;/p&gt;
&lt;p&gt;Otóż kolejka do dziekanatu na Elektronice wygląda jak kulka plasteliny ciśnięta o ścianę. Wynika to głównie z tego, że jakiś mózg wymyślił, że do dziekanatu, gdzie jest 8 stanowisk, są jedne drzwi i do tego nieprzezroczyste. Jako że stanowiska są przydzielone do studentów na stałe, niektórzy, udając że idą do stanowiska do którego nie ma kolejki, wchodzą do środka, pomijając ogromną kolejkę stojacą pod drzwiami, po czym stają w kolejce już do określonego stanowiska. W praktyce wygląda to tak, że 10 osób stoi pod drzwiami i nie może wejść (bo są wywalani), a w środku, do interesującego ich stanowiska jest cały czas tyle samo ludzi. Nie muszę wspominać, że ja oczywiście muszę swoje sprawy załatwiać przy stanowisku do którego zawsze jest najwięcej ludzi :).&lt;/p&gt;
&lt;p&gt;Na IZecie jednak za drzwiami jest tylko jedno okienko, więc problem nie istnieje. I tak po godzinie grzecznie odstanej w kolejce wyjaśniamy naszą sprawę bardzo przemiłej pani siedzącej w środku. Ona wpisuje moje nazwisko po czym z uśmiechem na twarzy oznajmia, że wybrałem nie ten kierunek. Z listy powinienem wybrać taki z &lt;code&gt;Ii&lt;/code&gt;, a nie samym &lt;code&gt;I&lt;/code&gt;. Uh - prawie bym się przeniósł na nieistniejący kierunek. Cóż za ulga. Przy okazji dowiedzieliśmy się, że należy wpisać tylko wiodące kursy.&lt;/p&gt;
&lt;p&gt;Myśląc że wiemy już wszystko spieszymy do jakiegoś wygodnego miejsca, aby usiąść i ponownie uzupełnić podanie. Wpisałem miasto, wybrałem dobry kierunek, zacząłem uzupełniać kursy, po czym chciałem je sparować. Uh... Znowu fail - nie wiem które z którymi połączyć (mniejsza z tym dlaczego). No to do dziekanatu.&lt;/p&gt;
&lt;p&gt;Tym razem już bez kolejki wchodzimy do środka. Pani cieszy się niezmiernie że widzi nas ponownie jeszcze tego samego dnia. Patrzy na nasze podania u siebie w systemie, po czym stwierdza, że System nas pokonał i musi to zrobić za nas. No dobrze - klikamy opcję &quot;przekaż&quot; przy podaniu i zostawiamy to Pani.&lt;/p&gt;
&lt;h3&gt;Akt szósty - podanie trzecie&lt;/h3&gt;
&lt;p&gt;Po dwóch dniach patrzę na status swojej sprawy, który zmienia się z &lt;samp&gt;&quot;złożona&quot;&lt;/samp&gt; na &lt;samp&gt;&quot;odrzucona&quot;&lt;/samp&gt;. Odrzucona przez dziekana, powód &lt;samp&gt;&quot;nie uzup. sem. real.&quot;&lt;/samp&gt;. Patrzę w system na swoje kursy... Nie ma pola od którego skrót mógłby tak wyglądać. Domyślam się jednak, że dziekan oczywiście widzi inne nazwy pól u siebie. Kolega po wizycie w dziekanacie potwierdza moje przypuszczenia i już wiemy co trzeba douzupełnić. No to jeszcze raz - 1h na uzupełnienie podania. Przy okazji wychodzi, że kiedy uzupełnia się te pole, system zapomina kilka innych (z losową jednak częstotliwością). Podanie złożone, wydrukowane, zaniesione, zatwierdzone. A nie - nie tak szybko, Panie Piotrze. Okazuje się, że pismo pt. &quot;różnice programowe&quot; które musieliśmy zanieść wczęsniej do dziekana nie ma podpisu, bo to co na nim widnieje, to jakieś gryzmoły. Uroczo - 2h w kolejce i mam podpis. No to teraz czekam.&lt;/p&gt;
&lt;p&gt;Po trzech dniach sprawa zmienia status ze &lt;samp&gt;&quot;złożona&quot;&lt;/samp&gt; na &lt;samp&gt;&quot;do rozpatrzenia&quot;&lt;/samp&gt;. Już się cieszę, że coś poszło o krok dalej niż ostatnio. Kawałek niżej jednak widnieje status &lt;samp&gt;&quot;brak decyzji&quot;&lt;/samp&gt;, a jeszcze w jednym miejscu &lt;samp&gt;&quot;decyzja prawomocna: tak&quot;&lt;/samp&gt;. Eee... no jasne. U kolegi to samo. Postanawiamy jeszcze poczekać.&lt;/p&gt;
&lt;p&gt;Tutaj dygresja apropo zapisów na Elektronice, które wypadły właśnie w tym momencie. Jako że nie wiedziałem, czy całą sprawę uda mi się pozytywnie załatwić postanowiłem się zapisać na zajęcia, normalnie jakbym dalej studiował.&lt;/p&gt;
&lt;p&gt;A po tygodniu postanawiamy zajrzeć do dziekanatu w sprawie naszych podań.&lt;/p&gt;
&lt;h3&gt;Akt siódmy - indeksik&lt;/h3&gt;
&lt;p&gt;Wystajemy znowu swoje w kolecje. W środku już o nas zapomniano, więc grzecznie tłumaczymy z czym przychodzimy. Pani zagląda do podania kolegi i okazuje się, że dobrze że przyszliśmy. Podczas przerabiania podania system wygenerował błąd i podanie zostało zapomniane. A skąd status &lt;samp&gt;&quot;do rozpatrzenia&quot;&lt;/samp&gt;? Tego nie udaje nam się dowiedzieć. &quot;Klik&quot; i podanie kolegi tym razem przechodzi - super, &lt;q&gt;witamy Pana na naszym wydziale&lt;/q&gt;. Teraz pora na moje podanie. &quot;Klik&quot; - &lt;q&gt;u Pana jest błąd. Musi Pan mieć przepisane wszystkie oceny do indeksu elektronicznego&lt;/q&gt;. Że co? Kolega nie ma, a jemu przeszło, dlaczego? Trzy razy spytałem i dowiedziałem się tylko, że &lt;em&gt;ja muszę&lt;/em&gt;. Pani niestety teraz nie była tak miła, bo dorwała administratora Systemu i mu nawymyślała.&lt;/p&gt;
&lt;p&gt;Wychodzę zniesmaczony, bo do tej pory moim prowadzącym udało się do tegoż indeksu (części Systemu) przepisać aż 3 oceny. Na 20... Że niby mam ich teraz do tego zmusić? No nic - łudzę się, że może ktoś to odgórnie zrobić. Idę do swojego dziekanatu - półtorej godziny w kolejeczce i dowiaduję się, że nie, nie ma takiej osoby. Idę jeszcze do sekcji informatycznej, gdzie od znajomego słyszę to samo. SUPER! Przy okazji dowiaduję się, że prowadzący mieli już jeden termin na załatwienie sprawy, ale prawie nikt tego nie zrobił, więc przedłużono im go do 7mego marca. Ekstra - na IZecie mam czas na załatwienie wszystkiego do 10tego. I jakoś nie wierzę, żeby wszyscy tego 7mego dotrzymali. Jedna osoba mnie oleje, zniknie na tydzień i nici z przenosiń.&lt;/p&gt;
&lt;p&gt;Co więcej - abym mógł spokojnie popracować, jedyną alternatywą dla przeniesienia się jest wzięcie dziekanki. Na to termin też mam do 10tego marca. Więc jedna rzecz się przedłuży, a będę musiał normalnie studiować. Uroczo. Półtora miesiąca zabawy i nic nie załatwię.&lt;/p&gt;
&lt;p&gt;Tak na koniec dzisiejszej części jeszcze krótko o wypełnianiu podania o urlop dziekański. Oczywiście wszystko w Systemie. Do uzupełnienia &lt;code&gt;początkowy semestr urlopu&lt;/code&gt; i &lt;code&gt;końcowy semestr urlopu&lt;/code&gt;. Niby wszystko jasne, ale zaraz - jak biorę urlop na jeden semestr to co wpisuję w końcowym? Ten sam co początkowy, czy następny? Nie dowiem się niestety metodą prób i błędów, bo System zezwoli nawet na wzięcie dziekanki rok temu i co więcej - nawet na wzięcie dziekanki cofającej - gdzie start &amp;gt; koniec ;).&lt;/p&gt;
&lt;h3&gt;Akt ósmy - pewna informacja&lt;/h3&gt;
&lt;p&gt;Część trzecia już za czas z góry nieokreślony :)&lt;/p&gt;
</description><pubDate>Fri, 06 Mar 2009 14:42:45 +0100</pubDate><guid>http://blog.koszulinski.pl/2009/03/06/przenosiny-cz-2/</guid><category>Ogólne</category><category>Przenosiny</category><category>PWR</category><category>edukacja</category><category>sygnity</category><category>informatyka</category><category>studia</category><category>fail</category></item><item><title>Przenosiny</title><link>http://blog.koszulinski.pl/2009/03/06/przenosiny/</link><description>&lt;p&gt;Żyję.&lt;/p&gt;
&lt;p&gt;To zdanie &lt;del&gt;(albo raczej, jeśli dobrze pamiętam z liceum, jego równoważnik)&lt;/del&gt; jest dla mnie zdaniem przełomowym, bo nie udało mi się opublikować żadnego wpisu od października 2006. Co oznacza skromną, ponaddwuletnią przerwę i moją pozorną śmierć (nawet w mych oczach). Ale nic to - o tym (tzn. o powodach) kiedy indziej (bo pisać mam zamiar więcej), a teraz na temat.&lt;/p&gt;
&lt;h3&gt;&lt;a href=&quot;http://pl.wikipedia.org/wiki/Prolog_(literatura)&quot;&gt;Prolog&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Na wstępie wypada mi przedstawić sytuację w jakiej znajdowałem się na początku całego dramatu (ma prolog i akty, to prawie jak dramat ;P - tylko chóru brakuje ;)&lt;/p&gt;
&lt;p&gt;W roku pańskim 2007 zacząłem studia na &lt;a href=&quot;http://www.eka.pwr.wroc.pl/&quot;&gt;Wydziale Elektroniki Politechniki Wrocławskiej&lt;/a&gt;, kierunek Informatyka. W teorii wymarzone - informatyczne, próg najwyższy i... i to chyba wszystko czym się kierowałem. A szkoda.&lt;/p&gt;
&lt;p&gt;W roku pańskim 2008, w miesiącu styczniu, później lutym, później lipcu - mówiąc wprost - od prawie samego początku pierwszego roku - narzekałem. Studia informatyczne okazały się być matematyczno-elektronicznymi i o ile to pierwsze nie dziwi na pierwszym roku, a drugie też nie dużo mniej, to miałem obawy czy nie będzie tak do końca. Jednak na obawach się skończyło i zostałem na Wydziale Elektroniki.&lt;/p&gt;
&lt;p&gt;W grudniu roku 2008 zapadła jednak decyzja - chcę się przenieść. Do wyboru miałem jeszcze dwie informatyki na &lt;acronym title=&quot;Politechnika Wrocławska&quot;&gt;PWR&lt;/acronym&gt;. Jedną na &lt;acronym title=&quot;Wydziale Informatyki i Zarządzania&quot;&gt;IZecie&lt;/acronym&gt;, a drugą na &lt;acronym title=&quot;Wydziale Podstawowych Problemów Techniki&quot;&gt;PPTcie&lt;/acronym&gt;. Wybór padł na IZet.&lt;/p&gt;
&lt;p&gt;Cały obszerny wstęp dopełnia informacja o tym, że z semetru 4tego planowałem się przenieść na semestr drugi. Cała zabawa po to, abym mógł trochę więcej poświęcić się pracy przez następny rok (większość kursów zostanie mi &lt;em&gt;mam nadzieję&lt;/em&gt; przepisana).&lt;/p&gt;
&lt;h3&gt;Akt pierwszy - rozpoczynamy&lt;/h3&gt;
&lt;p&gt;Pierwszym krokiem było powiadomienie rodziców - ok - podołali :). Drugim - znajomych i tu niespodzianka - jeden z moich lepszych kumpli jeszcze z czasów gimnazjum też chce się przenieść (kierunek macierzysty: &lt;acronym title=&quot;Automatyka i Robotyka&quot;&gt;AiR&lt;/acronym&gt; na &lt;acronym title=&quot;Elektronika&quot;&gt;EKA&lt;/acronym&gt;). Informacja ta dodała mi otuchy, bo to zawsze łatwiej.&lt;/p&gt;
&lt;p&gt;Krokiem następnym była wizyta u bardzo zachwalanego przez znajomych z IZetu dziekana do spraw dydaktycznych - dr. Janusza Martana. Pierwszy raz byliśmy u niego jakoś na początku stycznia i datę tę można uznać za początek procesu &lt;em&gt;Przenosin&lt;/em&gt;. Proces rozpoczęliśmy tak wcześniej (sesja od połowy lutego), aby przed sesją wszystko załatwić - wiadomo - kilometrowe kolejki, itd. Dziekan rzeczywiście okazał się być bardzo miłym i konkretnym człowiekiem. Wszystko (a przynajmniej tak się nam zdawało) nam wytłumaczył. Plan miał wyglądać następująco:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Tworzymy i przynosimy &quot;różnice programowe&quot; - tabelkę kursów które nam się pokrywają,&lt;/li&gt;
&lt;li&gt;Czekamy na otwarcieu &lt;em&gt;elektronicznego, internetowego&lt;/em&gt; systemu EdukacjaCL,&lt;/li&gt;
&lt;li&gt;Składamy podanie o przeniesienie,&lt;/li&gt;
&lt;li&gt;Przynosimy wydrukowane podanie (sic! - jest przecież w systemie),&lt;/li&gt;
&lt;li&gt;Dziekan akceptuje, bo czemu by nie,&lt;/li&gt;
&lt;li&gt;Hurraa!! krzyczymy i idziemy się nawalić jak zwierzęta. Tfu... studenci.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Nic prostszego, prawda? :) Ja nie byłem tak optymistycznie nastawiony, a to dlatego...&lt;/p&gt;
&lt;h3&gt;Akt drugi - &lt;a href=&quot;https://rekrutacja.pwr.wroc.pl/EdukacjaWeb/&quot;&gt;System&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Od początku kiedy mówiłem znajomym o przenosinach, ci ostrzegali mnie przed Systemem. System ów zwany pieszczotliwie Edukacją jest (a w zasadzie miał być) elektronicznym dziekanatem, a także systemem rekrutacyjnym i czym tam jeszcze. Nas interesowało to pierwsze. Politechnika wdraża go z oporami od niepamiętnych czasów, a teraz - w przerwie zimowej (nigdy nie pojmę dlaczego zimowej, a nie 5x dłuższej letniej :O?!?!) postanowiła wprowadzić go metodą małych kroczków - kroczków kangura giganta. Od teraz - wszystko co chcecie załatwiać w dziekanacie drodzy studenci możecie załatwić w portalu... po czym musicie to do nas przynieść i tak. Aha - to nic że w systemie nie ma jeszcze tego podania - złożysz je za pół roku. Czasy załatwiania spraw oczywiście się skrócą, pół roku temu znajomy przeniósł się w dwa dni, a my na pewno załatwimy to szybciej.&lt;/p&gt;
&lt;p&gt;Sam System tworzony jest przez notowaną na giełdzie spółkę &lt;a href=&quot;http://www.sygnity.pl/&quot;&gt;Sygnity SA&lt;/a&gt; (gdzie pewnie pracuje setka mściwych, byłych studentów Politechniki ;)). System jest bardzo sprawny - prawie jak Windows - uważaj co robisz, bo każda źle podjęta decyzja oznacza nieodwracalne w skutkach błędy. I tak - nie cofaj się do poprzedniej strony, bo dostaniesz komunikat o błędzie. Uzupełnij każde wymagane pole w podaniu zgodnie z przeznaczeniem. Niestety to które pola są wymagane oraz to jakie jest ich przeznaczenie miej lub bardziej jasne jest... Ee... Nie wiem - tego nie wie nikt. Od pań w dziekanatach, po dziekanów oraz po dokumentację systemu, która nie istnieje (piszę to z premedytacją, bo poradnik dla samobójców który jest dostępny raczaj się nie przydaje).&lt;/p&gt;
&lt;p&gt;Itd., itd... mógłbym marudzić dalej, ale ważne jest tylko to, że wiedziałem, że muszę wypełnić wszystko co wymagane, a jak o czymś zapomnę/pomylę się/nie będę wiedział, to dowiem się o tym jak będę całe podanie (2h pracy) uzupełniać ponownie, bo nie da się podania cofnąć i douzupełnić.&lt;/p&gt;
&lt;h3&gt;Akt trzeci - czekanie&lt;/h3&gt;
&lt;p&gt;Był początek stycznia kiedy zaczęliśmy czekać na otwarcie systemu... &lt;a href=&quot;http://reinmar.jogger.pl/2009/03/06/przenosiny-cz-2/&quot; rel=&quot;next&quot;&gt;Część druga&lt;/a&gt; już jutro :)&lt;/p&gt;
</description><pubDate>Fri, 06 Mar 2009 01:14:26 +0100</pubDate><guid>http://blog.koszulinski.pl/2009/03/06/przenosiny/</guid><category>Ogólne</category><category>Przenosiny</category><category>PWR</category><category>edukacja</category><category>sygnity</category><category>informatyka</category><category>studia</category></item></channel></rss>