OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 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 | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. 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 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 11 matching lines...) Expand all Loading... |
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 */ | 27 */ |
28 | 28 |
29 #include "modules/indexeddb/IDBRequest.h" | 29 #include "modules/indexeddb/IDBRequest.h" |
30 | 30 |
31 #include <memory> | 31 #include <memory> |
| 32 #include <utility> |
| 33 |
32 #include "bindings/core/v8/ExceptionState.h" | 34 #include "bindings/core/v8/ExceptionState.h" |
33 #include "bindings/core/v8/ToV8ForCore.h" | 35 #include "bindings/core/v8/ToV8ForCore.h" |
34 #include "bindings/modules/v8/ToV8ForModules.h" | 36 #include "bindings/modules/v8/ToV8ForModules.h" |
35 #include "bindings/modules/v8/V8BindingForModules.h" | 37 #include "bindings/modules/v8/V8BindingForModules.h" |
36 #include "core/dom/DOMException.h" | 38 #include "core/dom/DOMException.h" |
37 #include "core/dom/ExceptionCode.h" | 39 #include "core/dom/ExceptionCode.h" |
38 #include "core/dom/ExecutionContext.h" | 40 #include "core/dom/ExecutionContext.h" |
39 #include "core/events/EventQueue.h" | 41 #include "core/events/EventQueue.h" |
40 #include "modules/IndexedDBNames.h" | 42 #include "modules/IndexedDBNames.h" |
41 #include "modules/indexeddb/IDBCursorWithValue.h" | 43 #include "modules/indexeddb/IDBCursorWithValue.h" |
42 #include "modules/indexeddb/IDBDatabase.h" | 44 #include "modules/indexeddb/IDBDatabase.h" |
43 #include "modules/indexeddb/IDBEventDispatcher.h" | 45 #include "modules/indexeddb/IDBEventDispatcher.h" |
| 46 #include "modules/indexeddb/IDBRequestQueueItem.h" |
44 #include "modules/indexeddb/IDBTracing.h" | 47 #include "modules/indexeddb/IDBTracing.h" |
45 #include "modules/indexeddb/IDBValue.h" | 48 #include "modules/indexeddb/IDBValue.h" |
| 49 #include "modules/indexeddb/IDBValueWrapping.h" |
46 #include "modules/indexeddb/WebIDBCallbacksImpl.h" | 50 #include "modules/indexeddb/WebIDBCallbacksImpl.h" |
47 #include "platform/SharedBuffer.h" | 51 #include "platform/SharedBuffer.h" |
| 52 #include "platform/wtf/PtrUtil.h" |
48 #include "public/platform/WebBlobInfo.h" | 53 #include "public/platform/WebBlobInfo.h" |
49 | 54 |
50 using blink::WebIDBCursor; | 55 using blink::WebIDBCursor; |
51 | 56 |
52 namespace blink { | 57 namespace blink { |
53 | 58 |
54 IDBRequest* IDBRequest::Create(ScriptState* script_state, | 59 IDBRequest* IDBRequest::Create(ScriptState* script_state, |
55 IDBAny* source, | 60 IDBAny* source, |
56 IDBTransaction* transaction) { | 61 IDBTransaction* transaction) { |
57 IDBRequest* request = new IDBRequest(script_state, source, transaction); | 62 IDBRequest* request = new IDBRequest(script_state, source, transaction); |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
193 if (result_->GetType() == IDBAny::kIDBCursorType) | 198 if (result_->GetType() == IDBAny::kIDBCursorType) |
194 return result_->IdbCursor(); | 199 return result_->IdbCursor(); |
195 if (result_->GetType() == IDBAny::kIDBCursorWithValueType) | 200 if (result_->GetType() == IDBAny::kIDBCursorWithValueType) |
196 return result_->IdbCursorWithValue(); | 201 return result_->IdbCursorWithValue(); |
197 return nullptr; | 202 return nullptr; |
198 } | 203 } |
199 | 204 |
200 void IDBRequest::SetResultCursor(IDBCursor* cursor, | 205 void IDBRequest::SetResultCursor(IDBCursor* cursor, |
201 IDBKey* key, | 206 IDBKey* key, |
202 IDBKey* primary_key, | 207 IDBKey* primary_key, |
203 PassRefPtr<IDBValue> value) { | 208 RefPtr<IDBValue>&& value) { |
204 DCHECK_EQ(ready_state_, PENDING); | 209 DCHECK_EQ(ready_state_, PENDING); |
205 cursor_key_ = key; | 210 cursor_key_ = key; |
206 cursor_primary_key_ = primary_key; | 211 cursor_primary_key_ = primary_key; |
207 cursor_value_ = std::move(value); | 212 cursor_value_ = std::move(value); |
208 AckReceivedBlobs(cursor_value_.Get()); | 213 AckReceivedBlobs(cursor_value_.Get()); |
209 | 214 |
210 EnqueueResultInternal(IDBAny::Create(cursor)); | 215 EnqueueResultInternal(IDBAny::Create(cursor)); |
211 } | 216 } |
212 | 217 |
213 void IDBRequest::AckReceivedBlobs(const IDBValue* value) { | 218 void IDBRequest::AckReceivedBlobs(const IDBValue* value) { |
(...skipping 13 matching lines...) Expand all Loading... |
227 if (!GetExecutionContext()) | 232 if (!GetExecutionContext()) |
228 return false; | 233 return false; |
229 DCHECK(ready_state_ == PENDING || ready_state_ == DONE); | 234 DCHECK(ready_state_ == PENDING || ready_state_ == DONE); |
230 if (request_aborted_) | 235 if (request_aborted_) |
231 return false; | 236 return false; |
232 DCHECK_EQ(ready_state_, PENDING); | 237 DCHECK_EQ(ready_state_, PENDING); |
233 DCHECK(!error_ && !result_); | 238 DCHECK(!error_ && !result_); |
234 return true; | 239 return true; |
235 } | 240 } |
236 | 241 |
| 242 void IDBRequest::HandleResponse(DOMException* error) { |
| 243 transit_blob_handles_.clear(); |
| 244 if (!transaction_ || !transaction_->HasQueuedResults()) |
| 245 return EnqueueResponse(error); |
| 246 transaction_->EnqueueResult( |
| 247 WTF::MakeUnique<IDBRequestQueueItem>(this, error)); |
| 248 } |
| 249 |
| 250 void IDBRequest::HandleResponse(IDBKey* key) { |
| 251 transit_blob_handles_.clear(); |
| 252 DCHECK(transaction_); |
| 253 if (!transaction_->HasQueuedResults()) |
| 254 return EnqueueResponse(key); |
| 255 transaction_->EnqueueResult(WTF::MakeUnique<IDBRequestQueueItem>(this, key)); |
| 256 } |
| 257 |
| 258 void IDBRequest::HandleResponse(int64_t value_or_old_version) { |
| 259 transit_blob_handles_.clear(); |
| 260 if (!transaction_ || !transaction_->HasQueuedResults()) |
| 261 return EnqueueResponse(value_or_old_version); |
| 262 transaction_->EnqueueResult( |
| 263 WTF::MakeUnique<IDBRequestQueueItem>(this, value_or_old_version)); |
| 264 } |
| 265 |
| 266 void IDBRequest::HandleResponse() { |
| 267 transit_blob_handles_.clear(); |
| 268 if (!transaction_ || !transaction_->HasQueuedResults()) |
| 269 return EnqueueResponse(); |
| 270 transaction_->EnqueueResult(WTF::MakeUnique<IDBRequestQueueItem>(this)); |
| 271 } |
| 272 |
| 273 void IDBRequest::HandleResponse(std::unique_ptr<WebIDBCursor> backend, |
| 274 IDBKey* key, |
| 275 IDBKey* primary_key, |
| 276 RefPtr<IDBValue>&& value) { |
| 277 bool is_wrapped = IDBValueUnwrapper::IsWrapped(value.Get()); |
| 278 DCHECK(transaction_); |
| 279 if (!transaction_->HasQueuedResults() && !is_wrapped) { |
| 280 return EnqueueResponse(std::move(backend), key, primary_key, |
| 281 std::move(value)); |
| 282 } |
| 283 transaction_->EnqueueResult(WTF::MakeUnique<IDBRequestQueueItem>( |
| 284 this, std::move(backend), key, primary_key, std::move(value), |
| 285 is_wrapped)); |
| 286 } |
| 287 |
| 288 void IDBRequest::HandleResponse(RefPtr<IDBValue>&& value) { |
| 289 bool is_wrapped = IDBValueUnwrapper::IsWrapped(value.Get()); |
| 290 DCHECK(transaction_); |
| 291 if (!transaction_->HasQueuedResults() && !is_wrapped) |
| 292 return EnqueueResponse(std::move(value)); |
| 293 transaction_->EnqueueResult( |
| 294 WTF::MakeUnique<IDBRequestQueueItem>(this, std::move(value), is_wrapped)); |
| 295 } |
| 296 |
| 297 void IDBRequest::HandleResponse(const Vector<RefPtr<IDBValue>>& values) { |
| 298 bool is_wrapped = IDBValueUnwrapper::IsWrapped(values); |
| 299 DCHECK(transaction_); |
| 300 if (!transaction_->HasQueuedResults() && !is_wrapped) |
| 301 return EnqueueResponse(values); |
| 302 transaction_->EnqueueResult( |
| 303 WTF::MakeUnique<IDBRequestQueueItem>(this, values, is_wrapped)); |
| 304 } |
| 305 |
| 306 void IDBRequest::HandleResponse(IDBKey* key, |
| 307 IDBKey* primary_key, |
| 308 RefPtr<IDBValue>&& value) { |
| 309 bool is_wrapped = IDBValueUnwrapper::IsWrapped(value.Get()); |
| 310 |
| 311 DCHECK(transaction_); |
| 312 if (!transaction_->HasQueuedResults() && !is_wrapped) |
| 313 return EnqueueResponse(key, primary_key, std::move(value)); |
| 314 |
| 315 transaction_->EnqueueResult(WTF::MakeUnique<IDBRequestQueueItem>( |
| 316 this, key, primary_key, std::move(value), is_wrapped)); |
| 317 } |
| 318 |
237 void IDBRequest::EnqueueResponse(DOMException* error) { | 319 void IDBRequest::EnqueueResponse(DOMException* error) { |
238 IDB_TRACE("IDBRequest::onError()"); | 320 IDB_TRACE("IDBRequest::EnqueueResponse(DOMException)"); |
239 ClearPutOperationBlobs(); | |
240 if (!ShouldEnqueueEvent()) | 321 if (!ShouldEnqueueEvent()) |
241 return; | 322 return; |
242 | 323 |
243 error_ = error; | 324 error_ = error; |
244 SetResult(IDBAny::CreateUndefined()); | 325 SetResult(IDBAny::CreateUndefined()); |
245 pending_cursor_.Clear(); | 326 pending_cursor_.Clear(); |
246 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); | 327 EnqueueEvent(Event::CreateCancelableBubble(EventTypeNames::error)); |
247 } | 328 } |
248 | 329 |
249 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { | 330 void IDBRequest::EnqueueResponse(const Vector<String>& string_list) { |
250 IDB_TRACE("IDBRequest::onSuccess(StringList)"); | 331 IDB_TRACE("IDBRequest::onSuccess(StringList)"); |
251 if (!ShouldEnqueueEvent()) | 332 if (!ShouldEnqueueEvent()) |
252 return; | 333 return; |
253 | 334 |
254 DOMStringList* dom_string_list = DOMStringList::Create(); | 335 DOMStringList* dom_string_list = DOMStringList::Create(); |
255 for (size_t i = 0; i < string_list.size(); ++i) | 336 for (size_t i = 0; i < string_list.size(); ++i) |
256 dom_string_list->Append(string_list[i]); | 337 dom_string_list->Append(string_list[i]); |
257 EnqueueResultInternal(IDBAny::Create(dom_string_list)); | 338 EnqueueResultInternal(IDBAny::Create(dom_string_list)); |
258 } | 339 } |
259 | 340 |
260 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, | 341 void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, |
261 IDBKey* key, | 342 IDBKey* key, |
262 IDBKey* primary_key, | 343 IDBKey* primary_key, |
263 PassRefPtr<IDBValue> value) { | 344 RefPtr<IDBValue>&& value) { |
264 IDB_TRACE("IDBRequest::onSuccess(IDBCursor)"); | 345 IDB_TRACE("IDBRequest::EnqueueResponse(IDBCursor)"); |
265 if (!ShouldEnqueueEvent()) | 346 if (!ShouldEnqueueEvent()) |
266 return; | 347 return; |
267 | 348 |
268 DCHECK(!pending_cursor_); | 349 DCHECK(!pending_cursor_); |
269 IDBCursor* cursor = nullptr; | 350 IDBCursor* cursor = nullptr; |
270 switch (cursor_type_) { | 351 switch (cursor_type_) { |
271 case IndexedDB::kCursorKeyOnly: | 352 case IndexedDB::kCursorKeyOnly: |
272 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this, | 353 cursor = IDBCursor::Create(std::move(backend), cursor_direction_, this, |
273 source_.Get(), transaction_.Get()); | 354 source_.Get(), transaction_.Get()); |
274 break; | 355 break; |
275 case IndexedDB::kCursorKeyAndValue: | 356 case IndexedDB::kCursorKeyAndValue: |
276 cursor = | 357 cursor = |
277 IDBCursorWithValue::Create(std::move(backend), cursor_direction_, | 358 IDBCursorWithValue::Create(std::move(backend), cursor_direction_, |
278 this, source_.Get(), transaction_.Get()); | 359 this, source_.Get(), transaction_.Get()); |
279 break; | 360 break; |
280 default: | 361 default: |
281 NOTREACHED(); | 362 NOTREACHED(); |
282 } | 363 } |
283 SetResultCursor(cursor, key, primary_key, std::move(value)); | 364 SetResultCursor(cursor, key, primary_key, std::move(value)); |
284 } | 365 } |
285 | 366 |
286 void IDBRequest::EnqueueResponse(IDBKey* idb_key) { | 367 void IDBRequest::EnqueueResponse(IDBKey* idb_key) { |
287 IDB_TRACE("IDBRequest::onSuccess(IDBKey)"); | 368 IDB_TRACE("IDBRequest::EnqueueResponse(IDBKey)"); |
288 ClearPutOperationBlobs(); | |
289 if (!ShouldEnqueueEvent()) | 369 if (!ShouldEnqueueEvent()) |
290 return; | 370 return; |
291 | 371 |
292 if (idb_key && idb_key->IsValid()) | 372 if (idb_key && idb_key->IsValid()) |
293 EnqueueResultInternal(IDBAny::Create(idb_key)); | 373 EnqueueResultInternal(IDBAny::Create(idb_key)); |
294 else | 374 else |
295 EnqueueResultInternal(IDBAny::CreateUndefined()); | 375 EnqueueResultInternal(IDBAny::CreateUndefined()); |
296 } | 376 } |
297 | 377 |
298 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { | 378 void IDBRequest::EnqueueResponse(const Vector<RefPtr<IDBValue>>& values) { |
299 IDB_TRACE("IDBRequest::onSuccess([IDBValue])"); | 379 IDB_TRACE("IDBRequest::EnqueueResponse([IDBValue])"); |
300 if (!ShouldEnqueueEvent()) | 380 if (!ShouldEnqueueEvent()) |
301 return; | 381 return; |
302 | 382 |
303 AckReceivedBlobs(values); | 383 AckReceivedBlobs(values); |
304 EnqueueResultInternal(IDBAny::Create(values)); | 384 EnqueueResultInternal(IDBAny::Create(values)); |
305 } | 385 } |
306 | 386 |
307 #if DCHECK_IS_ON() | 387 #if DCHECK_IS_ON() |
308 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { | 388 static IDBObjectStore* EffectiveObjectStore(IDBAny* source) { |
309 if (source->GetType() == IDBAny::kIDBObjectStoreType) | 389 if (source->GetType() == IDBAny::kIDBObjectStoreType) |
310 return source->IdbObjectStore(); | 390 return source->IdbObjectStore(); |
311 if (source->GetType() == IDBAny::kIDBIndexType) | 391 if (source->GetType() == IDBAny::kIDBIndexType) |
312 return source->IdbIndex()->objectStore(); | 392 return source->IdbIndex()->objectStore(); |
313 | 393 |
314 NOTREACHED(); | 394 NOTREACHED(); |
315 return nullptr; | 395 return nullptr; |
316 } | 396 } |
317 #endif // DCHECK_IS_ON() | 397 #endif // DCHECK_IS_ON() |
318 | 398 |
319 void IDBRequest::EnqueueResponse(PassRefPtr<IDBValue> prp_value) { | 399 void IDBRequest::EnqueueResponse(RefPtr<IDBValue>&& value) { |
320 IDB_TRACE("IDBRequest::onSuccess(IDBValue)"); | 400 IDB_TRACE("IDBRequest::EnqueueResponse(IDBValue)"); |
321 if (!ShouldEnqueueEvent()) | 401 if (!ShouldEnqueueEvent()) |
322 return; | 402 return; |
323 | 403 |
324 RefPtr<IDBValue> value(std::move(prp_value)); | |
325 AckReceivedBlobs(value.Get()); | 404 AckReceivedBlobs(value.Get()); |
326 | 405 |
327 if (pending_cursor_) { | 406 if (pending_cursor_) { |
328 // Value should be null, signifying the end of the cursor's range. | 407 // Value should be null, signifying the end of the cursor's range. |
329 DCHECK(value->IsNull()); | 408 DCHECK(value->IsNull()); |
330 DCHECK(!value->BlobInfo()->size()); | 409 DCHECK(!value->BlobInfo()->size()); |
331 pending_cursor_->Close(); | 410 pending_cursor_->Close(); |
332 pending_cursor_.Clear(); | 411 pending_cursor_.Clear(); |
333 } | 412 } |
334 | 413 |
335 #if DCHECK_IS_ON() | 414 #if DCHECK_IS_ON() |
336 DCHECK(!value->PrimaryKey() || | 415 DCHECK(!value->PrimaryKey() || |
337 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath()); | 416 value->KeyPath() == EffectiveObjectStore(source_)->IdbKeyPath()); |
338 #endif | 417 #endif |
339 | 418 |
340 EnqueueResultInternal(IDBAny::Create(value.Release())); | 419 EnqueueResultInternal(IDBAny::Create(std::move(value))); |
341 } | 420 } |
342 | 421 |
343 void IDBRequest::EnqueueResponse(int64_t value) { | 422 void IDBRequest::EnqueueResponse(int64_t value) { |
344 IDB_TRACE("IDBRequest::onSuccess(int64_t)"); | 423 IDB_TRACE("IDBRequest::EnqueueResponse(int64_t)"); |
345 if (!ShouldEnqueueEvent()) | 424 if (!ShouldEnqueueEvent()) |
346 return; | 425 return; |
347 EnqueueResultInternal(IDBAny::Create(value)); | 426 EnqueueResultInternal(IDBAny::Create(value)); |
348 } | 427 } |
349 | 428 |
350 void IDBRequest::EnqueueResponse() { | 429 void IDBRequest::EnqueueResponse() { |
351 IDB_TRACE("IDBRequest::onSuccess()"); | 430 IDB_TRACE("IDBRequest::EnqueueResponse()"); |
352 if (!ShouldEnqueueEvent()) | 431 if (!ShouldEnqueueEvent()) |
353 return; | 432 return; |
354 EnqueueResultInternal(IDBAny::CreateUndefined()); | 433 EnqueueResultInternal(IDBAny::CreateUndefined()); |
355 } | 434 } |
356 | 435 |
357 void IDBRequest::EnqueueResultInternal(IDBAny* result) { | 436 void IDBRequest::EnqueueResultInternal(IDBAny* result) { |
358 DCHECK(GetExecutionContext()); | 437 DCHECK(GetExecutionContext()); |
359 DCHECK(!pending_cursor_); | 438 DCHECK(!pending_cursor_); |
360 DCHECK(transit_blob_handles_.IsEmpty()); | 439 DCHECK(transit_blob_handles_.IsEmpty()); |
361 SetResult(result); | 440 SetResult(result); |
362 EnqueueEvent(Event::Create(EventTypeNames::success)); | 441 EnqueueEvent(Event::Create(EventTypeNames::success)); |
363 } | 442 } |
364 | 443 |
365 void IDBRequest::SetResult(IDBAny* result) { | 444 void IDBRequest::SetResult(IDBAny* result) { |
366 result_ = result; | 445 result_ = result; |
367 result_dirty_ = true; | 446 result_dirty_ = true; |
368 } | 447 } |
369 | 448 |
370 void IDBRequest::EnqueueResponse(IDBKey* key, | 449 void IDBRequest::EnqueueResponse(IDBKey* key, |
371 IDBKey* primary_key, | 450 IDBKey* primary_key, |
372 PassRefPtr<IDBValue> value) { | 451 RefPtr<IDBValue>&& value) { |
373 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); | 452 IDB_TRACE("IDBRequest::EnqueueResponse(IDBKey, IDBKey primaryKey, IDBValue)"); |
374 if (!ShouldEnqueueEvent()) | 453 if (!ShouldEnqueueEvent()) |
375 return; | 454 return; |
376 | 455 |
377 DCHECK(pending_cursor_); | 456 DCHECK(pending_cursor_); |
378 SetResultCursor(pending_cursor_.Release(), key, primary_key, | 457 SetResultCursor(pending_cursor_.Release(), key, primary_key, |
379 std::move(value)); | 458 std::move(value)); |
380 } | 459 } |
381 | 460 |
382 bool IDBRequest::HasPendingActivity() const { | 461 bool IDBRequest::HasPendingActivity() const { |
383 // FIXME: In an ideal world, we should return true as long as anyone has a or | 462 // FIXME: In an ideal world, we should return true as long as anyone has a or |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 } | 632 } |
554 | 633 |
555 void IDBRequest::DequeueEvent(Event* event) { | 634 void IDBRequest::DequeueEvent(Event* event) { |
556 for (size_t i = 0; i < enqueued_events_.size(); ++i) { | 635 for (size_t i = 0; i < enqueued_events_.size(); ++i) { |
557 if (enqueued_events_[i].Get() == event) | 636 if (enqueued_events_[i].Get() == event) |
558 enqueued_events_.erase(i); | 637 enqueued_events_.erase(i); |
559 } | 638 } |
560 } | 639 } |
561 | 640 |
562 } // namespace blink | 641 } // namespace blink |
OLD | NEW |