Automatic update from web-platform-tests Fix LayoutShift attribution data to use CSS pixels The LayoutShift API was returning attribution data (currentRect and prevRect) in physical pixels instead of CSS pixels. This makes the Layout Instability API inconsistent with other layout-related APIs, which all use CSS pixels. With the current behavior, consumers of this API are required to manually convert the attribution data using devicePixelRatio to make the coordinates relative to the viewport. Previously, on a display with device pixel ratio 2.0, a 100x100 CSS pixel element positioned at (50, 50) would be reported as 200x200 at (100, 100) in the attribution data. After this fix, it correctly reports as 100x100 at (50, 50) CSS pixels, matching the actual element position and size as seen by web developers. The layout shift scores themselves remain unaffected as they are calculated using the impact fraction (shifted area relative to viewport) multiplied by the distance fraction (movement distance relative to viewport dimensions). Only the attribution data reporting to the Performance API is corrected. Bug: 399058544 Change-Id: Ib8109c12eaf1c1a2e5648edbc39ef97111431494 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6624567 Reviewed-by: Manuel Rego <rego@igalia.com> Reviewed-by: Michal Mocny <mmocny@chromium.org> Commit-Queue: Manuel Rego <rego@igalia.com> Cr-Commit-Position: refs/heads/main@{#1527545} -- wpt-commits: 30a480fedde7c4a4b51fb7697b39d7296d3ac292 wpt-pr: 55329
70 lines
2.3 KiB
HTML
70 lines
2.3 KiB
HTML
<!DOCTYPE html>
|
|
<title>Layout Instability: attribution rectangles pixel units</title>
|
|
<link rel="help" href="https://wicg.github.io/layout-instability/" />
|
|
<style>
|
|
|
|
body { margin: 10px; }
|
|
#shifter { position: relative; width: 100px; height: 100px; background: blue; }
|
|
|
|
</style>
|
|
<div id="shifter"></div>
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="resources/util.js"></script>
|
|
<script>
|
|
|
|
strrect = r => `[${r.x},${r.y},${r.width},${r.height}]`;
|
|
|
|
promise_test(async () => {
|
|
const watcher = new ScoreWatcher;
|
|
const shifter = document.querySelector("#shifter");
|
|
|
|
// Wait for the initial render to complete.
|
|
await waitForAnimationFrames(2);
|
|
|
|
// Modify the position and size of the div.
|
|
shifter.style = "top: 60px; left: 10px; width: 200px; height: 200px";
|
|
await watcher.promise;
|
|
|
|
const sources = watcher.lastEntry.sources;
|
|
assert_equals(sources.length, 1);
|
|
|
|
const source = sources[0];
|
|
assert_equals(source.node, shifter);
|
|
|
|
// Test that attribution rectangles are in CSS pixels
|
|
assert_equals(strrect(source.previousRect), "[10,10,100,100]",
|
|
"previousRect should be in CSS pixels");
|
|
assert_equals(strrect(source.currentRect), "[20,70,200,200]",
|
|
"currentRect should be in CSS pixels");
|
|
}, "Attribution rectangles should be in CSS pixels.");
|
|
|
|
// Test fractional pixel values
|
|
promise_test(async () => {
|
|
const watcher = new ScoreWatcher;
|
|
const shifter = document.querySelector("#shifter");
|
|
|
|
// Wait for the initial render to complete.
|
|
await waitForAnimationFrames(2);
|
|
|
|
// Test with fractional CSS pixel values
|
|
shifter.style.cssText = 'position: relative; width: 100.5px; height: 75.25px; background: blue;';
|
|
await waitForAnimationFrames(2);
|
|
|
|
shifter.style.top = '10.5px';
|
|
shifter.style.left = '15.75px';
|
|
await watcher.promise;
|
|
|
|
const sources = watcher.lastEntry.sources;
|
|
assert_equals(sources.length, 1);
|
|
|
|
const source = sources[0];
|
|
assert_equals(source.node, shifter);
|
|
|
|
// Test that fractional CSS pixel values are preserved
|
|
assert_equals(source.previousRect.width, 100.5, "previousRect.width should preserve fractional CSS pixels");
|
|
assert_equals(source.previousRect.height, 75.25, "previousRect.height should preserve fractional CSS pixels");
|
|
}, "Fractional pixel values should be handled correctly.");
|
|
|
|
</script>
|