avatarFeed icon

This Week in Ladybird #2

Published on 2023-04-02.

Overview of changes across the Ladybird Browser project in the week from March 27 to April 2 (plus everything merged Sunday evening) :^)


In chronological order:

#18001 by @Coderdreams

This makes Ladybird (as in the Qt application) behavior match Browser (as in the LibGUI application) for the following actions:

In the future we might make these configurable, but for now these are better defaults most people will be familiar with :^)

LibWeb: Implement custom element name validation and fix bug in element name validation

#18005 by @srikavin

We now validate the name of custom elements according to the spec so that valid names create an HTMLElement while invalid names create an HTMLUnknownElement.

LibWeb: Don't force relayout whole page on programmatic scroll

#18051 by @awesomekling

This implements two optimizations for page scrolling:

Note that JS-invoked page scroll currently uses a different code path, so we're possibly missing out on this optimization in some places :^)

Ladybird: Enable and document build and debug steps with Xcode

#18052 by @ADKaster

I'm not an Xcode user myself, but it's always nice to have proper documentation for more development platforms! Now if someone could document the steps to debug a WebContent process with gdb… πŸ˜…

Browser+Ladybird: Show current zoom level in the view menu

#18054 by @MacDue

We now tell you the current zoom level in both Browser and Ladybird, which you previously had to estimate yourself! The zoom actions have moved into a submenu for that to happen:

LibWeb: Stop returning the left padding for resolved padding-bottom

#18060 by @AtkinsSJ

I accidentally broke this 8 months ago and nobody noticed. πŸ˜…

I'm not sure how we managed to do that but thanks for the fix Sam!

LibWeb: Fix condition to early return in intrinsic sizing for TFC

#18064 by @kalenikaliaksandr

This fixes an incorrect auto height of a Table Formatting Context (TFC).

LibWeb: Handle flex column items with auto height that depends on auto width

#18066 by @awesomekling

Layout is like magic to me, so I'll trust you to understand this from the title alone :^)

LibWeb: Clamp fit-content widths in flex layout to min/max-width

#18072 by @awesomekling

More layout magic:

In situations where we need a width to calculate the intrinsic height of a flex item, we use the fit-content width as a stand-in. However, we also need to clamp it to any min-width and max-width properties present.

Tests/LibWeb: Add layout test for layout fix in PR #15780

#18074 by @Lubrsi

More tests = more good, even when the fix was from five months ago!

LibWeb+LibWasm: Implement and use the "reset the Memory buffer" steps

#18079 by @alimpfard

This implements reset the Memory buffer from the WebAssembly JS API spec, which is part of our checklist of features required for the Ruffle Flash Player emulator.

Ladybird+Browser: Add (reset) zoom level button to toolbar

#18080 by @MacDue

Similar to Firefox we also show a button to quickly reset the current zoom level next to the URL bar when it is not 100%.

LibWeb: Parse Element.style url functions relative to the document

#18081 by @Lubrsi

url()s in CSS applied via HTMLElement.style are parsed now relative to that element's document URL.

This fixes the images on Steam's store carousel, for example:

LibWeb: Resolve percentage vertical-align values against line-height

#18084 by @awesomekling

Even more layout fixes. Andreas really did a lot of that!

LibWeb: Implement HTMLAnchorElement.text and .referrerPolicy properties

#18086 by @AtkinsSJ

This implements the following APIs:

However we don't use the value of referrerPolicy yet when following the link.

LibWeb: Implement CRC2D.imageSmoothingEnabled

#18088 by @awesomekling

This implements the following APIs:

This means that pages can now choose whether we use the bilinear interpolation or nearest-neighbor interpolation (i.e. pixelated) when painting scaled images on a canvas. Previously bilinear interpolation was always used, matching the default of imageSmoothingEnabled = true.

Note that imageSmoothingQuality is not actually honored as LibGfx doesn't support this concept yet.

LibWeb: Remove redundant invocation of children changed in HTMLParser

#18098 by @awesomekling

A simple fix to avoid doing duplicate work, one of the easiest ways to make code faster :^)

Setting the data of a text node already triggers children changed per spec, so there's no need for an explicit call.

LibWeb: Don't re-sort StyleSheetList on every new sheet insertion

#18099 by @awesomekling

Another performance optimization:

This was causing a huge slowdown when loading some pages with weirdly huge number of style sheets. For example, amazon.com has over 200 style elements, which meant we had to resort the StyleSheetList 200 times. Instead of sorting, we now look for the correct insertion point when adding new style sheets, and we start the search from the end, which is where style sheets are typically added in the vast majority of cases.

And the result:

This removes a 600ms time sink when loading Amazon on my machine! :^)

