Commit graph

31 commits

Author SHA1 Message Date
Sam Atkins
76047d1932 LibWeb: Convert InlineLevelIterator/LineBox/LineBuilder to new px units 2023-01-05 17:42:31 +01:00
Baitinq
73e87d694e LibWeb: Don't collapse TextNode if it's editable
Fixes #16127
2022-11-26 01:21:02 +01:00
Andreas Kling
b062a0fb7c LibWeb: Make TextNode::ChunkIterator emit an empty chunk for content:""
This ensures that we create a line box for content:"", which would
otherwise get pruned by the empty line cleanup in IFC.

The empty line box is important in this case, since it gives us a
reference point for measuring the automatic height of the IFC's
containing block. By having an empty line, we can now correctly measure
the impact of vertical margins on a generated box with content:""
and allow them to contribute to the block height.
2022-10-14 19:50:15 +02:00
Andreas Kling
c70801ddbc LibWeb: Don't treat content: "" as collapsible whitespace
I couldn't find anything in specs about this, but it seems to be roughly
consistent with other engines.
2022-10-14 19:50:15 +02:00
Andreas Kling
063d6cab8b LibWeb: Remove unused Layout::TextNode::ChunkIterator::m_layout_mode 2022-10-14 19:50:15 +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
Ben Wiederhake
8deced39a8 LibWeb: Resolve cyclic declaration/definitions involving Length
This remained undetected for a long time as HeaderCheck is disabled by
default. This commit makes the following file compile again:

    // file: compile_me.cpp
    #include <LibWeb/CSS/GridTrackSize.h>
    // That's it, this was enough to cause a compilation error.
2022-09-15 14:45:38 +01:00
Andreas Kling
ed8930fff5 LibWeb: Add accessors for UsedValues::computed_{width,height}
This is preparation for doing some more work when assigning to these
values.
2022-07-19 15:40:41 +02:00
Andreas Kling
9b46091f38 LibWeb: Rename LayoutState::NodeState => LayoutState::UsedValues
This object contains all the CSS "used values" as seen during the layout
process, so calling it "used values" seems appropriate. :^)
2022-07-17 14:11:37 +02:00
Andreas Kling
52862c72d0 LibWeb: Rename FormattingState to LayoutState
This seems a bit more descriptive (and also a bit shorter).
2022-07-17 14:11:36 +02:00
Andreas Kling
28eec22c83 LibWeb: Don't iterate over text content inside replaced elements
This fixes an issue where whitespace inside embedded <svg> elements
would create unexpected whitespace text content on the page.

When combined with something like `white-space: pre-wrap`, it ended
up generating a lot of surprising vertical offsets.
2022-07-11 18:57:45 +02:00
Andreas Kling
8abbbdf6fa LibWeb: Cache a pointer to the IFC root in InlineLevelIterator 2022-07-06 20:31:27 +02:00
Andreas Kling
45db35ad04 LibWeb: Fix double-sized box model metrics on inline replaced elements
We were mistakenly treating inline replaced elements as if they are the
start of a regular display:inline element. This meant that we collected
the horizontal start and end metrics from the box model, and then added
those to the inline-level item produced by InlineLevelIterator.

This effectively meant that <img>, <svg> and other replaced elements got
double-sized values for margin/border/padding on the left and right
sides. (Which manifested as a mysterious margin around the element.)
2022-04-08 23:12:04 +02:00
Andreas Kling
4575ab558b LibWeb: Make whitespace collapsing stateless
Previously, the whitespace collapsing code had a parameter telling it
whether the previous text node ended in whitespace. This was not
actually necessary, so let's get rid of it.
2022-03-27 21:56:21 +02:00
Andreas Kling
aefe1727fc LibWeb: Make text newlines in "pre" mode emit a ForcedBreak item
Instead of emitting a Text item with the "should_force_break" flag set
to true, newlines in newline-preserving text content now timply turn
into ForcedBreak items. This makes the <pre> element work again.
2022-03-26 20:04:56 +01:00
Andreas Kling
de6f7f0029 LibWeb: Support CSS floats in inline flow
CSS floats are now emitted by the InlineLevelIterator. When this
happens, IFC coordinates with the parent BFC to float the box to the
side, using the current LineBuilder state for vertical placement.

This makes the "instructions" text on Acid3 render as a single
contiguous flow of inline content.
2022-03-22 19:26:51 +01:00
Andreas Kling
2dfb617c5b LibWeb: Make InlineLevelIterator emit absolutely positioned items
Note that we don't put absolutely positioned items on a line! This is
just so that IFC can discover boxes and pass them along to BFC.

