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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 ASSERT(m_registrations.isEmpty()); |
| 71 #endif | 71 #endif |
| 72 if (!m_records.isEmpty()) | 72 cancelInspectorAsyncTasks(); |
| 73 InspectorInstrumentation::didClearAllMutationRecords(m_callback->getExec utionContext(), this); | |
| 74 } | 73 } |
| 75 | 74 |
| 76 void MutationObserver::observe(Node* node, const MutationObserverInit& observerI nit, ExceptionState& exceptionState) | 75 void MutationObserver::observe(Node* node, const MutationObserverInit& observerI nit, ExceptionState& exceptionState) |
| 77 { | 76 { |
| 78 ASSERT(node); | 77 ASSERT(node); |
| 79 | 78 |
| 80 MutationObserverOptions options = 0; | 79 MutationObserverOptions options = 0; |
| 81 | 80 |
| 82 if (observerInit.hasAttributeOldValue() && observerInit.attributeOldValue()) | 81 if (observerInit.hasAttributeOldValue() && observerInit.attributeOldValue()) |
| 83 options |= AttributeOldValue; | 82 options |= AttributeOldValue; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 126 exceptionState.throwTypeError("The options object must set at least one of 'attributes', 'characterData', or 'childList' to true."); | 125 exceptionState.throwTypeError("The options object must set at least one of 'attributes', 'characterData', or 'childList' to true."); |
| 127 return; | 126 return; |
| 128 } | 127 } |
| 129 | 128 |
| 130 node->registerMutationObserver(*this, options, attributeFilter); | 129 node->registerMutationObserver(*this, options, attributeFilter); |
| 131 } | 130 } |
| 132 | 131 |
| 133 MutationRecordVector MutationObserver::takeRecords() | 132 MutationRecordVector MutationObserver::takeRecords() |
| 134 { | 133 { |
| 135 MutationRecordVector records; | 134 MutationRecordVector records; |
| 135 cancelInspectorAsyncTasks(); | |
| 136 records.swap(m_records); | 136 records.swap(m_records); |
| 137 InspectorInstrumentation::didClearAllMutationRecords(m_callback->getExecutio nContext(), this); | |
| 138 return records; | 137 return records; |
| 139 } | 138 } |
| 140 | 139 |
| 141 void MutationObserver::disconnect() | 140 void MutationObserver::disconnect() |
| 142 { | 141 { |
| 142 cancelInspectorAsyncTasks(); | |
| 143 m_records.clear(); | 143 m_records.clear(); |
| 144 InspectorInstrumentation::didClearAllMutationRecords(m_callback->getExecutio nContext(), this); | |
| 145 MutationObserverRegistrationSet registrations(m_registrations); | 144 MutationObserverRegistrationSet registrations(m_registrations); |
| 146 for (auto& registration : registrations) { | 145 for (auto& registration : registrations) { |
| 147 // The registration may be already unregistered while iteration. | 146 // The registration may be already unregistered while iteration. |
| 148 // Only call unregister if it is still in the original set. | 147 // Only call unregister if it is still in the original set. |
| 149 if (m_registrations.contains(registration)) | 148 if (m_registrations.contains(registration)) |
| 150 registration->unregister(); | 149 registration->unregister(); |
| 151 } | 150 } |
| 152 ASSERT(m_registrations.isEmpty()); | 151 ASSERT(m_registrations.isEmpty()); |
| 153 } | 152 } |
| 154 | 153 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 182 Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutation s)); | 181 Microtask::enqueueMicrotask(WTF::bind(&MutationObserver::deliverMutation s)); |
| 183 | 182 |
| 184 activeMutationObservers().add(observer); | 183 activeMutationObservers().add(observer); |
| 185 } | 184 } |
| 186 | 185 |
| 187 void MutationObserver::enqueueMutationRecord(RawPtr<MutationRecord> mutation) | 186 void MutationObserver::enqueueMutationRecord(RawPtr<MutationRecord> mutation) |
| 188 { | 187 { |
| 189 ASSERT(isMainThread()); | 188 ASSERT(isMainThread()); |
| 190 m_records.append(mutation); | 189 m_records.append(mutation); |
| 191 activateObserver(this); | 190 activateObserver(this); |
| 192 InspectorInstrumentation::didEnqueueMutationRecord(m_callback->getExecutionC ontext(), this); | 191 InspectorInstrumentation::scheduleAsyncTask(m_callback->getExecutionContext( ), mutation->type(), mutation); |
| 193 } | 192 } |
| 194 | 193 |
| 195 void MutationObserver::setHasTransientRegistration() | 194 void MutationObserver::setHasTransientRegistration() |
| 196 { | 195 { |
| 197 ASSERT(isMainThread()); | 196 ASSERT(isMainThread()); |
| 198 activateObserver(this); | 197 activateObserver(this); |
| 199 } | 198 } |
| 200 | 199 |
| 201 HeapHashSet<Member<Node>> MutationObserver::getObservedNodes() const | 200 HeapHashSet<Member<Node>> MutationObserver::getObservedNodes() const |
| 202 { | 201 { |
| 203 HeapHashSet<Member<Node>> observedNodes; | 202 HeapHashSet<Member<Node>> observedNodes; |
| 204 for (const auto& registration : m_registrations) | 203 for (const auto& registration : m_registrations) |
| 205 registration->addRegistrationNodesToSet(observedNodes); | 204 registration->addRegistrationNodesToSet(observedNodes); |
| 206 return observedNodes; | 205 return observedNodes; |
| 207 } | 206 } |
| 208 | 207 |
| 209 bool MutationObserver::shouldBeSuspended() const | 208 bool MutationObserver::shouldBeSuspended() const |
| 210 { | 209 { |
| 211 return m_callback->getExecutionContext() && m_callback->getExecutionContext( )->activeDOMObjectsAreSuspended(); | 210 return m_callback->getExecutionContext() && m_callback->getExecutionContext( )->activeDOMObjectsAreSuspended(); |
| 212 } | 211 } |
| 213 | 212 |
| 213 void MutationObserver::cancelInspectorAsyncTasks() | |
| 214 { | |
| 215 for (auto& record : m_records) | |
| 216 InspectorInstrumentation::cancelAsyncTask(m_callback->getExecutionContex t(), record); | |
| 217 } | |
| 218 | |
| 214 void MutationObserver::deliver() | 219 void MutationObserver::deliver() |
| 215 { | 220 { |
| 216 ASSERT(!shouldBeSuspended()); | 221 ASSERT(!shouldBeSuspended()); |
| 217 | 222 |
| 218 // Calling clearTransientRegistrations() can modify m_registrations, so it's necessary | 223 // Calling clearTransientRegistrations() can modify m_registrations, so it's necessary |
| 219 // 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. |
| 220 HeapVector<Member<MutationObserverRegistration>, 1> transientRegistrations; | 225 HeapVector<Member<MutationObserverRegistration>, 1> transientRegistrations; |
| 221 for (auto& registration : m_registrations) { | 226 for (auto& registration : m_registrations) { |
| 222 if (registration->hasTransientRegistrations()) | 227 if (registration->hasTransientRegistrations()) |
| 223 transientRegistrations.append(registration); | 228 transientRegistrations.append(registration); |
| 224 } | 229 } |
| 225 for (size_t i = 0; i < transientRegistrations.size(); ++i) | 230 for (size_t i = 0; i < transientRegistrations.size(); ++i) |
| 226 transientRegistrations[i]->clearTransientRegistrations(); | 231 transientRegistrations[i]->clearTransientRegistrations(); |
| 227 | 232 |
| 228 if (m_records.isEmpty()) | 233 if (m_records.isEmpty()) |
| 229 return; | 234 return; |
| 230 | 235 |
| 231 MutationRecordVector records; | 236 MutationRecordVector records; |
| 232 records.swap(m_records); | 237 records.swap(m_records); |
| 233 | 238 |
| 234 InspectorInstrumentation::willDeliverMutationRecords(m_callback->getExecutio nContext(), this); | 239 if (InspectorInstrumentation::hasFrontends()) { |
| 240 for (size_t i = 0; i < records.size(); ++i) | |
| 241 InspectorInstrumentation::asyncTaskStarted(m_callback->getExecutionC ontext(), records[i]); | |
|
dgozman
2016/04/06 02:31:08
Let's make a single call.
| |
| 242 } | |
| 235 m_callback->call(records, this); | 243 m_callback->call(records, this); |
| 236 InspectorInstrumentation::didDeliverMutationRecords(m_callback->getExecution Context()); | 244 if (InspectorInstrumentation::hasFrontends()) { |
| 245 for (size_t i = records.size(); i > 0; --i) | |
| 246 InspectorInstrumentation::asyncTaskFinished(m_callback->getExecution Context(), records[i - 1]); | |
| 247 } | |
| 237 } | 248 } |
| 238 | 249 |
| 239 void MutationObserver::resumeSuspendedObservers() | 250 void MutationObserver::resumeSuspendedObservers() |
| 240 { | 251 { |
| 241 ASSERT(isMainThread()); | 252 ASSERT(isMainThread()); |
| 242 if (suspendedMutationObservers().isEmpty()) | 253 if (suspendedMutationObservers().isEmpty()) |
| 243 return; | 254 return; |
| 244 | 255 |
| 245 MutationObserverVector suspended; | 256 MutationObserverVector suspended; |
| 246 copyToVector(suspendedMutationObservers(), suspended); | 257 copyToVector(suspendedMutationObservers(), suspended); |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 269 | 280 |
| 270 DEFINE_TRACE(MutationObserver) | 281 DEFINE_TRACE(MutationObserver) |
| 271 { | 282 { |
| 272 visitor->trace(m_callback); | 283 visitor->trace(m_callback); |
| 273 visitor->trace(m_records); | 284 visitor->trace(m_records); |
| 274 visitor->trace(m_registrations); | 285 visitor->trace(m_registrations); |
| 275 visitor->trace(m_callback); | 286 visitor->trace(m_callback); |
| 276 } | 287 } |
| 277 | 288 |
| 278 } // namespace blink | 289 } // namespace blink |
| OLD | NEW |