| 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..b67702f7efe8368800d198219c571a30b2917fa8
|
| --- /dev/null
|
| +++ b/LayoutTests/compositing/overflow/build-paint-order-list-where-opt-in-decisions-can-affect-each-other.html
|
| @@ -0,0 +1,218 @@
|
| +<!DOCTYPE html>
|
| +
|
| +<html><head>
|
| + <style>
|
| + .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>
|
| + 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 getStackingOrder()
|
| + {
|
| + var divElements = [];
|
| + // Force a style recalc.
|
| + document.body.offsetTop;
|
| +
|
| + var stackingOrder = window.internals.nodesFromRect(document, 100, 75, 200, 200, 200, 200, false, false, false);
|
| +
|
| + 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;
|
| +
|
| + var paintOrderListBeforePromote = window.internals.paintOrderListBeforePromote(document.getElementById('childscrollinglayer'));
|
| + var paintOrderListAfterPromote = window.internals.paintOrderListAfterPromote(document.getElementById('childscrollinglayer'));
|
| +
|
| + 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) {
|
| + // Here we want to compare paint order lists before and after promotion
|
| + // to the actual stacking order as determined by hit-testing. So we
|
| + // first force the element not to promote, then compute its paint and
|
| + // stacking order lists. We then force the element to opt in, and
|
| + // generate the paint and stacking order lists after opt-in.
|
| + //
|
| + // The paint order lists should exactly match the stacking order lists
|
| + // (modulo children that fall outside of the hit-testing area
|
| + // on-screen), both before and after promotion.
|
| + parentscrollinglayer.style.webkitTransform = 'translateZ(0px)';
|
| + document.body.offsetTop;
|
| +
|
| + window.internals.settings.setAcceleratedCompositingForOverflowScrollEnabled(false);
|
| + parentscrollinglayer.style.webkitTransform = '';
|
| +
|
| + var oldStackingOrder = getStackingOrder();
|
| + var oldPaintOrder = getPaintOrder();
|
| +
|
| + window.internals.settings.setAcceleratedCompositingForOverflowScrollEnabled(true);
|
| + parentscrollinglayer.style.webkitTransform = 'translateZ(0px)';
|
| +
|
| + var newStackingOrder = getStackingOrder();
|
| + var newPaintOrder = getPaintOrder();
|
| +
|
| + // The getPaintOrder() function should return a pair of paint orders.
|
| + // One before promotion and one after. This pair of lists should remain
|
| + // identical whether the element is actually currently promoted or not,
|
| + // its purpose is to generate hypothetical pre- and post-lists to
|
| + // determine if the element is promotable.
|
| + 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.");
|
| +
|
| + 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>
|
|
|