Chromium Code Reviews| Index: Source/modules/navigatorconnect/AcceptConnectionObserver.cpp |
| diff --git a/Source/modules/navigatorconnect/AcceptConnectionObserver.cpp b/Source/modules/navigatorconnect/AcceptConnectionObserver.cpp |
| index 9807f0dde6d0391eac241ebcaf67ae3939dcdaa8..f2418409eb5775b3f5ac06786e55b5564a3b5f1d 100644 |
| --- a/Source/modules/navigatorconnect/AcceptConnectionObserver.cpp |
| +++ b/Source/modules/navigatorconnect/AcceptConnectionObserver.cpp |
| @@ -9,7 +9,10 @@ |
| #include "bindings/core/v8/ScriptFunction.h" |
| #include "bindings/core/v8/ScriptPromise.h" |
| #include "bindings/core/v8/ScriptValue.h" |
| +#include "core/dom/DOMException.h" |
| #include "core/dom/ExceptionCode.h" |
| +#include "modules/navigatorconnect/ServicePort.h" |
| +#include "modules/navigatorconnect/ServicePortConnectResponse.h" |
| #include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h" |
| namespace blink { |
| @@ -49,9 +52,9 @@ private: |
| ASSERT(m_observer); |
| ASSERT(m_resolveType == Fulfilled || m_resolveType == Rejected); |
| if (m_resolveType == Rejected) |
| - m_observer->connectionWasRejected(); |
| + m_observer->responseWasRejected(); |
| else |
| - m_observer->connectionWasAccepted(value); |
| + m_observer->responseWasResolved(value); |
| m_observer = nullptr; |
| return value; |
| } |
| @@ -65,6 +68,11 @@ AcceptConnectionObserver* AcceptConnectionObserver::create(ExecutionContext* con |
| return new AcceptConnectionObserver(context, eventID); |
| } |
| +AcceptConnectionObserver* AcceptConnectionObserver::create(ServicePortCollection* collection, PassOwnPtr<WebServicePortConnectEventCallbacks> callbacks, WebServicePortID portID, const KURL& targetURL) |
| +{ |
| + return new AcceptConnectionObserver(collection, callbacks, portID, targetURL); |
| +} |
| + |
| void AcceptConnectionObserver::contextDestroyed() |
| { |
| ContextLifecycleObserver::contextDestroyed(); |
| @@ -76,7 +84,7 @@ void AcceptConnectionObserver::didDispatchEvent() |
| ASSERT(executionContext()); |
| if (m_state != Initial) |
| return; |
| - connectionWasRejected(); |
| + responseWasRejected(); |
| } |
| void AcceptConnectionObserver::acceptConnection(ScriptState* scriptState, ScriptPromise value, ExceptionState& exceptionState) |
| @@ -92,33 +100,105 @@ void AcceptConnectionObserver::acceptConnection(ScriptState* scriptState, Script |
| ThenFunction::createFunction(scriptState, this, ThenFunction::Rejected)); |
| } |
| -void AcceptConnectionObserver::connectionWasRejected() |
| +ScriptPromise AcceptConnectionObserver::respondWith(ScriptState* scriptState, ScriptPromise value, ExceptionState& exceptionState) |
| +{ |
| + if (m_state != Initial) { |
| + return ScriptPromise::rejectWithDOMException(scriptState, DOMException::create(InvalidStateError, "respondWith wsa already called.")); |
|
chasej
2015/07/02 20:45:28
Typo: "wsa" should be "was"
Marijn Kruisselbrink
2015/07/07 16:42:48
Done
|
| + } |
| + |
| + m_state = Pending; |
| + m_resolver = ScriptPromiseResolver::create(scriptState); |
| + ScriptPromise promise = m_resolver->promise(); |
| + value.then( |
| + ThenFunction::createFunction(scriptState, this, ThenFunction::Fulfilled), |
| + ThenFunction::createFunction(scriptState, this, ThenFunction::Rejected)); |
| + return promise; |
| +} |
| + |
| +void AcceptConnectionObserver::responseWasRejected() |
| { |
| ASSERT(executionContext()); |
| - ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleCrossOriginConnectEvent(m_eventID, false); |
| + if (m_resolver) |
| + m_resolver->reject(DOMException::create(AbortError)); |
| + if (m_callbacks) { |
| + m_callbacks->onError(); |
| + } else { |
| + ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleCrossOriginConnectEvent(m_eventID, false); |
| + } |
| m_state = Done; |
| } |
| -void AcceptConnectionObserver::connectionWasAccepted(const ScriptValue& value) |
| +void AcceptConnectionObserver::responseWasResolved(const ScriptValue& value) |
| { |
| ASSERT(executionContext()); |
| - if (!value.v8Value()->IsTrue()) { |
| - connectionWasRejected(); |
| + if (!m_resolver) { |
| + // TODO(mek): Get rid of this block when observer is only used for |
| + // service port connect events. |
| + if (!value.v8Value()->IsTrue()) { |
| + responseWasRejected(); |
| + return; |
| + } |
| + ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleCrossOriginConnectEvent(m_eventID, true); |
| + m_state = Done; |
| + return; |
| + } |
| + |
| + ScriptState* scriptState = m_resolver->scriptState(); |
| + ExceptionState exceptionState(ExceptionState::UnknownContext, nullptr, nullptr, scriptState->context()->Global(), scriptState->isolate()); |
| + ServicePortConnectResponse response = ScriptValue::to<ServicePortConnectResponse>(scriptState->isolate(), value, exceptionState); |
| + if (exceptionState.hadException()) { |
| + exceptionState.reject(m_resolver.get()); |
| + m_resolver = nullptr; |
| + responseWasRejected(); |
| + return; |
| + } |
| + if (!response.hasAccept() || !response.accept()) { |
| + responseWasRejected(); |
| return; |
| } |
| - ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleCrossOriginConnectEvent(m_eventID, true); |
| + WebServicePort webPort; |
| + webPort.targetUrl = m_targetURL; |
| + if (response.hasName()) |
| + webPort.name = response.name(); |
| + if (response.hasData()) { |
| + webPort.data = SerializedScriptValueFactory::instance().create(scriptState->isolate(), response.data(), nullptr, exceptionState)->toWireString(); |
| + if (exceptionState.hadException()) { |
| + exceptionState.reject(m_resolver.get()); |
| + m_resolver = nullptr; |
| + responseWasRejected(); |
| + return; |
| + } |
| + } |
| + webPort.id = m_portID; |
| + ServicePort* port = ServicePort::create(m_collection, webPort); |
| + m_collection->addPort(port); |
| + m_resolver->resolve(port); |
| + m_callbacks->onSuccess(&webPort); |
| m_state = Done; |
| } |
| AcceptConnectionObserver::AcceptConnectionObserver(ExecutionContext* context, int eventID) |
| : ContextLifecycleObserver(context) |
| , m_eventID(eventID) |
| + , m_portID(-1) |
| + , m_state(Initial) |
| +{ |
| +} |
| + |
| +AcceptConnectionObserver::AcceptConnectionObserver(ServicePortCollection* collection, PassOwnPtr<WebServicePortConnectEventCallbacks> callbacks, WebServicePortID portID, const KURL& targetURL) |
| + : ContextLifecycleObserver(collection->executionContext()) |
| + , m_eventID(-1) |
| + , m_callbacks(callbacks) |
| + , m_collection(collection) |
| + , m_portID(portID) |
| + , m_targetURL(targetURL) |
| , m_state(Initial) |
| { |
| } |
| DEFINE_TRACE(AcceptConnectionObserver) |
| { |
| + visitor->trace(m_collection); |
| ContextLifecycleObserver::trace(visitor); |
| } |