Scott Tiger Tech Blog

Blog technologiczny firmy Scott Tiger S.A.

HTML5

Więcej o technologiach webowych na blogu, zwłaszcza w kategorii WWW.
Ostatnia zmiana 16 sierpnia 2012.

Celem zespołu pracującego nad HTML5 jest utworzenie standardu który ułatwiałby tworzenie w przeglądarce interaktywnych aplikacji sieciowych (ang. web applications) takich jak GMail, Dokumenty Google itp. Choć jeszcze niekompletny, to już stanowczo wspierany przez producentów wiodących przeglądarek standard będzie używany przez następne lata.

Krótko o historii HTMLa

Pierwsza postać HTMLa (pochodnej SGMLa) stworzona przez Tima Bernersa-Lee w 1989 zawierała ok. 20 znaczników. Szybko stała się standardem IETF a od wersji 3.2 w 1997r. standardem W3C (konsorcjum założone przez Tima, w skład którego obecnie wchodzą przedstawiciele m.in. Apple, Microsoft, Adobe, Google, Oracle i IBM). Kamieniem milowym rozwoju był HTML 4.0 (i towarzyszące mu CSS, DOM, XML) opublikowany po raz pierwszy w okolicach tego samego 1997 roku i obowiązujący z drobnymi poprawkami do dziś (już 13 lat!).

Koncepcja rozdzielenia treści od prezentacji przyczyniła się do powstania w 2000 roku standardu XHTML który jest z grubsza dopasowaniem HTMLa do restrykcji narzucanych przez XML. Na warsztatach W3C w 2004 pojawiła się propozycja rozszerzenia HTMLa w sposób ułatwiający tworzenie aplikacji webowych – została odrzucona. W3C zajął się tworzeniem standardu XHTML 2.0 niekompatybilnego z 1.0, a niezadowoleni rebelianci (Apple, Mozilla, Opera) pod przewodnictwem Iana Hicksona (jeden z twórców Opery) utworzyli grupę WHATWG (ang. Web Hypertext Application Technology Working Group) pracującą nad standardami Web Forms 2.0 i Web Applications 1.0 które łącznie określano mianem HTML5.

Prace WHATWG przebiegały szybko, czemu być może sprzyjał obowiązujący schemat zatwierdzania: jedna osoba (Ian Hickson) ostatecznie podejmowała decyzję choć ryzykowała utratą stanowiska (commit then review). Tymczasem W3C (gdzie nb. decyzje zatwierdzano poprzez głosowanie – review than commit) ostatecznie w 2009r. zaniechała prac nad XHTML 2.0 który okazał się równie nietrafiony jak próba podziału dnia na 10 godzin i godziny na 100 minut dokonany przez Republikę po Rewolucji Francuskiej, po czym uznała racje swoich kontestatorów: w 2007 roku W3C HTML Working Group zadecydowała o wykorzystaniu pracy WHATWG jako podstawy nowego standardu W3C. HTML 5 osiągnął status First Public Draft w roku 2008.

Stanowcze wsparcie rynku dla nowego standardu pojawiło się w kontekście szybko postępujących wydarzeń:

  • Firefox i Safari zaczęły ochoczo implementować elementy HTML5,
  • pojawił się Google Chrome który od początku nastawił się na obsługę HTML5,
  • popularne stały się przeglądarki WWW w urządzeniach mobilnych (np. Safari w iPhone i iPod Touch),
  • coraz powszechniejsze stają się szerokopasmowe technologie sieciowe pociągające za sobą strumieniowe przekazy audio i video,
  • wzrost popularności blogów spowodował przeniesienie do głównego nurtu koncepcji treści WWW generowanej przez użytkowników,
  • wzrósł nacisk na tworzenie nie tyle witryn, co aplikacji webowych,
  • w 2010r. Microsoft formalnie stał się członkiem grupy standaryzującej HTML5.

Szacuje się, że standard zostanie ostatecznie zamrożony (Candidate Recommendation) w 2012 roku, a w 2022 osiągnie status Proposed Recommendation co w szczególności oznacza że będą istniały co najmniej dwie jego pełne implementacje. Tą drugą datą nie należy się zbytnio przejmować biorąc pod uwagę nierównomierność popularyzacji standardu (np. dopiero MSIE 8.0 zaczął w pełni obsługiwać HTML 4).

Z lotu ptaka

Główne cechy projektu nowego standardu:

  • rozwiązuje praktyczne problemy (takie o których mówi się od lat),
  • wspiera istniejące elementy języka (większość z HTML 4.01 przeżywa w HTML5); zapewnia możliwość łatwego zastępowania nowości starymi odpowiednikami (łagodna degradacja),
  • nie wymyśla koła od nowa, korzysta z wydeptanych ścieżek (ang. pave the cowpaths) – np. MSIE miał obsługę drag&drop od lat, więc nowe API jest oparte o istniejące rozwiązanie nawet jeśli niezbyt udane,
  • jeśli jakiś wzorzec implementowany w JavaScripcie jest wystarczająco popularny, HTML5 realizuje go deklaratywnie za pomocą znaczników i arkuszy stylów,
  • w razie konfliktu interesów ustawia priorytety w kolejności: użytkownik, twórca aplikacji WWW, twórca przeglądarki, twórca specyfikacji, czystość teorii,
  • promuje rozdzielanie treści (znaczniki) od prezentacji (CSS); odradza używania niestosujących się do tej zasady znaczników w HTML 4.0 i dodaje nowe znaczniki semantyczne,
  • przejęcie funkcjonalności dotychczas oferowanej tylko przez pluginy (audio/video/canvas) – pluginy nie zawsze są lub mogą być obecne (np. w iPadach nie ma Flasha) i są kłopotliwe w integracji z resztą dokumentu HTML.

O ile poprzednie specyfikacje HTMLa były skierowane głównie do webmasterów, o tyle specyfikacja HTML5 dotyczy zarówno twórców aplikacji WWW jak i twórców przeglądarek (na szczęście dostępna jest również wersja specyfikacji HTML5 dla twórców aplikacji WWW).

Ponieważ nastąpił odwrót od XHTMLa, HTML5 nie jest XMLem, a więc wielkość znaków w nazwach znaczników, cytowanie atrybutów, konieczność domykania wszystkich znaczników itp. nie obowiązują.

Standard nie czyni żadnego znacznika/atrybutu deprecjonowanym, ale w odniesieniu do niektórych obiektów używa słowa „przestarzały” (ang. obsolete). Oznacza to że są one wspierane, choć nie zalecane i nie mówi się o tym że w przyszłości znikną. Dotyczy to zwłaszcza tych znaczników które mogą zostać zastąpione odpowiednim użyciem arkuszy stylów (np. frame, frameset, noframes, font, big, center, strike, u) i atrybutów takich jak bgcolor, cellspacing, cellpadding, border, width, height, longdesc, target, valign, align. Kilka znaczników zostało zastąpionych przez nowe, np. zamiast acronym należy używać abbr, applet został zastąpiony przez object, a dir przez ul.

Inne znaczniki z kolei zmieniły swoje znaczenie. I tak np. znacznik oznaczający do tej pory wytłuszczenie oznacza teraz stylistyczne wysunięcie z tekstu bez nadawania temu specjalnego znaczenia (ang. to be stylistically offset from the normal prose without conveying any extra importance), z kolei jeśli chcemy uwypuklić tekst znaczeniowo to należy użyć znacznika strong. Znacznik „i” nie oznacza już kursywy, lecz zmianę charakteru wypowiedzi (np. termin techniczny lub w obcym języku) – dla wyrażenia nacisku na poziomie językowym należy użyć znacznika em.

Kompletny wykaz unieważnionych artefaktów z HTML4 i ich zamienników możesz znaleźć w specyfikacji: HTML5 differences from HTML4.

HTML 5 standaryzuje obsługę błędów, dzięki czemu wszystkie przeglądarki internetowe będą reagowały na błędy pojawiające się w kodzie HTML w dokładnie taki sam sposób.

Protoplaści HTML5

Warto zauważyć, że HTML5 wzoruje się na pomysłach które już dawno doczekały się konkretnych implementacji. Gears (firmy Google, projekt już zarzucony) to rozszerzenie przeglądarek Chrome, Firefox, MSIE i Safari, które oferowało twórcom aplikacji WWW takie możliwości jak interakcja z pulpitem, SQLowa baza danych w przeglądarce (SQLite), wątki, czy praca offline. Adobe AIR – platforma rozwijana do dziś i otwarcie nawiązująca do idei tworzenia aplikacji WWW o takich możliwościach jak dotychczasowe aplikacje standalone – przypomina „nowinki” HTML5 jeszcze bardziej. Można śmiało powiedzieć, że HTML5 spycha przeglądarki w stronę AIR. Tym niemniej, AIR ma kilka możliwości jakich przeglądarka WWW nigdy raczej mieć nie będzie:

  • dostęp (odczyt/zapis) do całego systemu plików klienta ograniczony tylko przez system operacyjny (ale patrz W3C File API: Writeri inne specyfikacje File API),
  • mozliwość uruchamiania dowolnych procesów po stronie klienta i komunikacji z nimi poprzez standardowe wejscie/wyjscie,
  • możliwość działania standalone, tj. bez kontaktu z jakimkolwiek serwerem WWW (typowa aplikacja WWW przynajmniej na jakimś etapie takiego kontaktu wymaga).

