OSDN Git Service

Merge WebKit at r78450: Initial merge by git.
[android-x86/external-webkit.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 "ExceptionCode.h"
31 #include "Frame.h"
32 #include "FrameLoader.h"
33 #include "FrameLoaderClient.h"
34 #include "Geolocation.h"
35 #include "KURL.h"
36 #include "Language.h"
37 #include "Page.h"
38 #include "PageGroup.h"
39 #include "PlatformString.h"
40 #include "PluginData.h"
41 #include "ScriptController.h"
42 #include "Settings.h"
43 #include "StorageNamespace.h"
44 #include <wtf/StdLibExtras.h>
45
46 #if PLATFORM(ANDROID)
47 #include "ApplicationInstalledCallback.h"
48 #include "Connection.h"
49 #include "PackageNotifier.h"
50 #endif
51
52 namespace WebCore {
53
54 Navigator::Navigator(Frame* frame)
55     : m_frame(frame)
56 {
57 }
58
59 Navigator::~Navigator()
60 {
61     disconnectFrame();
62 }
63
64 void Navigator::disconnectFrame()
65 {
66     if (m_plugins) {
67         m_plugins->disconnectFrame();
68         m_plugins = 0;
69     }
70     if (m_mimeTypes) {
71         m_mimeTypes->disconnectFrame();
72         m_mimeTypes = 0;
73     }
74     if (m_geolocation) {
75         m_geolocation->disconnectFrame();
76         m_geolocation = 0;
77     }
78     m_frame = 0;
79 }
80
81 // If this function returns true, we need to hide the substring "4." that would otherwise
82 // appear in the appVersion string. This is to avoid problems with old versions of a
83 // library called OpenCube QuickMenu, which as of this writing is still being used on
84 // sites such as nwa.com -- the library thinks Safari is Netscape 4 if we don't do this!
85 static bool shouldHideFourDot(Frame* frame)
86 {
87     const String* sourceURL = frame->script()->sourceURL();
88     if (!sourceURL)
89         return false;
90     if (!(sourceURL->endsWith("/dqm_script.js") || sourceURL->endsWith("/dqm_loader.js") || sourceURL->endsWith("/tdqm_loader.js")))
91         return false;
92     Settings* settings = frame->settings();
93     if (!settings)
94         return false;
95     return settings->needsSiteSpecificQuirks();
96 }
97
98 String Navigator::appVersion() const
99 {
100     if (!m_frame)
101         return String();
102     String appVersion = NavigatorBase::appVersion();
103     if (shouldHideFourDot(m_frame))
104         appVersion.replace("4.", "4_");
105     return appVersion;
106 }
107
108 String Navigator::language() const
109 {
110     return defaultLanguage();
111 }
112
113 String Navigator::userAgent() const
114 {
115     if (!m_frame)
116         return String();
117         
118     // If the frame is already detached, FrameLoader::userAgent may malfunction, because it calls a client method
119     // that uses frame's WebView (at least, in Mac WebKit).
120     if (!m_frame->page())
121         return String();
122         
123     return m_frame->loader()->userAgent(m_frame->document()->url());
124 }
125
126 DOMPluginArray* Navigator::plugins() const
127 {
128     if (!m_plugins)
129         m_plugins = DOMPluginArray::create(m_frame);
130     return m_plugins.get();
131 }
132
133 DOMMimeTypeArray* Navigator::mimeTypes() const
134 {
135     if (!m_mimeTypes)
136         m_mimeTypes = DOMMimeTypeArray::create(m_frame);
137     return m_mimeTypes.get();
138 }
139
140 bool Navigator::cookieEnabled() const
141 {
142     if (!m_frame)
143         return false;
144         
145     if (m_frame->page() && !m_frame->page()->cookieEnabled())
146         return false;
147
148     return cookiesEnabled(m_frame->document());
149 }
150
151 bool Navigator::javaEnabled() const
152 {
153     if (!m_frame || !m_frame->settings())
154         return false;
155
156     return m_frame->settings()->isJavaEnabled();
157 }
158
159 Geolocation* Navigator::geolocation() const
160 {
161     if (!m_geolocation)
162         m_geolocation = Geolocation::create(m_frame);
163     return m_geolocation.get();
164 }
165
166 #if PLATFORM(ANDROID)
167 Connection* Navigator::connection() const
168 {
169     if (!m_connection)
170         m_connection = Connection::create();
171     return m_connection.get();
172 }
173 #endif
174
175 #if PLATFORM(ANDROID) && ENABLE(APPLICATION_INSTALLED)
176
177 bool Navigator::isApplicationInstalled(const String& name, PassRefPtr<ApplicationInstalledCallback> callback)
178 {
179     if (m_applicationInstalledCallback)
180         return false;
181
182     m_applicationInstalledCallback = callback;
183     m_applicationNameQuery = name;
184
185     packageNotifier().requestPackageResult();
186
187     return true;
188 }
189
190 void Navigator::onPackageResult()
191 {
192     if (m_applicationInstalledCallback) {
193         m_applicationInstalledCallback->handleEvent(packageNotifier().isPackageInstalled(m_applicationNameQuery));
194         m_applicationInstalledCallback = 0;
195     }
196 }
197 #endif
198
199 #if ENABLE(DOM_STORAGE)
200 void Navigator::getStorageUpdates()
201 {
202     if (!m_frame)
203         return;
204
205     Page* page = m_frame->page();
206     if (!page)
207         return;
208
209     StorageNamespace* localStorage = page->group().localStorage();
210     if (localStorage)
211         localStorage->unlock();
212 }
213 #endif
214
215 #if ENABLE(REGISTER_PROTOCOL_HANDLER)
216 static bool verifyCustomHandlerURL(const String& baseURL, const String& url, ExceptionCode& ec)
217 {
218     // The specification requires that it is a SYNTAX_ERR if the "%s" token is
219     // not present.
220     static const char token[] = "%s";
221     int index = url.find(token);
222     if (-1 == index) {
223         ec = SYNTAX_ERR;
224         return false;
225     }
226
227     // It is also a SYNTAX_ERR if the custom handler URL, as created by removing
228     // the "%s" token and prepending the base url, does not resolve.
229     String newURL = url;
230     newURL.remove(index, WTF_ARRAY_LENGTH(token) - 1);
231
232     KURL base(ParsedURLString, baseURL);
233     KURL kurl(base, newURL);
234
235     if (kurl.isEmpty() || !kurl.isValid()) {
236         ec = SYNTAX_ERR;
237         return false;
238     }
239
240     return true;
241 }
242
243 static bool verifyProtocolHandlerScheme(const String& scheme, ExceptionCode& ec)
244 {
245     // It is a SECURITY_ERR for these schemes to be handled by a custom handler.
246     if (equalIgnoringCase(scheme, "http") || equalIgnoringCase(scheme, "https") || equalIgnoringCase(scheme, "file")) {
247         ec = SECURITY_ERR;
248         return false;
249     }
250     return true;
251 }
252
253 void Navigator::registerProtocolHandler(const String& scheme, const String& url, const String& title, ExceptionCode& ec)
254 {
255     if (!verifyProtocolHandlerScheme(scheme, ec))
256         return;
257
258     if (!m_frame)
259         return;
260
261     Document* document = m_frame->document();
262     if (!document)
263         return;
264
265     String baseURL = document->baseURL().baseAsString();
266
267     if (!verifyCustomHandlerURL(baseURL, url, ec))
268         return;
269
270     Page* page = m_frame->page();
271     if (!page)
272         return;
273
274     page->chrome()->registerProtocolHandler(scheme, baseURL, url, m_frame->displayStringModifiedByEncoding(title));
275 }
276 #endif
277
278 } // namespace WebCore