It's not safe to allocate from the GC heap while in the constructor of a
GC heap cell. (Because if this ends up triggering a collection, we may
end up trying to call through an uninitialized vtable).
This was already done safely in the initialize() virtual in much of
LibJS and LibWeb. This patch moves the logic for prototypes, mixins,
and CSSStyleDeclaration as well.
Fixes a long-standing GC crash that was pretty easy to reproduce by
refreshing https://vercel.com/
This implements the stop-opacity, fill-opacity, and stroke-opacity
properties (in CSS). This replaces the existing more ad-hoc
fill-opacity attribute handling.
The resolved property sets are stored with the element in a
per-pseudo-element array (same as for pseudo element layout nodes).
Longer term, we should stop storing this with elements entirely and make
it temporary state in StyleComputer somehow, so we don't waste memory
keeping all the resolved properties around.
This makes various gradients show up on https://shopify.com/ :^)
1. Propagate calc() values from StyleProperties to ComputedValues.
2. Actually resolve calc() values when determining the used flex basis.
This makes the "support" section on https://shopify.com/ show up
correctly as a 2x2 grid (instead of 1x4). :^)
Note that this simple form of text-indent only affects the first line
of formatted content in each block.
Percentages are resolved against the width of the block.
The spec says: "The first value gives the width of the corresponding
image, the second value its height. If only one value is given the
second is assumed to be auto."
Fixes#18782
This makes hovering around on GitHub fast again, as it no longer
believes that the grid-template-areas property keeps changing
when it didn't :^)
Also made to_string() work for calc() values as well, since I stumbled
upon that while debugging this.
Using LengthPercentage instead of Length and Percentage separately
is going to allow GridSize to store calc() values. It also allows
to simplify some parts of layout code.
While it's possible to getComputedStyle() on an unconnected element,
the resulting object is not supposed to have any values, since we can't
resolve style without a document root anyway.
This fixes a crash on https://bandcamp.com
The root element font metrics were getting queried again and again
during style computation. Before this change we would do some work to
recalculate them each time.
This patch simply caches them in a StyleComputer member. Since style
updates always start with the root element, we know that it'll be
up-to-date by the time we look at any other element.
Before this change, we were spending ~5% of CPU time on Google Groups
in root_element_font_metrics().
Old pattern:
foo.resolved(node, reference_value).to_px(node)
New pattern:
foo.to_px(node, reference_value)
Also, the reference value for to_px() is a CSSPixels, which means we
don't have to synthesize a CSS::Length just for this call.
This necessitated returning `nullptr` instead of just `{}` in a lot of
places. Also, some temporary hackiness in `parse_css_value()`: That
returns a special `ParseError` type already, so we now have a
`FIXME_TRY()` macro which logs the error and then returns a generic
`ParseError::InternalError` value. Eventually this macro will go away,
once I figure out how to deal with this more nicely.
In particular, we now blockify layout internal boxes (e.g table parts)
by turning them into `block flow`. This fixes a crash when viewing
our GitHub repo :^)
The Display class already supported all specific values, and now they
will be parsed too. The display property now has a special type
DisplayStyleValue.
Length units are either relative to the font, or to the viewport, but
never both. So we can save some work by not gathering font metrics for
a viewport unit, and not retrieving the viewport for a font unit.
Currently this is only helpful when the `to_px(Layout::Node)` method is
called, but since that is 208 places according to CLion, (plus 33
indirect uses via `Length::resolved()`) it still seems worthwhile. :^)
`*vi` and `*vb` vary on which direction they check depending on whether
the writing mode is horizontal or vertical, so they will need some
modification once we support that.
Using the rough heuristic instead of the actual spec measurement. It's
allowed by the spec, but not ideal:
> In the cases where it is impossible or impractical to determine the
ideographic advance measure, it must be assumed to be 1em.
As noted, the ascent of the font is not the best heuristic for this, but
it is one that's listed as OK to use by the spec:
> In the cases where it is impossible or impractical to determine the
cap-height, the font’s ascent must be used.