Newtoo - Entwicklung einer vollständigen Browser-Engine von Grund auf im Jahr 2018?

Published on September 30, 2018

Newtoo - Entwicklung einer vollständigen Browser-Engine von Grund auf im Jahr 2018?

Bild

Hallo! Ich heiße Dmitry Kozichev.

Heute erzähle ich Ihnen von meinem Versuch, meine eigene moderne Webbrowser-Engine von Grund auf neu zu erstellen.

Mein Motor heißt Newtoo.

Was ist neu?


Also, Newtoo. Warum habe ich es erstellt?

Es kommt also vor, dass es weltweit nur vier beliebte Browser-Engines gibt, die so komplex sind, dass die Entwickler selbst nicht einmal die Hälfte ihres Codes kennen und in der Technologie so weit fortgeschritten sind, dass es Zeitverschwendung ist, sie einzuholen.

Ist es wirklich so Mein Projekt wurde erstellt, um die Exploits moderner Browser-Engines zu wiederholen und zu sehen, wie realistisch es ist, eine würdige Alternative zu großen Projekten zu schaffen, deren Geschichte in den neunziger Jahren beginnt. Mein neuer Motor wurde von Grund auf neu erstellt, was bedeutet, dass seine Geschichte beginnt - heute.

Idea Newtoo - zeige die Seite schneller als andere.

So arbeitet Newtoo schneller


Wie ich bereits sagte, haben sich die wichtigsten Browser-Engines nicht für das erste Jahr entwickelt. Die Fehler, die in der Anfangsphase der Entwicklung gemacht wurden, bleiben bis zum Ende im Projekt. Das auffälligste Beispiel dafür - intelligente Zeiger in C ++ - ist eine noch komplexere Syntax, ein großer Aufwand beim Bearbeiten, Erstellen und Löschen intelligenter Zeiger. Darüber hinaus gibt es so viele Arten von intelligenten Zeigern, dass Sie wissen müssen, welchen Sie verwenden sollen, da jeder seine eigenen Überraschungsnuancen hat . Schauen Sie sich diese Datei aus dem Webkit an. Wenn Sie solchen Code sehen, die Syntax von intelligenten Zeigern, versuchen Sie sich zu beruhigen und gleichmäßig zu atmen, aber diese Art von Code ist das gesamte Webkit von Kopf bis Fuß. Es gibt keine derartigen Mängel in meinem Motor.

Was ist in der Box


Mal sehen, woraus Newtoo besteht

. Gegenwärtig sind die folgenden Teile des Projekts implementiert:

  • HTML-Parser
  • HTML-Serializer
  • CSS-Parser (Selektoren, Regeln und Eigenschaften)
  • CSS Serializer
  • Grundlegende DOM-API 1

Die restlichen Teile des Projekts, die noch nicht implementiert sind:

  • CSS-Kaskadierung (CSS-Stilberechnung)
  • Linker
  • Rendern
  • JS virtuelle Maschine und Ereignisse
  • Eventhandler und interaktive Seitenauswahl

HTML-Parser


Mein HTML-Parser kann als modern bezeichnet werden. Zunächst baut es auf dem Standard HTML5 auf . Es berücksichtigt alle Ihre Fehler.

Sie haben beispielsweise vergessen, Anführungszeichen zu setzen, indem Sie das Attribut eingegeben haben

<article id=hello></article>

Die Engine wird Sie verstehen, da ein Attributwert ohne Leerzeichen geschrieben ist.

Sie können das Tag nicht schließen, wenn es nicht erforderlich ist.


<div>
   <p>First line
   <p>Second line
   <img src="ru/images/2019.png" alt="С новым годом!">
   <p>Third line <br> Last line
</div>

Parser unterstützt Präfixe


<myprefix:span>Hello, world!</myprefix:span>

Um die Seitenelemente wieder in Code umzuwandeln, habe ich den HTML-Serializer geschrieben. Ich glaube, Sie haben erraten, was er getan hat.

Wie der HTML-Parser funktioniert


Zunächst schneidet unser Parser unseren HTML-Code in Stücke und bestimmt deren Typ.

Zum Beispiel das:


<!doctype html><html><head><title>Lorem ipsum</title></head></html>

Daraus ergibt sich:


