Tarayıcıların Nasıl Çalıştığı Hakkında Konuşacağız!
Günümüzde masaüstümüzde kullandığımız beş büyük tarayıcı mevcut: Chrome, Internet Explorer, Firefox, Safari ve Opera. Mobil cihazlarda,
temel başlıca tarayıcılar Android Tarayıcı, iPhone, Opera Mini ve Opera Mobile, UC Tarayıcı,
Nokia S40 / S60 ve Chrome'dur. Opera temelli tarayıcılar hariç tümü WebKit'i temel almaktadır. Açık kaynak tarayıcılardan örnekler vereceğim
Firefox ve Chrome ve Safari (neredeyse açık kaynaklıdırlar). StatCounter Verilerine bakıldığında (Haziran 2013'e göre)
Chrome, Firefox ve Safari 71% oranında küresel kullanımı bünyelerinde barındırmakta. Mobil cihazlara bakıldığında ise Android
Tarayıcı, iPhone ve Chrome genel kullanımın yaklaşık 54%'ü oluşturmaktadır.
Tarayıcının Ana İşlevleri
Bir tarayıcının ana işlevi web sayfasından ve tarayıcı sunucusundan istediğiniz web kaynaklamalarını kişiye göstermektir. Bu
kaynak genellikle herhangi bir HTML Dökümanı, belki bir PDF Dosyası, resim veya yazısal bir içerik olabilir.
Kaynağın belirli konumu kişi tarafından bir URI (Tekdüzen kaynak tanımlayıcısı) kullanılarak gösterilir. Tarayıcının herhangi bir HTML dosyasını görüntüleme ve listeleme şekli HTML ve CSS özellikleri ile belirtilir. Bu özellikler genel olarak web için standartlar
organizasyonu olan W3C (World Wide Web Consortium) kuruluşu sayesinde belirtilir. Yıllar boyunca tarayıcılar özelliklerin belirli kısımlarına uydular ve kendilerine
ait uzantılarını geliştirmeye devam ettiler. Bugün tarayıcıların az yada çoğu kısmı belirli özelliklere uymaktadır.
Ayrıa tarayıcı arayüzlerinin birbirleri ile birçok ortak noktası bulunmaktadır. Ortak arayüz birimleri içerisinde:
+URI ekleyebilmek için adres çubukları, Geri ve ileri butonları, Yer noktası(imi) ayarları, Hali hazırda devam eden belgelemelerin yüklenmesini
yeniden başlatmak veya durdurmak için yenileme ve durdurabilme düğmeleri, Kullanıyı ana sayfaya götürebilen ana sayfa butonu,
Gariplenecek bir şekilde, sayfaların herhangi bir kullanıcı arayüzü hakkında resmi bir satır yoktur. Yılların tecrübeleri ve birikimlerini taklit etmeye çalışan tarayıcılar ile gelen uygulama bütünleri vardır. HTML5 verileri, bir tarayıcı için herhangi bir UI tanımını belirlemez,
fakat bazı ortaklaşa öğeleri listeler. Bunlar içerisinde adres çubukları, durum çubuğu ve araç çubuğu vardır. Yinede Firefox'un
İndirme Yöneticisi gibi bazı belirli tarayıcı özellikleri mevcut.
Tarayıcının Üst Katman Yapısı
Tarayıcının Ana Kullanım (bileşenleri) şunlardır:
Kullanıcı Arayüzü: Genel olarak adres çubuğunu, geri/ileri düğmesini, yer noktası(imi) seçeneklerini vb. içermektedir. İstediğiniz
sayfayı gördüğünüz pencere dışında tarayıcının her parçası görüntülenir.
Tarayıcı Altyapısı: UI ve tarayıcı işleme altyapısı içerisindeki olay ve işlemler bütününü sıralamaktadır.
Oluşturma Motoru: İstenen döküman veya içeriği kullanıcıya sunma (görüntüleme) görevindedir. Örnek olarak kullanıcı tarafından istenen veri bütünü HTML ise, işlem ve yürütme motoru HTML ve CSS'yi ayrı olarak tanımlar ve ardından ayrılaştırılması tamamlanan içeriği ekranda görüntüler.
Ağ Oluşturma: HTTP Veri ve İstekleri benzeri ağ çağrı ve talepleri, tarayıcıdan farklı bir arayüzün arkasındaki farklı kullanımlar
için farklı ugulumalar işleme alınır.
UI Arka Uç: Griş kutuları ve pencereler benzeri temel widget'ları çizebilmek için kullanılır. Bu uç tanımı, sisteme bağlı olmayan bir
birim sunar. Alt dalında işletim sistemi, kullanıcı birimleri ve benzer yöntemler belirli olarak kullanılmaktadır.
JavaScript Yorumlayıcısı: JavaScript kodunu belirlemek ve yürütebilmek için kullanılmaktadır.
Veri Depolama: Bu katman kalıcılık içermektedir. Tarayının çerezleri gibi her türlü küçük birimi kaydetmesi gerekir. Tarayıcılar ayrıca
localStorage, IndexedDB, WebSQL ve Dosya Sistemi gibi depo içerikleride kullanır.
Chrome ve benzeri tarayıcıların oluşturma motorlarının bir çok veri ve şifrelemeyi hali hazırda çalıştırdığını belirtmek önemlidir. Her
sekme için ayrı bir işlemde çalışmaktadır.
İşleme (Render) Motoru
İşleme (Render) motorunun temel görev ve kullanımı tarayıcının ekranda istediği veriyi görüntülemesidir. Temel işleme motoru HTML ve XML döküman
ve verilerini görüntülemektedir. Ayrıca bu motor eklenti ve diğer uzanntı birimleri sayesinde farklı
verileride görüntüleyebilir. Örnek verecek olursak herhangi bir PDF Görüntüleme eklentisini kullanarak PDF verilerini ve belgelerinin tümünü görüntüleyebiliriz. Aynı zamanda Bu motorun ana kullanımı HTML VE CSS verilerini görüntülemek, görsel veriye dökmektir.
İşleme (Render) Motorları
Birbirinden farklı tarama motorları (tarayıcılar) birbirinden farklı tarama motorları kullanır. Örnek olarak Internet Explorer Trident kullanmaktadır, Firefox
Gecko kullanmaktadır, Safari WebKit kullanmaktadır. Chrome ve Opera (15. sürümü ardından) Webkit'in
küçük bir dalı olan Blink'i kullanmaktadır. WebKit, Linux platformu için kullanılan bir motor olarak piyasada başlayan ve Mac ve Windows'u desteklemek amacıyla Apple tarafından farklılaştırılan açık kaynaklı bir işleme (render) motorudur.
Ana Akış
İşleme altyapısı kullanıcı tarafından talep edilen belge veya veriyi ağ katmanlamasından almaktadır. Bu genel olarak 8kb parça bütünleri
şeklinde yapılmaktadır. Bunun ardından işleme motorunun ana akışı şeklindedir.
İşleme (render) motoru HTML belge ve verilerini birbirinden ayrılaştırmaya devam edecek ve ardından verileri "içerik ağacı" içerisindeki DOM birimi haline
getirmektedir. İşleme (render) motoru CSS dosyalarında bulunan öğeleri farklı style elementlerine çevirir.
HTML'de bulunan görsel belirlemeler ile style elementleri farklı bir veri ağacı oluşturmak için kullanılmaktadır. İşleme (Render) Ağacı, renk, görsel gibi başlıca özelliklere sahip dikdörtgenler içerir. Dikdörtgenler ekranda görüntülenme sırasına göre bir düzen içerisindedir.
İşlem-Render Ağacı temel oluşumunun ardından belirli bir düzen sürecine geçiş yapar. Bunun sayesinde her birim bir kordinat almış olur. Bunun ardındaki
aşamada UI arka uç katmanı çeşitli şekilde boyanacaktır. Bu süreç belirli bir düzen içerisindedir.
Önemli olarak daha iyi bir kullanıcı deneyimini sağlamak için bu işlemler bütününün hızlı ve kullanılır olması önemlidir. HTML veri bütünleri ayrıştırılana
kadar bu işlem için bekleme yapılmaz. Bölümler sırasıyla ayrıştıralacak ardından görüntülenecek ve gelen paket bütünüyle işlem devam edecektir.
Ana Akış Örnekleri
Şekillerden görüleceği gibi WebKit ve Gecko'nun bazı değişik terminaloji kullanmasına karşın, ana akışın benzer veya aynı olduğunu görebiliriz. Gecko, temel olarak
görsel olarak biçimlendirilmiş öğelerin ağacını "çerçeve ağacı"olarak adlandırır. WebKit "Render ağacı"
terimini kullanır ve "render nesneleri"den oluşur. WebKit, öğelerin yerleştirilmesi için "Düzen" terimini kullanır, Gecko ise "yeniden akış"olarak adlandırır. "Ek", webkit'in render ağacını oluşturmak için DOM düğümlerini ve görsel bilgileri bağlama terimidir. Küçük bir şey olamayan
fark Gecko temel olarak HTML ve DOM ağacı içerisinde fazladan herhangi bir katmana daha sahiptir. Buna "İçerik Havuzu" denmektedir ve aynı zamanda DOM elemanlarını yapmak için oluşturucu bir içeriktir. Ana akışın temel her parçası hakkında konuşacağız:
Ayrıştırma-GENEL
Ayrıştırma işlemi genel olarak "işleme (Render) Motoru)'nda önemli bir birimdir. Bundan dolayı daha da derine gidedeğiz. Küçük bir temel ile olaya giriş yapalım. Herhangi bir dökümanı kullanım için ayrıştırabilmek temel olarak kodun kullanılabilir bir yapıya dönüştürülmesine denmektedir. Ayrıştırmanın sonucu genellikle bu belge veya verinin yapısını belirten bir ağaç birikimidir. Genel olarak bu ağaca "ayrıştırma ağacı" veya "sözdizimi ağacı" denmektedir. Örneğin ifade ayrıştırması 2 + 3 - 1 bu ağaca geri dönüş yapabilir.
Temel Prensipler
Temel ayrıştırma belgenin kurallarına uyulan sözdizimine (yazıldığı dil veya da biçim) dayanmaktadır. Ayrıştıracağınız her tür biçimleme kelime bilgisi ve söz dizimi kurallarından oluşmakta, ve temel prensiplere sahip olmalıdır. Ayrıca insanların kullandığı (insan dilleri) bu tür diller içerisine girmez. Bu nedenle ayrıştırılamaz.
Ayrıçtırıcı-Lexer Kombinasyonu
Ayrıştırma genel olarak iki bölüme ayrılır: Sözcük ve Söz Dizimi analizi. Sözcük analizi girişi ve önemli bölümleri ayraçlar ile belirtme bölümüdür. Belirteçler dilin kelime haznesidir. İnsan dili olarak o sözlükte görülen tüm kelimlerden oluşacaktır. Sözdizimi Analizi ise dil genel sözdizimi kurallarına uygun kullanılması ve kurallara uyulmasıdır. Ayrıştırıcılar ise genelde bu işleri iki şekilde bölmektedir: girişi ve önemli kısımları belirteçlere ayıran lexer yapısı ve belgenin veya dökümanın temel yapısını sözdizimi kurallarını baz alarak kontrol eden, ve ayrıştırma ağacını oluşturan ayrıştırıcı. Lexer genel olarak satır sonları, karakter bileşenlerini düzenler.
Ayrıştırma işlemi bir bütün olarak tekrarlamaktadır. Ayrıştırıcı genellikle lexer bütününden belirteç isteyecektir ve bunu sözdizimi ile birleştirmeye çalışacaktır. Bu işlemin tamamlanması durumunda ayrıştırıcı lexer'den yeni bir belirteç ister ve aynı işlemi sürekli devam ettirir. Herhangi bir eşleşme gerçekleşmezse ayrıştıcı dahili olarak depolama yapar ve eşleşme yapana kadar denemeye devam eder. Eğer eşleşme olmamaya devam ederse bu durumda bu hataların olduğunu ve veri ve belgelerin yanlış olduğu anlamına gelmektedir.
Çevirme İşlemi
Çoğu zaman ayrıştırma ağacı ve bütünü son araç ve kullanım değildir. Ayrıştırma bazı zamanlar çeviride de kullanılır. Kullanımın amacı giriş belgesini başka belgelere dönüştürmek, çevirmektir. Buna örnek olarak derlemeyi verebiliriz. Kaynak kodlarını makine kodlamalarına çeviren bir dönüştürücü, derleyici. İlk olarak ayrıştırma yapar ve ardından daha sonra ayrıştırılan ağacı makine kodlamasına (belgesine) çevirir.
Ayrıştırma Örneği
Şekilde matematiksel bir verinin ayrıştırma ağacı gösterilmektedir. Temel bir matematiksel ayrıştırmasını gözlemleyelim.
Kelime Haznesi: Dilimiz tamsayıları, artı işaretleri ve diğer tamlamaları barındırmaktadır.
Sözdizimi (Syntax):
Dilin sözdizimi, yapı taşları, ifadeler, terimler ve temel işlemlerdir. Kullanılan dil herhangi bir ölçek (sayıda) ifade içerebilir. Bir ifade tam olarak bir "terim" ve ardından bir "işlem" ve ardından başka bir terim olarak tanımlanır. Bir işlem ise temelde bir artı belirteci veya eksi belirtecidir. Bir terim; bir tamsayının belirteci veya bir ifadesidir. Eğer girdiyi analiz edersek 2 + 3 - 1. Bir kural ile eşleşme özelliği gösteren ilk dize 2 ifadesidir: kural #5'e göre bir terimdir. İkinci eşleşme sıraya göre ise 2 + 3. Bu ise üçüncü kural ile eşleşmektedir:
bir ifade (terim), ardından bir işlem ve ardından başka bir terim. Bir ardındaki eşleşme ise sadece girişin sonundadır. 2 + 3 - 1 bir ifadedir (terimdir), çünkü 2 + 3'ün bir terim olduğunu hali hazırda gördük, bu yüzden bir terimin ardında başka bir terim onun ardında da bir işlem bulunmakta. 2 + + herhangi bir kural ile eşleşme göstermeyecek ve bu yüzden de geçersiz bir deneme (giriş) olacaktır.
Kelime ve Sözdizimi için Biçimsel Tanımlamalar
Temel prensip (kelime bilgisi) genellikle düzenli ifade edilir. Örnek olarak dilimiz şu şekilde tanımlanacaktır:
Kod:
INTEGER: 0|[1-9][0-9]*[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER]PLUS: +
MINUS: -
Görülen üzerine tam sayılar düzenli olarak ifade edilmektedir. Sözdizimi genel olarak BNF olarak tanımlanmaktadır. Dilimiz şu şekilde tanımlanacaktır:
Kod:
expression := term operation term[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER]operation := PLUS | MINUS
term := INTEGER | expression
Geçerli dil bilgisinin bağlam içermeyen bir dil bilgisi olması durumunda herhangi bir dil düzenli ayrıştırıcılar tarafından ayrıştırılabilir dedik.
Ayrıştırıcı Türleri
Ayrıştırıcılar tür olarak ikiye ayrılmaktadır: yukarıdan aşağıya ayrıştırıcılar, aşağıdan yukarıya ayrıştırıcılar. Yukarıdan aşağı ayrıştırıcıları tanımlayacak olursak
temel görevleri sözdiziminin üst yapısını incelemek, bir eşleşme bulmaya çalışmaktır.
Aşağıdan yukarıya ayrıştırıcılar girişle başlar ve yavaş yavaş, düşük düzey kurallarından başlayarak yüksek düzey kuralları karşılanana kadar sözdizimi kurallarına dönüştürür. İki türe ayrılan ayrıştırıcılarımızın örneğimizi nasıl ayrıştıracağını hep beraber görelim. Yukarıdan aşağı ayrıştırıcılarımız üst düzey kurallama
ve yöntemlerden başlayacaktır. Yukarıdan aşağıya ayrıştırıcı, üst düzey kuraldan başlayacaktır: 2 + 3'ü bir ifade olarak tanımlayacaktır. Daha sonra belirleyecek 2 + 3 - 1 bir ifade olarak (ifadeyi tanımlama süreci gelişir, diğer kuralları eşleştirir, ancak başlangıç noktası en üst düzey kuraldır). Aşağıdan yukarıya ayrıştırıcı, bir kural eşleşene kadar girişi tarar. Daha sonra eşleşen girişi kuralla değiştirir. Bu girişin sonuna kadar devam edecektir. Kısmen eşleşen ifade ayrıştırıcının yığınına yerleştirilir.
Birim Giriş
-Terim 2 + 3 - 1
-Terim İşlemi + 3 - 1
-Anlatım 3 - 1
-Anlatım İşlemi - 1
-Anlatım -
Bu tip aşağıdan yukarıya ayrıştırıcı bir shift-reduce ayrıştırıcı olarak adlandırılır , çünkü giriş sağa kaydırılır (giriş başlangıcında ilk önce işaret eden ve sağa doğru hareket eden bir işaretçi düşünün) ve yavaş yavaş sözdizimi kurallarına indirgenir.
Ayrıştırıcıları Otomatik Olarak Üretim
Bir ayrıştırıcı oluşturabilen araçlar vardır. Onlara dilinizin dilbilgisinikelime dağarcığını ve sözdizimi kurallarını-beslersiniz ve çalışan bir ayrıştırıcı oluştururlar. Bir ayrıştırıcı oluşturma ayrıştırma derin bir anlayış gerektirir ve elle optimize ayrıştırıcı oluşturmak kolay değil, bu yüzden ayrıştırıcı jeneratörler çok yararlı olabilir.
WebKit, iyi bilinen iki ayrıştırıcı jeneratörü kullanır: bir ayrıştırıcı oluşturmak için bir lexer ve Bison oluşturmak için Flex (Lex ve Yacc isimleriyle bunlara girebilirsiniz). Flex giriş belirteçleri düzenli ifade tanımlarını içeren bir dosyadır. Bison'un girişi, bnf formatındaki dil sözdizimi kurallarıdır.
HTML Ayrıştırıcı
HTML ayrıştırıcısının temel olarak görevi HTML birimlerini bir ayrıştırma ağacına ayrıştırmaktır.
HTML Dil Haznesi Tanımlaması
HTML'nin temel kelime haznesi ve sözdizimlemesi W3C kuruluşu tarafından oluşturulan bazı birimler ile tanımlanır.
Kesinlikle Bağlamdan Bağımsız Bir Dil Bilgisi Değildir
Ayrıştırma başlığımızın başlangıcında da gördüğümüz gibi dilbilgisi sözdizimleri "bnf" benzeri formatlar kullanılarak tanımlanabilmektedir. Buna rağmen bütün ayrıştırıcı denetim ve kurallamaları HTML için bir geçerlilik sunmamaktadır. HTML ayrıştırıcıların sebep ve ihtiyaç bulundurduğu bağlamı olmayan bir dilbilgisi ve sözdizimi ile kolayca tanımlanamaz. HTMLDTD'Yİ (belge türü tanımı) tanımlayabilmek için belirli bir format türü vardır fakat bağlamı olmayan bir dilbilgisi yoktur.
Bu ilk baktığınız taktirde garip görünebilir, HTML XML'YE oldukça yakınlık içerir. Birçok kullanılan XML ayrıştırıcısı bulunmaktadır. HTMLXHTML'nin bir XML versiyonu vardır, bu yüzden büyük fark nedir? Fark şudur ki HTML birimlemelerinin daha "kolaylaştırıcı" olmasından dolayıdır, belirli etiketleri (daha sonra örtülü olarak eklenir) atlamanıza veya bazen başlangıç veya bitiş etiketlerini atlamanıza izin verir. Genel olarak, XML'in sert ve zorlu sözdiziminin aksine "yumuşak" bir sözdizimi.
Bu görünüşe göre küçük detay fark bir dünya fark oluşturur. Bir dolayı da HTML'nin bu kadar popüler ve yaygın olabilmesinin ana nedeni budur, hatalarınızı affeder ve web yazarı için kodlama hayatını daha da kolaylaştırır. Öte yandan, resmi bir dilbilgisi yazmayı zorlaştırıyor. Özetlemek gerekirse, HTML geleneksel ayrıştırıcılar tarafından kolayca ayrıştırılamaz, çünkü dilbilgisi bağlamsız değildir. HTML XML ayrıştırıcıları tarafından ayrıştırılamaz.
HTML DTD
HTML tanımı DTD biçimindedir. Bu biçimleme genel olarak SGML familyasının dillerini tanımlayabilmek için kullanılmaktadır. Biçim, izin verilmekte olan tüm öğe ve birimler, öznitelikleri ve hiyerarşisi için tanımlamalarını içermektedir. Daha da önceden görebildiğimiz şekilde, HTML DTD bağlamsız bir dilbilgisi oluşturmaz.
DTD'nin birkaç farklı türü ve ayrımı bulunmaktadır. Sıkılaştırılmış kullanım yalnızca spesifikasyonlara uygundur, ancak diğer kullanımlar geçmişte tarayıcılar tarafından kullanılan biçimlendirme için destek içerir. Amaç, eski içerikle geriye dönük uyumluluktur.
DOM
Sonuç (Çıktı) ağacı - ayrıştırma ağacı DOM öğesinin ve öznitelik birim ve düğümlemelerinin bir tanım ağacıdır. DOM'un belgeleme için kullanımı kısıtlayıcı
ve kısadır. HTML belgesinin nesneleri ortaya sunumu ve HTML öğelerinin JavaScript gibi dış
dünyaya arayüz kullanımıdır. Ağacın kökü" belge " nesnesidir.
DOM-biçimlendirebilme için bir kullanım ve örnekleme nerdeyse sadece bir tane var. Örneğin;
Kod:
<html>[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER] <body>
<p>
Hello World
</p>
<div> <img src="example.png"/></div>
</body>
</html>
Bu nesnelendirme ağacı genel olarak aşağıdaki DOM ağacına çevrilmektedir:
HTML gibi DOM da W3C kuruluşu tarafından belirlenmek ve belirtilmektedir. Belirli bir modül HTML özel birimlemeleri açıklayabilmektedir.
Ağacın DOM düğüm ve bilgilerini içerisinde barındırdığını söylediğim zaman, ağaç DOM arayüzlerinden birini uygulayan öğelerden oluşur. Tarayıcılar, tarayıcı tarafından genel olarak "DAHİLİ" olarak kullanılan diğer özniteliklere sahip somut uygulamaları kullanır.
Ayrıştırma Algoritması
Daha önceki başlıklarda görebildiğimiz şekilde, HTML kullanım olarak yukarıdan aşağıya ya da aşağıdan yukarıya ayrıştırıcılar sayesinde ayrıştırılamaz.
Başlıca sebepleri şunlardır:
1 - Dilin düzeltici ve kolaylaştırıcı temel yapısı,
2 - Tarayıcıların bilinen geçerli olmayan temel HTML durumlarını desteklemek için geleneksel hata toleransına sahip olması,
+ Benzer farklı diller için kaynaklar ayrıştırma dolayısıyla farklılık göstermez, fakat HTML'deki dinamik kod (belge içeren komut dosyası öğeleri gibi .write()
çağrıları) fazladan jetonlar kullanabilirler, bu sayede ayrıştırma işlemi temelinde girişi tamamen farklılaştırır,
Düzenli ayrıştırma tekniklerini kullanamayan tarayıcılar, HTML'yi ayrıştırmak için özel ayrıştırıcılar oluşturur,Ayrıştırma algoritması HTML5 belirtimi tarafından ayrıntılı olarak açıklanmıştır. Algoritma iki aşamadan oluşur: tokenizasyon
ve ağaç yapımı, Tokenization temel olarak girişi belirteçlere ayrıştırarak sözcüksel analizdir. HTML belirteçleri arasında başlangıç etiketleri, bitiş
etiketleri, öznitelik adları ve öznitelik değerleri bulunur. Tokenizer belirteci tanır, ağaç yapıcısına verir ve sonraki belirteci tanımak
için bir sonraki karakteri tüketir ve böylece girişin sonuna kadar,
Tokinizasyon Algoritması
Algoritmanın genel son çıktısı bir HTML belirteci olabilir. Algoritmalar temel olarak bir durum makinesi olarak ifade edilmektedir. Her durum giriş akışının bir veya daha fazla karakterini tüketir ve bu karakterlere göre bir sonraki durumu günceller. Karar, mevcut tokenizasyon durumundan ve ağaç yapım durumundan etkilenir. Bu, aynı tüketilen karakterin geçerli duruma bağlı olarak doğru bir sonraki durum için farklı sonuçlar vereceği anlamına gelir. Algoritma tam olarak tanımlamak için çok karmaşıktır, bu yüzden prensibi anlamamıza yardımcı olacak basit bir örnek görelim.
Temel bir örnek olarak aşağıdaki HTML tokenizing:
Kod:
<html>[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER] <body>
Hello world
</body>
</html>
Başlangıç durumu "veri durumu"dır. < Karakter karşılaşıldığında, durum "etiketi açık durumu" olarak değiştirilir. Bir A-z karakteri tüketmek, bir "Başlat etiketi belirteci" oluşturulmasına neden olur, durum "Etiket adı durumu" olarak değiştirilir. Karakter tüketilene kadar bu durumda kalırız. Her karakter yeni belirteç adına eklenir. Bizim durumumuzda oluşturulan belirteç bir html belirtecidir. > Etiketine ulaşıldığında, geçerli belirteç yayılır ve durum "veri durumu"na geri döner. < Body > etiketi aynı adımlarla ele alınacaktır. Şimdiye kadar html ve vücut etiketleri yayılmıştır. Şimdi "veri durumu"na geri döndük. Hello world H karakterini tüketmek, bir karakter belirtecinin yaratılmasına ve yayılmasına neden olur, bu < of < / body> ulaşılana kadar devam eder. Merhaba dünyanın her karakteri için bir karakter belirteci yayacağız. Şimdi "Etiket açık durumu" na geri döndük. Bir sonraki girişi tüketmek / bir son etiket belirtecinin oluşturulmasına ve "etiket adı durumuna" taşınmasına neden olur. Ulaş untilana kadar yine bu durumda kal .ıyoruz.Sonra yeni etiket belirteci yayılacak ve "veri durumu"na geri dönüyoruz. < / Html> girişi önceki durum gibi ele alınacaktır.
Ağaç Yapımı Algoritması
Ayrıştırıcı oluşturulduğunda, belge nesnesi oluşturulur. Ağaç yapım aşamasında, kökünde belge bulunan DOM ağacı değiştirilecek ve ona elemanlar eklenecektir. Tokenizer tarafından yayılan her düğüm ağaç yapıcısı tarafından işlenecektir. Her belirteç için belirtim, hangi DOM öğesinin onunla alakalı olduğunu tanımlar ve Bu belirteç için oluşturulur. Öğe DOM ağacına ve ayrıca açık öğelerin yığınına eklenir. Bu yığın, yuvalama uyumsuzluklarını ve kapatılmamış etiketleri düzeltmek için kullanılır. Algoritma ayrıca bir durum makinesi olarak tanımlanır. Durumlara "ekleme modları" denir.
Örnek girdi için ağaç yapım sürecini görelim:
Kod:
<html>[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER] <body>
Hello world
</body>
</html>
Ağaç yapım aşamasında baaşlangıç, belirteçleme aşamasından bir dizi belirteçtir. İlk mod "ilk mod" dur. "Html" belirtecini almak, "önce html" moduna geçilmesine ve bu modda belirtecin yeniden işlenmesine neden olur. Bu, kök belge nesnesine eklenecek olan HTML
HtmlElement öğesinin oluşturulmasına neden olur.
Durum "before head" olarak değiştirilecek. Daha sonra "vücut" belirteci alınır. Bir "kafa" belirtecimiz olmamasına ve ağaca eklenmesine rağmen, bir HTMLHeadElement örtülü olarak oluşturulacaktır.
Şimdi "ın head" moduna ve ardından "after head" moduna geçiyoruz. Gövde simgesi yeniden işlenir, bir HTMLBodyElement oluşturulur ve eklenir ve mod "vücutta" olarak aktarılır. "Merhaba Dünya" dizesinin karakter belirteçleri şimdi alındı. Birincisi, bir "metin" düğümünün oluşturulmasına ve eklenmesine neden olur ve diğer karakterler bu düğüme eklenir.
Ayrıştırma Tamamlandığında Yapılması Gereken İşlemler
Bu aşamada tarayıcı belgeyi etkileşimli olarak işaretler ve "ertelenmiş" modda olan komut dosyalarını ayrıştırmaya başlar: belge ayrıştırıldıktan sonra çalıştırılması gerekenler. Belge durumu daha sonra "tamamlandı" olarak ayarlanır ve bir "yük" olayı harekete geçirilir. HTML5 belirtiminde tokenizasyon ve ağaç yapımı için tam algoritmaları görebilirsiniz
Tarayıcıların hata toleransı
Bir HTML sayfasında hiçbir zaman "geçersiz sözdizimi" hatası almazsınız. Tarayıcılar geçersiz içeriği düzeltir ve devam eder.
Örneğin bu HTML'yi alın:
Kod:
<html>[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER] <mytag>
</mytag>
<div>
<p>
</div>
Really lousy HTML
</p>
</html>
Yaklaşık bir milyon kuralı ihlal etmiş olmalı ("mytag "standart bir etiket değil," P "ve" div " öğelerinin yanlış yuvalanması ve daha fazlası), ancak tarayıcı hala doğru bir şekilde gösteriyor ve şikayet etmiyor. Bu yüzden ayrıştırıcı kodunun çoğu HTML yazar hatalarını düzeltiyor. Hata işleme tarayıcılarda oldukça tutarlıdır, ancak şaşırtıcı derecede HTML spesifikasyonlarının bir parçası olmamıştır. Yer imi ve Geri / İleri düğmeleri gibi, yıllar içinde tarayıcılarda geliştirilen bir şey. Birçok sitede tekrarlanan bilinen geçersiz HTML yapıları vardır ve tarayıcılar bunları diğer tarayıcılarla uyumlu bir şekilde düzeltmeye çalışırlar. HTML5 belirtimi bu gereksinimlerin bazılarını tanımlar. (WebKit, HTML ayrıştırıcı sınıfının başındaki yorumda bunu güzel bir şekilde özetlemektedir .)
Bazı WebKit hata toleransı örneklerini görelim:
bunun yerine <br></br>
Bazı siteler <br> yerine </br>kullanır. IE ve Firefox ile uyumlu olması için, WebKit bu gibi davranır.
Kod:
eğer (t - > isCloseTag (brTag) & & m_docum*nt - > inCompatMode()) {
reporderror (MalformedBRError);
t - > beginTag = true;
}Hata işlemenin dahili olduğunu unutmayın: kullanıcıya sunulmayacaktır.
Başı tablebo tableş bir masa
Bir başıboş tablo, başka bir tablonun içindeki bir tablodur, ancak bir tablo hücresinin içinde değildir.
Mesela:
Kod:
<Tablo>[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER]<Tablo>
<tr> < td>iç tablo< / td > < / tr>
</Tablo>
<tr> < td>dış tablo< / td > < / tr>
< / table>WebKit hiyerarşiyi iki kardeş tabloya değiştirir:
<Tablo>
<tr> < td>dış tablo< / td > < / tr>
</Tablo>
<Tablo>
<tr> < td>iç tablo< / td > < / tr>
< / table > kodu:
if (m_inStrayTableContent & & localName = = tableTag)
popBlock (tableTag);WebKit geçerli öğe içeriği için bir yığın kullanır: iç tabloyu dış tablo yığınından çıkarır. Tablolar artık kardeş olacak.
İç içe geçmiş form öğeleri
Kullanıcı başka bir form içinde bir form koyar, ikinci form yoksayılır.
Kod:
if (!m_currentFormElement) {[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER]M_currentformelement = yeni HTMLFormElement (formTag, m_docum*nt);
}
bool HTMLParser:: allowNestedRedundantTag (const AtomicString & tagName)
{
imzasız i = 0;
için (HTMLStackElem * curr = m_blockStack;
ben < cMaxRedundantTagDepth & & curr & & curr - > tagName = = tagName;
curr = curr - > sonraki, i++) { }
dönüş ben != cMaxRedundantTagDepth;
}
+ Yanlış yerleştirilmiş html veya gövde sonu etiketleri-/
Gerçekten kırık HTML desteği. Bazı aptal web sayfaları dokümanın gerçek sonundan önce kapattığından, vücut etiketini asla kapatmayız. İşleri kapatmak için end () çağrısına güvenelim. eğer (t - > tagName == htmlTag / / t - > tagName = = bodyTag )
Bu yüzden web yazarları dikkat edin-Bir WebKit hata tolerans kod parçacığında örnek olarak görünmek istemiyorsanız - iyi oluşturulmuş HTML yazın.
CSS Ayrıştırma
Girişteki ayrıştırma kavramlarını hatırlıyor musunuz? Peki, HTML'DEN farklı olarak, CSS bağlamsız bir dilbilgisidir ve girişte açıklanan ayrıştırıcı türleri kullanılarak ayrıştırılabilir. Aslında CSS belirtimi CSS sözcük ve sözdizimi dilbilgisini tanımlar.
Bazı örnekler görelim:
Sözcük dilbilgisi (kelime bilgisi), her belirteç için düzenli ifadelerle tanımlanır:
Kod:
\/\*[^*]*\*+([^/*][^*]*\*+)*\/[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER]num [0-9]+|[0-9]*"."[0-9]+
nonascii [\200 - \377]
nmstart [_a-z| / {nonascii} / {kaçış}
nmchar [_a-z0-9 -] / {nonascii} / {kaçış}
isim {nmchar}+
ident {nmstart}{nmchar}*
"ıdent", bir sınıf adı gibi tanımlayıcı için kısadır. "ad" bir öğe kimliğidir (bu, "#" )
Sözdizimi dilbilgisi bnf açıklanmıştır.
Kod:
ruleset[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER] : selector [ ',' S* selector ]*
'{' S* declaration [ ';' S* declaration ]* '}' S*
;
selector
: simple_selector [ combinator selector | S+ [ combinator? selector ]? ]?
;
simple_selector
: element_name [ HASH | class | attrib | pseudo ]*
| [ HASH | class | attrib | pseudo ]+
;
class
: '.' IDENT
;
element_name
: IDENT | '*'
;
attrib
: '[' S* IDENT S* [ [ '=' | INCLUDES | DASHMATCH ] S*
[ IDENT | STRING ] S* ] ']'
;
pseudo
: ':' [ IDENT | FUNCTION S* [IDENT S*] ')' ]
;
Açıklama: Bu bir kural kümesi yapısıdır.
Kod:
div.error, a.error {[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER] color:red;
font-weight:bold;
}
Bu, bir kural kümesinin bir seçici veya isteğe bağlı olarak virgül ve boşluklarla ayrılmış bir dizi seçici olduğu anlamına gelir (beyaz boşluk anlamına gelir). Kural kümesi, kıvırcık parantezleri ve içlerinde bir bildirim veya isteğe bağlı olarak noktalı virgülle ayrılmış bir dizi bildirim içerir. "bildirim" ve "seçici" aşağıdaki bnf tanımlarında tanımlanacaktır.
WebKit CSS ayrıştırıcı
WebKit, CSS dilbilgisi dosyalarından otomatik olarak ayrıştırıcılar oluşturmak için Flex ve Bison ayrıştırıcı jeneratörlerini kullanır. Ayrıştırıcı girişinden hatırladığınız gibi, Bison aşağıdan yukarıya kaydırmalı ayrıştırıcı oluşturur. Firefox elle yazılmış bir yukarıdan aşağıya ayrıştırıcı kullanır. Her iki durumda da her CSS dosyası bir stil sayfası nesnesine ayrıştırılır. Her nesne CSS kuralları içerir. CSS kural nesneleri, seçici ve bildirim nesnelerini ve CSS dilbilgisine karşılık gelen diğer nesneleri içerir.
Komut Belgelerinin ve Style (Stil) Dökümanlarının İşlenme Sırası
Scripts ( Komutlar )
Düzenleyiciler ayrıştırıcı temeline ulaşabildiğinde bu komut dosyalarının ayrıştırılmasının tamamlanmasını ve aynı zamanda çalıştırılmasını umarlar. Fakat komut dosyaları çalıştırılmadan önce belgenin ayrıştırılması durur. Belirli komut dosyaları harici olması durumunda kaynaklar ağdan getirilir. Bu yapılana kadar ayrıştırılma eş zamanlı çalışmadan dolayı durur. Kullanıcılar "defer" özelliğini herhangi bir komut dosyasına eklentileyebilir, bu durumda belge ayrıştırmayı durdurmaz ve belge ayrıştırıldıktan sonra yürütülür.
Spekülatif Ayrıştırma
Bu kullanımı hem webkit hemde aynı zamanda firefox gerçekleştirir. Komut dosyaları yürütülmeye başladığında başka herhangi bir iş birimide geriye kalan kaynakların ayrıştırılmasını tamamlar. Bunun sayesinde kaynaklar genellikle paralel bağlantılara eklenebilir ve hızları da bu sayede iyileşir.
Not: Spekülatif ayrıştırıcı sadece harici komut dosyaları, style (stil) sayfaları ve görüntüler benzeri harici kaynaklara dair yapılmakta olan istekleri ayrıştırmaktadır: DOM ağacını değiştirmez, bu ana ayrıştırıcıya bırakılır.
Style (Stil) Sayfaları
Bunların dışında stil sayfalarının yapısı diğerlerinden farklıdır. Terim olarak, stil sayfaları DOM ağaçları üzerinde değiştirme veya ayrıştırma işlemleri yapması için bir neden yoktur. Eğer bu aşamada stil hala sisteme yüklenmediyse hatalar alınacaktır. Kısacası komut dosyasında yanlışlıklar meydana gelecektir. Firefox işleyen bir stil sayfası görürse bu durumda komut dosyalarının çalışmasını engeller. WebKit, yalnızca kaldırılmış stil sayfalarından etkilenebilecek belirli stil özelliklerine erişmeye çalıştıklarında komut dosyalarını engeller.
Ağaç Yapımında Render
DOM Ağacının oluşturulması sırasında tarayıcı farklı bir ağa daha "render ağacını" oluşturmaktadır. Bu ağaç temelde görüntü ve görüntülenebilecek içeriklerin görüntülenmesinden sorumludur. Bu ağacın asıl amacı görsel nitelikleri renklendirmektir. Firefox genel olarak render ağacında bulunan birimleri "çerçeve" olarak adlandırmaktadır. Ayrıca webkit render nesnesini kullanmaktadır. Herhangi bir oluşturucu neler yapacağını, görevlerini yani renklendirmelerini bilmektedir. Webkit'in RenderObject sınıfı, oluşturucuların temel sınıfı aşağıdaki tanıma sahiptir:
Kod:
class RenderObject{[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER] virtual **** layout();
virtual **** paint(PaintInfo);
virtual **** rect repaintRect();
Node* node; //the DOM node
RenderStyle* style; // the computed style
RenderLayer* containgLayer; //the containing z-index layer
}
Her oluşturucu, genellikle css2 spesifikasyonu tarafından açıklandığı gibi bir düğümün CSS kutusuna karşılık gelen dikdörtgen bir alanı temsil eder. Genişlik, yükseklik ve konum gibi geometrik bilgileri içerir.
Kutu türü, düğümle ilgili olan stil özniteliğinin "görüntüleme" değerinden etkilenir(stil hesaplama bölümüne bakın). Display özniteliğine göre, bir DOM düğümü için ne tür bir işleyicinin oluşturulması gerektiğine karar vermek için WebKit kodu:
Kod:
RenderObject* RenderObject::createObject(Node* node, RenderStyle* style)[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER]{
********* doc = node->********();
RenderArena* arena = doc->renderArena();
...
RenderObject* o = 0;
switch (style->display()) {
case NONE:
break;
case INLINE:
o = new (arena) RenderInline(node);
break;
case BLOCK:
o = new (arena) RenderBlock(node);
break;
case INLINE_BLOCK:
o = new (arena) RenderBlock(node);
break;
case LIST_ITEM:
o = new (arena) RenderListItem(node);
break;
...
}
return o;
}
Öğe türü de dikkate alınır: örneğin, form kontrolleri ve tablolar özel çerçevelere sahiptir.
Webkit'te bir öğe özel bir işleyici oluşturmak istiyorsa, createRenderer() yöntemini geçersiz kılar. Oluşturucular, geometrik olmayan bilgiler içeren stil nesnelerine işaret eder.
DOM Ağacı ve Render Ağacının Temel İlişkisi
İşleyiciler DOM birimlerine denk gelmektedir. Fakat ilişki olarak bire bir değildirler. DOM birimleri görsel olmadığından render birimlerine eklenemez. Aynı zamanda görüntülenme değerlendirmeleri "none" olan birimler ağaçda herhangi bir işlem göstermez veya işleme karşılık gelmez. Fakat bazı görsel nesnelere karşılık gelen DOM birimleri de bulunmaktadır. Genelde bu birimler dikdörtgenler tarafından belirlenemeyen karmaşık ögelerden oluşmaktadır. Örnek verecek olursak "seç" biriminin üç adet renderi bulunmaktadır. Bir tanesi görüntüleme, bir tanesi açılabilir listeleme kutusu, bir tanesi ise düğme içindir. Birden çok işleyicinin bir başka örneği de html'dir. CSS spesifikasyonuna göre bir satır içi öğe yalnızca blok öğeleri veya yalnızca satır içi öğeler içermelidir. Karışık içerik durumunda, satır içi öğeleri sarmak için anonim blok oluşturucular oluşturulacaktır.Bazı render nesneleri bir DOM düğümüne karşılık gelir, ancak ağaçta aynı yerde değildir. Şamandıralar ve kesinlikle konumlandırılmış elemanlar akış dışındadır, ağacın farklı bir bölümüne yerleştirilir ve gerçek çerçeveye eşlenir. Olması gereken yer tutucu çerçevedir.
Ağacın Temel İnşa Şematize ve Akışı
Firefox içerisinde temel sunum bir dinleyici olarak DOM için yerleştirilir. Webkit içerisinde ise bu durum stili çözümleme ve oluşturucu oluşturabilme süreci genel olarak "ek dosya" olarak adlandırılır. Kısaca DOM'un bir "ek dosya" yöntemi vardır. Html ve gövde etiketlerinin işlenmesi, render ağacı kökünün oluşturulmasına neden olur.
Kök oluşturma nesnesi, CSS spesifikasyonunun içeren blok olarak adlandırdığı şeye karşılık gelir: diğer tüm blokları içeren en üst blok. Boyutları viewport: tarayıcı penceresi ekran alanı boyutlarıdır. Firefox bunu ViewPortFrame ve WebKit RenderView olarak adlandırıyor. Bu, belgenin işaret ettiği render nesnesidir. Ağacın geri kalanı bir DOM düğümleri ekleme olarak inşa edilmiştir.
Stil Hesaplaması
Render ağacını oluşturmak, her render nesnesinin görsel özelliklerini hesaplamayı gerektirir. Bu, her öğenin stil özelliklerini hesaplayarak yapılır.
Stil, çeşitli kökenlerin stil sayfalarını, satır içi stil öğelerini ve HTML'DEKİ görsel özellikleri ("bgcolor" özelliği gibi) içerir.Daha sonra eşleşen CSS stil özelliklerine çevrilir.
Stil sayfalarının kökeni, tarayıcının varsayılan stil sayfaları, sayfa yazarı ve kullanıcı stil sayfaları tarafından sağlanan stil sayfalarıdır - bunlar tarayıcı kullanıcısı tarafından sağlanan stil sayfalarıdır (tarayıcılar favori stillerinizi tanımlamanıza izin verir. Firefox'ta, örneğin, bu "Firefox profili" klasörüne bir stil sayfası yerleştirerek yapılır).
Stil hesaplama birkaç zorluk getiriyor:
Stil verileri çok sayıda stil özelliklerini tutan çok büyük bir yapıdır, bu bellek sorunlarına neden olabilir.
Her öğe için eşleşen kuralları bulmak, optimize edilmezse performans sorunlarına neden olabilir. Eşleşmeleri bulmak için her öğe için tüm kural listesini geçmek ağır bir iştir. Seçiciler, eşleştirme işleminin boşuna olduğu kanıtlanmış ve başka bir yolun denenmesi gereken görünüşte umut verici bir yolda başlamasına neden olabilecek karmaşık bir yapıya sahip olabilir.
Örneğin-bu bileşik seçici:
Kod:
div div div div{[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER] ...
}
Kurallar 3 divs soyundan olan bir <div> için geçerli anlamına gelir. Kuralın belirli bir < div> öğesi için geçerli olup olmadığını kontrol etmek istediğinizi varsayalım. Kontrol etmek için ağacın belli bir yolunu seçersiniz. Sadece iki div olduğunu ve kuralın geçerli olmadığını öğrenmek için düğüm ağacını yukarı doğru hareket ettirmeniz gerekebilir. Daha sonra ağaçta diğer yolları denemek gerekir.
Kuralların uygulanması, kuralların hiyerarşisini tanımlayan oldukça karmaşık basamaklı kuralları içerir.
Tarayıcıların bu sorunlarla nasıl yüzleştiğini görelim:
Sharing Style Data
WebKit düğümleri stil nesnelerine (RenderStyle) başvurur. Bu nesneler bazı koşullarda düğümler tarafından paylaşılabilir. Düğüm siler kardeş veya kuz andendir ve:
1.Öğeler aynı fare durumunda olmalıdır (örneğin, biri olamaz: diğeri değilken hover).
2.Hiçbir öğenin bir kimliği olmamalıdır.
3.Etiket adları eşleşmelidir.
4.Sınıf öznitelikleri eşleşmelidir.
5.Eşlenen öznitelikler kümesi aynı olmalıdır.
6.Bağlantı durumları eşleşmelidir.
7.Odak durumları eşleşmelidir.
8.Her iki öğe de öznitelik seçicilerinden etkilenmemelidir; burada etkilenen, seçici içindeki herhangi bir konumda bir öznitelik
seçicisini kullanan herhangi bir seçici eşleşmesine sahip olarak tanımlanır.
9.Öğeler üzerinde satır içi stil özniteliği olmamalıdır.
10.Kullanımda hiç kardeş seçicisi olmamalıdır. WebCore, herhangi bir kardeş seçiciyle karşılaşıldığında genel bir anahtar atar ve
mevcut olduklarında tüm belge için stil paylaşımını devre dışı bırakır. Bu + seçici ve seçiciler gibi içerir :first-child ve: last-child.
11.Firefox kural ağacı
12.Firefox'un daha kolay stil hesaplaması için iki ekstra ağacı vardır: kural ağacı ve stil bağlam ağacı. WebKit ayrıca stil nesnelerine de
sahiptir, ancak stil bağlam ağacı gibi bir ağaçta saklanmazlar, yalnızca DOM düğümü ilgili stiline işaret eder.
Stil bağlamları bitiş değerleri içerir. Değerler, eşleşen tüm kuralları doğru sırayla uygulayarak ve bunları mantıksal değerlerden somut değerlere dönüştüren manipülasyonlar gerçekleştirerek hesaplanır. Örneğin, mantıksal değer ekranın bir yüzdesi ise, hesaplanır ve mutlak birimlere dönüştürülür. Kural ağacı fikri gerçekten zekice. Bu değerleri tekrar hesaplamayı önlemek için düğümler arasında paylaşmayı sağlar. Bu aynı zamanda yerden tasarruf sağlar. Eşleşen tüm kurallar bir ağaçta saklanır. Bir yoldaki alt düğümler daha yüksek önceliğe sahiptir. Ağaç, bulunan kural eşleşmeleri için tüm yolları içerir. Kuralların saklanması tembelce yapılır. Ağaç her düğüm için başlangıçta hesaplanmaz, ancak bir düğüm stilinin hesaplanması gerektiğinde, hesaplanan yollar ağaca eklenir. Fikir, ağaç yollarını bir sözlükte kelimeler olarak görmektir. Diyelim ki bu kural ağacını zaten hesapladık:
İçerik ağacındaki başka bir öğe için kuralları eşleştirmemiz gerektiğini ve eşleşen kuralların (doğru sırayla) B-E-I olduğunu varsayalım. Ağaçta zaten bu yol var, çünkü zaten A-B-E-I-L yolunu hesaplamıştık. Şimdi yapacak daha az işimiz olacak.
Ağacın bizi nasıl kurtardığına bakalım.
Yapılara Bölünme
Stil bağlamları yapılara ayrılmıştır. Bu yapılar, kenarlık veya renk gibi belirli bir kategori için stil bilgisi içerir. Bir yapıdaki tüm özellikler miras alınır veya miras alınmaz. Devralınan özellikler, öğe tarafından tanımlanmadığı sürece, üst öğesinden devralınan özelliklerdir. Devralınmayan özellikler ("sıfırlama" özellikleri olarak adlandırılır) tanımlanmamışsa varsayılan değerleri kullanır. Ağaç, ağaçtaki tüm yapıları (hesaplanan son değerleri içeren) önbelleğe alarak bize yardımcı olur. Buradaki fikir, alt düğüm bir yapı için tanım sağlamadığı takdirde, üst düğümdeki önbelleğe alınmış bir yapının kullanılabileceği yönündedir.
Kural Ağacı Yardımıyla Style Bağlamlarının Hesaplanması
Belirli bir öğenin stil bağlamını hesaplarken, önce kural ağacında bir yol hesaplar veya mevcut olanı kullanırız. Daha sonra yeni stil bağlamımızdaki yapıları doldurma yolundaki kuralları uygulamaya başlarız. Yolun alt düğümünde başlıyoruz - en yüksek önceliğe sahip olan (genellikle en spesifik seçici) ve yapımız dolana kadar ağacı yukarı doğru hareket ettiriyoruz. Bu kural düğümündeki yapı için bir spesifikasyon yoksa, büyük ölçüde optimize edebiliriz - onu tamamen ve basitçe işaret eden bir düğüm bulana kadar ağaca çıkacağız - bu en iyi optimizasyondur - tüm yapı paylaşılır. Bu, son değerlerin ve belleğin hesaplanmasını kaydeder. Kısmi tanımlar bulursak, yapı dolana kadar ağaca gideriz. Yapımız için herhangi bir tanım bulamazsak, yapının "miras alınan" bir tür olması durumunda, ana ağacımızın içerik ağacındaki yapısına işaret ederiz. Bu durumda yapıları paylaşmayı da başardık. Eğer bir sıfırlama yapısı ise, varsayılan değerler kullanılır. En spesifik düğüm değer ekliyorsa, gerçek değerlere dönüştürmek için bazı ekstra hesaplamalar yapmamız gerekir. Daha sonra sonucu ağaç düğümünde önbelleğe alırız, böylece çocuklar tarafından kullanılabilir. Bir öğenin aynı ağaç düğümüne işaret eden bir kardeşi veya erkek kardeşi varsa, tüm stil bağlamı aralarında paylaşılabilir. Bir örneğe bakalım; Bu HTML'ye sahip olduğumuzu varsayalım:
Kod:
<html>[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER] <body>
<div class="err" id="div1">
<p>
this is a <span class="big"> big error </span>
this is also a
<span class="big"> very big error</span> error
</p>
</div>
<div class="err" id="div2">another error</div>
</body>
</html>
Kod:
div {margin:5px;color:black}[/B][/COLOR][/CENTER][/B][/COLOR][/CENTER][/B][/COLOR][/CENTER]
[COLOR=White][B][CENTER][COLOR=White][B][CENTER][COLOR=White][B][CENTER].err {color:red}
.big {margin-top:3px}
div span {margin-bottom:4px}
#div1 {color:blue}
#div2 {color:green}
işlemleri daha kolay hale getirmek için sadece iki adet yapıyı doldurmamız gerektiğini varsayalım; renk ve kenar boşluğu yapısı. Renk yapısı temel olarak sadece bir adet içerik içermektedir. Bu kenar boşluğu yapısının her tarafını saran renklendirmedir. Ortaya çıkan kural ağacı aşağıdaki şekilde görünecektir:
HTML'yi ayrıştırmayı başardığımızı ve ikinci <div> elementine ulaştığımızı düşünelim. Bunun için style bağlamı oluşturmamız, style boşluklarını doldurmamız gerekir. Kuralları eşlememiz durumunda <div> bağlamı ile eşleşen kuralların 1 - 2 ve 6 olduğunu görebilmekteyiz. Bunun anlamı ise ağaç içerisinde elementin temelde kullanabileceği bir yol olduğu, ayrıca kural "6" için farklı bir eşlem oluşturmamız gerektiğini belirtir. Bir stil bağlamı oluşturacağız ve bağlam ağacına koyacağız. Yeni stil içeriği, kural ağacında F düğümüne işaret eder.
Şimdi stil yapılarını doldurmamız gerekiyor. Marj yapısını doldurarak başlayacağız. Son kural düğümü (F) kenar boşluğu yapısına eklenmediğinden, önceki bir düğüm ekleme işleminde hesaplanan önbelleğe alınmış bir yapı bulana ve onu kullanana kadar ağaca çıkabiliriz. Kenar boşluğu kurallarını belirleyen en üst düğüm olan b düğümünde bulacağız. Renk yapılanması için temelde bir tanımımız bulunmaktadır. Bu nedenle ön belleğe geçmiş bir yapı kullanmak zorundayız. Rengin bir özelliği olduğundan, diğer özellikleri doldurmak için ağaca gitmemize gerek yoktur. Son değeri hesapladıktan sonra değerleri önbelleğe aktarmalıyız. Rengin bir özelliği olduğundan, diğer özellikleri doldurmak için ağaca gitmemize gerek yoktur. Son değeri hesaplayacağız (dizgeyi RGB'YE dönüştüreceğiz) ve bu düğümde hesaplanan yapıyı önbelleğe alacağız.
İkinci < span> elemanındaki çalışma daha da kolaydır. Kurallara uyacağız ve önceki yayılma gibi g kuralına işaret ettiği sonucuna varacağız. Aynı düğüme işaret eden kardeşlerimiz olduğundan, tüm stil bağlamını paylaşabilir ve sadece önceki yayılma bağlamına işaret edebiliriz.
Üst öğeden devralınan kuralları içeren yapılar için, bağlam ağacında önbelleğe alma yapılır (renk özelliği aslında devralınır, ancak Firefox bunu sıfırlama olarak değerlendirir ve kural ağacında önbelleğe alır). Örneğin, bir paragrafta yazı tipleri için kurallar eklersek:
Kod:
p {font-family: Verdana; font size: 10px; font-weight: bold}
Sonra bağlam ağacındaki div'nin bir altı olan paragraf öğesi, üstü ile aynı yazı tipi yapısını paylaşmış olabilir. Paragraf
için yazı tipi kuralları belirtilmemişse budur.
Bir kural ağacına sahip olmayan Webkit'te, eşleşen bildirimler dört kez geçilir. Önce önemli olmayan yüksek öncelikli özellikler uygulanır (önce Diğerleri bunlara bağlı olduğu için uygulanması gereken özellikler, örneğin ekran), daha sonra yüksek öncelikli önemli, daha sonra normal öncelikli önemli olmayan, daha sonra normal öncelikli önemli kurallar uygulanır. Bu, birden çok kez görünen özelliklerin doğru Basamaklama sırasına göre çözüleceği anlamına gelir. Son kazanır.
Özetlemek gerekirse: stil nesnelerini paylaşmak (tamamen veya içlerindeki yapılardan bazıları) 1 ve 3. sorunları çözer. Firefox kural
ağacı, özellikleri doğru sırayla uygulamada da yardımcı olur.
Moderatör tarafında düzenlendi: