Commit graph

198 commits

Author SHA1 Message Date
Sam Atkins
c449cabae3 LibWeb: Move CSS Parser into new Web::CSS::Parser namespace
The goal here is to move the parser-internal classes into this namespace
so they can have more convenient names without causing collisions. The
Parser itself won't collide, and would be more convenient to just
remain `CSS::Parser`, but having a namespace and a class with the same
name makes C++ unhappy.
2022-04-12 23:03:46 +02:00
Andreas Kling
a8afb883c1 LibWeb: Implement CSS declaration block's "updating flag"
This flag is used to prevent reparsing the style attribute after it is
automatically updated after using the CSSOM API to mutate style.
2022-04-11 21:10:07 +02:00
Andreas Kling
07a3002d39 LibWeb: Bring Element.client{Left,Top} closer to spec
These are supposed to return values based on the computed border size
of the element. Not the X/Y position values of the principal box.
2022-04-10 21:35:55 +02:00
Andreas Kling
25f6d2e2ab LibWeb: Update layout in Element.getBoundingClientRect() 2022-04-10 20:44:29 +02:00
Andreas Kling
bb17f74fb1 LibWeb: Bring Element.client{Width,Height} closer to spec
There were two main issues with these functions:

1. They were not updating layout before inspecting metrics.
2. They were not returning viewport metrics for the root and body
   elements when appropriate.
2022-04-10 20:30:19 +02:00
Simon Wanner
b19e134999 LibWeb: Invalidate layout after the computed font changes
If the font resource finishes loading we need to make sure the element
using it gets a chance to re-layout, even if the font-family property
didn't change.
2022-04-09 23:48:18 +02:00
Idan Horowitz
086969277e Everywhere: Run clang-format 2022-04-01 21:24:45 +01:00
Elisée Maurer
34db0dab41 LibWeb: Implement Element.toggleAttribute() 2022-03-30 18:30:29 +02:00
Andreas Kling
427beb97b5 LibWeb: Streamline how inline CSS style declarations are constructed
When parsing the "style" attribute on elements, we'd previously ask the
CSS parser for a PropertyOwningCSSStyleDeclaration. Then we'd create a
new ElementCSSInlineStyleDeclaration and transfer the properties from
the first object to the second object.

This patch teaches the parser to make ElementCSSInlineStyleDeclaration
objects directly.
2022-03-29 16:35:46 +02:00
Sam Atkins
da1a819858 LibWeb: Rename parse_css_declaration() -> parse_css_style_attribute() 2022-03-28 22:25:25 +02:00
Linus Groh
3cb7c463a7 LibWeb: Convert Element to use TRY for error propagation 2022-03-22 18:05:25 +00:00
Andreas Kling
8c88ee1165 LibWeb: Only invalidate stacking context tree for opacity/z-index change
I came across some websites that change an elements CSS "opacity" in
their :hover selectors. That caused us to relayout on hover, which we'd
like to avoid.

With this patch, we now check if a property only affects the stacking
context tree, and if nothing layout-affecting has changed, we only
invalidate the stacking context tree, causing it to be rebuilt on next
paint or hit test.

This makes :hover { opacity: ... } rules much faster. :^)
2022-03-21 13:03:33 +01:00
Andreas Kling
2b7775118d LibWeb: Clear element.style when the "style" attribute is removed
We were hanging on to element inline style, even after the style
attribute was removed. This made inline style sticky and impossible to
remove. This patch fixes that. :^)
2022-03-20 16:31:40 +01:00
Andreas Kling
3b037726e9 LibWeb: Invalidate layout after setting Element.innerHTML
It's not enough to only relayout here, since the API can substantially
change the DOM. We have to rebuild the layout tree.
2022-03-18 19:54:46 +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
d71b0e4638 LibWeb: Don't discard update_style_recursively() return value
This was causing us to miss layout invalidations. With this fixed, we
can remove the invalidation from Element::recompute_style() along with
the associated FIXME.

