Index: Source/modules/webmidi/NavigatorWebMIDI.cpp |
diff --git a/Source/modules/webmidi/NavigatorWebMIDI.cpp b/Source/modules/webmidi/NavigatorWebMIDI.cpp |
index 87f7b25d31ef0fbc61ed12c4644be689c87b3033..db5ac9872c911872a4aab79e3b08066a750227c1 100644 |
--- a/Source/modules/webmidi/NavigatorWebMIDI.cpp |
+++ b/Source/modules/webmidi/NavigatorWebMIDI.cpp |
@@ -31,11 +31,16 @@ |
#include "config.h" |
#include "modules/webmidi/NavigatorWebMIDI.h" |
+#include "bindings/v8/DOMRequestState.h" |
+#include "bindings/v8/ScriptPromise.h" |
+#include "bindings/v8/ScriptPromiseResolver.h" |
+#include "core/dom/DOMError.h" |
#include "core/dom/Document.h" |
#include "core/dom/ExecutionContext.h" |
#include "core/frame/Frame.h" |
#include "core/frame/Navigator.h" |
-#include "modules/webmidi/MIDIAccessPromise.h" |
+#include "modules/webmidi/MIDIAccess.h" |
+#include "modules/webmidi/MIDIOptions.h" |
namespace WebCore { |
@@ -46,6 +51,7 @@ NavigatorWebMIDI::NavigatorWebMIDI(Frame* frame) |
NavigatorWebMIDI::~NavigatorWebMIDI() |
{ |
+ clearPending(); |
} |
const char* NavigatorWebMIDI::supplementName() |
@@ -63,20 +69,85 @@ NavigatorWebMIDI* NavigatorWebMIDI::from(Navigator* navigator) |
return supplement; |
} |
-PassRefPtr<MIDIAccessPromise> NavigatorWebMIDI::requestMIDIAccess(Navigator* navigator, const Dictionary& options) |
+ScriptPromise NavigatorWebMIDI::requestMIDIAccess(Navigator* navigator, const Dictionary& options) |
{ |
return NavigatorWebMIDI::from(navigator)->requestMIDIAccess(options); |
} |
-PassRefPtr<MIDIAccessPromise> NavigatorWebMIDI::requestMIDIAccess(const Dictionary& options) |
+ScriptPromise NavigatorWebMIDI::requestMIDIAccess(const Dictionary& options) |
{ |
- if (!frame()) |
- return 0; |
+ if (!frame()) { |
+ ScriptPromise promise = ScriptPromise::createPending(); |
+ RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(promise); |
+ // FIXME: Currently this rejection does not work because the context is stopped. |
+ resolver->reject(DOMError::create("AbortError")); |
abarth-chromium
2013/12/03 16:57:57
Maybe we should throw an exception instead?
yhirano
2013/12/04 05:20:24
I think the spec doesn't want to throw an error ex
Takashi Toyoshima
2013/12/04 06:48:37
How about other Promise or asynchronous API usages
yhirano
2013/12/05 08:19:12
I think so as well.
Anyway, this may be a Promise
|
+ return promise; |
+ } |
ExecutionContext* context = frame()->document(); |
ASSERT(context); |
+ if (!m_requestState.get()) |
+ m_requestState = adoptPtr(new DOMRequestState(context)); |
abarth-chromium
2013/12/03 16:57:57
Why is there only one m_requestState? When is m_r
yhirano
2013/12/04 05:20:24
Done.
Now each MIDIAccessor has its DOMRequestStat
|
+ ScriptPromise promise = ScriptPromise::createPending(context); |
+ RefPtr<MIDIAccess> access = MIDIAccess::create(MIDIOptions(options), context, this); |
+ m_pending.add(access, ScriptPromiseResolver::create(promise, context)); |
+ access->startRequest(); |
+ return promise; |
+} |
+ |
+void NavigatorWebMIDI::didFinishRequest(MIDIAccess* access) |
+{ |
+ // FIXME: We should care about suspend / stop. |
+ RefPtr<MIDIAccess> key(access); |
+ if (!m_pending.contains(key)) |
+ return; |
+ RefPtr<ScriptPromiseResolver> resolver = m_pending.get(key); |
+ m_pending.remove(key); |
+ |
+ if (!frame()) { |
+ // We can break the promise if the frame does not exist. |
+ return; |
+ } |
+ ASSERT(m_requestState); |
+ DOMRequestState::Scope scope(*m_requestState); |
+ resolver->resolve(access, access->executionContext()); |
+} |
+ |
+void NavigatorWebMIDI::didFailRequest(MIDIAccess* access, PassRefPtr<DOMError> error) |
+{ |
+ // FIXME: We should care about suspend / stop. |
+ RefPtr<MIDIAccess> key(access); |
+ if (!m_pending.contains(key)) |
+ return; |
+ RefPtr<ScriptPromiseResolver> resolver = m_pending.get(key); |
+ m_pending.remove(key); |
+ if (!frame()) { |
+ // We can break the promise if the frame does not exist. |
+ return; |
+ } |
+ ASSERT(m_requestState); |
+ DOMRequestState::Scope scope(*m_requestState); |
+ resolver->reject(error, access->executionContext()); |
+} |
+ |
+void NavigatorWebMIDI::clearPending() |
+{ |
+ // FIXME: We should care about suspend / stop. |
+ HashMap<RefPtr<MIDIAccess>, RefPtr<ScriptPromiseResolver> > pending; |
+ pending.swap(m_pending); |
+ |
+ if (!frame()) { |
+ // We can break promises if the frame does not exist. |
+ return; |
+ } |
- return MIDIAccessPromise::create(context, options); |
+ ASSERT(m_requestState); |
+ for (HashMap<RefPtr<MIDIAccess>, RefPtr<ScriptPromiseResolver> >::iterator i = pending.begin(); |
+ i != pending.end(); ++i) { |
+ DOMRequestState::Scope scope(*m_requestState); |
+ MIDIAccess* access = i->key.get(); |
+ i->value->reject(DOMError::create("AbortError"), access->executionContext()); |
+ } |
} |
} // namespace WebCore |