Commit graph

115 commits

Author SHA1 Message Date
Aliaksandr Kalenik
910f9c2c09 LibWeb: Remove BrowsingContext pointer from Layout::Node
It's no longer needed.
2024-10-14 07:12:36 +02:00
Andreas Kling
cc4b3cbacc Meta: Update my e-mail address everywhere 2024-10-04 13:19:50 +02:00
Aliaksandr Kalenik
30b636e90b LibWeb: Add "position: sticky" support
Sticky positioning is implemented by modifying the algorithm for
assigning and refreshing scroll frames. Now, elements with
"position: sticky" are assigned their own scroll frame, and their
position is refreshed independently from regular scroll boxes.
Refreshing the scroll offsets for sticky boxes does not require display
list invalidation.

A separate hash map is used for the scroll frames of sticky boxes. This
is necessary because a single paintable box can have two scroll frames
if it 1) has "position: sticky" and 2) contains scrollable overflow.
2024-08-30 19:03:06 +02:00
Aliaksandr Kalenik
bbc89a383d LibWeb: Fix overflow clip when "complicated" CSS transform is used
Overflow clipping is currently implemented as:
1. Create clip frame for each box with hidden overflow
2. Calculate clip rect for each clip frame by intersecting padding boxes
   of all boxes with hidden overflow in containing block chain
3. Assign enclosing clip frame (closest clip frame in containing block
   chain) to each PaintableBox
4. Apply clip rect of enclosing clip frame in Paintable::before_paint()

It breaks when any CSS transform other than simple translation is lying
between box with hidden overflow and a clipped box, because clip
rectangle will be applied when transform has already changed.

The fix is implemented by relying on the following rule:
"For elements whose layout is governed by the CSS box model, any value
other than none for the transform also causes the element to establish
a containing block for all descendants."

It means everything nested into a stacking context with CSS transform
can't escape its clip, so it's safe to apply its clip for all children.
2024-08-01 12:03:13 +02:00
Arthur Hartwig Carlsson
196922ae5b LibWeb: Refactor out-of-flow and in-flow into functions
The concept of out-of-flow and in-flow elements is used in a few places
in the layout code. This change refactors these concepts into functions.
2024-07-06 10:02:29 +02:00
Timothy Flynn
464d7d5858 LibGfx+LibWeb: Allow inexact size lookups when requesting scaled fonts
For bitmap fonts, we will often not have an exact match for requested
sizes. Return the closest match instead of a nullptr.

LibWeb is currently the only user of this API. If it needs to be
configurable in the future to only allow exact matches, we can add a
parameter or another method at that time.
2024-05-06 23:26:42 +00:00
Andreas Kling
3945e1a82a LibJS: Make JS::Cell a Weakable
This makes things easier downstream of Cell, and is preparation for
using weak pointers in prototype chain property caches.
2024-05-04 21:42:59 +02:00
Aliaksandr Kalenik
613cd6104d LibWeb: Support masking of SVGForeignObjectPaintable 2024-04-27 07:10:20 +02:00
Andreas Kling
40a914ce1a LibWeb: Use static position for abspos box axes with auto insets
When both insets in a given axis are auto, we should use the static
position for absolutely positioned elements.

By doing this correctly, we exposed a bunch of other small bugs which
had to be fixed to compensate for new test failures. Those fixes are
included here as well:
- Don't apply margins twice.
- Compute the static position containing block chain correctly.

This makes https://brave.com/ look much better. :^)
2024-04-12 09:08:07 +02:00
Shannon Booth
c3217754f1 LibWeb: Remove a bunch of calls to to_byte_string
A bunch of this is leftover from pre porting over to new AK::String.
For example, for functions which previously took a ByteString const&
now accepting a StringView.
2024-04-05 20:01:37 -04:00
Andreas Kling
1987318cc2 LibWeb: Move selection state from layout tree to paint tree
Where we paint the selection is obviously paint-related information,
so let's keep it in the paint tree.
2024-03-18 13:42:16 +01:00
Andreas Kling
ad7e6878fe LibWeb: Allocate CSS::ComputedValues objects on the heap
This makes them cheap to move around, since we can store them in a
NonnullOwnPtr instead of memcopying 2584(!) bytes.