Więcej na temat AIR w osobnym poście z 21.09.2010.

Wykrywanie możliwości przeglądarki

Różne przeglądarki w różnym stopniu implementują dziś standard HTML5. Aby w kodzie JavaScriptu wykryć czy da się skorzystać z jakiegoś aspektu standardu HTML5 i CSS3, można użyć opensource’owej biblioteki Modernizr. Strona główna projektu dodatkowo wyświetla informacje o możliwościach Twojej przeglądarki w zakresie obsługi HTML5. Wystarczy załadować bibliotekę na stronie:

    <script src="modernizr.min.js"></script>

aby móc przeprowadzić detekcję:

    if( Modernizr.canvas ) { ... }

Ponadto, z uwagi na nietypowy sposób w jaki MSIE < 9 traktuje znaczniki których nie rozumie, warto umieścić na stronie HTML następujący kawałek kodu:

    <!--[if lt IE 9]>
      <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->

Kilka uproszczeń

Logo HTML5

Logo HTML5

Standard HTML5 nie tylko dodaje wiele nowych interfejsów i blisko setkę nowych tagów, ale również parę rzeczy upraszcza.Każdy dokument HTML4 zaczyna się czymś w rodzaju

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

Jeśli strona jest zgodna ze standardem HTML5, to możemy pisać po prostu:

    <!DOCTYPE HTML>

Kodowanie znaków:

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

to teraz:

    <meta charset="UTF-8"/>

Załączanie arkusza stylu CSS:

    <link rel="stylesheet" type="text/css" href="file.css">

nie wymaga już atrybutu type (który jest domyślny):

    <link rel="stylesheet" href="file.css">

Podobnie załączanie pliku JavaScriptu:

    <script type="text/javascript" src="file.js"></script>

nie wymaga domyślnego atrybutu type:

    <script src="file.js"></script>

Programistów JavaScript zapewne ucieszy że począwszy od wersji 9.0 Internet Explorer zacznie wreszcie implementować specyfikacje DOM Level 2 i Level 3, więc kod obsługi zdarzeń i manipulacji drzewem DOM będzie wreszcie jednolity dla wszystkich przeglądarek.

Web Forms 2.0

Usprawnienia formularzy poczynione w ramach Web Forms 2.0 są dobrym przykładem trzymania się reguły która nakazuje popularne wzorce implementowane do tej pory w JavaScripcie realizować deklaratywnie w postaci znaczników HTML.

I tak, aby automatycznie ustawić kursor w wybranej kontrolce formularza po załadowaniu strony, wystarczy dodać atrybut autofocus:

    <input name="hobbies" type="text" autofocus>

Placeholder to modna ostatnio etykietka-podpowiedź dla użytkownika umieszczona wewnątrz kontrolki, znikająca gdy użytkownik umieści w kontrolce kursor:

    <input name="data" type="text" placeholder="YYYY-MM-DD">

HTML5 pozwala wyłączyć autouzupełnianie w wybranych kontrolkach lub całym formularzu. Służy do tego atrybut autocomplete (domyślnie „on”):

    <input type="text" autocomplete="off">

Dla kontrolki możemy zdefiniować listę proponowanych wartości (wyświetlanych jako lista rozwijana) pozwalając użytkownikowi wprowadzić własną wartość spoza listy:

    <input type="text" name="homeworld" list="planets">
    <datalist id="planets">
      <option value="Mercury">
      <option value="Venus">
      ...
    </datalist>

Szczególne znaczenie w urządzeniach przenośnych ma możliwość głosowego wprowadzania tekstu. Funkcję taką udostępniają przeglądarki oparte na silniku WebKit (czyli np. Google Chrome):

    <input type="text" speech x-webkit-speech style="width:400px;"/>

W efekcie po prawej stronie kontrolki pojawia się ikonka mikrofonu – po jej kliknięciu można mówić. Niestety, praktyka pokazuje że dla użytkowników mówiących w języku angielskim z akcentem, albo w języku innym niż angielski, znacznik może okazać się bardzo trudny w użyciu.

Kliknij aby przetestować (Chrome).

Kliknij aby przetestować (Chrome).

Walidacja

Atrybut required powoduje że przeglądarka nie pozwoli na zatwierdzenie formularza gdy kontrolka nie ma wartości:

    <input type="text" required>

Na podobnej zasadzie możemy wymusić aby wartość pola tekstowego pasowała do określonego wyrażenia regularnego:

    <input type="text" pattern="[0-9]{2}-[0-9]{2}">

Innym sposobem na walidację są nowe natywne kontrolki wyspecjalizowane do wprowadzania danych odpowiedniego typu – przeglądarka nie pozwala wprowadzić błędnej wartości lub protestuje przy zatwierdzaniu całego formularza. Jeśli jakaś przeglądarka nie obsługuje jeszcze nowej kontrolki, wówczas użytkownik otrzymuje zwykłą kontrokę typu text (łagodna degradacja). I tak oprócz kontrolek znanych z HTML4 mamy teraz kontrolki do wprowadzania typów:

  • Email: <input type="email">,
  • URL: <input type="url">,
  • Tel: <input type="tel">,
  • Liczba: <input type="number" min="1" max="5" step="1" value="3">
    (liczba całkowita, wyświetlane jako tzw. spinner),
  • Liczba z zakresu: <input type="range" min="1" max="5" step="1" value="3">
    (liczba całkowita z przedziału, wyświetlane jako suwak),
  • Data: <input type="date" value="2010-11-14">
    (wyświetlane jako kalendarzyk),
  • Data+czas+strefa: <input type="datetime" value="2010-11-14T10:11:12 UTC">,
  • Data+czas (lokalny): <input type="datetime-local" value="2010-11-14T10:11:12">,
  • Czas: <input type="time" value="10:11:12">,
  • Miesiąc: <input type="month" value="2010-12">,
  • Kolor: <input type="color" value="#FFFFFF">,

Dodatkowo mamy jeszcze kontrolkę do wprowadzania tekstu do wyszukiwania (jej wygląd będzie zależał od systemu operacyjnego):

<input type="search">

Póki co wyglądu nowych kontrolek takich jak kalendarzyk nie da się modyfikować za pomocą arkuszy stylów.
Wymienione kontrolki mają szczególny sens w przypadku urządzeń mobilnych, które w zależności od tego która kontrolka jest aktywna wyświetlają różne rodzaje klawiatury – zawierające tylko potrzebne klawisze.

Poniżej przykładowa prezentacja nowych kontrolek (kliknij obrazek aby przetestować w nowym oknie):

Nowe kontrolki (Opera). Kliknij aby przetestować.

Nowe kontrolki (Opera). Kliknij aby przetestować.

Warstwa semantyczna

Tak jak wyszukując czegokolwiek w Google’u nie mamy gwarancji znalezienia na początku listy wyników dokładnie tego o co nam chodzi, po przetworzeniu chińskiej strony HTML Google Translatorem nie spodziewamy się literackiego tłumaczenia na język polski i zadowalamy się łamaną polszczyzną pozwalającą zorientować się o co chodzi, tak propozycja nadawania znaczenia fragmentom tekstu umieszczonym na stronie WWW poprzez określenie konwencji (mikroformaty i mikrodane – patrz dalej) i zdefiniowanie nowych znaczników nie oznacza jeszcze „semantycznego internetu”. Czyli pragmatyczna ewolucja zamiast podszytej dobrymi chęciami rewolucji.

Nowe znaczniki semantyczne

Roboty sieciowe indeksujące strony np. na użytek wyszukiwarki Google’a często mają problem z oddzieleniem na stronie właściwej treści (np. artykułu) od mniej istotnych informacji (komentarze, elementy nawigacyjne, reklamy, stopki itp.). Również niepełnosprawni Internauci wiele skorzystaliby, gdyby inteligentne czytniki były w stanie łatwiej nawigować po stronie zamiast czytać wszystko jak leci. Przykłady możnaby mnożyć. Faktem jest, że znaczniki HTML4 takie jak <div> mówią niewiele lub zgoła nic nie mówią o znaczeniu zawartych w nich danych. Coraz bardziej popularnymi pojęciami w kontekście sieci WWW stają się syndykacja oraz agregacja związane z współdzieleniem fragmentów kodu HTML przez różne witryny. Tymczasem często kod HTML4 po przeniesieniu w nowe miejsce wymaga modyfikacji (np. nagłówek H1 trzeba zmienić na H2).

