Chromium Code Reviews| 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 26fe2ecfdbbe9437d9efcd4d505b9d13e67f5e28..ddb9b6a5c821c9aaa5345a0819f44564f84edcef 100644 |
| --- a/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp |
| +++ b/third_party/WebKit/Source/core/dom/IntersectionObserver.cpp |
| @@ -28,7 +28,40 @@ |
| namespace blink { |
| -static void parseRootMargin(String rootMarginParameter, Vector<Length>& rootMargin, ExceptionState& exceptionState) |
| +namespace { |
| + |
| +// Internal implementation of IntersectionObserverCallback when using |
| +// IntersectionObserver with an EventCallback. |
| +class IntersectionObserverCallbackImpl final : public IntersectionObserverCallback { |
| + WTF_MAKE_NONCOPYABLE(IntersectionObserverCallbackImpl); |
| +public: |
| + IntersectionObserverCallbackImpl(ExecutionContext* context, std::unique_ptr<IntersectionObserver::EventCallback> callback) |
| + : m_context(context) |
| + , m_callback(std::move(callback)) |
| + {} |
| + |
| + void handleEvent(const HeapVector<Member<IntersectionObserverEntry>>& entries, IntersectionObserver&) override |
| + { |
| + (*m_callback.get())(entries); |
| + } |
| + |
| + ExecutionContext* getExecutionContext() const override |
| + { |
| + return m_context; |
| + } |
| + |
| + DEFINE_INLINE_TRACE() |
| + { |
| + IntersectionObserverCallback::trace(visitor); |
| + visitor->trace(m_context); |
| + } |
| + |
| +private: |
| + Member<ExecutionContext> m_context; |
|
szager1
2016/06/21 21:18:05
WeakMember<ExecutionContext> m_context;
mlamouri (slow - plz ping)
2016/06/21 21:25:50
Done.
|
| + std::unique_ptr<IntersectionObserver::EventCallback> m_callback; |
| +}; |
| + |
| +void parseRootMargin(String rootMarginParameter, Vector<Length>& rootMargin, ExceptionState& exceptionState) |
| { |
| // TODO(szager): Make sure this exact syntax and behavior is spec-ed somewhere. |
| @@ -66,7 +99,7 @@ static void parseRootMargin(String rootMarginParameter, Vector<Length>& rootMarg |
| } |
| } |
| -static void parseThresholds(const DoubleOrDoubleArray& thresholdParameter, Vector<float>& thresholds, ExceptionState& exceptionState) |
| +void parseThresholds(const DoubleOrDoubleArray& thresholdParameter, Vector<float>& thresholds, ExceptionState& exceptionState) |
| { |
| if (thresholdParameter.isDouble()) { |
| thresholds.append(static_cast<float>(thresholdParameter.getAsDouble())); |
| @@ -85,16 +118,26 @@ static void parseThresholds(const DoubleOrDoubleArray& thresholdParameter, Vecto |
| std::sort(thresholds.begin(), thresholds.end()); |
| } |
| +// Returns the root Node of a given Document to use as the IntersectionObserver |
| +// root when no root is given. |
| +// TODO(szager): it doesn't support RemoteFrames, see https://crbug.com/615156 |
| +Node* getRootNode(Document* document) |
| +{ |
| + Frame* mainFrame = document->frame()->tree().top(); |
| + if (mainFrame && mainFrame->isLocalFrame()) |
| + return toLocalFrame(mainFrame)->document(); |
| + return nullptr; |
| +} |
| + |
| +} // anonymous namespace |
| + |
| IntersectionObserver* IntersectionObserver::create(const IntersectionObserverInit& observerInit, IntersectionObserverCallback& callback, ExceptionState& exceptionState) |
| { |
| Node* root = observerInit.root(); |
| if (!root) { |
| - // TODO(szager): Use Document instead of document element for implicit root. (crbug.com/570538) |
| ExecutionContext* context = callback.getExecutionContext(); |
| DCHECK(context->isDocument()); |
| - Frame* mainFrame = toDocument(context)->frame()->tree().top(); |
| - if (mainFrame && mainFrame->isLocalFrame()) |
| - root = toLocalFrame(mainFrame)->document(); |
| + root = getRootNode(toDocument(context)); |
| } |
| if (!root) { |
| exceptionState.throwDOMException(HierarchyRequestError, "Unable to get root node in main frame to track."); |
| @@ -118,6 +161,16 @@ IntersectionObserver* IntersectionObserver::create(const IntersectionObserverIni |
| return new IntersectionObserver(callback, *root, rootMargin, thresholds); |
| } |
| +IntersectionObserver* IntersectionObserver::create(const Vector<Length>& rootMargin, const Vector<float>& thresholds, Document* document, std::unique_ptr<EventCallback> callback) |
| +{ |
| + Node* root = getRootNode(document); |
| + if (!root) |
| + return nullptr; |
| + |
| + IntersectionObserverCallbackImpl* intersectionObserverCallback = new IntersectionObserverCallbackImpl(document, std::move(callback)); |
| + return new IntersectionObserver(*intersectionObserverCallback, *root, rootMargin, thresholds); |
| +} |
| + |
| IntersectionObserver::IntersectionObserver(IntersectionObserverCallback& callback, Node& root, const Vector<Length>& rootMargin, const Vector<float>& thresholds) |
| : m_callback(&callback) |
| , m_root(&root) |
| @@ -184,7 +237,6 @@ void IntersectionObserver::observe(Element* target, ExceptionState& exceptionSta |
| if (target->ensureIntersectionObserverData().getObservationFor(*this)) |
| return; |
| - |
| bool shouldReportRootBounds = false; |
| bool isDOMDescendant = false; |
| LocalFrame* targetFrame = target->document().frame(); |
| @@ -340,7 +392,6 @@ unsigned IntersectionObserver::firstThresholdGreaterThan(float ratio) const |
| void IntersectionObserver::deliver() |
| { |
| - |
| if (m_entries.isEmpty()) |
| return; |