Commit graph

40 commits

Author SHA1 Message Date
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
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
e36750d591 LibWeb: Remove unused Layout::Node::did_insert_into_layout_tree() 2022-09-20 10:32:12 +02:00
Andreas Kling
6f433c8656 LibWeb+LibJS: Make the EventTarget hierarchy (incl. DOM) GC-allocated
This is a monster patch that turns all EventTargets into GC-allocated
PlatformObjects. Their C++ wrapper classes are removed, and the LibJS
garbage collector is now responsible for their lifetimes.

There's a fair amount of hacks and band-aids in this patch, and we'll
have a lot of cleanup to do after this.
2022-09-06 00:27:09 +02:00
MacDue
57c6792458 LibWeb: Support appearance: none for <progress> elements
This disables this system progress bar, and instead creates one
out of pseudo elements, that can be selected and styled with the
::-webkit-progress-bar/value selectors.
2022-07-23 01:45:49 +02:00
Andreas Kling
d2b887a793 LibWeb: Only create one wrapper for inline content inside flex container
Due to a missing `return` statement, we were creating two anonymous
wrapper blocks around each piece of inline content inside a flex
container.

This had no visual impact, since they ended up with 0x0 dimensions,
but we were wasting a fair bit of time running layout on them.
2022-07-13 01:26:29 +02:00
Andreas Kling
6712bbc0ee LibWeb: Tidy up Layout::TreeBuilder ancestor stack a little bit
- Make it a vector of references since we never put null pointers on
  the ancestor stack.

- Use Vector::in_reverse() to iterate backwards.
2022-04-13 19:52:25 +02:00
Andreas Kling
de5de4d99a LibWeb: Fix typo in CSS::Display::is_outside_and_inside() name 2022-04-13 16:40:46 +02:00
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Andreas Kling
9b0d158e69 LibWeb: Only set children-are-not-inline when inserting in-flow child
We were marking block boxes as having non-inline children when inserting
any child box, even if the child was out-of-flow.
2022-03-30 00:57:15 +02:00
Andreas Kling
54ffe79d70 LibWeb: Fix missing line-height & font-size on some anonymous blocks
Make sure we use the create_anonymous_wrapper() helper function whenever
wrapping inline content in anonymous wrapper blocks. We were forgetting
to do this in one case, which led to some wrapper blocks having 0px
font-size and line-height.
2022-03-24 18:30:56 +01:00
Andreas Kling
fa64a7f6cc LibWeb: Relax "all children must be either inline or block" invariant
This was implemented too rigidly, which made it impossible to place
floats correctly when they occurred in inline flow.

The new invariant is "all in-flow children must be either inline or
block". Out-of-flow children like floating and absolutely positioned
boxes are ignored when deciding when to generate anonymous boxes.
2022-03-22 19:26:51 +01:00
Andreas Kling
28b771560a LibWeb: Make SVG <svg> elements behave as CSS replaced elements
This makes SVG-in-HTML behave quite a bit better by following general
replaced layout rules. It also turns <svg> elements into inline-level
boxes instead of block-level boxes.
2022-03-19 12:42:10 +01:00
Lenny Maiorani
c37820b898 Libraries: Use default constructors/destructors in LibWeb
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#cother-other-default-operation-rules

"The compiler is more likely to get the default semantics right and
you cannot implement these functions better than the compiler."
2022-03-17 17:23:49 +00:00
Andreas Kling
b8ee4dfda8 LibWeb: Don't compute style *again* for elements in Layout::TreeBuilder
TreeBuilder wasn't taking advantage of the fact that we already have
computed style cached on each DOM::Element by the time we're
constructing a layout tree.

So instead of using the cached style, we recomputed it from scratch for
every element. This was done because invalidation was broken in many
places, but now that it's more or less trustworthy, stop recomputing
style on the fly in TreeBuilder and use what the preceding style update
pass gave us instead.

