Chromium Code Reviews| 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<RawPtrWillBeMember<MutationObserverRegistration> > registr ations(m_registrations); |
| 156 for (HashSet<MutationObserverRegistration*>::iterator iter = registrations.b egin(); iter != registrations.end(); ++iter) | 156 for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::i terator iter = registrations.begin(); iter != registrations.end(); ++iter) |
| 157 (*iter)->unregister(); | 157 (*iter)->unregister(); |
| 158 } | 158 } |
| 159 | 159 |
| 160 void MutationObserver::observationStarted(MutationObserverRegistration* registra tion) | 160 void MutationObserver::observationStarted(MutationObserverRegistration* registra tion) |
| 161 { | 161 { |
| 162 ASSERT(!m_registrations.contains(registration)); | 162 ASSERT(!m_registrations.contains(registration)); |
| 163 m_registrations.add(registration); | 163 m_registrations.add(registration); |
| 164 } | 164 } |
| 165 | 165 |
| 166 void MutationObserver::observationEnded(MutationObserverRegistration* registrati on) | 166 void MutationObserver::observationEnded(MutationObserverRegistration* registrati on) |
| 167 { | 167 { |
| 168 ASSERT(m_registrations.contains(registration)); | 168 ASSERT(m_registrations.contains(registration)); |
| 169 m_registrations.remove(registration); | 169 m_registrations.remove(registration); |
| 170 } | 170 } |
| 171 | 171 |
| 172 typedef HashSet<RefPtr<MutationObserver> > MutationObserverSet; | 172 typedef WillBeHeapHashSet<RefPtrWillBeMember<MutationObserver> > MutationObserve rSet; |
| 173 | 173 |
| 174 static MutationObserverSet& activeMutationObservers() | 174 static MutationObserverSet& activeMutationObservers() |
| 175 { | 175 { |
| 176 #if ENABLE(OILPAN) | |
| 177 DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, activeObservers, (new M utationObserverSet())); | |
| 178 return *activeObservers.get(); | |
|
haraken
2014/04/15 02:33:25
You can use 'return *activeObservers'.
sof
2014/04/15 22:00:53
Thanks, yes.
| |
| 179 #else | |
| 176 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, ()); | 180 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, ()); |
| 177 return activeObservers; | 181 return activeObservers; |
| 182 #endif | |
| 178 } | 183 } |
| 179 | 184 |
| 180 static MutationObserverSet& suspendedMutationObservers() | 185 static MutationObserverSet& suspendedMutationObservers() |
| 181 { | 186 { |
| 187 #if ENABLE(OILPAN) | |
| 188 DEFINE_STATIC_LOCAL(Persistent<MutationObserverSet>, suspendedObservers, (ne w MutationObserverSet())); | |
| 189 return *suspendedObservers.get(); | |
|
haraken
2014/04/15 02:33:25
Ditto.
sof
2014/04/15 22:00:53
Done.
| |
| 190 #else | |
| 182 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, ()); | 191 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, ()); |
| 183 return suspendedObservers; | 192 return suspendedObservers; |
| 193 #endif | |
| 184 } | 194 } |
| 185 | 195 |
| 186 static void activateObserver(PassRefPtr<MutationObserver> observer) | 196 static void activateObserver(PassRefPtrWillBeRawPtr<MutationObserver> observer) |
| 187 { | 197 { |
| 188 if (activeMutationObservers().isEmpty()) | 198 if (activeMutationObservers().isEmpty()) |
| 189 Microtask::enqueueMicrotask(&MutationObserver::deliverMutations); | 199 Microtask::enqueueMicrotask(&MutationObserver::deliverMutations); |
| 190 | 200 |
| 191 activeMutationObservers().add(observer); | 201 activeMutationObservers().add(observer); |
| 192 } | 202 } |
| 193 | 203 |
| 194 void MutationObserver::enqueueMutationRecord(PassRefPtr<MutationRecord> mutation ) | 204 void MutationObserver::enqueueMutationRecord(PassRefPtrWillBeRawPtr<MutationReco rd> mutation) |
| 195 { | 205 { |
| 196 ASSERT(isMainThread()); | 206 ASSERT(isMainThread()); |
| 197 m_records.append(mutation); | 207 m_records.append(mutation); |
| 198 activateObserver(this); | 208 activateObserver(this); |
| 199 InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionCont ext(), this); | 209 InspectorInstrumentation::didEnqueueMutationRecord(m_callback->executionCont ext(), this); |
| 200 } | 210 } |
| 201 | 211 |
| 202 void MutationObserver::setHasTransientRegistration() | 212 void MutationObserver::setHasTransientRegistration() |
| 203 { | 213 { |
| 204 ASSERT(isMainThread()); | 214 ASSERT(isMainThread()); |
| 205 activateObserver(this); | 215 activateObserver(this); |
| 206 } | 216 } |
| 207 | 217 |
| 208 HashSet<Node*> MutationObserver::getObservedNodes() const | 218 HashSet<Node*> MutationObserver::getObservedNodes() const |
| 209 { | 219 { |
| 210 HashSet<Node*> observedNodes; | 220 HashSet<Node*> observedNodes; |
| 211 for (HashSet<MutationObserverRegistration*>::const_iterator iter = m_registr ations.begin(); iter != m_registrations.end(); ++iter) | 221 for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::c onst_iterator iter = m_registrations.begin(); iter != m_registrations.end(); ++i ter) |
| 212 (*iter)->addRegistrationNodesToSet(observedNodes); | 222 (*iter)->addRegistrationNodesToSet(observedNodes); |
| 213 return observedNodes; | 223 return observedNodes; |
| 214 } | 224 } |
| 215 | 225 |
| 216 bool MutationObserver::canDeliver() | 226 bool MutationObserver::canDeliver() |
| 217 { | 227 { |
| 218 return !m_callback->executionContext()->activeDOMObjectsAreSuspended(); | 228 return !m_callback->executionContext()->activeDOMObjectsAreSuspended(); |
| 219 } | 229 } |
| 220 | 230 |
| 221 void MutationObserver::deliver() | 231 void MutationObserver::deliver() |
| 222 { | 232 { |
| 223 ASSERT(canDeliver()); | 233 ASSERT(canDeliver()); |
| 224 | 234 |
| 225 // Calling clearTransientRegistrations() can modify m_registrations, so it's necessary | 235 // Calling clearTransientRegistrations() can modify m_registrations, so it's necessary |
| 226 // to make a copy of the transient registrations before operating on them. | 236 // to make a copy of the transient registrations before operating on them. |
| 227 Vector<MutationObserverRegistration*, 1> transientRegistrations; | 237 WillBeHeapVector<RawPtrWillBeMember<MutationObserverRegistration>, 1> transi entRegistrations; |
| 228 for (HashSet<MutationObserverRegistration*>::iterator iter = m_registrations .begin(); iter != m_registrations.end(); ++iter) { | 238 for (WillBeHeapHashSet<RawPtrWillBeMember<MutationObserverRegistration> >::i terator iter = m_registrations.begin(); iter != m_registrations.end(); ++iter) { |
| 229 if ((*iter)->hasTransientRegistrations()) | 239 if ((*iter)->hasTransientRegistrations()) |
| 230 transientRegistrations.append(*iter); | 240 transientRegistrations.append(*iter); |
| 231 } | 241 } |
| 232 for (size_t i = 0; i < transientRegistrations.size(); ++i) | 242 for (size_t i = 0; i < transientRegistrations.size(); ++i) |
| 233 transientRegistrations[i]->clearTransientRegistrations(); | 243 transientRegistrations[i]->clearTransientRegistrations(); |
| 234 | 244 |
| 235 if (m_records.isEmpty()) | 245 if (m_records.isEmpty()) |
| 236 return; | 246 return; |
| 237 | 247 |
| 238 Vector<RefPtr<MutationRecord> > records; | 248 WillBeHeapVector<RefPtrWillBeMember<MutationRecord> > records; |
| 239 records.swap(m_records); | 249 records.swap(m_records); |
| 240 | 250 |
| 241 InspectorInstrumentation::willDeliverMutationRecords(m_callback->executionCo ntext(), this); | 251 InspectorInstrumentation::willDeliverMutationRecords(m_callback->executionCo ntext(), this); |
| 242 m_callback->call(records, this); | 252 m_callback->call(records, this); |
| 243 InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionCon text()); | 253 InspectorInstrumentation::didDeliverMutationRecords(m_callback->executionCon text()); |
| 244 } | 254 } |
| 245 | 255 |
| 246 void MutationObserver::resumeSuspendedObservers() | 256 void MutationObserver::resumeSuspendedObservers() |
| 247 { | 257 { |
| 248 ASSERT(isMainThread()); | 258 ASSERT(isMainThread()); |
| 249 if (suspendedMutationObservers().isEmpty()) | 259 if (suspendedMutationObservers().isEmpty()) |
| 250 return; | 260 return; |
| 251 | 261 |
| 252 Vector<RefPtr<MutationObserver> > suspended; | 262 WillBeHeapVector<RefPtrWillBeMember<MutationObserver> > suspended; |
| 253 copyToVector(suspendedMutationObservers(), suspended); | 263 copyToVector(suspendedMutationObservers(), suspended); |
| 254 for (size_t i = 0; i < suspended.size(); ++i) { | 264 for (size_t i = 0; i < suspended.size(); ++i) { |
| 255 if (suspended[i]->canDeliver()) { | 265 if (suspended[i]->canDeliver()) { |
| 256 suspendedMutationObservers().remove(suspended[i]); | 266 suspendedMutationObservers().remove(suspended[i]); |
| 257 activateObserver(suspended[i]); | 267 activateObserver(suspended[i]); |
| 258 } | 268 } |
| 259 } | 269 } |
| 260 } | 270 } |
| 261 | 271 |
| 262 void MutationObserver::deliverMutations() | 272 void MutationObserver::deliverMutations() |
| 263 { | 273 { |
| 264 ASSERT(isMainThread()); | 274 ASSERT(isMainThread()); |
| 265 Vector<RefPtr<MutationObserver> > observers; | 275 WillBeHeapVector<RefPtrWillBeMember<MutationObserver> > observers; |
| 266 copyToVector(activeMutationObservers(), observers); | 276 copyToVector(activeMutationObservers(), observers); |
| 267 activeMutationObservers().clear(); | 277 activeMutationObservers().clear(); |
| 268 std::sort(observers.begin(), observers.end(), ObserverLessThan()); | 278 std::sort(observers.begin(), observers.end(), ObserverLessThan()); |
| 269 for (size_t i = 0; i < observers.size(); ++i) { | 279 for (size_t i = 0; i < observers.size(); ++i) { |
| 270 if (observers[i]->canDeliver()) | 280 if (observers[i]->canDeliver()) |
| 271 observers[i]->deliver(); | 281 observers[i]->deliver(); |
| 272 else | 282 else |
| 273 suspendedMutationObservers().add(observers[i]); | 283 suspendedMutationObservers().add(observers[i]); |
| 274 } | 284 } |
| 275 } | 285 } |
| 276 | 286 |
| 287 void MutationObserver::trace(Visitor* visitor) | |
| 288 { | |
| 289 visitor->trace(m_records); | |
| 290 visitor->trace(m_registrations); | |
| 291 } | |
| 292 | |
| 277 } // namespace WebCore | 293 } // namespace WebCore |
| OLD | NEW |