OLD | NEW |
---|---|
(Empty) | |
1 <html><head> | |
2 <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.
| |
3 .filler { | |
4 background-color: #CC9900; | |
5 margin: 20px; | |
6 border-style: solid; | |
7 border-width: 1px; | |
8 width: 400px; | |
9 height: 100px; | |
10 } | |
11 | |
12 .negativechild { | |
13 z-index: -1; | |
14 position: relative; | |
15 } | |
16 | |
17 #parentscrollinglayer { | |
18 background-color: #CC9999; | |
19 height: 200px; | |
20 width: 500px; | |
21 overflow-y: scroll; | |
22 } | |
23 | |
24 #childscrollinglayer { | |
25 margin: 30px; | |
26 position: relative; | |
27 left: 20px; | |
28 top: 20px; | |
29 background-color: #990066; | |
30 height: 200px; | |
31 width: 300px; | |
32 overflow-x: scroll; | |
33 } | |
34 </style> | |
35 | |
36 <script type="text/javascript" charset="utf-8"> | |
Ian Vollick
2013/04/16 19:17:41
Ditto.
hartmanng
2013/04/17 18:00:20
Done.
| |
37 var debugMode = false; | |
38 | |
39 if (window.testRunner) | |
40 testRunner.dumpAsText(); | |
41 | |
42 function write(str) | |
43 { | |
44 var pre = document.getElementById('console'); | |
45 var text = document.createTextNode(str + '\n'); | |
46 pre.appendChild(text); | |
47 } | |
48 | |
49 function didOptIn() | |
50 { | |
51 // Force a style recalc. | |
52 document.body.offsetTop; | |
53 | |
54 // Force a layout. | |
55 window.internals.boundingBox(parentscrollinglayer); | |
56 var layerTree = window.internals.layerTreeAsText(document); | |
57 | |
58 if (debugMode) | |
59 write(layerTree); | |
60 | |
61 return !!layerTree; | |
62 } | |
63 | |
64 function getStackingOrder() | |
65 { | |
66 var divElements = []; | |
67 // Force a style recalc. | |
68 document.body.offsetTop; | |
69 | |
70 // Force a layout. | |
71 window.internals.boundingBox(parentscrollinglayer); | |
72 | |
73 var errorCode = 0; | |
74 var stackingOrder = window.internals.nodesFromRect(document, 100, 75, 200, 200, 200, 200, false, false, errorCode); | |
75 | |
76 for (var i = 0; i < stackingOrder.length; ++i) | |
77 if (stackingOrder[i].nodeName === "DIV") | |
78 divElements.push(stackingOrder[i]); | |
79 | |
80 return divElements; | |
81 } | |
82 | |
83 function getPaintOrder() | |
84 { | |
85 var divElementsBeforePromote = []; | |
86 var divElementsAfterPromote = []; | |
87 // Force a style recalc. | |
88 document.body.offsetTop; | |
89 | |
90 // Force a layout. | |
91 window.internals.boundingBox(parentscrollinglayer); | |
92 | |
93 var paintOrderLists = window.internals.paintOrderLists(document.getElement ById('childscrollinglayer')); | |
94 var paintOrderListBeforePromote = paintOrderLists.listBeforePromote; | |
95 var paintOrderListAfterPromote = paintOrderLists.listAfterPromote; | |
96 | |
97 for (var i = 0; i < paintOrderListBeforePromote.length; ++i) | |
98 if (paintOrderListBeforePromote[i].nodeName === "DIV") | |
99 divElementsBeforePromote.push(paintOrderListBeforePromote[i]); | |
100 | |
101 for (var i = 0; i < paintOrderListAfterPromote.length; ++i) | |
102 if (paintOrderListAfterPromote[i].nodeName === "DIV") | |
103 divElementsAfterPromote.push(paintOrderListAfterPromote[i]); | |
104 | |
105 return {"beforePromote": divElementsBeforePromote, | |
106 "afterPromote": divElementsAfterPromote}; | |
107 } | |
108 | |
109 function comparePaintOrderLists(oldPaintOrder, newPaintOrder) | |
110 { | |
111 if (oldPaintOrder.length != newPaintOrder.length) | |
112 return false; | |
113 | |
114 for (var i = 0; i < oldPaintOrder.length; i++) | |
115 if (oldPaintOrder[i] != newPaintOrder[i]) | |
116 return false; | |
117 | |
118 return true; | |
119 } | |
120 | |
121 function compareStackingOrderWithPaintOrder(stackingOrder, paintOrder) | |
122 { | |
123 if (debugMode) { | |
124 write("paint:") | |
125 for (var i = 0; i < paintOrder.length; i++) | |
126 write(paintOrder[i].id + " " + paintOrder[i].className + " " + paintOr der[i].tagName); | |
127 | |
128 write("stacking:") | |
129 for (var i = 0; i < stackingOrder.length; i++) | |
130 write(stackingOrder[i].id + " " + stackingOrder[i].className + " " + s tackingOrder[i].tagName); | |
131 } | |
132 | |
133 for (var i = 0, j = 0; i < stackingOrder.length && j < paintOrder.length; i++) { | |
134 // Ignore elements with class "filler negativechild". These elements are | |
135 // irrelevant to stacking order, since they do not overlap with the | |
136 // elements we care about. They exist in the paint order lists because | |
137 // they are still descendants of the same stacking context, but they | |
138 // will not affect visual layout. | |
139 while (j < paintOrder.length && paintOrder[paintOrder.length - j - 1].cl assName == "filler negativechild") | |
140 j++; | |
141 | |
142 if (j >= paintOrder.length) | |
143 break; | |
144 | |
145 if (stackingOrder[i] == paintOrder[paintOrder.length - j - 1]) | |
146 j++; | |
147 } | |
148 | |
149 if (debugMode) | |
150 write(stackingOrder.length + " " + i + " " + paintOrder.length + " " + j ); | |
151 | |
152 return j == paintOrder.length; | |
153 } | |
154 | |
155 function countOccurrencesOfChildScrollingLayerInPaintOrderList(paintOrder) { | |
156 var childScrollingLayer = document.getElementById('childscrollinglayer'); | |
157 var occurrenceCount = 0; | |
158 for (var i = 0; i < paintOrder.length; i++) | |
159 if (paintOrder[i] == childScrollingLayer) | |
160 occurrenceCount++; | |
161 | |
162 return occurrenceCount; | |
163 } | |
164 | |
165 function doTest() | |
166 { | |
167 var parentscrollinglayer = document.getElementById('parentscrollinglayer') ; | |
168 var childscrollinglayer = document.getElementById('childscrollinglayer'); | |
169 | |
170 if (window.internals) { | |
171 // below, when we set webkitTransform to '', we want that to force a sty le 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.
| |
172 // Making this not '' here will force this recalculation. | |
173 parentscrollinglayer.style.webkitTransform = 'translateZ(0px)'; | |
174 document.body.offsetTop; | |
175 | |
176 // force to not promote. | |
177 window.internals.settings.setAcceleratedCompositingForOverflowScrollEnab led(false); | |
178 parentscrollinglayer.style.webkitTransform = ''; | |
179 | |
180 var oldStackingOrder = getStackingOrder(); | |
181 var oldPaintOrder = getPaintOrder(); | |
182 | |
183 // force to promote. | |
184 window.internals.settings.setAcceleratedCompositingForOverflowScrollEnab led(true); | |
185 parentscrollinglayer.style.webkitTransform = 'translateZ(0px)'; | |
186 | |
187 var newStackingOrder = getStackingOrder(); | |
188 var newPaintOrder = getPaintOrder(); | |
189 | |
190 if (!comparePaintOrderLists(oldPaintOrder, newPaintOrder)) | |
191 write("FAIL - paint order lists not identical before/after promotion") ; | |
192 | |
193 if (!compareStackingOrderWithPaintOrder(oldStackingOrder, oldPaintOrder. beforePromote)) | |
194 write("FAIL - paint order list before promote doesn't match stacking o rder"); | |
195 | |
196 if (!compareStackingOrderWithPaintOrder(newStackingOrder, oldPaintOrder. afterPromote)) | |
197 write("FAIL - paint order list after promote doesn't match stacking or der"); | |
198 | |
199 var childScrollingLayerOccurrences = countOccurrencesOfChildScrollingLay erInPaintOrderList(oldPaintOrder.beforePromote); | |
200 if (childScrollingLayerOccurrences != 1) | |
201 write("FAIL - paint order list before promote contains " + childScroll ingLayerOccurrences + " occurrences of child scrolling layer. Should be exactly 1."); | |
202 | |
203 childScrollingLayerOccurrences = countOccurrencesOfChildScrollingLayerIn PaintOrderList(oldPaintOrder.afterPromote); | |
204 if (childScrollingLayerOccurrences != 1) | |
205 write("FAIL - paint order list after promote contains " + childScrolli ngLayerOccurrences + " occurrences of child scrolling layer. Should be exactly 1 ."); | |
206 | |
207 if (debugMode) | |
208 write(window.internals.paintOrderListsAsText(container)); | |
209 | |
210 var shouldOptIn = oldStackingOrder.length == newStackingOrder.length; | |
211 for (var i = 0; i < oldStackingOrder.length; ++i) { | |
212 if (oldStackingOrder[i] != newStackingOrder[i]) { | |
213 shouldOptIn = false; | |
214 break; | |
215 } | |
216 } | |
217 | |
218 parentscrollinglayer.style.webkitTransform = ''; | |
219 if (shouldOptIn != didOptIn()) { | |
hartmanng
2013/04/17 18:00:20
This part must have been left in from before. The
| |
220 if (shouldOptIn) | |
221 write("FAIL - should've automatically opted in but didn't"); | |
222 else | |
223 write('FAIL - automatically opted in and changed stacking order'); | |
224 } | |
225 | |
226 write("PASS - did not crash."); | |
227 } | |
228 } | |
229 | |
230 window.addEventListener('load', doTest, false); | |
231 </script> | |
232 </head> | |
233 <body> | |
234 <div class="filler"></div> | |
235 <div id="parentscrollinglayer"> | |
236 <div id="childscrollinglayer"> | |
237 <div class="filler"></div> | |
238 </div> | |
239 <div class="filler"></div> | |
240 <div class="filler"></div> | |
241 </div> | |
242 <div id="fillerchild1" class="filler negativechild"></div> | |
243 <div id="fillerchild2" class="filler negativechild"></div> | |
244 <div id="fillerchild3" class="filler negativechild"></div> | |
245 <div id="fillerchild4" class="filler negativechild"></div> | |
246 <pre id="console"></pre> | |
247 </body> | |
248 </html> | |
OLD | NEW |