Skip to content

Commit 03f2bbb

Browse files
committed
Add 2020 retrospective post
1 parent a2b9391 commit 03f2bbb

File tree

6 files changed

+135
-5
lines changed

6 files changed

+135
-5
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ _site
22
.sass-cache
33
.DS_Store
44
.idea/
5+
vendor/

Gemfile

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
source 'http://rubygems.org'
22

33
gem "github-pages", "~> 209", group: :jekyll_plugins
4-
# group :jekyll_plugins do
5-
# gem "jekyll-feed"
6-
# gem "jekyll-seo-tag"
7-
# gem "jekyll-sitemap"
8-
# end
4+
group :jekyll_plugins do
5+
gem "jekyll-feed"
6+
gem "jekyll-seo-tag"
7+
gem "jekyll-sitemap"
8+
gem "jekyll-footnotes"
9+
end
910

1011
gem "ffi", ">= 1.9.24"
1112

Gemfile.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ GEM
117117
jekyll (~> 3.0)
118118
jekyll-feed (0.15.1)
119119
jekyll (>= 3.7, < 5.0)
120+
jekyll-footnotes (1.0.0)
120121
jekyll-gist (1.5.0)
121122
octokit (~> 4.2)
122123
jekyll-github-metadata (2.13.0)
@@ -257,6 +258,10 @@ PLATFORMS
257258
DEPENDENCIES
258259
ffi (>= 1.9.24)
259260
github-pages (~> 209)
261+
jekyll-feed
262+
jekyll-footnotes
263+
jekyll-seo-tag
264+
jekyll-sitemap
260265

261266
BUNDLED WITH
262267
1.16.6

_config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ plugins:
1111
- jekyll-seo-tag
1212
- jekyll-feed
1313
- jekyll-sitemap
14+
- jekyll/footnotes
1415

