tag:blogger.com,1999:blog-11465802138347659012024-03-13T01:58:35.252+01:00sudlik dev.logfreelance web developer blogMarek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.comBlogger28125tag:blogger.com,1999:blog-1146580213834765901.post-51121444810594849462013-01-31T13:33:00.001+01:002014-10-26T11:40:23.691+01:00Refleksje - rzutowanie obiektu do klasyJava pozwala na tytułową operacją w bardzo prosty sposób
<br />
<pre class="brush:java">Object1.cast( Object2 );</pre>
<i>Object1</i> jest rzutowany do klasy reprezentowanej przez <i>Object2</i>. Ostatnio naszła mnie ochota na coś podobnego w PHP, żeby rzutować obiekt klasy rozszerzający <i>rodzica</i> do innej klasy rozszerzającej <i>rodzica</i>. W PHP nie ma na to prostej metody, ale można ją samemu napisać bardzo elegancko
<br />
<pre class="brush:php">// rozszerzenie klasy jest jak najbardziej na miejscu bo będziemy pracować na jej instancji
class ReflectionObjectExtended extends ReflectionObject
{
private $Obj;
public function __construct( $Object )
{
parent::__construct( $Object );
$this->Obj = $Object; // przyda też się oryginalny obiekt
}
// nowa metoda jako argumenty przyjmuje refleksję klasy do której obiekt ma być rzutowany, oraz tablicę z argumentami dla konstruktora
public function cast( ReflectionClass $ReflectionClass, array $arg = array() )
{
$New = $ReflectionClass->newInstanceArgs( $arg ); // tworzymy instancję obiektu który zostanie zwrócony
foreach( $this->getProperties() as $ReflectionProperty ) // pobieramy refleksje parametrów aktualnego obiektu
{
$ReflectionProperty->setAccessible( TRUE ); // dzięki temu mamy dostęp do chronionych i prywatnych właściwości
$name = $ReflectionProperty->getName(); // pobieramy nazwę...
$value = $ReflectionProperty->getValue( $this->Obj ); // ...i wartość aktualnego obiektu
if( $ReflectionClass->hasProperty( $name ) ) // jeśli klasa do której rzutujemy ma taką właściwość...
{
$Property = $ReflectionClass->getProperty( $name ); //...bierzemy jej refleksję...
$Property->setAccessible( TRUE ); // ...udostępniamy j.w...
$Property->setValue( $New, $value ); // ...i przypisujemy nową wartość...
}
else // ...w przeciwnym razie...
{
$New->$name = $value; // ...tworzymy właściwość
}
}
return $New;
}
}</pre>
A oto zastosowanie
<br />
<pre class="brush:php">$DOMDocument = new DOMDocument();
$ReflectionObjectExtended = new ReflectionObjectExtended( $DOMDocument );
$ReflectionObjectExtended->cast( new ReflectionClass( 'DOMElement' ), array( 'strong' ) );</pre>
Bardziej praktycznym przykładem jest przeniesienie danych z obiektu dla użytkownika niezalogowanego do obiektu dla zalogowanego podczas logowania.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-1683880278936097332013-01-29T10:47:00.000+01:002013-01-31T23:00:45.794+01:00Refleksje - uzyskanie tablicy argumentówJakiś czas temu spotkałem się w jakimś języku programowania z "agregacją" argumentów, nie pamiętam gdzie, ale wyglądało to mniej więcej tak:<br />
<br />
<pre class="brush:javascript">function test( foo, bar ... )
{
foo; // 1
bar; // [ 2, 3, 4, 5 ]
}
test( 1, 2, 3, 4, 5 );</pre>
foo jest to typowy argument - nazwany, bar to wspomniany agregujący, który przechowuje wartości w tablicy. W PHP podobna sytuacja jest rozwiązana specjalnym zestawem funkcji:
<br />
<pre class="brush:php">function test( $foo )
{
$foo; // 1
func_num_args(); // 5
func_get_args(); // array( 1, 2, 3, 4, 5 )
func_get_arg( 1 ); // 2
}
test(1,2,3,4,5);</pre>
Jak widać func_get_args() zwraca tablicę indeksowaną numerycznie, a co jeśli chciałbym mieć w kluczach nazwy argumentów? Tutaj właśnie pomoże programowanie refleksyjne
<br />
<pre class="brush:php">function test( $foo )
{
$foo; // 1
$ReflectionFunction = new ReflectionFunction( __FUNCTION__ ); // 1. tworzona jest refleksja aktualnej funkcji
$param = $ReflectionFunction->getParameters(); // 2. z refleksji funkcji pobierana jest tablica refleksji parametrów
$count = count( $param ); // 3. zapisuję liczbę parametrów
$bar = array_combine( // 8. wartości połączonej tablicy służą jako klucze dla kolejnych argumentów
array_merge( // 7. łączone są obie tablice
array_map( // 4. tablica parametrów jest mapowana
function( $ReflectionParameter )
{
return $ReflectionParameter->name; // 5. z parametru wyciągana jest tylko jej nazwa
},
$param ),
range( $count, func_num_args() - $count ) ), // 6. tworzona jest tablica z przyszłymi kluczami dla nienazwanych parametrów
func_get_args() );
$bar; // array( 'foo' => 1, 1 => 2, 2=> 3, 3 => 4, 4 => 5 )
}
test( 1, 2, 3, 4, 5 );</pre>
Jest to złożone rozwiązanie, ale jednocześnie uniwersalne (niezależne od liczby argumentów nazwanych i nienazwanych), które mi się przydało.<br />
<br />
<b>Update 2013-01-31 23:00:</b><br />
W dyskusji z bratem (który w przeciwieństwie do mnie jest na bieżąco z C++) wyszło że w C/C++ jest "agregacja" argumentów, nazywana zmienną liczbą argumentów
<br />
<pre class="brush:cpp">void fun( char *msg, ... );</pre>
Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-31224737001294414422012-11-10T11:45:00.001+01:002012-11-11T09:26:50.007+01:00Sticky Box<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdk15ISvR4sXNNDLs3hnmffs0AAAPx5W70JyyjCqEyNZl8dZ_IdrJYcLI49yxxsQIGzogHsDAMR565dwv60gfTCHkSIL6n76XgdnX8x1nFTHN2xcocFWDPlp8eSviPczCID-MJQyEtcUS0/s1600/JavaScript-logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdk15ISvR4sXNNDLs3hnmffs0AAAPx5W70JyyjCqEyNZl8dZ_IdrJYcLI49yxxsQIGzogHsDAMR565dwv60gfTCHkSIL6n76XgdnX8x1nFTHN2xcocFWDPlp8eSviPczCID-MJQyEtcUS0/s200/JavaScript-logo.png" width="200" /></a></div>
<i>Sticky box</i> podobnie jak element z <i>position : fixed </i>jest zawsze widoczny, ale w przeciwieństwie do niego nie jest zawsze w tym samym miejscu względem okna. Kiedy strona zostaje przewinięta przylepia się do krawędzi.<br />
<br />
Zdaje mi się że nawet padła propozycja uzupełnienia <i>CSS</i> o taką możliwość, ale póki co trzeba się wspomagać <i>JavaScript</i>.<br />
<a name='more'></a><br />
<br />
<br />
<br />
<br />
1. Odpowiednia struktura <i>HTML</i> dla celów demonstracji, tj: content, aside i wewnątrz jego <i>div</i> jako <i>sticky box</i>
<br />
<pre class="brush:html"><section>Treść</section>
<aside>
Sidebar
<div>
Lorem ipsum dolor sit amet...</div>
</aside></pre>
2. Żeby skrypt poprawnie działał div musi mieć względną pozycję<br />
<pre class="brush:css">div
{
background-color : #ccc;
height : 100px;
position : relative;
width : 100px;
}</pre>
3. Pozostałe style są tylko po to, żeby uwidocznić efekt
<br />
<pre class="brush:css">body
{
display : table;
}
section
{
background-color : #eee;
display : table-cell;
height : 1000px;
width : 640px;
}
aside
{
background-color : #ddd;
display : table-cell;
padding-top : 200px;
width : 320px;
}</pre>
<i>4</i>. Tworzymy referencję do elementu i pobieramy jego odległość od góry strony
<br />
<pre class="brush:js">var
div = document.getElementsByTagName( 'div' )[ 0 ],
offset = div.offsetTop;</pre>
5. Po przesunięciu paska pobierana jest odległość między górną krawędzią widoku, a początkiem strony
<br />
<pre class="brush:js">window.onscroll = function()
{
var scroll = window.scrollY;</pre>
6. Jeśli odległość okna jest równa większa niż elementu to jest ustawiany <i>inline style</i> dla <i>top
</i><br />
<pre class="brush:js">if( scroll > offset )
{
div.style.top = ( scroll - offset ) + 'px';
}</pre>
7. W przeciwnym razie porównywana jest aktualna i startowa odległość elementu, jeśli nie są równe to resetowany jest <i>top</i>. Pozwala to uniknąć niedokładności wynikających z skoków podczas przesuwania
<br />
<pre class="brush:js">else if( div.offsetTop !== offset )
{
div.style.top = 0;
}
};</pre>
Solucja działa we wszystkich popularnych przeglądarkach.<br />
<br />
Zobacz efekt na <a href="http://jsfiddle.net/sudlik/Fxt3r">jsFiddle</a>.
Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-61882065830675583052012-11-09T08:30:00.000+01:002012-11-10T11:02:30.002+01:00Checkbox Hack<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjavQa9JyMEwv23Yi50zu1idnZEDF1fNCkMAJWHQdixiUMEfAIRQAbEaak_NBPHz1aJPd8T6OLarwpfmh84D96HBqFtX5UT_FyDhmea19INofDWMIYCcPBB4kmt7LaYh-w3k3lAl4Pz6N6e/s1600/css3.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjavQa9JyMEwv23Yi50zu1idnZEDF1fNCkMAJWHQdixiUMEfAIRQAbEaak_NBPHz1aJPd8T6OLarwpfmh84D96HBqFtX5UT_FyDhmea19INofDWMIYCcPBB4kmt7LaYh-w3k3lAl4Pz6N6e/s1600/css3.jpg" /></a></div>
<a href="http://css-tricks.com/the-checkbox-hack/">Checkbox Hack</a> to technika wykorzystująca możliwości CSS3, tj. bez JavaScript, a z pomocą elementu checkbox można manipulować stylami sąsiadujących elementów.<br />
<br />
<a name='more'></a><br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
1. Tworzymy kontener<br />
<pre class="brush:html"><div>
</div>
</pre>
2. Wrzucamy do środka checkbox z etykietą
<br />
<pre class="brush:html"><div>
<input id="checkbox" type="checkbox" />
<label for="checkbox">
Checkbox
</label>
</div>
</pre>
3. Ustawiamy kontener jako relatywny
<br />
<pre class="brush:css">div
{
position : relative;
}</pre>
<br />
4. Ukrywamy checkbox
<br />
<pre class="brush:css">input
{
visibility : hidden;
}</pre>
5. Nad nim generujemy nowy element z szarym tłem
<br />
<pre class="brush:css">label:before
{
background-color : grey;
content : "";
height : 16px;
left : 0;
position : absolute;
width : 16px;
}</pre>
6. Z kolei nad nim następny<span class="css-punctuation"></span>, nie co mniejszy
<br />
<pre class="brush:css">label:after
{
content : "";
height : 12px;
left : 2px;
position : absolute;
top : 2px;
width : 12px;
}</pre>
7. Na końcu, kiedy element z tej samej gałęzi co label jest zaznaczony, to poprzedzający go pseudo-element zmienia kolor
<br />
<pre class="brush:css">:checked ~ label:after
{
background-color : black;
}</pre>
Dla poprawnego wyświetlenia w starszych przeglądarkach polecam <a href="https://code.google.com/p/ie7-js/">IE7.js</a>.<br />
<br />
Zobacz efekt na <a href="http://jsfiddle.net/sudlik/UJhCm/">jsFiddle</a>.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-78483977468688610112012-11-08T11:11:00.000+01:002012-11-12T17:14:23.845+01:00PHP i JavaScript. Część 2 - Wyjście, string i zmienne<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicKvh6frd9MrfbP4xQzPbIPWAjMErrLUxT6Neb3oLzIk2cf-LxKTUlbPVG7jT7h5cVDP3fbjL4LiYwfWsZes1oS-DHke_4f7TVducas0U-8kmX7tJVeOlsA-h0THBrhutK7QY7fPI2-G-S/s1600/phpjs.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><br /></a></div>
<br />
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicKvh6frd9MrfbP4xQzPbIPWAjMErrLUxT6Neb3oLzIk2cf-LxKTUlbPVG7jT7h5cVDP3fbjL4LiYwfWsZes1oS-DHke_4f7TVducas0U-8kmX7tJVeOlsA-h0THBrhutK7QY7fPI2-G-S/s1600/phpjs.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicKvh6frd9MrfbP4xQzPbIPWAjMErrLUxT6Neb3oLzIk2cf-LxKTUlbPVG7jT7h5cVDP3fbjL4LiYwfWsZes1oS-DHke_4f7TVducas0U-8kmX7tJVeOlsA-h0THBrhutK7QY7fPI2-G-S/s1600/phpjs.png" /></a><br />
W drugiej części <a href="http://sudlik.blogspot.com/p/tutorial-php-i-javascript.html">kursu</a> rozwinę to co poruszyłem w <a href="http://sudlik.blogspot.com/2012/09/php-i-javascript-czesc-1-hello-world.html">pierwszej części</a> z pomocą Hello World. Głównym tematem pozostaje wypisanie tesktu. Jak już wiemy jest na to kilka sposobów, ale nie poznaliśmy ich wszystkich cech w czym pomoże zapoznanie się z zmiennymi w PHP i JavaScript.<br />
<br />
<span style="background-color: white;"><b>Wpis z cyklu <a href="http://sudlik.blogspot.com/p/tutorial-php-i-javascript.html">Tutorial PHP i JavaScript</a></b></span>.<br />
<br />
<a name='more'></a><br />
<br />
<br />
<h4>
PHP</h4>
Nazwy zmiennych w PHP rozpoczynają się znakiem <i>$</i>
<br />
<pre class="brush:php">$variable;</pre>
Nie dotyczy to zmiennych obiektów
<br />
<pre class="brush:php">$Object->variable;
$this->variable;</pre>
gdzie nazwa poprzedzona jest referencją obiektu i <i>-></i>.<br />
Deklaruje się je przypisując im wartość<br />
<pre class="brush:php">$var = '';
$var2 = $var1;</pre>
Na tym polu zmienne obiektów znowu się wyróżniają, bo nie wymagają wartości, ale szczegółowiej to opiszę przy okazji omawiania <a href="http://pl.wikipedia.org/wiki/Programowanie_obiektowe">OOP</a>.<br />
Skomplikujmy <i>Hello World
</i><br />
<pre class="brush:php">$a = 'Hello';
$b = 'World';
echo '" . $a . ' ' . $b . '"';</pre>
Wygląda to trochę zagmatwanie jak na coś tak prostego, ale wykorzystanie podwójnego cudzysłowu uprości kod wizualnie choć trochę spowolni
<br />
<pre class="brush:php">$a = 'Hello';
$b = 'World';
echo "\"$a $b\"";</pre>
Żeby skrypt wykonał się poprawnie postawiłem escape, ten sam zabieg można dokonać przy <i>single-quote
</i><br />
<pre class="brush:php">$a = 'Hello';
$b = 'World';
echo '\'';</pre>
Wykorzystanie tej notacji daje dostęp także do innych <a href="http://php.net/manual/en/language.types.string.php#language.types.string.syntax.double">sekwencji specjalnych</a>. Powinno się jej jednak unikać chociażby w imię <a href="http://stackoverflow.com/a/482204">wydajności</a>, która spada kiedy silnik PHP musi dodatkowo sparsować tekst w poszukiwaniu zmiennych. Kolejną cechę można zilustrować sytuacją kiedy chcemy napisać <i>świat</i> w liczbie mnogiej
<br />
<pre class="brush:php">$a = 'Hello';
$b = 'World';
echo "$a $bs";</pre>
Wynik jest niepoprawny, bo parser szuka zmiennej <i>$bs</i>. Problem ten rozwiązują nawiasy klamrowe
<br />
<pre class="brush:php">$a = 'Hello';
$b = 'World';
echo "$a {$b}s";</pre>
Heredoc daje te same możliwości, ale z tą różnicą, że nie trzeba już <i>escape`ować</i> cudzysłowu.
<br />
<pre class="brush:php">$a = 'Hello';
$b = 'World';
echo <<<EOT
"$a $b"
EOT;</pre>
W Nowdoc z kolei realizacja naszego skryptu jest już karkołomna, bo wewnątrz ciągu nie może pojawić się zmienna.<br />
Nie wspominałem jeszcze o tablicach i kiedy indziej to zrobię, ale do jej elementów odwołuje się w ten sposób<br />
<pre class="brush:php">$array[ 0 ];</pre>
Gdzie <i>0</i> to klucz elementu. Wspominam teraz o tym, bo to samo można robić w PHP z łańcuchami znaków<br />
<pre class="brush:php">$hello = 'world';
echo $hello[ 1 ];</pre>
Zostanie wyświetlona druga litera, czyli <i>o</i>. Pamiętaj że programista zawsze liczy od 0!<br />
<br />
<h4>
JavaScript</h4>
Deklaracja zmiennej zachodzi w bardziej sformalizowany sposób i <strike>także</strike> <u>nie</u> wymaga nadania wartości<br />
<pre class="brush:js">var a = '';
var b = '';
var c; </pre>
Można to także zapisać w ten sposób<br />
<pre class="brush:js">var a = b = '';
var c; </pre>
lub mój ulubiony<br />
<pre class="brush:js">var a = '',
b = '',
c;</pre>
Jest on jednak krytykowany ze względy na to, że zgubienie przecinka <a href="http://stackoverflow.com/a/7384541">może narobić bałaganu</a>.<br />
Kwestię zmiennych obiektów teraz pominę.<br />
Double-quote zachowuje się tak samo jak single-quote, preferuję jednak ten drugi, jako lżejszy. Złożoną wersję Hello World można zrealizować zasadniczo w jeden sposób<br />
<pre class="brush:js">var a = 'hello',
b = 'world';
console.log( '"' + a + ' ' + b '"' );</pre>
Co może dziwić JavaScript nie pozwala na proste, wieloliniowe łańcuchy teksty. Kolejne linie trzeba zapisać osobno, a następnie połączyć<br />
<pre class="brush:js">console.log( 'hello world, hello world, hello world, hello world, hello world' +
'hello world, hello world, hello world, hello world, hello world, hello world' +
'hello world, hello world, hello world, hello world, hello world, hello world' );</pre>
Lecz ten sposób jest niepolecany ze względu na spadającą wydajność przy łączeniu. Można <i>escape`ować</i> nowe linie,<br />
<pre class="brush:js">console.log( 'hello world, hello world, hello world, hello world, hello world \
hello world, hello world, hello world, hello world, hello world, hello world \
hello world, hello world, hello world, hello world, hello world, hello world' );</pre>
ale <a href="http://stackoverflow.com/a/805113">są wątpliwości co do kompatybilności</a>.<br />
Póki co najwłaściwszym rozwiązaniem jest łączenie elementów tablicy<br />
<pre class="brush:js">console.log( [ 'hello world, hello world, hello world, hello world, hello world',
'hello world, hello world, hello world, hello world, hello world, hello world',
'hello world, hello world, hello world, hello world, hello world, hello world' ] );</pre>
<br />
W kolejnym wpisie na przykładzie <a href="http://pl.wikipedia.org/wiki/Foobar">klasycznego <i>foo-bar</i></a> omówię pozostałe typy danych, ich rzutowanie i może coś więcej.<br />
<br />
<b>Update 13:40</b><br />
<a href="https://plus.google.com/u/0/103378946488299749644/posts/iwHYwqzYW5U">Michał ma rację</a>: zmienne w <i>JavaScript</i> nie wymagają wartości przy deklaracji. Zamiast zawierzyć doświadczeniu nabrałem siebie pozornie dobrze skonstruowanym testem<br />
<pre class="brush:js">var y;
typeof x === typeof y; // true, undefined</pre>
W tym przypadku <i>x</i> jest oczywiście niezdefiniowany, ale <i>y</i> już tak, choć bez zdefiniowanej wartości.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-48631000323878926862012-10-09T13:03:00.001+02:002012-10-09T13:05:54.464+02:00Jest już SHA-3<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="http://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Padlock.svg/200px-Padlock.svg.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="http://upload.wikimedia.org/wikipedia/commons/thumb/5/59/Padlock.svg/200px-Padlock.svg.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://commons.wikimedia.org/wiki/File:Padlock.svg">źródło</a></td></tr>
</tbody></table>
Przez prawie tydzień miałem ograniczony dostęp do internetu i wczoraj zacząłem nadrabiać straty w kanale RSS/Atom. Jedną z ciekawszych informacji jest <a href="http://kopalniawiedzy.pl/SHA-3-funkcja-skrotu-algorytm-szyfrowanie-Keccak,16728">zakończenie konkursu na SHA-3</a> prowadzonego przez NIST. Zwycięzcąm został algorytm <a href="http://en.wikipedia.org/wiki/Sha-3">Keccak</a>, który dzięki <a href="http://en.wikipedia.org/wiki/Sponge_function">architekturze gąbki"</a>, oraz innym innowacjom ma być niepodatny na ewentualne skuteczne wektory ataków na <a href="http://pl.wikipedia.org/wiki/SHA-2">SHA-2</a>. Przy tym jest wydajniejszy o 25 do nawet 80% co w <a href="http://csrc.nist.gov/groups/ST/hash/sha-3/Round2/Aug2010/documents/presentations/Pornin_slides-sha3-tp.pdf">testach wykazał Thomas Pornin</a>.<br />
<br />
Kiedy się o tym dowiedziałem postanowiłem poszukać implementacji.<br />
<a name='more'></a><br />
Dla PHP znalazłem <a href="https://github.com/strawbrary/php-sha3">rozszerzenie</a> ze stosowną instrukcją zainstalowania przez phpize. Samą funkcje używa się typowo<br />
<pre class="brush:php">sha3( 'test', 512 );</pre>
Według specyfikacji pierwszy parametr powinien być typu string, ale podejrzewam że jak to zwykle jest w PHP może to być dowolny skalar. Drugim może być tylko: 224, 256, 384, 512. Jest ponad to trzeci - logiczny, domyślnie fałsz - czy ma być zwrócony zwykły łańczuch, czy w formie binarnej.<br />
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; text-align: right;"><tbody>
<tr><td style="text-align: center;"><a href="http://upload.wikimedia.org/wikipedia/commons/thumb/7/70/SpongeConstruction.svg/200px-SpongeConstruction.svg.png" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/70/SpongeConstruction.svg/200px-SpongeConstruction.svg.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://en.wikipedia.org/w/index.php?title=File:SpongeConstruction.svg&page=1"><i>sponge function</i></a></td></tr>
</tbody></table>
<br />
Także na GitHub`ie znajdują się <a href="https://github.com/drostie/sha3-js">implementacje 14 algorytmów-kandydatów</a> na SHA3-256 (niestety innych długości nie ma) w JavaScript, a wśród nich zwycięzca. Wywołuje się go w ten sposób:<br />
<pre class="brush:js">keccak( 'test' );</pre>
W przestrzeni globalnej jest włączony <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode"><i>strict mode</i></a>, więc kto go regularnie jeszcze nie używa może się zaskoczyć.<br />
<br />
Jeśli jednak wydajność nie jest tak istotna polecam <a href="http://pl.wikipedia.org/wiki/Blowfish"><i>Blowfish</i></a> - równie bezpieczny, ale dzięki temu że jest wolniejszy trudniej go złamać metodą bruteforce.<br />
<br />
Wracając do zestawu funkcji SHA-2, NIST zaznacza, że nadal jest bezpieczny.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-23241858900764109432012-09-25T16:33:00.000+02:002012-11-12T17:14:51.773+01:00PHP i JavaScript. Część 1 - Hello World<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicKvh6frd9MrfbP4xQzPbIPWAjMErrLUxT6Neb3oLzIk2cf-LxKTUlbPVG7jT7h5cVDP3fbjL4LiYwfWsZes1oS-DHke_4f7TVducas0U-8kmX7tJVeOlsA-h0THBrhutK7QY7fPI2-G-S/s1600/phpjs.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicKvh6frd9MrfbP4xQzPbIPWAjMErrLUxT6Neb3oLzIk2cf-LxKTUlbPVG7jT7h5cVDP3fbjL4LiYwfWsZes1oS-DHke_4f7TVducas0U-8kmX7tJVeOlsA-h0THBrhutK7QY7fPI2-G-S/s1600/phpjs.png" /></a></div>
Kontynuując wieloletnią tradycję wszelkich podręczników do nauki programowania, pierwszy stworzony program wypisze:<br />
<blockquote class="tr_bq">
<span style="font-size: small;"><i>Hello World</i></span></blockquote>
Tym samym pominę teoretyczne opisy obu języków, które <a href="http://pl.wikipedia.org/wiki/PHP">znajdziecie</a> na <a href="http://pl.wikipedia.org/wiki/JavaScript">Wikipedii</a>. <br />
<br />
<span style="background-color: white;"><b>Wpis z cyklu <a href="http://sudlik.blogspot.com/p/tutorial-php-i-javascript.html">Tutorial PHP i JavaScript</a></b></span>.<br />
<br />
<a name='more'></a><br />
<br />
<br />
<h4>
PHP</h4>
<pre class="brush:php">echo 'Hello World';</pre>
<pre class="brush:php">print 'Hello World';</pre>
<i><a href="http://php.net/manual/pl/function.echo.php">echo</a></i> i <i><a href="http://php.net/manual/en/function.print.php">print</a></i> to <a href="http://php.net/manual/en/reserved.keywords.php">konstrukcje językowe</a> i dwa zasadnicze sposoby na wyświetlenie treści. Generalnie kwestią gustu jest wybór, który używamy. <i>echo</i> w przeciwieństwie do <i>print</i> może pobierać wiele argumentów<br />
<pre class="brush:php">echo 'Hello', ' ', 'World'; </pre>
Można to jednak zrekompensować w <i>print</i> łączeniem stringów<br />
<pre class="brush:php">print 'Hello' . ' ' . 'World';</pre>
Co jest możliwe w większości miejsc gdzie można podać skalar.<br />
<br />
<i>print</i> zawsze zwraca 1<br />
<pre class="brush:php">echo print '';</pre>
<i>echo</i> nic jak wskazuje dokumentacja, ale próba wyświetlenia zwracanej wartości kończy się błędem składniowym <br />
<pre class="brush:php">print echo '';</pre>
<blockquote class="tr_bq">
<span style="font-size: small;"><i>Parse error: syntax error, unexpected T_ECHO</i></span></blockquote>
Po więcej różnic odsyłam na <a href="http://stackoverflow.com/questions/7094118/reference-comparing-phps-print-and-echo">StackOverflow</a>.<br />
<br />
Jako że preferuję <i>echo</i> dalsze przykłady będą tylko z nim.<br />
<br />
Nasz mini program można też zapisać w inny sposób<br />
<pre class="brush:php">echo( 'Hello World' );
echo "Hello World";
echo <<<EOT
Hello World
EOT;
echo <<<'EOT'
Hello World
EOT;</pre>
Nawiasy są opcjonalne i nic nie zmieniają, pozostałe wariacje to <a href="http://php.net/manual/en/language.types.string.php"><i>podwójny cudzysłów</i>, <i>Heredoc</i> i <i>Nowdoc</i></a>, ale w tym przypadku są one niewskazane, bo spada nam wydajność, a nie wykorzystujemy ich zalet. W przypadku <i>Heredoc</i> i <i>Nowdoc</i> zaraz po <i><<<</i> wstawia się identyfikator np. EOT, taki samo na końcu. Tekst musi w osobnej linii.<br />
<h4>
JavaScript</h4>
<pre class="brush:js">document.write( 'Hello World' );</pre>
<pre class="brush:js">console.log( 'Hello World' );</pre>
<i><a href="https://developer.mozilla.org/en-US/docs/DOM/document">document</a></i> i <i><a href="https://developer.mozilla.org/en-US/docs/DOM/console">console</a></i> to obiekty, <a href="https://developer.mozilla.org/en-US/docs/DOM/document.write"><i>write</i></a> i <i><a href="https://developer.mozilla.org/en-US/docs/DOM/console.log">log</a></i> to ich metody. W przypadku pierwszego kodu tekst pojawi się na stronie, w przypadku drugiego w konsoli przeglądarki.<br />
<i>console</i> ma znacznie więcej metod do wyświetlenia treści dedykowanych dla różnych sytuacji<br />
<pre class="brush:js">console.info( 'Hello World' );
console.warn( 'Hello World' );
console.error( 'Hello World' );</pre>
<i>document</i> ma jeszcze <i><a href="https://developer.mozilla.org/en-US/docs/DOM/document.writeln">writeln</a></i>, który dodatkowo stawia na końcu rozpoczęcie <a href="http://pl.wikipedia.org/wiki/End-of-line">nowej linii</a><br />
<pre class="brush:js">document.writeln( 'Hello World' );</pre>
Tak jak w przypadku <i>echo</i> i <i>print</i> można użyć podwójny cudzysłów co daje nam tylko możliwość wykorzystania wewnątrz ciągu pojedyńczego cudzysłowu<br />
<pre class="brush:js">document.write( "Hello World" );</pre>
<pre class="brush:js">console.log( "Hello World" );</pre>
<i>write</i> nie jest wieloargumentowy, ale metody <i>console</i> już tak<br />
<pre class="brush:js">console.log( 'Hello', ' ', 'World' );</pre>
We wszystkich przypadkach można jednak użyć łączenia stringów<br />
<pre class="brush:js">document.write( 'Hello' + ' ' + 'World' );</pre>
<pre class="brush:js">console.log( 'Hello' + ' ' + 'World' );</pre>
W kolejnej części skupię się na zmiennych i jeszcze trochę napiszę o stringach.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-49904699846434198932012-09-25T12:45:00.003+02:002012-09-25T12:45:51.051+02:00PHP i JavaScript - tutorial porównawczy<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicKvh6frd9MrfbP4xQzPbIPWAjMErrLUxT6Neb3oLzIk2cf-LxKTUlbPVG7jT7h5cVDP3fbjL4LiYwfWsZes1oS-DHke_4f7TVducas0U-8kmX7tJVeOlsA-h0THBrhutK7QY7fPI2-G-S/s1600/phpjs.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicKvh6frd9MrfbP4xQzPbIPWAjMErrLUxT6Neb3oLzIk2cf-LxKTUlbPVG7jT7h5cVDP3fbjL4LiYwfWsZes1oS-DHke_4f7TVducas0U-8kmX7tJVeOlsA-h0THBrhutK7QY7fPI2-G-S/s1600/phpjs.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;">Logo <a href="http://php.net/download-logos.php">PHP</a> i logo JavaScript z <a href="http://en.wikipedia.org/w/index.php?title=File:Unofficial_JavaScript_logo_2.svg&page=1">JSConf EU 2011</a></td></tr>
</tbody></table>
Od dawna planowałem mały podręcznik/tutorial dla PHP. Miał on się skupić na podstawach, eksploatowaniu mało znanych elementów, wytykaniu błędów i współpracy z innymi technologiami. Kiedy mimo niewielkich zasobów czasu uznałem, że dojrzałem do tego mini projektu, zacząłem mieć wątpliwości czy nie jest to zbyt trywialne. Potrzebowałem czegoś więcej i tak zrodził się pomysł na równoległe opisywanie dwóch języków.<br />
<a name='more'></a><br />
Ma to zasadniczo trzy zalety:<br />
<ul>
<li><b>szybciej i łatwiej</b> - znajomość PHP, lub JavaScript, lub innego języka pochodnego (ActionScript, Java, Perl, C...) znacząco ułatwia naukę</li>
<li><b>porównanie</b> - poznajesz różnice między nimi, wady i zalety</li>
<li><b>współpraca</b> - PHP to najpopularniejszy język server-side, a JavaScript client-side</li>
</ul>
To tytułem wstępu, w kolejnym wpisie pierwsza część tutoriala: Hello World :)Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-47361465507736113922012-09-19T18:34:00.001+02:002012-09-19T18:36:16.378+02:00Pseudolosowe wartości w PHP<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3oidJpWz81fAtmukO_AUlQ2mxzcb6VJKj7WckIMd1gl9f7y5-aXnf1DzwcTACW1lQDKhJbcgjwwp9CJvIxESb-6OJpk26SDJA07c7EU6FjRFUbqRQYKt8vsKEUz0XkCQxZkmkTI3Uq1g3/s1600/Dice.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3oidJpWz81fAtmukO_AUlQ2mxzcb6VJKj7WckIMd1gl9f7y5-aXnf1DzwcTACW1lQDKhJbcgjwwp9CJvIxESb-6OJpk26SDJA07c7EU6FjRFUbqRQYKt8vsKEUz0XkCQxZkmkTI3Uq1g3/s1600/Dice.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://commons.wikimedia.org/wiki/File:Dice.jpg">Gaz, en.wikipedia</a></td></tr>
</tbody></table>
<div style="text-align: left;">
</div>
Prosta sprawa, ale w gdy się poszuka <i><a href="https://www.google.pl/search?q=php+random+string">php random string</a></i> to <a href="http://stackoverflow.com/questions/4356289/php-random-string-generator">można</a> <a href="http://snipplr.com/view/1027/generate-random-string/">znaleźć</a> <a href="http://www.lost-in-code.com/programming/php-code/php-random-string-with-numbers-and-letters/">straszne</a> <a href="http://www.phpf1.com/tutorial/generate-random-string.html">głupoty</a>. No, ale zwykle są artykuły starszej daty. W PHP jest wiele gotowych rozwiązań (<i><a href="http://www.php.net/manual/en/function.rand.php">rand</a></i>, <i><a href="http://www.php.net/manual/en/function.rand.php">mt_rand</a></i>, <i><a href="http://php.net/manual/en/function.uniqid.php">uniqid</a></i>, <i><a href="http://php.net/manual/en/function.array-rand.php">array_rand</a></i>, <i><a href="http://www.php.net/manual/en/function.openssl-random-pseudo-bytes.php">openssl_random_pseudo_bytes</a></i>), ale często źle używanych.<br />
<a name='more'></a><br />
<br />
<h4>
Działania matematyczne</h4>
Są dwa dedykowane rozwiązania generujące integer w danym zasięgu: <span style="color: #666666;"><i>rand</i></span> i <i><span style="color: #666666;">mt_rand</span></i>. Zdecydowanie należy wybierać ten drugi - jest szybszy i o większym zasięgu.<br />
<blockquote class="tr_bq">
<span style="font-family: "Courier New",Courier,monospace;"><span style="font-size: x-small;"><span style="color: #666666;">mt_rand( int $min, int $max ) </span></span></span></blockquote>
<h4>
Unikalny identyfikator</h4>
W kwestii ID pomocny jest <span style="color: #666666;"><i>uniqid</i></span>, ma on dwa parametry: mało przydatny prefix i powiększenie entropii.<br />
<br />
<blockquote class="tr_bq">
<span style="color: #666666;"><span style="font-size: x-small;">uniqid( string $prefix, bool $entropy ) </span></span></blockquote>
<h4>
Tablice</h4>
W przypadku potrzeby wylosowania wartości z tablicy jest <span style="color: #666666;"><i>array_rand</i></span>. Wystarczy podać tablicę i opcjonalnie ilość elementów do zwrócenia.<br />
<blockquote class="tr_bq">
<span style="color: #666666;"><span style="font-size: x-small;">array_rand( array $input, int $number = 1 ) </span></span></blockquote>
<h4>
Bezpieczeństwo</h4>
Najważniejszą wspomnianą funkcją jest <span style="color: #666666;"><i>openssl_random_pseudo_bytes</i></span>. Jest przeznaczony stricte do zadań takich jak generowanie soli dla hasła. Jako że zwraca dane binarne wraz z nim warto użyć bin2hex.<br />
<blockquote class="tr_bq">
<span style="color: #666666;"><span style="font-size: x-small;">bin2hex( openssl_random_pseudo_bytes() )</span></span></blockquote>
Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-91944775026698874442012-06-07T17:48:00.000+02:002012-06-07T17:57:33.218+02:00Przerwanie zapytań AJAX<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZjGUNxLA1aEmaxZxWZjp7B_7Eso8ys7qMfTXQxSV4Gcdbr_zodkQCTL9SyeZpbUyKu4lfu2sh9k9rgdky9ZjU6KqFnVnlbTOs_iAr8r2xVNjNc5295LBTiKvzLz7rB0EEHplaxsHbkIh_/s1600/ajax.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZjGUNxLA1aEmaxZxWZjp7B_7Eso8ys7qMfTXQxSV4Gcdbr_zodkQCTL9SyeZpbUyKu4lfu2sh9k9rgdky9ZjU6KqFnVnlbTOs_iAr8r2xVNjNc5295LBTiKvzLz7rB0EEHplaxsHbkIh_/s1600/ajax.jpg" /></a></div>
Aktualnie pracuję przy <a href="https://kantoronline.pl/">projekcie KantorOnline.pl</a>, jednym z najważniejszych elementów serwisu jest tabela notowań kursów walut. Dane do niej są aktualizowane ze sporą częstotliwością, a zapytania temu towarzyszące nie zawsze wykonywane dostatecznie szybko, powoduje to pewien interesujący problem: podczas próby przejścia pod inny adres, przeglądarka stara się najpierw uporać ze wszystkimi niedokończonymi zapytaniami, mam tutaj na myśli głównie AJAX. Solucja na szczęście nie jest zbyt wymagająca.<br />
<br />
<a name='more'></a><br />
Na początek należy zadeklarować dwie zmienne, w <i>request</i> -domyślnie pustej tablicy- będą przechowywane referencje do obiektów <i>XHR</i>, a w <i>flag</i> -domyślnie o wartości <i>true</i>- wskazówka czy kolejne zapytania maja być wykonywane.<br />
<blockquote class="tr_bq">
<div style="text-align: right;">
</div>
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">var</span></span><span style="font-size: x-small;"><br style="font-family: "Courier New",Courier,monospace;" /></span><span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> request = [],</span></span><span style="font-size: x-small;"><br style="font-family: "Courier New",Courier,monospace;" /></span><span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> flag = true;</span></span><span style="font-size: x-small;"><br /></span></blockquote>
Zapytania będą wykonywane jeśli flaga będzie miała wartość <i>true</i>, a ich obiekty dodawane do do tablicy. Po wykonaniu zapytania obiekt zostanie usunięty z <i>request</i>.<br />
<blockquote class="tr_bq">
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">if( flag === true )</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> {</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> var id = Math.random().toString( 36 );</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> request[ id ] = new XMLHttpRequest(); </span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> request[ id ].open( 'GET', 'test.txt', true ); </span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> request[ id ].onload = function()</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> {</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> delete request[ id ];</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> }; </span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> request[ id ].send( null );</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> }</span></span></blockquote>
Jeśli użytkownik będzie chciał zmienić adres, przez zamknięciem strony <i>flag </i>zostanie ustawione na <i>false</i>, a we wszystkich nieusuniętych obiektach (niezakończonych zapytanich) zostanie wykonana metoda <i>abort</i>, kończące je.<br />
<blockquote class="tr_bq">
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;">window.onbeforeunload = function( e )</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> {</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> flag = false;</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> for( var id in request )</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> {</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> if( request.hasOwnProperty( id ) )</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> {</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> request[ id ].abort();</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> }</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> }</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> </span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> };</span></span></blockquote>
Przygotowałem <a href="https://docs.google.com/open?id=0B6m9ITElED6vbTk4WWNVS2p1NVU">test do pobrania</a>, musicie jednak jeszcze stworzyć i wypełnić plik <i>test.txt</i> zawartością, dostatecznie dużą aby zapytanie nie kończyło się zbyt szybko.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-91750540115323427822012-06-07T13:35:00.003+02:002012-06-07T17:55:12.330+02:00Apache: Najważniejsze możliwości .htaccess<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdJBzvtQIgyw1MvJDo9EMdHE2MFBxL5XDEzE4jMqihBARKqH-FmNQpGuL2mtnaUx1QmTUf-c3T1jB5J2HdWma8oJTAf6pLJoZ0fTPgj-E8tmBL43iNr7GnIPwYtLL0HcJ_7jjYbS5Y-nKR/s1600/httpd_logo_wide_new.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdJBzvtQIgyw1MvJDo9EMdHE2MFBxL5XDEzE4jMqihBARKqH-FmNQpGuL2mtnaUx1QmTUf-c3T1jB5J2HdWma8oJTAf6pLJoZ0fTPgj-E8tmBL43iNr7GnIPwYtLL0HcJ_7jjYbS5Y-nKR/s1600/httpd_logo_wide_new.png" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://httpd.apache.org/">Apache HTTP Server</a></td></tr>
</tbody></table>
Szukając na Google <a href="http://www.blogger.com/htaccess%20https://www.google.pl/search?q=tutorial+apache+htaccess">tutoriali do htaccess</a> zwykle natkniemy się na kopie (!) miernych treści, gdzie wśród kilkunastu proponowanych zastosowań giną te najważniejsze, albo nawet nie są wspomniane.<br />
<br />
Zamiast wałkować uzupełnianie listy typów <i>MIME</i> (które zwykle są kompletne) czy strony błędów (które zwykle można obsłużyć lepiej), warto się zająć czymś ważniejszym, jak pamięć podręczna i kompresja.<br />
<br />
<a name='more'></a><br />
<h2 style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">
Cache - mod_expires</h2>
Moduł <a href="http://httpd.apache.org/docs/current/mod/mod_expires.html">expires</a> pozwala na manipulowanie pamięcią podręczną przeglądarki, poprzez modyfikowanie nagłówka <i>Cache-Control</i>. Poniższa konfiguracja sprawdza czy na serwerze zainstalowany jest interesująca nas funkcjonalność, jeśli tak to aktywuje go, a następnie określa wg <i>MIME</i> żywotność plików.<br />
<blockquote class="tr_bq">
<span style="color: #666666; font-family: "Courier New",Courier,monospace; font-size: x-small;"><IfModule mod_expires.c></span><br />
<span style="color: #666666; font-family: "Courier New",Courier,monospace; font-size: x-small;"> ExpiresActive on</span><br />
<span style="color: #666666; font-family: "Courier New",Courier,monospace; font-size: x-small;"> ExpiresByType image/gif "access plus 1 month"</span><br />
<span style="color: #666666; font-family: "Courier New",Courier,monospace; font-size: x-small;"> ExpiresByType image/png "access plus 1 month"</span><br />
<span style="color: #666666; font-family: "Courier New",Courier,monospace; font-size: x-small;"> ExpiresByType image/jpg "access plus 1 month"</span><br />
<span style="color: #666666; font-family: "Courier New",Courier,monospace; font-size: x-small;"> ExpiresByType image/jpeg "access plus 1 month"</span><br />
<span style="color: #666666; font-family: "Courier New",Courier,monospace; font-size: x-small;"></IfModule></span></blockquote>
<h2 style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">
IE - mod_headers</h2>
<a href="http://httpd.apache.org/docs/current/mod/mod_headers.html">Headers</a> to ogólne narzędzie do manipulacji nagłówkami zapytań.<br />
Interesującą propozycją, choć nastręczająca pewne problemy, jest dodanie <a href="http://msdn.microsoft.com/en-us/library/cc288325%28v=vs.85%29.aspx">X-UA-Compatible</a> do zapytania, zamiast dokumenty<br />
<br />
Tak to wygląda w <i>HTML</i>:<br />
<blockquote class="tr_bq">
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><meta name="X-UA-Compatible" content="IE=Edge;chrome=1" /></span></span></blockquote>
Zamiast tego można użyć poniższą konfigurację wg wzorca <i>białej listy,</i> lub <i>czarnej listy</i>.<br />
<blockquote class="tr_bq">
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><IfModule mod_headers.c></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> # Biała lista...</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <FilesMatch "\.(html|php)$" ></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> Header set X-UA-Compatible "IE=Edge;chrome=1"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </FilesMatch></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> # ...lub czarna lista</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> Header set X-UA-Compatible "IE=Edge;chrome=1"</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> <FilesMatch "\.(js|css|gif|png|jpe?g|pdf|xml|oga|ogg|m4a|ogv|mp4|m4v|webm|svg|svgz|eot|ttf|otf|woff|ico|webp|htc)$" ></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> Header unset X-UA-Compatible</span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"> </FilesMatch></span><br style="font-family: "Courier New",Courier,monospace;" /><span style="font-family: "Courier New",Courier,monospace;"></IfModule> </span></span></blockquote>
<span style="color: #666666; font-size: x-small;"></span><br />
<h2>
<span style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">Kompresja - mod_deflate</span></h2>
Bardzo ważnym modułem jest <a href="http://httpd.apache.org/docs/current/mod/mod_deflate.html">mod_deflate</a>, który w locie kompresuje pliki.<br />
Po sprawdzeniu czy istnieje moduł istnieje ustawiamy filtr dla odpowiedzi, a następnie stosujemy go wg <i>MIME</i>. Zaznaczę że nie warto tego stosować np. przy plikach multimedialnych, które zwykle już są skompresowane.<br />
<blockquote class="tr_bq">
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"><IfModule mod_deflate.c></span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> SetOutputFilter DEFLATE</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"> AddOutputFilterByType DEFLATE text/html text/css application/javascript</span></span><br />
<span style="color: #666666; font-size: x-small;"><span style="font-family: "Courier New",Courier,monospace;"></IfModule></span></span></blockquote>
<h2 style="font-family: "Helvetica Neue",Arial,Helvetica,sans-serif;">
Ładne linki - mod_rewrite</h2>
Ten temat jest akurat bardzo często poruszany, albo może znajdzie się tutaj coś więcej. <a href="http://httpd.apache.org/docs/current/mod/mod_rewrite.html">Moduł rewrite</a> służy do przepisywania/przekierowywania adresów.<br />
Aktualnie popularną sztuczką jest przekierowanie wszystkich zapytań do jednego pliku, daje to możliwość stosowania atrakcyjniejszych adresów.<br />
Przykład zaczerpnąłem z <a href="http://kohanaframework.org/">Kohana Framework</a>. Moduł jest uruchamiany, następnie zostaje ustawiony katalog bazowy. Pierwsze RewriteRule blokuje dostęp do wybranych katalogów - adres kierujący do jednego z nich nie jest przetwarzany przez kolejne warunki, a serwer zwraca błąd braku dostępu.<br />
Kolejne linie to ustalenie, że jeśli plik (<i>-f</i>), lub folder (<i>-d</i>) istnieje to adres nie jest przepisywany, czyli jest do nich swobodny dostęp, a adres nie będzie przepisany.<br />
Ostatnia linia bloku to skierowanie wszystkich zapytań do pliku <i>index.php</i>. <br />
<blockquote class="tr_bq">
<span style="font-family: "Courier New",Courier,monospace; font-size: x-small;"><span style="color: #666666;"><IfModule mod_rewrite.c></span></span><br />
<span style="font-family: "Courier New",Courier,monospace; font-size: x-small;"><span style="color: #666666;"> RewriteEngine On</span></span><br />
<span style="font-family: "Courier New",Courier,monospace; font-size: x-small;"><span style="color: #666666;"> RewriteBase /</span></span><br />
<span style="font-family: "Courier New",Courier,monospace; font-size: x-small;"><span style="color: #666666;"> RewriteRule ^(?:admin|quest|modules|system)\b.* index.php/$0 [L]</span></span><br />
<span style="font-family: "Courier New",Courier,monospace; font-size: x-small;"><span style="color: #666666;"> RewriteCond %{REQUEST_FILENAME} !-f</span></span><br />
<span style="font-family: "Courier New",Courier,monospace; font-size: x-small;"><span style="color: #666666;"> RewriteCond %{REQUEST_FILENAME} !-d</span></span><br />
<span style="font-family: "Courier New",Courier,monospace; font-size: x-small;"><span style="color: #666666;"> RewriteRule .* index.php/$0 [PT]</span></span><br />
<span style="font-family: "Courier New",Courier,monospace; font-size: x-small;"><span style="color: #666666;"></IfModule></span></span></blockquote>
Na większości serwerach wszystkie wyżej wymienione możliwości są dostępne, ale nie zaszkodzi być przygotowanym na brak modułów. Wszystkie omówione konfiguracje wrzuciłem do <a href="https://docs.google.com/open?id=0B6m9ITElED6vdm80NkQ4ekd5LVU">jednego pliku</a>. Więcej informacji w temacie .htaccess warto szukać w <a href="http://httpd.apache.org/docs/current/">dokumentacji Apache HTTP Server</a> i <a href="http://stackoverflow.com/search?q=apache+htaccess">na Stack Overflow</a>.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-21171032504516543852012-02-14T23:56:00.000+01:002012-02-14T23:56:22.402+01:00Aktualizacja Yajs: php.js i Spinner<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEsgD3Ga1_gcPRNFxccyoiJgjNtZ3DK2Pq3UlubmQXZQTnAtJNeHhvxL5qYqUiqRr1t3aCiqhuCuSjRmviy1gWEOxmzRXDPj6EAjwBI3YXBxh9HfnO_01pJkI6dk9NF0RspIj-GZtt9Bkp/s1600/php.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEsgD3Ga1_gcPRNFxccyoiJgjNtZ3DK2Pq3UlubmQXZQTnAtJNeHhvxL5qYqUiqRr1t3aCiqhuCuSjRmviy1gWEOxmzRXDPj6EAjwBI3YXBxh9HfnO_01pJkI6dk9NF0RspIj-GZtt9Bkp/s1600/php.png" /></a></div>
Wiele jest powodów do krytyki PHP jak np. nazewnictwo predefiniowanych funkcji, ale same ich istnienie jest jedną z największych zalet <a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html">6 języka na świecie</a>. Dzięki nim osoby dla których nauka PHP jest pierwszym kontaktem z programowaniem, nie zniechęcają się tak łatwo. <a href="http://phpjs.org/">Projekt php.js</a> ma za cel przeniesienie jak największej ilości funkcji z PHP do JavaScript, tak jak to niegdyś zrobił PHP z funkcjami C. Aktualna lista choć jest <a href="http://phpjs.org/unported/index">pełna braków</a> to i tak <a href="http://phpjs.org/">imponuje</a>.<br />
<br />
<a name='more'></a><br />
Wśród aktualnie zaimplementowanych funkcji znajdziemy <a href="http://phpjs.org/functions/array_merge_recursive:327">array_merge_recursive</a>, <a href="http://phpjs.org/functions/get_defined_functions:413">get_defined_functions</a>, czy <a href="http://phpjs.org/functions/md5:469">md5</a>, którymi możemy się cieszyć po <a href="http://phpjs.org/packages/view/308">pobraniu biblioteki</a> i dodaniu do nagłówka strony<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;"><script src="php.default.min.js"></script></span></blockquote>
Zaznaczę, że na stronie <a href="http://phpjs.org/">phpjs.org</a> znajdują się różne <a href="http://phpjs.org/packages/index">gotowe paczki funkcji</a>, a także <a href="http://phpjs.org/packages/configure">narzędzie do przygotowania</a> własnej.<br />
<br />
Funkcje od teraz można przetestować także w <a href="http://yajs.sudlik.pl/">Yajs</a>. Przy okazji dodania tej w/w biblioteki do aplikacji zrobiłem kilka zmian, prześledźmy je.<br />
<br />
<span style="font-size: large;">Przestrzeń nazw i konwencje nazewnictwa</span><br />
<br />
Żeby lepiej zorganizować kod zrobiłem dwie rzeczy: wprowadziłem swoją przestrzeń nazw <i>Yats</i> w formie obiektu do którego przypisuję kolejne zmienne i funkcje, oraz rozszerzyłem konwencję nazewnictwa o quasi stałe (duże litery), oraz pusty jQuery.<br />
<br />
<script src="https://gist.github.com/1820541.js?file=app_0.js">
</script>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjtqvgFT7ueQx2FCb27kimsuyUFXs74xKGXM1pcMaCQsuSmoum_9bCTy5dDS6TsSfCpD1fdKN26x9tAM82HeMUDmy2AU5JjeRRO79cD1ZDceAQsC0c_fUIlfshIdHfaCP6cwVFfu-yQDgh/s1600/jQuery_logo_color_ondark.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" height="73" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjtqvgFT7ueQx2FCb27kimsuyUFXs74xKGXM1pcMaCQsuSmoum_9bCTy5dDS6TsSfCpD1fdKN26x9tAM82HeMUDmy2AU5JjeRRO79cD1ZDceAQsC0c_fUIlfshIdHfaCP6cwVFfu-yQDgh/s200/jQuery_logo_color_ondark.png" width="200" /></a><span style="font-size: large;">Kolejka zdarzeń</span><br />
<br />
<span style="font-size: small;">Wspomniany pusty obiekt wykorzystuję przy kolejce zdarzeń z jQuery: .queue() i .dequeue(). Dzięki niej nie muszę dodawać do moich funkcji callback.</span><br />
<br />
<script src="https://gist.github.com/1820541.js?file=app_3.js">
</script>
<br />
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKb55ASP61eMIMxWqOP9UsoSoX3TjObPHqCmkyj1jjzUcqPN1mZWYp8YaXxT5G2jaYZGwJnaGwoLZKpE0msB0opfGw0sxlfpt2_2y4zV70SKJNXei72vZkFhNqpzMyuUfeUZCAjlvBB4bG/s1600/fgnass.github.com+-+2012-02-13+-+22h-34m-08s.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="85" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKb55ASP61eMIMxWqOP9UsoSoX3TjObPHqCmkyj1jjzUcqPN1mZWYp8YaXxT5G2jaYZGwJnaGwoLZKpE0msB0opfGw0sxlfpt2_2y4zV70SKJNXei72vZkFhNqpzMyuUfeUZCAjlvBB4bG/s200/fgnass.github.com+-+2012-02-13+-+22h-34m-08s.png" width="200" /></a><span style="font-size: large;">Spinner</span><br />
<br />
Do zasygnalizowania pracy skryptu użyłem<a href="http://fgnass.github.com/spin.js/"> Spinner/spin.js</a>, który służy tylko do tworzenia <i>progress bar</i>, ale z wieloma opcjami.<br />
<br />
<script src="https://gist.github.com/1820541.js?file=app_6.js">
</script><br />
<span style="font-size: large;">Obsługa błędów</span><br />
<br />
Obsługa błędów to obowiązek przy poważnej aplikacji, a poza tym chciałem, żeby obsługiwała je konsola.<br />
<br />
<script src="https://gist.github.com/1820541.js?file=app_3.js">
</script>
<br />
<span style="font-size: large;">Ładowanie bibliotek</span><br />
<br />
W elemencie odpowiadającym za ładowanie bibliotek, ciekawy chyba tylko jest element odpowiadająca za wprost przeciwną funkcję, <i>wyładowywanie funkcji</i>. Problem tkwi w tym, że <b>raz załadowany skrypt</b> (w tym przypadku z pomocą <i>getScript</i>) <b>nie może zostać od tak wyłączony ze skryptu</b>. Żeby uzyskać taki efekt trzeba usunąć wszystkie funkcje i zmienne.<br />
<br />
<script src="https://gist.github.com/1820541.js?file=app_4.js">
</script>
<br />
<span style="font-size: large;">Time i String pad</span><br />
<br />
Tak rozległa definicja czasu to nie błąd. Teoretycznie mógłbym użyć <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString">toLocaleTimeString</a>, ale tak jak sama nazwa mówi nie uzyskałbym u wszytkich użytkowników jednolitego efektu. Poza tym brak w tej metodzie milisekund. Naprawiając niedociągnięcia użytych metod to wyświetlenia godzin etc. zdefiniowałem funkcję zbliżoną do PHP-owego <a href="http://php.net/manual/en/function.str-pad.php">str_pad</a>.<br />
<br />
<script src="https://gist.github.com/1820541.js?file=app_1.js">
</script>
<br />
<script src="https://gist.github.com/1820541.js?file=app_5.js">
</script>Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-3283249132129118102012-02-07T00:19:00.001+01:002012-02-07T00:19:13.546+01:00Yajs - mała pomoc jQuery<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkNAAwhq4DGsbZ6NaedoNueE_NXvoXxag0PyiMNAsCVFNt7uQAxlbtlXUknHdBAXk-EZi8BeKR4yOiocsZFzTbscbUalRTcSJFKi7tZRruGDlAxFB5DJ1FcPH7NOi4Lru6xfMKSLQt5ybf/s1600/jquery.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhkNAAwhq4DGsbZ6NaedoNueE_NXvoXxag0PyiMNAsCVFNt7uQAxlbtlXUknHdBAXk-EZi8BeKR4yOiocsZFzTbscbUalRTcSJFKi7tZRruGDlAxFB5DJ1FcPH7NOi4Lru6xfMKSLQt5ybf/s1600/jquery.png" /></a></div>
<a href="http://yajs.sudlik.pl/">Yajs</a> to prosty edytor kodu JavaScript online, który służy mi jako poligon testowy. <a href="http://sudlik.blogspot.com/2012/02/yajs-start-z-foundation.html#more">Projekt wystartował wczoraj</a>, ale wersja inicjacyjna wnosiła tylko podstawowy widok z użyciem <a href="http://foundation.zurb.com/">Foundation</a>.<br />
<br />
Pierwsza aktualizacja to:<br />
<ul>
<li>uruchomienie podstawowych funkcji z niewielką pomocą <i>jQuery</i></li>
<li>niewielkie zmiany w HTML i CSS</li>
</ul>
<br />
<a name='more'></a><br />
<ul>
</ul>
Aktualnie obsługa <i>Yajs</i> sprowadza się do wprowadzenia JavaScript do panelu <i>Edytor</i> i wciśnięcia przycisku <i>Uruchom</i>. Wynik będzie zaprezentowany w panelu <i>Konsola</i>.<br />
<br />
Serce aplikacji to około 30 wierszy w <i>app.js</i> wewnątrz obiektu <i>jQuery</i><br />
<blockquote class="tr_bq">
<div style="color: #666666;">
<span style="font-size: x-small;">$( function()</span></div>
<div style="color: #666666;">
<span style="font-size: x-small;"> {</span></div>
<span style="color: #666666; font-size: x-small;"> } );</span></blockquote>
który tak naprawdę jest skrótem dla<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">$( document ).ready( function()</span><br />
<span style="font-size: x-small;"> {</span><br />
<span style="font-size: x-small;"> } );</span></blockquote>
czyli funkcji wydarzenia <i>ready</i> dodanego do obiektu <i>jQuery</i> stworzonego z obiektu <i>document</i>.<br />
<br />
W pierwszej części funkcji znajduje się deklaracja wszystkich moich zmiennych.<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">var</span><br />
<span style="font-size: x-small;"> $editor = $( '#editor textarea' ),</span><br />
<span style="font-size: x-small;"> $console = $( '#console div' ),</span><br />
<span style="font-size: x-small;"> $run = $( '#run' ),</span><br />
<span style="font-size: x-small;"> msgs = [],</span><br />
<span style="font-size: x-small;"> code,</span><br />
<span style="font-size: x-small;"> result,</span><br />
<span style="font-size: x-small;"> run = function( e )</span><br />
<span style="font-size: x-small;"> {</span><br />
<span style="font-size: x-small;"> </span><br />
<span style="font-size: x-small;"> e.preventDefault();</span><br />
<span style="font-size: x-small;"> code = $editor.val();</span><br />
<span style="font-size: x-small;"> msgs.push( 'code: ' + code );</span><br />
<span style="font-size: x-small;"> try</span><br />
<span style="font-size: x-small;"> {</span><br />
<span style="font-size: x-small;"> msgs.push( 'success: ' + eval( code ) );</span><br />
<span style="font-size: x-small;"> }</span><br />
<span style="font-size: x-small;"> catch( e )</span><br />
<span style="font-size: x-small;"> {</span><br />
<span style="font-size: x-small;"> msgs.push( 'error: ' + e );</span><br />
<span style="font-size: x-small;"> }</span><br />
<span style="font-size: x-small;"> $console.html( msgs.join( '<br />' ) );</span><br />
<span style="font-size: x-small;"> </span><br />
<span style="font-size: x-small;"> };</span></blockquote>
<div style="color: #666666;">
</div>
Taka praktyka pozwoli nam zachować porządek, oraz uchronić kod przed wielokrotnym powtarzaniem tej samej funkcji z tym samym argumentem, mam tu głównie na myśli tworzenie obiektów<i> jQuery</i><br /> <br />
<blockquote class="tr_bq">
<span style="color: #666666; font-size: x-small;">$editor = $( '#editor textarea' ),</span><br /><span style="color: #666666; font-size: x-small;"> $console = $( '#console div' ),</span><br /><span style="color: #666666; font-size: x-small;"> $run = $( '#run' ),</span></blockquote>
Są one ponad to oznaczone znakiem dolara dla wyróżnienia w skrypcie.<br />
<br />
Ostatnia zmienna to deklaracja funkcji wykonywanej po uruchomieniu kodu z <i>Edytora</i>.<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">$run.on( 'click', run );</span></blockquote>
<a href="http://api.jquery.com/on/">On</a> to nowa metoda obiektu <i>jQuery</i> wprowadzona wraz z wersją 1.7. Działa podobnie do starszych: <i>live</i>, <i>delegate</i>, czy <i>bind</i>. Pierwszy argument to nazwa wydarzenia (<i>event</i>), drugi to wykonywana funkcja.<br />
<br />Parametr <i>e</i> wewnątrz funkcji <i>run</i> to obiekt wydarzenia, gdyby nie zapis<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">e.preventDefault();</span></blockquote>
po wciśnięciu przycisku wykonywała by się domyślna akcja, czyli przeładowanie strony. Kolejne linie to pobranie kodu użytkownika, oraz dodanie go do tablicy komunikatów<br />
<blockquote class="tr_bq">
<div style="color: #666666;">
<span style="font-size: x-small;">code = $editor.val();</span></div>
<div style="color: #666666;">
<span style="font-size: x-small;">msgs.push( 'code: ' + code );</span></div>
</blockquote>
Blok <i>try/catch</i> służy na wykonaniu odpowiedniej reakcji zgodnie z tym czy kod został poprawnie wykonany.<br />
<blockquote class="tr_bq">
<div style="color: #666666;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGTS_YoRfqkqsev6LFIO9Hfx0Aeq_SydUS_xzWu_ovpNAs4f07ANGaan-uKG4Dl8ROe_EVJyv3RBKeDPDWmvK-52W6LIZXgHram154KvBtAbWQWfRN5mewDv_pRCS9OwxoOSh7YprZFay_/s1600/yajs.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGTS_YoRfqkqsev6LFIO9Hfx0Aeq_SydUS_xzWu_ovpNAs4f07ANGaan-uKG4Dl8ROe_EVJyv3RBKeDPDWmvK-52W6LIZXgHram154KvBtAbWQWfRN5mewDv_pRCS9OwxoOSh7YprZFay_/s1600/yajs.png" /></a><span style="font-size: x-small;">try<br /> {<br /> msgs.push( 'success: ' + eval( code ) );<br /> }</span></div>
<div style="color: #666666;">
<span style="font-size: x-small;">catch( e )<br /> {<br /> msgs.push( 'error: ' + e );<br /> }</span></div>
</blockquote>
Ostatnia linia to wyświetlenie zgromadzonych komunikatów<br />
<blockquote class="tr_bq">
<div style="color: #666666;">
<span style="font-size: x-small;">$console.html( msgs.join( '<br />' ) );</span></div>
</blockquote>
Takim o to sposobem mamy prosty edytor <i>JavaScript</i>.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-90596715905495030292012-02-05T17:16:00.000+01:002012-02-05T17:17:28.016+01:00Yajs - start z Foundation<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvi187sEwsoGhBH5P2Txf-kq667s4djiBtyZ6pwwCRAFGtRLvJcuwYxpWwN2JPLj5s8BLJMuFajI-tel9sx2RLSHCEqvbeCS5HKrqF4ppaEn6_WITyjg7cYbZAklvlKLfmdkSDtdPPfFE7/s1600/found.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="103" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvi187sEwsoGhBH5P2Txf-kq667s4djiBtyZ6pwwCRAFGtRLvJcuwYxpWwN2JPLj5s8BLJMuFajI-tel9sx2RLSHCEqvbeCS5HKrqF4ppaEn6_WITyjg7cYbZAklvlKLfmdkSDtdPPfFE7/s320/found.png" width="320" /></a></div>
<a href="http://foundation.zurb.com/">Foundation</a> to jeden z najpopularniejszych webapp bootstrap`ów. Zgrabne połączenie HTML, CSS i JavaScript, którego możliwości postanowiłem zaprezentować w praktyce na mojej nowej aplikacji.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<a href="http://yajs.sudlik.pl/">Yajs - prosty edytor JavaScript</a>, od teraz aż do znudzenia staje się on moim poligonem doświadczalnym. Aktualnie nic nie potrafi z tego co powinien... poza wyglądaniem i to właśnie dzięki wspomnianemu bootstrapowi. Nie jest to szokujący layout, ale został stworzony bez większego wysiłku z mojej strony.<br />
<br />
<a name='more'></a><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimj6qPFiiZKZtnfRTN9cyPivLgnQQZzaaQwDLZXzIUkAFP0K6rRykcLWZSy_OnjT83JfessP56qrTC16XbMagdxW2si_J7nKciejL9S8bUPe8_C-PVBTchFUuzN1Bw_LA_6WVL3qTvs59S/s1600/found.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimj6qPFiiZKZtnfRTN9cyPivLgnQQZzaaQwDLZXzIUkAFP0K6rRykcLWZSy_OnjT83JfessP56qrTC16XbMagdxW2si_J7nKciejL9S8bUPe8_C-PVBTchFUuzN1Bw_LA_6WVL3qTvs59S/s1600/found.png" /></a></div>
<b>Projektowanie wyglądu w Foundation wymaga niewiele ponad znajomość HTML i CSS</b>, a polega głównie na zachowaniu odpowiedniej struktury tagów, oraz dodaniu pożądanych klas. Tak więc ładne elementy <i>textarea</i> i <i>button</i> uzyskałem poprzez dodanie do elementu <i>form</i> klasy <i>nice</i>:<br />
<blockquote class="tr_bq">
<span style="font-size: x-small;"><span style="color: #666666;"><form class="nice"></span><br style="color: #666666;" /><span style="color: #666666;"> <h2>Kod</h2></span><br style="color: #666666;" /><span style="color: #666666;"> <textarea></textarea></span><br style="color: #666666;" /><span style="color: #666666;"> <button class="nice radius small blue button">Uruchom</button></span><br style="color: #666666;" /><span style="color: #666666;"></form></span></span></blockquote>
Prawa strona edytora, prezentująca rezultat kodu to wynik dodania do elementu <i>div</i> klasy <i>panel</i>:<br />
<blockquote class="tr_bq">
<div style="color: #666666;">
<span style="font-size: x-small;"><h2>Rezultat</h2><br /><div class="panel"></div></span></div>
</blockquote>
<b>Siatka elementów jest oparta na 12 kolumnach</b> i wykorzystuje się ją także przez atrybut <i>class</i>:<br />
<blockquote class="tr_bq">
<span style="font-size: x-small;"><span style="color: #666666;"><div class="row"></span><br style="color: #666666;" /><span style="color: #666666;"> <div</span><br style="color: #666666;" /><span style="color: #666666;"> class="six columns"</span><br style="color: #666666;" /><span style="color: #666666;"> id="code"></span><br style="color: #666666;" /><span style="color: #666666;"> </div></span><br style="color: #666666;" /><span style="color: #666666;"> <div</span><br style="color: #666666;" /><span style="color: #666666;"> class="six columns"</span><br style="color: #666666;" /><span style="color: #666666;"> id="result"></span><br style="color: #666666;" /><span style="color: #666666;"> </div></span><br style="color: #666666;" /><span style="color: #666666;"></div></span></span></blockquote>
Jest to tylko kilka możliwości Foundation dlatego zachęcam do przejrzenia <a href="http://foundation.zurb.com/docs/">dokumentacji</a>, gdzie dowiemy się o kilkunastu elementach layout`u, wersji mobilnej, wsparciu starszych przeglądarek, wykorzystaniu <a href="http://jquery.com/">jQuery</a>, czy plikach startowych dla <a href="http://robotstxt.org/">robots.txt</a> i <a href="http://humanstxt.org/">humans.txt</a>.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-82334328770170894902012-01-31T19:45:00.002+01:002012-01-31T21:14:10.784+01:00html2canvas - znak nowych czasów<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUMZH0Cs3SmDb9m_Z2aHkgZjlJymVmw8BLBgrtGbfNxPI1o3x8S0bnNQpsi03Jd_RUQ8ZQwcHVDzWW9wcegIggLP-JgUzeGB4r57T5subNeRkDnMJ9sbVvLCOh4Fzv0MB6tF_Zwkjh_S0L/s1600/canvas.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUMZH0Cs3SmDb9m_Z2aHkgZjlJymVmw8BLBgrtGbfNxPI1o3x8S0bnNQpsi03Jd_RUQ8ZQwcHVDzWW9wcegIggLP-JgUzeGB4r57T5subNeRkDnMJ9sbVvLCOh4Fzv0MB6tF_Zwkjh_S0L/s1600/canvas.png" /></a></div>
O tej bibliotece miałem napisać jeszcze w zeszłym roku. <a href="http://html2canvas.hertzen.com/">html2canvas</a>, tak jak <a href="http://sudlik.blogspot.com/2011/06/renderowanie-pdfow-w-javascript.html">pdf.js</a>, czy <a href="http://sudlik.blogspot.com/2011/11/webodf-renderowanie-dokumentow-w.html">WebODF</a>, znak nowych czasów - czas przeglądarek. Nazwa tej biblioteki JavaScript (!) mówi wszystko. Pozwala ona na wykonanie po stronie przeglądarki konwersji strony do obiektu Canvas, czyli de facto obrazu, coś co wciąż jest uciążliwe na serwerach. Oczywiście przeglądarka przeglądarce nierówna, ale h2c ma całkiem niezłe wsparcie:<br />
<a name='more'></a><br />
<ul>
<li>Firefox >= 3.5</li>
<li>Google Chrome</li>
<li>Opera 11</li>
<li>Internet Explorer >= 8</li>
</ul>
Do tego grona mogą śmiało dołączyć także starsze wersje IE za sprawą <a href="http://flashcanvas.net/">flashcanvas</a>, czy <a href="http://excanvas.sourceforge.net/">ExplorerCanvas</a>.<br />
<br />
Biblioteka bierze pod uwagę HTML i CSS poza ramkami (frame, element iframe jest wspierane chociaż wiąże się to z pewną niedogodnością - szczegóły poniżej), osadzonymi obiektami (Flash, Java itp.), elementami tworzonymi przez przeglądarki (np. radio button) i wieloma właściwościami CSS 3.<br />
<br />
<blockquote class="tr_bq">
<span style="font-size: x-small;"><span style="color: #666666;">There are still <b>a lot of CSS properties missing, including most CSS3 properties</b> such as text-shadow, box-radius etc. as well as all elements created by the browser, such as radio and checkbox buttons and list icons. I will compile a full list of supported elements and CSS properties soon. There is <b>no support for frame and object content such as Flash</b>.</span></span></blockquote>
<br />
Ponad to h2c niestety wymaga na razie jQuery (w testach na stronie używany jest w wersji 1.6.2), ale autorzy wspominają o rezygnacji z niego w najbliższym czasie<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">It currently still has jQuery as a dependancy, but that will get removed soon.</span></blockquote>
Jak wygląda kod? Warto zajrzeć do źródła <a href="http://html2canvas.hertzen.com/build/jquery.plugin.html2canvas.js">jquery.plugin.html2canvas.js</a>, o to najciekawsze fragmenty:<br />
<br />
<blockquote class="tr_bq">
<span style="font-size: x-small;"><span style="color: #666666;">var object = $.extend( {}, {</span><br style="color: #666666;" /><span style="color: #666666;"> logging: false,</span><br style="color: #666666;" /><span style="color: #666666;"> proxyUrl: 'http://html2canvas.appspot.com/',</span><br style="color: #666666;" /><span style="color: #666666;"> ready: function( renderer )</span><br style="color: #666666;" /><span style="color: #666666;"> {</span><br style="color: #666666;" /><span style="color: #666666;"> document.body.appendChild( renderer.canvas );</span><br style="color: #666666;" /><span style="color: #666666;"> }</span><br style="color: #666666;" /><span style="color: #666666;"> }, options );</span><br style="color: #666666;" /><span style="color: #666666;">new html2canvas(this.get(0), object);</span></span></blockquote>
Jak widać serwer jest sprowadzany do nowej roli, jako proxy do pobierania treści pływających ramek, oraz treści (np. grafiki) z innych zewnętrznych źródeł. Wynika to z najnowszych zasad bezpieczeństwa przeglądarek: <a href="http://en.wikipedia.org/wiki/Same_origin_policy">same origin policy</a>.<br />
<br />
Przed użyciem powyższego kodu nie zapomnijmy załadować interesujących nas bibliotek.<br />
<br />
<blockquote class="tr_bq">
<div style="color: #666666;">
<span style="font-size: x-small;"><script type="text/javascript" src="external/jquery-1.6.2.min.js"></script></span></div>
<span style="color: #666666; font-size: x-small;"><script type="text/javascript" src="build/html2canvas.js"></script></span></blockquote>
Choć projekt wymaga jeszcze sporego rozwoju podziwiam jego <a href="http://html2canvas.hertzen.com/screenshots.html">aktualne możliwości</a>. Jeśli jesteście zainteresowani jego rozwojem zaglądajcie na <a href="https://github.com/niklasvh/html2canvas">GitHub</a>.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-51346150340321480912012-01-30T22:18:00.000+01:002012-01-31T15:36:00.318+01:00Kilka słów o MIME<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAdv2cN3f-R032F9UkhTjIlzWdRdqjFz9zivTclUjnSO4f25GkHzI_WpIuG3tG01nteydQLmzbCH0B5zyyrULDqVs8jEozQEExemc90myHGoQV_e-md_K7KXz5mNn_wGYPRYNHWg3Zium0/s1600/mime.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAdv2cN3f-R032F9UkhTjIlzWdRdqjFz9zivTclUjnSO4f25GkHzI_WpIuG3tG01nteydQLmzbCH0B5zyyrULDqVs8jEozQEExemc90myHGoQV_e-md_K7KXz5mNn_wGYPRYNHWg3Zium0/s1600/mime.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://www.flickr.com/photos/22280801@N07/2810153670">Mim w Sheffield</a></td></tr>
</tbody></table>
<a href="http://pl.wikipedia.org/wiki/Typ_MIME">Internet Media Type</a>, szerzej znany jak typ MIME i wartość Content-Type. Jest to <a href="http://www.iana.org/assignments/media-types/index.html">standaryzowana baza rodzajów plików</a>, ma ona pomóc w komunikacji między serwerami i klientami. Zwykle te pierwsze podają dane tym drugim, które z kolei muszą jakoś zinterpretować plik, co jest sednem całej sprawy.<br />
<br />
To tyle jeśli chodzi o podstawy i teorię, w praktyce bywa różnie. Wraz z rozwojem nowych technologii pojawiają się kolejne problemy z ich obsługą.<br />
<a name='more'></a><br />
<span style="font-size: large;">JavaScript</span><br />
<br />
Do niedawna był sygnalizowany poprzez:<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">text/javascript</span></blockquote>
i do teraz jest to najpopularniejsza forma, choć najpoprawniejszą jest<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">application/javascript</span></blockquote>
Zamieszanie jest tym większe, że można się spotkać z formami niestandardowymi<br />
<br />
<div style="text-align: left;">
<blockquote class="tr_bq">
<div style="color: #666666;">
<span style="font-size: x-small;">application/x-javascript</span></div>
</blockquote>
</div>
<div style="text-align: center;">
<span style="font-size: x-small;"><u><i>X</i> po slash`u stosuje się zwykle przy typach nie ujętych w bazie.</u></span></div>
<br />
<br />
<div style="text-align: left;">
<span style="font-size: large;">Czcionki</span><br />
<br />
Mimo co raz większej popularności osadzanych czcionek w IMT nadal brak rodziny typów<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">font/x</span></blockquote>
jest to poniekąd pokłosie jednej z bitew w standaryzacyjnej wojnie między Mozillą (WOFF) i Microsoft (EOT), którą najwyraźniej zwyciężył twórca Liska.</div>
<div style="text-align: left;">
Póki co nie zaleca się używania nawet</div>
<blockquote class="tr_bq">
<div style="color: #666666; text-align: left;">
<span style="font-size: x-small;">application/font-woff</span></div>
</blockquote>
<div style="text-align: left;">
z <a href="http://www.w3.org/TR/WOFF/">oficjalnych dokumentów W3C</a>, a <a href="http://stackoverflow.com/a/5142316">bezpiecznego</a></div>
<blockquote class="tr_bq">
<div style="color: #666666; text-align: left;">
<span style="font-size: x-small;">application/x-font-woff</span></div>
</blockquote>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
Jeśli chodzi o EOT, który jeszcze nam się przyda w przypadku Internet Explorer < 9 to korzysta on z <a href="http://www.iana.org/assignments/media-types/application/vnd.ms-fontobject">oficjalnego typu</a>:</div>
<blockquote class="tr_bq">
<div style="color: #666666; text-align: left;">
<span style="font-size: x-small;">application/vnd.ms-fontobject</span></div>
</blockquote>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
Ponad to jest jeszcze OTF, równie pokrzywdzony jak WOFF, gdzie <a href="http://stackoverflow.com/a/2907377">zamiast ładnego</a></div>
<blockquote class="tr_bq">
<div style="color: #666666; text-align: left;">
<span style="font-size: x-small;">font/opentype</span></div>
</blockquote>
<div style="text-align: left;">
<a href="http://stackoverflow.com/a/4657091">póki co używać lepiej</a></div>
<blockquote class="tr_bq" style="color: #666666;">
<div style="text-align: left;">
<span style="font-size: x-small;">application/x-opentype</span></div>
</blockquote>
<div style="text-align: left;">
a o czcionkach definiowanych w SVG lepiej zapomnieć.<br />
<br />
<span style="font-size: large;">HTML i XHTML</span><br />
<br />
Na początku było<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">text/html</span></blockquote>
i jest tak nadal... dla HTML. XHTML choć niósł szczytne idee to trochę namieszał.<br />
Generalnie powinno być (<a href="http://pl.wikipedia.org/wiki/XHTML#Typy_zawarto.C5.9Bci_XHTML">szczególnie dla XHTML 1.1</a>)<br />
<blockquote class="tr_bq">
<div style="color: #666666;">
<span style="font-size: x-small;">application/xhtml+xml</span></div>
</blockquote>
ewentualnie<br />
<blockquote class="tr_bq">
<div style="color: #666666;">
<span style="font-size: x-small;">application/xml</span></div>
</blockquote>
ale kIEpski < 9 się na tym wykładał.<br />
<br />
<span style="font-size: large;">Pozostałe</span><br />
<br />
Z resztą generalnie nie ma już takich problemów, CSS to<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">text/css</span></blockquote>
SVG to po prostu<br />
<blockquote class="tr_bq" style="color: #666666;">
<span style="font-size: x-small;">image/svg+xml</span></blockquote>
JPEG<br />
<blockquote class="tr_bq">
<span style="color: #666666; font-size: x-small;">image/jpeg</span></blockquote>
i tak dalej...</div>Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-10680230027323057792012-01-14T18:47:00.004+01:002012-01-14T18:47:53.038+01:00VirtualHost na Linux`ie<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWtdMuMcVTsnRnpwmfG-gZSARrJCfg8haea1kKARihYvz43BqsJ4AeMMGBgWqIK4XHvZGYz1WvgPyCdfa2GrcGLOBQSTdM64210MCwqUx5htHc9jIuSrrcqaWyOpWSlqtou2weWkKcCKH6/s1600/feather-small.gif" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWtdMuMcVTsnRnpwmfG-gZSARrJCfg8haea1kKARihYvz43BqsJ4AeMMGBgWqIK4XHvZGYz1WvgPyCdfa2GrcGLOBQSTdM64210MCwqUx5htHc9jIuSrrcqaWyOpWSlqtou2weWkKcCKH6/s1600/feather-small.gif" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="http://apache.org/">The Apache Software Foundation</a></td></tr>
</tbody></table>
Całkiem niedawno przesiadłem się na <a href="http://linuxmint.com/">Linux Mint</a>, dystrybucję opartą na Ubuntu, która z koleji opiera się na Debian`ie. Dwunasta wersja o nazwie kodowej "Lisa" prezentuje się całkiem nieźle, ale niestety z braku doświadczenia i wsparcia na Sony Vaio nie raz muszę się pogłowić jak coś zrobić. Czasami całkiem frustrujące sytuacje mają proste rozwiązania, tak też było z <a href="http://httpd.apache.org/docs/2.0/vhosts/">VirtualHost</a> w Apache.<br />
<br />
<a name='more'></a><br />
<br />
W Microsoft Windows obsługa własnych domen wygląda mniej więcej tak:<br />
<ol>
<li>Dodanie wpisu do pliku <i>C:/Windows/system32/hosts</i><br /><blockquote class="tr_bq" style="color: #666666;">
<div style="text-align: left;">
123.123.123.123 domena.localhost</div>
</blockquote>
</li>
<li>Dodanie wpisu do pliku <i>C:/XAMPP/apache/conf/httpd.conf</i><br /><blockquote class="tr_bq" style="color: #666666;">
<VirtualHost *:80><br /> RewriteEngine On<br /> RewriteOptions Inherit<br /> ServerName domena.localhost<br /> DocumentRoot /var/www/domena<br /> <Directory /><br /> Options FollowSymLinks<br /> AllowOverride All<br /> </Directory><br /> <Directory /var/www/domena><br /> Options Indexes FollowSymLinks MultiViews<br /> AllowOverride All<br /> Order allow,deny<br /> allow from all<br /> </Directory><br /> ErrorLog /var/www/domena/apache-error.log<br /> LogLevel warn<br /> CustomLog /var/www/domena/apache-access.log combined<br /></VirtualHost></blockquote>
</li>
</ol>
Teraz wystarczyło uruchomić serwer i cieszyć się z jej dobrodziejstw. Niestety trochę czasu potrwało zanim uzyskałem podobny efekt w moim nowym systemie.Rozpoczynamy podobnie:<br />
<ol>
<li>Dodanie wpisu do pliku <i>/etc/hosts</i><br /><blockquote class="tr_bq" style="color: #666666;">
123.123.123.123 domena.localhost</blockquote>
</li>
<li>Stworzenie nowego pliku w <i>/etc/apache2/sites-available/domena</i><br />
<blockquote class="tr_bq" style="color: #666666;">
<VirtualHost *:80><br />
RewriteEngine On<br />
RewriteOptions Inherit<br />
ServerName domena.localhost<br />
DocumentRoot /var/www/domena<br />
<Directory /><br />
Options FollowSymLinks<br />
AllowOverride All<br />
</Directory><br />
<Directory /var/www/domena><br />
Options Indexes FollowSymLinks MultiViews<br />
AllowOverride All<br />
Order allow,deny<br />
allow from all<br />
</Directory><br />
ErrorLog /var/www/domena/apache-error.log<br />
LogLevel warn<br />
CustomLog /var/www/domena/apache-access.log combined<br />
</VirtualHost></blockquote>
</li>
<li>Wykonanie komendy w terminalu<br /><blockquote class="tr_bq" style="color: #666666;">
a2esite domena</blockquote>
</li>
</ol>
Teraz należy usługę zrestartować i to wszystko. Listę uruchominych stron znajdziemy w katalogu <i>/etc/apache2/sites-enabled</i>.<br />
<br />
Jak widać na obu platformach sytuacja wygląda podobnie, ale nie tak samo więc mam nadzieję, że zaoszczędzę komuś czasu.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-75596079311443562112011-11-21T00:40:00.001+01:002011-11-26T19:34:47.958+01:00Struktura plików w projekcie<table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"><tbody>
<tr><td style="text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwyot1uKVjXENUA2f66js71AouGOiQZOpYsNBE_vPtoxKlEg8zYROar-8Js6nSpcV-BobaGNzCvlUKx3UyfHiUN13E8Th9nr2BHfT1q7VYG1_7Ysouwjxy_ndo4IJaHgQyKa3PYsyEIMnu/s1600/5113036539_79cf898fc3.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwyot1uKVjXENUA2f66js71AouGOiQZOpYsNBE_vPtoxKlEg8zYROar-8Js6nSpcV-BobaGNzCvlUKx3UyfHiUN13E8Th9nr2BHfT1q7VYG1_7Ysouwjxy_ndo4IJaHgQyKa3PYsyEIMnu/s1600/5113036539_79cf898fc3.jpg" /></a></td></tr>
<tr><td class="tr-caption" style="text-align: center;"><a href="https://secure.flickr.com/photos/cogdog/5113036539/">cogdogblog, CC BY 2.0</a></td></tr>
</tbody></table>
<div style="text-align: left;">
</div>
<div style="text-align: left;">
</div>
Gdy już mamy głębszą wizję naszego projektu - być może naszkicowaliśmy go na kartce papieru, albo przedstawiliśmy w formie <a href="http://drichard.org/mindmaps/">modelu</a> - czas zabrać się za pisanie kodu. Pierwszą rzeczą, która powinna nas interesować to struktura plików, chciałbym zaprezentować mój <i>bootstrap</i> na małe i średnie projekty.<br />
<a name='more'></a><br />
<br />
Czekam na czasy kiedy HTML zostanie rozczłonkowane na trzy rodzaje dokumentów, które przejmą po jednej funkcji jaką dotychczas spełniał jeden:<br />
<ol>
<li>Treść</li>
<li>Semantyka</li>
<li>Struktura</li>
</ol>
Póki co pozostaje mi dzielić pliki w projektach między foldery:<br />
<ul>
<li><b>data</b> - jeśli nie używamy do <u>cache</u> i <u>sesji</u> SQL, poza tym <u>logi</u>, <u>konfiguracja</u>, które dobrze mieć w takiej formie, <u>temp</u>, skrypty <u>SQL</u>, ewentualnie <u>pliki statyczne</u> db takie jak grafiki, oraz same <u>bazy danych</u> jeśli stosujemy <i>flat file database</i>, lub <a href="http://www.sqlite.org/">SQLite</a></li>
<li><b>engine</b> - kod <u>PHP</u></li>
<li><b>public</b> - pliki bezwzględnie potrzebny, czyli <u>index.php</u> i <u>.htaccess</u>, ewentualnie <u>robots.txt</u>, <u>humans.txt</u>, i <u>sitemap.xml</u></li>
<li><b>template</b> - pliki odpowiedzialnie za wygląd: <u>CSS</u>, <u>grafiki</u>, <u>JavaScript</u> i <u>WebFonts</u></li>
</ul>
Eksperymentowałem wcześniej z wydzieleniem JavaScript do osobnego folderu ze względu na swoją wyjątkową role (język programowania client-side) podobnie do PHP, ale było to zbyt naciągane.<br />
<br />
Po zastosowaniu powyższego podziału plików mój <i>bootstrap</i> wygląda tak:<br />
<br />
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
data/ </div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
cache/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
cfgs/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
db/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
logs/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
misc/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
static/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
engine/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
controllers/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
framework/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
libs/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
models/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
views/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
Bootstrap.class.php</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
public/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
.htaccess</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
humans.txt</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
index.php</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
robots.txt</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
sitemap.xml</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
template/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
fonts/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
imgs/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
misc/ </div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
scripts/ </div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
styles/</div>
<div style="background-color: #cccccc; font-family: "Courier New",Courier,monospace;">
<br /></div>
<br />
Dobrze wypracować własne metody, żeby harmonizowały się z resztą pracy, ale przy opracowywaniu ich nie zapominajmy o ewentualnych innych uczestnikach projektu.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-19324643511080731412011-11-17T13:55:00.002+01:002011-11-17T14:07:58.643+01:00FireBug - najlepszy przyjaciel web developera<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiVcGQCE0tetCoVU6XFEvhXo2u547JRxOCnQ5lAvlNBjn5Q_jGk_lbzdHVmZr0GAkW0xSt35OyKtguYtiGmuVeuGuLFwHN3K_idkR_I_Cz9AWHCXg0msYedXNxv41zuasm8vHqWnY5Q2ll/s1600/%2528Obrazek+JPEG%252C+211x168+pikseli%2529.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiVcGQCE0tetCoVU6XFEvhXo2u547JRxOCnQ5lAvlNBjn5Q_jGk_lbzdHVmZr0GAkW0xSt35OyKtguYtiGmuVeuGuLFwHN3K_idkR_I_Cz9AWHCXg0msYedXNxv41zuasm8vHqWnY5Q2ll/s1600/%2528Obrazek+JPEG%252C+211x168+pikseli%2529.jpg" /></a></div>Największym atutem <a href="https://www.mozilla.org/pl/firefox/fx/">Mozilla Firefox</a> dla web developera jest <a href="http://getfirebug.com/">FireBug</a>, narzędzie na tyle duże, że jest rozszerzalne dzięki własnym dodatkom. Jeśli nie przeglądaliście jeszcze ich <a href="https://getfirebug.com/wiki/index.php/Firebug_Extensions">listy na stronie FireBug`a</a> (aktualnie jest ich 58!) i <a href="https://addons.mozilla.org/pl/firefox/tag/firebug">Mozilla Dodatki</a> to najwyższy czas. Poniżej opisuję tylko te, które po dłuższym używaniu przypadły mi do gustu.<br />
<br />
<a name='more'></a><br />
<br />
<br />
<br />
<a href="https://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/10704-64.png?modified=1316552583" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/10704-64.png?modified=1316552583" /></a><span style="font-size: large;">CSS Usage</span><br />
<br />
Wskazuje nieużywane reguły <a href="http://www.w3.org/Style/CSS/">CSS</a>.<br />
<br />
<a href="https://addons.mozilla.org/pl/firefox/addon/css-usage/">Mozilla Dodatki</a><br />
<br />
<br />
<a href="https://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/11900-64.png?modified=1313331401" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/11900-64.png?modified=1313331401" /></a><span style="font-size: large;">FirePath</span><br />
<br />
Umożliwia inspekcję <a href="http://www.w3.org/DOM">DOM</a> z użyciem selektorów <a href="http://www.w3.org/TR/xpath/">XPath</a>, CSS i <a href="http://sizzlejs.com/">Sizzle</a>.<br />
<br />
<a href="https://code.google.com/p/firepath/">Strona</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/firepath/">Mozilla Dodatki</a><br />
<br />
<br />
<br />
<a href="https://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/12632-64.png?modified=1309313168" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/12632-64.png?modified=1309313168" /></a><span style="font-size: large;">FireQuery</span><br />
<br />
Dodaje wsparcie dla biblioteki JavaScript <a href="http://jquery.com/">jQuery</a>. <br />
<br />
<a href="http://firequery.binaryage.com/">Strona</a>, <a href="https://addons.mozilla.org/pl/firefox/addon/firequery/">Mozilla Dodatki</a><br />
<br />
<br />
<a href="https://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/9603-64.png?modified=1309314365" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/9603-64.png?modified=1309314365" /></a><span style="font-size: large;">FireRainbow</span><br />
<br />
Podświetla składnię <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">JavaScript</a>.<br />
<br />
<a href="http://firerainbow.binaryage.com/">Strona</a>, <a href="https://addons.mozilla.org/en-US/firefox/addon/firerainbow/">Mozilla Dodatki</a><br />
<br />
<br />
<a href="https://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/264087-64.png?modified=1313439064" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://static-cdn.addons.mozilla.net/en-US/firefox/images/addon_icon/264087-64.png?modified=1313439064" /></a><span style="font-size: large;">friendly bug</span><br />
<br />
Upiększa FireBug.<br />
<br />
<a href="https://addons.mozilla.org/pl/firefox/addon/friendly-bug">Mozilla Dodatki</a><br />
<br />
<br />
Przygotowanie tego wpisu było dla mnie dobrym pretekstem do lepszego poznania dodatków do FireBug`a i przy tej okazji usunąłem kilka: <a href="http://www.msi-stuff.com/acebug/">AceBug</a> (nie używałem), <a href="https://addons.mozilla.org/pl/firefox/addon/firefontfamily/">FireFontFamily</a> (nie działał), <a href="http://robertnyman.com/inline-code-finder/">Inline Code Finder</a> (nie używałem). Za to zainteresowałem się nowymi m.in.: <a href="http://www.firephp.org/">FirePHP</a>, <a href="http://firelogger.binaryage.com/">FireLogger i</a> <a href="https://code.google.com/intl/pl/speed/page-speed/download.html#extension-rel-ff">PageSpeed</a>, które muszę jeszcze przetestować nim opiszę.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-28579616331853076912011-11-15T13:06:00.000+01:002011-11-15T13:06:10.479+01:00WebODF - renderowanie dokumentów w JavaScript<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIWTsskuV9NBCaynAste_lxoM8BAUuzbiFx7gCbXQWpwJV5b-jkaMv1rZvuFTGKyMg-DMD-nCRaLMdN3BG1-nuO9nOun93Ko7Asygv0tCA4W5s23WYfXuwAmxDjHwd-qp8r9EpCailn63H/s1600/%2528Obrazek+JPEG%252C+225x225+pikseli%2529.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIWTsskuV9NBCaynAste_lxoM8BAUuzbiFx7gCbXQWpwJV5b-jkaMv1rZvuFTGKyMg-DMD-nCRaLMdN3BG1-nuO9nOun93Ko7Asygv0tCA4W5s23WYfXuwAmxDjHwd-qp8r9EpCailn63H/s1600/%2528Obrazek+JPEG%252C+225x225+pikseli%2529.jpg" /></a></div><a href="http://webodf.org/">WebODF</a> to jeden z tych niezwykłych projektów jakie w tym roku mam przyjemność poznać. Zapewnienie wsparcia dla <a href="https://pl.wikipedia.org/wiki/OpenDocument">ODF</a> po stronie klienta i to bez wysłużonej Javy, czy Flash które jest w kontrofensywie to kolejna mała rewolucja. WebODF pozwala nie tylko na wyświetlenie dokumentu, ale także na jego edycję (tekstu) i zoom co udowadnia nam <a href="http://webodf.org/demo/">demo</a>. Warto też wspomnieć, że wśród wspieranych formatów OpenDocument są arkusze kalkulacyjne (ods), dokumenty tekstowe (odt) i prezentacje (odp). A to wszystko dzięki Canvas - nowemu elementowi HTML5.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-1341355417682248522011-11-14T16:52:00.001+01:002011-11-17T13:58:02.869+01:00Jak rozpocząć pracę z Git?<div class="separator" style="clear: both; text-align: center;"></div><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQBYSdDTfnBTajJONIwOMJ8mh3XtCmqukAq2a1OblTht0jMJzOCruln4D2QMdQ8GbRDw5dI3tZyXAGzFlH24W-CnMpSfBbDsO8BEp4MejLfqNb87B7KGemkie4LFof-0EM2DH70tYPkEUg/s1600/octocat.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhQBYSdDTfnBTajJONIwOMJ8mh3XtCmqukAq2a1OblTht0jMJzOCruln4D2QMdQ8GbRDw5dI3tZyXAGzFlH24W-CnMpSfBbDsO8BEp4MejLfqNb87B7KGemkie4LFof-0EM2DH70tYPkEUg/s1600/octocat.png" /></a></div>W pewnym momencie stanąłem przed potrzebą pracy z systemem kontroli wersji. Istnieją mniej i bardziej popularne technologie, które dzielą się na systemy scentralizowane i rozproszone. Do tych pierwszych należy m.in. CVS i Subversion. Do zdecentralizowanych np. Bazaar i Git. Wybór padł na ten ostatni.<br />
<br />
<a name='more'></a><br />
<b>Dlaczego Git?</b> Stał się on dla mnie codziennością już dawno ze względu na takie serwisy jak <span id="goog_1054048402"></span><a href="http://github.com/">GitHub</a> i <a href="http://code.google.com/">Google Code</a>.<br />
<br />
<br />
<b>Jak zacząć:</b><br />
<br />
1. Poznaj <span id="goog_1054048402"></span><a href="http://github.com/">GitHub</a>.<br />
2. Pobierz <a href="http://sourceforge.net/projects/gitextensions/">Git Extensions</a>.<br />
3. Przeczytaj niestety nieukończoną i krótką, ale świetną serię Endera <a href="http://blog.end3r.com/142/github-kodowanie-spolecznosciowe/">GitHub - kodowanie społecznościowe</a>.<br />
4. Baw się dobrze :)Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-56590865445337431332011-08-23T18:51:00.006+02:002012-09-26T09:24:41.162+02:005 użytecznych skryptozakładek<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFbxPmS8N4hOzOH8HmKD156YDTnMgW_TvzJGzYf_ZYqLp3NDVxGwssjGVZoY7tMUsRv4Zp4vaq6UYqysiJubcAFnO4eDgdrJKXdmj-sduf9CxyXDJd9tSMZgyZb8Q519sJZ3uOB5w5sGhf/s1600/FireShot+capture+%2523041+-+%2527%2527+-+file____C__Users_Sudlik_Desktop_sad_txt.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFbxPmS8N4hOzOH8HmKD156YDTnMgW_TvzJGzYf_ZYqLp3NDVxGwssjGVZoY7tMUsRv4Zp4vaq6UYqysiJubcAFnO4eDgdrJKXdmj-sduf9CxyXDJd9tSMZgyZb8Q519sJZ3uOB5w5sGhf/s1600/FireShot+capture+%2523041+-+%2527%2527+-+file____C__Users_Sudlik_Desktop_sad_txt.png" /></a></div>
Skryptozakładki (inaczej bookmarklety, lub favelet`y) ostatnio straciły na popularności na rzecz bardziej kompleksowych dodatków do przeglądarek. Wciąż jednak są prostsze w tworzeniu i używaniu. Oto 5 skryptozakładek, które używam na co dzień.<br />
<br />
<a name='more'></a><br />
<br />
<span style="font-size: large;">jQuerify</span><br />
<br />
Kod: <a href="javascript:%20(function(){var%20el=document.createElement('div'),b=document.getElementsByTagName('body')[0];otherlib=false,msg='';el.style.position='fixed';el.style.height='32px';el.style.width='220px';el.style.marginLeft='-110px';el.style.top='0';el.style.left='50%';el.style.padding='5px%2010px';el.style.zIndex=1001;el.style.fontSize='12px';el.style.color='#222';el.style.backgroundColor='#f99';if(typeof%20jQuery!='undefined'){msg='This%20page%20already%20using%20jQuery%20v'+jQuery.fn.jquery;return%20showMsg();}else%20if(typeof%20$=='function'){otherlib=true;}%20function%20getScript(url,success){var%20script=document.createElement('script');script.src=url;var%20head=document.getElementsByTagName('head')[0],done=false;script.onload=script.onreadystatechange=function(){if(!done&&(!this.readyState||this.readyState=='loaded'||this.readyState=='complete')){done=true;success();script.onload=script.onreadystatechange=null;head.removeChild(script);}};head.appendChild(script);}%20getScript('http://code.jquery.com/jquery-latest.min.js',function(){if(typeof%20jQuery=='undefined'){msg='Sorry,%20but%20jQuery%20wasn\'t%20able%20to%20load';}else{msg='This%20page%20is%20now%20jQuerified%20with%20v'+jQuery.fn.jquery;if(otherlib){msg+='%20and%20noConflict().%20Use%20$jq(),%20not%20$().';}}%20return%20showMsg();});function%20showMsg(){el.innerHTML=msg;b.appendChild(el);window.setTimeout(function(){if(typeof%20jQuery=='undefined'){b.removeChild(el);}else{jQuery(el).fadeOut('slow',function(){jQuery(this).remove();});if(otherlib){$jq=jQuery.noConflict();}}},2500);}})();">dodaj do zakładek</a><br />
Strona: <a href="http://www.learningjquery.com/2009/04/better-stronger-safer-jquerify-bookmarklet">Better, Stronger, Safer jQuerify Bookmarklet</a><br />
<br />
jQuerify rozpoznaje czy strona używa <a href="http://jquery.com/">jQuery</a>, jeśli tak to podaję wersję, jeśli nie to dodaje najnowszą wersję do kodu.<br />
<br />
<br />
<span style="font-size: large;">Window Size</span><br />
<br />
Kod: <a href="javascript:(function(){var%20f=document,a=window,b=f.createElement("div"),c="position:fixed;top:0;left:0;color:#fff;background:#222;padding:5px%201em;font:14px%20sans-serif;z-index:999999",e=function(){if(a.innerWidth===undefined){b.innerText=f.documentElement.clientWidth+"x"+f.documentElement.clientHeight;}else%20if(f.all){b.innerText=a.innerWidth+"x"+a.innerHeight;}else{b.textContent=window.innerWidth+"x"+window.innerHeight;}};f.body.appendChild(b);if(typeof%20b.style.cssText!=="undefined"){b.style.cssText=c;}else{b.setAttribute("style",c);}e();if(a.addEventListener){a.addEventListener("resize",e,false);}else{if(a.attachEvent){a.attachEvent("onresize",e);}else{a.onresize=e;}}})();">dodaj do zakładek</a><br />
Strona: <a href="https://github.com/josscrowcroft/Window-Size-Bookmarklet">Window-Size-Bookmarklet</a><br />
<br />
Window Size podaje w górnym lewym rogu rozmiar okna, mały i przyjazny kod.<br />
<br />
<br />
<span style="font-size: large;">XRAY</span><br />
<br />
Kod: <a href="javascript:function%20loadScript(scriptURL)%20{%20var%20scriptElem%20=%20document.createElement('SCRIPT');%20scriptElem.setAttribute('language',%20'JavaScript');%20scriptElem.setAttribute('src',%20scriptURL);%20document.body.appendChild(scriptElem);}loadScript('http://westciv.com/xray/thexray.js');">dodaj do zakładek </a><br />
Strona: <a href="http://westciv.com/xray/">XRAY: look beneath the skin</a><br />
<br />
XRAY otwiera panel u góry strony, który wyświetla dane elementów strony. Element trzeba wcześniej nacisnąć. Skrypt nie wymaga aktualizacji, jest pobierany z serwera przy uruchomieniu.<br />
<br />
<br />
<span style="font-size: large;">MRI</span><br />
<br />
Kod: <a href="javascript:function%20loadScript(scriptURL)%20{%20var%20scriptElem%20=%20document.createElement('SCRIPT');%20scriptElem.setAttribute('language',%20'JavaScript');%20scriptElem.setAttribute('src',%20scriptURL);%20document.body.appendChild(scriptElem);}loadScript('http://westciv.com/mri/theMRI.js');">dodaj do zakładek</a><br />
Strona: <a href="http://westciv.com/mri/">MRI: test your selectors</a><br />
<br />
MRI podświetla elementy wskazane selektorem CSS. Skrypt jest tego samego autora co XRAY, już na początku zdradza to jego wygląd, ponad to także nie wymaga aktualizacji. <br />
<br />
<br />
<span style="font-size: large;">WhatFont</span><br />
<br />
Kod: <a href="javascript:(function(){var%20d=document,s=d.createElement('scr'+'ipt'),b=d.body,l=d.location;s.setAttribute('src','http://chengyinliu.com/wf.js?o='+encodeURIComponent(l.href)+'&t='+(new%20Date().getTime()));b.appendChild(s)})();">dodaj do zakładek</a><br />
Strona: <a href="https://github.com/willow/WhatFont-Bookmarklet">WhatFont-Bookmarklet</a><br />
<br />
WhatFont to świetne narzędzie, które skupia się na opisie czcionki stosowanej w zaznaczonym elemencie.<br />
<br />
<br />
Co prawda wszystko to znajdziemy w <a href="http://getfirebug.com/">FireBug</a>`u z odpowiednimi dodatkami, ale nie zawsze mamy go pod ręką, a bookmarklet`ów jest znacznie więcej,Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-29837654023434052052011-06-16T20:06:00.002+02:002011-11-15T12:46:57.258+01:00Renderowanie PDF`ów w JavaScript<div class="separator" style="clear: both; text-align: center;"></div><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjnm8Czfd28ZHJbN-NtWXru4-qYSkBBWxmow93tQ7Jv4xfOYtbcpUMb7dc1fdSXIXcIRAtsGYOMnTW7Ien7XfOrUJKI0bUuP3nInlQPNG6A2P49KLVBcazyP1JUydgEM2niXSmih8KXWWq/s1600/PDF_Logo.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjnm8Czfd28ZHJbN-NtWXru4-qYSkBBWxmow93tQ7Jv4xfOYtbcpUMb7dc1fdSXIXcIRAtsGYOMnTW7Ien7XfOrUJKI0bUuP3nInlQPNG6A2P49KLVBcazyP1JUydgEM2niXSmih8KXWWq/s1600/PDF_Logo.jpg" /></a> W sieci zrobiło się głośno o projekcie <a href="http://blog.mozilla.com/cjones/">Chris`a Jones</a> i <a href="http://andreasgal.com/">Andreas`a Gal</a>. Ich <a href="https://github.com/andreasgal/pdf.js">pdf.js</a> to nic innego jak biblioteka renderująca pliki PDF, rzecz jeszcze niedawno nie do wyobrażenia jest w toku pracy. Życzę im jak najlepiej, zagrożenie czai się jednak wśród niespójnych implementacji standardów (HTML Canvas, SVG) w przeglądarkach. <a href="http://people.mozilla.org/%7Egal/test.html">Efekty pracy</a> są obiecujące.<br />
<br />
Źródło: <a href="http://blog.mozilla.com/cjones/2011/06/15/overview-of-pdf-js-guts/">Chris Jones</a>, <a href="http://andreasgal.com/2011/06/15/pdf-js/">Andreas Gal</a>Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-79221789581700439882011-05-07T01:08:00.002+02:002011-08-23T15:41:55.888+02:00RegEx w przykładach<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaAHXKhkTdDsmeG3ZwtgW6pSyKzVgqgs2iGv06aHFr0XwodcgoSJusEEReYNXUS3QDsUkrpBqnn_8Jj3wMICbiViZHmre9dISz4WFIbaPSOZQzxsbWyGV-_XWGxrm-8PN4WhvOL-CuPLGt/s1600/FireShot+capture+%2523039+-+%2527%2527+-+file____C__Users_Sudlik_Desktop_new%252520%25252010_txt.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgaAHXKhkTdDsmeG3ZwtgW6pSyKzVgqgs2iGv06aHFr0XwodcgoSJusEEReYNXUS3QDsUkrpBqnn_8Jj3wMICbiViZHmre9dISz4WFIbaPSOZQzxsbWyGV-_XWGxrm-8PN4WhvOL-CuPLGt/s1600/FireShot+capture+%2523039+-+%2527%2527+-+file____C__Users_Sudlik_Desktop_new%252520%25252010_txt.png" /></a>Regex, znane także jako RegExp, a tj. Regular Expressions, czyli Wyrażenia Regularne to powszechne narzędzie do przeszukiwania, edytowania i dzielenia łańcuchów. Dosyć skomplikowane, ale za to szybkie i elastyczne. W sieci jest przedstawionych <a href="http://m1chu.eu/2009/10/13/15-przydatnych-wyrazen-regularnych-w-php/">wiele zastosowań</a> i czasami <a href="http://regexlib.com/">spore ich zbiory</a>. A oto mała próbka od mnie:<br />
<ul><li><b>BitTorrent Hash Info</b><br />
<pre>/(?:>|\s)([a-z0-9]{40})(?:<|\s)/i</pre></li>
<li><b>BitTorrent Tracker</b><br />
<pre>/\s*(http.*?\/announce(?:\..{1,3})?)\s*/gi</pre></li>
</ul>Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0tag:blogger.com,1999:blog-1146580213834765901.post-32652727123032300082011-04-29T06:35:00.004+02:002011-08-23T15:21:26.671+02:00Najstarszy niewspólny przodek w jQuery<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjtqvgFT7ueQx2FCb27kimsuyUFXs74xKGXM1pcMaCQsuSmoum_9bCTy5dDS6TsSfCpD1fdKN26x9tAM82HeMUDmy2AU5JjeRRO79cD1ZDceAQsC0c_fUIlfshIdHfaCP6cwVFfu-yQDgh/s1600/jQuery_logo_color_ondark.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" height="74" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgjtqvgFT7ueQx2FCb27kimsuyUFXs74xKGXM1pcMaCQsuSmoum_9bCTy5dDS6TsSfCpD1fdKN26x9tAM82HeMUDmy2AU5JjeRRO79cD1ZDceAQsC0c_fUIlfshIdHfaCP6cwVFfu-yQDgh/s200/jQuery_logo_color_ondark.png" width="200" /></a></div><br />
<br />
Tworząc dodatek <a href="http://userscripts.org/scripts/show/101826">Torrent Hash2Magnet</a> dla <a href="http://www.greasespot.net/">Greasemonkey</a> stanąłem przed potrzebom odnalezienie <b>najstarszego niewspólnego przodka</b> w przypadku wyparsowania kilku elementów z dokumentu.<br />
<br />
Problem wygląda następująco. Jest dokument z rozbudowaną hierarchią i <i>głęboko</i> osadzonymi 2 elementami: <i>#a3</i> i <i>#b3</i><br />
<a name='more'></a><br />
<br />
<pre name="code" class="html"><html>
<head></head>
<body>
<ul id="r1">
<li id="r2">
<ul id="r3">
<li id="a1">
<ul id="a2">
<li id="a3" class="child">
</li>
</ul>
</li>
<li id="b1">
<ul id="b2">
<li id="b3" class="child">
</li>
</ul>
</li>
</ul>
</li>
</ul>
</body>
</html>
</pre><br />
Używając biblioteki jQuery parsuję interesujące mnie elementy z klasą <i>.child</i> chcę znaleźć dla każdego z osobna wspomnianego wcześniej <b>NNP</b>, czyli najstarszego <i>rodzica</i>, który jednocześnie nie jest rodzicem drugiego elementu.<br />
<br />
<pre name="code" class="javascript">$(function(){
$('.child')
.parents()
.not(
$('.child')
.not($(this))
.parents())
.last();});
</pre><br />
Skrypt najpierw parsuje dokument w poszukiwaniu elementów z klasą <i>.child</i> w obrębie elementu <i>body</i>, następnie pobiera wszystkich przodków, aż do korzenia dokumentu, wyklucza rodziców pozostałych elementów z puli (wszystkie z <i>.child</i> bez <i>this</i>) i wybiera ostatni (najstarszy) element z puli.Marek Sudołhttp://www.blogger.com/profile/13394799909581503510noreply@blogger.com0