| 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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 | 47 |
| 48 struct MutationObserver::ObserverLessThan { | 48 struct MutationObserver::ObserverLessThan { |
| 49 bool operator()(const Member<MutationObserver>& lhs, const Member<MutationOb
server>& rhs) | 49 bool operator()(const Member<MutationObserver>& lhs, const Member<MutationOb
server>& rhs) |
| 50 { | 50 { |
| 51 return lhs->m_priority < rhs->m_priority; | 51 return lhs->m_priority < rhs->m_priority; |
| 52 } | 52 } |
| 53 }; | 53 }; |
| 54 | 54 |
| 55 RawPtr<MutationObserver> MutationObserver::create(RawPtr<MutationCallback> callb
ack) | 55 RawPtr<MutationObserver> MutationObserver::create(RawPtr<MutationCallback> callb
ack) |
| 56 { | 56 { |
| 57 ASSERT(isMainThread()); | 57 DCHECK(isMainThread()); |
| 58 return new MutationObserver(callback); | 58 return new MutationObserver(callback); |
| 59 } | 59 } |
| 60 | 60 |
| 61 MutationObserver::MutationObserver(RawPtr<MutationCallback> callback) | 61 MutationObserver::MutationObserver(RawPtr<MutationCallback> callback) |
| 62 : m_callback(callback) | 62 : m_callback(callback) |
| 63 , m_priority(s_observerPriority++) | 63 , m_priority(s_observerPriority++) |
| 64 { | 64 { |
| 65 } | 65 } |
| 66 | 66 |
| 67 MutationObserver::~MutationObserver() | 67 MutationObserver::~MutationObserver() |
| 68 { | 68 { |
| 69 #if !ENABLE(OILPAN) | 69 #if !ENABLE(OILPAN) |
| 70 ASSERT(m_registrations.isEmpty()); | 70 DCHECK(m_registrations.isEmpty()); |
| 71 #endif | 71 #endif |
| 72 cancelInspectorAsyncTasks(); | 72 cancelInspectorAsyncTasks(); |
| 73 } | 73 } |
| 74 | 74 |
| 75 void MutationObserver::observe(Node* node, const MutationObserverInit& observerI
nit, ExceptionState& exceptionState) | 75 void MutationObserver::observe(Node* node, const MutationObserverInit& observerI
nit, ExceptionState& exceptionState) |
| 76 { | 76 { |
| 77 ASSERT(node); | 77 DCHECK(node); |
| 78 | 78 |
| 79 MutationObserverOptions options = 0; | 79 MutationObserverOptions options = 0; |
| 80 | 80 |
| 81 if (observerInit.hasAttributeOldValue() && observerInit.attributeOldValue()) | 81 if (observerInit.hasAttributeOldValue() && observerInit.attributeOldValue()) |
| 82 options |= AttributeOldValue; | 82 options |= AttributeOldValue; |
| 83 | 83 |
| 84 HashSet<AtomicString> attributeFilter; | 84 HashSet<AtomicString> attributeFilter; |
| 85 if (observerInit.hasAttributeFilter()) { | 85 if (observerInit.hasAttributeFilter()) { |
| 86 const Vector<String>& sequence = observerInit.attributeFilter(); | 86 const Vector<String>& sequence = observerInit.attributeFilter(); |
| 87 for (unsigned i = 0; i < sequence.size(); ++i) | 87 for (unsigned i = 0; i < sequence.size(); ++i) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 { | 141 { |
| 142 cancelInspectorAsyncTasks(); | 142 cancelInspectorAsyncTasks(); |
| 143 m_records.clear(); | 143 m_records.clear(); |
| 144 MutationObserverRegistrationSet registrations(m_registrations); | 144 MutationObserverRegistrationSet registrations(m_registrations); |
| 145 for (auto& registration : registrations) { | 145 for (auto& registration : registrations) { |
| 146 // The registration may be already unregistered while iteration. | 146 // The registration may be already unregistered while iteration. |
| 147 // Only call unregister if it is still in the original set. | 147 // Only call unregister if it is still in the original set. |
| 148 if (m_registrations.contains(registration)) | 148 if (m_registrations.contains(registration)) |
| 149 registration->unregister(); | 149 registration->unregister(); |
| 150 } | 150 } |
| 151 ASSERT(m_registrations.isEmpty()); | 151 DCHECK(m_registrations.isEmpty()); |
| 152 } | 152 } |
| 153 | 153 |
| 154 void MutationObserver::observationStarted(MutationObserverRegistration* registra
tion) | 154 void MutationObserver::observationStarted(MutationObserverRegistration* registra
tion) |
| 155 { | 155 { |
| 156 ASSERT(!m_registrations.contains(registration)); | 156 DCHECK(!m_registrations.contains(registration)); |
| 157 m_registrations.add(registration); | 157 m_registrations.add(registration); |
| 158 } | 158 } |
| 159 | 159 |
| 160 void MutationObserver::observationEnded(MutationObserverRegistration* registrati
on) | 160 void MutationObserver::observationEnded(MutationObserverRegistration* registrati
on) |
| 161 { | 161 { |
| 162 ASSERT(m_registrations.contains(registration)); | 162 DCHECK(m_registrations.contains(registration)); |
| 163 m_registrations.remove(registration); | 163 m_registrations.remove(registration); |
| 164 } | 164 } |
| 165 | 165 |
| 166 static MutationObserverSet& activeMutationObservers() | 166 static MutationObserverSet& activeMutationObservers() |
| 167 { | 167 { |
| 168 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, (new MutationObser
verSet)); | 168 DEFINE_STATIC_LOCAL(MutationObserverSet, activeObservers, (new MutationObser
verSet)); |
| 169 return activeObservers; | 169 return activeObservers; |
| 170 } | 170 } |
| 171 | 171 |
| 172 static MutationObserverSet& suspendedMutationObservers() | 172 static MutationObserverSet& suspendedMutationObservers() |
| 173 { | 173 { |
| 174 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, (new MutationOb
serverSet)); | 174 DEFINE_STATIC_LOCAL(MutationObserverSet, suspendedObservers, (new MutationOb
serverSet)); |
| 175 return suspendedObservers; | 175 return suspendedObservers; |
| 176 } | 176 } |
| 177 | 177 |
| 178 static void activateObserver(RawPtr<MutationObserver> observer) | 178 static void activateObserver(RawPtr<MutationObserver> observer) |
| 179 { | 179 { |
| 180 if (activeMutationObservers().isEmpty()) | 180 if (activeMutationObservers().isEmpty()) |
| 181 Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutation
s)); | 181 Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutation
s)); |
| 182 | 182 |
| 183 activeMutationObservers().add(observer); | 183 activeMutationObservers().add(observer); |
| 184 } | 184 } |
| 185 | 185 |
| 186 void MutationObserver::enqueueMutationRecord(RawPtr<MutationRecord> mutation) | 186 void MutationObserver::enqueueMutationRecord(RawPtr<MutationRecord> mutation) |
| 187 { | 187 { |
| 188 ASSERT(isMainThread()); | 188 DCHECK(isMainThread()); |
| 189 m_records.append(mutation); | 189 m_records.append(mutation); |
| 190 activateObserver(this); | 190 activateObserver(this); |
| 191 InspectorInstrumentation::asyncTaskScheduled(m_callback->getExecutionContext
(), mutation->type(), mutation); | 191 InspectorInstrumentation::asyncTaskScheduled(m_callback->getExecutionContext
(), mutation->type(), mutation); |
| 192 } | 192 } |
| 193 | 193 |
| 194 void MutationObserver::setHasTransientRegistration() | 194 void MutationObserver::setHasTransientRegistration() |
| 195 { | 195 { |
| 196 ASSERT(isMainThread()); | 196 DCHECK(isMainThread()); |
| 197 activateObserver(this); | 197 activateObserver(this); |
| 198 } | 198 } |
| 199 | 199 |
| 200 HeapHashSet<Member<Node>> MutationObserver::getObservedNodes() const | 200 HeapHashSet<Member<Node>> MutationObserver::getObservedNodes() const |
| 201 { | 201 { |
| 202 HeapHashSet<Member<Node>> observedNodes; | 202 HeapHashSet<Member<Node>> observedNodes; |
| 203 for (const auto& registration : m_registrations) | 203 for (const auto& registration : m_registrations) |
| 204 registration->addRegistrationNodesToSet(observedNodes); | 204 registration->addRegistrationNodesToSet(observedNodes); |
| 205 return observedNodes; | 205 return observedNodes; |
| 206 } | 206 } |
| 207 | 207 |
| 208 bool MutationObserver::shouldBeSuspended() const | 208 bool MutationObserver::shouldBeSuspended() const |
| 209 { | 209 { |
| 210 return m_callback->getExecutionContext() && m_callback->getExecutionContext(
)->activeDOMObjectsAreSuspended(); | 210 return m_callback->getExecutionContext() && m_callback->getExecutionContext(
)->activeDOMObjectsAreSuspended(); |
| 211 } | 211 } |
| 212 | 212 |
| 213 void MutationObserver::cancelInspectorAsyncTasks() | 213 void MutationObserver::cancelInspectorAsyncTasks() |
| 214 { | 214 { |
| 215 for (auto& record : m_records) | 215 for (auto& record : m_records) |
| 216 InspectorInstrumentation::asyncTaskCanceled(m_callback->getExecutionCont
ext(), record); | 216 InspectorInstrumentation::asyncTaskCanceled(m_callback->getExecutionCont
ext(), record); |
| 217 } | 217 } |
| 218 | 218 |
| 219 void MutationObserver::deliver() | 219 void MutationObserver::deliver() |
| 220 { | 220 { |
| 221 ASSERT(!shouldBeSuspended()); | 221 DCHECK(!shouldBeSuspended()); |
| 222 | 222 |
| 223 // Calling clearTransientRegistrations() can modify m_registrations, so it's
necessary | 223 // Calling clearTransientRegistrations() can modify m_registrations, so it's
necessary |
| 224 // to make a copy of the transient registrations before operating on them. | 224 // to make a copy of the transient registrations before operating on them. |
| 225 HeapVector<Member<MutationObserverRegistration>, 1> transientRegistrations; | 225 HeapVector<Member<MutationObserverRegistration>, 1> transientRegistrations; |
| 226 for (auto& registration : m_registrations) { | 226 for (auto& registration : m_registrations) { |
| 227 if (registration->hasTransientRegistrations()) | 227 if (registration->hasTransientRegistrations()) |
| 228 transientRegistrations.append(registration); | 228 transientRegistrations.append(registration); |
| 229 } | 229 } |
| 230 for (size_t i = 0; i < transientRegistrations.size(); ++i) | 230 for (size_t i = 0; i < transientRegistrations.size(); ++i) |
| 231 transientRegistrations[i]->clearTransientRegistrations(); | 231 transientRegistrations[i]->clearTransientRegistrations(); |
| 232 | 232 |
| 233 if (m_records.isEmpty()) | 233 if (m_records.isEmpty()) |
| 234 return; | 234 return; |
| 235 | 235 |
| 236 MutationRecordVector records; | 236 MutationRecordVector records; |
| 237 records.swap(m_records); | 237 records.swap(m_records); |
| 238 | 238 |
| 239 // Report the first (earliest) stack as the async cause. | 239 // Report the first (earliest) stack as the async cause. |
| 240 InspectorInstrumentation::AsyncTask asyncTask(m_callback->getExecutionContex
t(), records.first()); | 240 InspectorInstrumentation::AsyncTask asyncTask(m_callback->getExecutionContex
t(), records.first()); |
| 241 m_callback->call(records, this); | 241 m_callback->call(records, this); |
| 242 } | 242 } |
| 243 | 243 |
| 244 void MutationObserver::resumeSuspendedObservers() | 244 void MutationObserver::resumeSuspendedObservers() |
| 245 { | 245 { |
| 246 ASSERT(isMainThread()); | 246 DCHECK(isMainThread()); |
| 247 if (suspendedMutationObservers().isEmpty()) | 247 if (suspendedMutationObservers().isEmpty()) |
| 248 return; | 248 return; |
| 249 | 249 |
| 250 MutationObserverVector suspended; | 250 MutationObserverVector suspended; |
| 251 copyToVector(suspendedMutationObservers(), suspended); | 251 copyToVector(suspendedMutationObservers(), suspended); |
| 252 for (size_t i = 0; i < suspended.size(); ++i) { | 252 for (size_t i = 0; i < suspended.size(); ++i) { |
| 253 if (!suspended[i]->shouldBeSuspended()) { | 253 if (!suspended[i]->shouldBeSuspended()) { |
| 254 suspendedMutationObservers().remove(suspended[i]); | 254 suspendedMutationObservers().remove(suspended[i]); |
| 255 activateObserver(suspended[i]); | 255 activateObserver(suspended[i]); |
| 256 } | 256 } |
| 257 } | 257 } |
| 258 } | 258 } |
| 259 | 259 |
| 260 void MutationObserver::deliverMutations() | 260 void MutationObserver::deliverMutations() |
| 261 { | 261 { |
| 262 ASSERT(isMainThread()); | 262 DCHECK(isMainThread()); |
| 263 MutationObserverVector observers; | 263 MutationObserverVector observers; |
| 264 copyToVector(activeMutationObservers(), observers); | 264 copyToVector(activeMutationObservers(), observers); |
| 265 activeMutationObservers().clear(); | 265 activeMutationObservers().clear(); |
| 266 std::sort(observers.begin(), observers.end(), ObserverLessThan()); | 266 std::sort(observers.begin(), observers.end(), ObserverLessThan()); |
| 267 for (size_t i = 0; i < observers.size(); ++i) { | 267 for (size_t i = 0; i < observers.size(); ++i) { |
| 268 if (observers[i]->shouldBeSuspended()) | 268 if (observers[i]->shouldBeSuspended()) |
| 269 suspendedMutationObservers().add(observers[i]); | 269 suspendedMutationObservers().add(observers[i]); |
| 270 else | 270 else |
| 271 observers[i]->deliver(); | 271 observers[i]->deliver(); |
| 272 } | 272 } |
| 273 } | 273 } |
| 274 | 274 |
| 275 DEFINE_TRACE(MutationObserver) | 275 DEFINE_TRACE(MutationObserver) |
| 276 { | 276 { |
| 277 visitor->trace(m_callback); | 277 visitor->trace(m_callback); |
| 278 visitor->trace(m_records); | 278 visitor->trace(m_records); |
| 279 visitor->trace(m_registrations); | 279 visitor->trace(m_registrations); |
| 280 visitor->trace(m_callback); | 280 visitor->trace(m_callback); |
| 281 } | 281 } |
| 282 | 282 |
| 283 } // namespace blink | 283 } // namespace blink |
| OLD | NEW |