Rozmaite badania i analizy obecnych w Internecie stron WWW (np. Web Authoring Statistics Google’a) wykazały istnienie często powtarzanych wzorców, implementowanych za pomocą skomplikowanej struktury znaczników HTML. I tak np. powszechnie stosuje się konstrukcje <div class="..."> gdzie często pojawiającymi się identyfikatorami klas są header, content, main, footerczy nav. Dobrym przykładem jest tu typowy post na blogu.

Odpowiedzią standardu HTML5 na tego rodzaju potrzeby jest kilka nowych znaczników:

  • <section>: grupuje tematycznie powiązaną zawartość, zwykle wraz z jakimś nagłówkiem,
  • <article>: samodzielna, główna treść, przeznaczona do syndykacji (post bloga, post na forum, artykuł gazety, ale również widget taki jak kalkulator, zegar, widget pogody itp.)
  • <header>: konetener dla informacji wprowadzających (np. tytuł, spis treści, pole wyszukiwania, logo) i wskazówek nawigacyjnych,
  • <hgroup>: kontener dla dwóch lub więcej elementów nagłówka (np. tytuł i podtytuł),
  • <footer>: informacje o kontenerze nadrzędnym: kontakt z autorem, prawa autorskie, polityka prywatności, łącza do powiązanych treści, łącze do pomocy itp.
  • <aside>: treść poboczna która może być usunięta bez szkody dla głównej treści sekcji, zwykle umieszczana w pasku bocznym (ang. sidebar), np. reklamy; biografia autora – mimo że często umieszczana z boku – znaczeniowo podpada raczej pod znacznik <footer>,
  • <nav>: łącza nawigacyjne witryny, zwykle wewnątrz elementu <header>,
  • <dialog>: wypowiedzi osób, np. wywiad lub komentarze pod artykułem:
      <dialog>
        <dt>Jan Kowalski</dt>
        <dd>HTML5 daje możliwość umieszczania elementów semantycznych na stronie.</dd>
        <dt>Anna Milusińska</dt>
        <dd>Tak, masz całkowitą rację.</dd>
        <dt>Jan Kowalski</dt>
        <dd>Rozmowa może być teraz łatwo wyodrębniona.</dd>
      </dialog>
  • <figure>: pozwala powiązać ilustrację/diagram/fotografię/listing kodu itp. z podpisem:
      <figure>
        <legend>Rysunek 12.  Jak naprawić kran</legend>
        <img ...>
      </figure>

Znacznik <section> jest ogólnym kontenerem powiązanych treści, <article> to wyspecjalizowany rodzaj elementu <section>, natomiast znaczniki <header>, <footer>, <nav>, <aside> itp. są kawałkami określonego, specyficznego rodzaju treści. HTML5 nie deprecjonuje elementu <div>, który nadal jest używany w charakterze kontenera dla niekoniecznie powiązanych ze sobą semantycznie treści.

Nowe znaczniki semantyczne nie wprowadzają żadnego formatowania – od tego są arkusze stylów.

Każda sekcja/artykuł jest osobną jednostką spisu treści. Poziom zagnieżdżenia w spisie treści zależy wyłącznie od poziomu zagnieżdżenia sekcji w innych sekcjach na stronie (co ułatwia wycinanie fragmentów ze strony i wklejanie bez zmian do innego kodu HTML), a nie od tego czy dla nagłówka użyto znacznika <H1> czy <H2>. W każdej sekcji zaleca się używać wyłącznie <H1>, a o nagłówkach dalszego poziomu zapomnieć.

Poniżej przykład wpisu na blogu, sporządzony przy użyciu nowych znaczników semantycznych HTML5:

  <!doctype html>
  <html>
    <head>
      <title>Example Blog in HTML5</title>
    </head>
    <body>
      <header>
	<h1><a href="www.someblogpost.com">HTML Element Language is Awesome</a></h1>
      </header>
      <section><h1><a href="/blog/html/my_title">My Title</a></h1>
	<article>
	  <p>Yesterday I started to write in Word and realized that...</p>
	  ...
	</article>
	<dialog>
	  <dt>John Smith</dt>
	  <dd>It is great that you take time to make these comments.</dd>
	  ...
	</dialog>
	<nav><a href="/blog/page/2/">Previous Entries</a></nav>
      </section>
      <footer>
	<nav>
	  <ul>
	    <li><a href="/blog/comment-policy/">Comment Policy</a></li>
	    <li><a href="/blog/Keywords/">Keyword List</a></li>
	  </ul>
	</nav>
	<p>Copyright 2009 Matthew David</p>
      </footer>
    </body>
  </html>

Do tej pory mówiliśmy o znacznikach blokowych. HTML5 definiuje również kilka znaczników wplatanych (ang. inline, tj. nie wymuszających podziału wiersza) obok znaczników takich jak <var>, <code>, <kbd>, <tt>, czy <samp> znanych z HTML4.:

  • <mark>: podświetlenie (np. wyszukiwanej frazy w tekście) dla celów referencyjnych,
  • <time>: oznaczenie czasu, np.:
        <time datetime="2010-04-07">7 kwietnia</time>
        <time>2010-04-07</time>
        <time datetime="2009-10-22T13:59:47-04:00" pubdate>22 października 2009 13:59 EDT</time>

    Atrybut pubdate wewnątrz <article> oznacza datę publikacji artykułu, w każdym innym wypadku datę publikacji całego dokumentu.

  • <meter>: wartość numeryczna z określonego zakresu, np.
        <p>W zawodach przepłynąłem dystans <meter value="120" min="0" max="200" low="80" high="200" optimum="200">120 metrów</meter></p>
  • <progress>: oznacza wskaźnik postępu (przydatne przy aktualizacji wartości znacznika z poziomu JavaScriptu i Ajaksa) jak w przykładzie:
        Plik załadowano w <progress min="0" max="100" value="60">60%</progress>.

Microdata

Nowe elementy semantyczne HTML5 zaspakajają tylko niektóre potrzeby. Na użytek narzędzi indeksujących Internet przydałaby się możliwość chirurgicznie precyzyjnego wyodrębniania ze stron HTML takich fragmentów jak specyfikacje lub recenzje produktów, czy informacje kontaktowe o osobach lub organizacjach.

Przed pojawieniem się HTML5 przynajmniej dwa podejścia do problemu osiągnęły w miarę dojrzały status:

  • Mikroformaty to zbiór uzgodnionych przez społeczność konwencji nadawania znaczenia treści HTML za pomocą stosownych wartości atrybutów class i rel:
    <div>
      <div>Joe Doe</div>
      <div>The Example Company</div>
      <div>604-555-1234</div>
      <a href="http://example.com/">http://example.com/</a>
    </div>
    =>
    <div class="vcard">
      <div class="fn">Joe Doe</div>
      <div class="org">The Example Company</div>
      <div class="tel">604-555-1234</div>
      <a class="url" href="http://example.com/">http://example.com/</a>
    </div>

    I tak możemy mówić o mikroformacie hCard do opisu kontaktów, hCalendar do zdarzeń itp. Ponieważ istnieje zgoda co do znaczenia takiego etykietowania, więc powstały parsery i rozszerzenia przeglądarek (np. Operator dla Firefoksa) pozwalające na pracę z takimi wzorcami. Mikroformaty są koncepcyjnie proste, ale przez to ograniczone i nie pozwalają na objęcie wszystkich możliwych potrzeb, ale za to większość najbardziej palących.

  • Resource Description Framework (RDF) pozwala na opisywanie zasobów sieci Web za pomocą składni opartej na XML i trzyelementowych wyrażeń zawierających podmiot (zasób), orzeczenie/predykat (własność) i dopełnienia/obiektu (wartość). W poniższym przykładzie url jest zasobem, element <autor>własnością, a „Krzysztof Kozłowski” wartością:
    <?xml version="1.0"?> 
    <RDF> 
    <Description about="http://pl.wikipedia.org/wiki/Wikipedysta:KoziK"> 
        <autor>Krzysztof Kozłowski</autor> 
        <utworzono>1 Maja 2009</utworzono> 
        <zmodyfikowano>1 Stycznia 2010</zmodyfikowano> 
    </Description> 
    </RDF>

HTML5 wprowadza własny mechanizm mikrodanych który ma naprawić niedoskonałości mikroformatów nie będąc jednocześnie tak skomplikowanym jak RDF. Microdata dekoruje drzewo DOM za pomocą par nazwa/wartość z dowolnie zdefiniowanego słownika o zasięgu ograniczonym do poddrzewa.
Poniżej przykład jak możemy semantycznie otagować informacje o organizacji (Google Inc.):

<article>
  <h1>Google, Inc.</h1>
  <p>
    1600 Amphitheatre Parkway<br>
    Mountain View, CA 94043<br>
    USA
  </p>
  <p>650-253-0000</p>
  <p><a href="http://www.google.com/">Google.com</a></p>
