| 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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 Node* root = getRootNode(document); | 181 Node* root = getRootNode(document); |
| 182 if (!root) { | 182 if (!root) { |
| 183 exceptionState.throwDOMException( | 183 exceptionState.throwDOMException( |
| 184 HierarchyRequestError, | 184 HierarchyRequestError, |
| 185 "Unable to get root node in main frame to track."); | 185 "Unable to get root node in main frame to track."); |
| 186 return nullptr; | 186 return nullptr; |
| 187 } | 187 } |
| 188 | 188 |
| 189 IntersectionObserverCallbackImpl* intersectionObserverCallback = | 189 IntersectionObserverCallbackImpl* intersectionObserverCallback = |
| 190 new IntersectionObserverCallbackImpl(document, std::move(callback)); | 190 new IntersectionObserverCallbackImpl(document, std::move(callback)); |
| 191 return new IntersectionObserver(*intersectionObserverCallback, *root, | 191 if (thresholds.isEmpty()) { |
| 192 rootMargin, thresholds); | 192 return new ViewportIntersectionObserver(*intersectionObserverCallback, |
| 193 *root, rootMargin); |
| 194 } else { |
| 195 return new IntersectionObserver(*intersectionObserverCallback, *root, |
| 196 rootMargin, thresholds); |
| 197 } |
| 193 } | 198 } |
| 194 | 199 |
| 195 IntersectionObserver::IntersectionObserver( | 200 IntersectionObserver::IntersectionObserver( |
| 196 IntersectionObserverCallback& callback, | 201 IntersectionObserverCallback& callback, |
| 197 Node& root, | 202 Node& root, |
| 198 const Vector<Length>& rootMargin, | 203 const Vector<Length>& rootMargin, |
| 199 const Vector<float>& thresholds) | 204 const Vector<float>& thresholds) |
| 200 : m_callback(&callback), | 205 : m_callback(&callback), |
| 201 m_root(&root), | 206 m_root(&root), |
| 202 m_thresholds(thresholds), | 207 m_thresholds(thresholds), |
| (...skipping 25 matching lines...) Expand all Loading... |
| 228 m_leftMargin = rootMargin[3]; | 233 m_leftMargin = rootMargin[3]; |
| 229 break; | 234 break; |
| 230 default: | 235 default: |
| 231 NOTREACHED(); | 236 NOTREACHED(); |
| 232 break; | 237 break; |
| 233 } | 238 } |
| 234 root.document().ensureIntersectionObserverController().addTrackedObserver( | 239 root.document().ensureIntersectionObserverController().addTrackedObserver( |
| 235 *this); | 240 *this); |
| 236 } | 241 } |
| 237 | 242 |
| 243 IntersectionObserver::~IntersectionObserver() {} |
| 244 |
| 238 void IntersectionObserver::clearWeakMembers(Visitor* visitor) { | 245 void IntersectionObserver::clearWeakMembers(Visitor* visitor) { |
| 239 if (ThreadHeap::isHeapObjectAlive(m_root)) | 246 if (ThreadHeap::isHeapObjectAlive(m_root)) |
| 240 return; | 247 return; |
| 241 IgnorableExceptionState exceptionState; | 248 IgnorableExceptionState exceptionState; |
| 242 disconnect(exceptionState); | 249 disconnect(exceptionState); |
| 243 m_root = nullptr; | 250 m_root = nullptr; |
| 244 } | 251 } |
| 245 | 252 |
| 246 LayoutObject* IntersectionObserver::rootLayoutObject() const { | 253 LayoutObject* IntersectionObserver::rootLayoutObject() const { |
| 247 Node* node = rootNode(); | 254 Node* node = rootNode(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 273 shouldReportRootBounds = true; | 280 shouldReportRootBounds = true; |
| 274 isDOMDescendant = rootNode()->isShadowIncludingInclusiveAncestorOf(target); | 281 isDOMDescendant = rootNode()->isShadowIncludingInclusiveAncestorOf(target); |
| 275 } else if (targetFrame && rootFrame) { | 282 } else if (targetFrame && rootFrame) { |
| 276 shouldReportRootBounds = | 283 shouldReportRootBounds = |
| 277 targetFrame->securityContext()->getSecurityOrigin()->canAccess( | 284 targetFrame->securityContext()->getSecurityOrigin()->canAccess( |
| 278 rootFrame->securityContext()->getSecurityOrigin()); | 285 rootFrame->securityContext()->getSecurityOrigin()); |
| 279 isDOMDescendant = (targetFrame->tree().top() == rootFrame); | 286 isDOMDescendant = (targetFrame->tree().top() == rootFrame); |
| 280 } | 287 } |
| 281 | 288 |
| 282 IntersectionObservation* observation = | 289 IntersectionObservation* observation = |
| 283 new IntersectionObservation(*this, *target, shouldReportRootBounds); | 290 createObservation(*target, shouldReportRootBounds); |
| 284 target->ensureIntersectionObserverData().addObservation(*observation); | 291 target->ensureIntersectionObserverData().addObservation(*observation); |
| 285 m_observations.add(observation); | 292 m_observations.add(observation); |
| 286 | 293 |
| 287 if (!isDOMDescendant) { | 294 if (!isDOMDescendant) { |
| 288 m_root->document().addConsoleMessage( | 295 m_root->document().addConsoleMessage( |
| 289 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, | 296 ConsoleMessage::create(JSMessageSource, WarningMessageLevel, |
| 290 "IntersectionObserver.observe(target): target " | 297 "IntersectionObserver.observe(target): target " |
| 291 "element is not a descendant of root.")); | 298 "element is not a descendant of root.")); |
| 292 return; | 299 return; |
| 293 } | 300 } |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 438 | 445 |
| 439 void IntersectionObserver::deliver() { | 446 void IntersectionObserver::deliver() { |
| 440 if (m_entries.isEmpty()) | 447 if (m_entries.isEmpty()) |
| 441 return; | 448 return; |
| 442 | 449 |
| 443 HeapVector<Member<IntersectionObserverEntry>> entries; | 450 HeapVector<Member<IntersectionObserverEntry>> entries; |
| 444 entries.swap(m_entries); | 451 entries.swap(m_entries); |
| 445 m_callback->handleEvent(entries, *this); | 452 m_callback->handleEvent(entries, *this); |
| 446 } | 453 } |
| 447 | 454 |
| 455 IntersectionObservation* IntersectionObserver::createObservation( |
| 456 Element& target, |
| 457 bool shouldReportRootBounds) { |
| 458 return new IntersectionObservation(*this, target, shouldReportRootBounds); |
| 459 } |
| 460 |
| 448 DEFINE_TRACE(IntersectionObserver) { | 461 DEFINE_TRACE(IntersectionObserver) { |
| 449 visitor->template registerWeakMembers< | 462 visitor->template registerWeakMembers< |
| 450 IntersectionObserver, &IntersectionObserver::clearWeakMembers>(this); | 463 IntersectionObserver, &IntersectionObserver::clearWeakMembers>(this); |
| 451 visitor->trace(m_callback); | 464 visitor->trace(m_callback); |
| 452 visitor->trace(m_observations); | 465 visitor->trace(m_observations); |
| 453 visitor->trace(m_entries); | 466 visitor->trace(m_entries); |
| 454 } | 467 } |
| 455 | 468 |
| 469 ViewportIntersectionObserver::ViewportIntersectionObserver( |
| 470 IntersectionObserverCallback& callback, |
| 471 Node& node, |
| 472 const Vector<Length>& rootMargin) |
| 473 : IntersectionObserver(callback, node, rootMargin, Vector<float>()) {} |
| 474 |
| 475 ViewportIntersectionObserver::~ViewportIntersectionObserver() {} |
| 476 |
| 477 IntersectionObservation* ViewportIntersectionObserver::createObservation( |
| 478 Element& target, |
| 479 bool) { |
| 480 return new ViewportIntersectionObservation(*this, target); |
| 481 } |
| 482 |
| 456 } // namespace blink | 483 } // namespace blink |
| OLD | NEW |