<!doctype html>   - doctype token
<html>            - tag token
<head>            - tag token
<title>           - tag token
Lorem ipsum       - text token
</title>          - close tag token
</head>           - close tag token
</html>           - close tag token

Diese Stücke werden Token genannt.

Tokens sind in 6 Typen unterteilt:

  • Tag
  • Schließtag
  • Text
  • Kommentar
  • Dokumenttyp (doctype)
  • Javascript oder CSS-Code



Parser liest Token von links nach rechts. Für jeden Typ ein eigener Parsing-Ansatz.

Wenn der Parser den Inhalt des Tags liest, wird das Tag selbst in der Hierarchie registriert (Hierarchie von untergeordnetem zu übergeordnetem Element nach unten), und wenn der Parser den Inhalt des Tags gelesen hat, wird er aus der Hierarchie entfernt.

Wenn es sich um ein öffnendes Tag handelt, werden der Tag-Name und die Attribute analysiert. Wenn es sich um einen Absatz handelt und die Hierarchie einen Absatz enthält, wird das in der Hierarchie vorhandene Absatz-Tag gelöscht und ein neues Tag hinzugefügt, wenn es sich nicht um ein einzelnes Tag handelt (ein Tag ohne schließendes Tag). Wenn es sich um ein schließendes Tag handelt, entfernt der Parser das letzte Tag aus der Hierarchie. Wenn das letzte Tag ein Absatz war, werden die letzten beiden gelöscht. Und wenn es sich um einen Code handelt, sind Sonderzeichen zulässig.

Mit dieser Methode zum Parsen von Token können Sie <p> ohne schließendes Tag schreiben.

CSS-Parser


Im Moment kann die Engine nur CSS-Regeln im Stil analysieren, zum Beispiel:

.flex[alignment="right"] { font-weight: light; color: #999 }

Indem Sie nur eine Stilregel unterstützen, können Sie die Desktop-Version einer Site bereits ordnungsgemäß anzeigen.

Im Gegensatz zu anderen Engines unterstützt Newtoo einzelne "//" - Kommentare im CSS-Code und entfernt diese nicht, wenn Sie mit CSS über Javascript interagieren.

CSS-Parser-Selektoren


Um herauszufinden, welche HTML-Elemente der Seite mit CSS-Stilen formatiert werden sollten, wurde eine Auswahlsprache erfunden . Sie kennen ihn wahrscheinlich schon.

Der Selektor-Parser unterstützt alle Kombinatoren, zwei Arten von Anführungszeichen, Tag-Selektoren, Klassen, Attribute, Mehrfachselektoren und Klassen.

Hier ist eine vollständige Liste aller unterstützten Selektoren:

TagName
#Id
.Class
[attr=value]
[attr|=value]
[attr$=value]
[attr~=value]
[attr^=value]
[attr*=value]
.Multi.Class
#Mix#ed.Selec[tor=s]
"Quotes"
'Alternative quotes'
#descedant #child
#parent < #child
#previous + #this
#other ~ #this
.multi, .selectors
#element:hover
#element:active
#element:...

Ja, die Vierte-Ebene-Auswahl- Engine unterstützt dies noch nicht, aber ich arbeite daran.

DOM API


Wenn mein HTML-Parser unseren Code liest, erstellt er ein Document Object Model (DOM). DOM sieht aus wie ein Knotenbaum, in dem das Stammverzeichnis ein Browserfenster ist, von dem ein Dokument verzweigt wird und Seitenelemente bereits aus dem Dokument stammen. Mit der DOM-API können Sie über JavaScript mit allen DOM-Knoten interagieren.

Mein Modul unterstützt alle Änderungen an den DOM-Änderungen. Sie können beispielsweise den HTML-Code eines beliebigen Elements neu erstellen:

document.getElementById("article").innerHTML = "Статья исчезла. <b>Бум!</b>";

Jetzt werde ich nicht alle Funktionen der Arbeit mit Elementen, Dokumenten, Texten, Auswahlen auflisten, glauben Sie mir, es gibt viele davon!

Die virtuelle JavaScript-Maschine wurde noch nicht geschrieben, aber die API ist bereits vorhanden und funktioniert gut.

Zukunft des Projekts


Über die Perspektiven des Projekts kann ich nichts sagen, es liegt an Ihnen.
Wenn dir mein Motor gefällt, habe ich es gut versucht.

Newtoo auf Github