Drastically reduces the chance of stack overflow while building the
layout tree for deeply nested DOMs (since tree building was putting
these things on the stack).

This change also exposed a completely unnecessary ComputedValues deep
copy in block layout.
2024-01-27 12:27:44 +01:00
Aliaksandr Kalenik
1294cfb55c LibWeb: Find font that has whitespace glyph in first_available_font()
Fixes https://github.com/SerenityOS/serenity/issues/22853
2024-01-22 14:14:59 +01:00
Aliaksandr Kalenik
7c2713c14f LibWeb: Move set_needs_display() from layout node to paintable
For this method, there is no need to go through the layout node when we
can directly reach the paintable.
2024-01-15 09:00:35 +01:00
Aliaksandr Kalenik
814bed33b4 LibWeb: Move box_type_agnostic_position() from layout node to paintable
For this method, there is no need to go through the layout node when we
can directly reach the paintable.
2024-01-15 09:00:35 +01:00
Andreas Kling
bc3a16396e LibWeb: Move font list from NodeWithStyle to ComputedValues
Same here, no need for this to live in NodeWithStyle. Inheritance
behavior for free in ComputedValues.
2024-01-12 17:26:16 +01:00
Andreas Kling
c82d517447 LibWeb: Move line-height from NodeWithStyle to ComputedValues
There's no need for this to live in the NodeWithStyle anymore. By moving
it to ComputedValues we get all the right inheritance behavior for free.
2024-01-12 17:26:16 +01:00
Andreas Kling
4a35693dd7 LibWeb: Improve style propagation to anonymous wrappers
- We now propagate changes in font and line-height to anonymous wrappers
  when doing a partial style update after invalidation.

- We no longer (incorrectly) propagate style from table wrapper boxes
  to the table root, since inheritance works in the other direction.

Fixes #22395
2024-01-07 14:24:38 +01:00
Andreas Kling
f900957d26 LibGfx+LibWeb: Move Gfx::ScaledFont caching from LibWeb into LibGfx
Before this change, we would only cache and reuse Gfx::ScaledFont
instances for downloaded CSS fonts.

By moving it into Gfx::VectorFont, we get caching for all vector fonts,
including local system TTFs etc.

This avoids a *lot* of style invalidations in LibWeb, since we now vend
the same Gfx::Font pointer for the same font when used repeatedly.
2023-12-26 18:15:55 +01:00
Ali Mohammad Pur
5e1499d104 Everywhere: Rename {Deprecated => Byte}String
This commit un-deprecates DeprecatedString, and repurposes it as a byte
string.
As the null state has already been removed, there are no other
particularly hairy blockers in repurposing this type as a byte string
(what it _really_ is).

This commit is auto-generated:
  $ xs=$(ack -l \bDeprecatedString\b\|deprecated_string AK Userland \
    Meta Ports Ladybird Tests Kernel)
  $ perl -pie 's/\bDeprecatedString\b/ByteString/g;
    s/deprecated_string/byte_string/g' $xs
  $ clang-format --style=file -i \
    $(git diff --name-only | grep \.cpp\|\.h)
  $ gn format $(git ls-files '*.gn' '*.gni')
2023-12-17 18:25:10 +03:30
Aliaksandr Kalenik
2cb0039a13 LibGfx+LibWeb: Produce font cascade list in CSS font matching algorithm
According to the CSS font matching algorithm specification, it is
supposed to be executed for each glyph instead of each text run, as is
currently done. This change partially implements this by having the
font matching algorithm produce a list of fonts against which each
glyph will be tested to find its suitable font.

