OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/webui/web_ui_factory.h" | 5 #include "content/browser/webui/web_ui_factory.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "content/browser/content_browser_client.h" |
8 #include "chrome/browser/about_flags.h" | 8 #include "content/common/content_client.h" |
9 #include "chrome/browser/extensions/extension_service.h" | |
10 #include "chrome/browser/extensions/extension_web_ui.h" | |
11 #include "chrome/browser/extensions/extensions_ui.h" | |
12 #include "chrome/browser/profiles/profile.h" | |
13 #include "chrome/browser/ui/webui/bookmarks_ui.h" | |
14 #include "chrome/browser/ui/webui/bug_report_ui.h" | |
15 #include "chrome/browser/ui/webui/constrained_html_ui.h" | |
16 #include "chrome/browser/ui/webui/crashes_ui.h" | |
17 #include "chrome/browser/ui/webui/devtools_ui.h" | |
18 #include "chrome/browser/ui/webui/downloads_ui.h" | |
19 #include "chrome/browser/ui/webui/flags_ui.h" | |
20 #include "chrome/browser/ui/webui/gpu_internals_ui.h" | |
21 #include "chrome/browser/ui/webui/history2_ui.h" | |
22 #include "chrome/browser/ui/webui/history_ui.h" | |
23 #include "chrome/browser/ui/webui/html_dialog_ui.h" | |
24 #include "chrome/browser/ui/webui/net_internals_ui.h" | |
25 #include "chrome/browser/ui/webui/new_tab_ui.h" | |
26 #include "chrome/browser/ui/webui/options/options_ui.h" | |
27 #include "chrome/browser/ui/webui/plugins_ui.h" | |
28 #include "chrome/browser/ui/webui/print_preview_ui.h" | |
29 #include "chrome/browser/ui/webui/remoting_ui.h" | |
30 #include "chrome/browser/ui/webui/slideshow_ui.h" | |
31 #include "chrome/browser/ui/webui/sync_internals_ui.h" | |
32 #include "chrome/browser/ui/webui/textfields_ui.h" | |
33 #include "chrome/common/chrome_switches.h" | |
34 #include "chrome/common/extensions/extension_constants.h" | |
35 #include "chrome/common/url_constants.h" | |
36 #include "content/browser/tab_contents/tab_contents.h" | |
37 #include "googleurl/src/gurl.h" | |
38 | 9 |
39 #if defined(OS_CHROMEOS) | 10 namespace content { |
40 #include "chrome/browser/ui/webui/chromeos/imageburner_ui.h" | |
41 #include "chrome/browser/ui/webui/chromeos/keyboard_overlay_ui.h" | |
42 #include "chrome/browser/ui/webui/chromeos/mobile_setup_ui.h" | |
43 #include "chrome/browser/ui/webui/chromeos/proxy_settings_ui.h" | |
44 #include "chrome/browser/ui/webui/chromeos/register_page_ui.h" | |
45 #include "chrome/browser/ui/webui/chromeos/sim_unlock_ui.h" | |
46 #include "chrome/browser/ui/webui/chromeos/system_info_ui.h" | |
47 #include "chrome/browser/ui/webui/filebrowse_ui.h" | |
48 #include "chrome/browser/ui/webui/mediaplayer_ui.h" | |
49 #endif | |
50 | 11 |
51 #if defined(TOUCH_UI) | 12 // static |
52 #include "chrome/browser/ui/webui/keyboard_ui.h" | 13 WebUIFactory* WebUIFactory::Get() { |
53 #endif | 14 return content::GetContentClient()->browser()->GetWebUIFactory(); |
54 | |
55 #if defined(TOUCH_UI) && defined(OS_CHROMEOS) | |
56 #include "chrome/browser/ui/webui/chromeos/login/login_container_ui.h" | |
57 #include "chrome/browser/ui/webui/chromeos/login/login_ui.h" | |
58 #endif | |
59 | |
60 #if defined(OS_WIN) | |
61 #include "chrome/browser/ui/webui/conflicts_ui.h" | |
62 #endif | |
63 | |
64 const WebUITypeID WebUIFactory::kNoWebUI = NULL; | |
65 | |
66 // A function for creating a new WebUI. The caller owns the return value, which | |
67 // may be NULL (for example, if the URL refers to an non-existent extension). | |
68 typedef WebUI* (*WebUIFactoryFunction)(TabContents* tab_contents, | |
69 const GURL& url); | |
70 | |
71 // Template for defining WebUIFactoryFunction. | |
72 template<class T> | |
73 WebUI* NewWebUI(TabContents* contents, const GURL& url) { | |
74 return new T(contents); | |
75 } | 15 } |
76 | 16 |
77 // Special case for extensions. | 17 } // namespace content |
78 template<> | |
79 WebUI* NewWebUI<ExtensionWebUI>(TabContents* contents, const GURL& url) { | |
80 // Don't use a WebUI for incognito tabs because we require extensions to run | |
81 // within a single process. | |
82 ExtensionService* service = contents->profile()->GetExtensionService(); | |
83 if (service && | |
84 service->ExtensionBindingsAllowed(url)) { | |
85 return new ExtensionWebUI(contents, url); | |
86 } | |
87 return NULL; | |
88 } | |
89 | |
90 // Returns a function that can be used to create the right type of WebUI for a | |
91 // tab, based on its URL. Returns NULL if the URL doesn't have WebUI associated | |
92 // with it. Even if the factory function is valid, it may yield a NULL WebUI | |
93 // when invoked for a particular tab - see NewWebUI<ExtensionWebUI>. | |
94 static WebUIFactoryFunction GetWebUIFactoryFunction(Profile* profile, | |
95 const GURL& url) { | |
96 if (url.host() == chrome::kChromeUIDialogHost) | |
97 return &NewWebUI<ConstrainedHtmlUI>; | |
98 | |
99 ExtensionService* service = profile ? profile->GetExtensionService() : NULL; | |
100 if (service && service->ExtensionBindingsAllowed(url)) | |
101 return &NewWebUI<ExtensionWebUI>; | |
102 | |
103 // All platform builds of Chrome will need to have a cloud printing | |
104 // dialog as backup. It's just that on Chrome OS, it's the only | |
105 // print dialog. | |
106 if (url.host() == chrome::kCloudPrintResourcesHost) | |
107 return &NewWebUI<ExternalHtmlDialogUI>; | |
108 | |
109 // This will get called a lot to check all URLs, so do a quick check of other | |
110 // schemes to filter out most URLs. | |
111 if (!url.SchemeIs(chrome::kChromeDevToolsScheme) && | |
112 !url.SchemeIs(chrome::kChromeInternalScheme) && | |
113 !url.SchemeIs(chrome::kChromeUIScheme)) | |
114 return NULL; | |
115 | |
116 if (url.host() == chrome::kChromeUISyncResourcesHost || | |
117 url.host() == chrome::kChromeUIRemotingResourcesHost || | |
118 url.host() == chrome::kCloudPrintSetupHost) | |
119 return &NewWebUI<HtmlDialogUI>; | |
120 | |
121 // Special case the new tab page. In older versions of Chrome, the new tab | |
122 // page was hosted at chrome-internal:<blah>. This might be in people's saved | |
123 // sessions or bookmarks, so we say any URL with that scheme triggers the new | |
124 // tab page. | |
125 if (url.host() == chrome::kChromeUINewTabHost || | |
126 url.SchemeIs(chrome::kChromeInternalScheme)) | |
127 return &NewWebUI<NewTabUI>; | |
128 | |
129 // Give about:about a generic Web UI so it can navigate to pages with Web UIs. | |
130 if (url.spec() == chrome::kChromeUIAboutAboutURL) | |
131 return &NewWebUI<WebUI>; | |
132 | |
133 // We must compare hosts only since some of the Web UIs append extra stuff | |
134 // after the host name. | |
135 if (url.host() == chrome::kChromeUIBookmarksHost) | |
136 return &NewWebUI<BookmarksUI>; | |
137 if (url.host() == chrome::kChromeUIBugReportHost) | |
138 return &NewWebUI<BugReportUI>; | |
139 if (url.host() == chrome::kChromeUICrashesHost) | |
140 return &NewWebUI<CrashesUI>; | |
141 if (url.host() == chrome::kChromeUIDevToolsHost) | |
142 return &NewWebUI<DevToolsUI>; | |
143 #if defined(OS_WIN) | |
144 if (url.host() == chrome::kChromeUIConflictsHost) | |
145 return &NewWebUI<ConflictsUI>; | |
146 #endif | |
147 if (url.host() == chrome::kChromeUIDownloadsHost) | |
148 return &NewWebUI<DownloadsUI>; | |
149 if (url.host() == chrome::kChromeUITextfieldsHost) | |
150 return &NewWebUI<TextfieldsUI>; | |
151 if (url.host() == chrome::kChromeUIExtensionsHost) | |
152 return &NewWebUI<ExtensionsUI>; | |
153 if (url.host() == chrome::kChromeUIHistoryHost) | |
154 return &NewWebUI<HistoryUI>; | |
155 if (url.host() == chrome::kChromeUIHistory2Host) | |
156 return &NewWebUI<HistoryUI2>; | |
157 if (url.host() == chrome::kChromeUIFlagsHost) | |
158 return &NewWebUI<FlagsUI>; | |
159 #if defined(TOUCH_UI) | |
160 if (url.host() == chrome::kChromeUIKeyboardHost) | |
161 return &NewWebUI<KeyboardUI>; | |
162 #endif | |
163 if (url.host() == chrome::kChromeUIGpuInternalsHost) | |
164 return &NewWebUI<GpuInternalsUI>; | |
165 if (url.host() == chrome::kChromeUINetInternalsHost) | |
166 return &NewWebUI<NetInternalsUI>; | |
167 if (url.host() == chrome::kChromeUIPluginsHost) | |
168 return &NewWebUI<PluginsUI>; | |
169 if (url.host() == chrome::kChromeUISyncInternalsHost) | |
170 return &NewWebUI<SyncInternalsUI>; | |
171 #if defined(ENABLE_REMOTING) | |
172 if (url.host() == chrome::kChromeUIRemotingHost) { | |
173 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
174 switches::kEnableRemoting)) { | |
175 return &NewWebUI<RemotingUI>; | |
176 } | |
177 } | |
178 #endif | |
179 | |
180 #if defined(OS_CHROMEOS) | |
181 if (url.host() == chrome::kChromeUICollectedCookiesHost || | |
182 url.host() == chrome::kChromeUIHttpAuthHost) | |
183 return &NewWebUI<ConstrainedHtmlUI>; | |
184 if (url.host() == chrome::kChromeUIFileBrowseHost) | |
185 return &NewWebUI<FileBrowseUI>; | |
186 if (url.host() == chrome::kChromeUIImageBurnerHost) | |
187 return &NewWebUI<ImageBurnUI>; | |
188 if (url.host() == chrome::kChromeUIKeyboardOverlayHost) | |
189 return &NewWebUI<KeyboardOverlayUI>; | |
190 if (url.host() == chrome::kChromeUIMediaplayerHost) | |
191 return &NewWebUI<MediaplayerUI>; | |
192 if (url.host() == chrome::kChromeUIMobileSetupHost) | |
193 return &NewWebUI<MobileSetupUI>; | |
194 if (url.host() == chrome::kChromeUIProxySettingsHost) | |
195 return &NewWebUI<chromeos::ProxySettingsUI>; | |
196 if (url.host() == chrome::kChromeUIRegisterPageHost) | |
197 return &NewWebUI<RegisterPageUI>; | |
198 if (url.host() == chrome::kChromeUISettingsHost) | |
199 return &NewWebUI<OptionsUI>; | |
200 if (url.host() == chrome::kChromeUISlideshowHost) | |
201 return &NewWebUI<SlideshowUI>; | |
202 if (url.host() == chrome::kChromeUISimUnlockHost) | |
203 return &NewWebUI<chromeos::SimUnlockUI>; | |
204 if (url.host() == chrome::kChromeUISystemInfoHost) | |
205 return &NewWebUI<SystemInfoUI>; | |
206 #else | |
207 if (url.host() == chrome::kChromeUISettingsHost) | |
208 return &NewWebUI<OptionsUI>; | |
209 if (url.host() == chrome::kChromeUIPrintHost) { | |
210 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
211 switches::kEnablePrintPreview)) { | |
212 return &NewWebUI<PrintPreviewUI>; | |
213 } | |
214 } | |
215 #endif // defined(OS_CHROMEOS) | |
216 | |
217 #if defined(TOUCH_UI) && defined(OS_CHROMEOS) | |
218 if (url.host() == chrome::kChromeUILoginHost) | |
219 return &NewWebUI<chromeos::LoginUI>; | |
220 if (url.host() == chrome::kChromeUILoginContainerHost) | |
221 return &NewWebUI<chromeos::LoginContainerUI>; | |
222 #endif | |
223 | |
224 if (url.spec() == chrome::kChromeUIConstrainedHTMLTestURL) | |
225 return &NewWebUI<ConstrainedHtmlUI>; | |
226 | |
227 return NULL; | |
228 } | |
229 | |
230 // static | |
231 WebUITypeID WebUIFactory::GetWebUIType(Profile* profile, const GURL& url) { | |
232 WebUIFactoryFunction function = GetWebUIFactoryFunction(profile, url); | |
233 return function ? reinterpret_cast<WebUITypeID>(function) : kNoWebUI; | |
234 } | |
235 | |
236 // static | |
237 bool WebUIFactory::HasWebUIScheme(const GURL& url) { | |
238 return url.SchemeIs(chrome::kChromeDevToolsScheme) || | |
239 url.SchemeIs(chrome::kChromeInternalScheme) || | |
240 url.SchemeIs(chrome::kChromeUIScheme) || | |
241 url.SchemeIs(chrome::kExtensionScheme); | |
242 } | |
243 | |
244 // static | |
245 bool WebUIFactory::UseWebUIForURL(Profile* profile, const GURL& url) { | |
246 return GetWebUIFactoryFunction(profile, url) != NULL; | |
247 } | |
248 | |
249 // static | |
250 bool WebUIFactory::IsURLAcceptableForWebUI(Profile* profile, const GURL& url) { | |
251 return UseWebUIForURL(profile, url) || | |
252 // javacsript: URLs are allowed to run in Web UI pages | |
253 url.SchemeIs(chrome::kJavaScriptScheme) || | |
254 // It's possible to load about:blank in a Web UI renderer. | |
255 // See http://crbug.com/42547 | |
256 url.spec() == chrome::kAboutBlankURL || | |
257 // about:crash, about:kill, about:hang, and about:shorthang are allowed. | |
258 url.spec() == chrome::kAboutCrashURL || | |
259 url.spec() == chrome::kAboutKillURL || | |
260 url.spec() == chrome::kAboutHangURL || | |
261 url.spec() == chrome::kAboutShorthangURL; | |
262 } | |
263 | |
264 // static | |
265 WebUI* WebUIFactory::CreateWebUIForURL(TabContents* tab_contents, | |
266 const GURL& url) { | |
267 WebUIFactoryFunction function = GetWebUIFactoryFunction( | |
268 tab_contents->profile(), url); | |
269 if (!function) | |
270 return NULL; | |
271 return (*function)(tab_contents, url); | |
272 } | |
273 | |
274 // static | |
275 void WebUIFactory::GetFaviconForURL(Profile* profile, | |
276 FaviconService::GetFaviconRequest* request, | |
277 const GURL& page_url) { | |
278 // All extensions but the bookmark manager get their favicon from the icons | |
279 // part of the manifest. | |
280 if (page_url.SchemeIs(chrome::kExtensionScheme) && | |
281 page_url.host() != extension_misc::kBookmarkManagerId) { | |
282 ExtensionWebUI::GetFaviconForURL(profile, request, page_url); | |
283 } else { | |
284 history::FaviconData favicon; | |
285 favicon.image_data = scoped_refptr<RefCountedMemory>( | |
286 WebUIFactory::GetFaviconResourceBytes(profile, page_url)); | |
287 favicon.known_icon = favicon.image_data.get() != NULL && | |
288 favicon.image_data->size() > 0; | |
289 request->ForwardResultAsync( | |
290 FaviconService::FaviconDataCallback::TupleType(request->handle(), | |
291 favicon)); | |
292 } | |
293 } | |
294 | |
295 // static | |
296 RefCountedMemory* WebUIFactory::GetFaviconResourceBytes(Profile* profile, | |
297 const GURL& page_url) { | |
298 // The bookmark manager is a chrome extension, so we have to check for it | |
299 // before we check for extension scheme. | |
300 if (page_url.host() == extension_misc::kBookmarkManagerId) | |
301 return BookmarksUI::GetFaviconResourceBytes(); | |
302 | |
303 // The extension scheme is handled in GetFaviconForURL. | |
304 if (page_url.SchemeIs(chrome::kExtensionScheme)) { | |
305 NOTREACHED(); | |
306 return NULL; | |
307 } | |
308 | |
309 if (!HasWebUIScheme(page_url)) | |
310 return NULL; | |
311 | |
312 #if defined(OS_WIN) | |
313 if (page_url.host() == chrome::kChromeUIConflictsHost) | |
314 return ConflictsUI::GetFaviconResourceBytes(); | |
315 #endif | |
316 | |
317 if (page_url.host() == chrome::kChromeUICrashesHost) | |
318 return CrashesUI::GetFaviconResourceBytes(); | |
319 | |
320 if (page_url.host() == chrome::kChromeUIDownloadsHost) | |
321 return DownloadsUI::GetFaviconResourceBytes(); | |
322 | |
323 if (page_url.host() == chrome::kChromeUIExtensionsHost) | |
324 return ExtensionsUI::GetFaviconResourceBytes(); | |
325 | |
326 if (page_url.host() == chrome::kChromeUIHistoryHost) | |
327 return HistoryUI::GetFaviconResourceBytes(); | |
328 | |
329 if (page_url.host() == chrome::kChromeUIHistory2Host) | |
330 return HistoryUI2::GetFaviconResourceBytes(); | |
331 | |
332 if (page_url.host() == chrome::kChromeUIFlagsHost) | |
333 return FlagsUI::GetFaviconResourceBytes(); | |
334 | |
335 if (page_url.host() == chrome::kChromeUISettingsHost) | |
336 return OptionsUI::GetFaviconResourceBytes(); | |
337 | |
338 if (page_url.host() == chrome::kChromeUIPluginsHost) | |
339 return PluginsUI::GetFaviconResourceBytes(); | |
340 | |
341 #if defined(ENABLE_REMOTING) | |
342 if (page_url.host() == chrome::kChromeUIRemotingHost) | |
343 return RemotingUI::GetFaviconResourceBytes(); | |
344 #endif | |
345 | |
346 return NULL; | |
347 } | |
OLD | NEW |