- PVSM.RU - https://www.pvsm.ru -

Newtoo — разработка полноценного браузерного движка с нуля в 2018?

image

Привет! Меня зовут Дмитрий Козичев.

Сегодня я вам расскажу о моей попытке создать собственный современный веб-браузерный движок с нуля.

Мой движок называется Newtoo.

Что за Newtoo

Итак, Newtoo. Зачем я его создал?

Так уж получилось, что в мире есть всего 4 популярных браузерных движка, которые настолько сложны, что сами разработчики не знают и половины их кодовой базы, и настолько продвинутые по технологиям, что начать их догонять — пустая трата времени.

А так ли это на самом деле? Мой проект создан, чтобы повторить подвиги современных браузерных движков и проверить, насколько ли реально создать достойную альтернативу крупным проектам, история которых начинается с девяностых годов. Мой новый движок создается с нуля, а значит его история начинается — сегодня.

Идеология Newtoo — показать страницу быстрее, чем остальные.

Как Newtoo работает быстрее

Как я говорил ранее, основные браузерные движки развиваются не первый год. Те ошибки, которые были допущены на начальных стадиях разработки остаются в проекте до конца. Самый яркий пример этому — умные указатели в C++ — это еще более сложный синтаксис, большой оверхед при работе, создании и удалении умных указателей. Кроме того, есть очень много типов умных указателей [1] и нужно знать, какой когда использовать, ведь у каждого есть свои сюрпризы ньюансы. Посмотрите на этот [2] файл из WebKit. Когда видишь такой код, синтаксис умных указателей, пытаешься успокоится и дышать ровно, но такого рода код — это весь вебкит с ног до головы. В моем движке нет таких недостатков.

Что в коробочке

Давайте посмотрим из чего состоит Newtoo

На данный момент реализованы следующие части проекта:

  • Парсер HTML
  • Сериализатор HTML
  • Парсер CSS (селекторы, правила и свойства)
  • Сериализатор CSS
  • Основное DOM API1

Остальные части проекта, которые пока не реализованы:

  • Каскадинг CSS (вычисление css стилей)
  • Компоновщик
  • Рендер
  • Виртуальная машина JS и события
  • Обработчик событий и интерактивное выделение страницы

Парсер HTML

Мой парсер HTML вполне можно назвать современным. Начнем с того, что он построен по стандарту HTML5 [3]. Он учитывает любую вашу ошибку.

Например, вы забыли поставить кавычки, набирая атрибут

<article id=hello></article>

Движок вас поймет, есть значение атрибута написано без пробелов

Вы можете не закрывать тег, когда это не обязательно


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

Парсер поддерживает префиксы


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

Для того, чтобы обратно превратить элементы страницы в код, я написал сериализатор HTML. Я думаю, вы догадались, что он делает.

Как работает парсер HTML

Для начала наш парсер режет наш html код на кусочки и определяет их тип.

К примеру вот это:


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

Превращается в это:


<!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

Эти кусочки называются токены.

Токены делятся на 6 типов:

  • Тег
  • Закрывающийся тег
  • Текст
  • Комментарий
  • Тип документа (doctype)
  • Javascript или css код


Парсер читает токены слева направо. Для каждого типа свой подход парсинга.

Когда парсер читает содержимое тега, сам тег регистрируется в иерархии (иерархия от ребенка до родителя вниз), а когда парсер закончил читать содержимое тега, он удаляет его из иерархии.

Если это открывающийся тег, он парсит его название тега, атрибуты, а затем, если это параграф и в иерархии тоже есть параграф, удаляет существующий в иерархии тег параграфа и добавляет туда новый, если это не одиночный тег (тег без закрывающегося тега). Если это закрывающийся тег, парсер удаляет из иерархии последний тег и если последний тег был параграфом, то удаляет сразу два последних. А если это код, в нем разрешены спецсимволы.

Используя такой метод парсинга токенов, можно писать <p> без закрывающегося тега.

Парсер CSS

На данный момент движок умеет парсить только стилевые css правила, например:

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

Поддерживая только одни стилевые правила, можно уже нормально отобразить настольную версию какого-нибудь сайта.

В отличии от других движков, Newtoo поддерживает одиночные комментарии '//' в css коде и не удаляет их при взаимодействии с css через javascript.

Парсер CSS селекторов

Чтобы узнать, какие именно html элементы страницы нужно форматировать стилями css, был придуман язык селекторов [4]. Вы наверное его уже знаете.

Парсер селекторов поддерживает все комбинаторы, два вида кавычек, селекторы тегов, классов, атрибутов, множественные селекторы и классы.

Вот полный список всех поддерживаемых селекторов:

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:...

Да, селекторы четвертого уровня [5] движок пока не поддерживает, но я работаю на этим.

DOM API

Когда мой парсер HTML читает наш код, он создает объектную модель документа (DOM). DOM выглядит как дерево из узлов, где корень — окно браузера, от него ответвляется документ, а от документа уже элементы страницы. Cо всеми узлами DOM можно взаимодействовать через JavaScript c помощью DOM API.

Мой движок поддерживает любые изменения изменения DOM. Например, можно переделать html код любого элемента:

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

Сейчас не буду перечислять все функции работы с элементами, документом, текстом, выделением, поверьте, их много!

Виртуальную машину JavaScript пока не написал, но API уже есть и хорошо работает.

Будущее проекта

Про перспективы проекта ничего не могу сказать, вам решать.
Если вам понравился мой движок, значит я хорошо постарался.

Newtoo на GitHub [6]

Автор: FlightBlaze

Источник [7]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/c-3/294384

Ссылки в тексте:

[1] очень много типов умных указателей: https://eax.me/cpp-smart-pointers/

[2] этот: https://opensource.apple.com/source/WebCore/WebCore-7604.5.6/html/HTMLAllCollection.cpp.auto.html

[3] HTML5: https://www.w3.org/TR/html53/single-page.html

[4] язык селекторов: https://puzzleweb.ru/css/selectors.php

[5] селекторы четвертого уровня: https://www.w3.org/TR/selectors/

[6] Newtoo на GitHub: https://github.com/FlightBlaze/Newtoo

[7] Источник: https://habr.com/post/424881/?utm_campaign=424881