Upstream version 5.34.92.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / serviceworkers / NavigatorServiceWorker.cpp
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #include "config.h"
31 #include "modules/serviceworkers/NavigatorServiceWorker.h"
32
33 #include "RuntimeEnabledFeatures.h"
34 #include "bindings/v8/CallbackPromiseAdapter.h"
35 #include "bindings/v8/ScriptPromiseResolver.h"
36 #include "core/dom/Document.h"
37 #include "core/dom/ExceptionCode.h"
38 #include "core/dom/ExecutionContext.h"
39 #include "core/frame/Frame.h"
40 #include "core/loader/DocumentLoader.h"
41 #include "core/loader/FrameLoaderClient.h"
42 #include "core/workers/SharedWorker.h"
43 #include "modules/serviceworkers/ServiceWorker.h"
44 #include "modules/serviceworkers/ServiceWorkerError.h"
45 #include "public/platform/WebServiceWorkerProvider.h"
46 #include "public/platform/WebServiceWorkerProviderClient.h"
47 #include "public/platform/WebString.h"
48 #include "public/platform/WebURL.h"
49
50 using blink::WebServiceWorkerProvider;
51 using blink::WebString;
52
53 namespace WebCore {
54
55 NavigatorServiceWorker::NavigatorServiceWorker(Navigator* navigator)
56     : DOMWindowProperty(navigator->frame())
57     , m_navigator(navigator)
58 {
59 }
60
61 NavigatorServiceWorker::~NavigatorServiceWorker()
62 {
63 }
64
65 const char* NavigatorServiceWorker::supplementName()
66 {
67     return "NavigatorServiceWorker";
68 }
69
70 WebServiceWorkerProvider* NavigatorServiceWorker::ensureProvider()
71 {
72     ASSERT(m_navigator->frame());
73     if (!m_provider) {
74         Frame* frame = m_navigator->frame();
75
76         FrameLoaderClient* client = frame->loader().client();
77         // FIXME: This is temporarily hooked up here until we hook up to the loading process.
78         m_provider = client->createServiceWorkerProvider(nullptr);
79     }
80     return m_provider.get();
81 }
82
83 NavigatorServiceWorker* NavigatorServiceWorker::from(Navigator* navigator)
84 {
85     NavigatorServiceWorker* supplement = toNavigatorServiceWorker(navigator);
86     if (!supplement) {
87         supplement = new NavigatorServiceWorker(navigator);
88         provideTo(navigator, supplementName(), adoptPtr(supplement));
89     }
90     return supplement;
91 }
92
93 ScriptPromise NavigatorServiceWorker::registerServiceWorker(ExecutionContext* context, Navigator* navigator, const String& pattern, const String& url, ExceptionState& exceptionState)
94 {
95     return from(navigator)->registerServiceWorker(context, pattern, url, exceptionState);
96 }
97
98 ScriptPromise NavigatorServiceWorker::registerServiceWorker(ExecutionContext* executionContext, const String& pattern, const String& scriptSrc, ExceptionState& exceptionState)
99 {
100     ASSERT(RuntimeEnabledFeatures::serviceWorkerEnabled());
101     ScriptPromise promise = ScriptPromise::createPending(executionContext);
102     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(promise, executionContext);
103
104     Frame* frame = m_navigator->frame();
105     if (!frame) {
106         resolver->reject(DOMError::create(InvalidStateError, "No document available."));
107         return promise;
108     }
109
110     RefPtr<SecurityOrigin> documentOrigin = frame->document()->securityOrigin();
111
112     KURL patternURL = executionContext->completeURL(pattern);
113     if (!documentOrigin->canRequest(patternURL)) {
114         resolver->reject(DOMError::create(SecurityError, "Can only register for patterns in the document's origin."));
115         return promise;
116     }
117
118     KURL scriptURL = executionContext->completeURL(scriptSrc);
119     if (!documentOrigin->canRequest(scriptURL)) {
120         resolver->reject(DOMError::create(SecurityError, "Script must be in document's origin."));
121         return promise;
122     }
123
124     ensureProvider()->registerServiceWorker(patternURL, scriptURL, new CallbackPromiseAdapter<ServiceWorker, ServiceWorkerError>(resolver, executionContext));
125     return promise;
126 }
127
128 ScriptPromise NavigatorServiceWorker::unregisterServiceWorker(ExecutionContext* context, Navigator* navigator, const String& pattern, ExceptionState& exceptionState)
129 {
130     return from(navigator)->unregisterServiceWorker(context, pattern, exceptionState);
131 }
132
133 ScriptPromise NavigatorServiceWorker::unregisterServiceWorker(ExecutionContext* executionContext, const String& pattern, ExceptionState& exceptionState)
134 {
135     ASSERT(RuntimeEnabledFeatures::serviceWorkerEnabled());
136     ScriptPromise promise = ScriptPromise::createPending(executionContext);
137     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(promise, executionContext);
138
139     Frame* frame = m_navigator->frame();
140     if (!frame) {
141         resolver->reject(DOMError::create(InvalidStateError, "No document available."));
142         return promise;
143     }
144
145     RefPtr<SecurityOrigin> documentOrigin = frame->document()->securityOrigin();
146
147     KURL patternURL = executionContext->completeURL(pattern);
148     if (!documentOrigin->canRequest(patternURL)) {
149         resolver->reject(DOMError::create(SecurityError, "Can only unregister for patterns in the document's origin."));
150
151         return promise;
152     }
153
154     ensureProvider()->unregisterServiceWorker(patternURL, new CallbackPromiseAdapter<ServiceWorker, ServiceWorkerError>(resolver, executionContext));
155     return promise;
156 }
157
158 void NavigatorServiceWorker::willDetachGlobalObjectFromFrame()
159 {
160     m_provider = nullptr;
161     DOMWindowProperty::willDetachGlobalObjectFromFrame();
162 }
163
164
165 } // namespace WebCore