Mozilla Hacks: Firefox 4 – nowy parser HTML5

W ramach serii tłumaczeń artykułów z bloga Mozilla Hacks, przedstawiam dzisiaj tłumaczenie artykułu Firefox 4: the HTML5 parser – inline SVG, speed and more. Oryginalny artykuł i jego tłumaczenie dostępne są na warunkach licencji Creative Commons Attribution 3.0 USA.


Autorem wersji oryginalnej tej notki jest Henri Sivonen, zajmujący się nowym parserem HTML5 Firefoksa. Parser HTML jest jednym z najbardziej skomplikowanych i wrażliwych elementów przeglądarki. Steruje procesem przetwarzania kodu źródłowego HTML do stron WWW, dlatego też zmiany w nim wprowadzane są rzadko i muszą być dobrze przetestowane. Podczas gdy większa część silnika Gecko została przebudowana od czasów jego powstania w późnych latach 90., parser był jedną z rzeczy, które pozostały od samego początku niezmienne. Teraz kod ten został zastąpiony nowym, który jest szybszy, zgodny z nowym standardem HTML5 i daje sporo nowych możliwości.

Od jakiegoś czasu prowadziliśmy prace nad zastąpieniem starego parsera HTML w silniku Gecko. Nowy parser został ostatnio domyślnie włączony w trunku, tak więc wystarczy po prostu pobrać conocną kompilację przeglądarki, by wypróbować nowy parser bez potrzeby przełączania żadnych opcji konfiguracyjnych.

Cztery najważniejsze rzeczy, które są związane z nowym parserem HTML5:

  • można korzystać z kodu SVG i MathML bezpośrednio (inline) na stronach HTML5, bez przestrzeni nazw XML
  • przetwarzanie odbywa się poza głównym wątkiem interfejsu użytkownika Firefoksa, zwiększając całkowitą responsywność przeglądarki
  • szybkość zapisu własności innerHTML jest o około 20% większa
  • nowy parser naprawia dziesiątki starych błędów dotyczących przetwarzania.

Obejrzyj democonocnej kompilacji Firefoksa lub innej przeglądarce obsługującej HTML5. Powinno to wyglądać tak:

Co to jest?

Parser HTML5 w Gecko zamienia strumień bajtów w drzewo DOM, zgodnie z algorytmem przetwarzania HTML5.

HTML5 to pierwsza specyfikacja, która szczegółowo określa sposób parsowania HTML. Dotychczasowe specyfikacje nie opisywały, jak przekształcić strumień bajtów w drzewo DOM. Teoretycznie HTML przed HTML5 był określony jako aplikacja SGML. Pociągało to za sobą określony związek między kodem
źródłowym poprawnych dokumentów HTML i drzewem DOM. Jednakże przetwarzanie niepoprawnych dokumentów nie było dobrze określone (a strony WWW w większości składają się z niepoprawnego kodu HTML4), a jednocześnie istnieją konstrukcje SGML, które teoretycznie były częścią HTML, ale nie były implementowane w rzeczywistości przez popularne przeglądarki.

Brak właściwej specyfikacji sprawił, że twórcy przeglądarek musieli samemu dojść do tego, jak traktować nieprawidłowe dokumenty, w razie wątpliwości badając działanie innych przeglądarek o największym udziale w rynku (najpierw Mosaic, potem Netscape, potem IE). Powstało w ten sposób wiele niepisanych reguł, ale także wiele różnic w zachowaniu przeglądarek.

Algorytm przetwarzania HTML5 standaryzuje zachowanie, do którego zbiegają się przeglądarki i inne aplikacje konsumujące HTML. Zgodnie z projektem, algorytm przetwarzania HTML5 jest właściwy do przetwarzania istniejących treści HTML, tak więc aplikacje nie muszą dalej wspierać swoich starych parserów, aby móc wyświetlić stare treści. W conocnych kompilacjach Firefoksa parser HTML5 używany jest dla wszystkich treści typu text/html.

Jak inny jest nowy parser?

