|
2 | 2 | title: This Month in Ladybird - July 2025
|
3 | 3 | description: ?
|
4 | 4 | date: 2025-07-31
|
5 |
| -draft: true |
| 5 | +draft: false |
6 | 6 | ---
|
7 | 7 |
|
8 |
| -Hello friends! July is done! |
| 8 | +Hello friends! July is done. We merged 319 pull requests from 47 contributors. |
9 | 9 |
|
10 |
| -### Web Platform Tests (WPT) |
| 10 | +### Welcoming new sponsors |
11 | 11 |
|
12 |
| -_insert WPT stats here_ |
| 12 | +Ladybird is entirely funded by the generous support of companies and individuals who believe in the open web. This month, we're excited to welcome the following new sponsors: |
13 | 13 |
|
14 |
| -### `:state(foo)` and `:unchecked` pseudo-classes |
| 14 | +- [Scraping Fish](https://scrapingfish.com) with $5,000 |
| 15 | +- [Blacksmith](https://t.co/McauGhPdxH) with high-performance CI infrastructure |
15 | 16 |
|
16 |
| -We gained a couple of new pseudo-classes this month: |
| 17 | +We're incredibly grateful for their support. If you're interested in sponsoring the project, please [contact us](mailto:contact@ladybird.org). |
17 | 18 |
|
18 |
| -- `:state(foo)` matches a custom element that has `foo` in its states set. This lets custom elements be styled |
19 |
| - differently depending on their state, just like a regular element can be `:empty` or `:checked`, for example. |
20 |
| -- Speaking of which, we also added `:unchecked`. This matches elements that can be checked, but currently are not. |
| 19 | +### Web Platform Tests (WPT) |
21 | 20 |
|
22 |
| -### Logical property groups |
| 21 | +As usual, we've made some progress on the Web Platform Tests. We've added 13,090 passing tests for a new total of 1,831,856. |
23 | 22 |
|
24 |
| -Continuing work that was started [https://ladybird.org/newsletter/2025-06-30/#css-logical-aliases](last month), |
25 |
| -we now generate the code that maps logical properties to physical ones, decreasing the amount of boilerplate to add |
26 |
| -a new logical property. Logical and physical properties form "groups", for example all the `margin` properties, and |
27 |
| -we now account for these when serializing them, and when modifying them through JavaScript. |
| 23 | +### Google reCAPTCHA passing |
28 | 24 |
|
29 |
| -### Arbitrary substitution functions |
| 25 | +There was a long-standing issue with our [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) implementation: if the serialized type had not previously been used in the destination realm, we would fail to reconstruct it. The realm didn’t recognize the type and rejected the message. |
30 | 26 |
|
31 |
| -This mouthful of a name refers to CSS functions like `var()` which get substituted with an arbitrary chunk of CSS. |
32 |
| -Recent versions of the CSS specs formally define how these work, and this month we rewrote our implementations of |
33 |
| -`var()` and `attr()` to match this new definition. Besides being easier to maintain, this prepares us to more easily |
34 |
| -add other arbitrary substitution functions in the future, such as `if()` and `env()`. |
| 27 | +This is now fixed, allowing Google reCAPTCHA to pass! |
35 | 28 |
|
36 |
| -### `<syntax>` parsing |
| 29 | +<video controls style="margin-bottom: 2em"> |
| 30 | + <source src="/assets/img/newsletter-july-2025-google-recaptcha.mp4"></source> |
| 31 | +</video> |
37 | 32 |
|
38 |
| -Some modern CSS features allow authors to specify their own CSS syntax which is then used to parse something else. |
39 |
| -We've implemented the `<syntax>` type which corresponds to this, and it can now be used in `attr()`, to specify how |
40 |
| -to interpret the attribute. For example, `attr(data-color type(<color>))` would parse the `data-color` attribute as |
41 |
| -if it was a CSS color value. |
| 33 | +Unfortunately, this only works on `https://www.google.com/` for now, due to a separate unresolved same-origin policy issue. |
42 | 34 |
|
43 |
| -### `@property` progress |
| 35 | +### High refresh rate support |
| 36 | + |
| 37 | +We now detect the refresh rate of the active screen to determine how often web content should be rendered. Previously, rendering was fixed at 60 frames per second. |
| 38 | + |
| 39 | +Websites using [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame) now render at up to 120Hz on supported hardware. This change also improves the smoothness of scrolling, animations, transitions, and more. |
44 | 40 |
|
45 |
| -We've had a stub implementation of `@property` for a while, and this month we started making some progress on it. |
46 |
| -We now make use of a registered custom property's initial value, and we also gained initial support for `CSS.registerProperty()`. |
| 41 | + |
47 | 42 |
|
48 | 43 | ### HTTP/3 support
|
49 | 44 |
|
50 |
| -Support for [HTTP/3](https://en.wikipedia.org/wiki/HTTP/3) with OpenSSL and [ngtcp2](https://github.com/ngtcp2/ngtcp2) was [recently added with curl 8.14.0.](https://curl.se/ch/8.14.0.html) |
| 45 | +[HTTP/3](https://en.wikipedia.org/wiki/HTTP/3) support was recently added in curl 8.14.0 for users of OpenSSL and [ngtcp2](https://github.com/ngtcp2/ngtcp2). Since Ladybird uses the OpenSSL backend with libcurl, this enabled us to support HTTP/3 as well. |
51 | 46 |
|
52 |
| -Since we depend on the OpenSSL backend for libcurl, this has allowed us to enable HTTP/3 support, which allows us to |
53 |
| -use it for servers that advertise support for it in the [Alt-Svc header.](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Alt-Svc) |
| 47 | +We now negotiate HTTP/3 for servers that advertise it via the [Alt-Svc header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Alt-Svc). |
54 | 48 |
|
55 | 49 | 
|
56 | 50 |
|
57 |
| -We found an issue relating to how libcurl parses `Alt-Svc: clear`, which was [fixed in curl 8.15.0.](https://curl.se/ch/8.15.0.html) |
| 51 | +We also found and reported an issue in curl where `Alt-Svc: clear` was parsed incorrectly. This has since been [fixed in curl 8.15.0.](https://curl.se/ch/8.15.0.html) |
58 | 52 |
|
59 |
| -### High refresh rate support |
| 53 | +### Trusted Types |
60 | 54 |
|
61 |
| -We now take into account the refresh rate of the current screen to determine how often we should update the rendering of web content. |
62 |
| -Previously, it was hardcoded to update at 60 frames per second. |
| 55 | +Trusted Types is a security feature that helps prevent cross-site scripting (XSS) by locking down injection sinks like `Element.innerHTML`, `HTMLScriptElement.text`, and `HTMLScriptElement.src`. It allows web developers to define policies that control how sanitized content can be created and consumed. |
63 | 56 |
|
64 |
| -For example, applications using [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/Window/requestAnimationFrame) |
65 |
| -will now render up to 120 times per second on a 120Hz screen. This also affects scrolling, animations, transitions and more. |
| 57 | +This month, we added initial support for Trusted Types. This includes recognizing policies and enforcing type-safe DOM writes. Further work is ongoing to support more of the spec and improve compliance. |
66 | 58 |
|
67 |
| - |
| 59 | +### SVG `foreignObject` improvements |
68 | 60 |
|
69 |
| -### Google reCAPTCHA passing |
| 61 | +The relationship between HTML and SVG is complex. While SVG content can appear in HTML, SVG can also embed arbitrary HTML using the `foreignObject` element. |
70 | 62 |
|
71 |
| -There was a long standing issue with our [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) implementation |
72 |
| -where if the serialized type was not used in the destination realm before, we would fail to reconstruct it because it did not think it was |
73 |
| -available in that realm. |
| 63 | +This month, we made major improvements to how Ladybird handles `foreignObject`. Layout, style resolution, and rendering inside embedded HTML are now much closer to spec behavior, with better integration between the two worlds. |
74 | 64 |
|
75 |
| -This was fixed this month, allowing Google reCAPTCHA to work and pass! |
| 65 | +### CSS `content: url(...)` |
76 | 66 |
|
77 |
| -<video controls style="margin-bottom: 2em"> |
78 |
| - <source src="/assets/img/newsletter-july-2025-google-recaptcha.mp4"></source> |
79 |
| -</video> |
| 67 | +We added support for using `content: url(...)` in CSS pseudo-elements such as `::before` and `::after`. This allows authors to insert images via CSS content, matching behavior seen on modern websites. |
| 68 | + |
| 69 | +### `:state(foo)` and `:unchecked` pseudo-classes |
80 | 70 |
|
81 |
| -Unfortunately, it does not work on origins that are not https://www.google.com/ due to a separate same-origin policy issue that has not been |
82 |
| -resolved. |
| 71 | +We gained two new pseudo-classes: |
83 | 72 |
|
84 |
| -### The Web is UTF-16 |
| 73 | +- `:state(foo)` matches a custom element whose states set includes `"foo"`. This allows custom elements to be styled based on internal state, similar to how `:checked` and `:empty` work. |
| 74 | +- `:unchecked` matches elements that are checkable but currently not checked. |
| 75 | + |
| 76 | +These additions improve our compatibility with web components and modern form styling. |
| 77 | + |
| 78 | +### Logical property groups |
| 79 | + |
| 80 | +Building on work from [last month](https://ladybird.org/newsletter/2025-06-30/#css-logical-aliases), we now generate the mappings from logical to physical properties at compile time. |
| 81 | + |
| 82 | +Logical and physical properties form groups—for example, the various `margin` properties—and we now take these into account when serializing styles and when modifying them from JavaScript. This improves both CSS fidelity and performance. |
| 83 | + |
| 84 | +### Arbitrary substitution functions |
| 85 | + |
| 86 | +This month we rewrote our implementations of `var()` and `attr()` to align with the formal definition of _arbitrary substitution functions_ in recent CSS specs. These are functions that return a value to be substituted into the rule before parsing continues. |
| 87 | + |
| 88 | +Our new implementation is more robust, more spec-compliant, and sets us up to support other substitution functions like `if()` and `env()` in the future. |
85 | 89 |
|
86 |
| -Strings in JavaScript and the Web are [UTF-16 by definition](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#utf-16_characters_unicode_code_points_and_grapheme_clusters). |
87 |
| -Until now, we have been using a UTF-8 string type internally to represent JS strings, and we would transcode to UTF-16 |
88 |
| -on-the-fly to satisfy specification requirements as needed. Over time, this has resulted in an ever-growing number of |
89 |
| -locations that need to perform extra work to behave correctly. This month, we've decided to introduce a UTF-16 string |
90 |
| -to begin using wholesale within LibJS and LibWeb. This not only make the code simpler to write and reason about, but |
91 |
| -has also fixed some Unicode-related edge cases that we previously missed. |
| 90 | +### `<syntax>` parsing |
| 91 | + |
| 92 | +CSS now allows authors to define the expected syntax for attribute values using the `<syntax>` type. This is used within `attr()` to guide how the value should be parsed. |
| 93 | + |
| 94 | +For example: |
| 95 | + |
| 96 | +```css |
| 97 | +color: attr(data-color type(<color>)); |
| 98 | +``` |
| 99 | + |
| 100 | +This instructs the parser to interpret the `data-color` attribute as a CSS color. Ladybird now supports `<syntax>` parsing and uses it to improve behavior in CSS Houdini and custom properties. |
| 101 | + |
| 102 | +### `@property` progress |
| 103 | + |
| 104 | +We’ve had a stub implementation of `@property` for a while. This month, we started fleshing it out. |
| 105 | + |
| 106 | +We now respect the initial value defined in a `@property` declaration and added initial support for `CSS.registerProperty()`. This brings us closer to full Houdini support. |
| 107 | + |
| 108 | +### The Web is UTF-16 |
92 | 109 |
|
93 |
| -### Trusted types |
| 110 | +By definition, strings in JavaScript and the web are [UTF-16 encoded](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#utf-16_characters_unicode_code_points_and_grapheme_clusters). Until now, LibJS used UTF-8 internally and transcoded to UTF-16 on the fly. |
94 | 111 |
|
95 |
| -Trusted Types is a web security feature that helps prevent cross-site scripting (XSS) attacks by restricting what data |
96 |
| -can be used to manipulate the DOM, inject scripts, or forge URLs. It allows web developers to define policy rules that |
97 |
| -specify how to create a type-safe sanitized version of a strings that can be used to manipulate injection sinks such as |
98 |
| -`Element.innerHTML`, `HTMLScriptElement.text`, and `HTMLScriptElement.src`. This month, a contributor added initial |
99 |
| -support for Trusted Types. Future work to flesh out the support for this security-conscious feature is already under way |
100 |
| -and will be continued in the coming months. |
| 112 | +This month, we introduced a native UTF-16 string type and began transitioning LibJS and LibWeb to use it internally. This simplifies the implementation and avoids subtle encoding-related bugs, especially with Unicode edge cases. |
101 | 113 |
|
102 | 114 | ### Credits
|
103 | 115 |
|
104 | 116 | We'd like to thank everyone who contributed code this month:
|
105 | 117 |
|
106 |
| -_names_ |
| 118 | +_Abhinav, Ali Mohammad Pur, Aliaksandr Kalenik, Andreas Kling, Andrew Kaster, aplefull, Arran Ireland, ayeteadoe, Ben Eidson, Callum Law, Chase Knowlden, dmaivel, edvwib, Gingeh, Glenn Skrzypczak, Grant Knowlton, InvalidUsernameException, Jan Koudijs, Jelle Raaijmakers, Kemal Zebari, Kenneth Myhra, Lucien Fiorini, Luke Wilde, Manuel Zahariev, Michael Manganiello, mikiubo, norbiros, Olekoop, Philipp Dreher, Psychpsyo, rmgx, Rocco Corsi, Ryan Liptak, Sam Atkins, Shannon Booth, Tete17, Tim Ledbetter, Timothy Flynn, Trey Shaffer, Undefine, Veeti Paananen, zac_ |
0 commit comments