Previously we only supported a subset of the predefined counter styles,
we now respect counter styles defined by `@counter-style` rules when
resolving the value of `counter()` and `counters()` functions
The height and depth attributes are parsed individually and then
combined into a `calc()` expression. Bare zero is valid as a standalone
CSS length but inside `calc()` it is typed as a number, so
`calc(0 + 0)` fails to parse as a length. We now check the parsed value
is valid to avoid a crash.
Previously, a table with `width: 100%` and `margin: auto` whose content
was narrower than the viewport would be centered based on content
width rather than filling the containing block. Resizing the viewport
wider than the content would shift the table progressively further to
the right.
Co-authored-by: Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
By doing so, we attenuate the perspective transform on higher resolution
devices such as Retina displays (2x).
This fixes the perspective transform on sites such as
https://poke-holo.simey.me/.
Instead of rendering text glyphs into a separate mask surface and using
clipShader, paint the backgrounds first and then composite the text
glyphs via saveLayer with SkBlendMode::kDstIn. Skia's saveLayer
automatically sizes its backing at device resolution including CSS
transforms, so no manual scale computation is needed.
Fixes pixelation when zooming in on clipped backgrounds on e.g. the
title of https://modern-css.com/.
We should decide at a later stage, when we've calculated the final
background painting area, whether that area is empty and we can skip
painting the background.
Fixes#7973
They're also no longer drawin in one stroke since that would
confuse the stroke-drawing code otherwise, since the order of it all
means that we'd be drawing a stroke that jumps back and forth a lot
and had gaps between every line segment.
Previously, text selection always used the system highlight color. This
implements support for the ::selection pseudo-element's background-color
and color properties.
For form controls like <input> and <textarea>, the selection style is
looked up on the shadow host element, since the actual text lives inside
their shadow DOM.
The text painting logic has been refactored to split fragments into
styled spans (before selection, selected, after selection) so that each
portion can be rendered with its appropriate colors, taking care not to
allocate in 99%+ of fragment rendering cases.
SVGPolylineElement::get_path() produces a path based on the points
attribute. During layout, this path is copied into paintables. If the
points attribute changes after layout, the path stored in the paintable
becomes stale. Fix by calling set_needs_layout_update() when it changes
so the path is recomputed.
SVGPolygonElement::get_path() produces a path based on the points
attribute. During layout, this path is copied into paintables. If the
points attribute changes after layout, the path stored in the paintable
becomes stale. Fix by calling set_needs_layout_update() when it changes
so the path is recomputed.
SVGPathElement::get_path() produces a path based on the d attribute.
During layout, this path is copied into paintables. If the d attribute
changes after layout, the path stored in the paintable becomes stale.
Fix by calling set_needs_layout_update() when it changes so the path
is recomputed.
SVGLineElement::get_path() produces a path based on x1, y1, x2, and
y2 attributes. During layout, this path is copied into paintables.
If any of these attributes change after layout, the path stored in the
paintable becomes stale. Fix by calling set_needs_layout_update() when
a geometry attribute changes so the path is recomputed.
Previously, absolutely positioned elements jumped directly to their
containing block's accumulated visual context, skipping effects
(opacity, mix-blend-mode, isolation) from intermediate ancestors. Per
CSS spec, these properties create stacking contexts that abspos elements
cannot escape — they only escape scroll containers and overflow clips.
Instead, compute them on demand. This affects ReplacedBox and its
subclasses.
This commit is centered around a new Box::auto_content_box_size
method. It returns a SizeWithAspectRatio representing the natural
size of a replaced element, or the size derived from attributes
for text input and textarea. These values are used when the
corresponding axis is auto or indefinite.
Although introducing this API choke-point for sizing replaced and
replaced-like elements was the main goal, it's notable that layout
becomes more robust in the face of dynamic changes due to reduced
potential for stale size values (at the cost of extra calculations
and allocations).
SVG images loaded as <img> elements must not execute scripts per spec.
Previously, SVGScriptElement::process_the_script_element() did not
check whether scripting was disabled, so script processing was
triggered via the children_changed() callback during XML parsing,
causing a nested event loop spin.
Fix this by:
- Disabling scripting on the SVG image's Page
- Passing XMLScriptingSupport::Disabled to the XML document builder
- Checking is_scripting_disabled() in SVGScriptElement before
processing any script element
- Logging a diagnostic when SVG XML parsing fails (previously the
parse result was silently discarded)
Previously, `greatest_child_width()` was used, which finds the maximum
margin box width among direct children. This is incorrect for tables,
whose width is determined by column distribution rather than by simply
finding the widest child. We now return the table's computed content
width instead, which already holds the correct value after layout.
When a sticky element was inside a position:fixed ancestor,
nearest_scroll_frame() would stop at the fixed boundary and return
nullptr. This caused precompute_sticky_constraints() to bail out,
leaving the sticky element at its normal flow position with no offset.
When painting inspector overlays for a highlighted node, we want to
ignore any clipping that may be going on due to explicit CSS properties,
stacking contexts or similar. That makes sure our overlay is not
obscured by the clipping.
This fixes a regression from 009ddd4823.
When highlighting something that does not correspond to a
`PaintableBox`, we still need to apply `AccumulatedVisualContext`s. In
that case, search for the closest `PaintableBox` ancestor and apply its
`AccumulatedVisualContext`
This bug is most easily observed by highlighting a text node on a page
that has a scrollbar and is scrolled down at least a bit.
This fixes a regression from 009ddd4823.
Previously, sticky elements were excluded from propagating their
scroll frame to descendants' accumulated visual context. This meant
that when a sticky element also had scrollable overflow, the scroll
offset was never visually applied to its children during painting.
In Element::set_scroll_offset(), when setting a pseudo-element's
scroll offset, the code was also incorrectly setting the generating
element's own m_scroll_offset. Added an else branch so only the
pseudo-element's offset is set.
Also adds a ref test for scrollable pseudo-elements to prevent
regression. The test scrolls a ::before pseudo-element via wheel
event and verifies the content scrolls correctly.
Previously, outlines for elements without their own stacking context
were painted during the `FocusAndOverlay` phase, which runs after all
child stacking contexts. This caused outlines to incorrectly appear
on top of elements with higher z-index.
Add a test case that was reduced from a regression discovered and fixed
during the AccumulatedVisualContext refactoring. The test verifies that
SVG elements with both CSS transforms (rotate) and opacity render
correctly together.
For XHTML documents, resolve named character entities (e.g., )
using the HTML entity table via a getEntity SAX callback. This avoids
parsing a large embedded DTD on every document and matches the approach
used by Blink and WebKit.
This also removes the now-unused DTD infrastructure:
- Remove resolve_external_resource callback from Parser::Options
- Remove resolve_xml_resource() function and its ~60KB embedded DTD
- Remove all call sites passing the unused callback