Now, it becomes possible to have per-glyph fallback fonts: if the
needed glyph is not present in a font, we can check the subsequent
fonts in the list.
2023-12-10 17:32:04 +01:00
Sam Atkins
9e99368694 LibWeb: Track quote-nesting level while building the layout tree
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.
2023-09-28 14:49:10 +02:00
Aliaksandr Kalenik
32be413f4e LibWeb: Add missing visit_edges() for ImageStyleValue
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.
2023-09-28 06:11:17 +02:00
Andreas Kling
1f69e9cddf LibWeb: Remove Layout::Node::m_visible and compute it on the fly
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
2023-09-18 14:45:20 +02:00
Aliaksandr Kalenik
dd7bba66ed LibWeb: Change viewport ownership from BrowsingContext to Navigable 2023-09-16 16:53:32 +02:00
Aliaksandr Kalenik
7eee3f6952 LibWeb: Add mutable_computed_values() for NodeWithStyle
This fixes the issue that we previously had to use a gross static_cast
whenever we wanted to mutate computed values outside of the Node
methods.
2023-09-12 17:26:30 +02:00
Aliaksandr Kalenik
b4064320bd LibWeb: Add m_is_grid_item in Layout::Node
This information is going to be needed during painting to treat grid
items as stacking contexts.
2023-08-22 11:33:24 +02:00
Andreas Kling
429b2e5860 LibWeb: Make FontCache per-StyleComputer
This effectively makes it per-Document, but we hang it off of
StyleComputer since that's what it's used for.

The purpose of this is to prevent downloaded fonts from escaping the
context that loaded them. There's probably a more elegant solution where
we still share caching of system fonts, but let's start here.
2023-08-17 20:32:21 +02:00
Andi Gallo
89305f1481 LibWeb: Copy button style properties for generated table and cell 2023-08-12 13:36:37 +02:00
Andi Gallo
b34b80104f LibWeb: Fix buttons with TextNode label
Fixes #20472.
2023-08-11 10:02:27 +02:00
Aliaksandr Kalenik
b6ea4b002b LibWeb: Add info about pseudo element type in Layout::Node 2023-08-07 05:23:31 +02:00
MacDue
21ace4f90b LibWeb: Add Node::scaled_font(float scale_factor)
This will allow fetching fonts scaled by a transform.
2023-07-21 11:42:30 +02:00
Andi Gallo
55f1a70577 LibWeb: Fix style updates for table box nodes
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.
2023-06-23 16:40:19 +02:00
Andreas Kling
b6f3369b66 LibWeb: Fix spelling of non_anonymous_containing_block() 2023-06-14 17:08:15 +02:00
Aliaksandr Kalenik
258f3ea952 LibWeb: Remove Layout::TableBox
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.
2023-05-29 14:12:29 +02:00
Andi Gallo
5cec517153 LibWeb: Get reference height from closest non-anonymous ancestor
Ignore anonymous block boxes when resolving percentage weights that
would refer to them, per the CSS 2 visual formatting model
specification. This fixes the case when we create an anonymous block
between an image which uses a percentage height relative to a parent
which specifies a definite height.

Fixes #19052.
2023-05-26 14:53:53 +02:00
Andreas Kling
e2c72922f6 LibWeb: Make LayoutState use HashMap instead of potentially huge Vector
Before this change, LayoutState essentially had a Vector<UsedValues*>
resized to the exact number of layout nodes in the current document.

When a nested layout is performed (to calculate the intrinsic size of
something), we make a new LayoutState with its own Vector. If an entry
is missing in a nested LayoutState, we check the parent chain all the
way up to the root.

Because each nested LayoutState had to allocate a new Vector with space
for all layout nodes, this could get really nasty on very large pages
(such as the ECMA262 specification).