This basically cuts style computation work in half. :^)
2022-03-15 22:43:44 +01:00
Andreas Kling
e31fe3eeb8 LibWeb: Rename Element::specified_css_values() => computed_css_values()
Let's make it very clear that these are *computed* values, and not at
all the specified values. The specified values are currently discarded
by the CSS cascade algorithm.
2022-03-15 19:48:19 +01:00
Andreas Kling
72e6bff8b8 LibWeb: Remove unused code for constructing partial layout trees
We only ever build the whole layout tree in one go. Maybe one day we'll
support partial rebuilds, but for now, let's keep things simple.
2022-03-15 19:48:19 +01:00
Andreas Kling
12ac6861e3 LibWeb: Improve how layout nodes decide whether they have definite sizes
1. Make this decision *after* we've inserted the layout node into the
   layout tree. Otherwise, we can't reach its containing block!
2. Per css-sizing-3, consider auto-sized blocks whose sizes resolve
   solely against other definite sizes as definite themselves.

In particular, (2) makes us consider width:auto block children of a
definite-size containing block as having definite size. This becomes
very important in flex layout.
2022-03-13 00:04:51 +01:00
Sam Atkins
6de2b62906 LibWeb: Display pseudo-elements in the DOM inspector
This patch only makes them appear in the tree - they are not yet
inspectable themselves.
2022-03-10 17:30:09 +01:00
Sam Atkins
817cd13d59 LibWeb: Implement the ::marker pseudo-element
This matches the marker boxes of list-items.
2022-02-25 19:35:34 +01:00
Sam Atkins
ab2c47542d LibWeb: Create layout nodes for ::before and ::after pseudo-elements :^)
For now, we only handle their `content` being text, but it's a start!
2022-02-25 19:35:34 +01:00
Andreas Kling
92266d2247 LibWeb: Create list-item markers during layout tree construction
Previously, these were added during layout. This didn't fit into the new
world where layout doesn't mutate the tree incrementally, so this patch
adds logic to Layout::TreeBuilder for adding a marker to each list-item
box after its children have been constructed.
2022-02-21 18:35:12 +01:00
Andreas Kling
7e1bf4d300 LibWeb: Compute element style in Layout::TreeBuilder
Instead of making each Layout::Node compute style for itself, we now
compute it in TreeBuilder before even calling create_layout_node().

For non-element DOM nodes, we create the style and layout tree node
in TreeBuilder. This allows us to move create_layout_node() from
DOM::Node to DOM::Element.
2022-02-05 22:50:39 +01:00
Andreas Kling
f6573f5f9d LibWeb: Don't create anonymous table boxes around whitespace
This was confusing table layout by adding empty whitspace table boxes
that wound up stealing a bunch of horizontal space.
2021-10-27 18:22:00 +02:00
Andreas Kling
c4826eae4f LibWeb: Rename Layout::BlockBox => BlockContainer
There's a subtle difference here. A "block box" in the spec is a
block-level box, while a "block container" is a box whose children are
either all inline-level boxes in an IFC, or all block-level boxes
participating in a BFC.

Notably, an "inline-block" box is a "block container" but not a "block
box" since it is itself inline-level.
2021-10-06 20:10:36 +02:00
Andreas Kling
85a0772147 LibWeb: Start work towards modern CSS "display" values
Until now, we've internally thought of the CSS "display" property as a
single-value property. In practice, "display" is a much more complex
property that comes in a number of configurations.

The most interesting one is the two-part format that describes the
outside and inside behavior of a box. Switching our own internal
representation towards this model will allow for much cleaner
abstractions around layout and the various formatting contexts.

Note that we don't *parse* two-part "display" yet, this is only about
changing the internal representation of the property.