Thanks to Idan for spotting this! :^)
2022-03-16 21:30:39 +01:00
Andreas Kling
f1711a562a LibWeb: Avoid layout invalidation for some CSS property changes
Use the new CSS::property_affects_layout() helper to figure out if we
actually need to perform a full relayout after recomputing style.

There are three tiers of required invalidation after an element receives
new style: none, repaint only, or full relayout.

This avoids the need to rebuild the layout tree (and perform layout on
it) when trivial properties like "color" etc are changed.
2022-03-16 18:06:45 +01:00
Andreas Kling
28721874e8 LibWeb: Schedule a relayout after setting Element.innerHTML 2022-03-16 18:06:45 +01:00
Andreas Kling
b1096c2ae4 LibWeb: Make Element::set_shadow_root() disconnect any previous root 2022-03-16 00:38: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
43ef813f3d LibWeb: Rename Element::computed_style() to resolved_css_values()
This more accurately reflects what's actually being returned.
2022-03-15 19:48:19 +01:00
Andreas Kling
a033dfc885 LibWeb: Actually connect ShadowRoot to its host element
This way we can traverse from inside a shadow root across the boundary
to the outside. :^)
2022-03-15 19:48:19 +01:00
Andreas Kling
201afb50c7 LibWeb: Make Element::recompute_style() really compare properties
It's not enough to compare StyleProperties pointers to see if something
changed, we have to do a deep compare.
2022-03-13 00:04:51 +01:00
Andreas Kling
ba606d9057 LibWeb: Move PaintingBox to its own .cpp and .h files 2022-03-11 00:21:49 +01:00
Andreas Kling
9461e44afa LibWeb: Use Layout::Box::paint_box() accessor in more places 2022-03-11 00:21:49 +01:00
Andreas Kling
f6497b64ac LibWeb: Rename Painting::Box => Paintable
Calling this "Box" made it very confusing to look at code that used both
Layout::Box and Painting::Box. Let's try calling it Paintable instead.
2022-03-11 00:21:49 +01:00
Andreas Kling
a4d51b3dc2 LibWeb: Add Painting::Box and move things from Layout::Box into it
The "paintable" state in Layout::Box was actually not safe to access
until after layout had been performed.

As a first step towards making this harder to mess up accidentally,
this patch moves painting information from Layout::Box to a new class:
Painting::Box. Every layout can have a corresponding paint box, and
it holds the final used metrics determined by layout.

The paint box is created and populated by FormattingState::commit().

I've also added DOM::Node::paint_box() as a convenient way to access
the paint box (if available) of a given DOM node.

Going forward, I believe this will allow us to better separate data
that belongs to layout vs painting, and also open up opportunities
for naturally invalidating caches in the paint box (since it's
reconstituted by every layout.)
2022-03-11 00:21:49 +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
Andreas Kling
6499cf4d28 LibWeb: Always relayout document on element style change
Let's get this right before trying to make it fast. This patch removes
the code that tried to do less work when an element's style changes,
and instead simply invalidates the entire document.

Note that invalidations are still coalesced, and will not be
synchronized until update_style() and/or update_layout() is used.
2022-03-09 18:14:24 +01:00
networkException
3e7869d57d LibWeb: Remove outdated FIXME comment in Namespaces validate_and_extract
As step "2. Validate qualifiedName" got implemented in
bfa7aad0f6, parts is known to have a
length of 2.
2022-03-08 16:23:35 +01:00
Andreas Kling
7d052250f2 LibWeb: Don't create unwanted layout nodes when recomputing style
When recomputing the style for an element that previously didn't have
a corresponding layout node, it may become necessary to create a layout
node for it.

