tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebCore / page / Navigator.cpp
1 /*
2  *  Copyright (C) 2000 Harri Porten (porten@kde.org)
3  *  Copyright (c) 2000 Daniel Molkentin (molkentin@kde.org)
4  *  Copyright (c) 2000 Stefan Schimanski (schimmi@kde.org)
5  *  Copyright (C) 2003, 2004, 2005, 2006 Apple Computer, Inc.
6  *  Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
7  *
8  *  This library is free software; you can redistribute it and/or
9  *  modify it under the terms of the GNU Lesser General Public
10  *  License as published by the Free Software Foundation; either
11  *  version 2 of the License, or (at your option) any later version.
12  *
13  *  This library is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  *  Lesser General Public License for more details.
17  *
18  *  You should have received a copy of the GNU Lesser General Public
19  *  License along with this library; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 #include "config.h"
24 #include "Navigator.h"
25
26 #include "Chrome.h"
27 #include "CookieJar.h"
28 #include "DOMMimeTypeArray.h"
29 #include "DOMPluginArray.h"
30 #include "Document.h"
31 #include "ExceptionCode.h"
32 #include "Frame.h"
33 #include "FrameLoader.h"
34 #include "FrameLoaderClient.h"
35 #include "Geolocation.h"
36 #include "PointerLock.h"
37 #include "KURL.h"
38 #include "Language.h"
39 #include "Page.h"
40 #include "PageGroup.h"
41 #include "PlatformString.h"
42 #include "PluginData.h"
43 #include "Settings.h"
44 #include "StorageNamespace.h"
45 #include <wtf/HashSet.h>
46 #include <wtf/StdLibExtras.h>
47
48 #if ENABLE(GAMEPAD)
49 #include "GamepadList.h"
50 #include "Gamepads.h"
51 #endif
52
53 #if ENABLE(MEDIA_STREAM)
54 #include "NavigatorUserMediaErrorCallback.h"
55 #include "NavigatorUserMediaSuccessCallback.h"
56 #include "UserMediaRequest.h"
57 #endif
58
59 namespace WebCore {
60
61 Navigator::Navigator(Frame* frame)
62     : m_frame(frame)
63 {
64 }
65
66 Navigator::~Navigator()
67 {
68     disconnectFrame();
69 }
70
71 void Navigator::resetGeolocation()
72 {
73     if (m_geolocation)
74         m_geolocation->reset();
75 }
76
77 void Navigator::disconnectFrame()
78 {
79     if (m_plugins) {
80         m_plugins->disconnectFrame();
81         m_plugins = 0;
82     }
83     if (m_mimeTypes) {
84         m_mimeTypes->disconnectFrame();
85         m_mimeTypes = 0;
86     }
87     if (m_geolocation) {
88         m_geolocation->disconnectFrame();
89         m_geolocation = 0;
90     }
91     m_frame = 0;
92 }
93
94 // If this function returns true, we need to hide the substring "4." that would otherwise
95 // appear in the appVersion string. This is to avoid problems with old versions of a
96 // library called OpenCube QuickMenu, which as of this writing is still being used on
97 // sites such as nwa.com -- the library thinks Safari is Netscape 4 if we don't do this!
98 static bool shouldHideFourDot(Frame* frame)
99 {
100     const String* sourceURL = frame->script()->sourceURL();
101     if (!sourceURL)
102         return false;
103     if (!(sourceURL->endsWith("/dqm_script.js") || sourceURL->endsWith("/dqm_loader.js") || sourceURL->endsWith("/tdqm_loader.js")))
104         return false;
105     Settings* settings = frame->settings();
106     if (!settings)
107         return false;
108     return settings->needsSiteSpecificQuirks();
109 }
110
111 String Navigator::appVersion() const
112 {
113     if (!m_frame)
114         return String();
115     String appVersion = NavigatorBase::appVersion();
116     if (shouldHideFourDot(m_frame))
117         appVersion.replace("4.", "4_");
118     return appVersion;
119 }
120
121 String Navigator::language() const
122 {
123     return defaultLanguage();
124 }
125
126 String Navigator::userAgent() const
127 {
128     if (!m_frame)
129         return String();
130         
131     // If the frame is already detached, FrameLoader::userAgent may malfunction, because it calls a client method
132     // that uses frame's WebView (at least, in Mac WebKit).
133     if (!m_frame->page())
134         return String();
135         
136     return m_frame->loader()->userAgent(m_frame->document()->url());
137 }
138
139 DOMPluginArray* Navigator::plugins() const
140 {
141     if (!m_plugins)
142         m_plugins = DOMPluginArray::create(m_frame);
143     return m_plugins.get();
144 }
145
146 DOMMimeTypeArray* Navigator::mimeTypes() const
147 {
148     if (!m_mimeTypes)
149         m_mimeTypes = DOMMimeTypeArray::create(m_frame);
150     return m_mimeTypes.get();
151 }
152
153 bool Navigator::cookieEnabled() const
154 {
155     if (!m_frame)
156         return false;
157         
158     if (m_frame->page() && !m_frame->page()->cookieEnabled())
159         return false;
160
161     return cookiesEnabled(m_frame->document());
162 }
163
164 bool Navigator::javaEnabled() const
165 {
166     if (!m_frame || !m_frame->settings())
167         return false;
168
169     return m_frame->settings()->isJavaEnabled();
170 }
171
172 Geolocation* Navigator::geolocation() const
173 {
174     if (!m_geolocation)
175         m_geolocation = Geolocation::create(m_frame);
176     return m_geolocation.get();
177 }
178
179 #if ENABLE(POINTER_LOCK)
180 PointerLock* Navigator::webkitPointer() const
181 {
182     if (!m_pointer)
183         m_pointer = PointerLock::create();
184     return m_pointer.get();
185 }
186 #endif
187
188 void Navigator::getStorageUpdates()
189 {
190     // FIXME: Remove this method or rename to yieldForStorageUpdates.
191 }
192
193 #if ENABLE(REGISTER_PROTOCOL_HANDLER)
194 static HashSet<String>* protocolWhitelist;
195
196 static void initProtocolHandlerWhitelist()
197 {
198     protocolWhitelist = new HashSet<String>;
199     static const char* protocols[] = {
200         "irc",
201         "mailto",
202         "mms",
203         "news",
204         "nntp",
205         "sms",
206         "smsto",
207         "tel",
208         "urn",
209         "webcal",
210     };
211     for (size_t i = 0; i < WTF_ARRAY_LENGTH(protocols); ++i)
212         protocolWhitelist->add(protocols[i]);
213 }
214
215 static bool verifyCustomHandlerURL(const String& baseURL, const String& url, ExceptionCode& ec)
216 {
217     // The specification requires that it is a SYNTAX_ERR if the "%s" token is
218     // not present.
219     static const char token[] = "%s";
220     int index = url.find(token);
221     if (-1 == index) {
222         ec = SYNTAX_ERR;
223         return false;
224     }
225
226     // It is also a SYNTAX_ERR if the custom handler URL, as created by removing
227     // the "%s" token and prepending the base url, does not resolve.
228     String newURL = url;
229     newURL.remove(index, WTF_ARRAY_LENGTH(token) - 1);
230
231     KURL base(ParsedURLString, baseURL);
232     KURL kurl(base, newURL);
233
234     if (kurl.isEmpty() || !kurl.isValid()) {
235         ec = SYNTAX_ERR;
236         return false;
237     }
238
239     return true;
240 }
241
242 static bool isProtocolWhitelisted(const String& scheme)
243 {
244     if (!protocolWhitelist)
245         initProtocolHandlerWhitelist();
246     return protocolWhitelist->contains(scheme);
247 }
248
249 static bool verifyProtocolHandlerScheme(const String& scheme, ExceptionCode& ec)
250 {
251     if (scheme.startsWith("web+")) {
252         if (isValidProtocol(scheme))
253             return true;
254         ec = SECURITY_ERR;
255         return false;
256     }
257
258     if (isProtocolWhitelisted(scheme))
259         return true;
260     ec = SECURITY_ERR;
261     return false;
262 }
263
264 void Navigator::registerProtocolHandler(const String& scheme, const String& url, const String& title, ExceptionCode& ec)
265 {
266     if (!m_frame)
267         return;
268
269     Document* document = m_frame->document();
270     if (!document)
271         return;
272
273     String baseURL = document->baseURL().baseAsString();
274
275     if (!verifyCustomHandlerURL(baseURL, url, ec))
276         return;
277
278     if (!verifyProtocolHandlerScheme(scheme, ec))
279         return;
280
281     Page* page = m_frame->page();
282     if (!page)
283         return;
284
285     page->chrome()->registerProtocolHandler(scheme, baseURL, url, m_frame->displayStringModifiedByEncoding(title));
286 }
287 #endif
288
289 #if ENABLE(MEDIA_STREAM)
290 void Navigator::webkitGetUserMedia(const String& options, PassRefPtr<NavigatorUserMediaSuccessCallback> successCallback, PassRefPtr<NavigatorUserMediaErrorCallback> errorCallback, ExceptionCode& ec)
291 {
292     if (!successCallback)
293         return;
294
295     if (!m_frame)
296         return;
297
298     Page* page = m_frame->page();
299     if (!page)
300         return;
301
302     RefPtr<UserMediaRequest> request = UserMediaRequest::create(m_frame->document(), page->userMediaClient(), options, successCallback, errorCallback);
303     if (!request) {
304         ec = NOT_SUPPORTED_ERR;
305         return;
306     }
307
308     request->start();
309 }
310 #endif
311
312 #if ENABLE(GAMEPAD)
313 GamepadList* Navigator::webkitGamepads()
314 {
315     if (!m_gamepads)
316         m_gamepads = GamepadList::create();
317     sampleGamepads(m_gamepads.get());
318     return m_gamepads.get();
319 }
320 #endif
321
322 } // namespace WebCore