| 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();
 | 
| 
 |