Algorytm przetwarzania HTML5 ma dwie główne części: tokenizację i budowanie drzewa. Tokenizacja jest procesem rozdzielania strumienia źródłowego do znaczników, tekstu, komentarzy i atrybutów wewnątrz znaczników. Faza budowania drzewa na bazie znaczników i tekstu pomiędzy nimi buduje drzewo DOM. Algorytm tokenizacji w parserze HTML5 bliższy jest temu, co robi Internet Explorer, niż temu, co robiły dotychczasowe wersje Gecko. IE miał przez długi czas dominację na rynku, przez co witryny były głównie testowane pod kątem prawidłowego działania z tokenizerem IE. Proces budowy drzewa natomiast jest zbliżony do dotychczasowego działania silnika WebKit. Spośród głównych silników przeglądarek przed HTML5, WebKit posiadał najbardziej rozsądne rozwiązanie problemu budowania drzewa.

Ponadto, nowy parser przetwarza strumienie poza głównym wątkiem. Tradycyjnie przeglądarki wykonywały większość zadań w głównym wątku. Radykalne zmiany, takie jak przeniesienie przetwarzania poza główny wątek, uprościły kod parsera HTML5 w porównaniu do starego parsera HTML Gecko.

Co nowego dla twórców witryn?

Zmiany omówione powyżej są interesujące głównie dla programistów przeglądarek. Kluczową cechą parsera HTML5 jest to, że właściwie nie widać, żeby cokolwiek się zmieniło.

Jest jednak jedna duża zmiana istotna dla twórców witryn: kod MathML i SVG bezpośrednio w dokumentach HTML5. Nowy sposób przetwarzania HTML5 uwalnia MathML i SVG od XML-a i udostępnia je w głównym formacie sieci WWW.

Oznacza to, że można osadzać złożone typograficznie wyrażenia matematyczne w dokumentach HTML, bez potrzeby przepisywania całego dokumentu do XHTML, jak też, co ważniejsze, bez potrzeby modyfikacji oprogramowania budującego witrynę do zwracania prawidłowo sformowanego kodu XHTML. Na przykład, aby osadzić w kodzie HTML wzór na rozwiązanie równania kwadratowego, wystarczy tylko poniższy kod:

<math>
  <mi>x</mi>
 
  <mo>=</mo>
  <mfrac>
    <mrow>
      <mo>&minus;</mo>
      <mi>b</mi>
      <mo>&PlusMinus;</mo>
      <msqrt>
        <msup>
 
          <mi>b</mi>
          <mn>2</mn>
        </msup>
        <mo>&minus;</mo>
        <mn>4</mn>
        <mo>&InvisibleTimes;</mo>
        <mi>a</mi>
 
        <mo>&InvisibleTimes;</mo>
        <mi>c</mi>
      </msqrt>
    </mrow>
    <mrow>
      <mn>2</mn>
      <mo>&InvisibleTimes;</mo>
      <mi>a</mi>
 
    </mrow>
  </mfrac>
</math>

W podobny sposób można osadzić skalowalną grafikę SVG – bez przepisywania HTML-a do XHTML-a. Podczas gdy rozmiary ekranów i rozdzielczości stają się coraz bardziej zróżnicowane, coraz większą wagę przywiązuje się do jakości grafiki przy różnych stopniach powiększenia. Wprawdzie dotychczas można było używać grafiki SVG w dokumentach HTML przez referencję (używając elementu object), wstawianie SVG bezpośrednio jest w niektórych przypadkach wygodniejsze. Na przykład ikona ostrzeżenia może być teraz osadzona bezpośrednio, a nie ładowana z zewnętrznego pliku.

<svg height=86 width=90 viewBox='5 9 90 86' style='float: right;'>
  <path stroke=#F53F0C stroke-width=10 fill=#F5C60C stroke-linejoin=round d='M 10,90 L 90,90 L 50,14 Z'/>
  <line stroke=black stroke-width=10 stroke-linecap=round x1=50 x2=50 y1=45 y2=75 />
</svg>

Wystarczy utworzyć stronę zaczynającą się od <!DOCTYPE html> i wstawić do niej dwa powyższe fragmenty, a będzie to działać w nowych nocnych kompilacjach Firefoksa.

