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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 | 91 |
92 ScriptValue IDBRequest::result(ScriptState* scriptState, | 92 ScriptValue IDBRequest::result(ScriptState* scriptState, |
93 ExceptionState& exceptionState) { | 93 ExceptionState& exceptionState) { |
94 if (m_readyState != DONE) { | 94 if (m_readyState != DONE) { |
95 // Must throw if returning an empty value. Message is arbitrary since it | 95 // Must throw if returning an empty value. Message is arbitrary since it |
96 // will never be seen. | 96 // will never be seen. |
97 exceptionState.throwDOMException( | 97 exceptionState.throwDOMException( |
98 InvalidStateError, IDBDatabase::requestNotFinishedErrorMessage); | 98 InvalidStateError, IDBDatabase::requestNotFinishedErrorMessage); |
99 return ScriptValue(); | 99 return ScriptValue(); |
100 } | 100 } |
101 if (m_contextStopped || !getExecutionContext()) { | 101 if (!getExecutionContext()) { |
102 exceptionState.throwDOMException(InvalidStateError, | 102 exceptionState.throwDOMException(InvalidStateError, |
103 IDBDatabase::databaseClosedErrorMessage); | 103 IDBDatabase::databaseClosedErrorMessage); |
104 return ScriptValue(); | 104 return ScriptValue(); |
105 } | 105 } |
106 m_resultDirty = false; | 106 m_resultDirty = false; |
107 ScriptValue value = ScriptValue::from(scriptState, m_result); | 107 ScriptValue value = ScriptValue::from(scriptState, m_result); |
108 return value; | 108 return value; |
109 } | 109 } |
110 | 110 |
111 DOMException* IDBRequest::error(ExceptionState& exceptionState) const { | 111 DOMException* IDBRequest::error(ExceptionState& exceptionState) const { |
112 if (m_readyState != DONE) { | 112 if (m_readyState != DONE) { |
113 exceptionState.throwDOMException( | 113 exceptionState.throwDOMException( |
114 InvalidStateError, IDBDatabase::requestNotFinishedErrorMessage); | 114 InvalidStateError, IDBDatabase::requestNotFinishedErrorMessage); |
115 return nullptr; | 115 return nullptr; |
116 } | 116 } |
117 return m_error; | 117 return m_error; |
118 } | 118 } |
119 | 119 |
120 ScriptValue IDBRequest::source(ScriptState* scriptState) const { | 120 ScriptValue IDBRequest::source(ScriptState* scriptState) const { |
121 if (m_contextStopped || !getExecutionContext()) | 121 if (!getExecutionContext()) |
122 return ScriptValue(); | 122 return ScriptValue(); |
123 | 123 |
124 return ScriptValue::from(scriptState, m_source); | 124 return ScriptValue::from(scriptState, m_source); |
125 } | 125 } |
126 | 126 |
127 const String& IDBRequest::readyState() const { | 127 const String& IDBRequest::readyState() const { |
128 DCHECK(m_readyState == PENDING || m_readyState == DONE); | 128 DCHECK(m_readyState == PENDING || m_readyState == DONE); |
129 | 129 |
130 if (m_readyState == PENDING) | 130 if (m_readyState == PENDING) |
131 return IndexedDBNames::pending; | 131 return IndexedDBNames::pending; |
132 | 132 |
133 return IndexedDBNames::done; | 133 return IndexedDBNames::done; |
134 } | 134 } |
135 | 135 |
136 std::unique_ptr<WebIDBCallbacks> IDBRequest::createWebCallbacks() { | 136 std::unique_ptr<WebIDBCallbacks> IDBRequest::createWebCallbacks() { |
137 DCHECK(!m_webCallbacks); | 137 DCHECK(!m_webCallbacks); |
138 std::unique_ptr<WebIDBCallbacks> callbacks = | 138 std::unique_ptr<WebIDBCallbacks> callbacks = |
139 WebIDBCallbacksImpl::create(this); | 139 WebIDBCallbacksImpl::create(this); |
140 m_webCallbacks = callbacks.get(); | 140 m_webCallbacks = callbacks.get(); |
141 return callbacks; | 141 return callbacks; |
142 } | 142 } |
143 | 143 |
144 void IDBRequest::webCallbacksDestroyed() { | 144 void IDBRequest::webCallbacksDestroyed() { |
145 DCHECK(m_webCallbacks); | 145 DCHECK(m_webCallbacks); |
146 m_webCallbacks = nullptr; | 146 m_webCallbacks = nullptr; |
147 } | 147 } |
148 | 148 |
149 void IDBRequest::abort() { | 149 void IDBRequest::abort() { |
150 DCHECK(!m_requestAborted); | 150 DCHECK(!m_requestAborted); |
151 if (m_contextStopped || !getExecutionContext()) | 151 if (!getExecutionContext()) |
152 return; | 152 return; |
153 DCHECK(m_readyState == PENDING || m_readyState == DONE); | 153 DCHECK(m_readyState == PENDING || m_readyState == DONE); |
154 if (m_readyState == DONE) | 154 if (m_readyState == DONE) |
155 return; | 155 return; |
156 | 156 |
157 EventQueue* eventQueue = getExecutionContext()->getEventQueue(); | 157 EventQueue* eventQueue = getExecutionContext()->getEventQueue(); |
158 for (size_t i = 0; i < m_enqueuedEvents.size(); ++i) { | 158 for (size_t i = 0; i < m_enqueuedEvents.size(); ++i) { |
159 bool removed = eventQueue->cancelEvent(m_enqueuedEvents[i].get()); | 159 bool removed = eventQueue->cancelEvent(m_enqueuedEvents[i].get()); |
160 DCHECK(removed); | 160 DCHECK(removed); |
161 } | 161 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 if (!uuids.isEmpty()) | 222 if (!uuids.isEmpty()) |
223 m_transaction->backendDB()->ackReceivedBlobs(uuids); | 223 m_transaction->backendDB()->ackReceivedBlobs(uuids); |
224 } | 224 } |
225 | 225 |
226 void IDBRequest::ackReceivedBlobs(const Vector<RefPtr<IDBValue>>& values) { | 226 void IDBRequest::ackReceivedBlobs(const Vector<RefPtr<IDBValue>>& values) { |
227 for (size_t i = 0; i < values.size(); ++i) | 227 for (size_t i = 0; i < values.size(); ++i) |
228 ackReceivedBlobs(values[i].get()); | 228 ackReceivedBlobs(values[i].get()); |
229 } | 229 } |
230 | 230 |
231 bool IDBRequest::shouldEnqueueEvent() const { | 231 bool IDBRequest::shouldEnqueueEvent() const { |
232 if (m_contextStopped || !getExecutionContext()) | 232 if (!getExecutionContext()) |
233 return false; | 233 return false; |
234 DCHECK(m_readyState == PENDING || m_readyState == DONE); | 234 DCHECK(m_readyState == PENDING || m_readyState == DONE); |
235 if (m_requestAborted) | 235 if (m_requestAborted) |
236 return false; | 236 return false; |
237 DCHECK_EQ(m_readyState, PENDING); | 237 DCHECK_EQ(m_readyState, PENDING); |
238 DCHECK(!m_error && !m_result); | 238 DCHECK(!m_error && !m_result); |
239 return true; | 239 return true; |
240 } | 240 } |
241 | 241 |
242 void IDBRequest::onError(DOMException* error) { | 242 void IDBRequest::onError(DOMException* error) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
352 } | 352 } |
353 | 353 |
354 void IDBRequest::onSuccess() { | 354 void IDBRequest::onSuccess() { |
355 IDB_TRACE("IDBRequest::onSuccess()"); | 355 IDB_TRACE("IDBRequest::onSuccess()"); |
356 if (!shouldEnqueueEvent()) | 356 if (!shouldEnqueueEvent()) |
357 return; | 357 return; |
358 onSuccessInternal(IDBAny::createUndefined()); | 358 onSuccessInternal(IDBAny::createUndefined()); |
359 } | 359 } |
360 | 360 |
361 void IDBRequest::onSuccessInternal(IDBAny* result) { | 361 void IDBRequest::onSuccessInternal(IDBAny* result) { |
362 DCHECK(!m_contextStopped); | 362 DCHECK(getExecutionContext()); |
363 DCHECK(!m_pendingCursor); | 363 DCHECK(!m_pendingCursor); |
364 setResult(result); | 364 setResult(result); |
365 enqueueEvent(Event::create(EventTypeNames::success)); | 365 enqueueEvent(Event::create(EventTypeNames::success)); |
366 } | 366 } |
367 | 367 |
368 void IDBRequest::setResult(IDBAny* result) { | 368 void IDBRequest::setResult(IDBAny* result) { |
369 m_result = result; | 369 m_result = result; |
370 m_resultDirty = true; | 370 m_resultDirty = true; |
371 } | 371 } |
372 | 372 |
373 void IDBRequest::onSuccess(IDBKey* key, | 373 void IDBRequest::onSuccess(IDBKey* key, |
374 IDBKey* primaryKey, | 374 IDBKey* primaryKey, |
375 PassRefPtr<IDBValue> value) { | 375 PassRefPtr<IDBValue> value) { |
376 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); | 376 IDB_TRACE("IDBRequest::onSuccess(key, primaryKey, value)"); |
377 if (!shouldEnqueueEvent()) | 377 if (!shouldEnqueueEvent()) |
378 return; | 378 return; |
379 | 379 |
380 DCHECK(m_pendingCursor); | 380 DCHECK(m_pendingCursor); |
381 setResultCursor(m_pendingCursor.release(), key, primaryKey, std::move(value)); | 381 setResultCursor(m_pendingCursor.release(), key, primaryKey, std::move(value)); |
382 } | 382 } |
383 | 383 |
384 bool IDBRequest::hasPendingActivity() const { | 384 bool IDBRequest::hasPendingActivity() const { |
385 // FIXME: In an ideal world, we should return true as long as anyone has a or | 385 // FIXME: In an ideal world, we should return true as long as anyone has a or |
386 // can get a handle to us and we have event listeners. This is order to | 386 // can get a handle to us and we have event listeners. This is order to |
387 // handle user generated events properly. | 387 // handle user generated events properly. |
388 return m_hasPendingActivity && !m_contextStopped; | 388 return m_hasPendingActivity && getExecutionContext(); |
389 } | 389 } |
390 | 390 |
391 void IDBRequest::contextDestroyed() { | 391 void IDBRequest::contextDestroyed() { |
392 if (m_contextStopped) | |
393 return; | |
394 | |
395 m_contextStopped = true; | |
396 | |
397 if (m_readyState == PENDING) { | 392 if (m_readyState == PENDING) { |
398 m_readyState = EarlyDeath; | 393 m_readyState = EarlyDeath; |
399 if (m_transaction) { | 394 if (m_transaction) { |
400 m_transaction->unregisterRequest(this); | 395 m_transaction->unregisterRequest(this); |
401 m_transaction.clear(); | 396 m_transaction.clear(); |
402 } | 397 } |
403 } | 398 } |
404 | 399 |
405 m_enqueuedEvents.clear(); | 400 m_enqueuedEvents.clear(); |
406 if (m_source) | 401 if (m_source) |
(...skipping 11 matching lines...) Expand all Loading... |
418 const AtomicString& IDBRequest::interfaceName() const { | 413 const AtomicString& IDBRequest::interfaceName() const { |
419 return EventTargetNames::IDBRequest; | 414 return EventTargetNames::IDBRequest; |
420 } | 415 } |
421 | 416 |
422 ExecutionContext* IDBRequest::getExecutionContext() const { | 417 ExecutionContext* IDBRequest::getExecutionContext() const { |
423 return ActiveDOMObject::getExecutionContext(); | 418 return ActiveDOMObject::getExecutionContext(); |
424 } | 419 } |
425 | 420 |
426 DispatchEventResult IDBRequest::dispatchEventInternal(Event* event) { | 421 DispatchEventResult IDBRequest::dispatchEventInternal(Event* event) { |
427 IDB_TRACE("IDBRequest::dispatchEvent"); | 422 IDB_TRACE("IDBRequest::dispatchEvent"); |
428 if (m_contextStopped || !getExecutionContext()) | 423 if (!getExecutionContext()) |
429 return DispatchEventResult::CanceledBeforeDispatch; | 424 return DispatchEventResult::CanceledBeforeDispatch; |
430 DCHECK_EQ(m_readyState, PENDING); | 425 DCHECK_EQ(m_readyState, PENDING); |
431 DCHECK(m_hasPendingActivity); | 426 DCHECK(m_hasPendingActivity); |
432 DCHECK(m_enqueuedEvents.size()); | 427 DCHECK(m_enqueuedEvents.size()); |
433 DCHECK_EQ(event->target(), this); | 428 DCHECK_EQ(event->target(), this); |
434 | 429 |
435 if (event->type() != EventTypeNames::blocked) | 430 if (event->type() != EventTypeNames::blocked) |
436 m_readyState = DONE; | 431 m_readyState = DONE; |
437 dequeueEvent(event); | 432 dequeueEvent(event); |
438 | 433 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 } | 517 } |
523 | 518 |
524 void IDBRequest::transactionDidFinishAndDispatch() { | 519 void IDBRequest::transactionDidFinishAndDispatch() { |
525 DCHECK(m_transaction); | 520 DCHECK(m_transaction); |
526 DCHECK(m_transaction->isVersionChange()); | 521 DCHECK(m_transaction->isVersionChange()); |
527 DCHECK(m_didFireUpgradeNeededEvent); | 522 DCHECK(m_didFireUpgradeNeededEvent); |
528 DCHECK_EQ(m_readyState, DONE); | 523 DCHECK_EQ(m_readyState, DONE); |
529 DCHECK(getExecutionContext()); | 524 DCHECK(getExecutionContext()); |
530 m_transaction.clear(); | 525 m_transaction.clear(); |
531 | 526 |
532 if (m_contextStopped) | 527 if (!getExecutionContext()) |
533 return; | 528 return; |
534 | 529 |
535 m_readyState = PENDING; | 530 m_readyState = PENDING; |
536 } | 531 } |
537 | 532 |
538 void IDBRequest::enqueueEvent(Event* event) { | 533 void IDBRequest::enqueueEvent(Event* event) { |
539 DCHECK(m_readyState == PENDING || m_readyState == DONE); | 534 DCHECK(m_readyState == PENDING || m_readyState == DONE); |
540 | 535 |
541 if (m_contextStopped || !getExecutionContext()) | 536 if (!getExecutionContext()) |
542 return; | 537 return; |
543 | 538 |
544 DCHECK(m_readyState == PENDING || m_didFireUpgradeNeededEvent) | 539 DCHECK(m_readyState == PENDING || m_didFireUpgradeNeededEvent) |
545 << "When queueing event " << event->type() << ", m_readyState was " | 540 << "When queueing event " << event->type() << ", m_readyState was " |
546 << m_readyState; | 541 << m_readyState; |
547 | 542 |
548 EventQueue* eventQueue = getExecutionContext()->getEventQueue(); | 543 EventQueue* eventQueue = getExecutionContext()->getEventQueue(); |
549 event->setTarget(this); | 544 event->setTarget(this); |
550 | 545 |
551 // Keep track of enqueued events in case we need to abort prior to dispatch, | 546 // Keep track of enqueued events in case we need to abort prior to dispatch, |
552 // in which case these must be cancelled. If the events not dispatched for | 547 // in which case these must be cancelled. If the events not dispatched for |
553 // other reasons they must be removed from this list via dequeueEvent(). | 548 // other reasons they must be removed from this list via dequeueEvent(). |
554 if (eventQueue->enqueueEvent(event)) | 549 if (eventQueue->enqueueEvent(event)) |
555 m_enqueuedEvents.append(event); | 550 m_enqueuedEvents.append(event); |
556 } | 551 } |
557 | 552 |
558 void IDBRequest::dequeueEvent(Event* event) { | 553 void IDBRequest::dequeueEvent(Event* event) { |
559 for (size_t i = 0; i < m_enqueuedEvents.size(); ++i) { | 554 for (size_t i = 0; i < m_enqueuedEvents.size(); ++i) { |
560 if (m_enqueuedEvents[i].get() == event) | 555 if (m_enqueuedEvents[i].get() == event) |
561 m_enqueuedEvents.remove(i); | 556 m_enqueuedEvents.remove(i); |
562 } | 557 } |
563 } | 558 } |
564 | 559 |
565 } // namespace blink | 560 } // namespace blink |
OLD | NEW |