Commit Graph

787 Commits

Author SHA1 Message Date
martinfalisse
a764e43db3 LibWeb: Factor out OccupationGrid functions
Clean up the code by using an OccupationGrid class. This was a neat idea
proposed by MacDue.
2022-10-06 21:16:01 +02:00
martinfalisse
db19570b94 LibWeb: Truncate oversized grid spans
If a span makes a CSS Grid item overflow vertically, then it should be
truncated as done on other web engines.
2022-10-06 21:16:01 +02:00
martinfalisse
f3bf01f265 LibWeb: Fix bug in placing row-constrained grid items
For row-constrained items (with a row position defined in the CSS),
should be checking for an available position in that row and not in
another..
2022-10-06 21:16:01 +02:00
martinfalisse
a528ea71d1 LibWeb: Use span values for auto-positioned grid items
Auto-positioned items should also take into account the span attributes
passed to them.
2022-10-06 21:16:01 +02:00
martinfalisse
330af1a769 LibWeb: Fix bug in spec implementation auto_placement_cursor 2022-10-06 21:16:01 +02:00
martinfalisse
93824edeb7 LibWeb: Fix implementation bugs of grid track is_span()
After having corrected the tracking of span variables in the
GridTrackPlacement class, now can fix some small bugs for its correct
implementation in the GridFormattingContext class.
2022-10-06 21:16:01 +02:00
martinfalisse
9fd07e9cb1 LibWeb: Make it easier to check if grid track is auto positioned
Add some helper functions for checking if a grid-track is
auto-positioned. I think this makes the code more legible.
2022-10-06 21:16:01 +02:00
martinfalisse
236795e931 LibWeb+Base: Re-implement grid track span
Implement span correctly when indicated in the grid-column-start,
grid-row-start, etc. CSS properties. Previously it had been implemented
as if span was something that went alongside the position property, but
actually it seems like if you do 'span 3' in the grid-column-start
property, for example, this means it literally spans 3 blocks, and the
3 has nothing to do with position.
2022-10-06 21:16:01 +02:00
Andreas Kling
b6ab9a261f LibWeb: Make TreeBuilder treat inline-flex's children correctly
We were skipping over inline flex containers when looking for an
insertion parent. This made us not generate flex items in those cases.

This commit changes the behavior, so that non-inline-level items can
get inserted into an inline-outside parent, as long as the parent isn't
just flow-inside.
2022-10-06 21:08:50 +02:00
Andreas Kling
71f7bb619d LibWeb: Use text node's own display value when inserting CSS content
This ensures that the pseudo element wrapper is transformed into a block
container with inline children if needed.
2022-10-06 21:08:50 +02:00
Andreas Kling
d3069bceeb LibWeb: Only consider inline-outside flag when choosing insertion type
Now that we don't have to deal with the ad-hoc "inline" flag on layout
nodes anymore, we're free to simply obey the inline-outside flag from
the CSS display value when choosing whether to insert as an inline-level
node or not.
2022-10-06 21:08:50 +02:00
Andreas Kling
82df793d5d LibWeb: Use correct cache key for pseudo elements
We were incorrectly caching both ::before and ::after pseudo elements
with the ::before key.

This regressed in 1ab7a8e0db.
2022-10-06 21:08:50 +02:00
Andreas Kling
97bbb630c8 LibWeb: Make IFC happy to layout anything as long as it's inline outside
Before this, whenever encountering something other than dumb text
content in an inline flow, we assumed it had to be either a replaced
element, or an inline-block.

This removes the special-casing of inline-block so that IFC can size and
layout anything as long as it's inline on the outside.
2022-10-06 21:08:50 +02:00
Andreas Kling
b9a45cf1aa LibWeb: Don't try to layout inside of replaced elements in BFC 2022-10-06 18:29:52 +02:00
Andreas Kling
5ff1fc4347 LibWeb: Make sure replaced elements never create a BFC 2022-10-06 18:29:52 +02:00
Andreas Kling
829ba4afb9 LibWeb: Remove unnecessary verify_cast in greatest_child_width() 2022-10-06 18:29:52 +02:00
Andreas Kling
2baad565ca LibWeb: Remove bogus verify_cast when dimensioning inline-blocks
There's no need to make the assumption that any inline-block box will
be represented by a BlockContainer. Nothing we do with the box here
requires that specific type anyway.
2022-10-06 17:15:28 +02:00
Andreas Kling
9d50191dca LibWeb: Tidy up FormattingContext::creates_block_formatting_context()
We use comments from MDN here, since the rules for creating a BFC are
inconsistently spread across many different specifications.
2022-10-06 17:15:28 +02:00
Andreas Kling
b4c90e35df LibWeb: Use CSS::Display::is_flow_inside() in InlineLevelIterator
This is a more correct check than !is_inline_block(), as it now enters
all elements that have inline behavior on the outside and flow behavior
on the inside.
2022-10-06 16:25:26 +02:00
Andreas Kling
13834cfdff LibWeb: Use Layout::Node::display() everywhere 2022-10-06 16:25:26 +02:00
Andreas Kling
49eb324535 LibWeb: Add Layout::Node::display()
This will return something sensible for style-less nodes as well.
2022-10-06 16:25:26 +02:00
Andreas Kling
a0e6882d99 LibWeb: Remove Layout::Node::set_inline()
Now that this flag is no longer used, we can stop setting it.
2022-10-06 15:29:38 +02:00
Andreas Kling
5989a3ee77 LibWeb: Honor CSS display value in is_inline() and is_inline_block()
These were totally ad-hoc before, is_inline() was based on a boolean
flag on Layout::Node that we set in various situations.