This patch replaces the Vector with a HashMap. There's now a small cost
to lookups, but what we get in return is the ability to handle huge
layout trees without spending eternity in page faults.
2023-05-23 09:24:08 +02:00
Timothy Flynn
8f0b7fa370 LibWeb: Verify that a node has styled properties in its styled accessors
For example, it's possible to access Node::computed_values() on a node
that neither has style nor a parent with style. This ultimately results
in a null pointer dereference when we return parent()->computed_values()
as a fallback. This can be a little tricky to track down due to these
functions being inlined, so add an explicit verification.
2023-04-27 18:28:43 +02:00
MacDue
7061a3d8e6 LibWeb: Add .scaled_font() helper to Layout::Node
This returns the font scaled for the current zoom level.
2023-04-01 22:39:47 +01:00
Andreas Kling
1cf5737e9e LibWeb: Add fast_is<T>() for various types stood out in a profile 2023-03-11 10:46:26 +01:00
Andreas Kling
7e76a51cb0 LibWeb: Rename Layout::InitialContainingBlock to Layout::Viewport
The name "initial containing block" was wrong for this, as it doesn't
correspond to the HTML element, and that's specifically what it's
supposed to do! :^)
2023-02-28 12:21:56 +01:00
Andreas Kling
f11899f885 LibWeb+LibIDL: Fix (or paper over) various const-correctness issues
There's definitely stuff to iterate on here, but this takes care of
making the libraries compile with stricter RP and NNRP.
2023-02-21 00:54:04 +01:00
Timothy Flynn
1c1b902a6a LibJS+LibWeb: Move headers around to allow including Value from Cell
The goal here is to allow Cell::initialize to return a ThrowCompletion,
to handle OOM for example. Cell.h will then need to include Completion.h
which must include Value.h. This currently can't happen because Value.h
includes BigInt.h, which in turn includes Cell.h. So we would have an
include cycle.

This removes BigInt.h from Value.h, as it is forward-declarable (it is
only referred to with a reference or pointer). Then the Value overload
for Cell::Visitor::visit is moved to Cell.h, and missing BigInt.h
includes as peppered as needed.
2023-01-29 00:02:45 +00:00
Andreas Kling
aa19c4a340 LibWeb: Add Layout::Node::is_table() and make is<TableBox>() fast 2023-01-24 11:44:03 +01:00
Andreas Kling
51555dea7c LibWeb: Make Layout::Node::containing_block() return a Layout::Box
Containing blocks can be formed by boxes that aren't block containers,
so let's make this return a Box and work towards type correctness here.
2023-01-24 11:44:03 +01:00
Aliaksandr Kalenik
45e85d20b6 LibWeb: Output display type inline-table in layout dump 2023-01-17 10:18:33 +01:00
Aliaksandr Kalenik
709fe01f52 LibWeb: Override width calculation for table wrappers
Introduce `TableWrapper` type so table wrappers could be
distinguished from block containers and override width
calculation for table wrappers (CSS 2.2 spec, section 17.5.2)
 inside BFCs in the way that their width should be equal to
width of table box they wrap.
2023-01-14 19:22:08 +01:00
Andreas Kling
4d401bf796 LibWeb: Make the paint tree GC-allocated
This simplifies the ownership model between DOM/layout/paint nodes
immensely by deferring to the garbage collector for figuring out what's
live and what's not.
2023-01-11 12:55:00 +01:00
Aliaksandr Kalenik
57940f4370 LibWeb: Wrap table roots in anonymous block boxes
According to table fixup algorithm:
https://www.w3.org/TR/css-tables-3/#fixup-algorithm
around every table-root should be generated anonymous
box wrapper.

Also this patch implements important part of CSS 2.2
spec that is currently not present in CSS Tables 3
spec draft: https://www.w3.org/TR/CSS22/tables.html#model
that portion of computed properties should be moved
from table-root to table wrapper box. Without having
this part implemented height of absolutely positioned
table with `height: auto` won't be computed correctly.
2023-01-09 11:47:31 +01:00
Sam Atkins
5d8e3f5122 LibWeb: Convert Layout::Node to new pixel units 2023-01-05 17:42:31 +01:00