This fixes an issue where only direct children of the IFC containing
block were considered for absolute positioning. Now we pick up
absolutely positioned children of nested inline nodes as well.
2022-03-08 00:19:49 +01:00
Andreas Kling
65b38f2623 LibWeb: Don't skip position:relative elements in inline-level layout
InlineLevelIterator was wrongly skipping over all positioned elements,
instead of just the absolutely positioned ones.
2022-03-02 17:40:18 +01:00
Andreas Kling
c8892f64f5 LibWeb: Make InlineLevelIterator not enter into inline-block boxes
The purpose of "entering" a box is to collect box model metrics that
apply to content fragments within the box. However, inline-blocks are
special, in that their inner content does not directly participate in
the inline formatting context outside it.
2022-02-26 09:27:20 +01:00
Andreas Kling
3ca26c7a7a LibWeb: Fix InlineLevelIterator not exiting box model metric nodes
We were neglecting to pop nodes from the box model stack. The metrics
were already being zeroed out when used, but let's not grow the stack
needlessly.
2022-02-26 09:25:24 +01:00
Andreas Kling
db5bf6e64c LibWeb: Rename FormattingState::ensure() -> get_mutable()
This makes it much more obvious what the difference between get() and
get_mutable() is.
2022-02-21 18:35:12 +01:00
Andreas Kling
c9700e100e LibWeb: Start making our layout system "transactional"
This patch adds a map of Layout::Node to FormattingState::NodeState.
Instead of updating layout nodes incrementally as layout progresses
through the formatting contexts, all updates are now written to the
corresponding NodeState instead.

At the end of layout, FormattingState::commit() is called, which
transfers all the values from the NodeState objects to the Node.

This will soon allow us to perform completely non-destructive layouts
which don't affect the tree.

Note that there are many imperfections here, and still many places
where we assign to the NodeState, but later read directly from the Node
instead. I'm just committing at this stage to make subsequent diffs
easier to understand.
2022-02-21 18:35:12 +01:00
Andreas Kling
6444525edc LibWeb: Make InlineLevelIterator skip over positioned elements 2022-02-15 02:05:53 +01:00
Andreas Kling
f2a917229a LibWeb: Support inline-level padding and border properly
Here's roughly how this works:

- InlineLevelIterator keeps a nesting stack of inline-level nodes with
  box model metrics.
- When entering a node with box model metrics, we add them to the
  current "leading metrics".
- When exiting a node with box model metrics, we add them to the
  current "trailing metrics".
- Pending leading metrics are consumed by the first fragment added
  to the line.
- Pending trailing metrics are consumed by the last fragment added
  to the line.

Like before, the position of a line box fragment is the top left of its
content box. However, fragments are placed horizontally along the line
with space inserted for padding and border.

InlineNode::paint() now expands the content rect as appropriate when
painting background and borders.

Note that margins and margin collapsing is not yet implemented.

This makes the eyes on ACID2 horizontally centered. :^)
2022-02-14 18:00:21 +01:00
Andreas Kling
0608de8c12 LibWeb: Rename Layout::Box::size() to content_size()
This property represents the CSS content size, so let's reduce ambiguity
by using the spec terminology.

We also bring a bunch of related functions along for the ride.
2022-02-06 01:07:47 +01:00
Andreas Kling
b1fd801436 LibWeb: Pass correct state to TextNode::compute_text_for_rendering()
This is poorly factored. TextNode needs to know whether the most
recently inserted fragment on the current line was empty or ended in
whitespace. This is used when deciding what to do with leading
whitespace in text nodes.

Let's keep this working for now, but we should eventually sort this out
and make text chunk iteration not depend on this information.
2022-01-23 01:22:41 +01:00
Andreas Kling
9f39ad8929 LibWeb: Ignore some collapsible whitespace when building lines
When collapsing whitespace, we can skip over all-whitespace chunks at
the start of each line, and immediately following fragments that
themselves end in whitespace.
2022-01-23 01:22:41 +01:00
Andreas Kling
78f2ddfc14 LibWeb: Make InlineLevelIterator ignore list item marker boxes
Marker boxes are managed explicitly by the corresponding list item box.
2022-01-23 01:22:41 +01:00
Andreas Kling
d3adc94ce8 LibWeb: Dimension inline-block boxes before deciding about line breaks
We won't know if we need to break before the inline-block box until
after we've dimensioned it.
2022-01-23 01:22:41 +01:00
Andreas Kling
67b3f769fb LibWeb: Teach InlineLevelIterator to skip across inline-block elements
We don't want to descend into inline-block containers when iterating
inline-level items, since that would make the inline-level children of
the inline-block bubble up to the containing block of the inline-block.
2022-01-23 01:22:41 +01:00
Andreas Kling
1f603c54ff LibWeb: Add inline-level iterator that enumerates items for line layout
This patch adds a new mechanism that allows InlineFormattingContext to
build line boxes incrementally instead of all-in-one go.

Incremental build will eventually allow much better support for CSS
floating objects.
2022-01-23 01:22:41 +01:00