Ogólnie, jeśli mamy kod MathML czy SVG jako XML, wystarczy po prostu wkleić kod XML bezpośrednio do HTML-a (pomijając, jeśli istnieją, deklarację XML oraz doctype). Dwa zastrzeżenia: kod nie może stosować przedrostków przestrzeni nazw dla elementów (tak więc żadnych svg:svg ani math:math), a przedrostkiem przestrzeni nazw XLink musi być xlink.

W powyższych fragmentach MathML i SVG uważna osoba dostrzeże, że bezpośrednio osadzane fragmenty MathML i SVG są bardziej podobne do HTML i prostsze niż po prostu wklekony w to miejsce XML. Nie ma deklaracji przestrzeni nazw, a niepotrzebne cudzysłowy wokół wartości atrybutów zostały pominięte. Działa to, ponieważ znaczniki są tokenizowane przez tokenizer HTML5, a nie przez tokenizer XML. Pomijanie deklaracji przestrzeni nazw działa, ponieważ proces budowania drzewa nie używa atrybutów wyglądających jak deklaracje przestrzeni nazw do przypisania elementom “MathML-owatości” czy “SVG-owatości”. Zamiast tego <svg> rozpoczyna zasięg elementów, którym przypisana będzie przestrzeń nazw SVG w DOM, a <math> rozpoczyna zasięg elementów, którym w DOM przypisana będzie przestrzeń nazw MathML. W przykładzie MathML widać także, że stosowane są odwołania do encji nazwanych, które wcześniej nie były obsługiwane w HTML.

