| Index: third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
|
| diff --git a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
|
| index b29b69e8b46ed857ca07cd7f76d5b958fd182fe6..efe97c99ee3066dda6863f074657f1b085ef15d1 100644
|
| --- a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
|
| +++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
|
| @@ -152,6 +152,16 @@ IntersectionObserver::IntersectionObserver(IntersectionObserverCallback& callbac
|
| root.document().ensureIntersectionObserverController().addTrackedObserver(*this);
|
| }
|
|
|
| +#if ENABLE(OILPAN)
|
| +void IntersectionObserver::clearWeakMembers(Visitor* visitor)
|
| +{
|
| + if (Heap::isHeapObjectAlive(m_root))
|
| + return;
|
| + disconnect();
|
| + m_root = nullptr;
|
| +}
|
| +#endif
|
| +
|
| LayoutObject* IntersectionObserver::rootLayoutObject() const
|
| {
|
| Node* rootNode = root();
|
| @@ -186,7 +196,6 @@ bool IntersectionObserver::isDescendantOfRoot(const Element* target) const
|
|
|
| void IntersectionObserver::observe(Element* target, ExceptionState& exceptionState)
|
| {
|
| - checkRootAndDetachIfNeeded();
|
| if (!m_root) {
|
| exceptionState.throwDOMException(HierarchyRequestError, "Invalid observer: root element or containing document has been deleted.");
|
| return;
|
| @@ -221,7 +230,6 @@ void IntersectionObserver::observe(Element* target, ExceptionState& exceptionSta
|
|
|
| void IntersectionObserver::unobserve(Element* target, ExceptionState&)
|
| {
|
| - checkRootAndDetachIfNeeded();
|
| if (!target || !target->intersectionObserverData())
|
| return;
|
| // TODO(szager): unobserve callback
|
| @@ -231,7 +239,6 @@ void IntersectionObserver::unobserve(Element* target, ExceptionState&)
|
|
|
| void IntersectionObserver::computeIntersectionObservations(double timestamp)
|
| {
|
| - checkRootAndDetachIfNeeded();
|
| if (!m_root)
|
| return;
|
| for (auto& observation : m_observations)
|
| @@ -240,11 +247,9 @@ void IntersectionObserver::computeIntersectionObservations(double timestamp)
|
|
|
| void IntersectionObserver::disconnect()
|
| {
|
| - HeapVector<Member<IntersectionObservation>> observationsToDisconnect;
|
| - copyToVector(m_observations, observationsToDisconnect);
|
| - for (auto& observation : observationsToDisconnect)
|
| - observation->disconnect();
|
| - ASSERT(m_observations.isEmpty());
|
| + for (auto& observation : m_observations)
|
| + observation->clearRootAndRemoveFromTarget();
|
| + m_observations.clear();
|
| }
|
|
|
| void IntersectionObserver::removeObservation(IntersectionObservation& observation)
|
| @@ -254,7 +259,6 @@ void IntersectionObserver::removeObservation(IntersectionObservation& observatio
|
|
|
| HeapVector<Member<IntersectionObserverEntry>> IntersectionObserver::takeRecords()
|
| {
|
| - checkRootAndDetachIfNeeded();
|
| HeapVector<Member<IntersectionObserverEntry>> entries;
|
| entries.swap(m_entries);
|
| return entries;
|
| @@ -299,7 +303,6 @@ unsigned IntersectionObserver::firstThresholdGreaterThan(float ratio) const
|
|
|
| void IntersectionObserver::deliver()
|
| {
|
| - checkRootAndDetachIfNeeded();
|
|
|
| if (m_entries.isEmpty())
|
| return;
|
| @@ -311,7 +314,6 @@ void IntersectionObserver::deliver()
|
|
|
| void IntersectionObserver::setActive(bool active)
|
| {
|
| - checkRootAndDetachIfNeeded();
|
| for (auto& observation : m_observations)
|
| observation->setActive(m_root && active && isDescendantOfRoot(observation->target()));
|
| }
|
| @@ -324,27 +326,12 @@ bool IntersectionObserver::hasPercentMargin() const
|
| || m_leftMargin.type() == Percent);
|
| }
|
|
|
| -void IntersectionObserver::checkRootAndDetachIfNeeded()
|
| +DEFINE_TRACE(IntersectionObserver)
|
| {
|
| #if ENABLE(OILPAN)
|
| - // TODO(szager): Pre-oilpan, ElementIntersectionObserverData::dispose() will take
|
| - // care of this cleanup. When oilpan ships, there will be a potential leak of the
|
| - // callback's execution context when the root goes away. For a detailed explanation:
|
| - //
|
| - // https://goo.gl/PC2Baj
|
| - //
|
| - // When that happens, this method should catch most potential leaks, but a complete
|
| - // solution will still be needed, along the lines described in the above link.
|
| - if (m_root)
|
| - return;
|
| - disconnect();
|
| + visitor->template registerWeakMembers<IntersectionObserver, &IntersectionObserver::clearWeakMembers>(this);
|
| #endif
|
| -}
|
| -
|
| -DEFINE_TRACE(IntersectionObserver)
|
| -{
|
| visitor->trace(m_callback);
|
| - visitor->trace(m_root);
|
| visitor->trace(m_observations);
|
| visitor->trace(m_entries);
|
| }
|
|
|