</article>
=>
<article itemscope itemtype="http://data-vocabulary.org/Organization">
  <h1 itemprop="name">Google, Inc.</h1>
  <p itemprop="address" itemscope itemtype="http://data-vocabulary.org/Address">
    1600 Amphitheatre Parkway<br>
    Mountain View,
    CA
    94043<br>
    USA
  </p>
  <p itemprop="tel">650-253-0000</p>
  <p><a itemprop="url" href="http://www.google.com/">Google.com</a></p>
</article>

Poniżej kilka uwag:

  • Atrybut itemtype deklaruje słownik mikrodanych jaki będzie używany (identyfikowany przez URL który może, ale nie musi odwoływać się do konkretnego zasobu), natomiast atrybut itemscopedeklaruje że wszystkie własności jakie ustawimy w poddrzewie DOM odnoszą się do tego słownika.
  • Mikroformaty możemy zagnieżdżać. Tutaj mikroformat http://data-vocabulary.org/Address jest zagnieżdżony w mikroformacie http://data-vocabulary.org/Organization (klucz address).
  • W przypadku gdy z dłuższego fragmentu tekstu (adres w naszym przykładzie) trzeba wyodrębnić wartości poszczególnych kluczy (locality, region, postal-code itp.), można wykorzystać znacznik który nie wpłynie na wygląd renderowanego HTMLa.
  • Można dodawać dane semantyczne które nie mają swojej reprezentacji graficznej na stronie WWW (choć należy tego unikać). Powiedzmy że do powyższej informacji o organizacji chcielibyśmy dodać nie wyświetlaną nigdzie lokalizację GPS. Możemy to (w obrębie elementu <article>zrobić tak:
    
      <meta itemprop="latitude" content="37.4149"/>
      <meta itemprop="longitude" content="-122.078"/>
    

Mechanizm mikrodanych zasadniczo odnosi się do dekorowania semantyką danych które już są obecne na stronie HTML a nie jako byt niezależny. Jest uzupełniającą niedostatki HTMLa warstwą semantyczną nie stanowiącą jednocześnie odrębnej całości.

Oczywiście mikrodane mają sens tylko wtedy gdy istnieją powszechnie przyjęte słowniki. Firma Google na użytek swojej wyszukiwarki zaproponowała standard o nazwie Google Rich Snippets a w nim słowniki takie jak Person, Review, Product, Organization, Event i Recipe. Po otagowaniu semantycznym swojej strony WWW można jej URL podać w narzędziu Rich Snippets Testing Tool aby upewnić się że Google prawidłowo wyciągnie potrzebne semantyczne dane. W rzeczywistości powyższy przykład wykorzystuje GRS, a użyte w nim URLe takie jak http://data-vocabulary.org/Organization odnoszą się do strony WWW na której zdefiniowano poszczególne klucze słownika w sposób czytelny dla ludzi.
Przykładowy wynik wyszukiwania osoby w Google’u wykorzystujący mikrodane może wyglądać jak na poniższym rysunku – proszę zwrócić uwagę na szary tekst poniżej tytułu zawierający miejsce zamieszkania wyszukanej osoby i jej stanowisko w firmie.

Wynik wyszukiwania osoby w Googlu, z wykorzystaniem mikrodanych

Wynik wyszukiwania osoby w Googlu, z wykorzystaniem mikrodanych

HTML5 definiuje również API DOM JavaScriptu do wyciągania mikrodanych ze strony HTML, ale póki co żadna przeglądarka nie implementuje tego jeszcze.

Wizualizacja i multimedia

Canvas

Element <canvas> tworzy na ekranie prostokątny obszar grafiki rastrowej na którym możesz rysować z poziomu JavaScriptu.

Technika działania elementu canvas określana jest mianem renderingu trybu natychmiastowego (ang. immediate mode rendering) w odróżnieniu od stosowanego w SVG renderingu trybu zachowanego (ang. retained mode rendering). Ten pierwszy jest szybszy, daje maksymalną kontrolę nad każdym pikselem obrazu (ważne ze względu na aspekty wydajnościowe i zużycie pamięci) ale wymaga jawnego pisania kodu JavaScriptu rysującego grafikę, w drugim mamy do czynienia z wewnętrznym modelem którego reprezentacją graficzną i odrysowywaniem zajmuje się system. Warto jeszcze zauważyć że o ile SVG stanowi część drzewa DOM dokumentu HTML, o tyle elementy rysowane na kanwie już nie.

Funkcjonalność oferowana przez kanwy:

  • rysowanie prostokątów i ścieżek (linie, łuki, krzywe Beziera lub krzywe drugiego stopnia),
  • wypełnianie figur kolorem (z kanałem alfa), wzorem lub gradientem (liniowym lub radialnym),
  • rysowanie napisów (tekstu),
  • obsługa przezroczystości,
  • przekształcenia (przesuwanie, skalowanie, obracanie, przekrzywianie itp.),
  • osadzanie obrazów rastrowych (PNG, JPEG, GIF),
  • cieniowanie,
  • style kompozycji określające jak nowe treści są rysowane na istniejących składnikach kanwy,
  • ścieżki przycinania (ang. clipping paths).

Typowe zastosowania canvas:

  • grafy i wykresy,
  • gry,
  • pełne aplikacje takie jak wymienione w ramce obok.

Mimo wszystkich tych możliwości korzystanie z „gołego” canvas jest dość pracochłonne z uwagi na jego niskopoziomowe API (np. nie ma możliwości rysowania bardziej skomplikowanych figur geometrycznych, łatwego rysowania wykresów itp.). Z tego względu często korzysta się z bibliotek JavaScriptu które dają dostęp do bardziej wysokopoziomowego API (np. LiquidCanvas, RGraph) być może dodatkowo ukrywając przed programistą JavaScriptu rzeczywistą implementację mechanizmu renderującego (VML pod MSIE, Canvas dla pozostałych przeglądarek) zwiększając tym samym przenośność (Processing.js, ExCanvas).

  <canvas id="my-first-canvas" width="360" height="240">
    Tutaj tekst wyświetlany gdy przeglądarka nie obsługuje canvas.
  </canvas>
  <script>
    var canvas = document.getElementById( 'my-first-canvas' );
    var context = canvas.getContext('2d');
    context.fillStyle = "red";
    context.fillRect(50,25,150,100);
  </script>

Dźwięk i wideo

Do niedawna obsługa wideo i odtwarzanie utworów muzycznych w przeglądarkach były domeną pluginów takich jak Flash, Apple Quick Time czy RealPlayer. HTML5 dodaje taką funkcjonalność w samym HTMLu.

Do odtwarzania dźwięku i wideo konieczne są kodeki (ang. codecs). Poniżej krótka charakterystyka najpopularniejszych w Internecie:

Kodeki audio:

  • MP3(MPEG-1 Audio Layer 3): max. 2 kanały; zastrzeżony prawnie,
  • AAC: max. 48 kanałów; zastrzeżony prawnie; obsługuje profile; głównie Apple, Flash
  • Vorbis: otwarty; dowolna liczba kanałów; obsługiwany przez wszystkie Linuksy
Kliknij aby pobawić się kontrolkami wideo i dźwięku w HTML5.

Kliknij aby pobawić się kontrolkami wideo i dźwięku w HTML5.

Kodeki wideo:

  • H.264(MPEG-4 part 10, MPEG-4 AVC): zastrzeżony prawnie; obsługuje profile Baseline (np. iPhone), Main i High; Blu-ray; dobre wsparcie sprzętowe,
  • Theora: otwarty; obsługiwany przez wszystkie Linuksy,
  • VP8: otwarty (Google).

Plik z filmem to tzw. kontener zawierający w sobie zarówno dane audio jak i wideo. W Internecie najpopularniejsze kontenery to:

  • MPEG-4 (pliki .mp4, .m4v), zamknięty – Safari, Chrome, iPhone, Android
  • Flash Video (pliki .flv) – wszystkie przeglądarki na których jest Flash Player,
  • Ogg (pliki .ogv), otwarty – Firefox, Opera, Chrome
  • WebM (pliki .webm), otwarty – Firefox, Opera, Chrome, w niedalekiej przyszłości wszystkie przeglądarki,
  • AVI (Audio Video Interleave, pliki .avi) – standard Microsoftu.

Niestety jak na razie nie ma takiego kontenera który byłby obsługiwany na pewno przez wszystkie przeglądarki:

  • Firefox, Opera: Ogg Theora/Vorbis, WebM VP8/Vorbis
  • Chrome: Ogg Theora/Vorbis, MP4 H.264/AAC, WebM VP8/Vorbis
  • Safari, urządzenia mobilne, Flash Player, MSIE9: MP4 H.264/AAC.

W rezultacie aby jak najwięcej internautów mogło obejrzeć nasz film, na dzień dzisiejszy warto przygotować 3 wersje wideo:

  • Ogg Theora/Vorbis (do konwersji można użyć Audacity lub HandBrake– ten ostatni ma wersję dla wiersza poleceń, warto pamiętać o włączeniu opcji „Web optimized”),
  • WebM VP8/Vorbis (do konwersji nadaje się np. połączenie narzędzi wiersza poleceń ffmpeg i mkclean),
  • MP4 H.264/AAC (do konwersji można użyć dodatku Firefogg Firefoksa lub narzędzia wiersza poleceń ffmpeg2theora)

Na szczęście znacznik <video> pozwala osadzić na stronie film tak, aby przeglądarka sama mogła sobie wybrać plik jaki obsługuje:

    <video controls width="360" height="240" poster="placeholder.jpg">
      <source src="movie.mp4" type="video/mp4">
      <source src="movie.webm" type="video/webm">
      <source src="movie.ogv" type="video/ogg">
      <object type="application/x-shockwave-flash" width="360" height="240" data="player.swf?file=movie.mp4">
	<param name="movie" value="player.swf?file=movie.mp4">
	<a href="movie.mp4">Download the movie</a>
      </object>
    </video>

Zdecydowanie warto podawać typ MIME w znacznikach <source>, żeby nie okazało się po ściągnięciu pliku że przeglądarka nie umie go obsłużyć. Warto nawet w typie MIME określić dokładniej użyty kodek (w tym profil jeśli kodek obsługuje profile).
Jest ważne, aby niezależnie od tej uwagi serwer WWW wysyłając pliki video opatrywał je właściwym nagłówkiem MIME (brak tego może spowodować problemy na niektórych przeglądarkach).

Plik audio osadzamy tak:

    <audio controls>
      <source src="pliczek.ogg" type="audio/ogg">
      <source src="pliczek.mp3" type="audio/mpeg">
      <object type="application/x-shockwave-flash" data="player.swf?soundFile=pliczek.mp3">
	<param name="movie" value="player.swf?soundFile=pliczek.mp3">
	<a href="pliczek.mp3">Download the song</a>
      </object>
    </audio>

Zarówno w znaczniku <video> jak i <audio> możemy nie dodawać atrybutu controls, co spowoduje że przeglądarka nie doda domyślnych przycisków nawigacyjnych. Można je utworzyć we własnym zakresie używając arkuszy stylu CSS i JavaScriptu do obsługi pauzy, odtwarzania, przewijania itp.

6.3. CSS3

Pierwsza wersja CSS definiowała ok. tuzina własności, dziś są już ich setki. Standardy CSS1 i CSS2 są w pełni wspierane przez wszystkie popularne przeglądarki WWW. Póki co nie ma edytorów wizualnych dla CSS3 (dla poprzedniej wersji standardu istnieją edytory m.in. w Adobe Dreamweaver i MS Expression Web).

CSS3 oferuje następujące nowinki:

  • cienie na tekście i prostokątach:
        <p style="text-shadow: 5px 5px 5px #999; font-size: 2pc;">Jasio</p>
  • zaokrąglone rogi obramowań,
  • przezroczystość,
  • wielokolumnowy rozkład treści (jak w gazetach),
  • można użyć na stronie niestandardowe czcionki z plików *.ttf (TrueType) lub *.otf(OpenType),
  • kolory oprócz RGB można również definiować w standardzie HSL (Hue, Saturation, Lightness), np. hsl(0%,100%,50%), a także RGBA i HSLA (A oznacza kanał alpha); dostępne są gradienty (liniowe i radialne),
  • jednoczesne używanie wielu obrazków dla tła,
  • animacje: przejścia (np. blaknięcie, zmiana koloru) i transformacje (np. pozycja na ekranie) – do tej pory osiągalne z poziomu JavaScriptu,
  • nowe selektory pozwalają precyzyjniej wskazać elementy poddawane obróbce przez styl.

Przykład użycia własnej czcionki (dla MSIE trzeba definiować czcionkę w plikach *.eot):

    @font-face {
      font-family: 'BlackJar';
      src: url('BLACKJAR.ttf') format('truetype');
      src: url('BLACKJAR.eot')
    }

Poniższy kawałek kodu HTML załącza plik CSS pod warunkiem że max. rozdzielczość ekranu internauty wynosi 320px:

    <link rel="stylesheet" type="text/css" media="(max-device-width: 320px)" href="iphone.css">

Z poziomu CSS możesz teraz kontrolować syntezator mowy, tj. określać głośność, balans, akcent itp.

Selectors API pozwala używać selektorów CSS3 w JavaScripcie do wyszukiwania wierzchołków drzewa DOM oraz testowania czy dany wierzchołek pasuje do selektora.

    // pierwsze wystąpienie którejkolwiek reguły
    var elemList = querySelector('rule', 'rule2', ...);

    // wszystkie wystąpienia którejkolwiek reguły
    var elemList2 = querySelectorALl('rule', 'rule2', ...);

Geolocation API

Geolocation API pozwala z poziomu JavaScriptu ustalić gdzie znajduje się internauta i udostępnić tę informację zaufanym osobom. Należy podkreślić, że przeglądarka nie może pobrać informacji o lokalizacji bez wyraźnej zgody użytkownika który określa dla jakiej domeny chce tą informację udostępnić i (opcjonalnie) czy wybór ma być zapamiętany dla tej domeny. Okienko dialogowe wyświetlane jest przez przeglądarkę gdy kod JavaScriptu usiłuje skorzystać z Geolocation API po raz pierwszy dla danej domeny.

Kliknij, żeby dać się namierzyć

Kliknij, żeby dać się namierzyć

Lokalizację internauty można uzyskać na przynajmniej 3 różne sposoby, z różną dokładnością:

  • na podstawie adresu IP klienta– bardzo mała dokładność, w praktyce miasto dostawcy internetowego; wystarcza do spersonalizowania cen towaru w witrynie sklepu w zależności od kraju/województwa),
  • na podstawie pomiaru siły sygnału BTSów w pobliżu(triangulacja) – pozwala ustalić lokalizację z dokładnością do kilkuset metrów; można wykorzystać do pokazania hoteli/kin/restauracji w pobliżu itp.
  • na podstawie wbudowanego w urządzenie GPSa – duża dokładność rzędu paru metrów, pozwala na naprowadzanie użytkownika komunikatami typu „za 5 metrów skręć w lewo”.

