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.
6 #include "ServiceWorkerRegistration.h"
8 #include "bindings/core/v8/CallbackPromiseAdapter.h"
9 #include "bindings/core/v8/ScriptPromise.h"
10 #include "bindings/core/v8/ScriptPromiseResolver.h"
11 #include "bindings/core/v8/ScriptState.h"
12 #include "core/dom/DOMException.h"
13 #include "core/dom/ExceptionCode.h"
14 #include "core/dom/ExecutionContext.h"
15 #include "core/events/Event.h"
16 #include "modules/EventTargetModules.h"
17 #include "modules/serviceworkers/ServiceWorkerContainerClient.h"
18 #include "modules/serviceworkers/ServiceWorkerError.h"
19 #include "public/platform/WebServiceWorkerProvider.h"
26 static bool take(ScriptPromiseResolver* resolver, WebType* boolean)
30 static void dispose(WebType* boolean) { }
36 static void deleteIfNoExistingOwner(WebServiceWorker* serviceWorker)
38 if (serviceWorker && !serviceWorker->proxy())
42 const AtomicString& ServiceWorkerRegistration::interfaceName() const
44 return EventTargetNames::ServiceWorkerRegistration;
47 void ServiceWorkerRegistration::dispatchUpdateFoundEvent()
49 dispatchEvent(Event::create(EventTypeNames::updatefound));
52 void ServiceWorkerRegistration::setInstalling(WebServiceWorker* serviceWorker)
54 if (!executionContext()) {
55 deleteIfNoExistingOwner(serviceWorker);
58 m_installing = ServiceWorker::from(executionContext(), serviceWorker);
61 void ServiceWorkerRegistration::setWaiting(WebServiceWorker* serviceWorker)
63 if (!executionContext()) {
64 deleteIfNoExistingOwner(serviceWorker);
67 m_waiting = ServiceWorker::from(executionContext(), serviceWorker);
70 void ServiceWorkerRegistration::setActive(WebServiceWorker* serviceWorker)
72 if (!executionContext()) {
73 deleteIfNoExistingOwner(serviceWorker);
76 m_active = ServiceWorker::from(executionContext(), serviceWorker);
79 ServiceWorkerRegistration* ServiceWorkerRegistration::from(ExecutionContext* executionContext, WebType* registration)
83 return getOrCreate(executionContext, registration);
86 ServiceWorkerRegistration* ServiceWorkerRegistration::take(ScriptPromiseResolver* resolver, WebType* registration)
88 return from(resolver->scriptState()->executionContext(), registration);
91 void ServiceWorkerRegistration::dispose(WebType* registration)
93 if (registration && !registration->proxy())
97 String ServiceWorkerRegistration::scope() const
99 return m_outerRegistration->scope().string();
102 ScriptPromise ServiceWorkerRegistration::unregister(ScriptState* scriptState)
104 RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
105 ScriptPromise promise = resolver->promise();
108 resolver->reject(DOMException::create(InvalidStateError, "No associated provider is available"));
112 RefPtr<SecurityOrigin> documentOrigin = scriptState->executionContext()->securityOrigin();
113 KURL scopeURL = scriptState->executionContext()->completeURL(scope());
114 scopeURL.removeFragmentIdentifier();
115 if (!scope().isEmpty() && !documentOrigin->canRequest(scopeURL)) {
116 resolver->reject(DOMException::create(SecurityError, "Can only unregister for scopes in the document's origin."));
120 m_provider->unregisterServiceWorker(scopeURL, new CallbackPromiseAdapter<BooleanValue, ServiceWorkerError>(resolver));
124 ServiceWorkerRegistration* ServiceWorkerRegistration::getOrCreate(ExecutionContext* executionContext, WebServiceWorkerRegistration* outerRegistration)
126 if (!outerRegistration)
129 ServiceWorkerRegistration* existingRegistration = static_cast<ServiceWorkerRegistration*>(outerRegistration->proxy());
130 if (existingRegistration) {
131 ASSERT(existingRegistration->executionContext() == executionContext);
132 return existingRegistration;
135 ServiceWorkerRegistration* registration = new ServiceWorkerRegistration(executionContext, adoptPtr(outerRegistration));
136 registration->suspendIfNeeded();
140 ServiceWorkerRegistration::ServiceWorkerRegistration(ExecutionContext* executionContext, PassOwnPtr<WebServiceWorkerRegistration> outerRegistration)
141 : ActiveDOMObject(executionContext)
142 , m_outerRegistration(outerRegistration)
146 ASSERT(m_outerRegistration);
148 if (!executionContext)
150 if (ServiceWorkerContainerClient* client = ServiceWorkerContainerClient::from(executionContext))
151 m_provider = client->provider();
152 m_outerRegistration->setProxy(this);
155 void ServiceWorkerRegistration::trace(Visitor* visitor)
157 visitor->trace(m_installing);
158 visitor->trace(m_waiting);
159 visitor->trace(m_active);
160 EventTargetWithInlineData::trace(visitor);
161 HeapSupplementable<ServiceWorkerRegistration>::trace(visitor);
164 bool ServiceWorkerRegistration::hasPendingActivity() const
169 void ServiceWorkerRegistration::stop()
174 m_outerRegistration->proxyStopped();