| Index: third_party/WebKit/Source/core/frame/FrameView.cpp | 
| diff --git a/third_party/WebKit/Source/core/frame/FrameView.cpp b/third_party/WebKit/Source/core/frame/FrameView.cpp | 
| index b82860ff65525863deba00c831cd2d48853c6f32..f2cfc11833f31633f82bfb1d45b7137d1c2b716e 100644 | 
| --- a/third_party/WebKit/Source/core/frame/FrameView.cpp | 
| +++ b/third_party/WebKit/Source/core/frame/FrameView.cpp | 
| @@ -32,6 +32,7 @@ | 
| #include "core/css/resolver/StyleResolver.h" | 
| #include "core/dom/AXObjectCache.h" | 
| #include "core/dom/Fullscreen.h" | 
| +#include "core/dom/IntersectionObserverController.h" | 
| #include "core/editing/EditingUtilities.h" | 
| #include "core/editing/FrameSelection.h" | 
| #include "core/editing/RenderedPosition.h" | 
| @@ -120,7 +121,7 @@ FrameView::FrameView(LocalFrame* frame) | 
| , m_inSynchronousPostLayout(false) | 
| , m_postLayoutTasksTimer(this, &FrameView::postLayoutTimerFired) | 
| , m_updateWidgetsTimer(this, &FrameView::updateWidgetsTimerFired) | 
| -    , m_intersectionObserverNotificationFactory(CancellableTaskFactory::create(this, &FrameView::notifyIntersectionObservers)) | 
| +    , m_renderThrottlingObserverNotificationFactory(CancellableTaskFactory::create(this, &FrameView::notifyRenderThrottlingObservers)) | 
| , m_isTransparent(false) | 
| , m_baseBackgroundColor(Color::white) | 
| , m_mediaType(MediaTypeNames::screen) | 
| @@ -285,7 +286,7 @@ void FrameView::dispose() | 
|  | 
| if (m_didScrollTimer.isActive()) | 
| m_didScrollTimer.stop(); | 
| -    m_intersectionObserverNotificationFactory->cancel(); | 
| +    m_renderThrottlingObserverNotificationFactory->cancel(); | 
|  | 
| // FIXME: Do we need to do something here for OOPI? | 
| HTMLFrameOwnerElement* ownerElement = m_frame->deprecatedLocalOwner(); | 
| @@ -2376,7 +2377,7 @@ void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases) | 
| RefPtrWillBeRawPtr<FrameView> protector(this); | 
|  | 
| if (shouldThrottleRendering()) { | 
| -        updateViewportIntersectionsForSubtree(); | 
| +        updateViewportIntersectionsForSubtree(std::min(phases, OnlyUpToCompositingCleanPlusScrolling)); | 
| return; | 
| } | 
|  | 
| @@ -2384,7 +2385,7 @@ void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases) | 
| ASSERT(lifecycle().state() >= DocumentLifecycle::LayoutClean); | 
|  | 
| if (phases == OnlyUpToLayoutClean) { | 
| -        updateViewportIntersectionsForSubtree(); | 
| +        updateViewportIntersectionsForSubtree(phases); | 
| return; | 
| } | 
|  | 
| @@ -2428,7 +2429,7 @@ void FrameView::updateLifecyclePhasesInternal(LifeCycleUpdateOption phases) | 
| } | 
| } | 
|  | 
| -    updateViewportIntersectionsForSubtree(); | 
| +    updateViewportIntersectionsForSubtree(phases); | 
| } | 
|  | 
| void FrameView::updatePaintProperties() | 
| @@ -3931,12 +3932,10 @@ void FrameView::setNeedsUpdateViewportIntersection() | 
|  | 
| void FrameView::updateViewportIntersectionIfNeeded() | 
| { | 
| -    // TODO(skyostil): Replace this with a real intersection observer. | 
| if (!m_needsUpdateViewportIntersection) | 
| return; | 
| m_needsUpdateViewportIntersection = false; | 
| m_viewportIntersectionValid = true; | 
| - | 
| FrameView* parent = parentFrameView(); | 
| if (!parent) { | 
| m_viewportIntersection = frameRect(); | 
| @@ -3963,14 +3962,20 @@ void FrameView::updateViewportIntersectionIfNeeded() | 
| m_viewportIntersection.intersect(viewport); | 
| } | 
|  | 
| -void FrameView::updateViewportIntersectionsForSubtree() | 
| +void FrameView::updateViewportIntersectionsForSubtree(LifeCycleUpdateOption phases) | 
| { | 
| bool hadValidIntersection = m_viewportIntersectionValid; | 
| bool hadEmptyIntersection = m_viewportIntersection.isEmpty(); | 
| updateViewportIntersectionIfNeeded(); | 
| + | 
| +    // Notify javascript IntersectionObservers | 
| +    if (phases == AllPhases) | 
| +        frame().document()->ensureIntersectionObserverController().computeTrackedIntersectionObservations(); | 
| + | 
| +    // Adjust render throttling for iframes based on visibility | 
| bool shouldNotify = !hadValidIntersection || hadEmptyIntersection != m_viewportIntersection.isEmpty(); | 
| -    if (shouldNotify && !m_intersectionObserverNotificationFactory->isPending()) | 
| -        m_frame->frameScheduler()->timerTaskRunner()->postTask(BLINK_FROM_HERE, m_intersectionObserverNotificationFactory->cancelAndCreate()); | 
| +    if (shouldNotify && !m_renderThrottlingObserverNotificationFactory->isPending()) | 
| +        m_frame->frameScheduler()->timerTaskRunner()->postTask(BLINK_FROM_HERE, m_renderThrottlingObserverNotificationFactory->cancelAndCreate()); | 
|  | 
| if (!m_needsUpdateViewportIntersectionInSubtree) | 
| return; | 
| @@ -3980,13 +3985,13 @@ void FrameView::updateViewportIntersectionsForSubtree() | 
| if (!child->isLocalFrame()) | 
| continue; | 
| if (FrameView* view = toLocalFrame(child)->view()) | 
| -            view->updateViewportIntersectionsForSubtree(); | 
| +            view->updateViewportIntersectionsForSubtree(phases); | 
| } | 
| } | 
|  | 
| -void FrameView::notifyIntersectionObservers() | 
| +void FrameView::notifyRenderThrottlingObservers() | 
| { | 
| -    TRACE_EVENT0("blink", "FrameView::notifyIntersectionObservers"); | 
| +    TRACE_EVENT0("blink", "FrameView::notifyRenderThrottlingObservers"); | 
| ASSERT(!isInPerformLayout()); | 
| ASSERT(!m_frame->document()->inStyleRecalc()); | 
| bool wasThrottled = canThrottleRendering(); | 
|  |