Kod JavaScriptu musi być przygotowany na taką ewentualność, że może uzyskać uprawnienie do lokalizacji z małą dokładnością i nie dostać uprawnień dla dużej dokładności.

  navigator.geolocation.getCurrentPosition( 
    function( position ) { alert( position.coords.latitude ); }, 
    error_callback, 
    { enableHighAccuracy: true}
  );

Oprócz współrzędnych geograficznych API daje dostęp do dokładności, prędkości poruszania się użytkownika, kierunku ruchu, czasu wykonania pomiaru.

Gdy chcemy śledzić użytkownika i dostawać informację o każdej zmianie lokalizacji, należy zamiast getCurrentPosition użyć watchPosition (takie same parametry). Ta funkcja zwraca identyfikator, który można użyć w wywołaniu clearWatch() aby zakończyć śledzenie.

Geolocation API HTML5 nie jest niestety powszechnie obsługiwanym standardem. Inne urządzenia (BlackBerry, Nokia, Palm itp.) oraz biblioteki/aplikacje (Google Gears, Adobe AIR) oferują inne API dla tej samej funkcjonalności. Biblioteka JavaScriptu geo.js jest wrapperem ktory ukrywa różne implementacje geolokacji udostępniając API W3C.

Dane aplikacji WWW na dysku klienta

Do niedawna jedyną formą przechowywania po stronie klienta danych przeżywających restart przeglądarki były ciasteczka (ang cookies). Ich wady to konieczność ciągłego (nieszyfrowanego) przesyłania do serwera nawet gdy nie jest to potrzebne i poważne ograniczenia w ilości (do 20 na domenę) i objętości danych (do 4KB na ciasteczko).

Rozmaite alternatywy starające się odnieść do tych wad to m.in.:

  • DHTML Behaviorsw MSIE – XML do 64KB na domenę (640KB dla domeny zaufanej),
  • Local Shared Objectswe Flashu (znane też jako „Flash cookies”) – do 100KB per domena z możliwością powiększenia za zgodą użytkownika,
  • Google Gears – baza danych SQLite dostępna z przeglądarki.

Twórcy HTML5 dostrzegli problem i wymyślili szereg rozwiązań na różne okazje.

Web Storage

WebStorage (znany też pod nazwą DOM Storage) to implementowana już przez wszystkie liczące się przeglądarki realizacja pamięci trwałej po stronie klienta, w postaci słownika łańcuch -> łańcuch, skojarzonej z domeną z której ściągnięto stronę HTML (a więc kod JS jednej witryny nie może modyfikować słowników innych witryn). Słownik nie jest przesyłany do serwera jak cookies, a dane nie są na szyfrowane na dysku klienta – każdy kto ma dostęp do przeglądarki może użyć konsoli JavaScript lub rozszerzenia typu Firebug aby oglądać i modyfikować słownik.

