| <!-- webkit-test-runner [ useThreadedScrolling=false ] --> |
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" |
| "http://www.w3.org/TR/html4/loose.dtd"> |
| |
| <html lang="en"> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> |
| <title>Opting into composited scrolling</title> |
| <style type="text/css" media="screen"> |
| .container { |
| width: 200px; |
| height: 200px; |
| overflow: scroll; |
| margin: 20px; |
| border: 1px solid black; |
| } |
| |
| .scrolled { |
| width: 180px; |
| height: 90px; |
| margin: 10px; |
| background-color: gray; |
| position: relative; |
| } |
| |
| .positioned { |
| width: 120px; |
| height: 240px; |
| background-color: green; |
| position: absolute; |
| } |
| |
| #predecessor { |
| left: 20px; |
| top: 20px; |
| } |
| |
| #successor { |
| left: 160px; |
| top: 20px; |
| } |
| |
| #descendant { |
| left: 90px; |
| top: 20px; |
| background-color: blue; |
| z-index: -20; |
| } |
| </style> |
| <script type="text/javascript" charset="utf-8"> |
| var debugMode = false; |
| |
| if (window.testRunner) |
| testRunner.dumpAsText(); |
| |
| if (window.internals) |
| window.internals.settings.setAcceleratedCompositingForOverflowScrollEnabled(true); |
| |
| function write(str) |
| { |
| var pre = document.getElementById('console'); |
| var text = document.createTextNode(str + '\n'); |
| pre.appendChild(text); |
| } |
| |
| var iteration = 0; |
| function printResult(expectedResult) |
| { |
| // Force a style recalc. |
| document.body.offsetTop; |
| |
| if (window.internals) { |
| // Force a layout. |
| window.internals.boundingBox(container); |
| var layerTree = window.internals.layerTreeAsText(document); |
| |
| if (!layerTree == !expectedResult) |
| write('Iteration ' + iteration.toString() + ': Passed') |
| else |
| write('Iteration ' + iteration.toString() + ': FAILED') |
| |
| if (layerTree) { |
| write('Iteration ' + iteration.toString() + ', layer tree'); |
| if (debugMode) |
| write(layerTree); |
| } else |
| write('Iteration ' + iteration.toString() + ', no layer tree'); |
| } |
| iteration++; |
| } |
| |
| function doTest() |
| { |
| var predecessor = document.getElementById('predecessor'); |
| var successor = document.getElementById('successor'); |
| var container = document.getElementById('container'); |
| var firstChild = document.getElementById('firstChild'); |
| var secondChild = document.getElementById('secondChild'); |
| var descendant = document.getElementById('descendant'); |
| var count = 0; |
| |
| descendant.style.display = 'none'; |
| |
| // descendants in stacking order. |
| for (i = 0; i < 3; ++i) { |
| for (j = 0; j < 5; ++j) { |
| for (k = 0; k < 2; ++k) { |
| for (l = 0; l < 2; ++l) { |
| var minZIndex = 0; |
| var maxZIndex = 0; |
| if (i == 0) { |
| firstChild.style.zIndex = '1'; |
| secondChild.style.zIndex = '3'; |
| maxZIndex = 3; |
| } else if (i == 1) { |
| firstChild.style.zIndex = '-1'; |
| secondChild.style.zIndex = '-3'; |
| minZIndex = -3; |
| } else { |
| firstChild.style.zIndex = '-1'; |
| secondChild.style.zIndex = '3'; |
| minZIndex = -1; |
| maxZIndex = 3; |
| } |
| |
| var sibling = predecessor; |
| var toHide = successor; |
| if (k == 1) { |
| sibling = successor; |
| toHide = predecessor; |
| } |
| |
| // The result should be the same if the the element to hide is |
| // display:hidden or display:none. |
| if (l == 0) |
| toHide.style.display = 'none'; |
| else |
| toHide.style.display = 'hidden'; |
| |
| sibling.style.display = ''; |
| |
| if (j == 0) |
| sibling.style.zIndex = (maxZIndex + 1).toString(); |
| else if (j == 1) |
| sibling.style.zIndex = (minZIndex - 1).toString(); |
| else if (j == 2) |
| sibling.style.zIndex = maxZIndex.toString(); |
| else if (j == 3) |
| sibling.style.zIndex = minZIndex.toString(); |
| else |
| sibling.style.zIndex = ((minZIndex + maxZIndex) / 2).toString(); |
| |
| var areContiguous = false; |
| if (sibling.style.zIndex > maxZIndex || |
| sibling.style.zIndex < minZIndex) { |
| // sibling is outside the range of our descendants. |
| areContiguous = true; |
| } else if (sibling.style.zIndex < maxZIndex && |
| sibling.style.zIndex > minZIndex) { |
| // sibling is between our descendants. |
| areContiguous = false; |
| } else if (sibling.style.zIndex == minZIndex) { |
| if (minZIndex == 0) { |
| // sibling lies between us (normal flow) and our pos |
| // z-order descendants, so we are not contiguous. |
| areContiguous = false; |
| } else { |
| // sibling's zIndex matches the min; we're only ok if it |
| // appears first. |
| areContiguous = k == 0; |
| } |
| } else if (sibling.style.zIndex == maxZIndex) { |
| if (maxZIndex < 0) { |
| // sibling lies between us (normal flow) and neg z-order |
| // descendants, so we are not contiguous. |
| areContiguous = false; |
| } else if (maxZIndex == 0) { |
| // sibling is in the pos z-order list and does not affect |
| // us since we're in the normal flow list and our |
| // descandants are in the neg z-order list. |
| areContiguous = true; |
| } else { |
| // sibling's zIndex matches the max; we're only ok if it |
| // appears after. |
| areContiguous = k == 1; |
| } |
| } |
| |
| printResult(areContiguous); |
| } // for l |
| } // for k |
| } // for j |
| } // for i |
| |
| // Now check that we don't promote if we have an out of flow descendant. |
| // We need to hide the predecessor and successor so they don't interfere |
| // with this experiment. |
| predecessor.style.display = 'none'; |
| successor.style.display = 'none'; |
| for (i = 0; i < 3; ++i) { |
| if (i == 0) |
| descendant.style.display = 'hidden'; |
| else if (i == 1) |
| descendant.style.display = ''; |
| else |
| descendant.style.display = 'none'; |
| |
| // If the out of flow positioned descendant is visible, we cannot opt |
| // into composited scrolling. |
| printResult(i != 1); |
| count++; |
| } // for i |
| |
| } // function doTest |
| |
| window.addEventListener('load', doTest, false); |
| </script> |
| </head> |
| |
| <body> |
| <div class="positioned" id="predecessor"></div> |
| <div class="container" id="container"> |
| <div class="scrolled" id="firstChild"></div> |
| <div class="scrolled" id="secondChild"></div> |
| <div class="positioned" id="descendant"></div> |
| </div> |
| <div class="positioned" id="successor"></div> |
| <pre id="console"></pre> |
| </body> |
| </html> |
| |