Chromium Code Reviews| Index: third_party/WebKit/Source/core/dom/ElementVisibilityObserver.cpp |
| diff --git a/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.cpp b/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.cpp |
| index 8c4ecab9c24d74549216268dbf9a3f38e3310e9a..ec25f71a02e02c705d3b4d8301aab0e908e9cc6f 100644 |
| --- a/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.cpp |
| +++ b/third_party/WebKit/Source/core/dom/ElementVisibilityObserver.cpp |
| @@ -21,12 +21,34 @@ bool isInRemoteFrame(const Document& document) { |
| } // anonymous namespace |
| +VisibilityObserverBase::VisibilityObserverBase(Element* element) |
| + : m_element(element) {} |
| + |
| +VisibilityObserverBase::~VisibilityObserverBase() {} |
| + |
| +void VisibilityObserverBase::stop() { |
| + // TODO(zqzhang): IntersectionObserver does not work for RemoteFrame, |
| + // so |m_intersectionObserver| may be null at this point after start(). |
| + // Replace this early return with DCHECK when this has been fixed. See |
| + // https://crbug.com/615156 |
| + if (!m_intersectionObserver) |
| + return; |
| + |
| + m_intersectionObserver->disconnect(); |
| + m_intersectionObserver = nullptr; |
| +} |
| + |
| +DEFINE_TRACE(VisibilityObserverBase) { |
| + visitor->trace(m_element); |
| + visitor->trace(m_intersectionObserver); |
| +} |
| + |
| ElementVisibilityObserver::ElementVisibilityObserver( |
| Element* element, |
| std::unique_ptr<VisibilityCallback> callback) |
| - : m_element(element), m_callback(std::move(callback)) {} |
| + : VisibilityObserverBase(element), m_callback(std::move(callback)) {} |
| -ElementVisibilityObserver::~ElementVisibilityObserver() = default; |
| +ElementVisibilityObserver::~ElementVisibilityObserver() {} |
| void ElementVisibilityObserver::start() { |
| ExecutionContext* context = m_element->getExecutionContext(); |
| @@ -51,31 +73,64 @@ void ElementVisibilityObserver::start() { |
| m_intersectionObserver->observe(m_element.release()); |
| } |
| -void ElementVisibilityObserver::stop() { |
| - // TODO(zqzhang): IntersectionObserver does not work for RemoteFrame, |
| - // so |m_intersectionObserver| may be null at this point after start(). |
| - // Replace this early return with DCHECK when this has been fixed. See |
| - // https://crbug.com/615156 |
| - if (!m_intersectionObserver) |
| - return; |
| - |
| - m_intersectionObserver->disconnect(); |
| - m_intersectionObserver = nullptr; |
| -} |
| - |
| void ElementVisibilityObserver::deliverObservationsForTesting() { |
| m_intersectionObserver->deliver(); |
| } |
| -DEFINE_TRACE(ElementVisibilityObserver) { |
| - visitor->trace(m_element); |
| - visitor->trace(m_intersectionObserver); |
| -} |
| - |
| void ElementVisibilityObserver::onVisibilityChanged( |
| const HeapVector<Member<IntersectionObserverEntry>>& entries) { |
| bool isVisible = entries.last()->intersectionRatio() > 0.f; |
| (*m_callback.get())(isVisible); |
| } |
| +ViewportIntersectionObserver::ViewportIntersectionObserver( |
| + Element* element, |
| + std::unique_ptr<RatioChangeCallback> callback) |
| + : VisibilityObserverBase(element), m_callback(std::move(callback)) {} |
| + |
| +ViewportIntersectionObserver::~ViewportIntersectionObserver() {} |
| + |
| +void ViewportIntersectionObserver::start() { |
| + ExecutionContext* context = m_element->getExecutionContext(); |
| + DCHECK(context->isDocument()); |
| + Document& document = toDocument(*context); |
| + |
| + // TODO(zqzhang): IntersectionObserver does not work for RemoteFrame. |
| + // Remove this early return when it's fixed. See https://crbug.com/615156 |
| + if (isInRemoteFrame(document)) { |
| + m_element.release(); |
| + return; |
| + } |
| + |
| + DCHECK(!m_intersectionObserver); |
| + m_intersectionObserver = IntersectionObserver::create( |
| + Vector<Length>(), &document, |
| + WTF::bind(&ViewportIntersectionObserver::onVisibilityChanged, |
| + wrapWeakPersistent(this))); |
| + DCHECK(m_intersectionObserver); |
| + m_intersectionObserver->setInitialState( |
| + IntersectionObserver::InitialState::kAuto); |
| + m_intersectionObserver->observe(m_element.release()); |
| +} |
| + |
| +void ViewportIntersectionObserver::onVisibilityChanged( |
| + const HeapVector<Member<IntersectionObserverEntry>>& entries) { |
| + IntersectionObserverEntry* entry = entries.last(); |
| + WebRect rootRect; |
| + if (entry && entry->rootBounds()) { |
| + rootRect = |
| + WebRect(entry->rootBounds()->top(), entry->rootBounds()->left(), |
|
miu
2016/11/16 02:40:26
Please fix: top() and left() are reversed.
xjz
2016/11/16 07:45:55
Done. Thanks for pointing this out!
|
| + entry->rootBounds()->width(), entry->rootBounds()->height()); |
| + } |
| + WebRect intersectRect; |
| + if (entry && entry->intersectionRect()) { |
| + intersectRect = WebRect(entry->intersectionRect()->top(), |
|
miu
2016/11/16 02:40:26
ditto: top() and left() are reversed.
xjz
2016/11/16 07:45:55
Done.
|
| + entry->intersectionRect()->left(), |
| + entry->intersectionRect()->width(), |
| + entry->intersectionRect()->height()); |
| + } |
| + |
| + (*m_callback.get())(rootRect, intersectRect); |
| +} |
| + |
| } // namespace blink |