| 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 2a9cd6f082099d2d6f1c4e72da891af2950a7052..b29b69e8b46ed857ca07cd7f76d5b958fd182fe6 100644
|
| --- a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
|
| +++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp
|
| @@ -186,6 +186,7 @@
|
|
|
| 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;
|
| @@ -220,6 +221,7 @@
|
|
|
| void IntersectionObserver::unobserve(Element* target, ExceptionState&)
|
| {
|
| + checkRootAndDetachIfNeeded();
|
| if (!target || !target->intersectionObserverData())
|
| return;
|
| // TODO(szager): unobserve callback
|
| @@ -229,6 +231,7 @@
|
|
|
| void IntersectionObserver::computeIntersectionObservations(double timestamp)
|
| {
|
| + checkRootAndDetachIfNeeded();
|
| if (!m_root)
|
| return;
|
| for (auto& observation : m_observations)
|
| @@ -251,6 +254,7 @@
|
|
|
| HeapVector<Member<IntersectionObserverEntry>> IntersectionObserver::takeRecords()
|
| {
|
| + checkRootAndDetachIfNeeded();
|
| HeapVector<Member<IntersectionObserverEntry>> entries;
|
| entries.swap(m_entries);
|
| return entries;
|
| @@ -295,6 +299,8 @@
|
|
|
| void IntersectionObserver::deliver()
|
| {
|
| + checkRootAndDetachIfNeeded();
|
| +
|
| if (m_entries.isEmpty())
|
| return;
|
|
|
| @@ -305,6 +311,7 @@
|
|
|
| void IntersectionObserver::setActive(bool active)
|
| {
|
| + checkRootAndDetachIfNeeded();
|
| for (auto& observation : m_observations)
|
| observation->setActive(m_root && active && isDescendantOfRoot(observation->target()));
|
| }
|
| @@ -317,17 +324,25 @@
|
| || m_leftMargin.type() == Percent);
|
| }
|
|
|
| -void IntersectionObserver::rootDisappearedCallback(Visitor* visitor, void* self)
|
| -{
|
| - IntersectionObserver* observer = static_cast<IntersectionObserver*>(self);
|
| - observer->disconnect();
|
| +void IntersectionObserver::checkRootAndDetachIfNeeded()
|
| +{
|
| +#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();
|
| +#endif
|
| }
|
|
|
| DEFINE_TRACE(IntersectionObserver)
|
| {
|
| -#if ENABLE(OILPAN)
|
| - visitor->registerWeakMembers(this, m_root.get(), IntersectionObserver::rootDisappearedCallback);
|
| -#endif
|
| visitor->trace(m_callback);
|
| visitor->trace(m_root);
|
| visitor->trace(m_observations);
|
|
|