mirror of
https://github.com/servo/servo.git
synced 2025-07-24 15:50:21 +01:00
layout: Round clientTop
, etc queries to pixels properly (#31187)
* layout: Round getClientRect queries to pixels properly Instead of just flooring all pixels in getClientRect queries, we should round the rectangle. * Fix scrollWidth/scrollHeight too, and tests * Tests passing * Test expectation for legacy layout --------- Co-authored-by: Oriol Brufau <obrufau@igalia.com>
This commit is contained in:
parent
bbba839278
commit
bbe505e52b
9 changed files with 194 additions and 25 deletions
|
@ -156,18 +156,20 @@ impl FragmentTree {
|
||||||
return Some(Rect::zero());
|
return Some(Rect::zero());
|
||||||
}
|
}
|
||||||
|
|
||||||
let padding_rect = padding_rect.to_physical(style.writing_mode, containing_block);
|
|
||||||
let border = style.get_border();
|
let border = style.get_border();
|
||||||
Some(Rect::new(
|
let padding_rect = padding_rect.to_physical(style.writing_mode, containing_block);
|
||||||
Point2D::new(
|
Some(
|
||||||
border.border_left_width.to_px(),
|
Rect::new(
|
||||||
border.border_top_width.to_px(),
|
Point2D::new(
|
||||||
),
|
border.border_left_width.to_f32_px(),
|
||||||
Size2D::new(
|
border.border_top_width.to_f32_px(),
|
||||||
padding_rect.size.width.px() as i32,
|
),
|
||||||
padding_rect.size.height.px() as i32,
|
Size2D::new(padding_rect.size.width.px(), padding_rect.size.height.px()),
|
||||||
),
|
)
|
||||||
))
|
.round()
|
||||||
|
.to_i32()
|
||||||
|
.to_untyped(),
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.unwrap_or_else(Rect::zero)
|
.unwrap_or_else(Rect::zero)
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,9 +211,12 @@ pub fn process_node_scroll_area_request(
|
||||||
};
|
};
|
||||||
|
|
||||||
Rect::new(
|
Rect::new(
|
||||||
Point2D::new(rect.origin.x.px() as i32, rect.origin.y.px() as i32),
|
Point2D::new(rect.origin.x.px(), rect.origin.y.px()),
|
||||||
Size2D::new(rect.size.width.px() as i32, rect.size.height.px() as i32),
|
Size2D::new(rect.size.width.px(), rect.size.height.px()),
|
||||||
)
|
)
|
||||||
|
.round()
|
||||||
|
.to_i32()
|
||||||
|
.to_untyped()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the resolved value of property for a given (pseudo)element.
|
/// Return the resolved value of property for a given (pseudo)element.
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
[subpixel-sizes-and-offsets.tentative.html]
|
||||||
|
[clientWidth, offsetWidth and scrollWidth round 5.5 to 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientWidth, offsetWidth and scrollWidth round 5.9 to 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientHeight, offsetHeight and scrollHeight round 5.1 to 5]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientHeight, offsetHeight and scrollHeight round 5.5 to 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientHeight, offsetHeight and scrollHeight round 5.9 to 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientLeft and clientTop don't round 44.9]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientLeft and clientTop don't round 44.5]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientLeft and clientTop don't round 44.1]
|
||||||
|
expected: FAIL
|
|
@ -562330,6 +562330,13 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"subpixel-sizes-and-offsets.tentative.html": [
|
||||||
|
"d198b9dde60c8cac16241c412d3e55f772166010",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"table-border-collapse-client-width-height.html": [
|
"table-border-collapse-client-width-height.html": [
|
||||||
"a7a1a435b2279ccb07136ed295dcc25b38c2c87c",
|
"a7a1a435b2279ccb07136ed295dcc25b38c2c87c",
|
||||||
[
|
[
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
[fractional-percent-width.html]
|
|
||||||
[.cell 2]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[.cell 3]
|
|
||||||
expected: FAIL
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
[subpixel-sizes-and-offsets.tentative.html]
|
||||||
|
[clientWidth, offsetWidth and scrollWidth round 5.5 to 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientWidth, offsetWidth and scrollWidth round 5.9 to 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientHeight, offsetHeight and scrollHeight round 5.1 to 5]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientHeight, offsetHeight and scrollHeight round 5.5 to 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientHeight, offsetHeight and scrollHeight round 5.9 to 6]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientLeft and clientTop don't round 44.9]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientLeft and clientTop don't round 44.5]
|
||||||
|
expected: FAIL
|
||||||
|
|
||||||
|
[clientLeft and clientTop don't round 44.1]
|
||||||
|
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
||||||
[table-border-collapse-client-width-height.html]
|
|
||||||
[Table's clientWidth/Height and OffsetWidth/Height should be the same]
|
|
||||||
expected: FAIL
|
|
|
@ -1,3 +0,0 @@
|
||||||
[table-border-separate-client-width-height.html]
|
|
||||||
[Table's clientWidth/Height and OffsetWidth/Height should be the same]
|
|
||||||
expected: FAIL
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<title>CSSOM View Module test: subpixel sizes and offsets</title>
|
||||||
|
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/cssom-view/#extension-to-the-element-interface">
|
||||||
|
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/9866">
|
||||||
|
<link rel="help" href="https://lists.w3.org/Archives/Public/www-style/2015Feb/0195.html">
|
||||||
|
|
||||||
|
<div style="overflow: hidden; position: relative">
|
||||||
|
<div id="target">
|
||||||
|
<div id="child"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="log"></div>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
// clientWidth, offsetWidth and scrollWidth round to the nearest integer.
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "width: 5.1px";
|
||||||
|
assert_equals(target.clientWidth, 5, "clientWidth");
|
||||||
|
assert_equals(target.offsetWidth, 5, "offsetWidth");
|
||||||
|
assert_equals(target.scrollWidth, 5, "scrollWidth");
|
||||||
|
}, "clientWidth, offsetWidth and scrollWidth round 5.1 to 5");
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "width: 5.5px";
|
||||||
|
assert_equals(target.clientWidth, 6, "clientWidth");
|
||||||
|
assert_equals(target.offsetWidth, 6, "offsetWidth");
|
||||||
|
assert_equals(target.scrollWidth, 6, "scrollWidth");
|
||||||
|
}, "clientWidth, offsetWidth and scrollWidth round 5.5 to 6");
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "width: 5.9px";
|
||||||
|
assert_equals(target.clientWidth, 6, "clientWidth");
|
||||||
|
assert_equals(target.offsetWidth, 6, "offsetWidth");
|
||||||
|
assert_equals(target.scrollWidth, 6, "scrollWidth");
|
||||||
|
}, "clientWidth, offsetWidth and scrollWidth round 5.9 to 6");
|
||||||
|
|
||||||
|
// clientHeight, offsetHeight and scrollHeight round to the nearest integer.
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "height: 5.1px";
|
||||||
|
assert_equals(target.clientHeight, 5, "clientHeight");
|
||||||
|
assert_equals(target.offsetHeight, 5, "offsetHeight");
|
||||||
|
assert_equals(target.scrollHeight, 5, "scrollHeight");
|
||||||
|
}, "clientHeight, offsetHeight and scrollHeight round 5.1 to 5");
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "height: 5.5px";
|
||||||
|
assert_equals(target.clientHeight, 6, "clientHeight");
|
||||||
|
assert_equals(target.offsetHeight, 6, "offsetHeight");
|
||||||
|
assert_equals(target.scrollHeight, 6, "scrollHeight");
|
||||||
|
}, "clientHeight, offsetHeight and scrollHeight round 5.5 to 6");
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "height: 5.9px";
|
||||||
|
assert_equals(target.clientHeight, 6, "clientHeight");
|
||||||
|
assert_equals(target.offsetHeight, 6, "offsetHeight");
|
||||||
|
assert_equals(target.scrollHeight, 6, "scrollHeight");
|
||||||
|
}, "clientHeight, offsetHeight and scrollHeight round 5.9 to 6");
|
||||||
|
|
||||||
|
// offsetLeft and offsetTop round to the nearest integer.
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "margin: 5.1px";
|
||||||
|
assert_equals(target.offsetLeft, 5, "offsetLeft");
|
||||||
|
assert_equals(target.offsetTop, 5, "offsetTop");
|
||||||
|
}, "offsetLeft and offsetTop round 5.1 to 5");
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "margin: 5.5px";
|
||||||
|
assert_equals(target.offsetLeft, 6, "offsetLeft");
|
||||||
|
assert_equals(target.offsetTop, 6, "offsetTop");
|
||||||
|
}, "offsetLeft and offsetTop round 5.5 to 6");
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "margin: 5.9px";
|
||||||
|
assert_equals(target.offsetLeft, 6, "offsetLeft");
|
||||||
|
assert_equals(target.offsetTop, 6, "offsetTop");
|
||||||
|
}, "offsetLeft and offsetTop round 5.9 to 6");
|
||||||
|
|
||||||
|
// clientLeft and clientTop round the border width to the nearest integer.
|
||||||
|
// Note that the computed value of a border width is snapped to device pixels,
|
||||||
|
// so the results can vary depending on the device pixel ratio.
|
||||||
|
function borderLeftWidth() {
|
||||||
|
return child.getBoundingClientRect().left - target.getBoundingClientRect().left;
|
||||||
|
}
|
||||||
|
function borderTopWidth() {
|
||||||
|
return child.getBoundingClientRect().top - target.getBoundingClientRect().top;
|
||||||
|
}
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "border: 5.1px solid";
|
||||||
|
assert_equals(target.clientLeft, Math.round(borderLeftWidth()), "clientLeft");
|
||||||
|
assert_equals(target.clientLeft, Math.round(borderTopWidth()), "clientTop");
|
||||||
|
}, "clientLeft and clientTop round 5.1");
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "border: 5.5px solid";
|
||||||
|
assert_equals(target.clientLeft, Math.round(borderLeftWidth()), "clientLeft");
|
||||||
|
assert_equals(target.clientLeft, Math.round(borderTopWidth()), "clientTop");
|
||||||
|
}, "clientLeft and clientTop round 5.5");
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "border: 5.9px solid";
|
||||||
|
assert_equals(target.clientLeft, Math.round(borderLeftWidth()), "clientLeft");
|
||||||
|
assert_equals(target.clientLeft, Math.round(borderTopWidth()), "clientTop");
|
||||||
|
}, "clientLeft and clientTop round 5.9");
|
||||||
|
|
||||||
|
// Unlike the attributes above, scrollLeft and scrollTop are `double`s,
|
||||||
|
// so the results shouldn't be rounded.
|
||||||
|
child.style.cssText = "width: 50px; height: 50px";
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "overflow: hidden; width: 5.1px;";
|
||||||
|
target.scrollTo(target.scrollWidth, target.scrollHeight);
|
||||||
|
assert_equals(target.scrollLeft, 44.9, "scrollLeft");
|
||||||
|
assert_equals(target.scrollTop, 44.9, "scrollTop");
|
||||||
|
}, "clientLeft and clientTop don't round 44.9");
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "overflow: hidden; width: 5.5px;";
|
||||||
|
target.scrollTo(target.scrollWidth, target.scrollHeight);
|
||||||
|
assert_equals(target.scrollLeft, 44.5, "scrollLeft");
|
||||||
|
assert_equals(target.scrollTop, 44.5, "scrollTop");
|
||||||
|
}, "clientLeft and clientTop don't round 44.5");
|
||||||
|
test(function() {
|
||||||
|
target.style.cssText = "overflow: hidden; width: 5.9px;";
|
||||||
|
target.scrollTo(target.scrollWidth, target.scrollHeight);
|
||||||
|
assert_equals(target.scrollLeft, 44.1, "scrollLeft");
|
||||||
|
assert_equals(target.scrollTop, 44.1, "scrollTop");
|
||||||
|
}, "clientLeft and clientTop don't round 44.1");
|
||||||
|
</script>
|
Loading…
Add table
Add a link
Reference in a new issue