Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / serviceworkers / WaitUntilObserver.cpp
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "config.h"
6 #include "modules/serviceworkers/WaitUntilObserver.h"
7
8 #include "bindings/core/v8/ScriptFunction.h"
9 #include "bindings/core/v8/ScriptPromise.h"
10 #include "bindings/core/v8/ScriptValue.h"
11 #include "bindings/core/v8/V8Binding.h"
12 #include "core/dom/ExecutionContext.h"
13 #include "modules/serviceworkers/ServiceWorkerGlobalScope.h"
14 #include "platform/NotImplemented.h"
15 #include "public/platform/WebServiceWorkerEventResult.h"
16 #include "wtf/Assertions.h"
17 #include "wtf/RefCounted.h"
18 #include "wtf/RefPtr.h"
19 #include <v8.h>
20
21 namespace blink {
22
23 class WaitUntilObserver::ThenFunction final : public ScriptFunction {
24 public:
25     enum ResolveType {
26         Fulfilled,
27         Rejected,
28     };
29
30     static v8::Handle<v8::Function> createFunction(ScriptState* scriptState, WaitUntilObserver* observer, ResolveType type)
31     {
32         ThenFunction* self = new ThenFunction(scriptState, observer, type);
33         return self->bindToV8Function();
34     }
35
36     virtual void trace(Visitor* visitor) override
37     {
38         visitor->trace(m_observer);
39         ScriptFunction::trace(visitor);
40     }
41
42 private:
43     ThenFunction(ScriptState* scriptState, WaitUntilObserver* observer, ResolveType type)
44         : ScriptFunction(scriptState)
45         , m_observer(observer)
46         , m_resolveType(type)
47     {
48     }
49
50     virtual ScriptValue call(ScriptValue value) override
51     {
52         ASSERT(m_observer);
53         ASSERT(m_resolveType == Fulfilled || m_resolveType == Rejected);
54         if (m_resolveType == Rejected)
55             m_observer->reportError(value);
56         m_observer->decrementPendingActivity();
57         m_observer = nullptr;
58         return value;
59     }
60
61     Member<WaitUntilObserver> m_observer;
62     ResolveType m_resolveType;
63 };
64
65 WaitUntilObserver* WaitUntilObserver::create(ExecutionContext* context, EventType type, int eventID)
66 {
67     return new WaitUntilObserver(context, type, eventID);
68 }
69
70 void WaitUntilObserver::willDispatchEvent()
71 {
72     incrementPendingActivity();
73 }
74
75 void WaitUntilObserver::didDispatchEvent(bool errorOccurred)
76 {
77     if (errorOccurred)
78         m_hasError = true;
79     decrementPendingActivity();
80 }
81
82 void WaitUntilObserver::waitUntil(ScriptState* scriptState, const ScriptValue& value)
83 {
84     incrementPendingActivity();
85     ScriptPromise::cast(scriptState, value).then(
86         ThenFunction::createFunction(scriptState, this, ThenFunction::Fulfilled),
87         ThenFunction::createFunction(scriptState, this, ThenFunction::Rejected));
88 }
89
90 WaitUntilObserver::WaitUntilObserver(ExecutionContext* context, EventType type, int eventID)
91     : ContextLifecycleObserver(context)
92     , m_type(type)
93     , m_eventID(eventID)
94     , m_pendingActivity(0)
95     , m_hasError(false)
96 {
97 }
98
99 void WaitUntilObserver::reportError(const ScriptValue& value)
100 {
101     // FIXME: Propagate error message to the client for onerror handling.
102     notImplemented();
103
104     m_hasError = true;
105 }
106
107 void WaitUntilObserver::incrementPendingActivity()
108 {
109     ++m_pendingActivity;
110 }
111
112 void WaitUntilObserver::decrementPendingActivity()
113 {
114     ASSERT(m_pendingActivity > 0);
115     if (!executionContext() || (!m_hasError && --m_pendingActivity))
116         return;
117
118     ServiceWorkerGlobalScopeClient* client = ServiceWorkerGlobalScopeClient::from(executionContext());
119     WebServiceWorkerEventResult result = m_hasError ? WebServiceWorkerEventResultRejected : WebServiceWorkerEventResultCompleted;
120     switch (m_type) {
121     case Activate:
122         client->didHandleActivateEvent(m_eventID, result);
123         break;
124     case Install:
125         client->didHandleInstallEvent(m_eventID, result);
126         break;
127     }
128     observeContext(0);
129 }
130
131 } // namespace blink