1516
# Build settings
1617
markdown: kramdown
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
---
2+
layout: post
3+
title: "My 2020 browser retrospective (and 2021 prospective)"
4+
categories: posts
5+
description: "A quick retrospective on the browser-related things I worked on in 2020, and what I have planned for 2021."
6+
---
7+
8+
{: .no_toc}
9+
#### Table of contents
10+
1. TOC
11+
{:toc}
12+
13+
<hr style="margin-bottom: 15px;" />
14+
15+
I spent much of 2020 working on web browsers (mainly [Kosmonaut](https://github.com/twilco/kosmonaut) and WebKit). Here's a little write-up about how that was, and what I have planned for
16+
the future.
17+
18+
### Kosmonaut in 2020
19+
20+
One year ago today, I was finishing the first implementation of [block layout](https://github.com/twilco/kosmonaut/commit/f3041f0b7e986b7a0be26b34870489cfaeb3e830) and [display-list generation](https://github.com/twilco/kosmonaut/commit/fedf68029e4ad9ea8bf4b96611b8738a347402f2). In terms of LoC, Kosmonaut hasn't grown much — from 7.5k LoC then to
21+
20k now. However, there are some pretty neat improvements wrapped up in that 12.5k LoC increase:
22+
23+
* Layout-tree dump{% fn %} snapshot based testing
24+
* Partial support{% fn %} for [abstract box layout](https://drafts.csswg.org/css-writing-modes-4/#abstract-layout) with the `writing-mode` and `direction` properties
25+
* Support for arbitrary scale factors, e.g. for HiDPI screens
26+
* OpenGL-based box painting and text rendering (though text rendering is not yet hooked into layout)
27+
28+
Three months ago, I ventured out to rewrite Kosmonaut's layout engine, as I had made a mess of it in my first pass at
29+
implementing abstract box layout. The result is [this PR](https://github.com/twilco/kosmonaut/pull/14), merged today,
30+
that ended up being a rewrite of...a lot of things. Some highlights from that PR include:
31+
32+
* Proper representation of many spec-level concepts, such as [text runs](https://drafts.csswg.org/css-display/#text-run), [formatting contexts](https://drafts.csswg.org/css-display/#formatting-context), various types of boxes, and more.
33+
* Much cleaner layout tree dump output. [Before](https://github.com/twilco/kosmonaut/blob/a6b7138b2c95714af8ce3a446e2f4b40b2d67950/tests/layout/snapshots/lib__layout__tests__rainbow_divs_baseline.snap) vs. [after](https://github.com/twilco/kosmonaut/blob/82cf7ef53e67e0c33ea8812e486fe8d867a82da9/tests/layout/snapshots/lib__layout__tests__rainbow_divs_baseline.snap)
34+
* A _much_ cleaner HiDPI scaling implementation. The TLDR of this is that scaling used to be done in layout, which required passing a `scale_factor` everywhere and applying it in exactly the right places. The [new implementation](https://github.com/twilco/kosmonaut/commit/15f76d68617bf3e846b8405d000b1b9e17dafd72) scales the viewport size down before layout and scales everything else up just before painting, making things far more simple and less prone to bugs.
35+
36+
There's a fair amount of cleanup I'd like to do following the landing of this PR, but it's a big step forward and
37+
I'm really happy with how it turned out.
38+
39+
One of the reasons this took so long is because I spent quite a long time trying out various designs and subsequently
40+
throwing them out. One thing I really wanted to do with this PR was to enforce certain spec-level constraints with
41+
the type system. To give a concrete example, [take this snippet from the CSS Display spec](https://drafts.csswg.org/css-display/#block-container) regarding block containers:
42+
43+
> A block container either contains only inline-level boxes participating in an inline formatting context, or contains only block-level boxes participating in a block formatting context.
44+
45+
I had experimented with a design that looked like this:
46+
47+
{% highlight rust %}
48+
pub struct BlockContainer {}
49+
pub struct BlockLevelBlockContainer {
50+
children: Vec<BlockLevelBox>
51+
}
52+
pub struct InlineLevelBlockContainer {
53+
children: Vec<InlineLevelBox>
54+
}
55+
56+
impl BlockContainer {
57+
pub fn new(...) -> BlockContainer {}
58+
59+
pub fn add_block_level_child(
60+
blb: BlockLevelBox
61+
) -> BlockLevelBlockContainer {}
62+
63+
pub fn add_inline_level_child(
64+
ilb: InlineLevelBox
65+
) -> InlineLevelBlockContainer {}
66+
}
67+
{% endhighlight %}
68+
69+
The idea is that you could only get a `BlockLevelBlockContainer` or `InlineLevelBlockContainer` by calling one of
70+
these `add_{block, inline}_level_child` methods (i.e. neither of these structs have `new` methods), ensuring at compile-time
71+
that the quoted spec invariant is upheld.
72+
73+
However, this proved to to be awkward for a number of reasons, and I scrapped the idea in favor of a less restrictive API
74+
that technically allows these rules to be broken. I would like to revisit this someday, as allowing users to encode
75+
rules via the type system (and making it ergonomic to do so) is something Rust is good at.
76+
77+
### WebKit in 2020
78+
79+
Kosmonaut was not the only browser I worked on in 2020 — this year also saw the beginning of my contributions to WebKit.
80+
I landed [13 patches](https://github.com/WebKit/WebKit/search?q=author%3Atwilco&type=commits), and worked on quite a few
81+
others I didn't push across the finish line. Here are some highlights:
82+
83+
* Various bug fixes and improvements to WebKit's CSS variables implementation. I have a blog post in the works describing these in more detail, so stay tuned.
84+
* Fixed a bug that caused `::selection` pseudoelement styles to not be applied to elements with direct anonymous parents, such as text nodes. [[commit]](9d06f52c2c04b24605af1bb19eed43ad03a6d9c4)
85+
* Per spec, ignore order when parsing `<inset>` and `<color>` values for the `box-shadow` property. [[commit]](https://github.com/WebKit/WebKit/commit/b1876da3f1ce3bed2a8c779e5716927ce9d85438)
86+
87+
In the second half of the year I really felt like I was getting into a groove in working on WebKit, so I'm excited to get
88+
back to it.
89+
90+
### My plans for 2021
91+
92+
2021 has arrived! Here are some things I'd like to complete in Kosmonaut soon:
93+
94+
* Parse and expand the most common CSS shorthands — `margin`, `border`, `padding`, etc. Kosmonaut currently only understands longhands, which is quickly becoming inconvenient.
95+
* Add the ability to load styles from `<link href="...">` and `<style></style>` tags. Currently, loading HTML and CSS in Kosmonaut requires passing all files individually via the `—files` flag, which is inconvenient (are you noticing a trend?).
96+
* [Handle `display: none` boxes](https://github.com/twilco/kosmonaut/blob/82cf7ef53e67e0c33ea8812e486fe8d867a82da9/src/layout/flow/block.rs#L358)
97+
* Further improve support for abstract box layout. Concretely, this means making `writing-mode: {sideways-lr, sideways-rl, vertical-rl}` and permutations with `direction: {ltr, rtl}` work. I don't think this will be all that hard. Calculation of [block start coordinates](https://github.com/twilco/kosmonaut/blob/82cf7ef53e67e0c33ea8812e486fe8d867a82da9/src/layout/flow/block.rs#L528) and [inline start coordinates](https://github.com/twilco/kosmonaut/blob/82cf7ef53e67e0c33ea8812e486fe8d867a82da9/src/layout/flow/block.rs#L533) will have to change, and maybe a few other things.
98+
* A basic implementation of [inline layout](https://drafts.csswg.org/css-inline-3/), followed by some polish of Kosmonaut's existing OpenGL text rendering.
99+
100+
After this list, I'm not really sure what will come next for Kosmonaut. I think it would be a fun minigame to start tackling the [Acid2 test](https://en.wikipedia.org/wiki/Acid2) and/or [some web platform tests](https://github.com/web-platform-tests/wpt).
101+
102+
I've taken a break from WebKit recently to push Kosmonaut's layout rewrite across the finish line, but want to get back to it soon. I have been pondering about an experiment I'd like to try regarding my work in WebKit, so stay tuned for information on that — I'll be posting about it here.
103+
104+
---
105+
106+
{% footnotes %}
107+
{% fnbody %}
108+
<a href="https://github.com/twilco/kosmonaut/blob/82cf7ef53e67e0c33ea8812e486fe8d867a82da9/tests/layout/directional/snapshots/lib__layout__directional__ltr_vertical_lr_block_boxes_top_left_right_mbp_applied_physically.snap">Here's what a layout dump looks like. </a>
109+
{% endfnbody %}
110+
{% fnbody %}
111+
The specifics of what "partial support" means are documented <a href="https://github.com/twilco/kosmonaut/blob/e50b640e467a630776a3a3c910839176da98f868/README.md#f1">here</a>.
112+
{% endfnbody %}
113+
{% endfootnotes %}
114+

_sass/_base.scss

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ ol.bold > li > span.non-bold {
4747
margin-bottom: 10px;
4848
}
4949

50+
.footnotelist {
51+
margin-top: 15px;
52+
}
53+
54+
.footnotelist > li {
55+
margin-top: 15px;
56+
}
57+
5058
/** Should have the same margin-bottom size as <p> elements do. */
5159
div.paragraph-sized-spacer {
5260
margin-bottom: 15px;

0 commit comments

Comments
 (0)