1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-22 17:15:08 +00:00
Commit graph

230 commits

Author SHA1 Message Date
Andreas Kling
2b8c7faee4 LibWeb: Use the margin box of floating elements for flowing around
Inline content flows around the entire margin box of floating elements,
not just the content box.
2020-12-12 19:59:24 +01:00
Andreas Kling
66e9dde86f LibWeb: Don't place floating boxes before everything else
Instead, just handle them as we go about laying out block-level boxes.
2020-12-12 19:31:46 +01:00
Andreas Kling
b60801a9ba LibWeb: Apply 'min-width' and 'max-width' constraints to replaced boxes
This is definitely not 100% correct but I tried implementing the basic
algorithms described in CSS 2.2. It's good enough to render the penguin
on @linusg's homepage at the right size. :^)
2020-12-12 00:29:49 +01:00
Andreas Kling
552ba1b0a3 LibWeb: Remove some unnecessary is_replaced() checks in BFC
BFC::compute_width() has a short-circuit path for replaced elements.
2020-12-11 22:59:46 +01:00
Andreas Kling
67732df034 LibWeb: Move replaced element layout out of Layout::ReplacedBox
Replaced elements are now laid out by the current formatting context.
Since the logic is almost identical in BFC and IFC, it's implemented
by static helpers in FormattingContext.
2020-12-11 22:59:46 +01:00
Andreas Kling
e8d6691470 LibWeb: Fix inline-block width computation with no specified width
Undefined width should be treated the same as width:auto;
2020-12-11 22:59:46 +01:00
Andreas Kling
350b2c6d9e LibWeb: Use the surrounding text color as the caret color
This way you can always see the cursor as long (as you can see the text
you are editing.)
2020-12-10 11:39:47 +01:00
asynts
10f9c85090 LibWeb: Make DOM::Range more suitable for JS. 2020-12-09 21:05:06 +01:00
asynts
43dc47a494 LibWeb: Add support for range deletion. 2020-12-09 21:05:06 +01:00
asynts
bbcc5a9332 LibWeb: Move editing stuff into EditEventHandler. 2020-12-09 21:05:06 +01:00
Andreas Kling
3852168c84 LibWeb: Compute final line box width *after* placing all fragments
We were doing this after every fragment instead of after every line.
2020-12-07 21:48:23 +01:00
Andreas Kling
56ff2c112b LibWeb: When adding inline-block fragment to line, use border box width
We were only using the content box width for inline-block fragments,
which caused them to not to claim the space needed for padding+border.
2020-12-07 21:47:13 +01:00
Andreas Kling
a3acbf1db2 LibWeb: Include padding+border in shrink-to-fit preferred min width 2020-12-07 21:13:41 +01:00
Andreas Kling
5a57f618ad LibWeb: Resolve width in relative length units on inline-block properly
Element-relative width units like em, ex, etc. should be resolved
against the inline block itself, not against its containing block.
2020-12-07 20:55:44 +01:00
Andreas Kling
70de5fd056 LibWeb: Simplify final line box width computation
The width of a line box is the distance from the left edge of the first
fragment to the right edge of the last fragment. We don't have to loop
over all the fragments to figure this out. :^)
2020-12-07 20:48:26 +01:00
Andreas Kling
be18ac36b2 LibWeb: Use CSS::Length::resolved_or_zero() in a few places 2020-12-07 20:46:01 +01:00
Andreas Kling
cb04a5c52c LibWeb: Forget floating boxes once we've gone past them
Once we've generated enough lines to make it past all the floating
boxes on either side, just forget those boxes. This simplifies the
available space computation since we don't have to consider boxes
that can't vertically intersect the current line anyway.
2020-12-06 21:11:28 +01:00
Andreas Kling
9470169317 LibWeb: Floating elements should not stack horizontally after clear
After we've cleared past some floating elements, we should not keep
stacking new floats horizontally.

Instead, new floats after the clear should once again start at the
left or right edge of their containing block.
2020-12-06 21:00:04 +01:00
Andreas Kling
c953e5d98a LibWeb: Paint positioned elements after non-positioned ones
Within the same stacking context, positioned elements must be painted
after non-positioned ones.

