Upstream version 7.35.144.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / LayoutTests / compositing / overflow / resources / automatically-opt-into-composited-scrolling.js
1 var debugMode = false;
2
3 if (window.testRunner)
4   testRunner.dumpAsText();
5
6 function write(str)
7 {
8   var pre = document.getElementById('console');
9   var text = document.createTextNode(str + '\n');
10   pre.appendChild(text);
11 }
12
13 function didOptIn(element)
14 {
15   var nonFastScrollableRects = window.internals.nonFastScrollableRects(document);
16   var elementBoundingBox = window.internals.boundingBox(element);
17
18   for (var i = 0; i < nonFastScrollableRects.length; ++i) {
19     var rect = nonFastScrollableRects[i];
20
21     if (rect.top === elementBoundingBox.top && rect.left === elementBoundingBox.left &&
22         rect.bottom === elementBoundingBox.bottom && rect.right === elementBoundingBox.right)
23       return false;
24   }
25
26   return true;
27 }
28
29 function getStackingOrder(element)
30 {
31   var divElements = [];
32
33   var stackingOrder = window.internals.nodesFromRect(document, 100, 75, 200, 200, 200, 200, false, false, false);
34
35   for (var i = 0; i < stackingOrder.length; ++i)
36     if (stackingOrder[i].nodeName === "DIV")
37       divElements.push(stackingOrder[i]);
38
39   return divElements;
40 }
41
42 function addDomElement(elementType, className, id, parent)
43 {
44   var element = document.createElement(elementType);
45   element.setAttribute("class", className);
46   element.setAttribute("id", id);
47   if (parent === "body")
48     document.body.appendChild(element);
49   else
50     document.getElementById(parent).appendChild(element);
51 }
52
53 function buildDom()
54 {
55   addDomElement("div", "", "ancestor", "body");
56   addDomElement("div", "positioned", "predecessor", "ancestor");
57   addDomElement("div", "container", "container", "ancestor");
58   addDomElement("div", "scrolled", "firstChild", "container");
59   addDomElement("div", "scrolled", "secondChild", "container");
60   addDomElement("div", "", "normalFlow", "container");
61   addDomElement("div", "positioned", "successor", "ancestor");
62   addDomElement("pre", "", "console", "body");
63 }
64
65 var permutationIteration = 0;
66
67 // We've already decided on the ordering of the elements, now we need to do the
68 // rest of the permutations.
69 function permuteWithFixedOrdering(testPermutation, siblingIndex, containerIndex, firstChildIndex, secondChildIndex, numElementsWithZIndexZero)
70 {
71   if (firstChildIndex > secondChildIndex)
72     return;
73   // One of the two children must be immediately to the right of us.
74   if (numElementsWithZIndexZero === 3 && containerIndex !== firstChildIndex - 1 && containerIndex !== secondChildIndex - 1)
75     return;
76   // If we have 2 elements with z-index:0, they will be the container and the
77   // sibling (we don't care about the case when the container and a child are
78   // both z-index:0 because the tree order would ensure that ordering anyway).
79   // The two elements with z-index:0 need to be adjacent in the ordering.
80   if (numElementsWithZIndexZero === 2 && containerIndex !== siblingIndex - 1 && containerIndex !== siblingIndex + 1)
81     return;
82
83   for (var containerIsPositioned = 0; containerIsPositioned <= 1; ++containerIsPositioned) {
84     for (var hasPositionedAncestor = 0; hasPositionedAncestor <= 1; ++hasPositionedAncestor) {
85       if (containerIsPositioned === 1 && hasPositionedAncestor === 1)
86         continue;
87       for (var siblingPrecedesContainer = 0; siblingPrecedesContainer <= 1; ++siblingPrecedesContainer) {
88         // If the sibling and the container both have z-index: 0, we only have
89         // one choice for who gets to be the sibling. For example, if the
90         // sibling is supposed to precede us in paint order, but we both have
91         // z-index: 0, the order will depend entirely on tree order, so we have
92         // to choose the predecessor as the sibling. If all elements have unique
93         // z-indices, either the predecessor or the successor could be our
94         // sibling; the z-indices will ensure that the paint order is correct.
95         if (numElementsWithZIndexZero >= 2 && siblingPrecedesContainer === 1)
96           continue;
97
98         var sibling = predecessor;
99         var toHide = successor;
100         if ((numElementsWithZIndexZero === 1 && siblingPrecedesContainer === 0) ||
101             (numElementsWithZIndexZero >= 2 && siblingIndex > containerIndex)) {
102           sibling = successor;
103           toHide = predecessor;
104         }
105
106         var ordering = [ null, null, null, null ];
107         ordering[siblingIndex] = sibling;
108         ordering[containerIndex] = hasPositionedAncestor === 1 ? ancestor : container;
109         ordering[firstChildIndex] = firstChild;
110         ordering[secondChildIndex] = secondChild;
111
112         toHide.style.display = 'none';
113         sibling.style.display = '';
114
115         var positioned = null;
116         if (containerIsPositioned === 1) {
117           container.style.position = 'relative';
118           positioned = container;
119         } else
120           container.style.position = '';
121
122         if (hasPositionedAncestor === 1) {
123           ancestor.style.position = 'relative';
124           positioned = ancestor;
125         } else
126           ancestor.style.position = '';
127
128         var currentZIndex = siblingPrecedesContainer === 1 ? 0 : -1;
129         for (var currentIndex = containerIndex - 1; currentIndex >= 0; --currentIndex) {
130           ordering[currentIndex].style.zIndex = currentZIndex.toString();
131           currentZIndex--;
132         }
133
134         currentZIndex = 1;
135         for (var currentIndex = containerIndex + 1; currentIndex < 4; ++currentIndex) {
136           ordering[currentIndex].style.zIndex = currentZIndex.toString();
137           currentZIndex++;
138         }
139
140         if (numElementsWithZIndexZero >= 1)
141           ordering[containerIndex].style.zIndex = '0';
142
143         if (numElementsWithZIndexZero >= 2)
144             ordering[siblingIndex].style.zIndex = '0';
145
146         // We want the first descendant succeeding us in the ordering to get
147         // z-index: 0.
148         if (numElementsWithZIndexZero === 3) {
149           if (firstChildIndex > containerIndex)
150             ordering[firstChildIndex].style.zIndex = '0';
151           else
152             ordering[secondChildIndex].style.zIndex = '0';
153         }
154
155         testPermutation(permutationIteration, ordering, hasPositionedAncestor, containerIsPositioned);
156         permutationIteration++;
157       }
158     }
159   }
160 }
161
162 function testOptInPermutation(count, ordering, hasPositionedAncestor, containerIsPositioned)
163 {
164   if (!window.internals)
165     return;
166
167   window.internals.forceCompositingUpdate(document);
168
169   var container = document.getElementById('container');
170   var containerOptedIn = didOptIn(container);
171
172   window.internals.setNeedsCompositedScrolling(container,
173       window.internals.COMPOSITED_SCROLLING_ALWAYS_OFF);
174
175   var oldStackingOrder = getStackingOrder(container);
176
177   window.internals.setNeedsCompositedScrolling(container,
178       window.internals.COMPOSITED_SCROLLING_ALWAYS_ON);
179
180   var newStackingOrder = getStackingOrder(container);
181
182   window.internals.setNeedsCompositedScrolling(container,
183       window.internals.DO_NOT_FORCE_COMPOSITED_SCROLLING);
184
185   var shouldOptIn = oldStackingOrder.length === newStackingOrder.length;
186   for (var i = 0; i < oldStackingOrder.length; ++i) {
187     if (oldStackingOrder[i] !== newStackingOrder[i]) {
188       shouldOptIn = false;
189       break;
190     }
191   }
192
193   if (shouldOptIn !== containerOptedIn) {
194     if (shouldOptIn)
195       write("FAIL - should've automatically opted in but didn't " + count);
196     else
197       write('FAIL - automatically opted in and changed stacking order ' + count);
198
199     var additionalFailureInfo = "\tOrdering:";
200     for(var i = 0; i < ordering.length; ++i) {
201       additionalFailureInfo += " " + ordering[i].id + " (z-index: " + ordering[i].style.zIndex + ")";
202       if(i < ordering.length - 1)
203         additionalFailureInfo += ",";
204     }
205
206     additionalFailureInfo += "\n\thasPositionedAncestor: " + hasPositionedAncestor + "; containerIsPositioned: " + containerIsPositioned;
207     write(additionalFailureInfo);
208   } else {
209     if (shouldOptIn)
210       write("PASS iteration " + count + ": opted in, since doing so does not change the stacking order.");
211     else
212       write("PASS iteration " + count + ": did not opt in, since doing so would change the stacking order.");
213   }
214 }
215
216 function runPermutationSet(testPermutation, siblingIndex)
217 {
218   var ancestor = document.getElementById('ancestor');
219   var predecessor = document.getElementById('predecessor');
220   var successor = document.getElementById('successor');
221   var container = document.getElementById('container');
222   var firstChild = document.getElementById('firstChild');
223   var secondChild = document.getElementById('secondChild');
224
225   write('Testing permutation set ' + siblingIndex + ' - this means that the "sibling" will be placed at the index ' + siblingIndex + ' of the paint order.')
226
227   var indices = [ 0, 1, 2, 3 ];
228   var siblingIndices = indices.slice(0);
229   siblingIndices.splice(siblingIndex, 1);
230   for (var containerSubindex = 0; containerSubindex < siblingIndices.length; ++containerSubindex) {
231     var containerIndices = siblingIndices.slice(0);
232     var containerIndex = containerIndices[containerSubindex];
233     containerIndices.splice(containerSubindex, 1);
234     var firstChildIndex = containerIndices[0];
235     var secondChildIndex = containerIndices[1];
236
237     permuteWithFixedOrdering(testPermutation, siblingIndex, containerIndex, firstChildIndex, secondChildIndex, 1);
238     permuteWithFixedOrdering(testPermutation, siblingIndex, containerIndex, firstChildIndex, secondChildIndex, 2);
239     permuteWithFixedOrdering(testPermutation, siblingIndex, containerIndex, firstChildIndex, secondChildIndex, 3);
240   }
241 } // function doTest
242
243 function runOptInPermutationSet(permutationSet) {
244   runPermutationSet(testOptInPermutation, permutationSet);
245 }