| 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/IntersectionObserverController.h" | 5 #include "core/dom/IntersectionObserverController.h" |
| 6 | 6 |
| 7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
| 8 #include "core/dom/IdleRequestOptions.h" |
| 8 | 9 |
| 9 namespace blink { | 10 namespace blink { |
| 10 | 11 |
| 11 typedef HeapVector<Member<IntersectionObserver>> IntersectionObserverVector; | 12 typedef HeapVector<Member<IntersectionObserver>> IntersectionObserverVector; |
| 12 | 13 |
| 13 IntersectionObserverController* IntersectionObserverController::create(Document*
document) | 14 IntersectionObserverController* IntersectionObserverController::create(Document*
document) |
| 14 { | 15 { |
| 15 IntersectionObserverController* result = new IntersectionObserverController(
document); | 16 IntersectionObserverController* result = new IntersectionObserverController(
document); |
| 16 result->suspendIfNeeded(); | 17 result->suspendIfNeeded(); |
| 17 return result; | 18 return result; |
| 18 } | 19 } |
| 19 | 20 |
| 20 IntersectionObserverController::IntersectionObserverController(Document* documen
t) | 21 IntersectionObserverController::IntersectionObserverController(Document* documen
t) |
| 21 : ActiveDOMObject(document) | 22 : ActiveDOMObject(document) |
| 22 , m_timer(this, &IntersectionObserverController::deliverIntersectionObservat
ions) | 23 , m_callbackIsScheduled(false) |
| 23 , m_timerFiredWhileSuspended(false) | 24 , m_callbackFiredWhileSuspended(false) |
| 24 { | 25 { |
| 25 } | 26 } |
| 26 | 27 |
| 27 IntersectionObserverController::~IntersectionObserverController() { } | 28 IntersectionObserverController::~IntersectionObserverController() { } |
| 28 | 29 |
| 29 void IntersectionObserverController::scheduleIntersectionObserverForDelivery(Int
ersectionObserver& observer) | 30 void IntersectionObserverController::scheduleIntersectionObserverForDelivery(Int
ersectionObserver& observer) |
| 30 { | 31 { |
| 31 // TODO(szager): use idle callback with a timeout. Until we do that, there
is no | |
| 32 // reliable way to write a test for takeRecords, because it's impossible to
guarantee | |
| 33 // that javascript will get a chance to run before the timer fires. | |
| 34 if (!m_timer.isActive()) | |
| 35 m_timer.startOneShot(0, BLINK_FROM_HERE); | |
| 36 m_pendingIntersectionObservers.add(&observer); | 32 m_pendingIntersectionObservers.add(&observer); |
| 33 if (m_callbackIsScheduled) |
| 34 return; |
| 35 Document* document = toDocument(getExecutionContext()); |
| 36 if (!document) |
| 37 return; |
| 38 m_callbackIsScheduled = true; |
| 39 IdleRequestOptions options; |
| 40 // The IntersectionObserver spec mandates that notifications be sent within
100ms. |
| 41 options.setTimeout(100); |
| 42 document->requestIdleCallback(this, options); |
| 37 } | 43 } |
| 38 | 44 |
| 39 void IntersectionObserverController::resume() | 45 void IntersectionObserverController::resume() |
| 40 { | 46 { |
| 41 // If the timer fired while DOM objects were suspended, notifications might
be late, so deliver | 47 // If the callback fired while DOM objects were suspended, notifications mig
ht be late, so deliver |
| 42 // them right away (rather than waiting for m_timer to fire again). | 48 // them right away (rather than waiting to fire again). |
| 43 if (m_timerFiredWhileSuspended) { | 49 if (m_callbackFiredWhileSuspended) { |
| 44 m_timerFiredWhileSuspended = false; | 50 m_callbackFiredWhileSuspended = false; |
| 45 deliverIntersectionObservations(nullptr); | 51 deliverIntersectionObservations(); |
| 46 } | 52 } |
| 47 } | 53 } |
| 48 | 54 |
| 49 void IntersectionObserverController::deliverIntersectionObservations(Timer<Inter
sectionObserverController>*) | 55 void IntersectionObserverController::handleEvent(IdleDeadline*) |
| 56 { |
| 57 m_callbackIsScheduled = false; |
| 58 deliverIntersectionObservations(); |
| 59 } |
| 60 |
| 61 void IntersectionObserverController::deliverIntersectionObservations() |
| 50 { | 62 { |
| 51 if (getExecutionContext()->activeDOMObjectsAreSuspended()) { | 63 if (getExecutionContext()->activeDOMObjectsAreSuspended()) { |
| 52 m_timerFiredWhileSuspended = true; | 64 m_callbackFiredWhileSuspended = true; |
| 53 return; | 65 return; |
| 54 } | 66 } |
| 55 IntersectionObserverVector observers; | 67 IntersectionObserverVector observers; |
| 56 copyToVector(m_pendingIntersectionObservers, observers); | 68 copyToVector(m_pendingIntersectionObservers, observers); |
| 57 m_pendingIntersectionObservers.clear(); | 69 m_pendingIntersectionObservers.clear(); |
| 58 for (auto& observer : observers) | 70 for (auto& observer : observers) |
| 59 observer->deliver(); | 71 observer->deliver(); |
| 60 } | 72 } |
| 61 | 73 |
| 62 void IntersectionObserverController::computeTrackedIntersectionObservations() | 74 void IntersectionObserverController::computeTrackedIntersectionObservations() |
| (...skipping 18 matching lines...) Expand all Loading... |
| 81 toRemove.append(observer); | 93 toRemove.append(observer); |
| 82 } | 94 } |
| 83 m_trackedIntersectionObservers.removeAll(toRemove); | 95 m_trackedIntersectionObservers.removeAll(toRemove); |
| 84 } | 96 } |
| 85 | 97 |
| 86 DEFINE_TRACE(IntersectionObserverController) | 98 DEFINE_TRACE(IntersectionObserverController) |
| 87 { | 99 { |
| 88 visitor->trace(m_trackedIntersectionObservers); | 100 visitor->trace(m_trackedIntersectionObservers); |
| 89 visitor->trace(m_pendingIntersectionObservers); | 101 visitor->trace(m_pendingIntersectionObservers); |
| 90 ActiveDOMObject::trace(visitor); | 102 ActiveDOMObject::trace(visitor); |
| 103 IdleRequestCallback::trace(visitor); |
| 91 } | 104 } |
| 92 | 105 |
| 93 } // namespace blink | 106 } // namespace blink |
| OLD | NEW |