Index: Source/modules/serviceworkers/ServiceWorker.cpp |
diff --git a/Source/modules/serviceworkers/ServiceWorker.cpp b/Source/modules/serviceworkers/ServiceWorker.cpp |
index b67bdb938f25024d8669b39403c50380646cdf4e..0eab334c59bc322fa371892b87e2c172616f209b 100644 |
--- a/Source/modules/serviceworkers/ServiceWorker.cpp |
+++ b/Source/modules/serviceworkers/ServiceWorker.cpp |
@@ -34,6 +34,7 @@ |
#include "EventTargetNames.h" |
#include "bindings/v8/ExceptionState.h" |
#include "bindings/v8/NewScriptState.h" |
+#include "bindings/v8/ScriptPromiseResolverWithContext.h" |
#include "core/dom/MessagePort.h" |
#include "core/events/Event.h" |
#include "platform/NotImplemented.h" |
@@ -43,6 +44,37 @@ |
namespace WebCore { |
+class ServiceWorker::ThenFunction FINAL : public ScriptFunction { |
+public: |
+ enum ResolveType { |
+ Fulfilled, |
+ Rejected, |
+ }; |
+ |
+ static PassOwnPtr<ScriptFunction> create(PassRefPtr<ServiceWorker> observer, ResolveType type) |
+ { |
+ ExecutionContext* executionContext = observer->executionContext(); |
+ return adoptPtr(new ThenFunction(toIsolate(executionContext), observer, type)); |
+ } |
+private: |
+ ThenFunction(v8::Isolate* isolate, PassRefPtr<ServiceWorker> observer, ResolveType type) |
+ : ScriptFunction(isolate) |
+ , m_observer(observer) |
+ , m_resolveType(type) |
+ { |
+ } |
+ |
+ virtual ScriptValue call(ScriptValue value) OVERRIDE |
+ { |
+ ASSERT(m_resolveType == Fulfilled); |
+ m_observer->onPromiseResolved(); |
+ return value; |
+ } |
+ |
+ RefPtr<ServiceWorker> m_observer; |
+ ResolveType m_resolveType; |
+}; |
+ |
const AtomicString& ServiceWorker::interfaceName() const |
{ |
return EventTargetNames::ServiceWorker; |
@@ -60,9 +92,17 @@ void ServiceWorker::postMessage(PassRefPtr<SerializedScriptValue> message, const |
m_outerWorker->postMessage(messageString, webChannels.leakPtr()); |
} |
+void ServiceWorker::onStateChanged(blink::WebServiceWorkerState state) |
+{ |
+ if (m_isPromisePending) |
+ m_queuedStates.append(state); |
+ else |
+ changeState(state); |
+} |
+ |
void ServiceWorker::dispatchStateChangeEvent() |
{ |
kinuko
2014/04/23 14:20:00
Can you also add 'FIXME: deprecate' comment here?
falken
2014/04/24 00:58:50
Done.
|
- this->dispatchEvent(Event::create(EventTypeNames::statechange)); |
+ changeState(m_outerWorker->state()); |
} |
const AtomicString& ServiceWorker::state() const |
@@ -98,9 +138,33 @@ const AtomicString& ServiceWorker::state() const |
} |
} |
-PassRefPtr<ServiceWorker> ServiceWorker::from(NewScriptState* scriptState, WebType* worker) |
+PassRefPtr<ServiceWorker> ServiceWorker::from(ScriptPromiseResolverWithContext* resolver, WebType* worker) |
{ |
- return create(scriptState->executionContext(), adoptPtr(worker)); |
+ NewScriptState::Scope scope(resolver->scriptState()); |
+ RefPtr<ServiceWorker> serviceWorker = create(resolver->scriptState()->executionContext(), adoptPtr(worker)); |
+ serviceWorker->waitOnPromise(resolver->promise()); |
+ return serviceWorker; |
+} |
+ |
+void ServiceWorker::onPromiseResolved() |
+{ |
kinuko
2014/04/23 14:20:00
nit: maybe ASSERT(m_isPromisePending) here
falken
2014/04/24 00:58:50
Done.
|
+ m_isPromisePending = false; |
+ for (Vector<blink::WebServiceWorkerState>::iterator iterator = m_queuedStates.begin(); iterator != m_queuedStates.end(); ++iterator) |
+ changeState(*iterator); |
+} |
+ |
+void ServiceWorker::waitOnPromise(ScriptPromise promise) |
+{ |
+ m_isPromisePending = true; |
+ promise.then( |
+ ThenFunction::create(this, ThenFunction::Fulfilled), |
+ ThenFunction::create(this, ThenFunction::Rejected)); |
+} |
+ |
+void ServiceWorker::changeState(blink::WebServiceWorkerState state) |
+{ |
+ m_outerWorker->setState(state); |
+ this->dispatchEvent(Event::create(EventTypeNames::statechange)); |
} |
PassRefPtr<ServiceWorker> ServiceWorker::create(ExecutionContext* executionContext, PassOwnPtr<blink::WebServiceWorker> outerWorker) |
@@ -113,6 +177,7 @@ PassRefPtr<ServiceWorker> ServiceWorker::create(ExecutionContext* executionConte |
ServiceWorker::ServiceWorker(ExecutionContext* executionContext, PassOwnPtr<blink::WebServiceWorker> worker) |
: AbstractWorker(executionContext) |
, m_outerWorker(worker) |
+ , m_isPromisePending(false) |
{ |
ScriptWrappable::init(this); |
ASSERT(m_outerWorker); |