Spec: https://drafts.csswg.org/css-display
2021-10-06 19:12:52 +02:00
Tobias Christiansen
6283086c2f LibWeb: Handle inline-block children of a flex-container as block
We don't want to wrap the inline-blocks the same way we want to wrap
pure inline children.
2021-10-04 18:54:52 +02:00
Tobias Christiansen
610f14992a LibWeb: Flexbox: Wrap inline Nodes if their parent is display: flex 2021-09-29 17:55:57 +02:00
Andreas Kling
e91edcaa28 LibWeb: Rename InitialContainingBlockBox => InitialContainingBlock
The "Box" suffix added nothing here.
2021-09-08 11:27:46 +02:00
Daniel Bertalan
d7b6cc6421 Everywhere: Prevent risky implicit casts of (Nonnull)RefPtr
Our existing implementation did not check the element type of the other
pointer in the constructors and move assignment operators. This meant
that some operations that would require explicit casting on raw pointers
were done implicitly, such as:
- downcasting a base class to a derived class (e.g. `Kernel::Inode` =>
  `Kernel::ProcFSDirectoryInode` in Kernel/ProcFS.cpp),
- casting to an unrelated type (e.g. `Promise<bool>` => `Promise<Empty>`
  in LibIMAP/Client.cpp)

This, of course, allows gross violations of the type system, and makes
the need to type-check less obvious before downcasting. Luckily, while
adding the `static_ptr_cast`s, only two truly incorrect usages were
found; in the other instances, our casts just needed to be made
explicit.
2021-09-03 23:20:23 +02:00
K-Adam
e8d10fb429 LibWeb: Ignore svg elements outside of <svg> when building layout tree
An svg layout element without a `SVGSVGElement` ancestor caused a failed
assertion before, because the svg context does not exist when `paint()`
is called
2021-08-05 20:17:08 +02:00
Andreas Kling
ee3a73ddbb AK: Rename downcast<T> => verify_cast<T>
This makes it much clearer what this cast actually does: it will
VERIFY that the thing we're casting is a T (using is<T>()).
2021-06-24 19:57:01 +02:00
Andreas Kling
b91c49364d AK: Rename adopt() to adopt_ref()
This makes it more symmetrical with adopt_own() (which is used to
create a NonnullOwnPtr from the result of a naked new.)
2021-04-23 16:46:57 +02:00
Brian Gianforcaro
1682f0b760 Everything: Move to SPDX license identifiers in all files.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.

See: https://spdx.dev/resources/use/#identifiers

This was done with the `ambr` search and replace tool.

 ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
2021-04-22 11:22:27 +02:00
Adam Hodgen
ae02acb8e1 LibWeb: Properly handle thead and tfooter HTML tags
As the spec for the table fixup algorythm says:

> Treat table-row-groups in this spec also encompass the specialized
> table-header-groups and table-footer-groups.
2021-04-19 12:26:05 +02:00
Luke
ca71ac484b LibWeb: Rename "for_each_in_subtree(_of_type)" to "for_each_in_inclusive_subtree(_of_type)"
This is because it includes the initial node that the function was
called on, which makes it "inclusive" as according to the spec.

This is important as there are non-inclusive variants, particularly
used in the node mutation algorithms.
2021-04-06 21:42:00 +02:00
Andreas Kling
5d180d1f99 Everywhere: Rename ASSERT => VERIFY
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED)

Since all of these checks are done in release builds as well,
let's rename them to VERIFY to prevent confusion, as everyone is
used to assertions being compiled out in release.

We can introduce a new ASSERT macro that is specifically for debug
checks, but I'm doing this wholesale conversion first since we've
accumulated thousands of these already, and it's not immediately
obvious which ones are suitable for ASSERT.
2021-02-23 20:56:54 +01:00
Andreas Kling
e562819a7e LibWeb: Generate layout nodes for shadow subtrees
Elements with shadow roots will now recurse into those shadow trees
while building the layout tree.

This is the first step towards basic Shadow DOM support. :^)
2021-02-10 19:06:20 +01:00
Andreas Kling
13d7c09125 Libraries: Move to Userland/Libraries/ 2021-01-12 12:17:46 +01:00
Renamed from Libraries/LibWeb/Layout/TreeBuilder.cpp (Browse further)