Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: third_party/WebKit/Source/core/frame/FrameView.cpp

Issue 1449623002: IntersectionObserver: second cut. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Add RuntimeEnabled flags to all idl's, fix test expectations. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3 * 1999 Lars Knoll <knoll@kde.org> 3 * 1999 Lars Knoll <knoll@kde.org>
4 * 1999 Antti Koivisto <koivisto@kde.org> 4 * 1999 Antti Koivisto <koivisto@kde.org>
5 * 2000 Dirk Mueller <mueller@kde.org> 5 * 2000 Dirk Mueller <mueller@kde.org>
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com) 7 * (C) 2006 Graham Dennis (graham.dennis@gmail.com)
8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com) 8 * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
9 * Copyright (C) 2009 Google Inc. All rights reserved. 9 * Copyright (C) 2009 Google Inc. All rights reserved.
10 * 10 *
(...skipping 14 matching lines...) Expand all
25 */ 25 */
26 26
27 #include "core/frame/FrameView.h" 27 #include "core/frame/FrameView.h"
28 28
29 #include "core/HTMLNames.h" 29 #include "core/HTMLNames.h"
30 #include "core/MediaTypeNames.h" 30 #include "core/MediaTypeNames.h"
31 #include "core/css/FontFaceSet.h" 31 #include "core/css/FontFaceSet.h"
32 #include "core/css/resolver/StyleResolver.h" 32 #include "core/css/resolver/StyleResolver.h"
33 #include "core/dom/AXObjectCache.h" 33 #include "core/dom/AXObjectCache.h"
34 #include "core/dom/Fullscreen.h" 34 #include "core/dom/Fullscreen.h"
35 #include "core/dom/IntersectionObserverController.h"
35 #include "core/editing/EditingUtilities.h" 36 #include "core/editing/EditingUtilities.h"
36 #include "core/editing/FrameSelection.h" 37 #include "core/editing/FrameSelection.h"
37 #include "core/editing/RenderedPosition.h" 38 #include "core/editing/RenderedPosition.h"
38 #include "core/editing/markers/DocumentMarkerController.h" 39 #include "core/editing/markers/DocumentMarkerController.h"
39 #include "core/fetch/ResourceFetcher.h" 40 #include "core/fetch/ResourceFetcher.h"
40 #include "core/frame/FrameHost.h" 41 #include "core/frame/FrameHost.h"
41 #include "core/frame/LocalFrame.h" 42 #include "core/frame/LocalFrame.h"
42 #include "core/frame/Settings.h" 43 #include "core/frame/Settings.h"
43 #include "core/html/HTMLFrameElement.h" 44 #include "core/html/HTMLFrameElement.h"
44 #include "core/html/HTMLPlugInElement.h" 45 #include "core/html/HTMLPlugInElement.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 static bool s_initialTrackAllPaintInvalidations = false; 114 static bool s_initialTrackAllPaintInvalidations = false;
114 115
115 FrameView::FrameView(LocalFrame* frame) 116 FrameView::FrameView(LocalFrame* frame)
116 : m_frame(frame) 117 : m_frame(frame)
117 , m_displayMode(WebDisplayModeBrowser) 118 , m_displayMode(WebDisplayModeBrowser)
118 , m_canHaveScrollbars(true) 119 , m_canHaveScrollbars(true)
119 , m_hasPendingLayout(false) 120 , m_hasPendingLayout(false)
120 , m_inSynchronousPostLayout(false) 121 , m_inSynchronousPostLayout(false)
121 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) 122 , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired)
122 , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired) 123 , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired)
123 , m_intersectionObserverNotificationFactory(CancellableTaskFactory::create(t his, &FrameView::notifyIntersectionObservers)) 124 , m_renderThrottlingObserverNotificationFactory(CancellableTaskFactory::crea te(this, &FrameView::notifyRenderThrottlingObservers))
124 , m_isTransparent(false) 125 , m_isTransparent(false)
125 , m_baseBackgroundColor(Color::white) 126 , m_baseBackgroundColor(Color::white)
126 , m_mediaType(MediaTypeNames::screen) 127 , m_mediaType(MediaTypeNames::screen)
127 , m_safeToPropagateScrollToParent(true) 128 , m_safeToPropagateScrollToParent(true)
128 , m_isTrackingPaintInvalidations(false) 129 , m_isTrackingPaintInvalidations(false)
129 , m_scrollCorner(nullptr) 130 , m_scrollCorner(nullptr)
130 , m_inputEventsScaleFactorForEmulation(1) 131 , m_inputEventsScaleFactorForEmulation(1)
131 , m_layoutSizeFixedToFrameSize(true) 132 , m_layoutSizeFixedToFrameSize(true)
132 , m_didScrollTimer(this, &FrameView::didScrollTimerFired) 133 , m_didScrollTimer(this, &FrameView::didScrollTimerFired)
133 , m_topControlsViewportAdjustment(0) 134 , m_topControlsViewportAdjustment(0)
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 279
279 // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing 280 // Destroy |m_autoSizeInfo| as early as possible, to avoid dereferencing
280 // partially destroyed |this| via |m_autoSizeInfo->m_frameView|. 281 // partially destroyed |this| via |m_autoSizeInfo->m_frameView|.
281 m_autoSizeInfo.clear(); 282 m_autoSizeInfo.clear();
282 283
283 if (m_postLayoutTasksTimer.isActive()) 284 if (m_postLayoutTasksTimer.isActive())
284 m_postLayoutTasksTimer.stop(); 285 m_postLayoutTasksTimer.stop();
285 286
286 if (m_didScrollTimer.isActive()) 287 if (m_didScrollTimer.isActive())
287 m_didScrollTimer.stop(); 288 m_didScrollTimer.stop();
288 m_intersectionObserverNotificationFactory->cancel(); 289 m_renderThrottlingObserverNotificationFactory->cancel();
289 290
290 // FIXME: Do we need to do something here for OOPI? 291 // FIXME: Do we need to do something here for OOPI?
291 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner(); 292 HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner();
292 // TODO(dcheng): It seems buggy that we can have an owner element that 293 // TODO(dcheng): It seems buggy that we can have an owner element that
293 // points to another Widget. 294 // points to another Widget.
294 if (ownerElement && ownerElement->ownedWidget() == this) 295 if (ownerElement && ownerElement->ownedWidget() == this)
295 ownerElement->setWidget(nullptr); 296 ownerElement->setWidget(nullptr);
296 297
297 #if ENABLE(ASSERT) 298 #if ENABLE(ASSERT)
298 m_hasBeenDisposed = true; 299 m_hasBeenDisposed = true;
(...skipping 2070 matching lines...) Expand 10 before | Expand all | Expand 10 after
2369 isUpdatingAllLifecyclePhasesScope.emplace(m_isUpdatingAllLifecyclePhases , true); 2370 isUpdatingAllLifecyclePhasesScope.emplace(m_isUpdatingAllLifecyclePhases , true);
2370 2371
2371 // This must be called from the root frame, since it recurses down, not up. 2372 // This must be called from the root frame, since it recurses down, not up.
2372 // Otherwise the lifecycles of the frames might be out of sync. 2373 // Otherwise the lifecycles of the frames might be out of sync.
2373 ASSERT(m_frame->isLocalRoot()); 2374 ASSERT(m_frame->isLocalRoot());
2374 2375
2375 // Updating layout can run script, which can tear down the FrameView. 2376 // Updating layout can run script, which can tear down the FrameView.
2376 RefPtrWillBeRawPtr<FrameView> protector(this); 2377 RefPtrWillBeRawPtr<FrameView> protector(this);
2377 2378
2378 if (shouldThrottleRendering()) { 2379 if (shouldThrottleRendering()) {
2379 updateViewportIntersectionsForSubtree(); 2380 updateViewportIntersectionsForSubtree(std::min(phases, OnlyUpToCompositi ngCleanPlusScrolling));
2380 return; 2381 return;
2381 } 2382 }
2382 2383
2383 updateStyleAndLayoutIfNeededRecursive(); 2384 updateStyleAndLayoutIfNeededRecursive();
2384 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean); 2385 ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean);
2385 2386
2386 if (phases == OnlyUpToLayoutClean) { 2387 if (phases == OnlyUpToLayoutClean) {
2387 updateViewportIntersectionsForSubtree(); 2388 updateViewportIntersectionsForSubtree(phases);
2388 return; 2389 return;
2389 } 2390 }
2390 2391
2391 if (LayoutView* view = layoutView()) { 2392 if (LayoutView* view = layoutView()) {
2392 { 2393 {
2393 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", Inspect orUpdateLayerTreeEvent::data(m_frame.get())); 2394 TRACE_EVENT1("devtools.timeline", "UpdateLayerTree", "data", Inspect orUpdateLayerTreeEvent::data(m_frame.get()));
2394 2395
2395 // This was required for slimming paint v1 but is only temporarily 2396 // This was required for slimming paint v1 but is only temporarily
2396 // needed for slimming paint v2. 2397 // needed for slimming paint v2.
2397 view->compositor()->updateIfNeededRecursive(); 2398 view->compositor()->updateIfNeededRecursive();
(...skipping 23 matching lines...) Expand all
2421 2422
2422 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled()) 2423 if (RuntimeEnabledFeatures::slimmingPaintV2Enabled())
2423 pushPaintArtifactToCompositor(); 2424 pushPaintArtifactToCompositor();
2424 2425
2425 ASSERT(!view->hasPendingSelection()); 2426 ASSERT(!view->hasPendingSelection());
2426 ASSERT((m_frame->document()->printing() && lifecycle().state() == Do cumentLifecycle::PaintInvalidationClean) 2427 ASSERT((m_frame->document()->printing() && lifecycle().state() == Do cumentLifecycle::PaintInvalidationClean)
2427 || lifecycle().state() == DocumentLifecycle::PaintClean); 2428 || lifecycle().state() == DocumentLifecycle::PaintClean);
2428 } 2429 }
2429 } 2430 }
2430 2431
2431 updateViewportIntersectionsForSubtree(); 2432 updateViewportIntersectionsForSubtree(phases);
2432 } 2433 }
2433 2434
2434 void FrameView::updatePaintProperties() 2435 void FrameView::updatePaintProperties()
2435 { 2436 {
2436 TRACE_EVENT0("blink", "FrameView::updatePaintProperties"); 2437 TRACE_EVENT0("blink", "FrameView::updatePaintProperties");
2437 2438
2438 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled()); 2439 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
2439 2440
2440 forAllNonThrottledFrameViews([](FrameView& frameView) { frameView.lifecycle( ).advanceTo(DocumentLifecycle::InUpdatePaintProperties); }); 2441 forAllNonThrottledFrameViews([](FrameView& frameView) { frameView.lifecycle( ).advanceTo(DocumentLifecycle::InUpdatePaintProperties); });
2441 PaintPropertyTreeBuilder().buildPropertyTrees(*this); 2442 PaintPropertyTreeBuilder().buildPropertyTrees(*this);
(...skipping 1482 matching lines...) Expand 10 before | Expand all | Expand 10 after
3924 3925
3925 void FrameView::setNeedsUpdateViewportIntersection() 3926 void FrameView::setNeedsUpdateViewportIntersection()
3926 { 3927 {
3927 m_needsUpdateViewportIntersection = true; 3928 m_needsUpdateViewportIntersection = true;
3928 for (FrameView* parent = parentFrameView(); parent; parent = parent->parentF rameView()) 3929 for (FrameView* parent = parentFrameView(); parent; parent = parent->parentF rameView())
3929 parent->m_needsUpdateViewportIntersectionInSubtree = true; 3930 parent->m_needsUpdateViewportIntersectionInSubtree = true;
3930 } 3931 }
3931 3932
3932 void FrameView::updateViewportIntersectionIfNeeded() 3933 void FrameView::updateViewportIntersectionIfNeeded()
3933 { 3934 {
3934 // TODO(skyostil): Replace this with a real intersection observer.
3935 if (!m_needsUpdateViewportIntersection) 3935 if (!m_needsUpdateViewportIntersection)
3936 return; 3936 return;
3937 m_needsUpdateViewportIntersection = false; 3937 m_needsUpdateViewportIntersection = false;
3938 m_viewportIntersectionValid = true; 3938 m_viewportIntersectionValid = true;
3939
3940 FrameView* parent = parentFrameView(); 3939 FrameView* parent = parentFrameView();
3941 if (!parent) { 3940 if (!parent) {
3942 m_viewportIntersection = frameRect(); 3941 m_viewportIntersection = frameRect();
3943 return; 3942 return;
3944 } 3943 }
3945 ASSERT(!parent->m_needsUpdateViewportIntersection); 3944 ASSERT(!parent->m_needsUpdateViewportIntersection);
3946 3945
3947 // If our parent is hidden, then we are too. 3946 // If our parent is hidden, then we are too.
3948 if (parent->m_viewportIntersection.isEmpty()) { 3947 if (parent->m_viewportIntersection.isEmpty()) {
3949 m_viewportIntersection = parent->m_viewportIntersection; 3948 m_viewportIntersection = parent->m_viewportIntersection;
3950 return; 3949 return;
3951 } 3950 }
3952 3951
3953 // Transform our bounds into the root frame's content coordinate space, 3952 // Transform our bounds into the root frame's content coordinate space,
3954 // making sure we have valid layout data in our parent document. If our 3953 // making sure we have valid layout data in our parent document. If our
3955 // parent is throttled, we'll use possible stale layout information and 3954 // parent is throttled, we'll use possible stale layout information and
3956 // rely on the fact that another lifecycle update will be scheduled once 3955 // rely on the fact that another lifecycle update will be scheduled once
3957 // our parent becomes unthrottled. 3956 // our parent becomes unthrottled.
3958 ASSERT(parent->lifecycle().state() >= DocumentLifecycle::LayoutClean || pare nt->shouldThrottleRendering()); 3957 ASSERT(parent->lifecycle().state() >= DocumentLifecycle::LayoutClean || pare nt->shouldThrottleRendering());
3959 m_viewportIntersection = parent->contentsToRootFrame(frameRect()); 3958 m_viewportIntersection = parent->contentsToRootFrame(frameRect());
3960 3959
3961 // TODO(skyostil): Expand the viewport to make it less likely to see stale c ontent while scrolling. 3960 // TODO(skyostil): Expand the viewport to make it less likely to see stale c ontent while scrolling.
3962 IntRect viewport = parent->m_viewportIntersection; 3961 IntRect viewport = parent->m_viewportIntersection;
3963 m_viewportIntersection.intersect(viewport); 3962 m_viewportIntersection.intersect(viewport);
3964 } 3963 }
3965 3964
3966 void FrameView::updateViewportIntersectionsForSubtree() 3965 void FrameView::updateViewportIntersectionsForSubtree(LifeCycleUpdateOption phas es)
3967 { 3966 {
3968 bool hadValidIntersection = m_viewportIntersectionValid; 3967 bool hadValidIntersection = m_viewportIntersectionValid;
3969 bool hadEmptyIntersection = m_viewportIntersection.isEmpty(); 3968 bool hadEmptyIntersection = m_viewportIntersection.isEmpty();
3970 updateViewportIntersectionIfNeeded(); 3969 updateViewportIntersectionIfNeeded();
3970
3971 // Notify javascript IntersectionObservers
3972 if (phases == AllPhases)
3973 frame().document()->ensureIntersectionObserverController().computeTracke dIntersectionObservations();
3974
3975 // Adjust render throttling for iframes based on visibility
3971 bool shouldNotify = !hadValidIntersection || hadEmptyIntersection != m_viewp ortIntersection.isEmpty(); 3976 bool shouldNotify = !hadValidIntersection || hadEmptyIntersection != m_viewp ortIntersection.isEmpty();
3972 if (shouldNotify && !m_intersectionObserverNotificationFactory->isPending()) 3977 if (shouldNotify && !m_renderThrottlingObserverNotificationFactory->isPendin g())
3973 m_frame->frameScheduler()->timerTaskRunner()->postTask(BLINK_FROM_HERE, m_intersectionObserverNotificationFactory->cancelAndCreate()); 3978 m_frame->frameScheduler()->timerTaskRunner()->postTask(BLINK_FROM_HERE, m_renderThrottlingObserverNotificationFactory->cancelAndCreate());
3974 3979
3975 if (!m_needsUpdateViewportIntersectionInSubtree) 3980 if (!m_needsUpdateViewportIntersectionInSubtree)
3976 return; 3981 return;
3977 m_needsUpdateViewportIntersectionInSubtree = false; 3982 m_needsUpdateViewportIntersectionInSubtree = false;
3978 3983
3979 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) { 3984 for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree ().nextSibling()) {
3980 if (!child->isLocalFrame()) 3985 if (!child->isLocalFrame())
3981 continue; 3986 continue;
3982 if (FrameView* view = toLocalFrame(child)->view()) 3987 if (FrameView* view = toLocalFrame(child)->view())
3983 view->updateViewportIntersectionsForSubtree(); 3988 view->updateViewportIntersectionsForSubtree(phases);
3984 } 3989 }
3985 } 3990 }
3986 3991
3987 void FrameView::notifyIntersectionObservers() 3992 void FrameView::notifyRenderThrottlingObservers()
3988 { 3993 {
3989 TRACE_EVENT0("blink", "FrameView::notifyIntersectionObservers"); 3994 TRACE_EVENT0("blink", "FrameView::notifyRenderThrottlingObservers");
3990 ASSERT(!isInPerformLayout()); 3995 ASSERT(!isInPerformLayout());
3991 ASSERT(!m_frame->document()->inStyleRecalc()); 3996 ASSERT(!m_frame->document()->inStyleRecalc());
3992 bool wasThrottled = canThrottleRendering(); 3997 bool wasThrottled = canThrottleRendering();
3993 3998
3994 // Only offscreen frames can be throttled. 3999 // Only offscreen frames can be throttled.
3995 m_hiddenForThrottling = m_viewportIntersectionValid && m_viewportIntersectio n.isEmpty(); 4000 m_hiddenForThrottling = m_viewportIntersectionValid && m_viewportIntersectio n.isEmpty();
3996 4001
3997 // We only throttle the rendering pipeline in cross-origin frames. This is 4002 // We only throttle the rendering pipeline in cross-origin frames. This is
3998 // to avoid a situation where an ancestor frame directly depends on the 4003 // to avoid a situation where an ancestor frame directly depends on the
3999 // pipeline timing of a descendant and breaks as a result of throttling. 4004 // pipeline timing of a descendant and breaks as a result of throttling.
(...skipping 29 matching lines...) Expand all
4029 return m_hiddenForThrottling && m_crossOriginForThrottling; 4034 return m_hiddenForThrottling && m_crossOriginForThrottling;
4030 } 4035 }
4031 4036
4032 LayoutBox& FrameView::boxForScrollControlPaintInvalidation() const 4037 LayoutBox& FrameView::boxForScrollControlPaintInvalidation() const
4033 { 4038 {
4034 ASSERT(layoutView()); 4039 ASSERT(layoutView());
4035 return *layoutView(); 4040 return *layoutView();
4036 } 4041 }
4037 4042
4038 } // namespace blink 4043 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698