blob: 9f1800341e95f6f49a574cecd8e4975992e37bfd [file] [edit]
<!DOCTYPE html>
<title>CSSOM View - getBoxQuads() options</title>
<link rel="help" href="https://drafts.csswg.org/cssom-view/#the-geometryutils-interface">
<link rel="help" href="https://hacks.mozilla.org/2014/03/introducing-the-getboxquads-api/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/geometry-utils.js"></script>
<style>
html, body {
margin: 0;
}
#target {
position: absolute;
left: 40px;
top: 30px;
width: 200px;
height: 160px;
margin: 11px 13px 17px 19px;
border: solid;
border-width: 2px 4px 6px 8px;
padding: 3px 5px 7px 9px;
box-sizing: content-box;
background: lightblue;
}
#relative {
position: absolute;
left: 20px;
top: 15px;
width: 300px;
height: 220px;
border: 10px solid gray;
padding: 12px;
}
#child {
position: absolute;
left: 50px;
top: 45px;
width: 80px;
height: 40px;
margin: 10px 14px 18px 22px;
border: solid;
border-width: 1px 3px 5px 7px;
padding: 2px 4px 6px 8px;
box-sizing: content-box;
background: gold;
}
#rtl {
position: absolute;
left: 320px;
top: 30px;
width: 60px;
height: 25px;
direction: rtl;
writing-mode: vertical-rl;
border: 4px solid black;
padding: 6px;
}
</style>
<div id="target"></div>
<div id="relative">
<div id="child"></div>
</div>
<div id="rtl"></div>
<script>
const boxes = ["margin", "border", "padding", "content"];
const target = document.getElementById("target");
const relative = document.getElementById("relative");
const child = document.getElementById("child");
const rtl = document.getElementById("rtl");
test(() => {
assert_geometry_utils_exist();
}, "GeometryUtils APIs exist on Element");
for (const box of boxes) {
test(() => {
const quad = target.getBoxQuads({box})[0];
const expected = local_box_rect(target, box);
const borderRect = target.getBoundingClientRect();
assert_point_approx_equals(quad.p1,
new DOMPoint(borderRect.left + expected.x,
borderRect.top + expected.y),
`${box} p1`);
assert_point_approx_equals(quad.p3,
new DOMPoint(borderRect.left + expected.x +
expected.width,
borderRect.top + expected.y +
expected.height),
`${box} p3`);
assert_approx_equals(quad.getBounds().width, expected.width,
GEOMETRY_UTILS_EPSILON, `${box} width`);
assert_approx_equals(quad.getBounds().height, expected.height,
GEOMETRY_UTILS_EPSILON, `${box} height`);
}, `getBoxQuads({box: "${box}"}) returns the requested CSS box`);
}
test(() => {
const defaultQuad = target.getBoxQuads()[0];
const borderQuad = target.getBoxQuads({box: "border"})[0];
assert_quad_approx_equals(defaultQuad, borderQuad,
"default getBoxQuads() border box");
}, "getBoxQuads() defaults to the border box");
test(() => {
const quad = child.getBoxQuads({relativeTo: relative})[0];
const childRect = child.getBoundingClientRect();
const relativeRect = relative.getBoundingClientRect();
assert_point_approx_equals(quad.p1,
new DOMPoint(childRect.left - relativeRect.left,
childRect.top - relativeRect.top),
"child border p1 relative to relative border box");
assert_point_approx_equals(quad.p3,
new DOMPoint(childRect.right - relativeRect.left,
childRect.bottom - relativeRect.top),
"child border p3 relative to relative border box");
}, "getBoxQuads({relativeTo}) uses the relative element border-box origin");
test(() => {
const quad = child.getBoxQuads({box: "content", relativeTo: relative})[0];
const childRect = child.getBoundingClientRect();
const relativeRect = relative.getBoundingClientRect();
const contentRect = local_box_rect(child, "content");
assert_point_approx_equals(quad.p1,
new DOMPoint(childRect.left - relativeRect.left +
contentRect.x,
childRect.top - relativeRect.top +
contentRect.y),
"child content p1 relative to relative");
assert_point_approx_equals(quad.p3,
new DOMPoint(childRect.left - relativeRect.left +
contentRect.x + contentRect.width,
childRect.top - relativeRect.top +
contentRect.y + contentRect.height),
"child content p3 relative to relative");
}, "getBoxQuads() combines box and relativeTo options");
test(() => {
const quad = rtl.getBoxQuads()[0];
assert_true(quad.p1.x < quad.p2.x, "p1 remains the physical left corner");
assert_true(quad.p1.y < quad.p4.y, "p1 remains the physical top corner");
}, "getBoxQuads() point order is physical for bidi and writing-mode");
test(() => {
const quad = document.getBoxQuads()[0];
assert_point_approx_equals(quad.p1, new DOMPoint(0, 0),
"document quad origin");
assert_approx_equals(quad.getBounds().width, document.documentElement.clientWidth,
GEOMETRY_UTILS_EPSILON, "document quad width");
assert_approx_equals(quad.getBounds().height, document.documentElement.clientHeight,
GEOMETRY_UTILS_EPSILON, "document quad height");
}, "Document.getBoxQuads() returns the viewport quad");
</script>