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

image

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

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

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

Что за Newtoo


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

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

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

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

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


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

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


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

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

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

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

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

Парсер HTML


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

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

<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, был придуман язык селекторов. Вы наверное его уже знаете.

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

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

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

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

DOM API


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

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

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

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

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

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


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

Newtoo на GitHub
Поделиться публикацией
Комментарии 475
    +9
    Круто. Браузер для ReactOS?
      +9
      Лучше бы для KolibriOS.
        +1
        Насчёт браузера не знаю, но в качестве MSHTML движка было бы интересно увидеть. :)
        +5
        Дело хорошее. В конце концов, nginx сожрал apache.
        Только польза от учитывания ошибок, ИМХО, сомнительная:
        1. Стимулирует писать некрасиво: и так сойдёт;
        2. Заставляет тратить время на поддержку возможности писать некрасиво, потенциально порождая баги;
        3. Этакая криво написанная страница, простимулированная таким парсером, ещё и сломает кучу других парсеров, написанных строже;
        Яндекс, Гугл даже в простом html стараются придерживаться XML, видимо, именно по причине 3.
          +13
          Игнорирование и исправление ошибок HTML было начиная с первых браузеров, и некоторые способы исправления даже задокументированы в стандартах, если я не путаю. Что касается тега <p>, стандарт разрешает не ставить закрывающий тег.
            +4
            Погодите. Например парсер от Google толерантен к ошибкам в html.
              +1
              Я про вот такие чудеса: XML — не просто расширение, там действительно под капотом XML. У Яндекса таких чудес тоже хватает.
                0

                Это совсем другое. Там действительно XML, который затем обрабатывается с помощью XSLT. В результате получается HTML, который затем отображает браузер. Поддержка этих технологий — отдельная задача.

            • НЛО прилетело и опубликовало эту надпись здесь
                0
                Я предлагаю изменить стандарт. Поэтому и подчеркнул ИМХО :) по тексту это всё понятно: автор сначала ссылается на стандарт, а потом раскрывает. Значит, такой стандарт. И это печально…
                • НЛО прилетело и опубликовало эту надпись здесь
                    0
                    Но если вам понадобится сверстать форматированную html-страницу с двумя картинками и парой абзацев текста — вам зачем это всё?

                    Насколько это типичный кейс?
                    Да, раньше подругому не было.
                    Но сейчас страницы так никто не делает и сделать так ничего толкового нельзя.
                    Дольше всех продержался IoT, но даже там уже не актуально и практически никто уже не верстает странички в блокноте.
                    • НЛО прилетело и опубликовало эту надпись здесь
                    +5
                    Уже пробовали, был такой XHTML больше 10 лет назад, который не прижился именно из-за его строгости.
                    Если хочется строгого четкого стандарта — всегда можно использовать XML.

                    И самый важный момент, если парсер браузера не будет поддерживать не строгий стандарт, на котором написаны уже миллионы сайтов, причем еще с 90-х, то зачем такой браузер, который не покажет большую часть веба?
                      0

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

                      • НЛО прилетело и опубликовало эту надпись здесь
                          0
                          Судя по всему вы «в теме» про багованные ХТМЛ.
                          Существует стандарт по парсингу и исправлению ХТМЛа с ошибками?

                          Лет 10 назад я написал свой парсер хтмл и рендер машину, и тогда с обработкой ошибками был полный аут, все пытались делать как у микрософта, но он никому ничего не рассказывал и поэтому у всех был свой велосипед.

                          С тех пор что-то изменилось?
                            0

                            Всё описано в спецификации. Там есть чудный алгоритм adoption agency algorithm, а так же reconstruct the active formatting elements.


                            Смотрим как оно работает в описании.


                            Следует помнить, что сайт заблокирован, под руку попали когда телеграмм блокировали.

                              0
                              Спасибо. Но я чуть про другие баги.

                              Есть ли например принцип, по которому «живые» тэги, попавшие например в незакрытый !--, «вытаскиваются» и обрабатываются.

                              Или ХТМЛ в котором 2+ BODY каждый со своими парметрами; style где то по середине и тому подобная хрень.

                              IE это все обрабатывает, но как именно я так и не понял.
                          0
                          который тащится и порождает проблемы, усложняющие разработки и поддержку веб-движков

                          Есть бенчмарки которые говорят, что парсинг HTML это самое тяжелое место?

                            +1
                            Мне кажется в статье и у вас подразумевается разный багаж. В статье говорится про багаж от ранних версий движков, что совершенно не нужно новому. А вот от багажа веба никуда не деться, он как раз нужен и от него, я надеюсь, автор статьи не собирается отказываться.
                          +3

                          Хотите изменить — изменяйте. Есть же комитет по стандартизации. А делать движок не по стандарту — это плохо. С ИЕ уже проходили.

                        +1

                        Кстати, знаете, что «самозакрывающиеся» теги в HTML (например, <img src="pic.jpg" />) — это, на самом деле, ошибка синтаксиса, которую браузеры в соответствии со стандартом игнорируют?

                          0
                          Так ведь в HTML5 это пофиксили. Там можно не указывать слеш перед закрытием. Но да, если слеш есть его игнорят.
                            +1

                            Раньше тоже не нужно было.

                            +4
                            Это не ошибка, это часть стандарта XHTML, в соответствии с которым каждый тэг должен быть закрыт. Допустимо писать как <img></img>, так и, чтобы было короче и красивее, <img />.

                            Жаль, что этот стандарт не получил развития.
                              0

                              Для режима XHTML также нужно сообщить браузеру об этом. Например, передать mime-тип application/xhtml+xml.

                              +3

                              Это не ошибка:


                              Then, if the element is one of the void elements, or if the element is a foreign element, then there may be a single U+002F SOLIDUS character (/). This character has no effect on void elements, but on foreign elements it marks the start tag as self-closing.
                              0

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

                                0
                                Это не криво написанная страница, а стандарт. Сейчас, валидная страница html вообще должна содержать только доктайп, остальное — по желанию.
                                Яндекс — Гугл построены на одном движке — Хромиум, который выведет даже содержимое текстового файла с расширением html без доктайпа и тегов.
                                  0
                                  Яндекс-то к чему приводить в пример? Такой же клон Хрома, как Opera, Maxthon, SlimJet и сотни других. И не то чтобы он был особо популярен.
                                    0
                                    Скоро будет: это очевидный основной кандидат на роль импортозамещающего браузера. По крайней мере, если конкурс или что там будет будет более-менее объективным.
                                      0
                                      Но он при этом, когда я его тестил года в 2015, тормозил сильно сильнее Хрома (во многом благодаря навороченному UI), и сам интерфейс был менее удобен, и слишком уж контрастен. Напоминал нынешний дефолтный UI Firefox 57+, который чёрно-белый.

                                      Если он стал лучше — то супер, но я почему-то не уверен :)
                                +17
                                Здравствуйте!

                                Могу я попросить Вас привести более страшный пример кода с умными указателями? Моя проблема заключается в том, что я не увидел страшного кода по приведённой Вами ссылке.
                                  +6

                                  Поддерживаю. Что страшного? Разве что много вложенных шаблонов, но это в принципе на С++ зачастую так, даже без умных указателей.


                                  RefPtr<HTMLCollection> { downcast<Document>(ownerNode()).allFilteredByName(name) }

                                  Это какой-то свой умный указатель вебкита?


                                  Вообще, идея отказа от умных указателей выглядит очень сомнительной. Не думаю, что именно из-за них браузеры такие тяжелые, зато они помогут не так часто выстреливать себе в ногу утечками памяти. Я немного поискал: 1, 2


                                  • unique_ptr не имеет оверхеда по памяти и имеет оверхед по производительности в конструкторе.
                                  • shared_ptr имеет оверхед по памяти на счетчик, оверхед по производительности в конструкторе, деструкторе, операторе присваивания. Зато разименование без оверхеда.
                                  • По результатам у обоих в конструкторе с включенной оптимизацией небольшой оверхед.
                                    +18

                                    Да ладно страшный пример кода с умными указателями.


                                    Я открыл рандомный файл (вот серьёзно, первое, во что я тыкнул), и тут прекрасно всё, можно разбирать на цитаты.


                                    1. USVString(const std::string str) : data_(str) {} и товарищи — это пять. Можно было бы написать (std::string str) : data_(std::move(str)) {}, можно было бы хотя бы (const std::string& str) : data_(str) {}, но мы возьмём худшее из двух миров. И мы возьмём худшее вместо того, чтобы жить в 2011 2018 году, когда с нами уже 7 лет как move-семантика, и ей бы неплохо научиться пользоваться, мы напишем стопицот перегрузок конструктора, вместо изящного и лаконичного


                                      UVString(std::string str) : data_(std::move(str)) {}
                                      UVString(const UVString&) = default;

                                      Это будет делать то же самое, только эффективнее. Писать конструкторы отдельно от const char*, отдельно от строк и всё такое в 2018 году не нужно уже 7 лет как.


                                    2. inline в определяемых в определении класса функциях не имеет смысла. Вообще.


                                    3. operator+= клёвенькие. Вместо data_ += str.data_ (что делает не более одной аллокации, а потенциально может обойтись и без них) мы делаем data_ = data_ + str.data_. Одна аллокация гарантирована. С оператора присоединения одного символа я… Ну, в общем, да, спасибо.


                                    4. Если бы я заботился о производительности, я бы добавил &&-перегрузки toUpper, toLower и подобных.


                                    5. dublicate, возвращающий, видимо, новую строку на хипе сырым указателем — это тоже очень хорошо. Зачем он нужен? Чем не устроил конструктор копирования? Так много вопросов, так мало ответов.


                                    6.     inline bool hasChar(const char str, unsigned long startsAt)
                                          {
                                              const char* i = strchr(this->data_.c_str(), str);
                                              if(i != NULL)
                                              {
                                                  if(i - this->data_.c_str() >= (int)startsAt)
                                                      return true;
                                              }
                                              return false;
                                          }

                                      Вы это серьёзно? Что оно должно делать и что оно делает? "aaa".hasChar('a', 1) возвращает false, это так и надо?


                                    7. Автор явно слышал про std::to_string, судя по коду выше. Но, видимо, далее захотелось нюхнуть сишца, и появилось


                                          #define m_from(format)          \
                                          char buff[128];                 \
                                          sprintf(buff, format, value);   \
                                          data_ = std::string(buff);
                                      
                                          inline void fromShort(short value)
                                          {
                                              m_from("%i");
                                          }
                                          inline void fromInt(int value)
                                          {
                                              m_from("%i");
                                          }
                                          inline void fromLong(long value)
                                          {
                                              m_from("%li");
                                          }
                                          inline void fromFloat(float value)
                                          {
                                              m_from("%f");
                                          }
                                          inline void fromDouble(double value)
                                          {
                                              m_from("%f");
                                          }

                                      Хотя можно было просто std::to_string(value) в каждом из этих случаев. Правда-правда.


                                    8. Самый главный вопрос. Нафига нужен этот очень тонкий враппер над std::string?



                                    Ща мне за оверхед от умных указателей зато расскажут.

                                      –15
                                      Спасибо за такое внимание к деталям. USVString я как-нибудь поправлю. Теперь на данный момент, c помощью вашего тонкого юмора у меня хорошее настроение, хотя некоторые люди из комментариев могут мне пожелать и плохое.

                                      UPD: Читаю ваш комментарий еще раз и снова смеюсь со свои «ошибочек»
                                        +2
                                        Самый главный вопрос. Нафига нужен этот очень тонкий враппер над std::string?

                                        Главный вопрос C++ программирования и всего такого: а писал ли ты свою реализацию строк/враппер над ними? Вот мужики теперь похвастаться могут.
                                          0
                                          Здравствуйте!

                                          Мне хватило ужаса от приведённых ранее ссылок, а Вы ещё больше пугаете.

                                          Мои варианты ответа на вопросы:
                                          2. Я бы постарался уменьшить количество таких inline методов в определении класса в принципе. Во-первых, это значительно усложняет понимание интерфейса класса, т.к. необходимо в куче кода выловить прототипы функций-членов. Во-вторых, если код не идеален и приводит к генерации предупреждений компилятора, то для каждого файла, в который включен заголовочный файл с определением класса, эти предупреждения будут генерироваться, что сделает сами предупреждения полностью бесполезными. Я с такой проблемой сталкивался, когда работал с H3D: включение заголовочных файлов H3D приводило к генерации 1500-2000 предупреждений.
                                          6. std::find?
                                          7. Можно поиграться со SFINAE, но в простейшем варианте я бы сделал так:
                                          template<class ValueType> 
                                          void fromValue (ValueType i_value) {
                                              data_ = std::to_string (i_value);
                                          }
                                          
                                            0

                                            2. Да, делайте интерфейсы тонкими.
                                            6. В идеале — да. Можно ещё std::string::find (и даже лучше, я не так давно бенчмаркал, оказалось, что std::string::find существенно быстрее и на уровне memchr).
                                            7. Да, почти. Я не уверен (и сходу не нагуглил), можно ли перегружать std::to_string для поддержки собственных типов данных, или же правильной идиомой будет как со swap:


                                            using std::to_string;
                                            data_ = to_string(value);
                                              0
                                              7. Видимо, как минимум формально, нельзя.
                                                0

                                                Ну, значит, точно надо с using, и SFINAE-акробатика несколько усложняется.

                                              0

                                              Или, как вариант, memchr(string+offset).

                                          –1
                                          Круто!
                                          А есть ли у вас режим редактирования?
                                          Почему спрашиваю: есть всем известные движки html, со всеми наворотами, но совсем нет удобных WYSISYG редакторов более легких форматов — таких как Markdown, FB2/FB3 и т.д. Или их делают на основе движков html типа Webkit и тащат вместе с движками кучу лишнего, т.е. написание такого редактора сводится к затыканию дыр и возможностей вставить в редактор то что там не должно быть. А чего-то простого и минималистичного, не завязанного на браузерных монстров — нет.
                                          +14
                                          Не поймите меня неправильно, но из того, что написано, я понял примерно следующее.
                                          На данный момент ваш движок поддерживает парсинг HTML и кое-как парсинг CSS? Т.е. по сути он не умеет вообще ничего и на данном этапе совершенно бесполезен как таковой?

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

                                          В целом, желаю удачи в этом нелёгком начинании. Был бы заинтересован помочь, если дело сдвинется хотя бы до рендера страничек :)
                                            0
                                            Спасибо большое. До рендера страничек еще пару to-do листов, а после рендера я сделаю интерактивное выделелние и поддержку contenteditable.
                                              +6
                                              Просто люди любят глазами. Представьте, что вы приходите к потенциальным инвесторам и заявляете, что пишете новый супер браузер, который будет лучше, быстрее и вообще качественней, чем все остальные. Инвесторы заинтересованы, вы рассказываете им о вашем крутом парсере, который соответствует всем стандартам и показывает просто невероятные цифры в бенчмарках. Но инвесторам всё-равно, они постоянно твердят вам: «а где посмотреть?»

                                              В данном случае инвесторов можно свободно заменить на читателей. Почитать это хорошо, но хотелось бы чего-нибудь наглядного — какие-нибудь тесты, пусть даже глуповатые типа «парсим миллион тегов в секунду». Это было бы куда более привлекательно, как мне кажется.
                                                +13
                                                Да дело даже не в любви, а просто для браузера визуальный рендеринг страниц — это тот основной функционал, ради которого всё и затевается. Если его нет (ну хоть в каком-то виде) — нет и браузера, есть только набор вспомогательных кирпичей.
                                                  +1
                                                  А я немного не согласен, очень часто может пригодится headless движок, если надо заниматься парсингом информации с сайтов.
                                                    +2
                                                    Парсинг — это парсинг, не браузер.
                                                    А браузер, даже headless, всё равно обязательно подразумевает рендеринг (просто headless не показывает результат на экране).
                                                    +2
                                                    Рендеринг и компоновку я еще успею сделать, а вот api, css каскадирование, и прочее нужно обязательно сделать. Мы же хотим интерактивную страницу, а не просто статичная нарисованная картинка.
                                                      +1

                                                      Зависит от ировня интерактивности, для начала можно отображать статичную страницу с применеными стилями и, опционально, возможностью перехода по гиперссылке. Как мне кажется, этого уже достаточно, чтобы его можно было начать использовать где-нибудь еще и привлечь внимание разработчиков.


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

                                                        0
                                                        99% что результат этой работы будет один — набор скила и знаний, хотя если цель в этом, то конечно стоит продолжить.

                                                        Движков не 4, а куда больше, десятки если не сотни.
                                                        Парсинг HTML/CSS это меньше 5% от задачи даже с учетом расчета параметров. Хотя все параметры все равно не посчитать — многие от редеринга зависят.

                                                        5% расчет реальных параметров тегов (зависящих от дисплей и их наследование)
                                                        5% рендер имиджей (включая динамические и background всех мастей)
                                                        5% разбивка и рендер текста
                                                        5% рендер с учетом параметра flow
                                                        15% рендер таблиц
                                                        10% веселуха с импут котролами
                                                        5% форматирование после ресайза
                                                        5% движение по документу (скрол линки и т.п.)
                                                        10% борьба с чарсетами, иероглифами и поломанным блин UTF
                                                        5% динамическая загрузка мегабайтных документов и как следствие перефарматирование всего предыдущего
                                                        10% печать документа и особенно инпут контролов :)
                                                        3% доводка для тестовых ХТМЛ (есть где то для проверки стандарта)
                                                        6% обработка багованных ХТМЛ

                                                        и уже не помню, что там еще из время затратного
                                                          0
                                                          Моя версия TODO:

                                                          1. API для DOM (выполнено)
                                                          2. Основное API для CSS OM (выполнено)
                                                          3. Парсеры и сериализаторы всякие (выполнено)
                                                          4. Взвешивание селекторов и проверка элементов на соответствие селекторам (выполнено)
                                                          5. Каскадирование стилей (выполнено)
                                                          6. Генерация контента с помощью псевдо элементов css (выполнено)
                                                          7. Метрика стилей и компоновка
                                                          8. CSS OM API для элементов DOM (ну там, страницу прокрутить)
                                                          9. Рисование всего этого на экран с учетом прокрутки
                                                          10. Возможность выделять страницу
                                                          11. Нативные контролы
                                                          12. Ивенты для псевдо классов CSS
                                                          13. Виртуальная машина JavaScript и события
                                                          14. SVG 2.0
                                                          15. Скачивание самой страницы по HTTPS
                                                          16. А там дальше ваши Canvas, WebGL, Video, XHR, Fullscreen requrest-ы, ...
                                                          17. А, про DevTools забыл, но инспектор dom со стилями думаю будет несложно сделать
                                                            0

                                                            Добавьте пож. иерархию Display Object как во флеше.
                                                            Максимально общее API для SVG,canvas и css. Поддержка use обязательна!
                                                            Многопоточность и многоядерность (т.е таймлайн в виде куба с переключением контекста по ядрам и процессам).
                                                            Всё остальное можно докодить ручками.
                                                            И да это будет JS на стероидах.

                                                        0
                                                        Рендерин это без сомнения тяжко, но когда на рендеринг накладывается селектирование, переходы по тексту, изменение размера браузера, обработка тега INPUT, вывод на принтер. Вот это веселуха по взрослому.

                                                        И все равно это даже не 20% браузера. Надо будет вечность дописывать например, систему загрузки файлов, систему post/get, различные шифрования, поддержку сотен других инструментов.

                                                        ИМХО, нафиг — это все дорого и бесперспективно.
                                                          0
                                                          Имхо, загрузка файлов — не такая сложная задача (как и менеджер загрузок), шифрование решается с помощью сторонней библиотеки (например, OpenSSL), базовая поддержка HTTP — или кодится ручками путём привлечения новых энтузиастов, или берётся что-то существующее типа Apache Commons, опять же.
                                                      0
                                                      Парсер читает токены слева направо. Для каждого типа свой подход парсинга.

                                                      Правильнее было бы справа налево. Так как в противном случае мы заранее не знаем какого типа будет значение (array или object) Можно конечно свести к одному типу, но это не то.

                                                        0
                                                        Так он справа налево и парсит, ведь существуют еще комбинаторы, которые меняют контекст селекторов перед собой. Заметь, перед собой, а не после. Поэтому надо парсить справа налево. Ну и вообще это в стандарте указано.
                                                          0
                                                          Можно сделать умнее и парсить в обе стороны, а начинать с фрагмента с решёткой (поиск элемента по id). Сильно сэкономит время :)
                                                    +8
                                                    Вот непонимаю, почему крупные заинтересованные компании (Google, Microsoft, Apple, Amazon, и т.п.) не соберутся и не переизобретут велосипед создадут замену для технологий, применяемых сейчас в вебе. HTTP, HTML, CSS имеют столько исторически сложившихся недоразумений, что проще сделать что-то новое, с учетом современных реалий. Тот же Google может запросто добавить поддержку новой технологии в свой браузер. А по прошествии периода адаптации, объявить старый стек технологий небезопасным/устаревшим, как они уже делали с Flash, HTTP.
                                                    Глядишь, и не нужно будет трать столько усилий на написание и поддержку браузерного движка.
                                                      +2
                                                      На большинство таких вопросов легко ответить: посчитайте, сколько это стоит. И сколько прибыли это принесет :) В случае с HTTP люди уже пытаются что-то сделать, однако прошло уже три года, а воз и ныне там. Люди вообще не любят менять то, что «итак работает», да и невыгодно это.
                                                        0
                                                        То же самое говорили про компилеры, например про gcc, внезапно аспирант Chris Lattner плюнул и написал офигенную LLVM, её купил Apple, за пару лет запилили компилеры кучи языков, а щаз на Clang + LLVM перешли кучи проектов и компаний.
                                                          +1

                                                          Компиллятор — он используется локально и генерирует совместимый с существующими ОС и процессорами код.
                                                          Т.е. остальным участникам не нужно ничего менять.


                                                          phantom-code предлагает заменить весь существующий веб на какую-то новую технологию.

                                                            +3
                                                            Чтобы разные проекты — завязанные на gcc — перешли на Clang, нужны причины! И про LLVM вначале говорили, что он не влетит — а затем, что жизнь его лишь в границах Mac OS X, а затем…

                                                            Резюме: временами полезно переписывать с нуля оси, компилеры, браузеры и иные базовые вещи нашего мира. Но бросая всем вызов, лучше быть всё же аспирантом американского универа! ;-)
                                                              –1
                                                              остальным участникам не нужно ничего менять.
                                                              Хе, ну скомпилируйте Linux kernel чем-либо кроме gcc! Apple лишь за пару лет перевёл свою инфраструктуру на LLVM! Аналогичные принципы, компилер — браузер, а веб-ресурсы — программы.
                                                                0
                                                                Андроид, начиная с версии 8 использует clang для сборки всего. Включая ядро.
                                                                  0
                                                                  Хе, ну скомпилируйте Linux kernel чем-либо кроме gcc!

                                                                  www.opennet.ru/opennews/art.shtml?num=47232
                                                                    0
                                                                    Насколько я помню, сам Линус не принимал PR, в котором фиксились UB, которые являются compiler-specified для gcc. То есть то, что оно там на llvm скомпилилось скорее совпадение нежели результат.
                                                                      0

                                                                      Ну вот только разработчики clang годами трудились над приличным уровнем совместимости с gcc, а так да, чистое совпадение.

                                                                        0
                                                                        Они копировали compiler-specific поведение gcc только ради Линукса? Если так, то снимаю шляпу, конечно.
                                                                +1

                                                                Так ваш пример про аспиранта, а не про корпорации. Корпорации намного инертнее одного человека. Может за 20 лет и поменяют, почему нет?

                                                              0

                                                              все так и происходит. Вышеозначенные компании находятся во всех инициативных и исполнительных группах, перепиливают старые стандарты, пишут новые, форсируют переходы на новые технологии.

                                                                –1
                                                                Они просто улучшают текущие технологии, не меняя основную идею. HTTP до сих пор использует отдельное TCP соединение для каждого нового запроса (я в курсе о гугловском SPDY), а информация передается в текстовом виде. Это конечно человекочитаемо и удобно, не спорю, но на практике все сводится к избыточному потреблению электроэнергии, ресурсов компьютера и пропускной способности канала.
                                                                  0

                                                                  у них мировая аудитория. Они допиливают до удобоваримого состояния внедренное, параллельно разрабатывая новое на будущее.

                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                      0
                                                                      Ну вот меня они всем устраивают, например. И что? Как убедить всех подряд, что HTTP/1.1 не торт и пора бы его заменять на HTTP/2, который объективно может быть сколь угодно лучше, а финансово катастрофически невыгоден? HTTP/2 уже 3 года с лишним, а он всё так же нечасто встречается на просторах интернета. Просто возьмите и сами посмотрите запросы к любым сайтам. hbar.com — HTTP/1.1, yandex.ru — HTTP/1.1. У крупных (особенно зарубежных) компаний и брендов HTTP/2 встречается (google, twitter, instagram), но у всяких мелких сайтов 1.1. Есть уже куча готовых сайтов, которые придётся обновлять и вбухивать миллионы для переезда на «новые» технологии, которые попросту не дадут никакого видимого результата.
                                                                      Три года могут показаться «не такими большими», но за 3 года Angular потихоньку поменялся на Electron, а C++14 на C++17. В мире ПО 3 года достаточно, чтобы возникла новая технология и тихо умерла. Так что жить нам с HTTP/1.1 еще очень и очень долго :) И поддерживать его.
                                                                        0
                                                                        HTTP/2 объективно очень плохой протокол и не является заменой HTTP/1.x. Нет у него будущего.
                                                                          0
                                                                          Это был своего рода абстрактный пример для донесения мысли, я не очень хорошо знаю веб и до HTTP/2 мне мало дела. Работает? Хорошо, пусть работает. Мы можем придумать XXXUBERTTP/9001.0 и любой другой мега-хороший и супер стандарт. Но только толку от него, если HTTP работает, и миллионы (если не миллиарды) сайтов успешно работают так, как есть сейчас. В компьютерах всё строится на очень своеобразных решениях, которые диктовались спецификой требований тех лет, легаси коде и костылях. Это везде, не только в вебе или HTTP. Посмотрите на Xorg, Linux Kernel и gcc. Хотя бы на них. Это просто клады легаси кода и поддержки уже давно несуществующих или слишком малозначимых платформ. Люди вон до сих пор находят вакансии на RPG, Delphi и PHP, хотя все они признаны мёртвыми. Ну не денемся мы никуда от легаси.
                                                                          P.S. Кстати Xorg пытались выпилить Вэйлендом, но не взлетело, впрочем примерно понятно, почему. Да и сам Вэйланд почти целиком эмулирует Xorg.
                                                                            0
                                                                            Учитывая, что все дистрибутивы потихоньку переползают на вейленд — странно писать о том, что он не взлетел.

                                                                            Не стоит путать легаси с надежным, проверенным временем решением. Должна происходить постепенная эволюция, а не революции с майданами. Когда горячие головы, терзаемые NIH-синдромом без десятков лет опыта за плечами, приходят с лозунгами: «а давайте всё перепишем!» — ничего хорошего на выходе не получается.

                                                                            Достаточно коротко и ясно происходящее описал легендарный Poul-Henning Kamp в своей заметке: queue.acm.org/detail.cfm?id=2716278
                                                                              0
                                                                              Я бы не сказал, что все дистрибутивы на него «переползают». Как максимум — предоставляют возможность использовать. Ubuntu вон так успешно ввела Wayland, что аж откатилась назад к Xorg в 18.04. Впрочем, учитывая специфику ОС и мира открытого ПО, поставить его может кто угодно и когда угодно, и собрать его можно попытаться подо что угодно. Включение пакета в репозиторий или возможность установить что-то еще не показывает, что он таки взлетел. Максимум находится в том же положении, что и HTTP/2.0
                                                                              Но это всё мелочи, мы сходимся в базовом аргументе — нельзя просто взять и сделать новый Интернет, уже слишком поздно для этого. А всё остальное — холивары :)
                                                                                +1
                                                                                Ubuntu вон так успешно ввела Wayland, что аж откатилась назад к Xorg в 18.04

                                                                                Опять глупости, вы делаете выводы, не располагая даже общеизвестной информацией. Релиз-цикл бунты предполагает выкатывание LTS-релизов, в качестве дефолтов туда попадает самое стабильное, а в промежуточных релизах, соответственно, могут позволить себе больше. И тем не менее, вейланд присутствует как минимум в дефолтном варианте с Gnome, лично я его и использую.

                                                                                  0
                                                                                  но новый интернет уже делается, когда вместо сайта в браузере телефона открывается приложение этого же ресурса, которое взаимодействует с сервером оптимально, а не прогружая почти каждый раз весь интерфейс и данные через HTTP/HTTPS при переходе в другой раздел :)
                                                                                    +2
                                                                                    Половина этих приложений — тот же сайт в браузере, только своём.
                                                                            +2
                                                                            HTTP/2 финансово катастрофически невыгоден

                                                                            Лол, что? Браузеры поддерживают, а в nginx оно включается правкой одной строки конфига. Где чего не выгодно?

                                                                          +4
                                                                          HTTP до сих пор использует отдельное TCP соединение для каждого нового запроса
                                                                          И это правильно, так и должно быть. А от того ужаса, который вышел в виде SPDY и HTTP/2 ещё долго придется плеваться. И да, в результате в SPDY и HTTP/2 гораздо больше накладных расходов.
                                                                            0
                                                                            Я не говорил, что SPDY или HTTP/2 не имеют проблем. Однако, одно соединение на один запрос довольно избыточно. В чем, по вашему, правильность данного метода? Даже для реализации «сессии» пришлось придумывать костыли. Теперь каждый второй сайт уведомляет о том, что он использует cookie и просит понять и простить. А все из-за того, что «это правильно, так и должно быть».
                                                                              +7
                                                                              Однако, одно соединение на один запрос довольно избыточно.
                                                                              В чем заключается избыточность?
                                                                              В чем, по вашему, правильность данного метода?
                                                                              В том, что TCP это протокол транспортного уровня и проблемы транспортного уровня должны решаться на транспортном уровне. Один запрос — это один поток данных. Один поток данных — одно независимое TCP соединение. Это правильно, это позволяет применять flow control на уровне каждого потока, а также роутить эти запросы независимо друг от друга. Они могут обрабатываться разными серверами, они могут идти разными маршрутами. Всё это позволяет лучше масштабировать нагрузку и лучше справляться с ошибками.

                                                                              Даже для реализации «сессии» пришлось придумывать костыли.
                                                                              В чем заключаются костыли? HTTP — это stateless протокол, благодаря этому он очень хорошо масштабируется, с помощью него можно реализовать удобный и красивые RESTfull интерфейсы. Не будь он stateless, костыли бы пришлость расставлять повсюду.

                                                                              Теперь каждый второй сайт уведомляет о том, что он использует cookie и просит понять и простить. А все из-за того, что «это правильно, так и должно быть».
                                                                              Смешались в кучу кони, люди, мухи, котлеты… Каждый второй сайт уведомляет об использовании cookies согласно новому закону евросоюза. Это не имеет никакого отношения к протоколам, а является законодательным актом.

                                                                              Более того, работа с cookies и сессиями, как и вся остальная семантика HTTP — совершенно одинаковая, что в HTTP/1.1, что в HTTP/2 и SPDY.

                                                                              Работу с сессиями вероятно можно было бы улучшить, но это никак не связано с количеством TCP соединений, и ни HTTP/2, ни SPDY — вообще ничего в этом отношении не улучшают.
                                                                                +1
                                                                                В чем заключается избыточность?
                                                                                Установка соединения (SYN->ACK->ACK) с передачей cookies для каждого запроса дает лишнюю нагрузку на сервер и на канал. Для одного клиента она не существенна, но когда клиентов тысячи, она внезапно начинает играть свою роль. А если мы вспомним, что внутри у нас plain text, то становится еще грустнее.

                                                                                Смешались в кучу кони, люди, мухи, котлеты… Каждый второй сайт уведомляет об использовании cookies согласно новому закону евросоюза.
                                                                                Безусловно. Только сами cookies появилсь, чтобы сервер мог хоть как-то хранить на клиенской машине информацию и различать сессии между собой. Исторически, это был именно костыль.

                                                                                HTTP — это stateless протокол
                                                                                Мое исходное сообщение было не про «улучшение» HTTP или HTML, а о полном переосмыслении всего веба. В текущем состоянии эти технологии обладают большой гибкостью, но нещадно жрут ресурсы.
                                                                                Возьмем к примеру QML. По сути QML реализует связку HTML+CSS+JavaScript (безусловно после определенной доработки), но при этом быстрее и выглядит на всех устройствах одинаково. Не требуется для каждой страницы подтягивать портянки bootsrap/jquery/etc (я понимаю, что браузеры кешируют данные, это всего лишь пример).

                                                                                Более того, работа с cookies и сессиями, как и вся остальная семантика HTTP — совершенно одинаковая, что в HTTP/1.1, что в HTTP/2 и SPDY.
                                                                                Доработки и улучшения — это хорошо. Но я говорю о «попробовать спроектировать с нуля исходя из текущего опыта». Я понимаю, что это не быстрый процесс и его внедрение может занять многие годы. Но иногда требуется отбросить обратную совместимость и дать дорогу чему-то принципиально новому.
                                                                                  0

                                                                                  С сжатием уже не plain text. Да, остаются еще заголовки, но есть WebSocket.


                                                                                  но при этом быстрее и выглядит на всех устройствах одинаково.

                                                                                  Он быстрее ровно настолько, насколько оптимизирован Qt. При этом там так же есть свои нюансы. Например под iOS нет JIT компилятора для QML.

                                                                                    0
                                                                                    С сжатием уже не plain text. Да, остаются еще заголовки, но есть WebSocket.
                                                                                    На сжатие/распаковку требуются ресурсы процессора (как сервера, так и клиента).

                                                                                    Он быстрее ровно настолько, насколько оптимизирован Qt. При этом там так же есть свои нюансы. Например под iOS нет JIT компилятора для QML.
                                                                                    Конкретно QML был всего-лишь примером.

                                                                                      0
                                                                                      На шифрование-дешифрование тоже требуются ресурсы процессора. Может тогда от HTTPS отказаться тоже? А неизмеримо бОльшие ресурсы требуются на поддержание электрического или беспроводного подключения сетей, и эта мощность лишь частично коррелирует с трафиком. И львиную долю трафика составляется не текстовый контент (в конце концов способность человека воспринять текст ограничена физиологически), и даже не код скриптов (и кстати, подумайте, как его передавать бинарно и при этом не навредить разнообразию скриптовых механизмов, гарантирующему их развитие, а также безопасности их выполнения), а видео и фото, которые сжаты максимально. Я думаю, вы сейчас не ту задачу решаете.
                                                                                    +3
                                                                                    Установка соединения (SYN->ACK->ACK) с передачей cookies для каждого запроса дает лишнюю нагрузку на сервер и на канал. Для одного клиента она не существенна, но когда клиентов тысячи, она внезапно начинает играть свою роль. А если мы вспомним, что внутри у нас plain text, то становится еще грустнее.
                                                                                    Нагрузка от TCP хэндшейка просто смешная по сравнению с дополнительной нагрузкой, которую дает реализация ещё одного пакетного слоя для мультиплексирования и ещё одного flow control внутри соединения. Для работы HTTP/2 требуется больше накладных расходов и больше пересылать TCP-пакетов, а также расходуется больше памяти и больше процессорных ресурсов. А внутри по сути такой же plain text, который также нужно парсить.

                                                                                    Безусловно. Только сами cookies появилсь, чтобы сервер мог хоть как-то хранить на клиенской машине информацию и различать сессии между собой. Исторически, это был именно костыль.
                                                                                    А как нужно их хранить и где по вашему? В чём же заключается «костыль» и кто мешает хранить простой ключ сессии, как в общем-то многие и делают?

                                                                                    Но иногда требуется отбросить обратную совместимость и дать дорогу чему-то принципиально новому.
                                                                                    Наверное такие решения должны прорабатываться, обсуждаться и приниматься с особой осторожностью, чтобы не сломать то, что работает годами, не сделать хуже. А сейчас мы видим то, что большие корпорации проталкивают свои протоколы в своих корыстных целях, при этом заставляя всех остальных страдать. Как в своё время было с Microsoft и IE, сейчас то же самое происходит, только в руках одной мегакорпорации оказались, как самые популярные браузеры так и самые посещаемые веб-ресурсы, а потому они в результате затачивают веб под себя, наплевав на остальных. Имея при этом большие маркетинговые ресурсы, они всё это подают под соусом улучшений и инноваций, легко одурачивая основную массу, которая плохо себе представляет работу сетевых протоколов и повторяет из статьи в статью одни и те же заблуждения касательно HTTP/1 vs 2.
                                                                                      0
                                                                                      А как нужно их хранить и где по вашему? В чём же заключается «костыль» и кто мешает хранить простой ключ сессии, как в общем-то многие и делают?
                                                                                      Я бы хранил все данные на сервере и отдавал клиенту только его ID или ID сессии. Костыль заключается в том, что сначала был разработан stateless HTTP, а уже потом появилась необходимость различать сессии/клиентов, в результате чего появились cookies. Конечно, если рассматривать stateless как преимущество, то это уже не костыль. Лично я не вижу особой необходимости в stateless протоколе, но готов поверить вам, т.к. в данном вопросе не имею достаточно опыта.

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

                                                                                        Так собственно, в большинстве случаев все так и работает — сервер хранит все у себя, а клиенту отдает ID в виде одной куки.


                                                                                        Вообще, кука в любом случае нужна, ибо мир не идеален, и сессии могут рваться. В вашем случае — клиент переподключается и получает новую сессию. А если он хочет восстановить старую — ему опять же нужна кука в каком-то виде.

                                                                                          0
                                                                                          Или его личный уникальный ID, который он сообщает серверу.
                                                                                            0
                                                                                            Ну вот этот самый личный уникальный ID и будет кукой. Суть то не меняется.

                                                                                            И опять же, тут возникают вопросы — если этот ID придумывает сервер — то это совершенно ничем не отличается от куки.

                                                                                            Если ID выбирает клиент — то как гарантировать уникальность? Как защититься от перебора? Надо что-то типа GUID, и то GUID не гарантирует защиту от перебора. Нужен более длинный идентификатор. Дальше — один GUID для всех серверов? Так нельзя, потому что тогда юзера можно трекать по всему Интернету без особых проблем. Значит нужно генерить GUID для каждого сайта.

                                                                                            Тут возникает вопрос с поддоменами. a.example.com и b.example.com — это разные сайты или один? На самом деле может быть и так и так.

                                                                                            В общем случае — разные, значит будут свои GUID. Значит, нельзя трекать авторизацию между подсайтами. Например, если я хочу оставить комментарий на user1.livejoural.com — мне надо логинится. Если потом хочу оставить комментарий на user2.livejournal.com — надо логиниться снова, потому что GUIDы будут разные и сайт не узнает что я — это я. С куками проще. Сайт выдает куку для *.livejournal.com и все.

                                                                                            Ну и самое страшное — уже писали сверху. Веб становится строго stateful и значит резко усложняется горизонтальное масштабирование. Грубо говоря, в куку можно запихнуть id пользователя, подписать ее и тогда любой сервер кластера будет знать что вы — это вы, даже без синхронизацию через общую базу.
                                                                                        0
                                                                                        Нагрузка от TCP хэндшейка просто смешная по сравнению с дополнительной нагрузкой, которую дает реализация ещё одного пакетного слоя для мультиплексирования и ещё одного flow control внутри соединения.
                                                                                        Она по нагрузке на ЦП, может, и смешная, а вот по времени и оверхеду данных, особенно для маленьких файлов — настолько несмешная, что бандлинг JS и CSS сейчас почти везде используется по умолчанию. И это я ещё молчу про тайлинг картинок.
                                                                                      +2
                                                                                      В том, что TCP это протокол транспортного уровня и проблемы транспортного уровня должны решаться на транспортном уровне. Один запрос — это один поток данных. Один поток данных — одно независимое TCP соединение.

                                                                                      Звучит правильно, но… но… ведь так можно оправдать дизайн протокола FTP :-)

                                                                                        +4

                                                                                        А что с ним? Если не учитывать неактуальные уже фичи типа перекодирования байтов, и неактуальные на момент создания протокола вопросы безопасности, он прекрасен своей простотой и тем, что работает. Просто работает. И понятно куда смотреть, если не работает как ожидалось.

                                                                                          0
                                                                                          Насколько я читал в старенькой книжке середины нулевых, там со скоростью передачи всё плохо (по каким-то неведомым причинам, которых я не понял).
                                                                                            0

                                                                                            Наоборот :) команды передаются по tcp в похожем на http текстовом виде, а данные — в отдельном tcp соединении, просто байты без мультиплексирования, оверхеда на какие-нибудь заголовки и переконвертирование. То есть передача файла работает всегда с максимальной скоростью, сколько можно выжать из tcp в данном канале. Но многие реализации серверов имеют упоротые лимиты и дефолтные настройки, например размеры буферов, поэтому можно наблюдать тормоза на ровном месте.

                                                                                  0
                                                                                  информация передается в текстовом виде
                                                                                  Информация давно уже передаётся в сжатом виде, а текстовый оставлен только для совместимости.
                                                                              +1
                                                                              А разработка нового стандарта породит два рода проблем:
                                                                              1) Производителям браузеров все равно прийдется поддерживать старые стандарты, так как на них написано уйма сайтов, которые обновляться не будут, но которые могут быть важны отдельным пользователям.
                                                                              2) Надо переучиваться всему сообществу веб разработчиков, выпускать новые книги, новые учебные курсы и т.п. — это встретит большое сопротивление!
                                                                                0
                                                                                На самом деле не совсем, вот есть у нас например всякие телеграмм, whatsup, fb мессенджеры. Ими пользуются сотни миллионов людей, под них уже сейчас пишутся боты для интерактивного взаимодействия системы и человека. С таким же успехом, как выпустили fb мессенджер, facebook может сделать зеркало своего сайта на новой технологии и выпустить для него браузер и сказать «Люди, пользуйтесь, пилите свои сайты вот на этом новом html10». И поставят люди себе декстопный клиент под facebook, и начнут программисты писать сайты в том числе и под новый стандарт(а скорее всего система сборки будет и под новый и под старый собирать сама). Так что старый легаси вообще не проблема, будет просто у людей браузер для старых сайтов и для новых. Проблема думаю в том, что люди которые понимают как это сделать, не видят в этом смысла, потому что в конце концов получится такой же монстр.
                                                                                  +1
                                                                                  Да, так можно, но только это не будет браузер для Веба — это будет браузер для facebook.
                                                                                  И вот такое расщепление веба на внутренние стандарты — это худше что можно для него придумать…
                                                                              +17
                                                                              насколько ли реально создать достойную альтернативу крупным проектам, история которых начинается с девяностых годов. Мой новый движок создается с нуля, а значит его история начинается — сегодня.

                                                                              Servo — тоже новый движок, разрабатываемый настолько с нуля, что под него даже новый язык программирования написали. Используются современные возможности, такие как многопоточность и рендеринг через GPU. Трудятся над ним больше десятка инженеров, сделавшие уже 34 тыс. коммитов, но до приемлемого состояния ещё очень далеко.

                                                                                –2
                                                                                угу. Нахрена тратить время на C++, если проблемы языка очевидны настолько, что целые языки придумывают под браузеры. Тот же раст например.
                                                                                  –1
                                                                                  Не завидую я этим инженерам. Писать не что-нибудь, а браузер — программу, где полным-полно связанных списков и деревьев, на языке, в котором даже нет полноценного ООП, и многие паттерны проектирования реализуются через тонны костылей — это ж врагу не пожелаешь…
                                                                                    +4

                                                                                    Функциональные языки при обработке связанных списков и деревьев как-то же без ООП обходятся.

                                                                                      +1

                                                                                      Я писал дерево отрезков, Фенвика, декартово и много других структур данных. И каждый раз это примерно 2 шаблонные структуры. В Расте такое делается также без проблем.

                                                                                        +5

                                                                                        Связные списки и деревья именно что хорошо обрабатывать на функциональщине. ООП и вот эти вот все паттерны там не то что не нужны, а вредны.

                                                                                        0
                                                                                        А что не так с его состоянием? Вроде работает шикарно.
                                                                                          +1

                                                                                          Думаю, если бы он действительно работал шикарно уже сейчас, то заменил бы Gecko в Firefox.

                                                                                            +4
                                                                                            Нововведения из Servo и так постепенно переносят. Servo же целенаправленно и разрабатывается как замена Gecko.
                                                                                              0
                                                                                              Только не замена, а тестовый полигон. Имеено для обкатки новых частей, которые потом переносят. Хотя в итоге и может всё прийти к, по сути, одному двужку — такой цели никто не заявлял.
                                                                                                0
                                                                                                Да, вы правы
                                                                                            0

                                                                                            Например, https://github.com/servo/servo/issues/13495.


                                                                                            И гитхаб выдаёт ещё 115 незакрытых багов с меткой I-wrong для самых разных сайтов.

                                                                                          +1
                                                                                          Те ошибки, которые были допущены на начальных стадиях разработки остаются в проекте до конца. Самый яркий пример этому — умные указатели в C++

                                                                                          Только вот «наследие со времен 90-х» не помешало Google после форка WebKit в Blink выпилить там умные указатели и завезти Garbage Collector, как и сделав красивее код, так и решив некоторые другие проблемы с работой с памятью.
                                                                                            +32

                                                                                            Привет!


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


                                                                                            1) Каким спецификациям соответствует парсинг HTML? Я так понял, что вы из головы написали парсер. Штука эта давольно сложная, тем более чтобы написать её правильно с заделом на будущее. Судя по вот этому о скоростях мечтать не приходится. Это действительно весь HTML парсер? Это тоже странно выглядит.


                                                                                            2) Каким спецификация соответствует парсинг CSS? Опять же, судя по коду никаким. Вы просто взяли из головы то, что знаете о CSS и сделали для этого парсинг. Вообще, CSS раздербанить ни фига не простая задача. Уж поверьте моему опыту.


                                                                                            3) У вас не верно сделана сериализация HTML. Точнее сказать, она сделана из каких-то ваших соображений. В спецификации чётко описано поведение сериализатора.


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


                                                                                            А теперь попугаю, немного :).


                                                                                            У вас исходники всего этого дела занимают 312КБ. Чтобы хоть как-то оценить насколько ничего нет: в проекте lexbor один только html парсер занимает 1.8МБ. DOM, в котором почти ничего нет, только минимум для создания и удаления нод, элементов, атрибутов 100КБ.


                                                                                            Чтобы понять масштаб того, что надо делать посмотрите мой roadmap, и это процентов 10 от полноценного браузерного движка.


                                                                                            Ваши бы силы да в нужное русло.
                                                                                            Поправьте меня если я где-то ошибся.

                                                                                              –7
                                                                                              Насчет размера.

                                                                                              Я не понял, важнее функционал или размер исходников?
                                                                                                +20
                                                                                                Дмитрий, важен не размер, нет.

                                                                                                Важно, чтобы ожидания сходились с заявлениями. У вас, к сожалению, нет парсера HTML, CSS, у вас нет сериализаторов. Да и странно заявлять о сериализации даных. Куда важнее заявить о парсинге чанков, парсинге фрагментов. У вас нет работы с неймспейсами. Не знание HTML спецификации сразу кинулось в глаза после фраз о кавычках, это самое стандартное поведение, зачем это оговаривать отдельно? У вас есть что-то, что вы сами придумали и назвали это парсером HTML, CSS.

                                                                                                Я никак не пытаюсь «наехать». И я искренне обрадовался когда прочитал заголовок, но по факту у вас пустышка + непонимание базовых вещей. Если вы хотите, то можете написать мне, что нибудь да обсудим.

                                                                                                Размер тут как показатель, на глаз прикинуть.
                                                                                                  0
                                                                                                  Александр, спасибо за конструктивную критику, она действительно важна для реализации сложных проектов. С удовольствием обсудим проект.
                                                                                                    –4
                                                                                                    А что такое чанки и фрагменты, и зачем их парсить?
                                                                                                      +4

                                                                                                      Чанки (chunks) — фрагменты.
                                                                                                      Браузеры процесят хтмл кусками. Прилетело по сети 4к данных, эти данные идут на парсинг и так далее. Данные могут быть прерваны в любом месте, соответственно и продолжить обработку надо уметь с того места где закончил. Но, тут магии нет, если ты посмотришь на спецификацию то поймешь, что она написана так, чтобы это работало "из коробки". Токенизатор на вход принимает codepoint (unicode) по одной штуки и решает куда дальше рулить. Это обычная стейт машина.


                                                                                                      Фрагменты — парсинг хтмл фрагментов очень важен. Это так называемый innerHTML. Штука эта довольно тяжелая для выполнения. Как оно должно работать так же описывает спецификация. Тяжелая она потому, что для неё необходимо создавать новый парсер, новый Document объект и root element + всякая логика.


                                                                                                      Сделать, хотя бы, парсинг хтмл быстрым задача тоже интересная.


                                                                                                      Ты, конечно, молодой и активный. Но прежде чем делать громкие заявления изучи как устроены текущие браузеры, посмотри почему они все отрабатывают страницы одинаково (спецификации).
                                                                                                      Конечно, фигачить из головы куда интереснее. Делать что-то по спецификациям нудное занятие.
                                                                                                      Чтобы что-то сделать лучше необходимо понять текущие проблемы. Нужен опыт. У тебя, к сожалению, опыт отсутствует как в программировании так и в понимании браузерных движков.


                                                                                                      Но шуму ты наделал много.

                                                                                                        0
                                                                                                        Хорошо, спасибо! Да, и у меня еще поддерживается get/set innerHTML и get/set outerHTML.
                                                                                                          +1

                                                                                                          Эх, вы либо вообще не понимаете о чём я пишу, либо, я даже не знаю. В общем, удачи вам.

                                                                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                              +1
                                                                                                              Ну, всё равно. За отвагу большой плюс.
                                                                                                              Я ему уже выше писал, что если захочет то пусть пишет мне лично, расскажу, что знаю.
                                                                                                          0
                                                                                                          А мне объясните пожалуйста, зачем для фрагментов создавать новый рут и новый парсер? Это же ресурсов дофига жрать будет, и будет дико тормозить. Можно пример сценария, где это реально необходимо (фреймы и айфреймы — не в счёт, тут без вопросов)?
                                                                                                            +1

                                                                                                            Ну, а как вы создадите ещё одно дерево? Понятно, что парсер можно создать один раз и держать его при себе. Всё остальное прийдется создавать каждый раз. Потому, что во время парсинга всё это используется/необходимо. Думаю, напишу статью о том как всё устроено в хтмл. Можете посмотреть в спецификацию: https://html.spec.whatwg.org/multipage/parsing.html#parsing-html-fragments


                                                                                                            Собственно, по этому innerHTML крайне дорогая штука в браузерах. innerHTML — это и есть парсинг фрагмента. Всегда лучше пользоваться напрямую через интерфейсы.

                                                                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                0

                                                                                                                Нет. Не быстрее.


                                                                                                                Дорого звать из js функции движка. innerHTML быстрее если нафигачить туда много HTML. Если сделать чистый тест по одному тегу, к примеру


                                                                                                                <div>Текст</div>

                                                                                                                и покрутить в цикле с реальным добавлением в текущий документ, то innerHTML проиграет в 3-4 раза.


                                                                                                                Более того, если в innerHTML отдать сразу 1000 тегов и тоже самое создать с помощью дом то время выполнения будет почти одинаковое.


                                                                                                                Но если в innerHTML зафигачить сразу кучу хтмл-а то он отработает быстрее. Потому, что он сразу передаст всё в движок и не будет делать вызовы по Н раз.


                                                                                                                Отсюда, надо понимать, что и как использовать.


                                                                                                                Код для примера:


                                                                                                                1-2 mc


                                                                                                                <div id="aaa"></div>
                                                                                                                
                                                                                                                <script>
                                                                                                                    let aaa = document.getElementById("aaa");
                                                                                                                
                                                                                                                    let t0 = performance.now();
                                                                                                                    let node;
                                                                                                                
                                                                                                                    for (let i = 0; i < 1000; i++) {
                                                                                                                        if (node) {
                                                                                                                            aaa.removeChild(node)
                                                                                                                        }
                                                                                                                
                                                                                                                        node = document.createElement("div");
                                                                                                                        let text = document.createTextNode("Text " + i);
                                                                                                                
                                                                                                                        node.appendChild(text);
                                                                                                                        aaa.appendChild(node);
                                                                                                                    }
                                                                                                                
                                                                                                                    let t1 = performance.now();
                                                                                                                
                                                                                                                    let res = document.createTextNode("Time: " + (t1 - t0) + " milliseconds.");
                                                                                                                    aaa.appendChild(res)
                                                                                                                </script>

                                                                                                                7-8 mc


                                                                                                                <div id="aaa"></div>
                                                                                                                
                                                                                                                <script>
                                                                                                                    let aaa = document.getElementById("aaa");
                                                                                                                
                                                                                                                    let t0 = performance.now();
                                                                                                                
                                                                                                                    for (let i = 0; i < 1000; i++) {
                                                                                                                        aaa.innerHTML = "<div>Text " + i + "</div>";
                                                                                                                    }
                                                                                                                
                                                                                                                    let t1 = performance.now();
                                                                                                                
                                                                                                                    let res = document.createTextNode("Time: " + (t1 - t0) + " milliseconds.");
                                                                                                                    aaa.appendChild(res)
                                                                                                                </script>
                                                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                    0

                                                                                                                    Я ну пойму, вы что хотите доказать?


                                                                                                                    Я вам доказал, что innerHTML внутри отрабатывает дольше на простом примере. Зафигачте 1000 элементов через innerHTML:


                                                                                                                    var html = "<div>Текст 1</div>...<div>Текст 1000</div>"
                                                                                                                    aaa.innerHTML(html)

                                                                                                                    B попробуйте создать те же самые элементы в цикле через дом добавляя их по одному в aaa.appendChild(node).


                                                                                                                    Скорость будет почти одинаковая. Это как доказательство, что основное время уйдет на оверхед.
                                                                                                                    Я опроверг ваше заявление:


                                                                                                                    Но innerHTML и DOMParser.parseFromString отрабатывает быстрее, чем постройка дом-дерева через методы DOM API по отдельности.

                                                                                                                    Опять же, выше я вам объяснил где будет выигрывать innerHTML.


                                                                                                                    Что это за синтетический тест, с измерением перфоманса на создание 1-2 дом узлов, когда один из них текстовый? Зачем это нужно делать через парсер адекватному человеку?

                                                                                                                    Вполне себе хороший тест. Показывает, что innerHTML медленнее. А точнее то, что вы не правы со своим заявлением, что он быстрее.


                                                                                                                    Давайте вы добавите в свой узел пару другую вложенных элементов, а еще назначите им атрибуты. И замерите снова.

                                                                                                                    Простите, но добавляйте сами, что хотите. Простым примером вам было показано как оно отрабатывает. Я хорошо знаю как оно устроено внутри и могу создать тесты там где inner выиграет и проиграет. Но выше я создал именно голые тесты, равные условия, чтобы показать, что вы не правы.


                                                                                                                    При этом я дописал, что:


                                                                                                                    Отсюда, надо понимать, что и как использовать.
                                                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                      +1

                                                                                                                      Вы специально искажаете всё? Читайте комментарий выше.
                                                                                                                      Я говорил, про 1000 элементов, а вы тут тестите 100000 тысяч.


                                                                                                                      Да, я выше написал, что innet будет выигрывать если ему много сразу зафигачить. Потому, что оферхеда не будет на вызов функций из js.


                                                                                                                      Но, даже при этом, при вашем тесте с котором я согласен был даже выше, что innet будет выигрывать если ему много дать, построение дом проигрывает всего в два раза. При вызове 100000 функции которая сходит в движок.

                                                                                                                        0
                                                                                                                        Кстати, я полностью переписал парсер селекторов CSS. Зацените github.com/FlightBlaze/Newtoo/tree/master/modules/assembly/selector. Кроме того, я ещё сделал концепцию новой оси github.com/FlightBlaze/mushroom.

                                                                                                                        Извините, что не в тему.
                                                                                                                          +1

                                                                                                                          main.cpp закомитьте для начала, а в оси ещё нечего смотреть, даже поведение UI не описано толком.

                                                                                                                            0
                                                                                                                            Я не увидел там главного: drafts.csswg.org/selectors-4/#grammar

                                                                                                                            Чувак, реально, ты тратишь силы в пустую. Это круто для опыта, но толку от этого никакого. Хотя, скорее всего, в твоём возрасте толк и не нужен, я хз.
                                                                                                                              0
                                                                                                                              А, так это синтаксис. Вот он у меня github.com/FlightBlaze/Newtoo/blob/master/modules/assembly/selector/SelectorSyntax.h

                                                                                                                              Только не кидайте тапками, если имели ввиду другое.
                                                                                                                                +1
                                                                                                                                Слушай, ну никто в тебя тапками кидать не собирается.
                                                                                                                                Нет, не то. Твоя ссылка это не синтаксис. Я привел ссылку на граммар. То есть, то как надо парсить токены которые создает синтаксический парсер css ( drafts.csswg.org/css-syntax-3/#tokenization ). В парсере css ты получаешь токены, не байтовый поток и не юникод. Читай ссылку.
                                                                                                        –4
                                                                                                        Я вот тоже пилю свой браузер. Точнее пока что браузер внутри браузера, а когда обкатаю алгоритмы, то уже нативной реализацией займусь. Только моя мысль в том, что нет смысла реализовывать весь тот легаси, что накопился за десятки лет, а ограничиться какой-то своей простой гибкой спекой, так что сайты, написанные с учётом этой спеки, получат все преимущества новой лёгкой, быстрой и гибкой реализации, а остальные будут просто открываться во встроенном chromeframe.

                                                                                                        Вообще, я тут создал чат в телеграме. Присоединяйтесь, будем обмениваться идеями :-) t.me/dev_browser
                                                                                                          +2
                                                                                                          О каком легаси вы пишете? В спеках всё довольно логично и понятно. Есть, конечно, шероховатости, но в целом всё ясно.
                                                                                                          Как вы поймёте, что сайт «нормально» отображается с помощью вашего движка? Что это будет за урезанная спека которая сможет предоставить весь нужный набор опций для верстки и будет лучше чем сейчас?
                                                                                                          Чтобы вам хоть как-то попытаться пропихнуть свою спеку вам надо стать гуглом, и то не прокатит.

                                                                                                          Есть стандарт который все знают и поддерживают, опираются на него. Идея написать свой движок, но если чего отдавать на отрисовку гуглу за гранью разумного.
                                                                                                            –1
                                                                                                            Да хотя бы даже фривольности с незакрытыми тегами в HTML. Можно ограничиться XHTML парсером, чем значительно упросить и ускорить реализацию. От разработчиков обеспечить совместимость с xhtml не составит труда. Кучу устаревших css свойств, вендорных префиксов и прочего барахла можно смело выбросить, опять же описав что использовать не следует, а что следует использовать вместо.
                                                                                                            Определять просто — специальным флагом в коде разработчик явно берёт на себя обязанность соблюдать более строгие требования. Подумать о том, как можно было улучшить текущий стек, я и предлагаю подумать. У меня, разумеется есть куча идей разной степени тяжести.
                                                                                                            И давайте вы свой пессимизм оставите ведру с крабами. Возможно тот же гугл заинтересуется проектом, когда он покажет свои преимущества. Глаза боятся — руки делают. А если вам страшно так, что руки немеют — так вас никто не заставляет. Каждый сам решает чем ему интересно заниматься.

                                                                                                            Никто не знает веб стандарты в полной мере. Это одна из бед этого переусложнённого бардака.
                                                                                                          0
                                                                                                          Судя по вот этому о скоростях мечтать не приходится. Это действительно весь HTML парсер? Это тоже странно выглядит.

                                                                                                          Там кстати можно применить оптимизацию habr.com/post/166201
                                                                                                          У html тегов длиннее 9 символов начальные части не пересекаются, поэтому их можно отбросить при вычислении хэша.
                                                                                                            0
                                                                                                            Тот кусок вообще нужно выкинуть, зачем его оптимизировать? Тем более так спичечно
                                                                                                          +4
                                                                                                          Насколько я понял из первых абзацев, вы считаете, что умные указатели — это зло?
                                                                                                          Хм, интересная точка зрения. И деструкторов в классах я что-то тоже не вижу, очень интересно)
                                                                                                            –2
                                                                                                            Garbage collector у меня в to-do, можете не переживать по этому поводу.
                                                                                                              +2
                                                                                                              Может проще было взять язык со встроенным GC? Тот же D — отлично бы подошёл.
                                                                                                                0

                                                                                                                Всё же парсеры и вот это вот всё лучше писать на функциональщине.

                                                                                                                +5

                                                                                                                Вы уверены, что GC это добро?

                                                                                                                  0
                                                                                                                  Если решитесь, то сначала хотя бы полистайте одну полезную книжку.
                                                                                                                +17

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

                                                                                                                  +2
                                                                                                                  JS нет. Рендеринга нет. DOM-дерево не оптимизировано. Точнее автор даже не доказал, что оно оптимизированное и корректное. Что его модель вообще будет рисоваться и ложиться на GPU. Что там корректный байт-код или он собирается строки гонять на каждый кадр.
                                                                                                                    0
                                                                                                                      +2

                                                                                                                      Мне кажется, заявлять о «полноценном браузерном движке с нуля» можно будет начинать, только когда рендеринг появится. Хотя перечисленное в комменте тоже нужно, на данный момент говорить по-моему ещё не о чем

                                                                                                                    +15
                                                                                                                    Слабоумие и отвага.jpg
                                                                                                                      –1

                                                                                                                      Какие все злые. Сами бы не сделали и доли того, что сделал автор. Потому что сложно, лень, никому не нужно, всё равно будет не по спецификациям и т.д. Разве это всё важно? Задумка интересная, автор молодец.

                                                                                                                        +1
                                                                                                                        >Сами бы не сделали и доли того, что сделал автор

                                                                                                                        Аффтар НИЧЕГО полезного не сделал, сколько бы строчек ненужного кода он в этот проект не накидал. Ибо, как активно делающий web scrape на java, авторитетно заявляю, даже если ему ещё 20 студентов (что маловероятно) дать в помощники, они не будут успевать. И уж точно это не будет самый быстрый и «архитектурно правильный» движок.

                                                                                                                        Самый продвинутый headless browser под java — HtmlUnit пилит команда из человек 5, причём безбожно проигрывают в гонке. Если 4 года назад можно было почти всё скрейпить, сейчас чуть ли не каждый второй сайт с авторизацией выпишет облом.
                                                                                                                        При этом безголовый браузер это далеко не полноценный браузер. Нужна лишь навигация по DOM.

                                                                                                                        В общем, через много лет это будет в самом лучшем случае что-то вроде chromium с выключенным js. Но в хроме я, когда сильно хочется, жму кнопочку «включить js», а у них такой волшебной кнопочки не будет.
                                                                                                                          0
                                                                                                                          Так автор обещал поддержку JS. Это вообще самое простое из всего. Я JS интерпретатор написал в январе-феврале этого года за 5-6 недель. Он покрыт юнит-тестами, и работает, не нарушая стандартов (хотя кое-где ведёт себя лучше и логичнее существующих JS движков на мой взгляд). Да, он не будет работать быстрее V8, там нет JIT. Но не пофиг ли? Я ставил цель сделать браузер хотя бы уровня IE7 по возможностям и скорости рендеринга, в те времена джитами и не пахло ещё.

                                                                                                                          P.S. Часть фич ES6 мой интерпретатор, кстати, умеет, включая стрелочные функции, block-scope variables и Promises.
                                                                                                                            0
                                                                                                                            А он у вас выложен в опенсорс? Интересно было бы взглянуть.
                                                                                                                              0
                                                                                                                              Не выложен. Я не очень дружу с Git, поэтому даже не знаю, может проще архивом куда-то будет залить :) Так-то мне поделиться не жалко, просто не очень хочу позориться, не уверен, что мой код настолько хорош.
                                                                                                                                0

                                                                                                                                Как раз повод освоить :)

                                                                                                                                  0
                                                                                                                                  Да я знаю, что там можно хоть через веб-интерфейс всё загрузить. Просто пока я единственный разработчик — это как-то очень криво будет выглядеть.

                                                                                                                                  У меня уже стоит Tortoise SVN, и я коммичу каждое небольшое изменение на старый вузовский сервер. Я пробовал ставить параллельно Tortoise Git, он мне мало того, что показался менее стабильным, так они вдвоём ещё и немного конфликтуют… Прямо хоть под другой ОС его ставить, я не знаю. Или использовать консольную версию Git.
                                                                                                                                    0

                                                                                                                                    В идеале лучше из консоли, но можно начать и с SourceTree.

                                                                                                                                      0
                                                                                                                                      Посмотрел. Интерфейс симпатичный. Но XP и Vista не поддерживаются (причём даже в первых версиях от середины-конца 2013-ого года!). Так что в любом случае надо ставить его под другой ОС (Win 7 например) — а в этом случае меня и Tortoise Git устроит, тем более, более новые версии должны были стать стабильнее и проработаннее.
                                                                                                                                        +1
                                                                                                                                        Еще можно на bitbucket.org — там есть что использовать — git или mercurial. Я вот даже не знаю, кто мне больше нравится git или mercurial, в некоторых вещах — меркуриал нравится больше, как минимум из-за отслеживания, что файл был скопирован и в него внесены изменения, ну и Tortoise Hg как-то адекватнее себя ведет, чем Tortoise Git.
                                                                                                                                        Но с репозиторием SVN можно работать и через Git. Получается, в целом, не плохо. Я работал с SVN через меркуриал (hgsvn) и git-svn. В целом, git-svn поудобнее, но бывали проблемы с клонированием SVN репозитория — если он большой, то клонируется очень долго, и иногда падает — приходилось подбирать параметры. С hgsvn такого не было, но он и не клонировал репозиторий, это фактически было в одном каталоге два репозитория — SVN и меркуриал, а утилита hgsvn позволяла их синхронизировать. Это было менее удобно, но позволяло не вытягивать при помощи hgsvn всю историю, а пользоваться историем SVN.
                                                                                                                                          0
                                                                                                                                          Не знал, что SVN можно использовать не только через клиенты для SVN)

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

                                                                                                                                          Когда ставил Git, пытался делать разные ветки на разные добавляемые фичи, потом их сливать — в итоге действий было много (а по факту ветка не жила дольше 1-2 коммитов), и не всегда делалось то, что я хочу (то есть меня даже GUI не спас).

                                                                                                                                          Может, попробовать какой-то вариант примерно как у вас был, с автосинхронизацией и подтягиванием истории из SVN? Только я хотел бы синхронизировать с Git, а не с Mercurial, и чтобы оно сразу при коммите в SVN на GitLab бы отправлялось.
                                                                                                                                            0

                                                                                                                                            Работа с Git/Меркуриал подразумевает большее количество шагов — добавить в "индекс", сделать локальный коммит, отправить коммит на сервер.


                                                                                                                                            Если Вы работаете с репозиторием один, то использование практики ветка-на-фичу, мне кажется излишней — потренироваться работать с ветками — да, пожалуй, но на постоянной основе — особого смысла нет. Это дает преимущества когда над проектом активно работает несколько человек. В этом случае удобно использовать ветки, чтобы не вливать сырые изменения в основную (trunk/master).


                                                                                                                                            Я использовал связку, так как в процессе работы мне было удобно делать локальные коммиты и отправлять промежуточные результаты работы в отдельный hg-репозиторий (потом git-репозиторий). Срок выполнения задачи был большим, поэтому я делал коммит каждый день с тем на чем закончил, иногда делал дополнительные ветки, чтобы попробовать какой-нибудь альтернативный вариант решения. После того как задача решена, объединял все коммиты в один и отправлял в SVN.


                                                                                                                                            К сожалению одной командой отправить изменения в SVN и другой git-репозиторий не получится. Не зависимо, что Вы выберете git-svn или hgsvn сценарий будет примерно такой:


                                                                                                                                            • внести изменения в индекс (stage)
                                                                                                                                            • сделать локальный коммита
                                                                                                                                            • отправить изменения на сервер SVN
                                                                                                                                            • отправить изменения на сервер Git (Меркуриал)
                                                                                                                                              0
                                                                                                                                              Окей, спасибо. Но возможно есть какой-то софт, автоматизирующий отправку коммита в несколько репозиториев? Например, локальный Git коммит + Push в Git на гитлаб + коммит в SVN. Ну или в простейшем случае — батник написать какой-нибудь, я почти уверен, что это реализуемо.
                                                                                                                                                0
                                                                                                                                                Да, конечно, это можно сделать. Это можно батник (из него вызвать git commit и если код возврата 0, то отправлять изменения на сервера последующими командами). Еще можно попробовать посмотреть на локальные хуки гита, которые будут срабатывать после комита (не уверен, можно ли из них отправить изменения на сервер).

                                                                                                                                                Кажется, что tortoise git как раз и делал отправку изменений на сервер сразу после комита, но могу ошибаться. Я не очень люблю клиенты для git, так как в них очень легко можно наворотить что-нибудь не то, а потом придется разгребать. С этим сталкивался не раз, поэтому предпочитаю работать с консолью — выше осознаность действий.
                                                                                                                                                  0
                                                                                                                                                  В хуках вы можете делать всё, что угодно.

                                                                                                                                                  tortoise git сам ничего не пушит, но он позволяет это сделать в один клик после коммита.

                                                                                                                                                  Через консоль сломать git репозиторий куда легче, чем через гуй. У mecurial с этим получше.
                                                                                                                                                    0
                                                                                                                                                    А что, если вызывать консольную команду git в качестве post-commit хука в Tortoise SVN? Только там наверное нужны будут две команды — для коммита и для пуша. И опять же, если по какой-то причине я буду держать ещё и Tortoise Git параллельно (можно конечно его держать, но отключить интеграцию с проводником, чтобы не было конфликтов с Tortoise SVN в виде «борьбы за иконки») — я вот думаю, может тем же батником сперва и копирование в отдельный каталог делать, можно даже на другом логическом диске, а в Git пушить уже оттуда (то есть локальный Git репозиторий держать отдельно от рабочей копии SVN).

                                                                                                                                                    С копированием я разберусь, а вот как через консольный Git сделать сразу коммит и пуш на гитхаб, не подскажете?
                                                                                                                                                      0

                                                                                                                                                      git commit && git push

                                                                                                                                                        0
                                                                                                                                                        А комментарий к коммиту где тут указать? Я хочу, чтобы оно было прямо совсем автоматически в идеале. В Tortoise SVN там окно открывается для комментария, тут я в принципе готов вручную даже его ввести (возможно, я не каждый коммит в SVN буду отправлять в Git), просто интересно, куда его вводить, если нет клиента с GUI. В консоль?
                                                                                                                                                          0

                                                                                                                                                          Ну а документацию прочитать? git commit откроет дефолтный консольный редактор (обычно vim), git commit -m позволяет задать название коммита прямо в консоли.

                                                                                                                                                            0
                                                                                                                                                            git commit -m
                                                                                                                                                            Уже почитал в статье про введение в Git (точнее, в руководстве по загрузке проекта на гитхаб). С текстовым редактором — имхо это какая-то странная механика, особенно как для Windows. Как программа поймёт, что файл готов? Мониторит файловый дескриптор, отслеживая закрытие текстового редактора?
                                                                                                                                                              0

                                                                                                                                                              Как-то же работает :)

                                                                                                                                                                0
                                                                                                                                                                По завершению процесса. Поэтому с многодокументными редакторами могут быть проблемы, да. Надо обязательно, чтоб умел отдельную копию запускать.
                                                                                                                                                                  0
                                                                                                                                                                  Я использую старую версию GridinSoft Notepad (2.8), там вообще нет мультидокументного режима, каждый документ — новый процесс. А по дефолту у меня вообще Блокнот используется. Когда текст комментария пишешь, синтаксис вроде подсвечивать не нужно. Нужные же типы файлов у меня вручную в реестре проставлены ассоциациями, плюс для них добавлен пункт в контекстное меню проводника («Редактировать»).
                                                                                                                                    0
                                                                                                                                    К слову, мой движок (его render-компонента) уже умеет работать с z-index и контекстами наложения (в целом всё строго по стандарту, исключая момент с opacity, это надо будет доделать потом), корректно выводит float элементы (включая float сбоку от float, float + clear под float и т.д.), и сегодня он научился выводить элементы с pre-run контентом (пока поддерживаются только элементы списков, и пока только маркированные, нумерованные пока не сделал).

                                                                                                                                    Но есть и проблемы...
                                                                                                                                    Это, к сожалению, не делает его менее багнутым. К примеру, после полного построения структуры элементов, выполнения layout и render, при полной очистке и добавлении элементов заново внутри методов-тестов — всё ОК, но если очистить не всё, а только содержимое одного из блоков, и начать добавлять контент для теста туда — то остаются полупрозрачные «следы» старого контента, и ни один из методов очистки не помогает это убрать (что странно). Причём таких следов не будет, если закомментировать первый вызов render (до вызова тестового метода, в коде main метода). То есть рисуемое не всегда корректно очищается (иногда нормально, судя по тому, что в ряде других тестовых методов оно работало как надо — опять же, «работало» не значит «работает», нужно проверять по новой, я мог что-то и поломать).
                                                                                                                                      0
                                                                                                                                      Выложил исходники в открытый доступ.

                                                                                                                                      Должен сказать, что пока ещё очень многое не реализовано: нет поддержки фреймов, таблиц, элементов форм. Даже box-sizing пока реализовать руки не дошли (по умолчанию расчёты ведутся в режиме border-box ради удобства отладки и наглядности).

                                                                                                                                      Однако на днях я реализовал в JS движке методы Promise.all и Promise.race, реализовал там же корректные вычисления с бесконечностями (раньше бесконечности просто не поддерживались в принципе), сделал нумерованные списки нескольких видов в рендер-движке (включая нумерацию римскими цифрами и латинскими буквами). Также ввёл в JS-движке скрытие возвращаемых значений при установке таймеров, чтобы не засорять вывод (однако, его можно активировать с помощью статического поля класса в несколько доработанном виде).

                                                                                                                                      github.com/popov654/tinybrowser
                                                                                                                                      0
                                                                                                                                      хотя кое-где ведёт себя лучше и логичнее существующих JS движков на мой взгляд

                                                                                                                                      А в чём именно?

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

                                                                                                                                          А что на счёт поведения этих функций говорит стандарт?


                                                                                                                                          в поддержке некоторых конструкций, запрещённых в текущих реализациях (например, инкремент и декремент с числовым литералом)

                                                                                                                                          То есть 5++?

                                                                                                                                            0
                                                                                                                                            А что на счёт поведения этих функций говорит стандарт?

                                                                                                                                            Надо почитать. За стандарт не скажу (не читал), но когда у нас с точки зрения математики результат вычисления — плюс или минус бесконечность, то это скорее NaN (особенно если нет специальных констант, как в Java), чем непонятная фигня с плавающей точкой, которая проверку isNaN() не проходит (возвращает false).

                                                                                                                                            Кстати, оказывается, в JavaScript ещё есть функция isFinite() (стыд и позор мне, не знал про неё). Так вот, внимание — isFinite(tan(Math.PI / 2)) возвращает false! Стандарты стандартами, но здравый смысл подсказывает, что это бред.

                                                                                                                                            То есть 5++?

                                                                                                                                            Именно так. Не то чтобы в этом был практический смысл… Но если есть возможность отличить -1 от --1 (по числу минусов) и ++3 от +3 (по числу плюсов) — то нет особого смысла падать с ошибкой, если можно посчитать выражение по тем же правилам, что и в случае переменной (только сайд-эффектов не будет).
                                                                                                                                              0
                                                                                                                                              Если есть возможность отличить -1 от --1 (по числу минусов) и ++3 от +3 (по числу плюсов)

                                                                                                                                              5++-5 — это (5++)-5 или 5+(+(-5))? Ведь +-5 в js — валидная операция.
                                                                                                                                                0
                                                                                                                                                +-5

                                                                                                                                                Хм. Не знал про такой нюанс. Но писать +-5 смысла даже ещё меньше, чем 5++: поменяли два раза знак и получили то же, что было. Причём у нас заведомо integer (потому что литерал), а не, например, boolean, поэтому это даже для преобразования типа в данной ситуации бесполезно.

                                                                                                                                                И вообще — писать код, не ставя пробелы — ужасно дурной тон. Напишите 5++ -5, и вопросы отпадут сами собой. Мой парсер смотрит код посимвольно, а пробел — гарантированный признак конца токена.

                                                                                                                                                Текущая же реализация парсера именно при вашей форме записи воспримет это именно как (5++)-5, потому что скобок нет, а анализ идёт слева направо.
                                                                                                                                                  +1
                                                                                                                                                  писать код, не ставя пробелы — ужасно дурной тон.

                                                                                                                                                  Минификация же.
                                                                                                                                                    –1
                                                                                                                                                    А, ну да, разумно. Ну и ок — просто не использовать такие конструкции, если планируешь использовать минификацию. Не такая большая проблема. Я кстати никогда код не минифицировал, не вижу в этом смысла. Особенно его не вижу, если на сервере включен GZIP, который и так всё сожмёт одинаково хорошо (или почти одинаково, но разница там совершенно мизерная).
                                                                                                                                                      0
                                                                                                                                                      Разница от минификации может быть в несколько раз, он не только пробелы уберет, но и пожмет все названия переменных и функций до 1-2ух символов, удалит неиспользуемый код, выделит повторяющиеся паттерны строк в отдельные переменные и много чего еще. И тот факт что Вы его не используете ни о чем не говорит, минификацию используют на сегодняшний день почти все (и правильно делают), что толку от вашего JS-интерпретатора, если он сможет открывать только Ваши сайты (не минифицированные).
                                                                                                                                                        0
                                                                                                                                                        но и пожмет все названия переменных и функций до 1-2ух символов

                                                                                                                                                        Я знаю об этом.

                                                                                                                                                        минификацию используют на сегодняшний день почти все (и правильно делают)

                                                                                                                                                        Нет, не правильно. Из-за этого код становится намного сложнее анализировать (хотя для людей, его писавших — это даже плюс, но я не про них сейчас, а про всех прочих). Ценность же анализа просто огромна для самообучения и развития.

                                                                                                                                                        Насчёт выгоды от уменьшения размера после минификации — она вовсе не так велика, как вы говорите. Даже вк до перехода на новый дизайн не минифицировал свои скрипты (можете даже посмотреть сами на wayback machine, если что).

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

                                                                                                                                                        Не говоря уже о том, что для очень маленьких сайтов, где все скрипты весят меньше 800-1000 Кб, вообще можно не использовать ни минификацию, ни сжатие: каналы сегодня быстрые, а часть данных — кэшируется браузером и не будет загружаться при каждом запросе повторно. При грамотно же настроенном кэшировании на стороне сервера можно и вовсе получить гарантию кэширования всей статики на N часов или суток.
                                                                                                                                                          –1
                                                                                                                                                          Что вы несёте? Какой анализ минифицированного продакш кода? Анализируйте исходники на здоровье, или вы также сидите и анализируете байт-код джавы после компиляции? Анализируете нативные ассемблерные инструкции с кода?

                                                                                                                                                          Выгода от минификации колоссальна в масштабах всего интернета, если вы этого не понимаете, да ещё и утверждаете обратное, то и говорить не о чем.
                                                                                                                                                            +1

                                                                                                                                                            Давайте разделим на 2 части.
                                                                                                                                                            1) Удаление неиспользуемого кода.
                                                                                                                                                            Все модные инструменты вроде вебпака НЯП это делают всегда.
                                                                                                                                                            2) Сжатие имен переменных, выделение общих частей строк и т.д.
                                                                                                                                                            Мне тоже непонятно, почему минификатор сделает это лучше чем Brotli.

                                                                                                                                                              0
                                                                                                                                                              Так не надо пользоваться вебпаком, и не будет проблем. И потом, зачем вообще писать/подключать неиспользуемый код?

                                                                                                                                                                0

                                                                                                                                                                Наоборот, вебпак решает проблему неиспользуемого кода.
                                                                                                                                                                Такой код берется очень просто.
                                                                                                                                                                Пусть libfoojs умеет делать операции foo и bar.
                                                                                                                                                                Но мне нужна только foo. Значит код для бар будет неиспользуемым.
                                                                                                                                                                Если говорить про С, то там тоже при линковке избыточный код выбрасывается. У других ЯП, я думаю, ситуация такая же.

                                                                                                                                                                  0
                                                                                                                                                                  Это интересный функционал, не знал, что такое возможно. Выходит, люди, которые ноют, что «веб стал слишком толстым», ноют зря? Ну раз лишнее выкидывается при загрузке в продакшен.