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 |