mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 00:55:37 +00:00
399 lines
15 KiB
HTML
399 lines
15 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<style>
|
|
.testcase {
|
|
height:200px;
|
|
width:200px;
|
|
position:absolute;
|
|
overflow:hidden;
|
|
left:0;
|
|
top:0;
|
|
}
|
|
iframe {
|
|
border:none;
|
|
}
|
|
</style>
|
|
<script src="region_lib.js"></script>
|
|
</head>
|
|
<body style="margin:0">
|
|
<!-- We use gradients here to fill elements with an unpredictable image. Since
|
|
our scrolling optimizations take account of areas of an element which
|
|
are blank or filled with a solid color, it's fragile to use those in
|
|
tests which expect to observe scrolling happening. -->
|
|
|
|
<!-- Each of the "testcase" elements is one test. We scroll that element's
|
|
scrollTop (or scrollLeft, if the element's class is 'horizontal')
|
|
from 0 to 20 and then call the function given by the element's id,
|
|
passing the blit region and the paint region as a parameters. -->
|
|
|
|
<div id="testSimpleScroll" class="testcase">
|
|
<div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
|
|
</div>
|
|
|
|
<div id="testFixedBackground" class="testcase">
|
|
<div style="height:300px; margin-bottom:-300px; background:-moz-linear-gradient(left, red, black) fixed;"></div>
|
|
<div style="height:300px; background:-moz-linear-gradient(top, rgba(0,0,0,0.7), rgba(255,0,0,0.7));"></div>
|
|
</div>
|
|
|
|
<div id="testFixedPosOverlay" class="testcase">
|
|
<div style="position:fixed; left:0; top:50px; width:100px; height:45px; background:yellow;"></div>
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
<p>Hello
|
|
</div>
|
|
|
|
<div style="border:1px solid black;" id="testBorder" class="testcase">
|
|
<div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
|
|
</div>
|
|
|
|
<div id="testScrollOutOfView" class="testcase">
|
|
<div style="height:10px; margin-bottom:210px; background:-moz-linear-gradient(top, rgba(0,0,0,0.7), rgba(255,0,0,0.7));"></div>
|
|
</div>
|
|
|
|
<div id="testScrollIntoView" class="testcase">
|
|
<div style="height:10px; margin-top:210px; background:-moz-linear-gradient(top, rgba(0,0,0,0.7), rgba(255,0,0,0.7));"></div>
|
|
</div>
|
|
|
|
<div id="testSimpleScrollWithSubpixelOffset1" style="top:0.2px" class="testcase">
|
|
<div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
|
|
</div>
|
|
|
|
<div id="testSimpleScrollWithSubpixelOffset2" style="top:0.8px" class="testcase">
|
|
<div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
|
|
</div>
|
|
|
|
<div id="testSimpleScrollWithSubpixelOffset3" style="left:0.2px" class="horizontal testcase">
|
|
<div style="width:300px; height:200px; background:-moz-linear-gradient(left, red, black);"></div>
|
|
</div>
|
|
|
|
<div id="testSimpleScrollWithSubpixelOffset4" style="left:0.8px" class="horizontal testcase">
|
|
<div style="width:300px; height:200px; background:-moz-linear-gradient(left, red, black);"></div>
|
|
</div>
|
|
|
|
<div id="testMovingClipArea" class="testcase">
|
|
<div style="margin-top:20px; height:20px; margin-bottom:300px; background-color:blue; overflow:hidden;"></div>
|
|
</div>
|
|
|
|
<div id="testNonmovingClipArea" class="testcase">
|
|
<div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
|
|
<div style="position:fixed; left:0; top:150px; width:200px; height:50px; background:yellow; overflow:hidden; opacity:0.5;">
|
|
<div style="height:50px; background:-moz-linear-gradient(top, green, yellow); opacity:0.3;"></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="testFixedOverUniform" class="testcase">
|
|
<div style="height:300px; background:blue;"></div>
|
|
<div style="position:fixed; left:0; top:50px; width:100px; height:45px; background:yellow; opacity:0.5;"></div>
|
|
</div>
|
|
|
|
<iframe class="testcase" id="testClipIFRAME"
|
|
src="data:text/html,<body class='testcase' style='margin:0; height:300px; background:-moz-linear-gradient(top, red, black);'>">
|
|
</iframe>
|
|
|
|
<iframe class="testcase" id="testClipIFRAME2" style="top:-50px"
|
|
src="data:text/html,<body class='testcase' style='margin:0; height:300px; background:-moz-linear-gradient(top, red, black);'>">
|
|
</iframe>
|
|
|
|
<div id="testHiddenTable" class="testcase">
|
|
<table style="position:fixed; visibility:hidden; width:200px; height:200px; background:blue;">
|
|
<tr><td>Hidden stuff</td></tr>
|
|
</table>
|
|
<div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
|
|
</div>
|
|
|
|
<div id="testTableNoBackground" class="testcase">
|
|
<table style="position:fixed; width:200px; height:200px;">
|
|
<tr><td></td></tr>
|
|
</table>
|
|
<div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
|
|
</div>
|
|
|
|
<script>
|
|
var testcases = document.querySelectorAll("div.testcase");
|
|
var tests = [];
|
|
var iframes = document.querySelectorAll("iframe.testcase");
|
|
|
|
var currentTest = -1;
|
|
|
|
function ok(a, msg) {
|
|
window.opener.ok(a, tests[currentTest].container.id + ": " + msg);
|
|
};
|
|
function todo(a, msg) {
|
|
window.opener.todo(a, tests[currentTest].container.id + ": " + msg);
|
|
};
|
|
function finish() {
|
|
window.opener.SimpleTest.finish();
|
|
window.close();
|
|
}
|
|
window.onerror = function (event) { window.opener.onerror(event); window.close(); };
|
|
|
|
// Simple sanity check that scrolling a window with moving content in it does
|
|
// the obvious thing: blit the content that was already visible, and repaint
|
|
// the content that has scrolled into view.
|
|
function testSimpleScroll(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[0,0,200,180]])),
|
|
"Should blit everything that was already visible: " + blitRegion.toString());
|
|
ok(paintRegion.equalsRegion(new Region([[0,180,200,200]])),
|
|
"Should repaint area that was scrolled into view: " + paintRegion.toString());
|
|
}
|
|
|
|
// Check that scrolling visible content over background-attachment:fixed
|
|
// content repaints everything
|
|
function testFixedBackground(blitRegion, paintRegion) {
|
|
ok(blitRegion.isEmpty(),
|
|
"Shouldn't blit anything: " + blitRegion.toString());
|
|
ok(paintRegion.equalsRegion(new Region([[0,0,200,200]])),
|
|
"Should repaint everything: " + paintRegion.toString());
|
|
}
|
|
|
|
// Check that we optimize scrolling in a reasonable way in the presence of a
|
|
// non-moving opaque overlay
|
|
function testFixedPosOverlay(blitRegion, paintRegion) {
|
|
// The area of the fixed element should not be repainted or blitted at all
|
|
var fixedElemRect = [0,50,100,95]
|
|
ok(!blitRegion.intersectsRect(fixedElemRect),
|
|
"blit region should not intersect fixed-pos element area: " + blitRegion.toString());
|
|
ok(!paintRegion.intersectsRect(fixedElemRect),
|
|
"paint region should not intersect fixed-pos element area: " + paintRegion.toString());
|
|
|
|
// The area to the right of the fixed element that we can fill with blitting
|
|
// existing content should not be repainted (but may be blitted, although
|
|
// it doesn't all need to be blitted either, since most of it is blank)
|
|
var noPaintRect = [100,0,200,180];
|
|
ok(!paintRegion.intersectsRect(noPaintRect),
|
|
"paint region should not intersect blittable area: " + paintRegion.toString());
|
|
}
|
|
|
|
// Check that scrolling an element with moving content in it does
|
|
// the obvious thing, even if the element has a border.
|
|
function testBorder(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[1,1,201,181]])),
|
|
"Should blit everything that was already visible: " + blitRegion.toString());
|
|
ok(paintRegion.equalsRegion(new Region([[1,181,201,201]])),
|
|
"Should repaint area that was scrolled into view: " + paintRegion.toString());
|
|
}
|
|
|
|
// Check that scrolling some content out of view updates the area that
|
|
// was displaying the content
|
|
function testScrollOutOfView(blitRegion, paintRegion) {
|
|
var all = blitRegion.unionRegion(paintRegion);
|
|
ok(all.containsRect([0,0,200,10]),
|
|
"Should update everything that was previously visible but scrolled out of view: " + all.toString());
|
|
}
|
|
|
|
// Check that scrolling some content into view updates the area that
|
|
// is displaying the content
|
|
function testScrollIntoView(blitRegion, paintRegion) {
|
|
var all = blitRegion.unionRegion(paintRegion);
|
|
ok(all.containsRect([0,190,200,200]),
|
|
"Should update everything that was previously visible: " + all.toString());
|
|
}
|
|
|
|
// When we scroll an area which has a very small subpixel offset, we should
|
|
// still be doing the obvious thing --- we shouldn't end up painting an extra
|
|
// row of pixels anywhere
|
|
function testSimpleScrollWithSubpixelOffset1(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[0,0,200,180]])),
|
|
"Should blit everything that was already visible: " + blitRegion.toString());
|
|
// The next test is contains, not equals, since we repaint down to 200.2
|
|
// which is OK
|
|
ok(paintRegion.containsRegion(new Region([[0,180,200,200]])),
|
|
"Should repaint area that was scrolled into view: " + paintRegion.toString());
|
|
// Check that we're not repainting anything in the area that's blitted
|
|
ok(!paintRegion.intersectsRect([0,0,200,180]),
|
|
"Should not repaint area that was blitted: " + paintRegion.toString());
|
|
}
|
|
|
|
function testSimpleScrollWithSubpixelOffset2(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[0,1,200,181]])),
|
|
"Should blit everything that was already visible: " + blitRegion.toString());
|
|
// The next test is contains, not equals, since we repaint down to 200.8
|
|
// which is OK
|
|
ok(paintRegion.containsRegion(new Region([[0,181,200,200]])),
|
|
"Should repaint area that was scrolled into view: " + paintRegion.toString());
|
|
// Check that we're not repainting anything in the area that's blitted
|
|
ok(!paintRegion.intersectsRect([0,0,200,180]),
|
|
"Should not repaint area that was blitted: " + paintRegion.toString());
|
|
}
|
|
|
|
function testSimpleScrollWithSubpixelOffset3(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[0,0,180,200]])),
|
|
"Should blit everything that was already visible: " + blitRegion.toString());
|
|
// The next test is contains, not equals, since we repaint across to 200.2
|
|
// which is OK
|
|
ok(paintRegion.containsRegion(new Region([[180,0,200,200]])),
|
|
"Should repaint area that was scrolled into view: " + paintRegion.toString());
|
|
// Check that we're not repainting anything in the area that's blitted
|
|
ok(!paintRegion.intersectsRect([0,0,180,200]),
|
|
"Should not repaint area that was blitted: " + paintRegion.toString());
|
|
}
|
|
|
|
function testSimpleScrollWithSubpixelOffset4(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[1,0,181,200]])),
|
|
"Should blit everything that was already visible: " + blitRegion.toString());
|
|
// The next test is contains, not equals, since we repaint down to 200.8
|
|
// which is OK
|
|
ok(paintRegion.containsRegion(new Region([[181,0,200,200]])),
|
|
"Should repaint area that was scrolled into view: " + paintRegion.toString());
|
|
// Check that we're not repainting anything in the area that's blitted
|
|
ok(!paintRegion.intersectsRect([0,0,180,200]),
|
|
"Should not repaint area that was blitted: " + paintRegion.toString());
|
|
}
|
|
|
|
function testMovingClipArea(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[0,0,200,40]])),
|
|
"Should blit everything that's affected: " + blitRegion.toString());
|
|
ok(paintRegion.isEmpty(),
|
|
"Shouldn't repaint anything: " + paintRegion.toString());
|
|
}
|
|
|
|
function testNonmovingClipArea(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[0,0,200,130]])),
|
|
"Should only blit necessary strip: " + blitRegion.toString());
|
|
ok(paintRegion.equalsRegion(new Region([[0,130,200,200]])),
|
|
"Should only repaint necessary strip: " + paintRegion.toString());
|
|
}
|
|
|
|
function testFixedOverUniform(blitRegion, paintRegion) {
|
|
ok(!blitRegion.intersectsRect([0,20,200,200]),
|
|
"Shouldn't blit anything except possibly to cover the area that has moved offscreen: " + blitRegion.toString());
|
|
ok(paintRegion.isEmpty(),
|
|
"Shouldn't repaint anything: " + paintRegion.toString());
|
|
}
|
|
|
|
function testClipIFRAME(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[0,0,200,180]])),
|
|
"Should blit everything that was already visible: " + blitRegion.toString());
|
|
ok(paintRegion.equalsRegion(new Region([[0,180,200,200]])),
|
|
"Should repaint area that was scrolled into view: " + paintRegion.toString());
|
|
}
|
|
|
|
function testClipIFRAME2(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[0,50,200,180]])),
|
|
"Should blit everything that was already visible: " + blitRegion.toString());
|
|
// ok(paintRegion.equalsRegion(new Region([[0,180,200,200]])),
|
|
// "Should repaint area that was scrolled into view: " + paintRegion.toString());
|
|
}
|
|
|
|
function testHiddenTable(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[0,0,200,180]])),
|
|
"Should blit everything that was already visible: " + blitRegion.toString());
|
|
ok(paintRegion.equalsRegion(new Region([[0,180,200,200]])),
|
|
"Should repaint area that was scrolled into view: " + paintRegion.toString());
|
|
}
|
|
|
|
function testTableNoBackground(blitRegion, paintRegion) {
|
|
ok(blitRegion.equalsRegion(new Region([[0,0,200,180]])),
|
|
"Should blit everything that was already visible: " + blitRegion.toString());
|
|
ok(paintRegion.equalsRegion(new Region([[0,180,200,200]])),
|
|
"Should repaint area that was scrolled into view: " + paintRegion.toString());
|
|
}
|
|
|
|
function clientRectToRect(cr)
|
|
{
|
|
return [cr.left, cr.top, cr.right, cr.bottom];
|
|
}
|
|
|
|
function regionForReason(requests, reason)
|
|
{
|
|
var rects = [];
|
|
for (var i = 0; i < requests.length; ++i) {
|
|
var r = requests[i];
|
|
if (r.reason == reason) {
|
|
rects.push(clientRectToRect(r.clientRect));
|
|
}
|
|
}
|
|
return new Region(rects);
|
|
}
|
|
|
|
function afterPaint(event) {
|
|
var requests = event.paintRequests;
|
|
|
|
if (!requests) {
|
|
todo(false, "cannot run tests since paintRequests not supported");
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
var blitRegion = regionForReason(requests, "scroll copy");
|
|
var paintRegion = regionForReason(requests, "scroll repaint");
|
|
|
|
if (blitRegion.isEmpty() && paintRegion.isEmpty())
|
|
return;
|
|
|
|
var testFunc = window[tests[currentTest].container.id];
|
|
if (!testFunc) {
|
|
ok(false, "Cannot find test function for " + tests[currentTest].container.id);
|
|
} else {
|
|
testFunc(blitRegion, paintRegion);
|
|
}
|
|
tests[currentTest].container.style.display = 'none';
|
|
|
|
nextTest();
|
|
}
|
|
|
|
function nextTest() {
|
|
++currentTest;
|
|
if (currentTest >= tests.length) {
|
|
finish();
|
|
return;
|
|
}
|
|
|
|
var t = tests[currentTest];
|
|
t.container.style.display = "";
|
|
setTimeout(function() {
|
|
if (t.scrollable.getAttribute("class").match(/horizontal/)) {
|
|
t.scrollable.scrollLeft = 20;
|
|
} else {
|
|
t.scrollable.scrollTop = 20;
|
|
}
|
|
}, 0);
|
|
}
|
|
|
|
function runTests() {
|
|
for (var i = 0; i < testcases.length; ++i) {
|
|
tests.push({ scrollable:testcases[i], container:testcases[i] });
|
|
}
|
|
for (var i = 0; i < iframes.length; ++i) {
|
|
tests.push({ scrollable:iframes[i].contentDocument.body, container:iframes[i] });
|
|
}
|
|
|
|
for (var i = 0; i < tests.length; ++i) {
|
|
var t = tests[i];
|
|
t.container.style.display = "none";
|
|
// Make sure we don't remember a scroll position from history
|
|
t.scrollable.scrollTop = 0;
|
|
t.scrollable.scrollLeft = 0;
|
|
}
|
|
|
|
window.addEventListener("MozAfterPaint", afterPaint, false);
|
|
for (var i = 0; i < iframes.length; ++i) {
|
|
iframes[i].contentWindow.addEventListener("MozAfterPaint", afterPaint, false);
|
|
}
|
|
nextTest();
|
|
}
|
|
window.onload = function() { setTimeout(runTests, 0); };
|
|
</script>
|
|
</body>
|
|
</html>
|