I added a Layout::Node::for_each_child_in_paint_order() to help with
this since it's also needed for hit testing.
2020-12-06 20:05:04 +01:00
Andreas Kling
85a1bd6803 LibWeb: Add Layout::Node::is_positioned()
Any node that has a CSS position other than "static" is positioned.
2020-12-06 20:05:04 +01:00
Andreas Kling
59de4adb60 LibWeb: Pass current target box to BFC::run()
The BFC "context box" is now the outer box of the block formatting
context. Previously the context box was always the current target box,
which made it hard to reason about who was really the containing block
of whom in various places.

Note that IFC still has the containing block as its context box, this
change only affects BFC. However, to clarify the situation in IFC,
I've added a containing_block() getter than returns the context_box().
2020-12-06 20:05:04 +01:00
Andreas Kling
b638e74b68 LibWeb: Move box floatation out of normal flow layout
Layout of floating children now places the child in the normal flow and
then floats it left or right afterwards.
2020-12-06 20:05:04 +01:00
Andreas Kling
d582828040 LibWeb: Layout floating children per block instead of whole BFC at once
Instead of plowing through all the floating boxes within a BFC and
doing all the layout up front, do the children of each block as we go.
This will allow us to know the vertical position of the containing
block when placing floats.
2020-12-06 20:05:04 +01:00
Andreas Kling
6b4281c3aa LibWeb: Do floating box placement together with other boxes
I realized that we're supposed to float the boxes sideways, but not
always to y=0, so that makes it logical to share the placement logic
with other normal non-replaced blocks.

This is still pretty buggy but we're getting closer. :^)
2020-12-06 01:59:35 +01:00
Andreas Kling
af757a1659 LibWeb: Naively implement the CSS clear property
This is definitely not fully-featured, but basically we now handle
the clear property by forcing the cleared box below the bottom-most
floated box on the relevant side.
2020-12-06 01:45:51 +01:00
Andreas Kling
26a9ab7cd5 LibWeb: Floating boxes with width:auto should be shrink-to-fit 2020-12-06 01:16:45 +01:00
Andreas Kling
31a3ed70f0 LibWeb: Hit test floats using the top of lines, not middle
I don't know why basing the available space between floats on the y
coordinate in the middle of each line seemed like a good idea. It just
creates situations with a few pixels of floats overlapping text!
2020-12-05 23:54:07 +01:00
Andreas Kling
04e1827864 LibWeb: Run clang-format on ReplacedBox.cpp 2020-12-05 23:41:07 +01:00
Andreas Kling
66a053da77 LibWeb: Don't subtract dubious "line spacing" from line y offsets
I'm not sure what this was trying to achieve, but it was moving all
line fragments upwards and a lot of things look a lot better if we
just stop doing that.
2020-12-05 23:17:23 +01:00
Andreas Kling
65e430eee5 LibWeb: Floating boxes follow normal containing block rules
I had guessed that floating boxes should somehow be hoisted up to the
nearest block ancestor that creates a block formatting context, but
that's just wrong. They move up to the nearest block ancestor like any
other box that's not absolutely (or fixed) positioned. :^)
2020-12-05 23:12:29 +01:00
Andreas Kling
2f38d94c70 LibWeb: Fix off-by-one when computing available space between floats
Whoops, this explains why things were not lining up correctly. :^)
2020-12-05 22:51:03 +01:00
Andreas Kling
615a4d4f71 LibWeb: First slightly naive implementation of CSS floats :^)
Boxes can now be floated left or right, which makes text within the
same block formatting context flow around them.

We were creating way too many block formatting contexts. As it turns
out, we don't need one for every new block, but rather there's a set
of rules that determines whether a given block creates a new block
formatting context.

Each BFC keeps track of the floating boxes within it, and IFC's can
then query it to find the available space for line boxes.

There's a huge hack in here where we assume all lines are the exact
line-height. Making this work with vertically non-uniform lines will
require some architectural changes.
2020-12-05 22:51:03 +01:00
Andreas Kling
11256de366 LibWeb: Add Layout::Node::is_root_element()
This returns true if the layout node corresponds to the <html> element.
2020-12-05 22:51:03 +01:00
Andreas Kling
157896cc0b LibWeb: Block layout should account for vertical border space
We were not accounting for space occupied by borders when computing
the vertical (y) position of blocks. This meant that blocks with wide
top/bottom borders could bleed into each other incorrectly.