Poniżej krótkie podsumowanie przetwarzania MathML i SVG bezpośrednio w dokumentach HTML dla twórców witryn:

  • <svg></svg> przypisany jest do przestrzeni nazw SVG w DOM.
  • <math></math> przypisany jest do przestrzeni nazw MathML w DOM.
  • foreignObject oraz annotation-xml (na różnych mniej istotnych elementach) rozpoczyna zagnieżdżony zasięg HTML, tak więc można zagnieżdżać SVG, MathML i HTML w sposób, jakiego można oczekiwać.
  • Parser poprawia wielkość znaków w znakowaniu, tak więc <SVG VIEWBOX=’0 0 10 10′> działa w kodzie HTML.
  • Metody DOM i selektory CSS rozróżniają wielkość znaków, należy więc pisać wywołania DOM oraz selektory CSS z użyciem kanonicznej wielkości znaków, czyli tzw. camelCase w przypadku różnych części SVG, takich jak viewBox.
  • Składnia <foo/> otwiera i natychmiast zamyka element foo, jeśli jest to element MathML lub SVG (ale nie element HTML).
  • Tokenizacja atrybutów przebiega w taki sam sposób, jak w HTML, tak więc można pomijać cudzysłowy w sytuacjach, w których można byłoby je pominąć w HTML (tj. kiedy wartość atrybutu nie jest pusta oraz nie zawiera białych znaków, ", ', `, <, = ani >).
  • Uwaga: dwie powyższe cechy nie współgrają ze sobą dobrze z przyczyn zachowania zgodności z tokenizacją starego HTML-a. Jeśli cudzysłowy zostaną pominięte przy wartości ostatniego atrybutu, konieczne jest wstawienie spacji przed zamykającym ukośnikiem. Tak więc prawidłowy jest kod: <circle fill=green />, ale nieprawidłowy jest: <circle fill=red/>.
  • Atrybuty zaczynające się od xmlns nie mają absolutnie żadnych skutków, nie wpływają na obecność elementów ani atrybutów w danej przestrzeni nazw, tak więc nie ma potrzeby ich stosowania.
  • Atrybuty w przestrzeni nazw XLink muszą stosować przedrostek xlink (np. xlink:href).
  • Nazwy elementów nie mogą zawierać przedrostków ani dwukropków.
  • Zawartość elementów script w SVG tokenizowana jest tak, jak w XML – nie jak zawartość elementów script w HTML.
  • Kiedy element SVG lub MathML jest otwarty, sekcje <![CDATA[]]> działają tak, jak w XML. Można to wykorzystać do ukrycia treści tekstowych przed starszymi przeglądarkami nie obsługującymi SVG ani MathML w text/html.
  • Encje nazwane MathML dostępne są w całym dokumencie (także w treści HTML).
  • Aby zapewnić działanie stron, na których autorzy umieścili fragmenty SVG w HTML (nie wiadomo, po co) lub użyli znacznika <math> do celów niezwiązanych z MathML, próby zagnieżdżenia różnych popularnych elementów HTML jako elementów potomnych SVG (bez użycia foreignObject) spowodują natychmiastowe wyjście z kontekstu SVG lub MathML. Może to sprawić, że literówki będą miały zaskakujące efekty.

Mozilla Hacks: API selektorów w DOM w Firefoksie 3.5

W ramach serii tłumaczeń artykułów z bloga Mozilla Hacks, przedstawiam dzisiaj tłumaczenie artykułu DOM Selectors API in Firefox 3.5 autorstwa Johna Resiga. Oryginalny artykuł i jego tłumaczenie dostępne są na warunkach licencji Creative Commons Attribution 3.0 USA.

API selektorów w DOM w Firefoksie 3.5

Specyfikacja Selectors API, rekomendacja W3C, to nowe rozwiązanie pozwalające programistom JavaScriptu odnajdywać elementy drzewa DOM strony przy użyciu selektorów CSS. To pojedyncze API pozwala na przeszukiwanie drzewa DOM i odnajdywanie jego elementów przy użyciu prostego, ujednoliconego interfejsu.

API selektorów jest jednym z lepiej obsługiwanych przez wszystkie przeglądarki nowych standardów: można z niego korzystać już dziś w Internet Explorerze 8, Chrome, Safari, Firefoksie 3.5 i wkrótce w Operze 10.

Korzystanie z querySelectorAll

Selectors API zawiera dwie metody dostępne na wszystkich dokumentach, elementach i fragmentach DOM: querySelector i querySelectorAll. Metody te działają prawie identycznie – obie przyjmują jako argument selektor CSS i zwracają pasujące do niego elementy DOM (z tą różnica, że querySelector zwraca tylko pierwszy pasujący element).

Na przykład, mając dany poniższy fragment kodu HTML:

<div id="id" class="class">
    <p>Pierwszy akapit.</p>

    <p>Drugi akapit.</p>
</div>

możemy wykorzystać querySelectorAll do ustawienia czerwonego koloru tła wszystkich akapitów leżących wewnątrz diva o ID równym „id”:

var p = document.querySelectorAll("#id p");

for ( var i = 0; i < p.length; i++ ) {

    p[i].style.backgroundColor = "red";
}

Możemy też odnaleźć pierwszy akapit diva o klasie „class” i ustawić jego nazwę klasy na „first”.

document.querySelector("div.class > p:first-child")
    .className = "first";

Dotychczas, bez użycia Selectors API, tego rodzaju przeszukiwanie wymagałoby napisania długiego kodu JavaScript/DOM, złożonego z wielu linii i wielu zapytań.

O ile metody Selectors API są relatywnie proste w użyciu (pobierają tylko jeden argument), o tyle bardziej problematyczną sprawą jest dobór selektorów CSS. API selektorów korzysta z selektorów CSS natywnie obsługiwanych przez przeglądarkę do stylowania elementów przy użyciu CSS. W większości przeglądarek (Firefoksa, Safari, Chrome i Opery) oznacza to, że możemy w pełni korzystać z selektorów CSS 3. Internet Explorer 8 obsługuje bardziej ograniczony podzbiór selektorów, włączając w to selektory CSS 2 (które i tak są bardzo przydatne).

Największym wyzwaniem dla nowych użytkowników API selektorów jest więc określenie, które selektory CSS są odpowiednie do odnalezienia pożądanych elementów – szczególnie, że większość programistów piszących kod działający w wielu przeglądarkach ma doświadczenie głównie z ograniczonym podzbiorem w pełni działających selektorów CSS 1.

Dobrze jest zacząć od specyfikacji selektorów CSS 2 i CSS 3, ale warto też przejrzeć poniższe artykuły, by dowiedzieć się więcej (w języku angielskim – przyp. tłum.):

Implementacje w bibliotekach

Najciekawszy przypadek użycia API selektorów to nie tyle ich bezpośrednie stosowanie przez programistów WWW, ale ich wykorzystanie w bibliotekach, które już teraz dostarczają funkcjonalność selektorów CSS w DOM. Istotnym dziś problemem w szerszym stosowaniu API selektorów jest fakt, że nie są one dostępne we wszystkich przeglądarkach, dla których tworzy się obecnie strony (w tym IE 6, IE 7 i Firefox 3). Dlatego też, dopóki starsze przeglądarki są w użyciu, musimy korzystać z narzędzia pośredniczącego, aby odtworzyć zachowanie selektorów CSS w DOM.

Na szczęście w wielu istniejących bibliotekach jest dostępne API zgodne z Selectors API (w rzeczywistości Selectors API zostało w dużej mierze zainspirowane przez istniejące biblioteki). Co więcej, wiele z tych implementacji używa wewnętrznie właśnie Selectors API. Oznacza to, że można stosować selektory CSS w DOM w wielu przeglądarkach już teraz, zapewniając większą wydajność w nowych przeglądarkach obsługujących Selectors API, bez nadmiernego wysiłku.

Oto niektóre z istniejących implementacji, które korzystają z Selectors API, o ile to możliwe:

Warto jeszcze raz podkreślić duży skok w wydajności, jaki powoduje korzystanie z nowego API (w porównaniu z tradycyną mieszanką DOM i JabaScriptu, stosowaną do tej pory). Różnicę tę widać na przykład we wzroście wydajności bibliotek javascriptowych, odkąd zaimplementowały one Selectors API.

Ostatnio wykonane testy przyniosły następujące wyniki:

Widać tu dramatyczny wzrost wydajności po zaimplementowaniu natywnego API selektorów w bibliotekach – całkiem możliwe, że podobny wzrost wydajności zobaczysz także w swoich aplikacjach.

Zestaw testów

Razem ze specyfikacją Selectors API przygotowany został zbiór testów Selectors API, jego autorem jest John Resig z Mozilli. Ten zbiór testów pozwala określić jakość implementacji API selektorów w głównych przeglądarkach.

Aktualne wyniki (w momencie pisania oryginalnego artykułu – przyp. tłum.) dla przeglądarek obsługujących nowe API:

  • Firefox 3.5: 99.3%
  • Safari 4: 99.3%
  • Chrome 2: 99.3%
  • Opera 10b1: 97.5%
  • Internet Explorer 8: 47.4%

Internet Explorer 8, jak wspomniano wcześniej, nie obsługuje większości selektorów CSS 3, dlatego nie przechodzi większości powiązanych testów.

Selectors API pozwala na proste i szybkie odnajdywanie elementów DOM strony. Już teraz przynosi ono pożytek osobom korzystającym z bibliotek javascriptowych zapewniających podobną funkcjonalność, dlatego też zachęcamy do wypróbowania nowego API już teraz.

Mozilla in Poland: EPIC WIN! ;-)