However, we should not do this if it's within a subtree that can't have
layout children. Nor should we do it for elements who have an ancestor
with display:none.
2022-03-04 23:40:21 +01:00
Andreas Kling
bfa7aad0f6 LibWeb: Support (and validate) prefixes in Document.createElementNS()
1% progression on ACID3. :^)
2022-03-02 10:55:16 +01:00
Andreas Kling
7231c1c895 LibWeb: Fix bogus result from "validate and extract" DOM operation
We were returning a QualifiedName with the localName and namespace
fields swapped.
2022-03-02 10:21:57 +01:00
Andreas Kling
29144f9238 LibWeb: Allow all ASCII whitespace chars between element class names
1% progression on ACID3. :^)
2022-02-25 19:38:31 +01:00
Sam Atkins
5390e05851 LibWeb: Extract code for creating a Layout::Node based on display type
We need to run the same logic for creating the ::before and ::after
pseudo-elements, so this saves us from duplicating the code.
2022-02-25 19:35:34 +01:00
Sam Atkins
7bb721bea2 LibWeb: Make display: foo box constructors take the Element by pointer
This means we can instantiate them for pseudo-elements, which don't have
an associated Element. They all pass it to their parent as a
`Layout::Node*` and handle a lack of `layout_node()` already so this
won't affect any functionality.
2022-02-25 19:35:34 +01:00
Andreas Kling
1b6ed558bb LibWeb: Move QualifiedName into the Web::DOM namespace 2022-02-19 14:45:59 +01:00
Edwin Hoksberg
c646afc26c LibWeb: Support Element.closest(selectors) 2022-02-16 07:23:27 -05:00
Andreas Kling
bdf0254b16 LibWeb: Add Element::did_remove_attribute() virtual
This allows subclasses to react to DOM attributes being removed.
2022-02-15 23:24:41 +01:00
Andreas Kling
c52dc87a42 LibWeb: Don't crash on unknown CSS display types, fall back to inline
This patch also adds CSS::Display::to_string() so we can log the
unimplemented CSS display value (if you have LIBWEB_CSS_DEBUG enabled).
2022-02-13 01:03:49 +01:00
DerpyCrabs
58ce2dd088 LibWeb: Add stub implementation for Element's getClientRects
getClientRects supposed to return a list of bounding DOMRect
for each box fragment of Element's layout, but most elements have
only one box fragment, so implementing it with getBoundingClientRect
is useful.
2022-02-12 22:43:10 +01:00
Andreas Kling
e2c71b6725 LibWeb: Add a partial implementation of Element.setAttributeNS()
This implementation does some of the required validation and then passes
through the localName and value to Element.setAttribute().
2022-02-05 22:50:39 +01:00
Andreas Kling
04bec7a4f5 LibWeb: Remove CSS::StyleInvalidator in favor of dirtying + lazy update
Style updates are lazy since late last year, so the StyleInvalidator is
actually hurting us more than it's helping by running the entire CSS
selector machine on the whole DOM for every attribute change.

Instead, simply mark the entire DOM dirty and let the lazy style update
mechanism run *once* on next event loop iteration.
2022-02-05 22:50:39 +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
Luke Wilde
4427386d5f LibWeb: Implement Element.getAttributeNames 2021-12-30 14:30:35 +01:00
Sam Atkins
7196570f9b LibWeb: Cast unused smart-pointer return values to void 2021-12-05 15:31:03 +01:00
Andreas Kling
7c57961c61 LibWeb: Move BrowsingContext into HTML/
Browsing contexts are defined by the HTML specification, so let's move
them into the HTML directory. :^)
2021-11-18 21:11:30 +01:00
Timothy Flynn
691e4820ac LibWeb: Remove two lowercase string creations from Element::has_class 2021-10-28 15:09:06 +02:00
Timothy Flynn
7f223e2290 LibWeb: Do not create lowercase strings in NamedNodeMap::get_attribute
Rather than following the spec exactly and creating lowercase strings,
we can simply do a case-insensitive string comparison. The caveat is
that creating attributes must follow the spec by creating the attribute
name with a lowercase string.
2021-10-28 15:09:06 +02:00
Timothy Flynn
14349f058a LibWeb: Implement the Element classList attribute
And ensure it is updated (if it exists) when the 'class' attribute is
changed.
2021-10-18 23:33:56 +02:00