OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 // This file contains the implementation of TestWebViewDelegate, which serves | |
6 // as the WebViewDelegate for the TestShellWebHost. The host is expected to | |
7 // have initialized a MessageLoop before these methods are called. | |
8 | |
9 #include "webkit/tools/test_shell/test_webview_delegate.h" | |
10 | |
11 #include "base/debug/trace_event.h" | |
12 #include "base/file_util.h" | |
13 #include "base/message_loop.h" | |
14 #include "base/process_util.h" | |
15 #include "base/string_util.h" | |
16 #include "base/stringprintf.h" | |
17 #include "base/strings/string_number_conversions.h" | |
18 #include "base/utf_string_conversions.h" | |
19 #include "media/base/filter_collection.h" | |
20 #include "media/base/media_log.h" | |
21 #include "net/base/net_errors.h" | |
22 #include "third_party/WebKit/Source/Platform/chromium/public/Platform.h" | |
23 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h" | |
24 #include "third_party/WebKit/Source/Platform/chromium/public/WebData.h" | |
25 #include "third_party/WebKit/Source/Platform/chromium/public/WebDragData.h" | |
26 #include "third_party/WebKit/Source/Platform/chromium/public/WebImage.h" | |
27 #include "third_party/WebKit/Source/Platform/chromium/public/WebPoint.h" | |
28 #include "third_party/WebKit/Source/Platform/chromium/public/WebStorageNamespace
.h" | |
29 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" | |
30 #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" | |
31 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h" | |
32 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLRequest.h" | |
33 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLResponse.h" | |
34 #include "third_party/WebKit/Source/Platform/chromium/public/WebVector.h" | |
35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObjec
t.h" | |
36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebConsoleMessage.h" | |
37 #include "third_party/WebKit/Source/WebKit/chromium/public/WebContextMenuData.h" | |
38 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" | |
39 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDeviceOrientationC
lientMock.h" | |
40 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" | |
41 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileError.h" | |
42 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystemCallback
s.h" | |
43 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | |
44 #include "third_party/WebKit/Source/WebKit/chromium/public/WebGeolocationClientM
ock.h" | |
45 #include "third_party/WebKit/Source/WebKit/chromium/public/WebHistoryItem.h" | |
46 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" | |
47 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" | |
48 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPresen
ter.h" | |
49 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPluginParams.h" | |
50 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" | |
51 #include "third_party/WebKit/Source/WebKit/chromium/public/WebRange.h" | |
52 #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" | |
53 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | |
54 #include "third_party/WebKit/Source/WebKit/chromium/public/WebWindowFeatures.h" | |
55 #include "ui/base/window_open_disposition.h" | |
56 #include "ui/gfx/native_widget_types.h" | |
57 #include "ui/gfx/point.h" | |
58 #include "webkit/appcache/web_application_cache_host_impl.h" | |
59 #include "webkit/glue/glue_serialize.h" | |
60 #include "webkit/glue/webdropdata.h" | |
61 #include "webkit/glue/webkit_glue.h" | |
62 #include "webkit/glue/webpreferences.h" | |
63 #include "webkit/glue/weburlrequest_extradata_impl.h" | |
64 #include "webkit/media/webmediaplayer_impl.h" | |
65 #include "webkit/media/webmediaplayer_params.h" | |
66 #include "webkit/plugins/npapi/plugin_list.h" | |
67 #include "webkit/plugins/npapi/webplugin_delegate_impl.h" | |
68 #include "webkit/plugins/npapi/webplugin_impl.h" | |
69 #include "webkit/tools/test_shell/mock_spellcheck.h" | |
70 #include "webkit/tools/test_shell/notification_presenter.h" | |
71 #include "webkit/tools/test_shell/simple_appcache_system.h" | |
72 #include "webkit/tools/test_shell/simple_dom_storage_system.h" | |
73 #include "webkit/tools/test_shell/simple_file_system.h" | |
74 #include "webkit/tools/test_shell/test_navigation_controller.h" | |
75 #include "webkit/tools/test_shell/test_shell.h" | |
76 | |
77 #if defined(OS_WIN) | |
78 // TODO(port): make these files work everywhere. | |
79 #include "webkit/tools/test_shell/drop_delegate.h" | |
80 #endif | |
81 | |
82 #if defined(OS_MACOSX) | |
83 #include "webkit/plugins/plugin_constants.h" | |
84 #endif | |
85 | |
86 using appcache::WebApplicationCacheHostImpl; | |
87 using WebKit::WebAccessibilityObject; | |
88 using WebKit::WebApplicationCacheHost; | |
89 using WebKit::WebApplicationCacheHostClient; | |
90 using WebKit::WebConsoleMessage; | |
91 using WebKit::WebContextMenuData; | |
92 using WebKit::WebCookieJar; | |
93 using WebKit::WebData; | |
94 using WebKit::WebDataSource; | |
95 using WebKit::WebDragData; | |
96 using WebKit::WebDragOperationsMask; | |
97 using WebKit::WebEditingAction; | |
98 using WebKit::WebFileSystem; | |
99 using WebKit::WebFileSystemCallbacks; | |
100 using WebKit::WebFormElement; | |
101 using WebKit::WebFrame; | |
102 using WebKit::WebGraphicsContext3D; | |
103 using WebKit::WebHistoryItem; | |
104 using WebKit::WebImage; | |
105 using WebKit::WebMediaPlayer; | |
106 using WebKit::WebMediaPlayerClient; | |
107 using WebKit::WebNavigationType; | |
108 using WebKit::WebNavigationPolicy; | |
109 using WebKit::WebNode; | |
110 using WebKit::WebNotificationPresenter; | |
111 using WebKit::WebPlugin; | |
112 using WebKit::WebPluginParams; | |
113 using WebKit::WebPoint; | |
114 using WebKit::WebPopupMenu; | |
115 using WebKit::WebPopupType; | |
116 using WebKit::WebRange; | |
117 using WebKit::WebRect; | |
118 using WebKit::WebScreenInfo; | |
119 using WebKit::WebSecurityOrigin; | |
120 using WebKit::WebSize; | |
121 using WebKit::WebStorageNamespace; | |
122 using WebKit::WebString; | |
123 using WebKit::WebTextAffinity; | |
124 using WebKit::WebTextDirection; | |
125 using WebKit::WebURL; | |
126 using WebKit::WebURLError; | |
127 using WebKit::WebURLRequest; | |
128 using WebKit::WebURLResponse; | |
129 using WebKit::WebWidget; | |
130 using WebKit::WebWindowFeatures; | |
131 using WebKit::WebWorker; | |
132 using WebKit::WebVector; | |
133 using WebKit::WebView; | |
134 | |
135 namespace { | |
136 | |
137 // WebNavigationType debugging strings taken from PolicyDelegate.mm. | |
138 const char* kLinkClickedString = "link clicked"; | |
139 const char* kFormSubmittedString = "form submitted"; | |
140 const char* kBackForwardString = "back/forward"; | |
141 const char* kReloadString = "reload"; | |
142 const char* kFormResubmittedString = "form resubmitted"; | |
143 const char* kOtherString = "other"; | |
144 const char* kIllegalString = "illegal value"; | |
145 | |
146 int next_page_id_ = 1; | |
147 | |
148 // Used to write a platform neutral file:/// URL by taking the | |
149 // filename and its directory. (e.g., converts | |
150 // "file:///tmp/foo/bar.txt" to just "bar.txt"). | |
151 // Get a debugging string from a WebNavigationType. | |
152 const char* WebNavigationTypeToString(WebNavigationType type) { | |
153 switch (type) { | |
154 case WebKit::WebNavigationTypeLinkClicked: | |
155 return kLinkClickedString; | |
156 case WebKit::WebNavigationTypeFormSubmitted: | |
157 return kFormSubmittedString; | |
158 case WebKit::WebNavigationTypeBackForward: | |
159 return kBackForwardString; | |
160 case WebKit::WebNavigationTypeReload: | |
161 return kReloadString; | |
162 case WebKit::WebNavigationTypeFormResubmitted: | |
163 return kFormResubmittedString; | |
164 case WebKit::WebNavigationTypeOther: | |
165 return kOtherString; | |
166 } | |
167 return kIllegalString; | |
168 } | |
169 | |
170 std::string GetURLDescription(const GURL& url) { | |
171 if (url.SchemeIs("file")) | |
172 return url.ExtractFileName(); | |
173 | |
174 return url.possibly_invalid_spec(); | |
175 } | |
176 | |
177 std::string GetNodeDescription(const WebNode& node, int exception) { | |
178 if (exception) | |
179 return "ERROR"; | |
180 if (node.isNull()) | |
181 return "(null)"; | |
182 std::string str = node.nodeName().utf8(); | |
183 const WebNode& parent = node.parentNode(); | |
184 if (!parent.isNull()) { | |
185 str.append(" > "); | |
186 str.append(GetNodeDescription(parent, 0)); | |
187 } | |
188 return str; | |
189 } | |
190 | |
191 } // namespace | |
192 | |
193 // WebViewDelegate ----------------------------------------------------------- | |
194 | |
195 std::string TestWebViewDelegate::GetResourceDescription(uint32 identifier) { | |
196 ResourceMap::iterator it = resource_identifier_map_.find(identifier); | |
197 return it != resource_identifier_map_.end() ? it->second : "<unknown>"; | |
198 } | |
199 | |
200 void TestWebViewDelegate::SetUserStyleSheetEnabled(bool is_enabled) { | |
201 WebPreferences* prefs = shell_->GetWebPreferences(); | |
202 prefs->user_style_sheet_enabled = is_enabled; | |
203 webkit_glue::ApplyWebPreferences(*prefs, shell_->webView()); | |
204 } | |
205 | |
206 void TestWebViewDelegate::SetUserStyleSheetLocation(const GURL& location) { | |
207 WebPreferences* prefs = shell_->GetWebPreferences(); | |
208 prefs->user_style_sheet_enabled = true; | |
209 prefs->user_style_sheet_location = location; | |
210 webkit_glue::ApplyWebPreferences(*prefs, shell_->webView()); | |
211 } | |
212 | |
213 void TestWebViewDelegate::SetAuthorAndUserStylesEnabled(bool is_enabled) { | |
214 WebPreferences* prefs = shell_->GetWebPreferences(); | |
215 prefs->author_and_user_styles_enabled = is_enabled; | |
216 webkit_glue::ApplyWebPreferences(*prefs, shell_->webView()); | |
217 } | |
218 | |
219 // WebViewClient ------------------------------------------------------------- | |
220 WebView* TestWebViewDelegate::createView( | |
221 WebFrame* creator, | |
222 const WebURLRequest& request, | |
223 const WebWindowFeatures& window_features, | |
224 const WebString& frame_name, | |
225 WebNavigationPolicy policy) { | |
226 return shell_->CreateWebView(); | |
227 } | |
228 | |
229 WebWidget* TestWebViewDelegate::createPopupMenu(WebPopupType popup_type) { | |
230 // TODO(darin): Should we take into account |popup_type| (for activation | |
231 // purpose)? | |
232 return shell_->CreatePopupWidget(); | |
233 } | |
234 | |
235 WebStorageNamespace* TestWebViewDelegate::createSessionStorageNamespace( | |
236 unsigned quota) { | |
237 return SimpleDomStorageSystem::instance().CreateSessionStorageNamespace(); | |
238 } | |
239 | |
240 void TestWebViewDelegate::didAddMessageToConsole( | |
241 const WebConsoleMessage& message, const WebString& source_name, | |
242 unsigned source_line) { | |
243 logging::LogMessage("CONSOLE", 0).stream() << "\"" | |
244 << message.text.utf8().data() | |
245 << ",\" source: " | |
246 << source_name.utf8().data() | |
247 << "(" | |
248 << source_line | |
249 << ")"; | |
250 } | |
251 | |
252 void TestWebViewDelegate::didStartLoading() { | |
253 shell_->set_is_loading(true); | |
254 shell_->UpdateNavigationControls(); | |
255 } | |
256 | |
257 void TestWebViewDelegate::didStopLoading() { | |
258 shell_->set_is_loading(false); | |
259 shell_->UpdateNavigationControls(); | |
260 } | |
261 | |
262 // The output from these methods in layout test mode should match that | |
263 // expected by the layout tests. See EditingDelegate.m in DumpRenderTree. | |
264 | |
265 bool TestWebViewDelegate::shouldBeginEditing(const WebRange& range) { | |
266 return shell_->AcceptsEditing(); | |
267 } | |
268 | |
269 bool TestWebViewDelegate::shouldEndEditing(const WebRange& range) { | |
270 return shell_->AcceptsEditing(); | |
271 } | |
272 | |
273 bool TestWebViewDelegate::shouldInsertNode(const WebNode& node, | |
274 const WebRange& range, | |
275 WebEditingAction action) { | |
276 return shell_->AcceptsEditing(); | |
277 } | |
278 | |
279 bool TestWebViewDelegate::shouldInsertText(const WebString& text, | |
280 const WebRange& range, | |
281 WebEditingAction action) { | |
282 return shell_->AcceptsEditing(); | |
283 } | |
284 | |
285 bool TestWebViewDelegate::shouldChangeSelectedRange(const WebRange& from_range, | |
286 const WebRange& to_range, | |
287 WebTextAffinity affinity, | |
288 bool still_selecting) { | |
289 return shell_->AcceptsEditing(); | |
290 } | |
291 | |
292 bool TestWebViewDelegate::shouldDeleteRange(const WebRange& range) { | |
293 return shell_->AcceptsEditing(); | |
294 } | |
295 | |
296 bool TestWebViewDelegate::shouldApplyStyle(const WebString& style, | |
297 const WebRange& range) { | |
298 return shell_->AcceptsEditing(); | |
299 } | |
300 | |
301 void TestWebViewDelegate::didBeginEditing() { | |
302 } | |
303 | |
304 void TestWebViewDelegate::didChangeSelection(bool is_empty_selection) { | |
305 UpdateSelectionClipboard(is_empty_selection); | |
306 } | |
307 | |
308 void TestWebViewDelegate::didChangeContents() { | |
309 } | |
310 | |
311 void TestWebViewDelegate::didEndEditing() { | |
312 } | |
313 | |
314 bool TestWebViewDelegate::handleCurrentKeyboardEvent() { | |
315 if (edit_command_name_.empty()) | |
316 return false; | |
317 | |
318 WebFrame* frame = shell_->webView()->focusedFrame(); | |
319 if (!frame) | |
320 return false; | |
321 | |
322 return frame->executeCommand(WebString::fromUTF8(edit_command_name_), | |
323 WebString::fromUTF8(edit_command_value_)); | |
324 } | |
325 | |
326 void TestWebViewDelegate::spellCheck(const WebString& text, | |
327 int& misspelledOffset, | |
328 int& misspelledLength) { | |
329 #if defined(OS_MACOSX) | |
330 // Check the spelling of the given text. | |
331 // TODO(hbono): rebaseline layout-test results of Windows and Linux so we | |
332 // can enable this mock spellchecker on them. | |
333 base::string16 word(text); | |
334 mock_spellcheck_.SpellCheckWord(word, &misspelledOffset, &misspelledLength); | |
335 #endif | |
336 } | |
337 | |
338 WebString TestWebViewDelegate::autoCorrectWord(const WebString& word) { | |
339 // Returns an empty string as Mac WebKit ('WebKitSupport/WebEditorClient.mm') | |
340 // does. (If this function returns a non-empty string, WebKit replaces the | |
341 // given misspelled string with the result one. This process executes some | |
342 // editor commands and causes layout-test failures.) | |
343 return WebString(); | |
344 } | |
345 | |
346 void TestWebViewDelegate::runModalAlertDialog( | |
347 WebFrame* frame, const WebString& message) { | |
348 if (!shell_->layout_test_mode()) { | |
349 ShowJavaScriptAlert(message); | |
350 } else { | |
351 printf("ALERT: %s\n", message.utf8().data()); | |
352 } | |
353 } | |
354 | |
355 bool TestWebViewDelegate::runModalConfirmDialog( | |
356 WebFrame* frame, const WebString& message) { | |
357 if (shell_->layout_test_mode()) { | |
358 // When running tests, write to stdout. | |
359 printf("CONFIRM: %s\n", message.utf8().data()); | |
360 return true; | |
361 } | |
362 return false; | |
363 } | |
364 | |
365 bool TestWebViewDelegate::runModalPromptDialog( | |
366 WebFrame* frame, const WebString& message, const WebString& default_value, | |
367 WebString* actual_value) { | |
368 if (shell_->layout_test_mode()) { | |
369 // When running tests, write to stdout. | |
370 printf("PROMPT: %s, default text: %s\n", | |
371 message.utf8().data(), | |
372 default_value.utf8().data()); | |
373 return true; | |
374 } | |
375 return false; | |
376 } | |
377 | |
378 bool TestWebViewDelegate::runModalBeforeUnloadDialog( | |
379 WebFrame* frame, const WebString& message) { | |
380 return true; // Allow window closure. | |
381 } | |
382 | |
383 | |
384 | |
385 | |
386 void TestWebViewDelegate::setStatusText(const WebString& text) { | |
387 } | |
388 | |
389 void TestWebViewDelegate::startDragging( | |
390 WebFrame* frame, | |
391 const WebDragData& data, | |
392 WebDragOperationsMask mask, | |
393 const WebImage& image, | |
394 const WebPoint& image_offset) { | |
395 shell_->webView()->dragSourceSystemDragEnded(); | |
396 } | |
397 | |
398 void TestWebViewDelegate::navigateBackForwardSoon(int offset) { | |
399 shell_->navigation_controller()->GoToOffset(offset); | |
400 } | |
401 | |
402 int TestWebViewDelegate::historyBackListCount() { | |
403 int current_index = | |
404 shell_->navigation_controller()->GetLastCommittedEntryIndex(); | |
405 return current_index; | |
406 } | |
407 | |
408 int TestWebViewDelegate::historyForwardListCount() { | |
409 int current_index = | |
410 shell_->navigation_controller()->GetLastCommittedEntryIndex(); | |
411 return shell_->navigation_controller()->GetEntryCount() - current_index - 1; | |
412 } | |
413 | |
414 WebNotificationPresenter* TestWebViewDelegate::notificationPresenter() { | |
415 return shell_->notification_presenter(); | |
416 } | |
417 | |
418 WebKit::WebGeolocationClient* TestWebViewDelegate::geolocationClient() { | |
419 return shell_->geolocation_client_mock(); | |
420 } | |
421 | |
422 WebKit::WebDeviceOrientationClient* | |
423 TestWebViewDelegate::deviceOrientationClient() { | |
424 return shell_->device_orientation_client_mock(); | |
425 } | |
426 | |
427 WebKit::WebSpeechInputController* TestWebViewDelegate::speechInputController( | |
428 WebKit::WebSpeechInputListener* listener) { | |
429 return 0; | |
430 } | |
431 | |
432 // WebWidgetClient ----------------------------------------------------------- | |
433 | |
434 void TestWebViewDelegate::didInvalidateRect(const WebRect& rect) { | |
435 if (WebWidgetHost* host = GetWidgetHost()) | |
436 host->DidInvalidateRect(rect); | |
437 } | |
438 | |
439 void TestWebViewDelegate::didScrollRect(int dx, int dy, | |
440 const WebRect& clip_rect) { | |
441 if (WebWidgetHost* host = GetWidgetHost()) | |
442 host->DidScrollRect(dx, dy, clip_rect); | |
443 } | |
444 | |
445 void TestWebViewDelegate::scheduleComposite() { | |
446 if (WebWidgetHost* host = GetWidgetHost()) | |
447 host->ScheduleComposite(); | |
448 } | |
449 | |
450 void TestWebViewDelegate::scheduleAnimation() { | |
451 if (WebWidgetHost* host = GetWidgetHost()) | |
452 host->ScheduleAnimation(); | |
453 } | |
454 | |
455 void TestWebViewDelegate::didFocus() { | |
456 if (WebWidgetHost* host = GetWidgetHost()) | |
457 shell_->SetFocus(host, true); | |
458 } | |
459 | |
460 void TestWebViewDelegate::didBlur() { | |
461 if (WebWidgetHost* host = GetWidgetHost()) | |
462 shell_->SetFocus(host, false); | |
463 } | |
464 | |
465 WebScreenInfo TestWebViewDelegate::screenInfo() { | |
466 if (WebWidgetHost* host = GetWidgetHost()) | |
467 return host->GetScreenInfo(); | |
468 | |
469 return WebScreenInfo(); | |
470 } | |
471 | |
472 // WebFrameClient ------------------------------------------------------------ | |
473 | |
474 WebPlugin* TestWebViewDelegate::createPlugin(WebFrame* frame, | |
475 const WebPluginParams& params) { | |
476 bool allow_wildcard = true; | |
477 std::vector<webkit::WebPluginInfo> plugins; | |
478 std::vector<std::string> mime_types; | |
479 webkit::npapi::PluginList::Singleton()->GetPluginInfoArray( | |
480 params.url, params.mimeType.utf8(), allow_wildcard, | |
481 NULL, &plugins, &mime_types); | |
482 if (plugins.empty()) | |
483 return NULL; | |
484 | |
485 WebPluginParams params_copy = params; | |
486 params_copy.mimeType = WebString::fromUTF8(mime_types.front()); | |
487 | |
488 #if defined(OS_MACOSX) | |
489 if (!shell_->layout_test_mode()) { | |
490 bool flash = LowerCaseEqualsASCII(params_copy.mimeType.utf8(), | |
491 kFlashPluginSwfMimeType); | |
492 if (flash) { | |
493 // Mac does not support windowed plugins. Force Flash plugins to use | |
494 // windowless mode by setting the wmode="opaque" attribute. | |
495 DCHECK(params_copy.attributeNames.size() == | |
496 params_copy.attributeValues.size()); | |
497 size_t size = params_copy.attributeNames.size(); | |
498 | |
499 WebVector<WebString> new_names(size+1), new_values(size+1); | |
500 | |
501 for (size_t i = 0; i < size; ++i) { | |
502 new_names[i] = params_copy.attributeNames[i]; | |
503 new_values[i] = params_copy.attributeValues[i]; | |
504 } | |
505 | |
506 new_names[size] = "wmode"; | |
507 new_values[size] = "opaque"; | |
508 | |
509 params_copy.attributeNames.swap(new_names); | |
510 params_copy.attributeValues.swap(new_values); | |
511 | |
512 return new webkit::npapi::WebPluginImpl( | |
513 frame, params_copy, plugins.front().path, AsWeakPtr()); | |
514 } | |
515 } | |
516 #endif // defined (OS_MACOSX) | |
517 | |
518 return new webkit::npapi::WebPluginImpl( | |
519 frame, params, plugins.front().path, AsWeakPtr()); | |
520 } | |
521 | |
522 WebMediaPlayer* TestWebViewDelegate::createMediaPlayer( | |
523 WebFrame* frame, const WebKit::WebURL& url, WebMediaPlayerClient* client) { | |
524 webkit_media::WebMediaPlayerParams params( | |
525 NULL, NULL, new media::MediaLog()); | |
526 return new webkit_media::WebMediaPlayerImpl( | |
527 frame, | |
528 client, | |
529 base::WeakPtr<webkit_media::WebMediaPlayerDelegate>(), | |
530 params); | |
531 } | |
532 | |
533 WebApplicationCacheHost* TestWebViewDelegate::createApplicationCacheHost( | |
534 WebFrame* frame, WebApplicationCacheHostClient* client) { | |
535 return SimpleAppCacheSystem::CreateApplicationCacheHost(client); | |
536 } | |
537 | |
538 bool TestWebViewDelegate::allowPlugins(WebFrame* frame, | |
539 bool enabled_per_settings) { | |
540 return enabled_per_settings && shell_->allow_plugins(); | |
541 } | |
542 | |
543 bool TestWebViewDelegate::allowImage(WebFrame* frame, | |
544 bool enabled_per_settings, | |
545 const WebURL& image_url) { | |
546 return enabled_per_settings && shell_->allow_images(); | |
547 } | |
548 | |
549 void TestWebViewDelegate::loadURLExternally( | |
550 WebFrame* frame, const WebURLRequest& request, | |
551 WebNavigationPolicy policy) { | |
552 DCHECK_NE(policy, WebKit::WebNavigationPolicyCurrentTab); | |
553 TestShell* shell = NULL; | |
554 if (TestShell::CreateNewWindow(request.url(), &shell)) | |
555 shell->Show(policy); | |
556 } | |
557 | |
558 WebNavigationPolicy TestWebViewDelegate::decidePolicyForNavigation( | |
559 WebFrame* frame, WebDataSource::ExtraData* extraData, | |
560 const WebURLRequest& request, WebNavigationType type, | |
561 WebNavigationPolicy default_policy, bool is_redirect) { | |
562 WebNavigationPolicy result; | |
563 if (policy_delegate_enabled_) { | |
564 printf("Policy delegate: attempt to load %s with navigation type '%s'\n", | |
565 GetURLDescription(request.url()).c_str(), | |
566 WebNavigationTypeToString(type)); | |
567 if (policy_delegate_is_permissive_) { | |
568 result = WebKit::WebNavigationPolicyCurrentTab; | |
569 } else { | |
570 result = WebKit::WebNavigationPolicyIgnore; | |
571 } | |
572 } else { | |
573 result = default_policy; | |
574 } | |
575 return result; | |
576 } | |
577 | |
578 WebNavigationPolicy TestWebViewDelegate::decidePolicyForNavigation( | |
579 WebFrame* frame, const WebURLRequest& request, | |
580 WebNavigationType type, WebNavigationPolicy default_policy, | |
581 bool is_redirect) { | |
582 return decidePolicyForNavigation(frame, 0, request, type, | |
583 default_policy, is_redirect); | |
584 } | |
585 | |
586 bool TestWebViewDelegate::canHandleRequest( | |
587 WebFrame* frame, const WebURLRequest& request) { | |
588 GURL url = request.url(); | |
589 // Just reject the scheme used in | |
590 // LayoutTests/http/tests/misc/redirect-to-external-url.html | |
591 return !url.SchemeIs("spaceballs"); | |
592 } | |
593 | |
594 WebURLError TestWebViewDelegate::cannotHandleRequestError( | |
595 WebFrame* frame, const WebURLRequest& request) { | |
596 WebURLError error; | |
597 // A WebKit layout test expects the following values. | |
598 // unableToImplementPolicyWithError() below prints them. | |
599 error.domain = WebString::fromUTF8("WebKitErrorDomain"); | |
600 error.reason = 101; | |
601 error.unreachableURL = request.url(); | |
602 return error; | |
603 } | |
604 | |
605 WebURLError TestWebViewDelegate::cancelledError( | |
606 WebFrame* frame, const WebURLRequest& request) { | |
607 WebURLError error; | |
608 error.domain = WebString::fromUTF8(net::kErrorDomain); | |
609 error.reason = net::ERR_ABORTED; | |
610 error.unreachableURL = request.url(); | |
611 return error; | |
612 } | |
613 | |
614 void TestWebViewDelegate::unableToImplementPolicyWithError( | |
615 WebFrame* frame, const WebURLError& error) { | |
616 std::string domain = error.domain.utf8(); | |
617 printf("Policy delegate: unable to implement policy with error domain '%s', " | |
618 "error code %d, in frame '%s'\n", | |
619 domain.data(), error.reason, frame->uniqueName().utf8().data()); | |
620 } | |
621 | |
622 void TestWebViewDelegate::willPerformClientRedirect( | |
623 WebFrame* frame, const WebURL& from, const WebURL& to, | |
624 double interval, double fire_time) { | |
625 } | |
626 | |
627 void TestWebViewDelegate::didCancelClientRedirect(WebFrame* frame) { | |
628 } | |
629 | |
630 void TestWebViewDelegate::didCreateDataSource( | |
631 WebFrame* frame, WebDataSource* ds) { | |
632 ds->setExtraData(pending_extra_data_.release()); | |
633 } | |
634 | |
635 void TestWebViewDelegate::didStartProvisionalLoad(WebFrame* frame) { | |
636 UpdateAddressBar(frame->view()); | |
637 } | |
638 | |
639 void TestWebViewDelegate::didReceiveServerRedirectForProvisionalLoad( | |
640 WebFrame* frame) { | |
641 UpdateAddressBar(frame->view()); | |
642 } | |
643 | |
644 void TestWebViewDelegate::didFailProvisionalLoad( | |
645 WebFrame* frame, const WebURLError& error) { | |
646 // Don't display an error page if we're running layout tests, because | |
647 // DumpRenderTree doesn't. | |
648 if (shell_->layout_test_mode()) | |
649 return; | |
650 | |
651 // Don't display an error page if this is simply a cancelled load. Aside | |
652 // from being dumb, WebCore doesn't expect it and it will cause a crash. | |
653 if (error.reason == net::ERR_ABORTED) | |
654 return; | |
655 | |
656 const WebDataSource* failed_ds = frame->provisionalDataSource(); | |
657 | |
658 TestShellExtraData* extra_data = | |
659 static_cast<TestShellExtraData*>(failed_ds->extraData()); | |
660 bool replace = extra_data && extra_data->pending_page_id != -1; | |
661 | |
662 // Ensure the error page ends up with the same page ID if we are replacing. | |
663 if (replace) | |
664 set_pending_extra_data(new TestShellExtraData(extra_data->pending_page_id)); | |
665 | |
666 const std::string& error_text = | |
667 base::StringPrintf("Error %d when loading url %s", error.reason, | |
668 failed_ds->request().url().spec().data()); | |
669 | |
670 // Make sure we never show errors in view source mode. | |
671 frame->enableViewSourceMode(false); | |
672 | |
673 frame->loadHTMLString( | |
674 error_text, GURL("testshell-error:"), error.unreachableURL, replace); | |
675 | |
676 // In case the load failed before DidCreateDataSource was called. | |
677 if (replace) | |
678 set_pending_extra_data(NULL); | |
679 } | |
680 | |
681 void TestWebViewDelegate::didCommitProvisionalLoad( | |
682 WebFrame* frame, bool is_new_navigation) { | |
683 UpdateForCommittedLoad(frame, is_new_navigation); | |
684 } | |
685 | |
686 void TestWebViewDelegate::didReceiveTitle( | |
687 WebFrame* frame, const WebString& title, WebTextDirection direction) { | |
688 SetPageTitle(title); | |
689 } | |
690 | |
691 void TestWebViewDelegate::didFinishDocumentLoad(WebFrame* frame) { | |
692 unsigned pending_unload_events = frame->unloadListenerCount(); | |
693 if (pending_unload_events) { | |
694 printf("%s - has %u onunload handler(s)\n", | |
695 UTF16ToUTF8(GetFrameDescription(frame)).c_str(), pending_unload_events); | |
696 } | |
697 } | |
698 | |
699 void TestWebViewDelegate::didHandleOnloadEvents(WebFrame* frame) { | |
700 } | |
701 | |
702 void TestWebViewDelegate::didFinishLoad(WebFrame* frame) { | |
703 TRACE_EVENT_END_ETW("frame.load", this, frame->document().url().spec()); | |
704 UpdateAddressBar(frame->view()); | |
705 } | |
706 | |
707 void TestWebViewDelegate::didNavigateWithinPage( | |
708 WebFrame* frame, bool is_new_navigation) { | |
709 frame->dataSource()->setExtraData(pending_extra_data_.release()); | |
710 | |
711 UpdateForCommittedLoad(frame, is_new_navigation); | |
712 } | |
713 | |
714 void TestWebViewDelegate::didChangeLocationWithinPage(WebFrame* frame) { | |
715 } | |
716 | |
717 void TestWebViewDelegate::assignIdentifierToRequest( | |
718 WebFrame* frame, unsigned identifier, const WebURLRequest& request) { | |
719 } | |
720 | |
721 void TestWebViewDelegate::willSendRequest( | |
722 WebFrame* frame, unsigned identifier, WebURLRequest& request, | |
723 const WebURLResponse& redirect_response) { | |
724 GURL url = request.url(); | |
725 std::string request_url = url.possibly_invalid_spec(); | |
726 | |
727 request.setExtraData( | |
728 new webkit_glue::WebURLRequestExtraDataImpl( | |
729 frame->document().referrerPolicy(), WebString())); | |
730 | |
731 if (!redirect_response.isNull() && block_redirects_) { | |
732 printf("Returning null for this redirect\n"); | |
733 | |
734 // To block the request, we set its URL to an empty one. | |
735 request.setURL(WebURL()); | |
736 return; | |
737 } | |
738 | |
739 if (request_return_null_) { | |
740 // To block the request, we set its URL to an empty one. | |
741 request.setURL(WebURL()); | |
742 return; | |
743 } | |
744 | |
745 std::string host = url.host(); | |
746 if (TestShell::layout_test_mode() && !host.empty() && | |
747 (url.SchemeIs("http") || url.SchemeIs("https")) && | |
748 host != "127.0.0.1" && | |
749 host != "255.255.255.255" && // Used in some tests that expect to get | |
750 // back an error. | |
751 host != "localhost" && | |
752 !TestShell::allow_external_pages()) { | |
753 printf("Blocked access to external URL %s\n", request_url.c_str()); | |
754 | |
755 // To block the request, we set its URL to an empty one. | |
756 request.setURL(WebURL()); | |
757 return; | |
758 } | |
759 | |
760 for (std::set<std::string>::const_iterator header = clear_headers_.begin(); | |
761 header != clear_headers_.end(); ++header) | |
762 request.clearHTTPHeaderField(WebString::fromUTF8(*header)); | |
763 | |
764 TRACE_EVENT_BEGIN_ETW("url.load", identifier, request_url); | |
765 // Set the new substituted URL. | |
766 request.setURL(GURL(TestShell::RewriteLocalUrl(request_url))); | |
767 } | |
768 | |
769 void TestWebViewDelegate::didReceiveResponse( | |
770 WebFrame* frame, unsigned identifier, const WebURLResponse& response) { | |
771 } | |
772 | |
773 void TestWebViewDelegate::didFinishResourceLoad( | |
774 WebFrame* frame, unsigned identifier) { | |
775 TRACE_EVENT_END_ETW("url.load", identifier, ""); | |
776 resource_identifier_map_.erase(identifier); | |
777 } | |
778 | |
779 void TestWebViewDelegate::didFailResourceLoad( | |
780 WebFrame* frame, unsigned identifier, const WebURLError& error) { | |
781 resource_identifier_map_.erase(identifier); | |
782 } | |
783 | |
784 void TestWebViewDelegate::didDisplayInsecureContent(WebFrame* frame) { | |
785 } | |
786 | |
787 void TestWebViewDelegate::didRunInsecureContent( | |
788 WebFrame* frame, const WebSecurityOrigin& origin, const WebURL& target) { | |
789 } | |
790 | |
791 bool TestWebViewDelegate::allowScript(WebFrame* frame, | |
792 bool enabled_per_settings) { | |
793 return enabled_per_settings && shell_->allow_scripts(); | |
794 } | |
795 | |
796 void TestWebViewDelegate::openFileSystem( | |
797 WebFrame* frame, | |
798 WebKit::WebFileSystemType type, | |
799 long long size, bool create, | |
800 WebFileSystemCallbacks* callbacks) { | |
801 SimpleFileSystem* fileSystem = static_cast<SimpleFileSystem*>( | |
802 WebKit::Platform::current()->fileSystem()); | |
803 fileSystem->OpenFileSystem(frame, type, size, create, callbacks); | |
804 } | |
805 | |
806 // WebPluginPageDelegate ----------------------------------------------------- | |
807 | |
808 WebKit::WebPlugin* TestWebViewDelegate::CreatePluginReplacement( | |
809 const base::FilePath& file_path) { | |
810 return NULL; | |
811 } | |
812 | |
813 WebCookieJar* TestWebViewDelegate::GetCookieJar() { | |
814 return WebKit::Platform::current()->cookieJar(); | |
815 } | |
816 | |
817 // Public methods ------------------------------------------------------------ | |
818 | |
819 TestWebViewDelegate::TestWebViewDelegate(TestShell* shell) | |
820 : policy_delegate_enabled_(false), | |
821 policy_delegate_is_permissive_(false), | |
822 policy_delegate_should_notify_done_(false), | |
823 shell_(shell), | |
824 page_id_(-1), | |
825 last_page_id_updated_(-1), | |
826 using_fake_rect_(false), | |
827 #if defined(TOOLKIT_GTK) | |
828 cursor_type_(GDK_X_CURSOR), | |
829 #endif | |
830 block_redirects_(false), | |
831 request_return_null_(false) { | |
832 } | |
833 | |
834 TestWebViewDelegate::~TestWebViewDelegate() { | |
835 } | |
836 | |
837 void TestWebViewDelegate::Reset() { | |
838 // Do a little placement new dance... | |
839 TestShell* shell = shell_; | |
840 this->~TestWebViewDelegate(); | |
841 new (this) TestWebViewDelegate(shell); | |
842 } | |
843 | |
844 void TestWebViewDelegate::RegisterDragDrop() { | |
845 #if defined(OS_WIN) | |
846 // TODO(port): add me once drag and drop works. | |
847 DCHECK(!drop_delegate_); | |
848 drop_delegate_ = new TestDropDelegate(shell_->webViewWnd(), | |
849 shell_->webView()); | |
850 #endif | |
851 } | |
852 | |
853 void TestWebViewDelegate::RevokeDragDrop() { | |
854 #if defined(OS_WIN) | |
855 ::RevokeDragDrop(shell_->webViewWnd()); | |
856 #endif | |
857 } | |
858 | |
859 void TestWebViewDelegate::SetCustomPolicyDelegate(bool is_custom, | |
860 bool is_permissive) { | |
861 policy_delegate_enabled_ = is_custom; | |
862 policy_delegate_is_permissive_ = is_permissive; | |
863 } | |
864 | |
865 void TestWebViewDelegate::WaitForPolicyDelegate() { | |
866 policy_delegate_enabled_ = true; | |
867 policy_delegate_should_notify_done_ = true; | |
868 } | |
869 | |
870 // Private methods ----------------------------------------------------------- | |
871 | |
872 void TestWebViewDelegate::UpdateAddressBar(WebView* webView) { | |
873 WebFrame* main_frame = webView->mainFrame(); | |
874 | |
875 WebDataSource* data_source = main_frame->dataSource(); | |
876 if (!data_source) | |
877 data_source = main_frame->provisionalDataSource(); | |
878 if (!data_source) | |
879 return; | |
880 | |
881 SetAddressBarURL(data_source->request().url()); | |
882 } | |
883 | |
884 WebWidgetHost* TestWebViewDelegate::GetWidgetHost() { | |
885 if (this == shell_->delegate()) | |
886 return shell_->webViewHost(); | |
887 if (this == shell_->popup_delegate()) | |
888 return shell_->popupHost(); | |
889 return NULL; | |
890 } | |
891 | |
892 void TestWebViewDelegate::UpdateForCommittedLoad(WebFrame* frame, | |
893 bool is_new_navigation) { | |
894 // Code duplicated from RenderView::DidCommitLoadForFrame. | |
895 TestShellExtraData* extra_data = static_cast<TestShellExtraData*>( | |
896 frame->dataSource()->extraData()); | |
897 | |
898 if (is_new_navigation) { | |
899 // New navigation. | |
900 UpdateSessionHistory(frame); | |
901 page_id_ = next_page_id_++; | |
902 } else if (extra_data && extra_data->pending_page_id != -1 && | |
903 !extra_data->request_committed) { | |
904 // This is a successful session history navigation! | |
905 UpdateSessionHistory(frame); | |
906 page_id_ = extra_data->pending_page_id; | |
907 } | |
908 | |
909 // Don't update session history multiple times. | |
910 if (extra_data) | |
911 extra_data->request_committed = true; | |
912 | |
913 UpdateURL(frame); | |
914 } | |
915 | |
916 void TestWebViewDelegate::UpdateURL(WebFrame* frame) { | |
917 WebDataSource* ds = frame->dataSource(); | |
918 DCHECK(ds); | |
919 | |
920 const WebURLRequest& request = ds->request(); | |
921 | |
922 // Type is unused. | |
923 scoped_ptr<TestNavigationEntry> entry(new TestNavigationEntry); | |
924 | |
925 // Bug 654101: the referrer will be empty on https->http transitions. It | |
926 // would be nice if we could get the real referrer from somewhere. | |
927 entry->SetPageID(page_id_); | |
928 if (ds->hasUnreachableURL()) { | |
929 entry->SetURL(ds->unreachableURL()); | |
930 } else { | |
931 entry->SetURL(request.url()); | |
932 } | |
933 | |
934 const WebHistoryItem& history_item = frame->currentHistoryItem(); | |
935 if (!history_item.isNull()) | |
936 entry->SetContentState(webkit_glue::HistoryItemToString(history_item)); | |
937 | |
938 shell_->navigation_controller()->DidNavigateToEntry(entry.release()); | |
939 shell_->UpdateNavigationControls(); | |
940 UpdateAddressBar(frame->view()); | |
941 | |
942 last_page_id_updated_ = std::max(last_page_id_updated_, page_id_); | |
943 } | |
944 | |
945 void TestWebViewDelegate::UpdateSessionHistory(WebFrame* frame) { | |
946 // If we have a valid page ID at this point, then it corresponds to the page | |
947 // we are navigating away from. Otherwise, this is the first navigation, so | |
948 // there is no past session history to record. | |
949 if (page_id_ == -1) | |
950 return; | |
951 | |
952 TestNavigationEntry* entry = static_cast<TestNavigationEntry*>( | |
953 shell_->navigation_controller()->GetEntryWithPageID(page_id_)); | |
954 if (!entry) | |
955 return; | |
956 | |
957 const WebHistoryItem& history_item = | |
958 shell_->webView()->mainFrame()->previousHistoryItem(); | |
959 if (history_item.isNull()) | |
960 return; | |
961 | |
962 entry->SetContentState(webkit_glue::HistoryItemToString(history_item)); | |
963 } | |
964 | |
965 base::string16 TestWebViewDelegate::GetFrameDescription(WebFrame* webframe) { | |
966 std::string name = UTF16ToUTF8(webframe->uniqueName()); | |
967 | |
968 if (webframe == shell_->webView()->mainFrame()) { | |
969 if (name.length()) | |
970 name = "main frame \"" + name + "\""; | |
971 else | |
972 name = "main frame"; | |
973 } else { | |
974 if (name.length()) | |
975 name = "frame \"" + name + "\""; | |
976 else | |
977 name = "frame (anonymous)"; | |
978 } | |
979 return UTF8ToUTF16(name); | |
980 } | |
981 | |
982 void TestWebViewDelegate::set_fake_window_rect(const WebRect& rect) { | |
983 fake_rect_ = rect; | |
984 using_fake_rect_ = true; | |
985 } | |
986 | |
987 WebRect TestWebViewDelegate::fake_window_rect() { | |
988 return fake_rect_; | |
989 } | |
OLD | NEW |