Bug 1889244 - Truncate rather than round inner sizes. r=dholbert

This should allow us to work on bug 1647356 and co again, and prevents
undesired scrollbars like those from bug 1648265. It should also be more
compatible (seems like my comment in
https://github.com/w3c/csswg-drafts/issues/5260 still holds).

Differential Revision: https://phabricator.services.mozilla.com/D206434
This commit is contained in:
Emilio Cobos Álvarez 2024-04-03 10:42:54 +00:00
parent 284b666425
commit 5b3d95fe9f
5 changed files with 52 additions and 39 deletions

View file

@ -3473,9 +3473,17 @@ nsresult nsGlobalWindowOuter::GetInnerSize(CSSSize& aSize) {
aSize = CSSPixel::FromAppUnits(viewportSize);
if (StaticPrefs::dom_innerSize_rounded()) {
aSize.width = std::roundf(aSize.width);
aSize.height = std::roundf(aSize.height);
switch (StaticPrefs::dom_innerSize_rounding()) {
case 1:
aSize.width = std::roundf(aSize.width);
aSize.height = std::roundf(aSize.height);
break;
case 2:
aSize.width = std::truncf(aSize.width);
aSize.height = std::truncf(aSize.height);
break;
default:
break;
}
return NS_OK;

View file

@ -13,7 +13,7 @@ function test_once() {
`${rect.width}x${rect.height}, ${content.innerWidth}x${content.innerHeight}`
);
is(
Math.round(rect.height),
Math.trunc(rect.height),
content.innerHeight,
"Should fill the viewport and not overflow"
);

View file

@ -2779,7 +2779,11 @@
value: false
mirror: always
# Whether innerWidth / innerHeight return rounded or fractional sizes.
# How innerWidth / innerHeight return rounded or fractional sizes.
#
# 0 or others: Do not round at all.
# 1: Round.
# 2: Truncate.
#
# NOTE(emilio): Fractional sizes are not web-compatible, see the regressions
# from bug 1676843, but we want to expose the fractional sizes (probably in
@ -2787,9 +2791,9 @@
# time being.
#
# [1]: https://github.com/w3c/csswg-drafts/issues/5260
- name: dom.innerSize.rounded
type: bool
value: true
- name: dom.innerSize.rounding
type: uint32_t
value: 2
mirror: always
# Whether we conform to Input Events Level 1 or Input Events Level 2.

View file

@ -1,5 +0,0 @@
[window_size_rounding.html]
bug: Different viewport size
[window_size_rounding]
expected:
if os == "android": FAIL

View file

@ -1,35 +1,41 @@
<!doctype html>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<pre>
<iframe style="border: 0; padding: 0; width: 100.75px; height: 100.75px" srcdoc="<html style='width: 100vw; height: 100vh'>"></iframe>
<script>
test(function() {
let originalWidth = window.innerWidth;
let originalHeight = window.innerHeight;
onload = function() {
test(() => {
assert_equals(window.devicePixelRatio, 1, `precondition: ${window.innerWidth}x${window.innerHeight}`);
assert_equals(window.devicePixelRatio, 1, `precondition: ${originalWidth}x${originalHeight}`);
// So that the 100.75 is fractional css pixel, but whole dev pixels, and representable in app units.
SpecialPowers.setFullZoom(window, 4);
// This precondition holds because of:
// https://searchfox.org/mozilla-central/rev/50215d649d4854812837f1343e8f47bd998dacb5/browser/base/content/browser.js#1717
//
// But if this test starts failing you can just update the assert and the
// factor below accordingly so that the asserts keep passing.
assert_equals(originalWidth, 1280, "precondition");
let win = document.querySelector("iframe").contentWindow;
const rounded = 101;
const truncated = 100;
const raw = 100.75;
// Set a fractional scale factor that guarantees that we get a fractional innerWidth
const kFactor = 1.5;
const kOneAppUnit = 1 / 60;
const rect = win.document.documentElement.getBoundingClientRect();
assert_equals(rect.height, raw);
assert_equals(rect.width, raw);
SpecialPowers.setFullZoom(window, kFactor);
assert_approx_equals(window.devicePixelRatio, kFactor, kOneAppUnit);
assert_not_equals(window.innerWidth, originalWidth);
assert_not_equals(window.innerHeight, originalHeight);
if (SpecialPowers.getBoolPref("dom.innerSize.rounded")) {
assert_equals(window.innerWidth, Math.round(originalWidth / kFactor));
assert_equals(window.innerHeight, Math.round(originalHeight / kFactor));
} else {
assert_not_equals(window.innerWidth, Math.round(window.innerWidth));
}
SpecialPowers.setFullZoom(window, 1); // Restore zoom so results can be seen fine...
});
switch (SpecialPowers.getIntPref("dom.innerSize.rounding")) {
case 1:
assert_equals(win.innerWidth, rounded);
assert_equals(win.innerHeight, rounded);
break;
case 2:
assert_equals(win.innerWidth, truncated);
assert_equals(win.innerHeight, truncated);
break;
default:
assert_equals(win.innerWidth, raw);
assert_equals(win.innerHeight, raw);
break;
}
SpecialPowers.setFullZoom(window, 1);
})
};
</script>