For the first time since the late nineties, Microsoft Internet Explorer is no longer the most popular web browser in Poland. Mozilla Firefox scores the highest marketshare percentage ever, 45.3%, leaving MSIE behind by 0,3 percentage points.

All the Gecko-based browsers amount to 45.5% of the marketshare, Opera is at 8% and growing. WebKit-based browsers like Chrome and Safari grouped with KHTML-based Konqueror are only at 0.3%.

We did it! We broke the Microsoft monopoly! Big thanks to all the people who have supported Mozilla in Poland, starting with Marcin Jagodziński, the first man to translate Mozilla into Polish, Piotr Bartecki and Marek “GmbH” Wawoczny for everything they did at MozillaPL.org, and to all of my friends at Aviary.pl. We would not be here without all your work! I also personally would like to thank the Mozilla Europe team for supporting the Polish team.

To our great community – MozillaPL.org forum members, Polish extension developers,  contributors to the alt.pl.mozilla newsgroup, and to all the Polish web developers who supported web standards and Gecko even in the days of 1% marketshare, to all of you – THANK YOU!!!

History happens!


mozillaepicwin


Po raz pierwszy od lat dziewięćdziesiątych Microsoft Internet Explorer nie jest już liderem rynku przeglądarek internetowych w Polsce. Mozilla Firefox uzyskuje najwyższy wynik w historii – 45,3%, wyprzedzając MSIE o 0,3 pkt proc.