Fix this by using the combined padding+border geometry instead of just
the padding when placing blocks on the y axis.
2020-12-04 21:24:35 +01:00
Andreas Kling
c39e29d186 LibWeb: Block layout should resolve relative lengths against each box
We were incorrectly resolving relative length units (ex, em, etc.)
against the containing block in many cases. Fix this to resolve them
against the descendant box we're currently processing.
2020-12-04 21:22:49 +01:00
Andreas Kling
90b12a41c8 LibWeb: Make LineBox take incoming fragment size as floats 2020-12-04 21:06:27 +01:00
Andreas Kling
3eb07d289e LibWeb: Move border painting from Layout::Box to a free function
This will allow us to share some code between inline and non-inline
border painting.
2020-12-04 18:02:21 +01:00
Andreas Kling
169a9150cb LibWeb: Rename LayoutNode::is_root() => is_initial_containing_block()
Let's use spec language for this. :^)
2020-12-04 16:27:07 +01:00
Andreas Kling
e0809f78a9 LibWeb: Call the correct base class in InlineNode::split_into_lines() 2020-12-04 16:21:21 +01:00
Andreas Kling
2cbbab8f73 LibWeb: Compute the final border-style property before painting
Instead of doing a CSS property lookup for the line style of each
border edge during paint, we now cache the final CSS::LineStyle to use
in the Layout::BorderData.
2020-12-04 16:11:55 +01:00
Andreas Kling
88ca932fac LibWeb: Make LineBoxFragment store non-const Layout::Node&
This is more honest, since we actually const_cast these layout nodes
during inline layout anyway.
2020-12-04 15:46:58 +01:00
Andreas Kling
f35b406dfb LibWeb: Virtualize Layout::Node::paint_fragment()
LineBoxFragment no longer needs to care what type of layout node a
fragment refers to during paint, it can just call paint_fragment(). :^)
2020-12-03 21:46:01 +01:00
Andreas Kling
d59ec3ab85 LibWeb: Create "empty" line box fragments for inline elements
In order for inline elements (e.g <span>) to contribute padding etc.
to line boxes, we now create special "leading" and "trailing" fragments
for Layout::InlineNode and size them according to the horizontal
padding values.

The height of these fragments is taken from the tallest fragment on the
line. (Perhaps we should stop having per-fragment heights and just keep
a single height per line box, but that's a separate issue.)

In order to make things look nice, we now also adjust the height of all
fragments on a line so that nobody is shorter than the CSS line-height.
2020-12-03 21:45:51 +01:00
Andreas Kling
311e1039b5 LibWeb: Paint line box fragments during all paint phases
Fragment painting was very limited by only being called during the
foreground paint phase. We now paint fragments as part of every phase
(and the phase is passed to paint_fragment() of course!)
2020-12-03 21:45:46 +01:00
Andreas Kling
d129e68da8 LibWeb: Move PaintPhase enum out of Layout::Node
Now it's just Layout::PaintPhase instead of Layout::Node::PaintPhase.
2020-12-03 21:45:41 +01:00
Andreas Kling
d6c2a61fa1 LibWeb: Add type casting helpers for Layout::InlineNode 2020-12-03 21:45:38 +01:00
Andreas Kling
17e9a5e0c5 LibWeb: Hoist an early return in Layout::BlockBox::paint() 2020-12-03 17:17:11 +01:00
Andreas Kling
65eef944ab LibWeb: Auto-size table box height to fit all the rows
This is just a hack until we implement the full 'height' property for
tables. :^)
2020-11-29 22:39:01 +01:00
Andreas Kling
b19f62217f LibWeb: Allow inline-block boxes to have non-inline children
We were incorrectly hoisting non-inline children of inline-block boxes
to the nearest non-inline ancestor.

Since inline-block boxes are only inline on the *outside*, it's fine
for them to have non-inline children.

Eventually we should clarify these relationships by making the inside
and outside display types more explicit.
2020-11-29 22:26:54 +01:00
Andreas Kling
39c7d9f061 LibWeb: Remove margin/border/padding from inline-block available width 2020-11-29 22:00:44 +01:00