Commit graph

31 commits

Author SHA1 Message Date
zac
8c29b0a848 LibWeb/Tests: Add empty text chunk in empty editables
Otherwise the cursor won't get rendered in empty input fields.
2025-09-24 12:33:17 +01:00
Jelle Raaijmakers
9e9db9a9dd LibWeb: Store correct text offsets in PaintableFragment
Previously, we were collapsing whitespace in Layout::TextNode and then
passed the resulting string for further processing through ChunkIterator
-> InlineLevelIterator -> InlineFormattingContext -> LineBuilder ->
LineBoxFragment -> PaintableFragment. Our painting tree is where we deal
with things like range offsets into the underlying text nodes, but since
we modified the original string, the offsets were wrong.

This changes the way we generate fragments:

  * Layout::TextNode no longer collapses whitespace as part of its
    stored "text for rendering", but moves this logic to ChunkIterator
    which splits up this text into separate views whenever whitespace
    needs to be collapsed.

  * Layout::LineBox now only extends the last fragment if its end offset
    is equal to the new fragment's start offset. Otherwise, there's a
    gap caused by collapsing whitespace and we need to generate a
    separate fragment for that in order to have a correct start offset.

Some tests need new baselines because of the fixed start offsets.

Fixes #566.
2025-09-12 15:34:09 -04:00
Jelle Raaijmakers
d1076c1e6e LibWeb: Remove text storage from TextPaintable
Instead of copying the layout node's text, retrieve the text from the
layout node directly.
2025-09-12 15:34:09 -04:00
Jelle Raaijmakers
e6474778c6 LibWeb: Some text-related cleanup
No functional changes.
2025-09-12 15:34:09 -04:00
Jelle Raaijmakers
7375d8c6f9 LibWeb: Simplify ASCII whitespace check in Layout::TextNode
No functional changes.
2025-09-12 15:34:09 -04:00
Timothy Flynn
0e4fb9ae73 LibWeb: Ensure up/down arrow navigation is grapheme-aware
Previously, it was possible for an up/down arrow press to place the
cursor in the middle of a multi-code point grapheme cluster. We want to
prevent this in a way that matches the behavior of other browsers.

Both Chrome and Firefox will map the starting position to a visually
equivalent position in the target line with harfbuzz and ICU segmenters.
The need for this is explained in a code comment. The result is a much
more natural feeling of text navigation.
2025-08-18 13:17:28 +02:00
Timothy Flynn
97548f48de LibWeb: Port rendered text to UTF-16
This migrates TextNode::text_for_rendering() to Utf16String and deals
with the fallout. As a consequence, this effectively reverts commit
3df83dade8.

The layout test expecation file updates are because we now express text
lengths and offsets in UTF-16 code units.

The selection-over-multiple-code-units expectation file update actually
represents a correctness fix. Our result now matches Firefox.
2025-07-25 18:16:22 +02:00
Timothy Flynn
8b6e3cb735 LibWeb+LibUnicode+WebContent: Port DOM:CharacterData to UTF-16
This replaces the underlying storage of CharacterData with Utf16String
and deals with the fallout.
2025-07-24 19:00:20 +02:00
Jelle Raaijmakers
c91718148d LibWeb: Undo curious case of line wrapping 2025-06-17 17:03:33 +02:00
Callum Law
94f5a51820 LibWeb: Convert white-space CSS property to shorthand
This exposed a few bugs which caused the following tests to behave
incorrectly:
- `tab-size-text-wrap.html`: This previously relied on a bug where we
  incorrectly treated `white-space: pre` as allowing text wrapping. The
  fix here is to implement the text-wrap CSS shorthand property.

- `execCommand-preserveWhitespace.html`: We don't correctly serialize
  shorthand properties. This is covered by an existing FIXME in
  `CSSStyleProperties::serialized()`

- `white-space-shorthand.html`: The last 5 subtests here fail as we
  don't correctly handle shorthand properties in
  `CSSStyleProperties::remove_property()`. This is covered by an
  existing FIXME in said function.
