The postitioning enum values are used by the position CSS property.
Unfortunately, the prior naming clashes with the CSS Values-4 type
named position, which will be implemented in a later commit.
Instead of resolving lengths used in the backdrop-filter during
painting, we can do that earlier in apply_style().
This change moves us a bit closer to the point when the stacking
context tree will be completely separated from the layout tree :)
Renaming the DeprecatedString version of this function to
Element::get_deprecated_attribute.
While performing this rename, port over functions where it is trivial to
do so to the Optional<String> version of this function.
This makes multiple levels of quote actually use different quotation
marks, instead of always the first available pair of them.
Each Layout::Node remembers what the quote-nesting level was before its
content was evaluated, so that we can re-use this number in
`apply_style()`. This is a bit hacky, since we end up converting the
`content` value into a string twice.
`StyleProperties::content()` now takes an initial quote-nesting level,
and returns the final level after that content.
ImageStyleValue has a visit_edges() method, although it is not a
GC-allocated object. This is necessary because it owns a GC-allocated
ImageRequest that we want to visit, instead of using JS::Handle, to
avoid leaks. In the future, we might want to make StyleValue be
GC-allocated.
For now, this change adds missing visit_edges() calls for objects that
own ImageStyleValue.
This fixes an issue where the value would be out of sync with reality
in anonymous wrapper block boxes, since we forgot to compute m_visible
after assigning the computed values to them.
Fixes#21106
This one is a bit fun because it can be `add(<integer>)` or `auto-add`,
but children have to inherit the computed value not the specified one.
We also have to compute it before computing the font-size, because of
`font-size: math` which will be implemented later.
The value is originally set using a `CSSPixels` value converted to
double, then when it is used it is always converted back to a
`CSSPixels` again. Let's just store it as that instead.
This is intended to annotate conversions from unknown floating-point
values to CSSPixels, and make it more obvious the fp value will be
rounded to the nearest fixed-point value.
In general it is not safe to convert any arbitrary floating-point value
to CSSPixels. CSSPixels has a resolution of 0.015625, which for small
values (e.g. scale factors between 0 and 1), can produce bad results
if converted to CSSPixels then scaled back up. In the worst case values
can underflow to zero and produce incorrect results.
...along with `outline-color`, `outline-style`, and `outline-width`.
This re-uses the existing border-painting code, which seems to work well
enough!
This replaces the previous code for drawing focus-outlines, with generic
outline painting for any elements that want it. Focus outlines are now
instead supported by this code in Default.css:
```css
:focus-visible {
outline: auto;
}
```
Previously, we always rounded border-widths up when converting them to
device pixels. However, the spec asks us to follow a specific algorithm
to "snap" these values, so that the computed value is snapped.
The difference from before, is that widths of between 0 and 1 device
pixels are rounded up to 1, and and values larger than 1 are rounded
down.
The `clip_shrink` optimization in `paint_background()` now also
correctly uses DevicePixels, instead of reducing a DevicePixel rect by
a CSSPixels amount.
Anonymous wrapper boxes inherit style from their layout tree parent,
and since style data is per-layout-node, we have to manually sync them
from parent to anonymous children when something changes.
This is not very elegant or efficient, so I've left a FIXME about
solving it in a nicer way.
This fixes horizontal dog alignment on https://waffles.dog/ :^)
The CSS box-shadow property takes 2-4 properties that are `<length>`s,
those being:
- offset-x
- offset-y
- blur-radius
- spread-radius
Previously these were resolved directly to concrete Lengths at parse
time, but now they will be parsed as LengthStyleValues and/or
CalculatedStyleValues and be stored that way until styles are later
resolved.
On style update, we have to preserve the invariant established when we
built the layout tree - some properties are applied to the table wrapper
and the table box values are reset to their initial values.
This also ensures that the containing block of a table box is always a
table wrapper, which isn't the case if we set absolute position on the
box instead of the wrapper.
Fixes#19452.
Although DistinctNumeric, which is supposed to abstract the underlying
type, was used to represent CSSPixels, we have a whole bunch of places
in the layout code that assume CSSPixels::value() returns a
floating-point type. This assumption makes it difficult to replace the
underlying type in CSSPixels with a non-floating type.
To make it easier to transition CSSPixels to fixed-point math, one step
we can take is to prevent access to the underlying type using value()
and instead use explicit conversions with the to_float(), to_double(),
and to_int() methods.
Previously, we did an evenodd fill for everything which while for most
SVGs works, it is not correct default (it should be nonzero), and broke
some SVGs. This fixes a few of the icons on https://shopify.com/.
Having one StyleValue for `<number>` and `<integer>` is making user code
more complicated than it needs to be. We know based on the property
being parsed, whether it wants a `<number>` or an `<integer>`, so we
can use separate StyleValue types for these.
Solves conflict in layout tree "type system" when elements <label> (or
<button>) can't have `display: table` because Box can't be
Layout::Label (or Layout::ButtonBox) and Layout::TableBox at the same
time.
Specifically, stop letting NumericStyleValues holding `0` from
pretending to hold a Length. The parser is now smart enough that we
don't have to do this. :^)
Only NumericStyleValue holds integers.
I'm not sure our current distinction between NumericStyleValue holding
an integer or non-integer is useful given it always returns a float.
:thonk: