CSSPixelFraction::to_float() and to_double() were converting to
CSSPixels (6-bit fixed-point) before converting to float/double,
which truncated the result to 1/64 precision. For example, 500/2500
(= 0.2) became 12/64 (= 0.1875).
Fix by dividing the numerator and denominator as floats/doubles
directly, which is what every other browser engine does when
converting layout units to floating-point ratios.
This was an oversight in the original CSSPixelFraction implementation
(commit 8cd1f65507). The class was designed for lossless comparison
and multiply-then-divide operations (which stay in CSSPixels land),
and the to_float/to_double methods were convenience additions that
took the easy path through CSSPixels conversion without considering
the precision loss.
Per the spec, the observer's [[scrollMargin]] should be applied to
each scroll container's scrollport when walking the containing block
chain. This expands the effective clip rect, allowing targets to be
detected as intersecting before they actually enter the visible area
of the scroll container.
Add a scroll_margin_values() accessor to IntersectionObserver so the
raw LengthPercentage values can be used during intersection computation.
The scroll margin is applied by inflating the scroll container's
padding box rect before clipping the intersection rect against it.
Add a test that creates two observers watching the same target inside
an overflow:hidden container: one without scroll margin and one with
scrollMargin "50px". The target is partially visible (10px out of 50px).
Without scroll margin, the ratio is ~0.19 (10px visible / 50px target).
With scroll margin, the expanded scrollport should make the full target
visible (ratio=1), but currently both report the same ratio because
scroll margin is not yet applied in compute_intersection.