Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / serviceworkers / RespondWithObserver.cpp
index d2fc67a..7f123f8 100644 (file)
 #include "bindings/modules/v8/V8Response.h"
 #include "core/dom/ExecutionContext.h"
 #include "modules/serviceworkers/ServiceWorkerGlobalScopeClient.h"
+#include "platform/RuntimeEnabledFeatures.h"
+#include "public/platform/WebServiceWorkerResponse.h"
 #include "wtf/Assertions.h"
 #include "wtf/RefPtr.h"
 #include <v8.h>
 
 namespace blink {
 
-class RespondWithObserver::ThenFunction FINAL : public ScriptFunction {
+class RespondWithObserver::ThenFunction final : public ScriptFunction {
 public:
     enum ResolveType {
         Fulfilled,
         Rejected,
     };
 
-    static PassOwnPtr<ScriptFunction> create(PassRefPtr<RespondWithObserver> observer, ResolveType type)
+    static v8::Handle<v8::Function> createFunction(ScriptState* scriptState, RespondWithObserver* observer, ResolveType type)
     {
-        ExecutionContext* executionContext = observer->executionContext();
-        return adoptPtr(new ThenFunction(toIsolate(executionContext), observer, type));
+        ThenFunction* self = new ThenFunction(scriptState, observer, type);
+        return self->bindToV8Function();
+    }
+
+    virtual void trace(Visitor* visitor) override
+    {
+        visitor->trace(m_observer);
+        ScriptFunction::trace(visitor);
     }
 
 private:
-    ThenFunction(v8::Isolate* isolate, PassRefPtr<RespondWithObserver> observer, ResolveType type)
-        : ScriptFunction(isolate)
+    ThenFunction(ScriptState* scriptState, RespondWithObserver* observer, ResolveType type)
+        : ScriptFunction(scriptState)
         , m_observer(observer)
         , m_resolveType(type)
     {
     }
 
-    virtual ScriptValue call(ScriptValue value) OVERRIDE
+    virtual ScriptValue call(ScriptValue value) override
     {
         ASSERT(m_observer);
         ASSERT(m_resolveType == Fulfilled || m_resolveType == Rejected);
@@ -51,17 +59,13 @@ private:
         return value;
     }
 
-    RefPtr<RespondWithObserver> m_observer;
+    Member<RespondWithObserver> m_observer;
     ResolveType m_resolveType;
 };
 
-PassRefPtr<RespondWithObserver> RespondWithObserver::create(ExecutionContext* context, int eventID)
-{
-    return adoptRef(new RespondWithObserver(context, eventID));
-}
-
-RespondWithObserver::~RespondWithObserver()
+RespondWithObserver* RespondWithObserver::create(ExecutionContext* context, int eventID, WebURLRequest::FetchRequestMode requestMode, WebURLRequest::FrameType frameType)
 {
+    return new RespondWithObserver(context, eventID, requestMode, frameType);
 }
 
 void RespondWithObserver::contextDestroyed()
@@ -72,50 +76,68 @@ void RespondWithObserver::contextDestroyed()
 
 void RespondWithObserver::didDispatchEvent()
 {
-    if (m_state == Initial)
-        sendResponse(nullptr);
+    ASSERT(executionContext());
+    if (m_state != Initial)
+        return;
+    ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleFetchEvent(m_eventID);
+    m_state = Done;
 }
 
-void RespondWithObserver::respondWith(ScriptState* scriptState, const ScriptValue& value)
+void RespondWithObserver::respondWith(ScriptState* scriptState, const ScriptValue& value, ExceptionState& exceptionState)
 {
-    if (m_state != Initial)
+    ASSERT(RuntimeEnabledFeatures::serviceWorkerOnFetchEnabled());
+    if (m_state != Initial) {
+        exceptionState.throwDOMException(InvalidStateError, "respondWith is already called.");
         return;
+    }
 
     m_state = Pending;
     ScriptPromise::cast(scriptState, value).then(
-        ThenFunction::create(this, ThenFunction::Fulfilled),
-        ThenFunction::create(this, ThenFunction::Rejected));
-}
-
-void RespondWithObserver::sendResponse(PassRefPtrWillBeRawPtr<Response> response)
-{
-    if (!executionContext())
-        return;
-    ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleFetchEvent(m_eventID, response);
-    m_state = Done;
+        ThenFunction::createFunction(scriptState, this, ThenFunction::Fulfilled),
+        ThenFunction::createFunction(scriptState, this, ThenFunction::Rejected));
 }
 
 void RespondWithObserver::responseWasRejected()
 {
-    // FIXME: Throw a NetworkError to service worker's execution context.
-    sendResponse(nullptr);
+    ASSERT(executionContext());
+    // The default value of WebServiceWorkerResponse's status is 0, which maps
+    // to a network error.
+    WebServiceWorkerResponse webResponse;
+    ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleFetchEvent(m_eventID, webResponse);
+    m_state = Done;
 }
 
 void RespondWithObserver::responseWasFulfilled(const ScriptValue& value)
 {
-    if (!executionContext())
-        return;
+    ASSERT(executionContext());
     if (!V8Response::hasInstance(value.v8Value(), toIsolate(executionContext()))) {
         responseWasRejected();
         return;
     }
-    v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(value.v8Value());
-    sendResponse(V8Response::toNative(object));
+    Response* response = V8Response::toImplWithTypeCheck(toIsolate(executionContext()), value.v8Value());
+    // "If either |response|'s type is |opaque| and |request|'s mode is not
+    // |no CORS| or |response|'s type is |error|, return a network error."
+    const FetchResponseData::Type responseType = response->response()->type();
+    if ((responseType == FetchResponseData::OpaqueType && m_requestMode != WebURLRequest::FetchRequestModeNoCORS) || responseType == FetchResponseData::ErrorType) {
+        responseWasRejected();
+        return;
+    }
+    // Treat the opaque response as a network error for frame loading.
+    if (responseType == FetchResponseData::OpaqueType && m_frameType != WebURLRequest::FrameTypeNone) {
+        responseWasRejected();
+        return;
+    }
+    WebServiceWorkerResponse webResponse;
+    response->populateWebServiceWorkerResponse(webResponse);
+    ServiceWorkerGlobalScopeClient::from(executionContext())->didHandleFetchEvent(m_eventID, webResponse);
+    m_state = Done;
 }
 
-RespondWithObserver::RespondWithObserver(ExecutionContext* context, int eventID)
+RespondWithObserver::RespondWithObserver(ExecutionContext* context, int eventID, WebURLRequest::FetchRequestMode requestMode, WebURLRequest::FrameType frameType)
     : ContextLifecycleObserver(context)
     , m_eventID(eventID)
+    , m_requestMode(requestMode)
+    , m_frameType(frameType)
     , m_state(Initial)
 {
 }