Commit Graph

2255 Commits

Author SHA1 Message Date
Andreas Kling
b1096c2ae4 LibWeb: Make Element::set_shadow_root() disconnect any previous root 2022-03-16 00:38:44 +01:00
sin-ack
d2a99eded7 LibWeb: Convert usages of type() to type_state()
This doesn't have any performance benefit yet as we still do string
comparisons everytime, but it should improve once type_state() has a
better implementation.
2022-03-16 00:38:31 +01:00
sin-ack
57a85b1017 LibWeb: Ensure that radio group is updated when radio is checked from JS
Fixes test 56 in Acid3.

Farewell, radio eyes, you will be missed. :^(
2022-03-16 00:38:31 +01:00
sin-ack
b3df222e52 LibWeb: Fire a UIEvents::MouseEvent for HTMLElement.click()
This still is not perfectly correct but it's enough to trigger the
activation behavior of elements and gain us a point on Acid3. :^)
2022-03-16 00:38:31 +01:00
sin-ack
29583104d2 LibWeb: Refactor all LabelableNode subclasses + input event handling :^)
This commit is messy due to the Paintable and Layout classes being
tangled together.

The RadioButton, CheckBox and ButtonBox classes are now subclasses of
FormAssociatedLabelableNode. This subclass separates these layout nodes
from LabelableNode, which is also the superclass of non-form associated
labelable nodes (Progress).

ButtonPaintable, CheckBoxPaintable and RadioButtonPaintable no longer
call events on DOM nodes directly from their mouse event handlers;
instead, all the functionality is now directly in EventHandler, which
dispatches the related events. handle_mousedown and related methods
return a bool indicating whether the event handling should proceed.

Paintable classes can now return an alternative DOM::Node which should
be the target of the mouse event. Labels use this to indicate that the
labeled control should be the target of the mouse events.

HTMLInputElement put its activation behavior on run_activation_behavior,
which wasn't actually called anywhere and had to be manually called by
other places. We now use activation_behavior which is used by
EventDispatcher.

This commit also brings HTMLInputElement closer to spec by removing the
did_foo functions that did ad-hoc event dispatching and unifies the
behavior under run_input_activation_behavior.
2022-03-16 00:38:31 +01:00
Andreas Kling
06ccc45157 LibWeb: Don't create HTMLInputElement's UA shadow tree for buttons
We don't need an internal editable text node inside buttons. :^)
2022-03-16 00:26:02 +01: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
1881761d0f LibWeb: Fix mistake in Node::invalidate_style()
We were not actually walking past the first ancestor when setting
child-needs-update bit upwards.

Also, let's walk all the way to the root, even if there's a
child-needs-update bit already set. This ensures that we always leave
this function with the ancestor chain in a sane state.
2022-03-15 22:43:44 +01:00
Andreas Kling
b4bda4cdf3 LibWeb: Make invalidate_style() set child-needs-update on shadow hosts 2022-03-15 22:43:44 +01:00
Andreas Kling
03d6e1953f LibWeb: Improvements to Node::invalidate_style()
- Access members directly instead of going through accessors,
  avoiding a lot of redundant traversal done by accessors.

- Cross shadow boundaries and make sure that shadow trees get their
  dirty bits updated as well.

- Do the minimum amount of traversal needed when setting the "child
  needs style update" bit upwards through ancestors.
2022-03-15 20:02:30 +01:00
Vrins
044be82567 Browser: Allow jumping to stylenames by typing in the inspector
This adds the default behavior of search and highlighting of
abstractView to the inspectorWidget. Search results are based on
the titles in the first columns.
2022-03-15 20:00:09 +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
8aa24c45dd LibWeb: Make BrowsingContext::reset_cursor_blink_cycle() more robust
If the browsing context text cursor has become invalid for whatever
reason, don't try to repaint its associated node.
2022-03-15 19:48:19 +01:00
Andreas Kling
5b8290dfa3 LibWeb: Invalidate document style after Node.insertBefore() 2022-03-15 19:48:19 +01:00
Andreas Kling
cf49e93b04 LibWeb: Invalidate style on media query evaluation change 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
759bfbb572 LibWeb: Use StyleComputer::invalidate_rule_cache() directly everywhere
Get rid of the old, roundabout way of invalidating the rule cache by
incrementing the StyleSheetList "generation".

Instead, when something wants to invalidate the rule cache, just have it
directly invalidate the rule cache. This makes it much easier to see
what's happening anyway.
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
88173648e3 LibWeb: Create HTMLInputElement UA shadow tree when inserted into DOM
Previously, we were creating a user-agent shadow tree when constructing
a layout tree. This meant that we did DOM manipulation (and consequently
style invalidation) during layout tree construction, which made things
very hard to reason about in Layout::TreeBuilder.

Simply everything by simply creating the UA shadow tree when the input
element inserted into a parent node instead.
2022-03-15 19:48:19 +01:00
Andreas Kling
511d4951b0 LibWeb: Don't access layout nodes in StyleComputer
Style computation always happens *before* layout, so we can't rely on
things having (or not having) layout nodes, as that information will
always be one step behind.

Instead, we have to use the DOM to find all the information we need.
2022-03-15 19:48:19 +01:00
Andreas Kling
cf69cc7f7d LibWeb: Invalidate style when a browsing context's viewport is resized
Anything with viewport-relative CSS lengths (vw/vh/vmin/vmax) needs to
have its style recomputed if the viewport size changes.
2022-03-15 19:48:19 +01:00
Andreas Kling
2be4064ca8 LibWeb: Add fast_is<ParentNode>() 2022-03-15 19:48:19 +01:00
Andreas Kling
32dd4bf1b9 LibWeb: Recurse into shadow trees when updating style
The style update mechanism was happily ignoring shadow subtrees.
Fix this by checking if an element has a shadow root, and recursing into
it if needed.
2022-03-15 19:48:19 +01:00
Andreas Kling
5d941ddf3a LibWeb: Make style invalidation cross shadow boundaries
Before this change, style invalidation didn't propagate upwards across
shadow boundaries, so our shadow trees were sitting there with invalid
style, never actually getting updated.
2022-03-15 19:48:19 +01:00
Andreas Kling
fdb647c097 LibWeb: Use a WeakPtr for DocumentFragment's "host" field
We had a reference cycle between fragments and their hosts.
2022-03-15 19:48:19 +01:00
Andreas Kling
7a82a6dfe8 LibWeb: Add equals() override to a bunch of StyleValue subclasses
The less we fall back to string-based equality testing, the better.
2022-03-15 19:48:19 +01:00
Brian Gianforcaro
af50895fa3 LibWeb: Fix height/width copy paste bug in SVGFormattingContext::run
This was found by SonarCloud:
- Identical sub-expressions on both sides of operator "&&".
2022-03-14 22:30:22 +01:00
Simon Wanner
1f9d76c7b8 LibWeb: Invalidate styles after CSSImportRule loads
This replicates the behavior of StyleSheetList::add_sheet, making sure
the rules added by the imported style sheet are applied.
2022-03-14 22:22:53 +01:00
Simon Wanner
1ed5e79478 LibWeb: Fix resolving relative URLs in style sheets
Relative URLs in style sheets should be resolved relative to the
style sheet they're in instead of the document.
2022-03-14 22:22:53 +01:00
Idan Horowitz
c575710e5e LibWeb: Use inline script tag source line as javascript line offset
This makes JS exception line numbers meaningful for inline script tags.
2022-03-14 00:25:33 +01:00
Andreas Kling
c1e6fc67a1 LibWeb: Add a Vector::ensure_capacity() in collect_matching_rules()
Avoid some incremental Vector growth by pre-allocating enough capacity
to cover the case where every single selector matches an element.
2022-03-13 19:55:08 +01:00
Andreas Kling
afc5fade05 LibWeb: Add some fast_is<T> helpers for hot classes on GitHub :^) 2022-03-13 18:09:43 +01:00
Andreas Kling
39389b5704 LibWeb: Don't make deep copy of custom properties for every element
Previously we were making a copy of the full set of custom properties
that applied to a DOM element. This was very costly and dominated the
profile when mousing around on GitHub.

Note that this may break custom properties on pseudo elements a little
bit, and that's something we'll have to look into.
2022-03-13 18:09:43 +01:00
Andreas Kling
f88d65d9cb LibWeb: Cache CSS::Selector's pseudo element at construction time
Computing the pseudo element of a CSS::Selector was very hot when
mousing around on GitHub in Browser. A profile had it at ~10%.
After these changes, it's totally gone from the profile. :^)
2022-03-13 18:09:43 +01:00
Andreas Kling
f5c2e87965 LibWeb: Sort stacking context tree once, after fully building it
Instead of calling quick_sort() every time a StackingContext child
is added to a parent, we now do a single pass of sorting work after the
full StackingContext tree has been built.

Before this change, the quick_sort() was ~13.5% of the profile while
hovering links on GitHub in the Browser. After the change, it's down to
~0.6%. Pretty good! :^)
2022-03-13 18:09:43 +01:00
Andreas Kling
13c253d2ee LibWeb: Fix serialization of selectors with universal subject (*)
For seletors whose subject is unversal (i.e selectors that end in "*")
we were not serializing the asterisk. Instead "foo bar *" came out as
"foo bar foo". This patch fixes that by correctly serializing the last
simple selector if it's universal.
2022-03-13 15:41:54 +01:00
Andreas Kling
ab9d9709b9 LibWeb: Give flex containers with percentage cross size some dimensions
Instead of making them zero-sized on the cross axis, just treat
percentage sizes like auto for now. Better to have *some* size than none
at all.
2022-03-13 00:04:51 +01:00
Andreas Kling
bd94f2c4c8 LibWeb: Add a debug helper to dump current state of an FFC 2022-03-13 00:04:51 +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
1223c88e68 LibWeb: Mark input elements for style update in set_checked()
When the checkedness changes, :checked selectors may yield different
results, so we have to update style.
2022-03-13 00:04:51 +01:00
Andreas Kling
630f2e0ee9 LibWeb: Make StyleProperties::operator==(StyleProperties) actually work
It was comparing against itself, oopsie!
2022-03-13 00:04:51 +01:00
Andreas Kling
ad8d65fd6e LibWeb: Fix calculation of hypothetical cross size in column flex layout
Simplify automatic cross sizing of items in flex-direction:column by
using the fit-content width directly.

There's obviously a lot more nuance to this, but for now this makes
flex items with both width:auto and height:auto actually get some height
in column flex layouts.
2022-03-13 00:04:51 +01:00
Andreas Kling
2f3d7a7c36 LibWeb: Swap min-content and max-content intrinsic sizes if needed
I'm a little confused about intrinsic heights *really* work, and I'm
struggling to extract that information from the spec. In the meantime,
let's ensure that min-content is always smaller than (or equal to)
max-content so that other math works as expected.
2022-03-13 00:04:51 +01:00
Andreas Kling
4a14c4dae8 LibWeb: Support the CSS 'unset' value
This works as 'inherit' for inherited properties and 'initial' for
everything else.
2022-03-13 00:04:51 +01:00
Andreas Kling
515db5fc1b LibWeb: Make Layout::FormattingState copies shallow
Previously, each NodeState in a FormattingState was shared with the
parent FormattingState, but the HashMap of NodeState had to be copied
when making FormattingState copies.

This patch makes copying instant by keeping a pointer to the parent
FormattingState instead. When fetching immutable state via get(), we may
now return a reference to a NodeState owned by a parent FormattingState.

get_mutable() will copy any NodeState found in the ancestor chain before
making a brand new one.
2022-03-13 00:04:51 +01:00
Andreas Kling
b6097cf724 LibWeb: Add fast_is<SVG::SVGSVGElement>() 2022-03-13 00:04:51 +01:00
Andreas Kling
8c91e8016c LibWeb: Handle many more cases with intrinsic/auto sizing in flex layout
The flexbox specification barely even handwaves about automatically
sized items, but there's actually a lot of work to do in order for them
to get the correct size.

This patch is messy, but does make significant progress on supporting
flex items with indefinite width and/or height.

There's a fair amount of nested layout going on here, but do note that
we'll be hitting the intrinsic sizes cache whenever possible.
2022-03-13 00:04:51 +01:00
Andreas Kling
3f2b17f602 LibWeb: Add functions for calculating intrinsic sizes of a Layout::Box
FormattingContext can now calculate the intrinsic sizes (min-content and
max-content in both axes) for a given Layout::Box.

This is a rather expensive operation, as it necessitates performing two
throwaway layouts of the subtree rooted at the box. Fortunately, we can
cache the results of these calculations, as intrinsic sizes don't change
based on other context around the box. They are intrinsic after all. :^)
2022-03-13 00:04:51 +01:00
Andreas Kling
aa969cc591 LibWeb: Make Layout::SVGBox a BlockContainer again
This wasn't worth the headache of trying to make SVG boxes work together
with BFC right now. Let's just make it a block container once again, and
have its corresponding SVGPaintable inherit from PaintableWithLines.

We'll have to revisit this as SVG support improves.
2022-03-13 00:04:51 +01:00