Wszystkie przeglądarki oparte na silniku Gecko mają łącznie 45,5%, a Opera osiągnęła poziom 8% i nie przestaje rosnąć. Przeglądarki oparte na silniku WebKit, takie jak Chrome i Safari, łącznie z opartym na KHTML Konquerorze mają łącznie 0,3%.

Udało się! Przełamaliśmy monopol Microsoftu! W tym miejscu chciałbym podziękować wszystkim, którzy wspierali Mozillę w Polsce, zaczynając od Marcina Jagodzińskiego, który rozpoczął polską lokalizację Mozilli, przez Piotra Barteckiego i Marka “GmbH” Wawocznego (za wszystko, co zrobiliście w MozillaPL.org) po moich przyjaciół z Aviary.pl. Bez Waszego oddania nie byłoby to możliwe. Dziękuję także stowarzyszeniu Mozilla Europe za wsparcie, jakiego udziela polskiemu zespołowi.

Naszej wspaniałej społeczności – użytkownikom forum MozillaPL.org, twórcom polskich rozszerzeń, uczestnikom dyskusji na alt.pl.mozilla, a także tym wszystkim web developerom w Polsce, którzy przestrzegali standardów WWW i wspierali Gecko nawet w najbiedniejszych dniach jednoprocentowego udziału w rynku, Wam wszystkim – WIELKIE DZIĘKI!!!

Tak oto dzieje się historia. :)

PS. Na ten temat po polsku pisze dziś także Hubert.

Przełom nadchodzi? :)

W najnowszym rankingu GemiusTraffic MSIE wyprzedza przeglądarki oparte na Gecko tylko o 0,9 punkta procentowego:

obrazek-11

Firefox we wszystkich wersjach ma łącznie 44,7% (sam Firefox 3: 38.4%), Opera – 7,7%, wszystkie WebKitopodobne – 1,2% (z tego większość ma Chrome – 0,8%). MSIE 7 nieco wyprzedza swojego starszego brata – o 0,8 pkt proc. (23,3% do 22,5%).

Czy w przyszłym tygodniu IE zasłużenie utraci prowadzenie? Zobaczymy. Fajnie by było. :-)

Sześć…

Tylko 6 (słownie: sześć) punktów procentowych w najnowszym rankingu Gemiusa dzieli przeglądarki oparte na silniku Gecko (Mozilla) od przeglądarek opartych na silniku Trident (Microsoft/Windows Internet Explorer) – 42,7% polskich użytkowników korzysta z przeglądarek z silnikiem Mozilli (w tym sam Firefox: 42,5%), a z przeglądarki Microsoftu i jej “opakowań” – 48,7%.

Przeglądarkom konkurencyjnym wobec niedawnego monopolisty udział w rynku dość wysoko podskoczył – o ponad trzy punkty procentowe w przypadku Firefoksa i o 0,4 pkt. procentowego w przypadku norweskiej przeglądarki. Przyczyn można się dopatrywać w odkrytej niedawno poważnej luce w zabezpieczeniach produktu Microsoftu, choć głośniej o niej zrobiło się dopiero pod koniec okresu, którego dotyczy najnowszy raport GemiusTraffic.

Stoją za to w miejscu przeglądarki oparte na silniku WebKit, takie jak Safari i Google Chrome, które łącznie w polskim rynku do kupy z linuksowym Konquerorem nie osiągają nawet procenta użytkowników.

Cieszy to, że już 73% użytkowników Firefoksa korzysta z wersji 3.0.x  (lub testuje 3.1 beta). Wśród użytkowników Firefoksa procentowo najwięcej osób używa jego najnowszej wersji, co znaczy, że, po pierwsze, system aktualizacji działa całkiem nieźle, a po drugie, samo przejście na 3.0.x nie stanowi większego problemu. Odsetek użytkowników najnowszych wersji w przypadku IE i Opery jest znacząco niższy, odpowiednio ok. 50% i 51%.

PS. Osobom używającym wersji 2.0.0.x Firefoksa przypominam, że wsparcie dla niej skończy się dziś wieczorem (wydaniem niespodziewanej wersji 2.0.0.20), dlatego naprawdę warto poczynić kroki ku migracji do “trójki” – dla bezpieczeństwa, ale też i wygody. :)