mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +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());
|
||||
}
|
||||
|
||||
let padding_rect = padding_rect.to_physical(style.writing_mode, containing_block);
|
||||
let border = style.get_border();
|
||||
Some(Rect::new(
|
||||
Point2D::new(
|
||||
border.border_left_width.to_px(),
|
||||
border.border_top_width.to_px(),
|
||||
),
|
||||
Size2D::new(
|
||||
padding_rect.size.width.px() as i32,
|
||||
padding_rect.size.height.px() as i32,
|
||||
),
|
||||
))
|
||||
let padding_rect = padding_rect.to_physical(style.writing_mode, containing_block);
|
||||
Some(
|
||||
Rect::new(
|
||||
Point2D::new(
|
||||
border.border_left_width.to_f32_px(),
|
||||
border.border_top_width.to_f32_px(),
|
||||
),
|
||||
Size2D::new(padding_rect.size.width.px(), padding_rect.size.height.px()),
|
||||
)
|
||||
.round()
|
||||
.to_i32()
|
||||
.to_untyped(),
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(Rect::zero)
|
||||
}
|
||||
|
|
|
@ -211,9 +211,12 @@ pub fn process_node_scroll_area_request(
|
|||
};
|
||||
|
||||
Rect::new(
|
||||
Point2D::new(rect.origin.x.px() as i32, rect.origin.y.px() as i32),
|
||||
Size2D::new(rect.size.width.px() as i32, rect.size.height.px() as i32),
|
||||
Point2D::new(rect.origin.x.px(), rect.origin.y.px()),
|
||||
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.
|
||||
|
|
|
@ -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": [
|
||||
"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