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/IntersectionObserver.h" | 5 #include "core/dom/IntersectionObserver.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ExceptionState.h" | 7 #include "bindings/core/v8/ExceptionState.h" |
| 8 #include "core/css/parser/CSSParserTokenRange.h" | 8 #include "core/css/parser/CSSParserTokenRange.h" |
| 9 #include "core/css/parser/CSSTokenizer.h" | 9 #include "core/css/parser/CSSTokenizer.h" |
| 10 #include "core/dom/Element.h" | 10 #include "core/dom/Element.h" |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 162 Vector<Length> rootMargin; | 162 Vector<Length> rootMargin; |
| 163 parseRootMargin(observerInit.rootMargin(), rootMargin, exceptionState); | 163 parseRootMargin(observerInit.rootMargin(), rootMargin, exceptionState); |
| 164 if (exceptionState.hadException()) | 164 if (exceptionState.hadException()) |
| 165 return nullptr; | 165 return nullptr; |
| 166 | 166 |
| 167 Vector<float> thresholds; | 167 Vector<float> thresholds; |
| 168 parseThresholds(observerInit.threshold(), thresholds, exceptionState); | 168 parseThresholds(observerInit.threshold(), thresholds, exceptionState); |
| 169 if (exceptionState.hadException()) | 169 if (exceptionState.hadException()) |
| 170 return nullptr; | 170 return nullptr; |
| 171 | 171 |
| 172 return new IntersectionObserver(callback, *root, rootMargin, thresholds); | 172 return new IntersectionObserver(callback, *root, rootMargin, thresholds, |
| 173 false); | |
| 173 } | 174 } |
| 174 | 175 |
| 175 IntersectionObserver* IntersectionObserver::create( | 176 IntersectionObserver* IntersectionObserver::create( |
| 176 const Vector<Length>& rootMargin, | 177 const Vector<Length>& rootMargin, |
| 177 const Vector<float>& thresholds, | 178 const Vector<float>& thresholds, |
| 178 Document* document, | 179 Document* document, |
| 179 std::unique_ptr<EventCallback> callback, | 180 std::unique_ptr<EventCallback> callback, |
| 180 ExceptionState& exceptionState) { | 181 ExceptionState& exceptionState) { |
| 181 Node* root = getRootNode(document); | 182 Node* root = getRootNode(document); |
| 182 if (!root) { | 183 if (!root) { |
| 183 exceptionState.throwDOMException( | 184 exceptionState.throwDOMException( |
| 184 HierarchyRequestError, | 185 HierarchyRequestError, |
| 185 "Unable to get root node in main frame to track."); | 186 "Unable to get root node in main frame to track."); |
| 186 return nullptr; | 187 return nullptr; |
| 187 } | 188 } |
| 188 | 189 |
| 189 IntersectionObserverCallbackImpl* intersectionObserverCallback = | 190 IntersectionObserverCallbackImpl* intersectionObserverCallback = |
| 190 new IntersectionObserverCallbackImpl(document, std::move(callback)); | 191 new IntersectionObserverCallbackImpl(document, std::move(callback)); |
| 191 return new IntersectionObserver(*intersectionObserverCallback, *root, | 192 return new IntersectionObserver(*intersectionObserverCallback, *root, |
| 192 rootMargin, thresholds); | 193 rootMargin, thresholds, false); |
| 194 } | |
| 195 | |
| 196 IntersectionObserver* IntersectionObserver::create( | |
| 197 const Vector<Length>& rootMargin, | |
| 198 Document* document, | |
| 199 std::unique_ptr<EventCallback> callback, | |
| 200 ExceptionState& exceptionState) { | |
| 201 Node* root = getRootNode(document); | |
| 202 if (!root) { | |
| 203 exceptionState.throwDOMException( | |
| 204 HierarchyRequestError, | |
| 205 "Unable to get root node in main frame to track."); | |
| 206 return nullptr; | |
| 207 } | |
| 208 | |
| 209 IntersectionObserverCallbackImpl* intersectionObserverCallback = | |
| 210 new IntersectionObserverCallbackImpl(document, std::move(callback)); | |
| 211 return new IntersectionObserver(*intersectionObserverCallback, *root, | |
| 212 rootMargin, Vector<float>(), true); | |
| 193 } | 213 } |
| 194 | 214 |
| 195 IntersectionObserver::IntersectionObserver( | 215 IntersectionObserver::IntersectionObserver( |
| 196 IntersectionObserverCallback& callback, | 216 IntersectionObserverCallback& callback, |
| 197 Node& root, | 217 Node& root, |
| 198 const Vector<Length>& rootMargin, | 218 const Vector<Length>& rootMargin, |
| 199 const Vector<float>& thresholds) | 219 const Vector<float>& thresholds, |
| 220 bool observeViewportIntersection) | |
| 200 : m_callback(&callback), | 221 : m_callback(&callback), |
| 201 m_root(&root), | 222 m_root(&root), |
| 202 m_thresholds(thresholds), | 223 m_thresholds(thresholds), |
| 203 m_topMargin(Fixed), | 224 m_topMargin(Fixed), |
| 204 m_rightMargin(Fixed), | 225 m_rightMargin(Fixed), |
| 205 m_bottomMargin(Fixed), | 226 m_bottomMargin(Fixed), |
| 206 m_leftMargin(Fixed), | 227 m_leftMargin(Fixed), |
| 207 m_initialState(InitialState::kHidden) { | 228 m_initialState(InitialState::kHidden), |
| 229 m_observeViewportIntersection(observeViewportIntersection) { | |
| 208 switch (rootMargin.size()) { | 230 switch (rootMargin.size()) { |
| 209 case 0: | 231 case 0: |
| 210 break; | 232 break; |
| 211 case 1: | 233 case 1: |
| 212 m_topMargin = m_rightMargin = m_bottomMargin = m_leftMargin = | 234 m_topMargin = m_rightMargin = m_bottomMargin = m_leftMargin = |
| 213 rootMargin[0]; | 235 rootMargin[0]; |
| 214 break; | 236 break; |
| 215 case 2: | 237 case 2: |
| 216 m_topMargin = m_bottomMargin = rootMargin[0]; | 238 m_topMargin = m_bottomMargin = rootMargin[0]; |
| 217 m_rightMargin = m_leftMargin = rootMargin[1]; | 239 m_rightMargin = m_leftMargin = rootMargin[1]; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 262 if (!target || m_root.get() == target) | 284 if (!target || m_root.get() == target) |
| 263 return; | 285 return; |
| 264 | 286 |
| 265 if (target->ensureIntersectionObserverData().getObservationFor(*this)) | 287 if (target->ensureIntersectionObserverData().getObservationFor(*this)) |
| 266 return; | 288 return; |
| 267 bool shouldReportRootBounds = false; | 289 bool shouldReportRootBounds = false; |
| 268 bool isDOMDescendant = false; | 290 bool isDOMDescendant = false; |
| 269 LocalFrame* targetFrame = target->document().frame(); | 291 LocalFrame* targetFrame = target->document().frame(); |
| 270 LocalFrame* rootFrame = m_root->document().frame(); | 292 LocalFrame* rootFrame = m_root->document().frame(); |
| 271 | 293 |
| 272 if (target->document() == rootNode()->document()) { | 294 if (m_observeViewportIntersection) { |
| 295 shouldReportRootBounds = true; | |
| 296 } else if (target->document() == rootNode()->document()) { | |
|
szager1
2016/11/16 17:53:54
Please push the logic for determining shouldReport
xjz
2016/11/16 20:38:59
Sorry, I didn't quite get your comment "It's very
| |
| 273 shouldReportRootBounds = true; | 297 shouldReportRootBounds = true; |
| 274 isDOMDescendant = rootNode()->isShadowIncludingInclusiveAncestorOf(target); | 298 isDOMDescendant = rootNode()->isShadowIncludingInclusiveAncestorOf(target); |
| 275 } else if (targetFrame && rootFrame) { | 299 } else if (targetFrame && rootFrame) { |
| 276 shouldReportRootBounds = | 300 shouldReportRootBounds = |
| 277 targetFrame->securityContext()->getSecurityOrigin()->canAccess( | 301 targetFrame->securityContext()->getSecurityOrigin()->canAccess( |
| 278 rootFrame->securityContext()->getSecurityOrigin()); | 302 rootFrame->securityContext()->getSecurityOrigin()); |
| 279 isDOMDescendant = (targetFrame->tree().top() == rootFrame); | 303 isDOMDescendant = (targetFrame->tree().top() == rootFrame); |
| 280 } | 304 } |
| 281 | 305 |
| 282 IntersectionObservation* observation = | 306 IntersectionObservation* observation; |
| 283 new IntersectionObservation(*this, *target, shouldReportRootBounds); | 307 if (m_observeViewportIntersection) { |
|
szager1
2016/11/16 17:53:54
Why is this 'if' clause necessary? The value of s
xjz
2016/11/16 20:38:59
This 'if' clause here is to create the ViewportInt
| |
| 308 observation = new ViewportIntersectionObservation(*this, *target); | |
| 309 } else { | |
| 310 observation = | |
| 311 new IntersectionObservation(*this, *target, shouldReportRootBounds); | |
| 312 } | |
| 284 target->ensureIntersectionObserverData().addObservation(*observation); | 313 target->ensureIntersectionObserverData().addObservation(*observation); |
| 285 m_observations.add(observation); | 314 m_observations.add(observation); |
| 286 | 315 |
| 287 if (!isDOMDescendant) { | 316 if (!isDOMDescendant) { |
| 288 m_root->document().addConsoleMessage( | 317 m_root->document().addConsoleMessage( |
| 289 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, | 318 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, |
| 290 "IntersectionObserver.observe(target): target " | 319 "IntersectionObserver.observe(target): target " |
| 291 "element is not a descendant of root.")); | 320 "element is not a descendant of root.")); |
| 292 return; | 321 return; |
| 293 } | 322 } |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 | 476 |
| 448 DEFINE_TRACE(IntersectionObserver) { | 477 DEFINE_TRACE(IntersectionObserver) { |
| 449 visitor->template registerWeakMembers< | 478 visitor->template registerWeakMembers< |
| 450 IntersectionObserver, &IntersectionObserver::clearWeakMembers>(this); | 479 IntersectionObserver, &IntersectionObserver::clearWeakMembers>(this); |
| 451 visitor->trace(m_callback); | 480 visitor->trace(m_callback); |
| 452 visitor->trace(m_observations); | 481 visitor->trace(m_observations); |
| 453 visitor->trace(m_entries); | 482 visitor->trace(m_entries); |
| 454 } | 483 } |
| 455 | 484 |
| 456 } // namespace blink | 485 } // namespace blink |
| OLD | NEW |