Editor's note: Amazon really needs to get its websites under control. Andreas also shared the following screenshot earlier:

LibWeb: Actually visit rules and media queries in imported style sheets

#18101 by @awesomekling

This ensures that we also consider @media queries in style sheets loaded via CSS @import, which previously wouldn't happen due to a bogus getter:

bool has_import_result() const { return !m_style_sheet; }

LibWeb: Split CalculatedStyleValue out of StyleValue.{h,cpp}

#18104 by @AtkinsSJ

Another refactor of some CSS machinery, aimed at reducing dependency cycles and improving build times πŸš€πŸš€πŸš€

LibJS: Add fast path to Value::to_u32() if Value is a positive i32

#18105 by @awesomekling

This change nicely demonstrates the kind of low hanging performance fruit we still have in LibJS!

6.6% speed-up on Kraken's stanford-crypto-aes subtest. :^)

This is the entire diff:

--- a/Userland/Libraries/LibJS/Runtime/Value.cpp
+++ b/Userland/Libraries/LibJS/Runtime/Value.cpp
@@ -947,6 +947,10 @@ ThrowCompletionOr<i32> Value::to_i32(VM& vm) const
 // 7.1.7 ToUint32 ( argument ), https://tc39.es/ecma262/#sec-touint32
 ThrowCompletionOr<u32> Value::to_u32(VM& vm) const
+    // OPTIMIZATION: If this value is encoded as a positive i32, return it directly.
+    if (is_int32() && as_i32() >= 0)
+        return as_i32();
     // 1. Let number be ? ToNumber(argument).
     double number = TRY(to_number(vm)).as_double();

LibWeb: Begin implementing the Streams API

#18109 by @mattco98

With the exception of an empty ReadableStream interface, no one had done any work on implementing the Streams API yet β€” until now!

This implements the following APIs:

With those we can already run the Simple random stream example from MDN!

Ladybird+Browser: Add tooltip to reset zoom level button

#18119 by @MacDue

A follow-up to the previous UI changes around zooming to make the new button's purpose more clear.

LibWeb: Don't churn HTML::EventLoop while in microtask checkpoint

#18125 by @awesomekling

This was the reason my Serenity VM's CPU was spinning at 100% for the entirety of the March update video (caused by having two GitHub tabs open) πŸ˜…

Luckily Andreas looked into it and found the cause: the event loop would constantly re-schedule itself even while we're performing a microtask checkpoint, except queued tasks wouldn't get processed in that state!

LibWeb: Fix application of intrinsic aspect ratio to flex column items

#18130 by @awesomekling

Only when using flex-direction: row{,-reverse} the intrinsic aspect ratio was calculated correctly, not when using a column{,-reverse} layout.

As many layout-related things this is somewhat vaguely defined in the spec, so it's easy to miss:

…then the flex base size is calculated from its inner cross size and the flex item’s intrinsic aspect ratio.

LibWeb+Tests: Allow subdirectories in layout_test.sh and add grid tests

#18134 by @martinfalisse

An initial set of 12 layout tests for CSS grid, which we use to ensure that changes don't regress layout β€” a rather complex part of the engine β€” by accident.

LibJS: Fix parsing of mixed CoalesceExpression and Logical{AND,OR}Expression

#18136 by @linusg

Bugs in the JS parser have mostly been flushed out over the years, but still occur at times; especially when we throw megabytes of JS from the web at it :^)

This specific bug prevented us from parsing an expression like this, which occurred on vscode.dev:

0 ?? 0 ? 0 : 0 || 0;

To be clear, I'm neither an expert on our JS parser nor do I really enjoy working on it, but I promised Andreas to fix the bug if he'd reduce it, which he did, so here we are. No test262 tests fixed, sadly πŸ˜„

LibWeb: Fix a few font scaling issues

#18137 by @MacDue

Even now that fonts scale properly with the CSS pixel mechanism we still occasionally find cases where device pixels are used. This fix corrected the scaling of text shadows and the markers of ordered lists (<ol>).

LibWeb: Don't apply element inline style & presentational hints to associated pseudo elements

#18144 by @awesomekling

This fixes a bug where inline styles (<foo style="...">) and presentational hints (e.g. <foo width="...">) would leak into the element's pseudo elements (::before, ::after) by accident β€” they should only apply to the element itself.


I didn't do this last week, but the browser engineer in me always gets excited when people share progress in form of a screenshot showing a mildly broken website so I think a section of random screenshots people shared is worth having πŸ₯Ή

And that concludes the second post of the This Week in Ladybird series!

Also check out the SerenityOS update (March 2023) video if you haven't done that yet:

Loading posts...