Chromium Code Reviews| Index: LayoutTests/compositing/overflow/build-paint-order-list-where-opt-in-decisions-can-affect-each-other.html |
| diff --git a/LayoutTests/compositing/overflow/build-paint-order-list-where-opt-in-decisions-can-affect-each-other.html b/LayoutTests/compositing/overflow/build-paint-order-list-where-opt-in-decisions-can-affect-each-other.html |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4d238eee6294f3d1464ab90058a81117ef9e0fd5 |
| --- /dev/null |
| +++ b/LayoutTests/compositing/overflow/build-paint-order-list-where-opt-in-decisions-can-affect-each-other.html |
| @@ -0,0 +1,248 @@ |
| +<html><head> |
| + <style type="text/css" media="screen"> |
|
Ian Vollick
2013/04/16 19:17:41
Ditch the unnecessary attributes.
hartmanng
2013/04/17 18:00:20
Done.
|
| + .filler { |
| + background-color: #CC9900; |
| + margin: 20px; |
| + border-style: solid; |
| + border-width: 1px; |
| + width: 400px; |
| + height: 100px; |
| + } |
| + |
| + .negativechild { |
| + z-index: -1; |
| + position: relative; |
| + } |
| + |
| + #parentscrollinglayer { |
| + background-color: #CC9999; |
| + height: 200px; |
| + width: 500px; |
| + overflow-y: scroll; |
| + } |
| + |
| + #childscrollinglayer { |
| + margin: 30px; |
| + position: relative; |
| + left: 20px; |
| + top: 20px; |
| + background-color: #990066; |
| + height: 200px; |
| + width: 300px; |
| + overflow-x: scroll; |
| + } |
| + </style> |
| + |
| + <script type="text/javascript" charset="utf-8"> |
|
Ian Vollick
2013/04/16 19:17:41
Ditto.
hartmanng
2013/04/17 18:00:20
Done.
|
| + var debugMode = false; |
| + |
| + if (window.testRunner) |
| + testRunner.dumpAsText(); |
| + |
| + function write(str) |
| + { |
| + var pre = document.getElementById('console'); |
| + var text = document.createTextNode(str + '\n'); |
| + pre.appendChild(text); |
| + } |
| + |
| + function didOptIn() |
| + { |
| + // Force a style recalc. |
| + document.body.offsetTop; |
| + |
| + // Force a layout. |
| + window.internals.boundingBox(parentscrollinglayer); |
| + var layerTree = window.internals.layerTreeAsText(document); |
| + |
| + if (debugMode) |
| + write(layerTree); |
| + |
| + return !!layerTree; |
| + } |
| + |
| + function getStackingOrder() |
| + { |
| + var divElements = []; |
| + // Force a style recalc. |
| + document.body.offsetTop; |
| + |
| + // Force a layout. |
| + window.internals.boundingBox(parentscrollinglayer); |
| + |
| + var errorCode = 0; |
| + var stackingOrder = window.internals.nodesFromRect(document, 100, 75, 200, 200, 200, 200, false, false, errorCode); |
| + |
| + for (var i = 0; i < stackingOrder.length; ++i) |
| + if (stackingOrder[i].nodeName === "DIV") |
| + divElements.push(stackingOrder[i]); |
| + |
| + return divElements; |
| + } |
| + |
| + function getPaintOrder() |
| + { |
| + var divElementsBeforePromote = []; |
| + var divElementsAfterPromote = []; |
| + // Force a style recalc. |
| + document.body.offsetTop; |
| + |
| + // Force a layout. |
| + window.internals.boundingBox(parentscrollinglayer); |
| + |
| + var paintOrderLists = window.internals.paintOrderLists(document.getElementById('childscrollinglayer')); |
| + var paintOrderListBeforePromote = paintOrderLists.listBeforePromote; |
| + var paintOrderListAfterPromote = paintOrderLists.listAfterPromote; |
| + |
| + for (var i = 0; i < paintOrderListBeforePromote.length; ++i) |
| + if (paintOrderListBeforePromote[i].nodeName === "DIV") |
| + divElementsBeforePromote.push(paintOrderListBeforePromote[i]); |
| + |
| + for (var i = 0; i < paintOrderListAfterPromote.length; ++i) |
| + if (paintOrderListAfterPromote[i].nodeName === "DIV") |
| + divElementsAfterPromote.push(paintOrderListAfterPromote[i]); |
| + |
| + return {"beforePromote": divElementsBeforePromote, |
| + "afterPromote": divElementsAfterPromote}; |
| + } |
| + |
| + function comparePaintOrderLists(oldPaintOrder, newPaintOrder) |
| + { |
| + if (oldPaintOrder.length != newPaintOrder.length) |
| + return false; |
| + |
| + for (var i = 0; i < oldPaintOrder.length; i++) |
| + if (oldPaintOrder[i] != newPaintOrder[i]) |
| + return false; |
| + |
| + return true; |
| + } |
| + |
| + function compareStackingOrderWithPaintOrder(stackingOrder, paintOrder) |
| + { |
| + if (debugMode) { |
| + write("paint:") |
| + for (var i = 0; i < paintOrder.length; i++) |
| + write(paintOrder[i].id + " " + paintOrder[i].className + " " + paintOrder[i].tagName); |
| + |
| + write("stacking:") |
| + for (var i = 0; i < stackingOrder.length; i++) |
| + write(stackingOrder[i].id + " " + stackingOrder[i].className + " " + stackingOrder[i].tagName); |
| + } |
| + |
| + for (var i = 0, j = 0; i < stackingOrder.length && j < paintOrder.length; i++) { |
| + // Ignore elements with class "filler negativechild". These elements are |
| + // irrelevant to stacking order, since they do not overlap with the |
| + // elements we care about. They exist in the paint order lists because |
| + // they are still descendants of the same stacking context, but they |
| + // will not affect visual layout. |
| + while (j < paintOrder.length && paintOrder[paintOrder.length - j - 1].className == "filler negativechild") |
| + j++; |
| + |
| + if (j >= paintOrder.length) |
| + break; |
| + |
| + if (stackingOrder[i] == paintOrder[paintOrder.length - j - 1]) |
| + j++; |
| + } |
| + |
| + if (debugMode) |
| + write(stackingOrder.length + " " + i + " " + paintOrder.length + " " + j); |
| + |
| + return j == paintOrder.length; |
| + } |
| + |
| + function countOccurrencesOfChildScrollingLayerInPaintOrderList(paintOrder) { |
| + var childScrollingLayer = document.getElementById('childscrollinglayer'); |
| + var occurrenceCount = 0; |
| + for (var i = 0; i < paintOrder.length; i++) |
| + if (paintOrder[i] == childScrollingLayer) |
| + occurrenceCount++; |
| + |
| + return occurrenceCount; |
| + } |
| + |
| + function doTest() |
| + { |
| + var parentscrollinglayer = document.getElementById('parentscrollinglayer'); |
| + var childscrollinglayer = document.getElementById('childscrollinglayer'); |
| + |
| + if (window.internals) { |
| + // below, when we set webkitTransform to '', we want that to force a style recalculation. |
|
Ian Vollick
2013/04/16 19:17:41
Rather than comments like 'force to promote' and '
hartmanng
2013/04/17 18:00:20
Done.
|
| + // Making this not '' here will force this recalculation. |
| + parentscrollinglayer.style.webkitTransform = 'translateZ(0px)'; |
| + document.body.offsetTop; |
| + |
| + // force to not promote. |
| + window.internals.settings.setAcceleratedCompositingForOverflowScrollEnabled(false); |
| + parentscrollinglayer.style.webkitTransform = ''; |
| + |
| + var oldStackingOrder = getStackingOrder(); |
| + var oldPaintOrder = getPaintOrder(); |
| + |
| + // force to promote. |
| + window.internals.settings.setAcceleratedCompositingForOverflowScrollEnabled(true); |
| + parentscrollinglayer.style.webkitTransform = 'translateZ(0px)'; |
| + |
| + var newStackingOrder = getStackingOrder(); |
| + var newPaintOrder = getPaintOrder(); |
| + |
| + if (!comparePaintOrderLists(oldPaintOrder, newPaintOrder)) |
| + write("FAIL - paint order lists not identical before/after promotion"); |
| + |
| + if (!compareStackingOrderWithPaintOrder(oldStackingOrder, oldPaintOrder.beforePromote)) |
| + write("FAIL - paint order list before promote doesn't match stacking order"); |
| + |
| + if (!compareStackingOrderWithPaintOrder(newStackingOrder, oldPaintOrder.afterPromote)) |
| + write("FAIL - paint order list after promote doesn't match stacking order"); |
| + |
| + var childScrollingLayerOccurrences = countOccurrencesOfChildScrollingLayerInPaintOrderList(oldPaintOrder.beforePromote); |
| + if (childScrollingLayerOccurrences != 1) |
| + write("FAIL - paint order list before promote contains " + childScrollingLayerOccurrences + " occurrences of child scrolling layer. Should be exactly 1."); |
| + |
| + childScrollingLayerOccurrences = countOccurrencesOfChildScrollingLayerInPaintOrderList(oldPaintOrder.afterPromote); |
| + if (childScrollingLayerOccurrences != 1) |
| + write("FAIL - paint order list after promote contains " + childScrollingLayerOccurrences + " occurrences of child scrolling layer. Should be exactly 1."); |
| + |
| + if (debugMode) |
| + write(window.internals.paintOrderListsAsText(container)); |
| + |
| + var shouldOptIn = oldStackingOrder.length == newStackingOrder.length; |
| + for (var i = 0; i < oldStackingOrder.length; ++i) { |
| + if (oldStackingOrder[i] != newStackingOrder[i]) { |
| + shouldOptIn = false; |
| + break; |
| + } |
| + } |
| + |
| + parentscrollinglayer.style.webkitTransform = ''; |
| + if (shouldOptIn != didOptIn()) { |
|
hartmanng
2013/04/17 18:00:20
This part must have been left in from before. The
|
| + if (shouldOptIn) |
| + write("FAIL - should've automatically opted in but didn't"); |
| + else |
| + write('FAIL - automatically opted in and changed stacking order'); |
| + } |
| + |
| + write("PASS - did not crash."); |
| + } |
| + } |
| + |
| + window.addEventListener('load', doTest, false); |
| + </script> |
| +</head> |
| +<body> |
| +<div class="filler"></div> |
| +<div id="parentscrollinglayer"> |
| + <div id="childscrollinglayer"> |
| + <div class="filler"></div> |
| + </div> |
| + <div class="filler"></div> |
| + <div class="filler"></div> |
| +</div> |
| +<div id="fillerchild1" class="filler negativechild"></div> |
| +<div id="fillerchild2" class="filler negativechild"></div> |
| +<div id="fillerchild3" class="filler negativechild"></div> |
| +<div id="fillerchild4" class="filler negativechild"></div> |
| +<pre id="console"></pre> |
| +</body> |
| +</html> |