Index: third_party/WebKit/Source/core/observer/ResizeObserver.cpp |
diff --git a/third_party/WebKit/Source/core/observer/ResizeObserver.cpp b/third_party/WebKit/Source/core/observer/ResizeObserver.cpp |
index f285e0d3e4147e6f762f7e06f56271d36e5afa32..3d567e19afdb4fc56ba60bbbdb5211aa526f3aa8 100644 |
--- a/third_party/WebKit/Source/core/observer/ResizeObserver.cpp |
+++ b/third_party/WebKit/Source/core/observer/ResizeObserver.cpp |
@@ -20,6 +20,8 @@ ResizeObserver* ResizeObserver::create(Document& document, ResizeObserverCallbac |
ResizeObserver::ResizeObserver(ResizeObserverCallback* callback, Document& document) |
: m_callback(callback) |
+ , m_skippedObservations(false) |
+ , m_elementSizeChanged(false) |
{ |
m_controller = &document.ensureResizeObserverController(); |
m_controller->addObserver(*this); |
@@ -56,17 +58,72 @@ void ResizeObserver::disconnect() |
ObservationList observations; |
m_observations.swap(observations); |
- for (auto observation : observations) { |
+ for (auto& observation : observations) { |
Element* target = (*observation).target(); |
if (target) |
target->ensureResizeObserverData().remove(this); |
} |
+ clearObservations(); |
+} |
+ |
+size_t ResizeObserver::gatherObservations(size_t deeperThan) |
+{ |
+ DCHECK(m_activeObservations.isEmpty()); |
+ |
+ size_t minObservedDepth = ResizeObserverController::kDepthBottom; |
+ if (!m_elementSizeChanged) |
+ return minObservedDepth; |
+ for (auto& observation : m_observations) { |
+ if (!observation->observationSizeOutOfSync()) |
+ continue; |
+ auto depth = observation->targetDepth(); |
+ if (depth > deeperThan) { |
+ m_activeObservations.append(*observation); |
+ minObservedDepth = std::min(minObservedDepth, depth); |
+ } else { |
+ m_skippedObservations = true; |
+ } |
+ } |
+ return minObservedDepth; |
+} |
+ |
+void ResizeObserver::deliverObservations() |
+{ |
+ // We can only clear this flag after all observations have been |
+ // broadcast. |
+ m_elementSizeChanged = m_skippedObservations; |
+ if (m_activeObservations.size() == 0) |
+ return; |
+ |
+ HeapVector<Member<ResizeObserverEntry>> entries; |
+ |
+ for (auto& observation : m_activeObservations) { |
+ auto entry = new ResizeObserverEntry(observation->target()); |
+ entries.append(entry); |
+ observation->setObservationSize(entry->contentSize()); |
+ } |
+ m_callback->handleEvent(entries, this); |
+ clearObservations(); |
+} |
+ |
+void ResizeObserver::clearObservations() |
+{ |
+ m_activeObservations.clear(); |
+ m_skippedObservations = false; |
+} |
+ |
+void ResizeObserver::elementSizeChanged() |
+{ |
+ m_elementSizeChanged = true; |
+ if (m_controller) |
+ m_controller->observerChanged(); |
} |
DEFINE_TRACE(ResizeObserver) |
{ |
visitor->trace(m_callback); |
visitor->trace(m_observations); |
+ visitor->trace(m_activeObservations); |
visitor->trace(m_controller); |
} |