Meanwhile, is_inline_block() was a combination on is_inline() plus a
type check to see if the layout node inherited from BlockContainer.

This patch replaces the above mess with simple lookups of the CSS
display value. Note that layout nodes without their own style (i.e text
nodes) are automatically assumed to be inline and non-blocks. This has
to be special-cased since layout nodes without style will consult the
style of their parent, so without short-circuiting this would break.
2022-10-06 15:29:38 +02:00
Andreas Kling
fe03149a47 LibWeb: Base Layout::TreeBuilder decisions on CSS display property
This is one of many small steps towards being able to remove the ad-hoc
Layout::Node::is_inline() in favor of honoring the CSS display value
everywhere instead.
2022-10-06 15:29:38 +02:00
Andreas Kling
1ab7a8e0db LibWeb: Simplify construction of :before and :after pseudo elements
Let create_pseudo_element_if_needed() take care of inserting the pseudo
elements into the layout tree as well.
2022-10-06 15:29:38 +02:00
Andreas Kling
4fdfaff4ca LibWeb: Split out helper functions in TreeBuilder::create_layout_tree()
Let's make this function a little easier to understand by splitting out
helpers into separate functions.
2022-10-06 15:29:38 +02:00
Andreas Kling
f5844b85ff LibWeb: Let FFC parent context "handle" sizing of child FFC container
When we have nested flexbox layouts within one another, and the child
context wants to call up to the parent context and ask for help with
dimensioning the child flex container, we now simply do nothing.

As far as I can tell, this works out just fine, since the child flex
container will already be dimensioned by the flex layout algorithm.
2022-10-04 21:30:58 +02:00
Andreas Kling
c48931d15c LibWeb: Only calculate intrinsic size in the desired flex axis
Previously, FlexFormattingContext would calculate intrinsic sizes in
both axes simultaneously, despite only one being needed.

This patch reduces the amount of unnecessary work by only calculating
the requested intrinsic size.
2022-10-04 11:56:59 +02:00
Andreas Kling
4d84e349ae LibWeb: Recreate flex lines before calculating intrinsic cross size
This will allow us to do intrinsic cross sizing without depending on
intrinsic main sizing happening first.
2022-10-04 11:55:58 +02:00
Andreas Kling
181fc6cead LibWeb: Pack flex container from opposite end in *-reverse directions 2022-10-04 09:42:17 +02:00
Andreas Kling
b13a8706e1 LibWeb: Make intrinsic heights dependent on available width
After speaking with fantasai at CSSWG about this, it turns out I had
misunderstood intrinsic heights. I originally believed all intrinsic
sizes had to be computed with no influence from the surrounding context.

As it turns out, intrinsic heights *are* influenced by the available
width, since it's needed to determine where lines break.

The APIs for calculating min-content and max-content heights now take
the available width as inputs. This instantly improves layout in many
cases where we'd previously make things way too wide.
2022-10-03 23:49:23 +02:00
Andreas Kling
3408f7a3c5 LibWeb: Get rid of FormattingContext::run_intrinsic_sizing()
Now that we have AvailableSpace, it's actually quite convenient to
simply set up the available space and call run() with that directly.
2022-10-03 23:49:23 +02:00
Andreas Kling
f260afedb1 LibWeb: Don't add half-leading twice to inline block boxes
Inline-level blocks already have the half-leading applied internally,
so by adding it twice, we were offsetting their baseline by the
half-leading of the line.

This fixes an issue where inline-blocks were vertically offset from
the line they're supposed to sit on.
2022-10-03 17:22:08 +02:00
Andreas Kling
de6d012367 LibWeb: Improve placement of abspos boxes with dual-auto insets
When an absolutely positioned box has auto insets on both sides of an
axis, it's placed according to the "static position rectangle". This is,
roughly, the rectangle a box would occupy if it were position:static
instead of position:absolute or position:fixed.

This patch implements a rough, but still significantly better,
estimation of such static positions. It gets pretty hairy in the case
where an abspos box has a parent whose children are inline.
2022-10-02 21:14:02 +02:00
Andreas Kling
46a13c3d2e LibWeb: Add helpful locals in layout_absolutely_positioned_element()
This code had some obnoxiously repetetive call chains.
2022-10-02 21:14:02 +02:00
Andreas Kling
d1d99fda32 LibWeb: Vertical % margins are relative to containing block width
We were messing this up on absolutely positioned elements by using the
containing block height instead.
2022-10-02 21:14:02 +02:00
Andreas Kling
9c44634ca5 LibWeb: Reorganize layout algorithms around available space
This is a big and messy change, and here's the gist:

- AvaliableSpace is now 2x AvailableSize (width and height)

- Layout algorithms are redesigned around the idea of available space

- When doing layout across nested formatting contexts, the parent
  context tells the child context how much space is available for the
  child's root box in both axes.

- "Available space" replaces "containing block width" in most places.

- The width and height in a box's UsedValues are considered to be
  definite after they're assigned to. Marking something as having
  definite size is no longer a separate step,

This probably introduces various regressions, but the big win here is
that our layout system now works with available space, just like the
specs are written. Fixing issues will be much easier going forward,
since you don't need to do nearly as much conversion from "spec logic"
to "LibWeb logic" as you previously did.
2022-10-02 21:14:02 +02:00
Andreas Kling
b55c4ccdf7 LibWeb: Don't try to format inline-block boxes in BFC
Inline-level block boxes are handled by IFC. BFC doesn't have to worry
about these.
2022-10-02 21:14:02 +02:00
Andreas Kling
a0f3e2c9a2 LibWeb: Never claim that flex containers create a BFC
If a flex item is itself a flex container, we were previously lying when
asked if the item created a BFC. It creates an FFC, so stop lying about
this in FormattingContext::creates_block_formatting_context().
2022-09-29 20:10:12 +02:00
Andreas Kling
7c6e42c2d4 LibWeb: Fix bogus comparison when measuring if a float can fit
We were using `>=` instead of `>` when checking if a float with a given
width could fit in the available space. If the width was an exact match,
we rejected it! Oops :^)
2022-09-29 20:10:07 +02:00
Andreas Kling
e8a5233b94 LibWeb: Don't round fragment widths while accumulating in LineBuilder
By rounding the fragment widths, we sometimes inserted line breaks
prematurely, even though the fragment *would* fit.
2022-09-29 20:09:56 +02:00
Andreas Kling
d64a8c3d2a LibWeb: Resolve cross-axis flex item margins in the common case 2022-09-29 20:09:52 +02:00
Andreas Kling
9e4226f353 LibWeb: Create flex items for empty generated boxes
I couldn't find anything in the specs about this, but GMail uses
empty generated boxes (`::before` and `::after` with `content: ""`)
inside a flexbox container in order to vertically center things.

The flexbox spec tells us to not generate flex items for empty
*anonymous* boxes, so we continue not doing that, but generated boxes
(any pseudo-element box) now always produce a flex item. This probably
isn't perfect either, and we'll have to revisit it for stuff like
`::first-letter`.
2022-09-29 20:09:49 +02:00
Andreas Kling
8fa459f2d6 LibWeb: Add missing null checks in Layout::Node::set_needs_display()
Let's not assume the containing block has a paintable box just because
someone is calling set_needs_display(). It can just be a no-op in that
case, and nobody gets hurt.
2022-09-29 18:33:41 +02:00
Andreas Kling
385657a4bf LibWeb: Add a helper for calculating the stretch-fit width of a box 2022-09-29 18:33:41 +02:00
Andreas Kling
f161e20e57 LibWeb: Make FormattingContext::run() take available space as input
Instead of formatting contexts flailing around to figure out from the
"inside" how much space is available on the "outside", we should
provide the amount of available space in both axes as an input to run().

This basically means that when something creates a nested formatting
context, the parent context is responsible for telling the nested context
how much space is available for layout. This information is provided
immediately when invoking run().

Note that this commit doesn't pass accurate values in all cases yet.
This first step just makes it build, and passes available values in some
cases where getting them was trivial.
2022-09-29 18:33:41 +02:00
Andreas Kling
0843960235 LibWeb: Use CSS::Size for computed size and max-size values
This patch changes the *computed* representation of the following CSS
properties to use CSS::Size:

- width, min-width, max-width
- height, min-height, max-height

A few things had to change in order for things to keep working,
but I tried to keep the diff to a minimum.

The main trouble was that `min-width` and `max-width` can't actually be
`auto`, but they *can* be `none`. We previously treated `auto` as a
valid value (and it behaved mostly like `none`).
2022-09-25 17:51:43 +02:00
martinfalisse
521e19444c LibWeb: Make CSS Grid work again
Fixes bug after the automatic_content_height() changes where the height
of the grid container was not being calculated correctly.
2022-09-24 20:57:28 +02:00
Andreas Kling
c04b107e26 LibWeb: Treat replaced % sizes as 0 if containing block is indefinite 2022-09-24 14:41:18 +02:00
Andreas Kling
416fa7bd4f LibWeb: Bring flex basis calculation a little closer to spec
This ends up having a big impact on performance, as we now correctly
treat a used flex-basis of `content` as `max-content` which means
we can use cacheable intrinsic sizes for flex items in the majority
of cases.
2022-09-24 14:09:56 +02:00