Maksymalny rozmiar słownika dla pojedynczej domeny nie jest określony przez specyfikację HTML5, ale w praktyce wynosi ok. 5MB i nie ma możliwości rozszerzenia tej przestrzeni. Przekroczenie limitu kończy się wyjątkiem.

    window.localStorage.
      setItem( 'foo', 'bar' );
      getItem( 'foo' );    // jak nie ma klucza to zwracany jest null
      removeItem( 'foo' ); // dla nieistniejącego klucza nic się nie dzieje
      clear();             // czyści słownik
      length;              // liczba elementów w słowniku
      key(index) -> String // numerujemy od 0

Każda faktyczna zmiana w słowniku pociąga za sobą nie dające się anulować zdarzenie storage na obiekcie window. Zdarzenie jest wysyłane do innych zakładek przeglądarki otwierających strony z tej samej domeny, a niesie ze sobą informacje takie jak zmodyfikowany klucz, oraz stara i nowa wartość.

Oprócz obiektu localStorage mamy również podobny w działaniu sessionStorage, lecz zawartość tego drugiego jest czyszczona w chwili zamknięcia sesji przeglądarki.

Przykłady wykorzystania w praktyce magazynu Web Storage to np.:

  • przechowywanie informacji o sesji,
  • przechowywanie preferencji użytkownika (niektóre frameworki JavaScriptu, np. ExtJS, używają Web Storage do zapamiętywania stanu kontrolek, np. kolejności i szerokości kolumn w tabelce),
  • cache dla danych nie zmieniających się zbyt często, aby zaoszczędzić na komunikacji z serwerem (np. lista krajów i ich walut),
  • przechowywanie zmian w celu późniejszej synchronizacji z serwerem; każde wywołanie AJAX zapisujemy w kolejce obiektu localStorage (przypomina to dziennik transakcji używany w bazie danych); po ponownym nawiązaniu połączenia sieciowego przez przeglądarkę kolejka może być przekazana serwerowi.

Ponieważ nie wszystkie przeglądarki (zwłaszcza te starsze) udostępniają magazyn Web Storage, więc w celu większej przenośności tworzonych przez siebie aplikacji webowych warto skorzystać z biblioteki jStore. Jest to dodatek do jQuery, który realizuje funkcje magazynu localStorage korzystając z innych mechanizmów w razie potrzeby (np. SQLite, Flash Storage, czy wbudowane w MSIE 7). Inny przykład unifikacji, to dojox.storage z biblioteki Dojo.

Web SQL Database

Web SQL Database, dawniej WebDB to mechanizm dostępu do SQLowej bazy danych po stronie przeglądarki (w praktyce jest to SQLite). Nie implementowany obecnie przez MSIE i Firefoksa. Mozilla stanowczo stoi na stanowisku że nigdy WebDB nie zaimplementuje w Firefoksie.

    var db = window.openDatabase( "Ekspert", "1.0" );
    db.transaction( function( tx ) {
      tx.executeSql( "CREATE TABLE IF NOT EXISTS eksperci (id REAL UNIQUE, created_at TEXT, screen_name TEXT)",
	[], successCallback, errorCallback);
    });

    db.transaction( function( tx ) {
      tx.executeSql( "SELECT * FROM eksperci", [], successCallback, errorCallback );
    });

    db.transaction( function( tx ) {
      tx.executeSql( "INSERT INTO eksperci (id, text) VALUES (?, ?)",
	[num, document.querySelector('#todoitem').value] );
    });

IndexedDB

Patrz osobny artykuł.

Offline Web Applications

Kod JS aplikacji ma dostęp do flagi która mówi czy aplikacja działa offline (window.navigator.onLine), jak również do zdarzeń rozsyłanych gdy status połączenia się zmienia (window.ononline, window.onoffline).

HTML5 umożliwia programiście przekazanie przeglądarce zestawienia plików (tekstowy plik manifestu), które powinny być załadowane i przechowywane lokalnie u klienta. Przeglądarka będzie mogła uzyskać dostęp do tych plików nawet wtedy, gdy nie ma połączenia sieciowego z serwerem. Jeśli podczas ładowania strony przeglądarka działa w trybie z połączeniem, sprawdzi plik manifestu przy użyciu serwera. Jeśli plik został zmodyfikowany, przeglądarka znowu spróbuje pobrać wszystkie pliki wyszczególnione w manifeście jako pliki do pobrania. Plik manifestu będzie buforować żądania GET protokołu HTTP, natomiast żądania POST, PUT i DELETE nadal będą kierowane do sieci.

W kodzie HTML każdej strony aplikacji należy odwołać się do pliku manifestu udostępnianego przez serwer WWW z mime type text/cache-manifest:

    <html manifest="/cache.manifest">

Plik manifestu jest zwykłym plikiem tekstowym, podzielonym na trzy sekcje: explicit, fallback i online whitelist, z których pierwsza jest obowiązkowa i domyślna.

  CACHE MANIFEST
  # rev 42
  CACHE:
  /clock.css
  /clock.js
  /clock-face.jpg
  NETWORK:
  /tracking.cgi

W powyższym pliku jest zawarta informacja o 3 plikach wchodzących w skład aplikacji offline (sekcja explicit) i jednym pliku sekcji online whitelist, która wymienia pliki jakie nigdy nie powinny być cacheowane.

Jeśli plik manifestu się nie zmieni, przeglądarka nie dostrzeże zmian w plikach aplikacji. Dlatego po każdej zmianie w którymkolwiek pliku aplikacji należy zmodyfikować plik manifestu (chociażby zmieniając numer wersji w komentarzu). Ponadto, jeśli nie powiedzie się pobranie któregoś z plików wyszczególnionych w manifeście, to tak jak gdyby cały plik manifestu był błędny (przyjęta zostanie poprzednia wersja pliku manifestu, lub – jeśli to była pierwsza wersja – pliki nie będą buforowane).

W sekcji FALLBACK: możesz podać zamienniki zasobów online które mają być użyte dla zasobów których nie wolno ściągać lub nie zostały ściągnięte poprawnie:

  FALLBACK:
  / /offline.html

W powyższym przykładzie mamy zapisaną regułkę która mówi przeglądarce że gdy aplikacja pracuje offline i nie może znaleźć pliku w cache’u (wzorzec ‚/’ oznacza dowolną stronę witryny), wówczas ma wyświetlić stronę /offline.html. Zarówno sekcja network jak i fallback wyszczególniają wzorce plików, a nie konkretne pliki. Możliwe jest zatem określanie w tych sekcjach list całych katalogów lub adresów URL oraz typów plików, takich jak obrazy (np. *.jpg).

Podczas obsługi pliku manifestu przeglądarka generuje szereg zdarzeń na obiekcie window.applicationCache. Są to zdarzenia: downloading (gdy rozpoczęto pobieranie plików wyszczególnionych w manifeście), noupdate (gdy nie ma potrzeby aktualizacji plików bo manifest się nie zmienił), progress (w trakcie pobierania plików), cached (po pobraniu wszystkich plików), oraz error (jeśli coś się nie powiedzie).

Odnośnie mechanizmu Offline Web Applications warto przyjąć do wiadomości kilka porad wdrożeniowych:

  • narzędzia deweloperskie przeglądarek na ogół pozwalają wyświetlić listę plików manifestu wraz ze statusem każdego z nich,
  • mechanizm może znacząco utrudnić debugowanie aplikacji; dobrym pomysłem jest włączenie pliku manifestu tylko wtedy, gdy projekt jest już gotowy do wdrożenia w środowisku produkcyjnym,
  • bardzo ważne jest zadbanie o to, aby sam plik manifestu nie był buforowany przez przeglądarkę (nagłówki HTTP generowane przez serwer przy wysyłaniu pliku); jeśli nie ustawiono nagłówków kontrolujących bufor, przeglądarka ponownie pobierze manifest po kilku godzinach od ostatniej operacji pobierania.

Komunikacja

Cross-Document Messaging

CDM pozwala na bezpieczną komunikację pomiędzy obiektami iframe i oknami przeglądarki nawet wtedy, gdy zawartości komunikujących się kontenerów pochodzą z różnych hostów i wymiana danych w inny sposób jest utrudniona ze względu na zasadę same origin policy. Jest obecny we wszystkich nowszych przeglądarkach (nawet w MSIE 8.0).

Źródłem nazywamy trójkę protokół, host i port, reprezentowaną przez zapis postaci http[s]://host[:port]. Mechanizm sprowadza się do wysłania komunikatu do obiektu window (wywołanie jego metody postMessage), przy czym należy poprawnie określić źródło odbiorcy. Odbiorca otrzymuje zdarzenie (zasada ta sama co w przypadku innych zdarzeń DOM), a jego właściwościami są komunikat (data: na pewno może być łańcuch, w niektórych przeglądarkach np. JSON), źródło nadawcy (origin), od którego zależy obsługa komunikatu. Odbiorca zawsze powinien weryfikować źródło nadawcy, oraz referencja (source) do obiektu window nadawcy.

