OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2011 Google Inc. All rights reserved. | 2 * Copyright (C) 2011 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 #include "core/dom/MutationRecord.h" | 42 #include "core/dom/MutationRecord.h" |
43 #include "core/dom/Node.h" | 43 #include "core/dom/Node.h" |
44 #include "core/inspector/InspectorInstrumentation.h" | 44 #include "core/inspector/InspectorInstrumentation.h" |
45 #include "wtf/MainThread.h" | 45 #include "wtf/MainThread.h" |
46 | 46 |
47 namespace WebCore { | 47 namespace WebCore { |
48 | 48 |
49 static unsigned s_observerPriority = 0; | 49 static unsigned s_observerPriority = 0; |
50 | 50 |
51 struct MutationObserver::ObserverLessThan { | 51 struct MutationObserver::ObserverLessThan { |
52 bool operator()(const RefPtr<MutationObserver>& lhs, const RefPtr<MutationOb server>& rhs) | 52 bool operator()(const RefPtrWillBeMember<MutationObserver>& lhs, const RefPt rWillBeMember<MutationObserver>& rhs) |
53 { | 53 { |
54 return lhs->m_priority < rhs->m_priority; | 54 return lhs->m_priority < rhs->m_priority; |
55 } | 55 } |
56 }; | 56 }; |
57 | 57 |
58 PassRefPtr<MutationObserver> MutationObserver::create(PassOwnPtr<MutationCallbac k> callback) | 58 PassRefPtrWillBeRawPtr<MutationObserver> MutationObserver::create(PassOwnPtr<Mut ationCallback> callback) |
59 { | 59 { |
60 ASSERT(isMainThread()); | 60 ASSERT(isMainThread()); |
61 return adoptRef(new MutationObserver(callback)); | 61 return adoptRefWillBeNoop(new MutationObserver(callback)); |
62 } | 62 } |
63 | 63 |
64 MutationObserver::MutationObserver(PassOwnPtr<MutationCallback> callback) | 64 MutationObserver::MutationObserver(PassOwnPtr<MutationCallback> callback) |
65 : m_callback(callback) | 65 : m_callback(callback) |
66 , m_priority(s_observerPriority++) | 66 , m_priority(s_observerPriority++) |
67 { | 67 { |
68 ScriptWrappable::init(this); | 68 ScriptWrappable::init(this); |
69 } | 69 } |
70 | 70 |
71 MutationObserver::~MutationObserver() | 71 MutationObserver::~MutationObserver() |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 } | 133 } |
134 | 134 |
135 if (!(options & (Attributes | CharacterData | ChildList))) { | 135 if (!(options & (Attributes | CharacterData | ChildList))) { |
136 exceptionState.throwTypeError("The options object must set at least one of 'attributes', 'characterData', or 'childList' to true."); | 136 exceptionState.throwTypeError("The options object must set at least one of 'attributes', 'characterData', or 'childList' to true."); |
137 return; | 137 return; |
138 } | 138 } |
139 | 139 |
140 node->registerMutationObserver(*this, options, attributeFilter); | 140 node->registerMutationObserver(*this, options, attributeFilter); |
141 } | 141 } |
142 | 142 |
143 Vector<RefPtr<MutationRecord> > MutationObserver::takeRecords() | 143 WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > MutationObserver::takeReco rds() |
144 { | 144 { |
145 Vector<RefPtr<MutationRecord> > records; | 145 WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > records; |
146 records.swap(m_records); | 146 records.swap(m_records); |
147 InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionCo ntext(), this); | 147 InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionCo ntext(), this); |
148 return records; | 148 return records; |
149 } | 149 } |
150 | 150 |
151 void MutationObserver::disconnect() | 151 void MutationObserver::disconnect() |
152 { | 152 { |
153 m_records.clear(); | 153 m_records.clear(); |
154 InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionCo ntext(), this); | 154 InspectorInstrumentation::didClearAllMutationRecords(m_callback->executionCo ntext(), this); |
155 HashSet<MutationObserverRegistration*> registrations(m_registrations); | 155 WillBeHeapHashSet<RawPtrWillBeWeakMember<MutationObserverRegistration> > reg istrations(m_registrations); |
156 for (HashSet<MutationObserverRegistration*>::iterator iter = registrations.b egin(); iter != registrations.end(); ++iter) | 156 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<MutationObserverRegistration> >::iterator iter = registrations.begin(); iter != registrations.end(); ++iter) |
haraken
2014/04/21 06:00:34
Why do you need to copy the hash set for the itera
sof
2014/04/21 07:34:05
The registration objects will signal the end of th
haraken
2014/04/21 07:41:31
Makes sense.
| |
157 (*iter)->unregister(); | 157 (*iter)->unregister(); |
158 ASSERT(m_registrations.isEmpty()); | |
158 } | 159 } |
159 | 160 |
160 void MutationObserver::observationStarted(MutationObserverRegistration* registra tion) | 161 void MutationObserver::observationStarted(MutationObserverRegistration* registra tion) |
161 { | 162 { |
162 ASSERT(!m_registrations.contains(registration)); | 163 ASSERT(!m_registrations.contains(registration)); |
163 m_registrations.add(registration); | 164 m_registrations.add(registration); |
164 } | 165 } |
165 | 166 |
166 void MutationObserver::observationEnded(MutationObserverRegistration* registrati on) | 167 void MutationObserver::observationEnded(MutationObserverRegistration* registrati on) |
167 { | 168 { |
168 ASSERT(m_registrations.contains(registration)); | 169 ASSERT(m_registrations.contains(registration)); |
169 m_registrations.remove(registration); | 170 m_registrations.remove(registration); |
170 } | 171 } |
171 | 172 |
172 typedef HashSet<RefPtr<MutationObserver> > MutationObserverSet; | 173 typedef WillBeHeapHashSet<RefPtrWillBeMember<MutationObserver> > MutationObserve rSet; |
173 | 174 |
174 static MutationObserverSet& activeMutationObservers() | 175 static MutationObserverSet& activeMutationObservers() |
175 { | 176 { |
177 #if ENABLE(OILPAN) | |
178 DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, activeObservers, (new M utationObserverSet())); | |
179 return *activeObservers; | |
180 #else | |
176 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, ()); | 181 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, ()); |
177 return activeObservers; | 182 return activeObservers; |
183 #endif | |
178 } | 184 } |
179 | 185 |
180 static MutationObserverSet& suspendedMutationObservers() | 186 static MutationObserverSet& suspendedMutationObservers() |
181 { | 187 { |
188 #if ENABLE(OILPAN) | |
189 DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, suspendedObservers, (ne w MutationObserverSet())); | |
190 return *suspendedObservers; | |
191 #else | |
182 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, ()); | 192 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, ()); |
183 return suspendedObservers; | 193 return suspendedObservers; |
194 #endif | |
184 } | 195 } |
185 | 196 |
186 static void activateObserver(PassRefPtr<MutationObserver> observer) | 197 static void activateObserver(PassRefPtrWillBeRawPtr<MutationObserver> observer) |
187 { | 198 { |
188 if (activeMutationObservers().isEmpty()) | 199 if (activeMutationObservers().isEmpty()) |
189 Microtask::enqueueMicrotask(&MutationObserver::deliverMutations); | 200 Microtask::enqueueMicrotask(&MutationObserver::deliverMutations); |
190 | 201 |
191 activeMutationObservers().add(observer); | 202 activeMutationObservers().add(observer); |
192 } | 203 } |
193 | 204 |
194 void MutationObserver::enqueueMutationRecord(PassRefPtr<MutationRecord> mutation ) | 205 void MutationObserver::enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationReco rd> mutation) |
195 { | 206 { |
196 ASSERT(isMainThread()); | 207 ASSERT(isMainThread()); |
197 m_records.append(mutation); | 208 m_records.append(mutation); |
198 activateObserver(this); | 209 activateObserver(this); |
199 InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionCont ext(), this); | 210 InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionCont ext(), this); |
200 } | 211 } |
201 | 212 |
202 void MutationObserver::setHasTransientRegistration() | 213 void MutationObserver::setHasTransientRegistration() |
203 { | 214 { |
204 ASSERT(isMainThread()); | 215 ASSERT(isMainThread()); |
205 activateObserver(this); | 216 activateObserver(this); |
206 } | 217 } |
207 | 218 |
208 HashSet<Node*> MutationObserver::getObservedNodes() const | 219 HashSet<Node*> MutationObserver::getObservedNodes() const |
209 { | 220 { |
210 HashSet<Node*> observedNodes; | 221 HashSet<Node*> observedNodes; |
211 for (HashSet<MutationObserverRegistration*>::const_iterator iter = m_registr ations.begin(); iter != m_registrations.end(); ++iter) | 222 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<MutationObserverRegistration> >::const_iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter) |
212 (*iter)->addRegistrationNodesToSet(observedNodes); | 223 (*iter)->addRegistrationNodesToSet(observedNodes); |
213 return observedNodes; | 224 return observedNodes; |
214 } | 225 } |
215 | 226 |
216 bool MutationObserver::canDeliver() | 227 bool MutationObserver::canDeliver() |
217 { | 228 { |
218 return !m_callback->executionContext()->activeDOMObjectsAreSuspended(); | 229 return !m_callback->executionContext()->activeDOMObjectsAreSuspended(); |
219 } | 230 } |
220 | 231 |
221 void MutationObserver::deliver() | 232 void MutationObserver::deliver() |
222 { | 233 { |
223 ASSERT(canDeliver()); | 234 ASSERT(canDeliver()); |
224 | 235 |
225 // Calling clearTransientRegistrations() can modify m_registrations, so it's necessary | 236 // Calling clearTransientRegistrations() can modify m_registrations, so it's necessary |
226 // to make a copy of the transient registrations before operating on them. | 237 // to make a copy of the transient registrations before operating on them. |
227 Vector<MutationObserverRegistration*, 1> transientRegistrations; | 238 WillBeHeapVector<RawPtrWillBeMember<MutationObserverRegistration>, 1> transi entRegistrations; |
228 for (HashSet<MutationObserverRegistration*>::iterator iter = m_registrations .begin(); iter != m_registrations.end(); ++iter) { | 239 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<MutationObserverRegistration> >::iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++ite r) { |
229 if ((*iter)->hasTransientRegistrations()) | 240 if ((*iter)->hasTransientRegistrations()) |
230 transientRegistrations.append(*iter); | 241 transientRegistrations.append(*iter); |
231 } | 242 } |
232 for (size_t i = 0; i < transientRegistrations.size(); ++i) | 243 for (size_t i = 0; i < transientRegistrations.size(); ++i) |
233 transientRegistrations[i]->clearTransientRegistrations(); | 244 transientRegistrations[i]->clearTransientRegistrations(); |
234 | 245 |
235 if (m_records.isEmpty()) | 246 if (m_records.isEmpty()) |
236 return; | 247 return; |
237 | 248 |
238 Vector<RefPtr<MutationRecord> > records; | 249 WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > records; |
239 records.swap(m_records); | 250 records.swap(m_records); |
240 | 251 |
241 InspectorInstrumentation::willDeliverMutationRecords(m_callback->executionCo ntext(), this); | 252 InspectorInstrumentation::willDeliverMutationRecords(m_callback->executionCo ntext(), this); |
242 m_callback->call(records, this); | 253 m_callback->call(records, this); |
243 InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionCon text()); | 254 InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionCon text()); |
244 } | 255 } |
245 | 256 |
246 void MutationObserver::resumeSuspendedObservers() | 257 void MutationObserver::resumeSuspendedObservers() |
247 { | 258 { |
248 ASSERT(isMainThread()); | 259 ASSERT(isMainThread()); |
249 if (suspendedMutationObservers().isEmpty()) | 260 if (suspendedMutationObservers().isEmpty()) |
250 return; | 261 return; |
251 | 262 |
252 Vector<RefPtr<MutationObserver> > suspended; | 263 WillBeHeapVector<RefPtrWillBeMember<MutationObserver> > suspended; |
253 copyToVector(suspendedMutationObservers(), suspended); | 264 copyToVector(suspendedMutationObservers(), suspended); |
254 for (size_t i = 0; i < suspended.size(); ++i) { | 265 for (size_t i = 0; i < suspended.size(); ++i) { |
255 if (suspended[i]->canDeliver()) { | 266 if (suspended[i]->canDeliver()) { |
256 suspendedMutationObservers().remove(suspended[i]); | 267 suspendedMutationObservers().remove(suspended[i]); |
257 activateObserver(suspended[i]); | 268 activateObserver(suspended[i]); |
258 } | 269 } |
259 } | 270 } |
260 } | 271 } |
261 | 272 |
262 void MutationObserver::deliverMutations() | 273 void MutationObserver::deliverMutations() |
263 { | 274 { |
264 ASSERT(isMainThread()); | 275 ASSERT(isMainThread()); |
265 Vector<RefPtr<MutationObserver> > observers; | 276 WillBeHeapVector<RefPtrWillBeMember<MutationObserver> > observers; |
266 copyToVector(activeMutationObservers(), observers); | 277 copyToVector(activeMutationObservers(), observers); |
267 activeMutationObservers().clear(); | 278 activeMutationObservers().clear(); |
268 std::sort(observers.begin(), observers.end(), ObserverLessThan()); | 279 std::sort(observers.begin(), observers.end(), ObserverLessThan()); |
269 for (size_t i = 0; i < observers.size(); ++i) { | 280 for (size_t i = 0; i < observers.size(); ++i) { |
270 if (observers[i]->canDeliver()) | 281 if (observers[i]->canDeliver()) |
271 observers[i]->deliver(); | 282 observers[i]->deliver(); |
272 else | 283 else |
273 suspendedMutationObservers().add(observers[i]); | 284 suspendedMutationObservers().add(observers[i]); |
274 } | 285 } |
275 } | 286 } |
276 | 287 |
288 void MutationObserver::trace(Visitor* visitor) | |
289 { | |
290 visitor->trace(m_records); | |
291 visitor->trace(m_registrations); | |
292 } | |
293 | |
277 } // namespace WebCore | 294 } // namespace WebCore |
OLD | NEW |