OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 #include "modules/serviceworkers/ServiceWorkerError.h" | 49 #include "modules/serviceworkers/ServiceWorkerError.h" |
50 #include "modules/serviceworkers/ServiceWorkerMessageEvent.h" | 50 #include "modules/serviceworkers/ServiceWorkerMessageEvent.h" |
51 #include "modules/serviceworkers/ServiceWorkerRegistration.h" | 51 #include "modules/serviceworkers/ServiceWorkerRegistration.h" |
52 #include "platform/RuntimeEnabledFeatures.h" | 52 #include "platform/RuntimeEnabledFeatures.h" |
53 #include "platform/weborigin/SchemeRegistry.h" | 53 #include "platform/weborigin/SchemeRegistry.h" |
54 #include "public/platform/WebString.h" | 54 #include "public/platform/WebString.h" |
55 #include "public/platform/WebURL.h" | 55 #include "public/platform/WebURL.h" |
56 #include "public/platform/modules/serviceworker/WebServiceWorker.h" | 56 #include "public/platform/modules/serviceworker/WebServiceWorker.h" |
57 #include "public/platform/modules/serviceworker/WebServiceWorkerProvider.h" | 57 #include "public/platform/modules/serviceworker/WebServiceWorkerProvider.h" |
58 #include "public/platform/modules/serviceworker/WebServiceWorkerRegistration.h" | 58 #include "public/platform/modules/serviceworker/WebServiceWorkerRegistration.h" |
| 59 #include "wtf/PtrUtil.h" |
| 60 #include <memory> |
59 | 61 |
60 namespace blink { | 62 namespace blink { |
61 | 63 |
62 class RegistrationCallback : public WebServiceWorkerProvider::WebServiceWorkerRe
gistrationCallbacks { | 64 class RegistrationCallback : public WebServiceWorkerProvider::WebServiceWorkerRe
gistrationCallbacks { |
63 public: | 65 public: |
64 explicit RegistrationCallback(ScriptPromiseResolver* resolver) | 66 explicit RegistrationCallback(ScriptPromiseResolver* resolver) |
65 : m_resolver(resolver) { } | 67 : m_resolver(resolver) { } |
66 ~RegistrationCallback() override { } | 68 ~RegistrationCallback() override { } |
67 | 69 |
68 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> handle)
override | 70 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> handle)
override |
69 { | 71 { |
70 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 72 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
71 return; | 73 return; |
72 m_resolver->resolve(ServiceWorkerRegistration::getOrCreate(m_resolver->g
etExecutionContext(), adoptPtr(handle.release()))); | 74 m_resolver->resolve(ServiceWorkerRegistration::getOrCreate(m_resolver->g
etExecutionContext(), wrapUnique(handle.release()))); |
73 } | 75 } |
74 | 76 |
75 void onError(const WebServiceWorkerError& error) override | 77 void onError(const WebServiceWorkerError& error) override |
76 { | 78 { |
77 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 79 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
78 return; | 80 return; |
79 if (error.errorType == WebServiceWorkerError::ErrorTypeType) { | 81 if (error.errorType == WebServiceWorkerError::ErrorTypeType) { |
80 m_resolver->reject(V8ThrowException::createTypeError(m_resolver->get
ScriptState()->isolate(), error.message)); | 82 m_resolver->reject(V8ThrowException::createTypeError(m_resolver->get
ScriptState()->isolate(), error.message)); |
81 } else { | 83 } else { |
82 m_resolver->reject(ServiceWorkerError::take(m_resolver.get(), error)
); | 84 m_resolver->reject(ServiceWorkerError::take(m_resolver.get(), error)
); |
83 } | 85 } |
84 } | 86 } |
85 | 87 |
86 private: | 88 private: |
87 Persistent<ScriptPromiseResolver> m_resolver; | 89 Persistent<ScriptPromiseResolver> m_resolver; |
88 WTF_MAKE_NONCOPYABLE(RegistrationCallback); | 90 WTF_MAKE_NONCOPYABLE(RegistrationCallback); |
89 }; | 91 }; |
90 | 92 |
91 class GetRegistrationCallback : public WebServiceWorkerProvider::WebServiceWorke
rGetRegistrationCallbacks { | 93 class GetRegistrationCallback : public WebServiceWorkerProvider::WebServiceWorke
rGetRegistrationCallbacks { |
92 public: | 94 public: |
93 explicit GetRegistrationCallback(ScriptPromiseResolver* resolver) | 95 explicit GetRegistrationCallback(ScriptPromiseResolver* resolver) |
94 : m_resolver(resolver) { } | 96 : m_resolver(resolver) { } |
95 ~GetRegistrationCallback() override { } | 97 ~GetRegistrationCallback() override { } |
96 | 98 |
97 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> webPass
Handle) override | 99 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> webPass
Handle) override |
98 { | 100 { |
99 OwnPtr<WebServiceWorkerRegistration::Handle> handle = adoptPtr(webPassHa
ndle.release()); | 101 std::unique_ptr<WebServiceWorkerRegistration::Handle> handle = wrapUniqu
e(webPassHandle.release()); |
100 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 102 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
101 return; | 103 return; |
102 if (!handle) { | 104 if (!handle) { |
103 // Resolve the promise with undefined. | 105 // Resolve the promise with undefined. |
104 m_resolver->resolve(); | 106 m_resolver->resolve(); |
105 return; | 107 return; |
106 } | 108 } |
107 m_resolver->resolve(ServiceWorkerRegistration::getOrCreate(m_resolver->g
etExecutionContext(), std::move(handle))); | 109 m_resolver->resolve(ServiceWorkerRegistration::getOrCreate(m_resolver->g
etExecutionContext(), std::move(handle))); |
108 } | 110 } |
109 | 111 |
(...skipping 10 matching lines...) Expand all Loading... |
120 }; | 122 }; |
121 | 123 |
122 class GetRegistrationsCallback : public WebServiceWorkerProvider::WebServiceWork
erGetRegistrationsCallbacks { | 124 class GetRegistrationsCallback : public WebServiceWorkerProvider::WebServiceWork
erGetRegistrationsCallbacks { |
123 public: | 125 public: |
124 explicit GetRegistrationsCallback(ScriptPromiseResolver* resolver) | 126 explicit GetRegistrationsCallback(ScriptPromiseResolver* resolver) |
125 : m_resolver(resolver) { } | 127 : m_resolver(resolver) { } |
126 ~GetRegistrationsCallback() override { } | 128 ~GetRegistrationsCallback() override { } |
127 | 129 |
128 void onSuccess(std::unique_ptr<WebVector<WebServiceWorkerRegistration::Handl
e*>> webPassRegistrations) override | 130 void onSuccess(std::unique_ptr<WebVector<WebServiceWorkerRegistration::Handl
e*>> webPassRegistrations) override |
129 { | 131 { |
130 Vector<OwnPtr<WebServiceWorkerRegistration::Handle>> handles; | 132 Vector<std::unique_ptr<WebServiceWorkerRegistration::Handle>> handles; |
131 OwnPtr<WebVector<WebServiceWorkerRegistration::Handle*>> webRegistration
s = adoptPtr(webPassRegistrations.release()); | 133 std::unique_ptr<WebVector<WebServiceWorkerRegistration::Handle*>> webReg
istrations = wrapUnique(webPassRegistrations.release()); |
132 for (auto& handle : *webRegistrations) { | 134 for (auto& handle : *webRegistrations) { |
133 handles.append(adoptPtr(handle)); | 135 handles.append(wrapUnique(handle)); |
134 } | 136 } |
135 | 137 |
136 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 138 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
137 return; | 139 return; |
138 m_resolver->resolve(ServiceWorkerRegistrationArray::take(m_resolver.get(
), &handles)); | 140 m_resolver->resolve(ServiceWorkerRegistrationArray::take(m_resolver.get(
), &handles)); |
139 } | 141 } |
140 | 142 |
141 void onError(const WebServiceWorkerError& error) override | 143 void onError(const WebServiceWorkerError& error) override |
142 { | 144 { |
143 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) | 145 if (!m_resolver->getExecutionContext() || m_resolver->getExecutionContex
t()->activeDOMObjectsAreStopped()) |
(...skipping 10 matching lines...) Expand all Loading... |
154 public: | 156 public: |
155 explicit GetRegistrationForReadyCallback(ReadyProperty* ready) | 157 explicit GetRegistrationForReadyCallback(ReadyProperty* ready) |
156 : m_ready(ready) { } | 158 : m_ready(ready) { } |
157 ~GetRegistrationForReadyCallback() override { } | 159 ~GetRegistrationForReadyCallback() override { } |
158 | 160 |
159 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> handle)
override | 161 void onSuccess(std::unique_ptr<WebServiceWorkerRegistration::Handle> handle)
override |
160 { | 162 { |
161 ASSERT(m_ready->getState() == ReadyProperty::Pending); | 163 ASSERT(m_ready->getState() == ReadyProperty::Pending); |
162 | 164 |
163 if (m_ready->getExecutionContext() && !m_ready->getExecutionContext()->a
ctiveDOMObjectsAreStopped()) | 165 if (m_ready->getExecutionContext() && !m_ready->getExecutionContext()->a
ctiveDOMObjectsAreStopped()) |
164 m_ready->resolve(ServiceWorkerRegistration::getOrCreate(m_ready->get
ExecutionContext(), adoptPtr(handle.release()))); | 166 m_ready->resolve(ServiceWorkerRegistration::getOrCreate(m_ready->get
ExecutionContext(), wrapUnique(handle.release()))); |
165 } | 167 } |
166 | 168 |
167 private: | 169 private: |
168 Persistent<ReadyProperty> m_ready; | 170 Persistent<ReadyProperty> m_ready; |
169 WTF_MAKE_NONCOPYABLE(GetRegistrationForReadyCallback); | 171 WTF_MAKE_NONCOPYABLE(GetRegistrationForReadyCallback); |
170 }; | 172 }; |
171 | 173 |
172 ServiceWorkerContainer* ServiceWorkerContainer::create(ExecutionContext* executi
onContext) | 174 ServiceWorkerContainer* ServiceWorkerContainer::create(ExecutionContext* executi
onContext) |
173 { | 175 { |
174 return new ServiceWorkerContainer(executionContext); | 176 return new ServiceWorkerContainer(executionContext); |
(...skipping 13 matching lines...) Expand all Loading... |
188 } | 190 } |
189 | 191 |
190 DEFINE_TRACE(ServiceWorkerContainer) | 192 DEFINE_TRACE(ServiceWorkerContainer) |
191 { | 193 { |
192 visitor->trace(m_controller); | 194 visitor->trace(m_controller); |
193 visitor->trace(m_ready); | 195 visitor->trace(m_ready); |
194 EventTargetWithInlineData::trace(visitor); | 196 EventTargetWithInlineData::trace(visitor); |
195 ContextLifecycleObserver::trace(visitor); | 197 ContextLifecycleObserver::trace(visitor); |
196 } | 198 } |
197 | 199 |
198 void ServiceWorkerContainer::registerServiceWorkerImpl(ExecutionContext* executi
onContext, const KURL& rawScriptURL, const KURL& scope, PassOwnPtr<RegistrationC
allbacks> callbacks) | 200 void ServiceWorkerContainer::registerServiceWorkerImpl(ExecutionContext* executi
onContext, const KURL& rawScriptURL, const KURL& scope, std::unique_ptr<Registra
tionCallbacks> callbacks) |
199 { | 201 { |
200 if (!m_provider) { | 202 if (!m_provider) { |
201 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eState, "Failed to register a ServiceWorker: The document is in an invalid state
.")); | 203 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::ErrorTyp
eState, "Failed to register a ServiceWorker: The document is in an invalid state
.")); |
202 return; | 204 return; |
203 } | 205 } |
204 | 206 |
205 RefPtr<SecurityOrigin> documentOrigin = executionContext->getSecurityOrigin(
); | 207 RefPtr<SecurityOrigin> documentOrigin = executionContext->getSecurityOrigin(
); |
206 String errorMessage; | 208 String errorMessage; |
207 // Restrict to secure origins: https://w3c.github.io/webappsec/specs/powerfu
lfeatures/#settings-privileged | 209 // Restrict to secure origins: https://w3c.github.io/webappsec/specs/powerfu
lfeatures/#settings-privileged |
208 if (!executionContext->isSecureContext(errorMessage)) { | 210 if (!executionContext->isSecureContext(errorMessage)) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 } | 250 } |
249 | 251 |
250 ContentSecurityPolicy* csp = executionContext->contentSecurityPolicy(); | 252 ContentSecurityPolicy* csp = executionContext->contentSecurityPolicy(); |
251 if (csp) { | 253 if (csp) { |
252 if (!csp->allowWorkerContextFromSource(scriptURL, ResourceRequest::Redir
ectStatus::NoRedirect, ContentSecurityPolicy::SendReport)) { | 254 if (!csp->allowWorkerContextFromSource(scriptURL, ResourceRequest::Redir
ectStatus::NoRedirect, ContentSecurityPolicy::SendReport)) { |
253 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::Erro
rTypeSecurity, String("Failed to register a ServiceWorker: The provided scriptUR
L ('" + scriptURL.getString() + "') violates the Content Security Policy."))); | 255 callbacks->onError(WebServiceWorkerError(WebServiceWorkerError::Erro
rTypeSecurity, String("Failed to register a ServiceWorker: The provided scriptUR
L ('" + scriptURL.getString() + "') violates the Content Security Policy."))); |
254 return; | 256 return; |
255 } | 257 } |
256 } | 258 } |
257 | 259 |
258 m_provider->registerServiceWorker(patternURL, scriptURL, callbacks.leakPtr()
); | 260 m_provider->registerServiceWorker(patternURL, scriptURL, callbacks.release()
); |
259 } | 261 } |
260 | 262 |
261 ScriptPromise ServiceWorkerContainer::registerServiceWorker(ScriptState* scriptS
tate, const String& url, const RegistrationOptions& options) | 263 ScriptPromise ServiceWorkerContainer::registerServiceWorker(ScriptState* scriptS
tate, const String& url, const RegistrationOptions& options) |
262 { | 264 { |
263 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 265 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
264 ScriptPromise promise = resolver->promise(); | 266 ScriptPromise promise = resolver->promise(); |
265 | 267 |
266 if (!m_provider) { | 268 if (!m_provider) { |
267 resolver->reject(DOMException::create(InvalidStateError, "Failed to regi
ster a ServiceWorker: The document is in an invalid state.")); | 269 resolver->reject(DOMException::create(InvalidStateError, "Failed to regi
ster a ServiceWorker: The document is in an invalid state.")); |
268 return promise; | 270 return promise; |
269 } | 271 } |
270 | 272 |
271 ExecutionContext* executionContext = scriptState->getExecutionContext(); | 273 ExecutionContext* executionContext = scriptState->getExecutionContext(); |
272 // FIXME: May be null due to worker termination: http://crbug.com/413518. | 274 // FIXME: May be null due to worker termination: http://crbug.com/413518. |
273 if (!executionContext) | 275 if (!executionContext) |
274 return ScriptPromise(); | 276 return ScriptPromise(); |
275 | 277 |
276 KURL scriptURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(url); | 278 KURL scriptURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(url); |
277 scriptURL.removeFragmentIdentifier(); | 279 scriptURL.removeFragmentIdentifier(); |
278 | 280 |
279 KURL patternURL; | 281 KURL patternURL; |
280 if (options.scope().isNull()) | 282 if (options.scope().isNull()) |
281 patternURL = KURL(scriptURL, "./"); | 283 patternURL = KURL(scriptURL, "./"); |
282 else | 284 else |
283 patternURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(options.scope()); | 285 patternURL = enteredExecutionContext(scriptState->isolate())->completeUR
L(options.scope()); |
284 | 286 |
285 registerServiceWorkerImpl(executionContext, scriptURL, patternURL, adoptPtr(
new RegistrationCallback(resolver))); | 287 registerServiceWorkerImpl(executionContext, scriptURL, patternURL, wrapUniqu
e(new RegistrationCallback(resolver))); |
286 | 288 |
287 return promise; | 289 return promise; |
288 } | 290 } |
289 | 291 |
290 ScriptPromise ServiceWorkerContainer::getRegistration(ScriptState* scriptState,
const String& documentURL) | 292 ScriptPromise ServiceWorkerContainer::getRegistration(ScriptState* scriptState,
const String& documentURL) |
291 { | 293 { |
292 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; | 294 ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState)
; |
293 ScriptPromise promise = resolver->promise(); | 295 ScriptPromise promise = resolver->promise(); |
294 | 296 |
295 if (!m_provider) { | 297 if (!m_provider) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 m_provider->getRegistrationForReady(new GetRegistrationForReadyCallb
ack(m_ready.get())); | 380 m_provider->getRegistrationForReady(new GetRegistrationForReadyCallb
ack(m_ready.get())); |
379 } | 381 } |
380 | 382 |
381 return m_ready->promise(callerState->world()); | 383 return m_ready->promise(callerState->world()); |
382 } | 384 } |
383 | 385 |
384 void ServiceWorkerContainer::setController(std::unique_ptr<WebServiceWorker::Han
dle> handle, bool shouldNotifyControllerChange) | 386 void ServiceWorkerContainer::setController(std::unique_ptr<WebServiceWorker::Han
dle> handle, bool shouldNotifyControllerChange) |
385 { | 387 { |
386 if (!getExecutionContext()) | 388 if (!getExecutionContext()) |
387 return; | 389 return; |
388 m_controller = ServiceWorker::from(getExecutionContext(), adoptPtr(handle.re
lease())); | 390 m_controller = ServiceWorker::from(getExecutionContext(), wrapUnique(handle.
release())); |
389 if (m_controller) | 391 if (m_controller) |
390 UseCounter::count(getExecutionContext(), UseCounter::ServiceWorkerContro
lledPage); | 392 UseCounter::count(getExecutionContext(), UseCounter::ServiceWorkerContro
lledPage); |
391 if (shouldNotifyControllerChange) | 393 if (shouldNotifyControllerChange) |
392 dispatchEvent(Event::create(EventTypeNames::controllerchange)); | 394 dispatchEvent(Event::create(EventTypeNames::controllerchange)); |
393 } | 395 } |
394 | 396 |
395 void ServiceWorkerContainer::dispatchMessageEvent(std::unique_ptr<WebServiceWork
er::Handle> handle, const WebString& message, const WebMessagePortChannelArray&
webChannels) | 397 void ServiceWorkerContainer::dispatchMessageEvent(std::unique_ptr<WebServiceWork
er::Handle> handle, const WebString& message, const WebMessagePortChannelArray&
webChannels) |
396 { | 398 { |
397 if (!getExecutionContext() || !getExecutionContext()->executingWindow()) | 399 if (!getExecutionContext() || !getExecutionContext()->executingWindow()) |
398 return; | 400 return; |
399 | 401 |
400 MessagePortArray* ports = MessagePort::toMessagePortArray(getExecutionContex
t(), webChannels); | 402 MessagePortArray* ports = MessagePort::toMessagePortArray(getExecutionContex
t(), webChannels); |
401 RefPtr<SerializedScriptValue> value = SerializedScriptValue::create(message)
; | 403 RefPtr<SerializedScriptValue> value = SerializedScriptValue::create(message)
; |
402 ServiceWorker* source = ServiceWorker::from(getExecutionContext(), adoptPtr(
handle.release())); | 404 ServiceWorker* source = ServiceWorker::from(getExecutionContext(), wrapUniqu
e(handle.release())); |
403 dispatchEvent(ServiceWorkerMessageEvent::create(ports, value, source, getExe
cutionContext()->getSecurityOrigin()->toString())); | 405 dispatchEvent(ServiceWorkerMessageEvent::create(ports, value, source, getExe
cutionContext()->getSecurityOrigin()->toString())); |
404 } | 406 } |
405 | 407 |
406 const AtomicString& ServiceWorkerContainer::interfaceName() const | 408 const AtomicString& ServiceWorkerContainer::interfaceName() const |
407 { | 409 { |
408 return EventTargetNames::ServiceWorkerContainer; | 410 return EventTargetNames::ServiceWorkerContainer; |
409 } | 411 } |
410 | 412 |
411 ServiceWorkerContainer::ServiceWorkerContainer(ExecutionContext* executionContex
t) | 413 ServiceWorkerContainer::ServiceWorkerContainer(ExecutionContext* executionContex
t) |
412 : ContextLifecycleObserver(executionContext) | 414 : ContextLifecycleObserver(executionContext) |
413 , m_provider(0) | 415 , m_provider(0) |
414 { | 416 { |
415 | 417 |
416 if (!executionContext) | 418 if (!executionContext) |
417 return; | 419 return; |
418 | 420 |
419 if (ServiceWorkerContainerClient* client = ServiceWorkerContainerClient::fro
m(executionContext)) { | 421 if (ServiceWorkerContainerClient* client = ServiceWorkerContainerClient::fro
m(executionContext)) { |
420 m_provider = client->provider(); | 422 m_provider = client->provider(); |
421 if (m_provider) | 423 if (m_provider) |
422 m_provider->setClient(this); | 424 m_provider->setClient(this); |
423 } | 425 } |
424 } | 426 } |
425 | 427 |
426 } // namespace blink | 428 } // namespace blink |
OLD | NEW |