Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/dom/IntersectionObservation.h" | 5 #include "core/dom/IntersectionObservation.h" |
| 6 | 6 |
| 7 #include "core/dom/ElementRareData.h" | 7 #include "core/dom/ElementRareData.h" |
| 8 #include "core/dom/IntersectionObserver.h" | 8 #include "core/dom/IntersectionObserver.h" |
| 9 #include "core/frame/FrameView.h" | 9 #include "core/frame/FrameView.h" |
| 10 #include "core/frame/LocalFrame.h" | 10 #include "core/frame/LocalFrame.h" |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 203 // only two states are recognized: | 203 // only two states are recognized: |
| 204 // - 0 means not intersecting. | 204 // - 0 means not intersecting. |
| 205 // - 1 means intersecting. | 205 // - 1 means intersecting. |
| 206 // No other threshold crossings are possible. | 206 // No other threshold crossings are possible. |
| 207 // - Otherwise: | 207 // - Otherwise: |
| 208 // - If root and target do not intersect, the threshold index is 0. | 208 // - If root and target do not intersect, the threshold index is 0. |
| 209 // - If root and target intersect but the intersection has zero-area | 209 // - If root and target intersect but the intersection has zero-area |
| 210 // (i.e., they have a coincident edge or corner), we consider the | 210 // (i.e., they have a coincident edge or corner), we consider the |
| 211 // intersection to have "crossed" a zero threshold, but not crossed | 211 // intersection to have "crossed" a zero threshold, but not crossed |
| 212 // any non-zero threshold. | 212 // any non-zero threshold. |
| 213 // When observer is observing the element/viewport ratio, ignore thresholds | |
| 214 // and report any changes on ratio. | |
| 213 unsigned newThresholdIndex; | 215 unsigned newThresholdIndex; |
| 214 float newVisibleRatio = 0; | 216 float newVisibleRatio = 0; |
| 217 bool isObservingRatio = m_observer->isObservingElementViewportRatio(); | |
|
miu
2016/11/09 22:02:08
naming/semantics: IMHO, this shouldn't semanticall
xjz
2016/11/11 01:07:29
Not needed. Added a subclass to observe element/vi
| |
| 215 if (geometry.targetRect.isEmpty()) { | 218 if (geometry.targetRect.isEmpty()) { |
| 216 newThresholdIndex = geometry.doesIntersect ? 1 : 0; | 219 newThresholdIndex = geometry.doesIntersect ? 1 : 0; |
| 217 } else if (!geometry.doesIntersect) { | 220 } else if (!geometry.doesIntersect) { |
| 218 newThresholdIndex = 0; | 221 newThresholdIndex = 0; |
| 219 } else { | 222 } else { |
| 220 float intersectionArea = | 223 float intersectionArea = |
| 221 geometry.intersectionRect.size().width().toFloat() * | 224 geometry.intersectionRect.size().width().toFloat() * |
| 222 geometry.intersectionRect.size().height().toFloat(); | 225 geometry.intersectionRect.size().height().toFloat(); |
| 223 float targetArea = geometry.targetRect.size().width().toFloat() * | 226 if (isObservingRatio) { |
| 224 geometry.targetRect.size().height().toFloat(); | 227 float rootArea = geometry.rootRect.size().width().toFloat() * |
|
miu
2016/11/09 22:02:07
Doesn't seem like the math should be different. Wo
xjz
2016/11/11 01:07:29
They are different. The targetRect is the element
| |
| 225 newVisibleRatio = intersectionArea / targetArea; | 228 geometry.rootRect.size().height().toFloat(); |
| 226 newThresholdIndex = observer().firstThresholdGreaterThan(newVisibleRatio); | 229 newVisibleRatio = intersectionArea / rootArea; |
| 230 } else { | |
| 231 float targetArea = geometry.targetRect.size().width().toFloat() * | |
| 232 geometry.targetRect.size().height().toFloat(); | |
| 233 newVisibleRatio = intersectionArea / targetArea; | |
| 234 newThresholdIndex = observer().firstThresholdGreaterThan(newVisibleRatio); | |
| 235 } | |
| 227 } | 236 } |
| 228 if (m_lastThresholdIndex != newThresholdIndex) { | 237 bool shouldReportChange = |
| 238 (isObservingRatio && m_lastVisibleRatio != newVisibleRatio) || | |
| 239 (!isObservingRatio && m_lastThresholdIndex != newThresholdIndex); | |
| 240 if (shouldReportChange) { | |
|
miu
2016/11/09 22:02:07
IMHO, this change should be:
if (m_lastThreshol
xjz
2016/11/11 01:07:29
I think we only want to report if the ratio is cha
| |
| 229 IntRect snappedRootBounds = pixelSnappedIntRect(geometry.rootRect); | 241 IntRect snappedRootBounds = pixelSnappedIntRect(geometry.rootRect); |
| 230 IntRect* rootBoundsPointer = | 242 IntRect* rootBoundsPointer = |
| 231 m_shouldReportRootBounds ? &snappedRootBounds : nullptr; | 243 m_shouldReportRootBounds ? &snappedRootBounds : nullptr; |
| 232 IntersectionObserverEntry* newEntry = new IntersectionObserverEntry( | 244 IntersectionObserverEntry* newEntry = new IntersectionObserverEntry( |
| 233 timestamp, newVisibleRatio, pixelSnappedIntRect(geometry.targetRect), | 245 timestamp, newVisibleRatio, pixelSnappedIntRect(geometry.targetRect), |
| 234 rootBoundsPointer, pixelSnappedIntRect(geometry.intersectionRect), | 246 rootBoundsPointer, pixelSnappedIntRect(geometry.intersectionRect), |
| 235 target()); | 247 target()); |
| 236 observer().enqueueIntersectionObserverEntry(*newEntry); | 248 observer().enqueueIntersectionObserverEntry(*newEntry); |
| 237 setLastThresholdIndex(newThresholdIndex); | 249 if (isObservingRatio) |
| 250 m_lastVisibleRatio = newVisibleRatio; | |
| 251 else | |
| 252 setLastThresholdIndex(newThresholdIndex); | |
| 238 } | 253 } |
| 239 } | 254 } |
| 240 | 255 |
| 241 void IntersectionObservation::disconnect() { | 256 void IntersectionObservation::disconnect() { |
| 242 IntersectionObserver* observer = m_observer; | 257 IntersectionObserver* observer = m_observer; |
| 243 clearRootAndRemoveFromTarget(); | 258 clearRootAndRemoveFromTarget(); |
| 244 observer->removeObservation(*this); | 259 observer->removeObservation(*this); |
| 245 } | 260 } |
| 246 | 261 |
| 247 void IntersectionObservation::clearRootAndRemoveFromTarget() { | 262 void IntersectionObservation::clearRootAndRemoveFromTarget() { |
| 248 if (m_target) | 263 if (m_target) |
| 249 target()->ensureIntersectionObserverData().removeObservation(observer()); | 264 target()->ensureIntersectionObserverData().removeObservation(observer()); |
| 250 m_observer.clear(); | 265 m_observer.clear(); |
| 251 } | 266 } |
| 252 | 267 |
| 253 DEFINE_TRACE(IntersectionObservation) { | 268 DEFINE_TRACE(IntersectionObservation) { |
| 254 visitor->trace(m_observer); | 269 visitor->trace(m_observer); |
| 255 visitor->trace(m_target); | 270 visitor->trace(m_target); |
| 256 } | 271 } |
| 257 | 272 |
| 258 } // namespace blink | 273 } // namespace blink |
| OLD | NEW |