Przykład: powiedzmy że strona http://portal.example.com/postMessagePortal.html chce osadzić iframe z widgetem o URLu http://chat.example.net/postMessageWidget.html i komunikować się z nim w dwie strony. To są różne domeny, więc zasada same origin policy zasadniczo nie pozwala na coś takiego.

Na stronie nadrzędnej umieszczamy kod:

    window.addEventListener( "message", function( e ) {
      if( e.origin == "http://chat.example.net" ) {
        console.info( "Odebrany komunikat od widgetu: " + e.data );
      }
    }, true );

Na stronie zawartej w ramce z kolei:

    window.addEventListener( "message", function( e ) {
      if( e.origin == "http://portal.example.com" ) {
        console.info( "Odebrany komunikat od strony nadrzędnej: " + e.data );
      }
    }, true );

Teraz strona nadrzędna może wysłać komunikat do widgetu:

    document.getElementById("chat-widget").contentWindow.postMessage( 'komunikat do widgetu', "http://chat.example.net" );

a widget do strony nadrzędnej:

    window.top.postMessage( 'komunikat do strony nadrzędnej', "http://portal.example.com" );

XMLHttpRequest Level 2

Większość przeglądarek od jakiegoś czasu obsługuje już rozszerzoną wersję mechanizmu AJAX. W dużym skrócie:

  • można wykonywać zapytania do serwerów innych niż ten z którego pochodzi bieżąca strona WWW – pozwala to łatwiej tworzyć witryny typu mashup; mechanizm Cross Origin Resource Sharing (CORS) jest przedmiotem osobnego posta,
  • pojawiły się zdarzenia informujące o postępie w transmisji danych z serwerem – pozwala to wyświetlić pasek postępu,
  • przeglądarka może przesyłać z/do serwera również dane binarne (wcześniej tylko tekstowe),
  • pojawiło się udogodnienie do wysyłania formularzy.

Sprawdzenie czy XHR2 jest obsługiwane przez przeglądarkę:

        if( typeof (new XMLHttpRequest()).withCredentials !== undefined ) { ... }

Nowe zdarzenia postępu transmisji

Oprócz starego zdarzenia readystatechange mamy kilka nowych: loadstart, progress, abort, error, load (transmisja zakończyła się powodzeniem) i loadend (transmisja się zakończyła, niekoniecznie powodzeniem), przy czym te nowe zdarzenia na obiekcie XHR dotyczą danych transmitowanych z serwera do przeglądarki, a na obiekcie xhr.upload – w drugą stronę. Zdarzenie progress posiada atrybuty total i loaded na określenie ilości danych do załadowania (nie zawsze dostępne) i już załadowanych.

        xhr.upload.onprogress = function(e) {
          progressBar.value = (e.loaded / e.total) * 100;
        }

Dane binarne

Własność responseType mogliśmy dotychczas ustawić na wartości text (domyślnie) lub document (dla XML). Obecnie doszły dwie dodatkowe wartości: blob i arraybuffer, czyli możemy odebrać odpowiednio dane typu Blob (patrz osobny post) oraz Typed Array (patrz osobny post). Gdy transmisja zakończy się powodzeniem, wynik jest dostępny na własności response obiektu XHR.

Z kolei w przypadku komunikacji w drugą stronę, czyli wysyłania danych na serwer, parametrem metody send oprócz wartości wymienionych wyżej dodatkowych typów, można jeszcze wysłać wartości typu File (czyli tak naprawdę Blob), a także FormData.

Formularze

Typ FormData reprezentuje formularz, a jego obsługa jest prosta:

        var formData = new FormData();
        formData.append( 'username', 'Jan Kowalski' );
        formData.append( 'file', myFile );

Mając gotowy formularz w postaci elementu form w HTMLu, możemy skonstruować i wypełnić obiekt typu FormData jeszcze prościej:

        var formData = new FormData( formHTMLElement );

WebSocket

HTTP jest protokołem zapytanie-odpowiedź z własnymi narzutami na niepotrzebne nagłówki, przez co słabo się nadaje na realizację kanału full-duplex czasu rzeczywistego. Podejmowano różne rozpaczliwe próby rozwiązania problemu – wszystkie słabo skalowalne, nadmiernie obciążające sieć i procesor, wolne, nierzadko podatne na błędy i skomplikowane:

  • Ajax polling,
  • Ajax long-polling: polling wstrzymujący odpowiedź serwera gdy nie ma danych do przesłania,
  • streaming: serwer odsyła odpowiedź ale nie sygnalizuje jej końca, przez co przeglądarka odbiera kolejne „uzupełnienia” będące kolejnymi komunikatami od serwera; problemem są tu serwery proxy po drodze, które nie widząc końca komunikatu mogą zdecydować o jego buforowaniu; rozwiązanie to użycie TLS (SSL) lub powrót do Ajax long-polling przy wykryciu buforujących proxy po drodze; Comet (zwany też Ajax Push, Reverse Ajax, Two-way web, HTTP streaming, HTTP server push) – to zbiorczy termin dla zestawu różnych technik sprowadzających się do tego że długo realizowana odpowiedź na żądanie HTTP z przeglądarki pozwala serwerowi WWW wpychać kolejne dane do klienta.

HTML5 WebSocket definiuje kanał komunikacyjny full-duplex przeznaczony dla sterowanych zdarzeniami aplikacji czasu rzeczywistego. W chwili obecnej implementowany w Chrome 4.0+, Firefox 4.0+ i Safari 5.0+ (nie ma w MSIE i Operze).

Jeśli serwer WWW implementuje standard, wówczas w dowolnym momencie istniejące połączenie HTTP można łatwo przekształcić w połączenie WebSocket. Wystarczy, że przeglądarka wyśle do serwera komunikat HTTP:

    GET /demo HTTP/1.1
    Host: example.com
    Connection: Upgrade
    Sec-WebSocket-Key2: 12998 5 Y3 1 .P00
    Sec-WebSocket-Protocol: sample
    Upgrade: WebSocket
    Sec-WebSocket-Key1: 4@1 46546xW%0l 1 5
    Origin: http://example.com

    [8-byte security key]

Serwer odpowiada:

    HTTP/1.1 101 WebSocket Protocol Handshake
    Upgrade: WebSocket
    Connection: Upgrade
    WebSocket-Origin: http://example.com
    WebSocket-Location: ws://example.com/demo
    WebSocket-Protocol: sample

    [16-byte hash response]

Od tej pory komunikaty mogą być wymieniane asynchronicznie w obie strony. Każdy komunikat jest zwykłym łańcuchem UTF-8 poprzedzonym bajtem 0x00 i zakończonym bajtem 0xFF.

Rozważmy zyski. Polling HTTP co sekundę wymaga na same nagłówki ok. 1KB, co w przypadku 1000 klientów wymaga przepustowości 8Mbps, dla 10.000 klientów 80Mbps, a dla 100.000 klientów 800Mbps. Komunikat WebSocket nakłada tylko 2 bajty narzutu, co oznacza odpowiednio 0.015Mbps, 0.153Mbps i 1.526Mbps. Szacuje się, że WebSocket w porównaniu z pollingiem HTTP redukuje obciążenie sieci do 500 razy, a opóźnienie do 3 razy. Klienty mogą nawiązywać połączenia WebSocket z dowolnymi domenami, to serwer decyduje które klienty mogą się z nim połączyć.

Istnieją już implementacje serwerów WebSocket, m.in.:

Uwaga: protokół WebSocket ulega znacznym modyfikacjom w czasie, więc powyższe informacje (zwłaszcza niskopoziomowe) są tylko poglądowe. Jeśli chcesz zaimplementować własny serwer (co wcale nie jest trudne), zajrzyj do aktualnej oficjalnej specyfikacji protokołu przypominającej dokument RFC.

Aby sprawdzić czy przeglądarka obsługuje standard WebSocket:

    if( window.WebSocket ) { ... }

Aby zestawić połączenie WebSocket wystarczy podać URL, przy czym można się łączyć do innego serwera niż serwer WWW z którego załadowano stronę HTML:

    w = new WebSocket( "ws://localhost:8080/echo" );

(protokół ws oznacza WebSocket, a wss oznaczałby secure WebSocket).
Teraz wystarczy zarejestrować słuchaczy dla zdarzeń otwarcia i zamknięcia gniazda oraz nadchodzących komunikatów. Do wysyłania komunikatu służy metoda send():

    w.onopen = function() { console.info( "open" ); }
    w.onmessage = function(e) { console.info( d.data ); }
    w.onclose = function() { console.info( "closed" ); }
    ...
    w.send( "Komunikat" );
    ...
    w.close();

Web Workers

