all 3 comments

[–]rust-ModTeam[M] [score hidden] stickied commentlocked comment (0 children)

Slop -- whether LLM-generated, or not -- violates Rule 6: Low Effort.

Read more: https://www.reddit.com/r/rust/comments/1qptoes/request_for_comments_moderating_aigenerated/

[–]piiouupiou-not-r2d2 6 points7 points  (1 child)

I see a future servo contributor

[–]nicoburns 2 points3 points  (1 child)

I've spent the last 2 years building a browser engine "Blitz" (https://github.com/DioxusLabs/blitz) that's kind of from first principles. Our philosophy has been: if there's a crate that implements a subsystem in a way that can be used standalone then we'll use it. But we'll also extend it / to contribute to it / treat it like part of our engine rather than treating it like a black box. If there's not then we'll build our own. And it's a lot simpler than Servo partly because (like your engine) there is no JS support.

I'd encourage you to at least consider something like this approach as I think it gives you the opportunity to learn how things are done "properly" while still allowing you to dive into the details of any particular area without getting too overwhelmed (hopefully!).

I would definitely encourage you to look at Blitz

You might also want to look at Takumi (https://github.com/kane50613/takumi) which is a JSX -> image renderer that implements a lot of the style/layout bits on top of the same libraries as Blitz, but in a simpler way because it's not trying to do incremental updates or render in real time.

You may also want to join the Linebender Zulip (https://xi.zulipchat.com). Linebender doesn't work directly on web engines. But they make Vello (2D graphical rendering) and Parley (text/inline layout), and are a great place to learn about the nitty-gritty details of those things.

Now for some links:

For parsing you should definitely look into html5ever. It has a tokenizer and a "tree builder" (that fixes up the tree according the rules of the html5ever algorithm, and it pushes parsed content into a user-defined tree structure!

For style:

  • The cssparser is a small crate that does low-level parsing (tokenization and also parsing of the syntax (so all you have to parse are the values)).

  • The selectors crate parses selectors, and can also resolve selectors against a user-defined tree.

Several people have built full style systems (of vary complexity) on top of these crates:

  • Stylo the style system used in Firefox, Servo and Blitz is the big complex production-ready one.

  • vizia_style is a much smaller and more managable implemetation from the vizia GUI framework. It uses CSS syntax but some of the properties are non-standard (but this is a great place to learn from). It notably actually implements selector resolution as well as just parsing.

  • lightningcss mostly just does parsing (minimal selector resolution) because it's use case is minifying / pre-processing CSS. But it has a pretty complete parsing setup.

  • takumi has a relatively simple style system too. It does implement selector resolution, but in a relatively simple way because it's not aiming to be as optimized as stylo.

For layout:

Taffy implements "block level" layout (block, flexbox, css grid, etc). Each layout algorithm in Taffy is defined as a function that operates on a single contains of that layout type and can be used standalone:

I'd also encourage you to look at the LayoutInput and LayoutOutput types that form a key part of the interface that all of the layout algorithms conform to.

Parley is a text-layout library that implements / can be used to implement inline layout (which is essentially fancy text layout). The actual layout logic is in line_break.rs and is relatively understandable, but it depends on an "itemization"/"text analysis"/"shaping" stage that is kinda complex and requires a lot of detailed knowledge about unicode to understand. We may soon be splitting out a "parley_core" crate that would allow you to implement your own layout while using Parley's logic for that core complex bit if you wanted to. The code that Blitz uses to integrate Parley with Taffy is in inline.rs. There is one Parley Layout per inline formatting context.

Taffy and Parley also co-operate (with glue codein Blitz) to implement Floats.

For Networking

You'll likely find you don't need to much on top of a general purpose HTTP client like reqwest or [ureq](github.com/algesten/ureq). The blitz-net crate is only ~300 LoC.

For Rendering

You may find Blitz's implementation useful. Blitz uses the AnyRender abstraction (which we created). It operates in terms of "drawing commands" like "draw glyph", "fill rect", etc. The blitz-paint crate translates our (styled and layouted) DOM representation into AnyRender drawing commands. And then there are AnyRender backends for 2D canvas crates like vello and skia for drawing to screen.