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" | |
9 | 8 |
10 namespace blink { | 9 namespace blink { |
11 | 10 |
12 typedef HeapVector<Member<IntersectionObserver>> IntersectionObserverVector; | 11 typedef HeapVector<Member<IntersectionObserver>> IntersectionObserverVector; |
13 | 12 |
14 IntersectionObserverController* IntersectionObserverController::create(Document*
document) | 13 IntersectionObserverController* IntersectionObserverController::create(Document*
document) |
15 { | 14 { |
16 IntersectionObserverController* result = new IntersectionObserverController(
document); | 15 IntersectionObserverController* result = new IntersectionObserverController(
document); |
17 result->suspendIfNeeded(); | 16 result->suspendIfNeeded(); |
18 return result; | 17 return result; |
19 } | 18 } |
20 | 19 |
21 IntersectionObserverController::IntersectionObserverController(Document* documen
t) | 20 IntersectionObserverController::IntersectionObserverController(Document* documen
t) |
22 : ActiveDOMObject(document) | 21 : ActiveDOMObject(document) |
23 , m_callbackIsScheduled(false) | 22 , m_timer(this, &IntersectionObserverController::deliverIntersectionObservat
ions) |
24 , m_callbackFiredWhileSuspended(false) | 23 , m_timerFiredWhileSuspended(false) |
25 { | 24 { |
26 } | 25 } |
27 | 26 |
28 IntersectionObserverController::~IntersectionObserverController() { } | 27 IntersectionObserverController::~IntersectionObserverController() { } |
29 | 28 |
30 void IntersectionObserverController::scheduleIntersectionObserverForDelivery(Int
ersectionObserver& observer) | 29 void IntersectionObserverController::scheduleIntersectionObserverForDelivery(Int
ersectionObserver& observer) |
31 { | 30 { |
| 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); |
32 m_pendingIntersectionObservers.add(&observer); | 36 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); | |
43 } | 37 } |
44 | 38 |
45 void IntersectionObserverController::resume() | 39 void IntersectionObserverController::resume() |
46 { | 40 { |
47 // If the callback fired while DOM objects were suspended, notifications mig
ht be late, so deliver | 41 // If the timer fired while DOM objects were suspended, notifications might
be late, so deliver |
48 // them right away (rather than waiting to fire again). | 42 // them right away (rather than waiting for m_timer to fire again). |
49 if (m_callbackFiredWhileSuspended) { | 43 if (m_timerFiredWhileSuspended) { |
50 m_callbackFiredWhileSuspended = false; | 44 m_timerFiredWhileSuspended = false; |
51 deliverIntersectionObservations(); | 45 deliverIntersectionObservations(nullptr); |
52 } | 46 } |
53 } | 47 } |
54 | 48 |
55 void IntersectionObserverController::handleEvent(IdleDeadline*) | 49 void IntersectionObserverController::deliverIntersectionObservations(Timer<Inter
sectionObserverController>*) |
56 { | |
57 m_callbackIsScheduled = false; | |
58 deliverIntersectionObservations(); | |
59 } | |
60 | |
61 void IntersectionObserverController::deliverIntersectionObservations() | |
62 { | 50 { |
63 if (getExecutionContext()->activeDOMObjectsAreSuspended()) { | 51 if (getExecutionContext()->activeDOMObjectsAreSuspended()) { |
64 m_callbackFiredWhileSuspended = true; | 52 m_timerFiredWhileSuspended = true; |
65 return; | 53 return; |
66 } | 54 } |
67 IntersectionObserverVector observers; | 55 IntersectionObserverVector observers; |
68 copyToVector(m_pendingIntersectionObservers, observers); | 56 copyToVector(m_pendingIntersectionObservers, observers); |
69 m_pendingIntersectionObservers.clear(); | 57 m_pendingIntersectionObservers.clear(); |
70 for (auto& observer : observers) | 58 for (auto& observer : observers) |
71 observer->deliver(); | 59 observer->deliver(); |
72 } | 60 } |
73 | 61 |
74 void IntersectionObserverController::computeTrackedIntersectionObservations() | 62 void IntersectionObserverController::computeTrackedIntersectionObservations() |
(...skipping 18 matching lines...) Expand all Loading... |
93 toRemove.append(observer); | 81 toRemove.append(observer); |
94 } | 82 } |
95 m_trackedIntersectionObservers.removeAll(toRemove); | 83 m_trackedIntersectionObservers.removeAll(toRemove); |
96 } | 84 } |
97 | 85 |
98 DEFINE_TRACE(IntersectionObserverController) | 86 DEFINE_TRACE(IntersectionObserverController) |
99 { | 87 { |
100 visitor->trace(m_trackedIntersectionObservers); | 88 visitor->trace(m_trackedIntersectionObservers); |
101 visitor->trace(m_pendingIntersectionObservers); | 89 visitor->trace(m_pendingIntersectionObservers); |
102 ActiveDOMObject::trace(visitor); | 90 ActiveDOMObject::trace(visitor); |
103 IdleRequestCallback::trace(visitor); | |
104 } | 91 } |
105 | 92 |
106 } // namespace blink | 93 } // namespace blink |
OLD | NEW |