Technologia Web Workers pozwala na przetwarzanie w tle, zwykle na osobnych wątkach systemu operacyjnego – co pozwala wykorzystać wielordzeniowe procesory. Obecnie jest implementowana w Chrome 3.0+, Firefox 3.5+, Opera 10.6+ i Safari 4.0+. Nowe wątki nie blokują przeglądarkowego interfejsu użytkownika, a ponieważ mogą się komunikować wyłącznie za pomocą komunikatów (brak pamięci współdzielonej), więc ich użycie jest dużo prostsze niż w wielu innych językach programowania (brak potrzeby stosowania blokad i innych mechanizmów synchronizacji, nie występują zakleszczenia ani warunki wyścigu, można używać istniejących bibliotek bez obawy czy są one bezpieczne pod względem wielowątkowości).
Wątki WebWorkers mają też ograniczenia:

  • nie mają bezpośredniego dostępu do obiektu window i drzewa DOM dokumentu HTML (ale pozwalają korzystać z XHR i technologii WebSocket, jak również obiektów navigator i location, funkcji setTimeout, setInterval i clearTimeout, oraz mechanizmu IndexedDB),
  • są dość ciężkie, więc nie należy uruchamiać ich zbyt wiele; z racji dość długiego czasu tworzenia i sporego zużycia pamięci nadają się do długo trwających zadań,
  • są problemy z debugowaniem takich wątków (debuggery kodu JavaScript na ogół nie mogą uzyskać do nich dostępu w takim zakresie jak do wątku głównego, np. żeby wykonywać kod krokowo).

Aby sprawdzić czy przeglądarka obsługuje Web Workers:

    if( window.Worker ) { ... }

Użycie nowych wątków jest dość proste.
W kodzie JavaScript na stronie HTML wystarczy utworzyć nowy obiekt Worker i wskazać plik z kodem JavaScriptu do wykonania:

    worker = new Worker("myWorker.js");

(wątek może również tworzyć wątki potomne, w dokładnie ten sam sposób). Każdy wątek roboczy utrzymuje niezależną pętlę zdarzeń. Aby wysłać do wątku komunikat (wspólną bazą obsługiwaną przez wszystkie przeglądarki są łańcuchy, liczby i wartości logiczne – dobrą praktyką jest kodowanie wszystkich danych w formacie JSON), wystarczy napisać:

    worker.postMessage( "Here's a message for you" );

Z kolei chcąc odbierać komunikaty i błędy od wątku, należy zarejestrować słuchaczy:

    worker.onmessage = function(e) { ... };
    worker.onerror = function(e) { console.log( e.message ); };

Komunikat błędu jest wysyłany gdy w wątku poleci nieobsługiwany wyjątek.
Analogiczny interfejs służy do komunikacji kodu wątku z kodem strony głównej (tutaj wątek po prostu odsyła komunikat z powrotem):

  function messageHandler(e) {
    postMessage( "worker says: " + e.data + " too" );
  }
  addEventListener( "message", messageHandler, true );

Ten kto uruchomił wątek, może też go zatrzymać:

    worker.terminate();

Kod wątku ma dostęp do obiektu self (obiekt wątku) oraz metod importScripts (blokująca, pozwala załadować biblioteki JavaScript w określonej kolejności) i close() (kończy pracę wątku).
Aby ułatwić sobie pracę z wątkami, warto skorzystać z dodatkowych bibliotek takich jak jQuery Hive.

Przyszłość

Quake II w przeglądarce (WebGL)

Quake II w przeglądarce (WebGL)

Pewne planowane rozszerzenia HTML znajdują się obecnie w początkowym stadium rozwoju.

WebGL to API do grafiki 3D pomyślane jako integralna część przeglądarki WWW (renderuje do elementu canvas), rozwijane przez tą samą organizację (Khronos Group) która rozwija standard OpenGL. Na witrynie Quake II GWT Port znajduje się projekt pozwalający uruchomić Quake II w przeglądarce Google Chrome i Safari. Tutorial.

Znacznik <device> miałby (za pozwoleniem użytkownika) dawać aplikacjom WWW dostęp do urządzeń na komputerze klienta (kamerka internetowa do konferencji wideo, mikrofon, pendrive).

Audio Data API. Programowanie danych audio (możliwość nagrywania i edycji dźwięku) uczyniłoby dla znacznika <audio> to co <canvas> zrobił dla <img>. Obecnie pewne kroki w tym kierunku wykonuje Mozilla.

Standaryzacja wielodotyku (ang. multitouch), gestów i zmiany orientacji urządzenia mobilnego, obsługiwanych m.in. w przeglądarce iPhone’a.

P2P – komunikacja pomiędzy przeglądarkami bez pośrednictwa serwerów (np. do gier sieciowych, wspólnej pracy, chatu wideo). Krokiem w tym kierunku jest Opera Unite pozwalająca na współdzielenie plików, chatowanie i strumieniowanie mediów.

I na koniec kilka nowych specyfikacji W3C, które być może zostaną zaimplementowane:

  • File API: This specification provides an API for representing file objects in web applications, as well as programmatically selecting them and accessing their data.
  • File API: Writer: This specification defines an API for writing to files from web applications. This API is designed to be used in conjunction with, and depends on definitions in, other APIs and elements on the web platform. Most relevant among these are File API and Web Workers.
  • File API: Directories and System: This specification defines an API to navigate file system hierarchies, and defines a means by which a user agent may expose sandboxed sections of a user’s local filesystem to web applications. It builds on File API: Writer, which in turn built on File API, each adding a different kind of functionality.
  • Messaging API: This specification defines an API that provides access to messaging functionality in the device, including SMS, MMS and email.
  • The Contacts API: This specification defines an API that provides access to a user’s unified address book.

Literatura

HTML5, 5.0 out of 5 based on 12 ratings
Share and Enjoy:
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Śledzik
  • Blip
  • Blogger.com
  • Gadu-Gadu Live
  • LinkedIn
  • MySpace
  • Wykop

8 Komentarzy do “HTML5”

  1. procek napisał(a):

    Doskonały artykuł! Niestety na dziś dzień nawet Firefox 4.0 lub nowy Chrome nie interpretują wszystkich znaczników :/

  2. Ola napisał(a):

    To prawda. Ciekawe ile czasu teraz przeglądarkom zajmie dostosowanie do najnowszych wersji, że nie wspomnę o zacofanych użytkownikach.
    Ale zmiany super! Jak najbardziej potrzebne i bardzo ułatwiające i upraszczające kod html.
    A spytam jeszcze, jest już jakaś dobra polska książka, publikacja (poza tą) na temat HTML5 i CSS3?

  3. Piotr Karpiuk napisał(a):

    Na polskim rynku wydawniczym póki co posucha, ale Helion planuje w najbliższym czasie wydać dwie książki na ten temat:
    http://helion.pl/search.cgi?qa=&wsprzed=1&wprzyg=1&szukaj=html5
    Trudno powiedzieć czy warte polecenia.
    Artykuły o HTML5 i CSS3 od jakiegoś czasu pojawiają się w polskich czasopismach (LinuxMagazine, Komputer Expert itp.).
    W księgarniach zagranicznych jest w czym przebierać – artykuł przygotowałem na podstawie książek wymienionych w literaturze na koncu, dostępnych w Amazonie. Ciekawie wygląda też książka „Smashing CSS: Professional Techniques for Modern Layout” Erica Meyera – uznanego autorytetu w świecie CSS.
    Zapewne sporo informacji leży w internecie, ale prawdopodobnie bedzie to wiedza mocno pofragmentowana – proszę poszukać a gdyby znalazł się artykuł pełniejszy lub choćby dodający coś nowego, poprosimy o linka w komentarzu.

  4. procek napisał(a):

    Owszem, moja praca inżynierska, którą broniłem wczoraj 🙂 „Zastosowanie języka XML w budowie systemu CMS” – polecam gorąco 🙂 HTML5 for Webdesigners – jedyna sensowna książka, której i tak nie mogę polecić, bo jest to CTRL+C, CTRL+V ze źródeł sieciowych…

  5. Smuggy napisał(a):

    Świetny artykuł! Powoli przeglądarka internetowa nabiera – jako narzędzie – szerszego znaczenia. Pod kątem programistycznym – wygląda to wszystko ciekawie i poszerza możliwości dzisiejszych aplikacji webowych.

  6. Grzegorz napisał(a):

    Ciekawy artykul, dosc techniczny. Najbardziej zaciekawilo mnie uzywanie Workerow, czyli watkow przez przegladarke. Czyli mamy jakas operacje kosztowna i calosc przepisujemy do pliku o rozszerzeniu js a nastepnie w prosty sposob front end developer uruchamia ten watek.
    Fajne jest tez odbieranie komunikatow od serwera ( czy to sie dzieje za pomoca get lub post?ciekawe czy roboty google beda tez odbierac komunikaty z serwera, co za tym idzie ajaxowe interkatywne stronki beda wyzej pozycjonowane dzieki samej optymalizacji tresci a nie linkom do witryny.

  7. Kshyhoo napisał(a):

    Błędne kodowanie znaków e znacznikach

  8. Bartek napisał(a):

    Wielkie dzięki za to opracowanie!

Zostaw komentarz

XHTML: Możesz użyć następujących tagów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>