2025-05-29 12:04:28 +02:00
Jelle Raaijmakers
29f1648bc5 LibWeb: Do not override whitespace handling for editable elements
This condition no longer seems to be necessary for anything, and it
caused newlines to not render correctly in editable nodes.
2025-05-16 12:08:29 +01:00
Shannon Booth
3e17b1c9ae LibWeb: Make Node::parent_element return GC::Ptr
This is useful for people like myself who run with debug mode to
more reliably get stacktraces without spinning up a debugger.
2025-04-18 10:49:02 +02:00
Shannon Booth
f87041bf3a LibGC+Everywhere: Factor out a LibGC from LibJS
Resulting in a massive rename across almost everywhere! Alongside the
namespace change, we now have the following names:

 * JS::NonnullGCPtr -> GC::Ref
 * JS::GCPtr -> GC::Ptr
 * JS::HeapFunction -> GC::Function
 * JS::CellImpl -> GC::Cell
 * JS::Handle -> GC::Root
2024-11-15 14:49:20 +01:00
Sam Atkins
c747b1c6b5 LibWeb: Calculate hidden password text using code-point count
This means that an `<input type=password>` will show the correct number
of *s in it when non-ASCII characters are entered.

We also don't need to perform text-transform on these as that doesn't
affect the output length, so I've moved it earlier.
2024-11-14 20:23:58 +01:00
Timothy Flynn
93712b24bf Everywhere: Hoist the Libraries folder to the top-level 2024-11-10 12:50:45 +01:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Andreas Kling
612827eff3 LibWeb: Don't prune whitespace nodes from layout tree
Various whitespace-related issues have been fixed, and support for the
different CSS white-space values is improved enough that I think we can
stop doing the hack where we just prune whitespace nodes from the tree
and actually let them show up.

This is a nice step forward for correctness with the slight downside of
cluttering up layout tree dumps with tons of whitespace text nodes.
But hey, that's the web we know & love. :^)

Fixes #4427.
2021-01-06 14:58:48 +01:00
Andreas Kling
e5490ae1d1 LibWeb: Rename Layout::Node::style() => computed_values() 2021-01-06 14:58:48 +01:00
Andreas Kling
e187a5365a LibWeb: Store the used font in Layout::NodeWithStyle
This is a step towards not having to carry the full set of specified
values around with every layout node.
2021-01-06 14:58:48 +01:00
Andreas Kling
4a7d948f14 LibWeb: Simplify one kind of whitespace collapsing
For a non-empty TextNode chunk that begins with collapsible whitespace,
we can simply step right over the whitespace by adjusting the chunk.
2021-01-06 00:54:54 +01:00
Andreas Kling
18f1f4e1a2 LibWeb: Only preserve full whitspace for white-space: pre{,-wrap} 2020-12-18 11:04:29 +01:00
Andreas Kling
6d7892cfc4 LibWeb: Whitespace that causes a line to wrap should be hidden
We were only pruning trailing whitespace on lines. This patch makes it
so we also don't add whitespace as the leading line box fragment on new
lines.

This logic is pretty crufty and I think we can do better, but for now
I've just made it handle this extra case so we can stop having lines
that start with a space character. :^)
2020-12-17 21:10:57 +01:00
Andreas Kling
c630ae517e LibWeb: Put final foreground/background colors in LayoutStyle
This way we don't have to look them up in the CSS::StyleProperties
every time we want to paint with them.
2020-12-15 19:33:53 +01:00
Andreas Kling
78a51933ad LibWeb: Use IdentifierStyleValue for CSS 'text-transform' 2020-12-15 19:33:53 +01:00
Andreas Kling
4d7ce81835 LibWeb: Use IdentifierStyleValue for CSS 'text-decoration-line'
Also 'text-decoration' is actually a shorthand, so treat it that way.
2020-12-15 19:33:53 +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
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
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
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
5aeab9878e LibWeb: Rename LayoutNode classes and move them into Layout namespace
Bring the names of various boxes closer to spec language. This should
hopefully make things easier to understand and hack on. :^)

Some notable changes:

- LayoutNode -> Layout::Node
- LayoutBox -> Layout::Box
- LayoutBlock -> Layout::BlockBox
- LayoutReplaced -> Layout::ReplacedBox
- LayoutDocument -> Layout::InitialContainingBlockBox
- LayoutText -> Layout::TextNode
- LayoutInline -> Layout::InlineNode

Note that this is not strictly a "box tree" as we also hang inline/text
nodes in the same tree, and they don't generate boxes. (Instead, they
contribute line box fragments to their containing block!)
2020-11-22 15:56:27 +01:00
Renamed from Libraries/LibWeb/Layout/LayoutText.cpp (Browse further)