OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "core/html/HTMLIFrameElement.h" |
| 6 #include "core/paint/PaintPropertyTreeBuilderTest.h" |
| 7 #include "core/paint/PaintPropertyTreePrinter.h" |
| 8 |
| 9 namespace blink { |
| 10 |
| 11 // Tests covering incremental updates of paint property trees. |
| 12 class PaintPropertyTreeUpdateTest : public PaintPropertyTreeBuilderTest {}; |
| 13 |
| 14 TEST_P(PaintPropertyTreeUpdateTest, |
| 15 ThreadedScrollingDisabledMainThreadScrollReason) { |
| 16 setBodyInnerHTML( |
| 17 "<style>" |
| 18 " #overflowA {" |
| 19 " position: absolute;" |
| 20 " overflow: scroll;" |
| 21 " width: 20px;" |
| 22 " height: 20px;" |
| 23 " }" |
| 24 " .forceScroll {" |
| 25 " height: 4000px;" |
| 26 " }" |
| 27 "</style>" |
| 28 "<div id='overflowA'>" |
| 29 " <div class='forceScroll'></div>" |
| 30 "</div>" |
| 31 "<div class='forceScroll'></div>"); |
| 32 Element* overflowA = document().getElementById("overflowA"); |
| 33 EXPECT_FALSE(frameScroll()->threadedScrollingDisabled()); |
| 34 EXPECT_FALSE(overflowA->layoutObject() |
| 35 ->paintProperties() |
| 36 ->scroll() |
| 37 ->threadedScrollingDisabled()); |
| 38 |
| 39 document().settings()->setThreadedScrollingEnabled(false); |
| 40 // TODO(pdr): The main thread scrolling setting should invalidate properties. |
| 41 document().view()->setNeedsPaintPropertyUpdate(); |
| 42 overflowA->layoutObject()->setNeedsPaintPropertyUpdate(); |
| 43 document().view()->updateAllLifecyclePhases(); |
| 44 |
| 45 EXPECT_TRUE(frameScroll()->threadedScrollingDisabled()); |
| 46 EXPECT_TRUE(overflowA->layoutObject() |
| 47 ->paintProperties() |
| 48 ->scroll() |
| 49 ->threadedScrollingDisabled()); |
| 50 } |
| 51 |
| 52 TEST_P(PaintPropertyTreeUpdateTest, |
| 53 BackgroundAttachmentFixedMainThreadScrollReasonsWithNestedScrollers) { |
| 54 setBodyInnerHTML( |
| 55 "<style>" |
| 56 " #overflowA {" |
| 57 " position: absolute;" |
| 58 " overflow: scroll;" |
| 59 " width: 20px;" |
| 60 " height: 20px;" |
| 61 " }" |
| 62 " #overflowB {" |
| 63 " position: absolute;" |
| 64 " overflow: scroll;" |
| 65 " width: 5px;" |
| 66 " height: 3px;" |
| 67 " }" |
| 68 " .backgroundAttachmentFixed {" |
| 69 " background-image: url('foo');" |
| 70 " background-attachment: fixed;" |
| 71 " }" |
| 72 " .forceScroll {" |
| 73 " height: 4000px;" |
| 74 " }" |
| 75 "</style>" |
| 76 "<div id='overflowA'>" |
| 77 " <div id='overflowB' class='backgroundAttachmentFixed'>" |
| 78 " <div class='forceScroll'></div>" |
| 79 " </div>" |
| 80 " <div class='forceScroll'></div>" |
| 81 "</div>" |
| 82 "<div class='forceScroll'></div>"); |
| 83 Element* overflowA = document().getElementById("overflowA"); |
| 84 Element* overflowB = document().getElementById("overflowB"); |
| 85 |
| 86 EXPECT_TRUE(frameScroll()->hasBackgroundAttachmentFixedDescendants()); |
| 87 EXPECT_TRUE(overflowA->layoutObject() |
| 88 ->paintProperties() |
| 89 ->scroll() |
| 90 ->hasBackgroundAttachmentFixedDescendants()); |
| 91 EXPECT_FALSE(overflowB->layoutObject() |
| 92 ->paintProperties() |
| 93 ->scroll() |
| 94 ->hasBackgroundAttachmentFixedDescendants()); |
| 95 |
| 96 // Removing a main thread scrolling reason should update the entire tree. |
| 97 overflowB->removeAttribute("class"); |
| 98 document().view()->updateAllLifecyclePhases(); |
| 99 EXPECT_FALSE(frameScroll()->hasBackgroundAttachmentFixedDescendants()); |
| 100 EXPECT_FALSE(overflowA->layoutObject() |
| 101 ->paintProperties() |
| 102 ->scroll() |
| 103 ->hasBackgroundAttachmentFixedDescendants()); |
| 104 EXPECT_FALSE(overflowB->layoutObject() |
| 105 ->paintProperties() |
| 106 ->scroll() |
| 107 ->hasBackgroundAttachmentFixedDescendants()); |
| 108 |
| 109 // Adding a main thread scrolling reason should update the entire tree. |
| 110 overflowB->setAttribute(HTMLNames::classAttr, "backgroundAttachmentFixed"); |
| 111 document().view()->updateAllLifecyclePhases(); |
| 112 EXPECT_TRUE(frameScroll()->hasBackgroundAttachmentFixedDescendants()); |
| 113 EXPECT_TRUE(overflowA->layoutObject() |
| 114 ->paintProperties() |
| 115 ->scroll() |
| 116 ->hasBackgroundAttachmentFixedDescendants()); |
| 117 EXPECT_FALSE(overflowB->layoutObject() |
| 118 ->paintProperties() |
| 119 ->scroll() |
| 120 ->hasBackgroundAttachmentFixedDescendants()); |
| 121 } |
| 122 |
| 123 TEST_P(PaintPropertyTreeUpdateTest, |
| 124 BackgroundAttachmentFixedMainThreadScrollReasonsWithFixedScroller) { |
| 125 setBodyInnerHTML( |
| 126 "<style>" |
| 127 " #overflowA {" |
| 128 " position: absolute;" |
| 129 " overflow: scroll;" |
| 130 " width: 20px;" |
| 131 " height: 20px;" |
| 132 " }" |
| 133 " #overflowB {" |
| 134 " position: fixed;" |
| 135 " overflow: scroll;" |
| 136 " width: 5px;" |
| 137 " height: 3px;" |
| 138 " }" |
| 139 " .backgroundAttachmentFixed {" |
| 140 " background-image: url('foo');" |
| 141 " background-attachment: fixed;" |
| 142 " }" |
| 143 " .forceScroll {" |
| 144 " height: 4000px;" |
| 145 " }" |
| 146 "</style>" |
| 147 "<div id='overflowA'>" |
| 148 " <div id='overflowB' class='backgroundAttachmentFixed'>" |
| 149 " <div class='forceScroll'></div>" |
| 150 " </div>" |
| 151 " <div class='forceScroll'></div>" |
| 152 "</div>" |
| 153 "<div class='forceScroll'></div>"); |
| 154 Element* overflowA = document().getElementById("overflowA"); |
| 155 Element* overflowB = document().getElementById("overflowB"); |
| 156 |
| 157 // This should be false. We are not as strict about main thread scrolling |
| 158 // reasons as we could be. |
| 159 EXPECT_TRUE(overflowA->layoutObject() |
| 160 ->paintProperties() |
| 161 ->scroll() |
| 162 ->hasBackgroundAttachmentFixedDescendants()); |
| 163 EXPECT_FALSE(overflowB->layoutObject() |
| 164 ->paintProperties() |
| 165 ->scroll() |
| 166 ->hasBackgroundAttachmentFixedDescendants()); |
| 167 EXPECT_TRUE(overflowB->layoutObject() |
| 168 ->paintProperties() |
| 169 ->scroll() |
| 170 ->parent() |
| 171 ->isRoot()); |
| 172 |
| 173 // Removing a main thread scrolling reason should update the entire tree. |
| 174 overflowB->removeAttribute("class"); |
| 175 document().view()->updateAllLifecyclePhases(); |
| 176 EXPECT_FALSE(overflowA->layoutObject() |
| 177 ->paintProperties() |
| 178 ->scroll() |
| 179 ->hasBackgroundAttachmentFixedDescendants()); |
| 180 EXPECT_FALSE(overflowB->layoutObject() |
| 181 ->paintProperties() |
| 182 ->scroll() |
| 183 ->hasBackgroundAttachmentFixedDescendants()); |
| 184 EXPECT_FALSE(overflowB->layoutObject() |
| 185 ->paintProperties() |
| 186 ->scroll() |
| 187 ->parent() |
| 188 ->hasBackgroundAttachmentFixedDescendants()); |
| 189 } |
| 190 |
| 191 TEST_P(PaintPropertyTreeUpdateTest, DescendantNeedsUpdateAcrossFrames) { |
| 192 setBodyInnerHTML( |
| 193 "<style>body { margin: 0; }</style>" |
| 194 "<div id='divWithTransform' style='transform: translate3d(1px,2px,3px);'>" |
| 195 " <iframe style='border: 7px solid black'></iframe>" |
| 196 "</div>"); |
| 197 setChildFrameHTML( |
| 198 "<style>body { margin: 0; }</style><div id='transform' style='transform: " |
| 199 "translate3d(4px, 5px, 6px); width: 100px; height: 200px'></div>"); |
| 200 |
| 201 FrameView* frameView = document().view(); |
| 202 frameView->updateAllLifecyclePhases(); |
| 203 |
| 204 LayoutObject* divWithTransform = |
| 205 document().getElementById("divWithTransform")->layoutObject(); |
| 206 LayoutObject* childLayoutView = childDocument().layoutView(); |
| 207 LayoutObject* innerDivWithTransform = |
| 208 childDocument().getElementById("transform")->layoutObject(); |
| 209 |
| 210 // Initially, no objects should need a descendant update. |
| 211 EXPECT_FALSE(document().layoutView()->descendantNeedsPaintPropertyUpdate()); |
| 212 EXPECT_FALSE(divWithTransform->descendantNeedsPaintPropertyUpdate()); |
| 213 EXPECT_FALSE(childLayoutView->descendantNeedsPaintPropertyUpdate()); |
| 214 EXPECT_FALSE(innerDivWithTransform->descendantNeedsPaintPropertyUpdate()); |
| 215 |
| 216 // Marking the child div as needing a paint property update should propagate |
| 217 // up the tree and across frames. |
| 218 innerDivWithTransform->setNeedsPaintPropertyUpdate(); |
| 219 EXPECT_TRUE(document().layoutView()->descendantNeedsPaintPropertyUpdate()); |
| 220 EXPECT_TRUE(divWithTransform->descendantNeedsPaintPropertyUpdate()); |
| 221 EXPECT_TRUE(childLayoutView->descendantNeedsPaintPropertyUpdate()); |
| 222 EXPECT_TRUE(innerDivWithTransform->needsPaintPropertyUpdate()); |
| 223 EXPECT_FALSE(innerDivWithTransform->descendantNeedsPaintPropertyUpdate()); |
| 224 |
| 225 // After a lifecycle update, no nodes should need a descendant update. |
| 226 frameView->updateAllLifecyclePhases(); |
| 227 EXPECT_FALSE(document().layoutView()->descendantNeedsPaintPropertyUpdate()); |
| 228 EXPECT_FALSE(divWithTransform->descendantNeedsPaintPropertyUpdate()); |
| 229 EXPECT_FALSE(childLayoutView->descendantNeedsPaintPropertyUpdate()); |
| 230 EXPECT_FALSE(innerDivWithTransform->descendantNeedsPaintPropertyUpdate()); |
| 231 |
| 232 // A child frame marked as needing a paint property update should not be |
| 233 // skipped if the owning layout tree does not need an update. |
| 234 FrameView* childFrameView = childDocument().view(); |
| 235 childFrameView->setNeedsPaintPropertyUpdate(); |
| 236 EXPECT_TRUE(document().layoutView()->descendantNeedsPaintPropertyUpdate()); |
| 237 frameView->updateAllLifecyclePhases(); |
| 238 EXPECT_FALSE(document().layoutView()->descendantNeedsPaintPropertyUpdate()); |
| 239 EXPECT_FALSE(frameView->needsPaintPropertyUpdate()); |
| 240 EXPECT_FALSE(childFrameView->needsPaintPropertyUpdate()); |
| 241 } |
| 242 |
| 243 TEST_P(PaintPropertyTreeUpdateTest, UpdatingFrameViewContentClip) { |
| 244 setBodyInnerHTML("hello world."); |
| 245 EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600), frameContentClip()->clipRect()); |
| 246 document().view()->resize(800, 599); |
| 247 document().view()->updateAllLifecyclePhases(); |
| 248 EXPECT_EQ(FloatRoundedRect(0, 0, 800, 599), frameContentClip()->clipRect()); |
| 249 document().view()->resize(800, 600); |
| 250 document().view()->updateAllLifecyclePhases(); |
| 251 EXPECT_EQ(FloatRoundedRect(0, 0, 800, 600), frameContentClip()->clipRect()); |
| 252 document().view()->resize(5, 5); |
| 253 document().view()->updateAllLifecyclePhases(); |
| 254 EXPECT_EQ(FloatRoundedRect(0, 0, 5, 5), frameContentClip()->clipRect()); |
| 255 } |
| 256 |
| 257 TEST_P(PaintPropertyTreeUpdateTest, BuildingStopsAtThrottledFrames) { |
| 258 setBodyInnerHTML( |
| 259 "<style>body { margin: 0; }</style>" |
| 260 "<div id='transform' style='transform: translate3d(4px, 5px, 6px);'>" |
| 261 "</div>" |
| 262 "<iframe id='iframe' sandbox></iframe>"); |
| 263 setChildFrameHTML( |
| 264 "<style>body { margin: 0; }</style>" |
| 265 "<div id='iframeTransform'" |
| 266 " style='transform: translate3d(4px, 5px, 6px);'/>"); |
| 267 |
| 268 // Move the child frame offscreen so it becomes available for throttling. |
| 269 auto* iframe = toHTMLIFrameElement(document().getElementById("iframe")); |
| 270 iframe->setAttribute(HTMLNames::styleAttr, "transform: translateY(5555px)"); |
| 271 document().view()->updateAllLifecyclePhases(); |
| 272 // Ensure intersection observer notifications get delivered. |
| 273 testing::runPendingTasks(); |
| 274 EXPECT_FALSE(document().view()->isHiddenForThrottling()); |
| 275 EXPECT_TRUE(childDocument().view()->isHiddenForThrottling()); |
| 276 |
| 277 auto* transform = document().getElementById("transform")->layoutObject(); |
| 278 auto* iframeLayoutView = childDocument().layoutView(); |
| 279 auto* iframeTransform = |
| 280 childDocument().getElementById("iframeTransform")->layoutObject(); |
| 281 |
| 282 // Invalidate properties in the iframe and ensure ancestors are marked. |
| 283 iframeTransform->setNeedsPaintPropertyUpdate(); |
| 284 EXPECT_FALSE(document().layoutView()->needsPaintPropertyUpdate()); |
| 285 EXPECT_TRUE(document().layoutView()->descendantNeedsPaintPropertyUpdate()); |
| 286 EXPECT_FALSE(transform->needsPaintPropertyUpdate()); |
| 287 EXPECT_FALSE(transform->descendantNeedsPaintPropertyUpdate()); |
| 288 EXPECT_FALSE(iframeLayoutView->needsPaintPropertyUpdate()); |
| 289 EXPECT_TRUE(iframeLayoutView->descendantNeedsPaintPropertyUpdate()); |
| 290 EXPECT_TRUE(iframeTransform->needsPaintPropertyUpdate()); |
| 291 EXPECT_FALSE(iframeTransform->descendantNeedsPaintPropertyUpdate()); |
| 292 |
| 293 transform->setNeedsPaintPropertyUpdate(); |
| 294 EXPECT_TRUE(transform->needsPaintPropertyUpdate()); |
| 295 EXPECT_FALSE(transform->descendantNeedsPaintPropertyUpdate()); |
| 296 |
| 297 { |
| 298 DocumentLifecycle::AllowThrottlingScope throttlingScope( |
| 299 document().lifecycle()); |
| 300 EXPECT_FALSE(document().view()->shouldThrottleRendering()); |
| 301 EXPECT_TRUE(childDocument().view()->shouldThrottleRendering()); |
| 302 |
| 303 // A lifecycle update should update all properties except those with |
| 304 // actively throttled descendants. |
| 305 document().view()->updateAllLifecyclePhases(); |
| 306 EXPECT_FALSE(document().layoutView()->needsPaintPropertyUpdate()); |
| 307 EXPECT_TRUE(document().layoutView()->descendantNeedsPaintPropertyUpdate()); |
| 308 EXPECT_FALSE(transform->needsPaintPropertyUpdate()); |
| 309 EXPECT_FALSE(transform->descendantNeedsPaintPropertyUpdate()); |
| 310 EXPECT_FALSE(iframeLayoutView->needsPaintPropertyUpdate()); |
| 311 EXPECT_TRUE(iframeLayoutView->descendantNeedsPaintPropertyUpdate()); |
| 312 EXPECT_TRUE(iframeTransform->needsPaintPropertyUpdate()); |
| 313 EXPECT_FALSE(iframeTransform->descendantNeedsPaintPropertyUpdate()); |
| 314 } |
| 315 |
| 316 EXPECT_FALSE(document().view()->shouldThrottleRendering()); |
| 317 EXPECT_FALSE(childDocument().view()->shouldThrottleRendering()); |
| 318 // Once unthrottled, a lifecycel update should update all properties. |
| 319 document().view()->updateAllLifecyclePhases(); |
| 320 EXPECT_FALSE(document().layoutView()->needsPaintPropertyUpdate()); |
| 321 EXPECT_FALSE(document().layoutView()->descendantNeedsPaintPropertyUpdate()); |
| 322 EXPECT_FALSE(transform->needsPaintPropertyUpdate()); |
| 323 EXPECT_FALSE(transform->descendantNeedsPaintPropertyUpdate()); |
| 324 EXPECT_FALSE(iframeLayoutView->needsPaintPropertyUpdate()); |
| 325 EXPECT_FALSE(iframeLayoutView->descendantNeedsPaintPropertyUpdate()); |
| 326 EXPECT_FALSE(iframeTransform->needsPaintPropertyUpdate()); |
| 327 EXPECT_FALSE(iframeTransform->descendantNeedsPaintPropertyUpdate()); |
| 328 } |
| 329 |
| 330 TEST_P(PaintPropertyTreeUpdateTest, ClipChangesUpdateOverflowClip) { |
| 331 setBodyInnerHTML( |
| 332 "<style>" |
| 333 " body { margin:0 }" |
| 334 " #div { overflow:hidden; height:0px; }" |
| 335 "</style>" |
| 336 "<div id='div'></div>"); |
| 337 auto* div = document().getElementById("div"); |
| 338 div->setAttribute(HTMLNames::styleAttr, "display:inline-block; width:7px;"); |
| 339 document().view()->updateAllLifecyclePhases(); |
| 340 auto* clipProperties = div->layoutObject()->paintProperties()->overflowClip(); |
| 341 EXPECT_EQ(FloatRect(0, 0, 7, 0), clipProperties->clipRect().rect()); |
| 342 |
| 343 // Width changes should update the overflow clip. |
| 344 div->setAttribute(HTMLNames::styleAttr, "display:inline-block; width:7px;"); |
| 345 document().view()->updateAllLifecyclePhases(); |
| 346 clipProperties = div->layoutObject()->paintProperties()->overflowClip(); |
| 347 EXPECT_EQ(FloatRect(0, 0, 7, 0), clipProperties->clipRect().rect()); |
| 348 div->setAttribute(HTMLNames::styleAttr, "display:inline-block; width:9px;"); |
| 349 document().view()->updateAllLifecyclePhases(); |
| 350 EXPECT_EQ(FloatRect(0, 0, 9, 0), clipProperties->clipRect().rect()); |
| 351 |
| 352 // An inline block's overflow clip should be updated when padding changes, |
| 353 // even if the border box remains unchanged. |
| 354 div->setAttribute(HTMLNames::styleAttr, |
| 355 "display:inline-block; width:7px; padding-right:3px;"); |
| 356 document().view()->updateAllLifecyclePhases(); |
| 357 clipProperties = div->layoutObject()->paintProperties()->overflowClip(); |
| 358 EXPECT_EQ(FloatRect(0, 0, 10, 0), clipProperties->clipRect().rect()); |
| 359 div->setAttribute(HTMLNames::styleAttr, |
| 360 "display:inline-block; width:8px; padding-right:2px;"); |
| 361 document().view()->updateAllLifecyclePhases(); |
| 362 EXPECT_EQ(FloatRect(0, 0, 10, 0), clipProperties->clipRect().rect()); |
| 363 div->setAttribute(HTMLNames::styleAttr, |
| 364 "display:inline-block; width:8px;" |
| 365 "padding-right:1px; padding-left:1px;"); |
| 366 document().view()->updateAllLifecyclePhases(); |
| 367 EXPECT_EQ(FloatRect(0, 0, 10, 0), clipProperties->clipRect().rect()); |
| 368 |
| 369 // An block's overflow clip should be updated when borders change. |
| 370 div->setAttribute(HTMLNames::styleAttr, "border-right:3px solid red;"); |
| 371 document().view()->updateAllLifecyclePhases(); |
| 372 clipProperties = div->layoutObject()->paintProperties()->overflowClip(); |
| 373 EXPECT_EQ(FloatRect(0, 0, 797, 0), clipProperties->clipRect().rect()); |
| 374 div->setAttribute(HTMLNames::styleAttr, "border-right:5px solid red;"); |
| 375 document().view()->updateAllLifecyclePhases(); |
| 376 EXPECT_EQ(FloatRect(0, 0, 795, 0), clipProperties->clipRect().rect()); |
| 377 |
| 378 // Removing overflow clip should remove the property. |
| 379 div->setAttribute(HTMLNames::styleAttr, "overflow:hidden;"); |
| 380 document().view()->updateAllLifecyclePhases(); |
| 381 clipProperties = div->layoutObject()->paintProperties()->overflowClip(); |
| 382 EXPECT_EQ(FloatRect(0, 0, 800, 0), clipProperties->clipRect().rect()); |
| 383 div->setAttribute(HTMLNames::styleAttr, "overflow:visible;"); |
| 384 document().view()->updateAllLifecyclePhases(); |
| 385 EXPECT_TRUE(!div->layoutObject()->paintProperties() || |
| 386 !div->layoutObject()->paintProperties()->overflowClip()); |
| 387 } |
| 388 |
| 389 TEST_P(PaintPropertyTreeUpdateTest, ContainPaintChangesUpdateOverflowClip) { |
| 390 setBodyInnerHTML( |
| 391 "<style>" |
| 392 " body { margin:0 }" |
| 393 " #div { will-change:transform; width:7px; height:6px; }" |
| 394 "</style>" |
| 395 "<div id='div' style='contain:paint;'></div>"); |
| 396 document().view()->updateAllLifecyclePhases(); |
| 397 auto* div = document().getElementById("div"); |
| 398 auto* properties = div->layoutObject()->paintProperties()->overflowClip(); |
| 399 EXPECT_EQ(FloatRect(0, 0, 7, 6), properties->clipRect().rect()); |
| 400 |
| 401 div->setAttribute(HTMLNames::styleAttr, ""); |
| 402 document().view()->updateAllLifecyclePhases(); |
| 403 EXPECT_TRUE(!div->layoutObject()->paintProperties() || |
| 404 !div->layoutObject()->paintProperties()->overflowClip()); |
| 405 } |
| 406 |
| 407 // A basic sanity check for over-invalidation of paint properties. |
| 408 TEST_P(PaintPropertyTreeUpdateTest, NoPaintPropertyUpdateOnBackgroundChange) { |
| 409 setBodyInnerHTML("<div id='div' style='background-color: blue'>DIV</div>"); |
| 410 auto* div = document().getElementById("div"); |
| 411 |
| 412 document().view()->updateAllLifecyclePhases(); |
| 413 div->setAttribute(HTMLNames::styleAttr, "background-color: green"); |
| 414 document().view()->updateLifecycleToLayoutClean(); |
| 415 EXPECT_FALSE(div->layoutObject()->needsPaintPropertyUpdate()); |
| 416 } |
| 417 |
| 418 // Disabled due to stale scrollsOverflow values, see: https://crbug.com/675296. |
| 419 TEST_P(PaintPropertyTreeUpdateTest, |
| 420 DISABLED_FrameVisibilityChangeUpdatesProperties) { |
| 421 setBodyInnerHTML( |
| 422 "<style>body { margin: 0; }</style>" |
| 423 "<div id='iframeContainer'>" |
| 424 " <iframe id='iframe' style='width: 100px; height: 100px;'></iframe>" |
| 425 "</div>"); |
| 426 setChildFrameHTML( |
| 427 "<style>body { margin: 0; }</style>" |
| 428 "<div id='forceScroll' style='height: 3000px;'></div>"); |
| 429 |
| 430 FrameView* frameView = document().view(); |
| 431 frameView->updateAllLifecyclePhases(); |
| 432 EXPECT_EQ(nullptr, frameScroll(frameView)); |
| 433 FrameView* childFrameView = childDocument().view(); |
| 434 EXPECT_NE(nullptr, frameScroll(childFrameView)); |
| 435 |
| 436 auto* iframeContainer = document().getElementById("iframeContainer"); |
| 437 iframeContainer->setAttribute(HTMLNames::styleAttr, "visibility: hidden;"); |
| 438 frameView->updateAllLifecyclePhases(); |
| 439 |
| 440 EXPECT_EQ(nullptr, frameScroll(frameView)); |
| 441 EXPECT_EQ(nullptr, frameScroll(childFrameView)); |
| 442 } |
| 443 |
| 444 } // namespace blink |
OLD | NEW |