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 #include <ApplicationServices/ApplicationServices.h> | |
6 #import <Cocoa/Cocoa.h> | |
7 #import <objc/objc-runtime.h> | |
8 #include <sys/stat.h> | |
9 | |
10 #include "webkit/tools/test_shell/test_shell.h" | |
11 | |
12 #include "base/base_paths.h" | |
13 #include "base/basictypes.h" | |
14 #include "base/debug/debugger.h" | |
15 #include "base/file_util.h" | |
16 #include "base/files/file_path.h" | |
17 #include "base/logging.h" | |
18 #include "base/mac/bundle_locations.h" | |
19 #include "base/mac/mac_util.h" | |
20 #include "base/mac/scoped_nsautorelease_pool.h" | |
21 #include "base/message_loop.h" | |
22 #include "base/path_service.h" | |
23 #include "base/string16.h" | |
24 #include "base/strings/string_piece.h" | |
25 #include "base/utf_string_conversions.h" | |
26 #include "grit/webkit_resources.h" | |
27 #include "net/base/mime_util.h" | |
28 #include "skia/ext/bitmap_platform_device.h" | |
29 #include "testing/gtest/include/gtest/gtest.h" | |
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | |
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | |
32 #include "ui/base/resource/data_pack.h" | |
33 #include "ui/gfx/size.h" | |
34 #include "webkit/glue/webkit_glue.h" | |
35 #include "webkit/glue/webpreferences.h" | |
36 #include "webkit/plugins/npapi/plugin_list.h" | |
37 #include "webkit/tools/test_shell/mac/test_shell_webview.h" | |
38 #include "webkit/tools/test_shell/resource.h" | |
39 #include "webkit/tools/test_shell/simple_resource_loader_bridge.h" | |
40 #include "webkit/tools/test_shell/test_navigation_controller.h" | |
41 #include "webkit/tools/test_shell/test_shell_webkit_init.h" | |
42 #include "webkit/tools/test_shell/test_webview_delegate.h" | |
43 | |
44 #include "third_party/skia/include/core/SkBitmap.h" | |
45 | |
46 #import "mac/DumpRenderTreePasteboard.h" | |
47 | |
48 using WebKit::WebWidget; | |
49 | |
50 #define MAX_LOADSTRING 100 | |
51 | |
52 // Sizes for URL bar layout | |
53 #define BUTTON_HEIGHT 22 | |
54 #define BUTTON_WIDTH 72 | |
55 #define BUTTON_MARGIN 8 | |
56 #define URLBAR_HEIGHT 32 | |
57 | |
58 // Global Variables: | |
59 | |
60 // Content area size for newly created windows. | |
61 const int kTestWindowWidth = 800; | |
62 const int kTestWindowHeight = 600; | |
63 | |
64 // The W3C SVG layout tests use a different size than the other layout tests | |
65 const int kSVGTestWindowWidth = 480; | |
66 const int kSVGTestWindowHeight = 360; | |
67 | |
68 // Hide the window offscreen when in layout test mode. Mac OS X limits | |
69 // window positions to +/- 16000. | |
70 const int kTestWindowXLocation = -14000; | |
71 const int kTestWindowYLocation = -14000; | |
72 | |
73 // Data pack resource. This is a pointer to the mmapped resources file. | |
74 static ui::DataPack* g_resource_data_pack = NULL; | |
75 | |
76 // Define static member variables | |
77 base::LazyInstance <std::map<gfx::NativeWindow, TestShell *> > | |
78 TestShell::window_map_ = LAZY_INSTANCE_INITIALIZER; | |
79 | |
80 // Helper method for getting the path to the test shell resources directory. | |
81 base::FilePath GetResourcesFilePath() { | |
82 base::FilePath path; | |
83 // We need to know if we're bundled or not to know which path to use. | |
84 if (base::mac::AmIBundled()) { | |
85 PathService::Get(base::DIR_EXE, &path); | |
86 path = path.Append(base::FilePath::kParentDirectory); | |
87 return path.AppendASCII("Resources"); | |
88 } else { | |
89 PathService::Get(base::DIR_SOURCE_ROOT, &path); | |
90 path = path.AppendASCII("webkit"); | |
91 path = path.AppendASCII("tools"); | |
92 path = path.AppendASCII("test_shell"); | |
93 return path.AppendASCII("resources"); | |
94 } | |
95 } | |
96 | |
97 // Receives notification that the window is closing so that it can start the | |
98 // tear-down process. Is responsible for deleting itself when done. | |
99 @interface WindowDelegate : NSObject<NSWindowDelegate> { | |
100 @private | |
101 TestShellWebView* m_webView; | |
102 } | |
103 - (id)initWithWebView:(TestShellWebView*)view; | |
104 @end | |
105 | |
106 @implementation WindowDelegate | |
107 | |
108 - (id)initWithWebView:(TestShellWebView*)view { | |
109 if ((self = [super init])) { | |
110 m_webView = view; | |
111 } | |
112 return self; | |
113 } | |
114 | |
115 - (void)windowDidBecomeKey:(NSNotification*)notification { | |
116 [m_webView setIsActive:YES]; | |
117 } | |
118 | |
119 - (void)windowDidResignKey:(NSNotification*)notification { | |
120 [m_webView setIsActive:NO]; | |
121 } | |
122 | |
123 // Called when the window is about to close. Perform the self-destruction | |
124 // sequence by getting rid of the shell and removing it and the window from | |
125 // the various global lists. Instead of doing it here, however, we fire off | |
126 // a delayed call to |-cleanup:| to allow everything to get off the stack | |
127 // before we go deleting objects. By returning YES, we allow the window to be | |
128 // removed from the screen. | |
129 - (BOOL)windowShouldClose:(id)window { | |
130 m_webView = nil; | |
131 | |
132 // Try to make the window go away, but it may not when running layout | |
133 // tests due to the quirkyness of autorelease pools and having no main loop. | |
134 [window autorelease]; | |
135 | |
136 // clean ourselves up and do the work after clearing the stack of anything | |
137 // that might have the shell on it. | |
138 [self performSelectorOnMainThread:@selector(cleanup:) | |
139 withObject:window | |
140 waitUntilDone:NO]; | |
141 | |
142 return YES; | |
143 } | |
144 | |
145 // does the work of removing the window from our various bookkeeping lists | |
146 // and gets rid of the shell. | |
147 - (void)cleanup:(id)window { | |
148 TestShell::RemoveWindowFromList(window); | |
149 TestShell::DestroyAssociatedShell(window); | |
150 | |
151 [self release]; | |
152 } | |
153 | |
154 @end | |
155 | |
156 // Mac-specific stuff to do when the dtor is called. Nothing to do in our | |
157 // case. | |
158 void TestShell::PlatformCleanUp() { | |
159 } | |
160 | |
161 void TestShell::EnableUIControl(UIControl control, bool is_enabled) { | |
162 // TODO(darin): Implement me. | |
163 } | |
164 | |
165 // static | |
166 void TestShell::DestroyAssociatedShell(gfx::NativeWindow handle) { | |
167 WindowMap::iterator it = window_map_.Get().find(handle); | |
168 if (it != window_map_.Get().end()) { | |
169 // Break the view's association with its shell before deleting the shell. | |
170 TestShellWebView* web_view = | |
171 static_cast<TestShellWebView*>(it->second->m_webViewHost->view_handle()); | |
172 if ([web_view isKindOfClass:[TestShellWebView class]]) { | |
173 [web_view setShell:NULL]; | |
174 } | |
175 | |
176 delete it->second; | |
177 window_map_.Get().erase(it); | |
178 } else { | |
179 LOG(ERROR) << "Failed to find shell for window during destroy"; | |
180 } | |
181 } | |
182 | |
183 // static | |
184 void TestShell::PlatformShutdown() { | |
185 // for each window in the window list, release it and destroy its shell | |
186 for (WindowList::iterator it = TestShell::windowList()->begin(); | |
187 it != TestShell::windowList()->end(); | |
188 ++it) { | |
189 DestroyAssociatedShell(*it); | |
190 [*it release]; | |
191 } | |
192 // assert if we have anything left over, that would be bad. | |
193 DCHECK(window_map_.Get().empty()); | |
194 | |
195 // Dump the pasteboards we built up. | |
196 [DumpRenderTreePasteboard releaseLocalPasteboards]; | |
197 } | |
198 | |
199 // static | |
200 void TestShell::InitializeTestShell(bool layout_test_mode, | |
201 bool allow_external_pages) { | |
202 // This should move to a per-process platform-specific initialization function | |
203 // when one exists. | |
204 | |
205 window_list_ = new WindowList; | |
206 layout_test_mode_ = layout_test_mode; | |
207 allow_external_pages_ = allow_external_pages; | |
208 | |
209 web_prefs_ = new WebPreferences; | |
210 | |
211 // mmap the data pack which holds strings used by WebCore. This is only | |
212 // a fatal error if we're bundled, which means we might be running layout | |
213 // tests. This is a harmless failure for test_shell_tests. | |
214 g_resource_data_pack = new ui::DataPack(ui::SCALE_FACTOR_100P); | |
215 NSString *resource_path = | |
216 [base::mac::FrameworkBundle() pathForResource:@"test_shell" | |
217 ofType:@"pak"]; | |
218 base::FilePath resources_pak_path([resource_path fileSystemRepresentation]); | |
219 if (!g_resource_data_pack->LoadFromPath(resources_pak_path)) { | |
220 LOG(FATAL) << "failed to load test_shell.pak"; | |
221 } | |
222 | |
223 ResetWebPreferences(); | |
224 | |
225 // Load the Ahem font, which is used by layout tests. | |
226 NSString* ahem_path = [[base::mac::FrameworkBundle() resourcePath] | |
227 stringByAppendingPathComponent:@"AHEM____.TTF"]; | |
228 NSURL* ahem_path_url = [NSURL fileURLWithPath:ahem_path]; | |
229 CFErrorRef error; | |
230 if (!CTFontManagerRegisterFontsForURL((CFURLRef)ahem_path_url, | |
231 kCTFontManagerScopeProcess, &error)) { | |
232 DLOG(FATAL) << "CTFontManagerRegisterFontsForURL " | |
233 << [ahem_path fileSystemRepresentation] | |
234 << [[(NSError*)error description] UTF8String]; | |
235 } | |
236 | |
237 // Add <app bundle's parent dir>/plugins to the plugin path so we can load | |
238 // test plugins. | |
239 base::FilePath plugins_dir; | |
240 PathService::Get(base::DIR_EXE, &plugins_dir); | |
241 if (base::mac::AmIBundled()) { | |
242 plugins_dir = plugins_dir.AppendASCII("../../../plugins"); | |
243 } else { | |
244 plugins_dir = plugins_dir.AppendASCII("plugins"); | |
245 } | |
246 webkit::npapi::PluginList::Singleton()->AddExtraPluginDir(plugins_dir); | |
247 } | |
248 | |
249 NSButton* MakeTestButton(NSRect* rect, NSString* title, NSView* parent) { | |
250 NSButton* button = [[[NSButton alloc] initWithFrame:*rect] autorelease]; | |
251 [button setTitle:title]; | |
252 [button setBezelStyle:NSSmallSquareBezelStyle]; | |
253 [button setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)]; | |
254 [parent addSubview:button]; | |
255 rect->origin.x += BUTTON_WIDTH; | |
256 return button; | |
257 } | |
258 | |
259 bool TestShell::Initialize(const GURL& starting_url) { | |
260 // Perform application initialization: | |
261 // send message to app controller? need to work this out | |
262 | |
263 // TODO(awalker): this is a straight recreation of windows test_shell.cc's | |
264 // window creation code--we should really pull this from the nib and grab | |
265 // references to the already-created subviews that way. | |
266 NSRect screen_rect = [[NSScreen mainScreen] visibleFrame]; | |
267 NSRect window_rect = { {0, screen_rect.size.height - kTestWindowHeight}, | |
268 {kTestWindowWidth, kTestWindowHeight} }; | |
269 m_mainWnd = [[NSWindow alloc] | |
270 initWithContentRect:window_rect | |
271 styleMask:(NSTitledWindowMask | | |
272 NSClosableWindowMask | | |
273 NSMiniaturizableWindowMask | | |
274 NSResizableWindowMask ) | |
275 backing:NSBackingStoreBuffered | |
276 defer:NO]; | |
277 [m_mainWnd setTitle:@"TestShell"]; | |
278 | |
279 // Add to our map | |
280 window_map_.Get()[m_mainWnd] = this; | |
281 | |
282 // Rely on the window delegate to clean us up rather than immediately | |
283 // releasing when the window gets closed. We use the delegate to do | |
284 // everything from the autorelease pool so the shell isn't on the stack | |
285 // during cleanup (ie, a window close from javascript). | |
286 [m_mainWnd setReleasedWhenClosed:NO]; | |
287 | |
288 // Create a webview. Note that |web_view| takes ownership of this shell so we | |
289 // will get cleaned up when it gets destroyed. | |
290 m_webViewHost.reset( | |
291 WebViewHost::Create([m_mainWnd contentView], | |
292 delegate_.get(), | |
293 0, | |
294 *TestShell::web_prefs_)); | |
295 delegate_->RegisterDragDrop(); | |
296 TestShellWebView* web_view = | |
297 static_cast<TestShellWebView*>(m_webViewHost->view_handle()); | |
298 [web_view setShell:this]; | |
299 | |
300 // Create a window delegate to watch for when it's asked to go away. It will | |
301 // clean itself up so we don't need to hold a reference. | |
302 [m_mainWnd setDelegate:[[WindowDelegate alloc] initWithWebView:web_view]]; | |
303 | |
304 // create buttons | |
305 NSRect button_rect = [[m_mainWnd contentView] bounds]; | |
306 button_rect.origin.y = window_rect.size.height - URLBAR_HEIGHT + | |
307 (URLBAR_HEIGHT - BUTTON_HEIGHT) / 2; | |
308 button_rect.size.height = BUTTON_HEIGHT; | |
309 button_rect.origin.x += BUTTON_MARGIN; | |
310 button_rect.size.width = BUTTON_WIDTH; | |
311 | |
312 NSView* content = [m_mainWnd contentView]; | |
313 | |
314 NSButton* button = MakeTestButton(&button_rect, @"Back", content); | |
315 [button setTarget:web_view]; | |
316 [button setAction:@selector(goBack:)]; | |
317 | |
318 button = MakeTestButton(&button_rect, @"Forward", content); | |
319 [button setTarget:web_view]; | |
320 [button setAction:@selector(goForward:)]; | |
321 | |
322 // reload button | |
323 button = MakeTestButton(&button_rect, @"Reload", content); | |
324 [button setTarget:web_view]; | |
325 [button setAction:@selector(reload:)]; | |
326 | |
327 // stop button | |
328 button = MakeTestButton(&button_rect, @"Stop", content); | |
329 [button setTarget:web_view]; | |
330 [button setAction:@selector(stopLoading:)]; | |
331 | |
332 // text field for URL | |
333 button_rect.origin.x += BUTTON_MARGIN; | |
334 button_rect.size.width = [[m_mainWnd contentView] bounds].size.width - | |
335 button_rect.origin.x - BUTTON_MARGIN; | |
336 m_editWnd = [[NSTextField alloc] initWithFrame:button_rect]; | |
337 [[m_mainWnd contentView] addSubview:m_editWnd]; | |
338 [m_editWnd setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)]; | |
339 [m_editWnd setTarget:web_view]; | |
340 [m_editWnd setAction:@selector(takeURLStringValueFrom:)]; | |
341 [[m_editWnd cell] setWraps:NO]; | |
342 [[m_editWnd cell] setScrollable:YES]; | |
343 | |
344 // show the window | |
345 [m_mainWnd makeKeyAndOrderFront: nil]; | |
346 | |
347 // Load our initial content. | |
348 if (starting_url.is_valid()) | |
349 LoadURL(starting_url); | |
350 | |
351 if (IsSVGTestURL(starting_url)) { | |
352 SizeTo(kSVGTestWindowWidth, kSVGTestWindowHeight); | |
353 } else { | |
354 SizeToDefault(); | |
355 } | |
356 | |
357 return true; | |
358 } | |
359 | |
360 void TestShell::InteractiveSetFocus(WebWidgetHost* host, bool enable) { | |
361 if (enable) { | |
362 [[host->view_handle() window] makeKeyAndOrderFront:nil]; | |
363 } else { | |
364 // There is no way to resign key window status in Cocoa. Fake it by | |
365 // ordering the window out (transferring key status to another window) and | |
366 // then ordering the window back in, but without making it key. | |
367 [[host->view_handle() window] orderOut:nil]; | |
368 [[host->view_handle() window] orderFront:nil]; | |
369 } | |
370 } | |
371 | |
372 // static | |
373 void TestShell::DestroyWindow(gfx::NativeWindow windowHandle) { | |
374 // This code is like -cleanup: on our window delegate. This call needs to be | |
375 // able to force down a window for tests, so it closes down the window making | |
376 // sure it cleans up the window delegate and the test shells list of windows | |
377 // and map of windows to shells. | |
378 | |
379 TestShell::RemoveWindowFromList(windowHandle); | |
380 TestShell::DestroyAssociatedShell(windowHandle); | |
381 | |
382 id windowDelegate = [windowHandle delegate]; | |
383 DCHECK(windowDelegate); | |
384 [windowHandle setDelegate:nil]; | |
385 [windowDelegate release]; | |
386 | |
387 [windowHandle close]; | |
388 [windowHandle autorelease]; | |
389 } | |
390 | |
391 WebWidget* TestShell::CreatePopupWidget() { | |
392 DCHECK(!m_popupHost); | |
393 m_popupHost = WebWidgetHost::Create(webViewWnd(), popup_delegate_.get()); | |
394 | |
395 return m_popupHost->webwidget(); | |
396 } | |
397 | |
398 void TestShell::ClosePopup() { | |
399 // PostMessage(popupWnd(), WM_CLOSE, 0, 0); | |
400 m_popupHost = NULL; | |
401 } | |
402 | |
403 void TestShell::SizeTo(int width, int height) { | |
404 // WebViewHost::Create() sets the HTML content rect to start 32 pixels below | |
405 // the top of the window to account for the "toolbar". We need to match that | |
406 // here otherwise the HTML content area will be too short. | |
407 NSRect r = [m_mainWnd contentRectForFrameRect:[m_mainWnd frame]]; | |
408 r.size.width = width; | |
409 r.size.height = height + URLBAR_HEIGHT; | |
410 [m_mainWnd setFrame:[m_mainWnd frameRectForContentRect:r] display:YES]; | |
411 } | |
412 | |
413 void TestShell::ResizeSubViews() { | |
414 // handled by Cocoa for us | |
415 } | |
416 | |
417 /* static */ void TestShell::DumpAllBackForwardLists(base::string16* result) { | |
418 result->clear(); | |
419 for (WindowList::iterator iter = TestShell::windowList()->begin(); | |
420 iter != TestShell::windowList()->end(); iter++) { | |
421 NSWindow* window = *iter; | |
422 WindowMap::iterator it = window_map_.Get().find(window); | |
423 if (it != window_map_.Get().end()) | |
424 it->second->DumpBackForwardList(result); | |
425 else | |
426 LOG(ERROR) << "Failed to find shell for window during dump"; | |
427 } | |
428 } | |
429 | |
430 void TestShell::LoadURLForFrame(const GURL& url, | |
431 const base::string16& frame_name) { | |
432 if (!url.is_valid()) | |
433 return; | |
434 | |
435 if (IsSVGTestURL(url)) { | |
436 SizeTo(kSVGTestWindowWidth, kSVGTestWindowHeight); | |
437 } else { | |
438 // only resize back to the default when running tests | |
439 if (layout_test_mode()) | |
440 SizeToDefault(); | |
441 } | |
442 | |
443 navigation_controller_->LoadEntry( | |
444 new TestNavigationEntry(-1, url, frame_name)); | |
445 } | |
446 | |
447 bool TestShell::PromptForSaveFile(const wchar_t* prompt_title, | |
448 base::FilePath* result) | |
449 { | |
450 NSSavePanel* save_panel = [NSSavePanel savePanel]; | |
451 | |
452 /* set up new attributes */ | |
453 [save_panel setAllowedFileTypes:@[@"txt"]]; | |
454 [save_panel setMessage: | |
455 [NSString stringWithUTF8String:WideToUTF8(prompt_title).c_str()]]; | |
456 | |
457 /* display the NSSavePanel */ | |
458 [save_panel setDirectoryURL:[NSURL fileURLWithPath:NSHomeDirectory()]]; | |
459 [save_panel setNameFieldStringValue:@""]; | |
460 if ([save_panel runModal] == NSFileHandlingPanelOKButton) { | |
461 *result = base::FilePath([[[save_panel URL] path] fileSystemRepresentation])
; | |
462 return true; | |
463 } | |
464 return false; | |
465 } | |
466 | |
467 // static | |
468 std::string TestShell::RewriteLocalUrl(const std::string& url) { | |
469 // Convert file:///tmp/LayoutTests urls to the actual location on disk. | |
470 const char kPrefix[] = "file:///tmp/LayoutTests/"; | |
471 const int kPrefixLen = arraysize(kPrefix) - 1; | |
472 | |
473 std::string new_url(url); | |
474 if (url.compare(0, kPrefixLen, kPrefix, kPrefixLen) == 0) { | |
475 base::FilePath replace_path; | |
476 PathService::Get(base::DIR_SOURCE_ROOT, &replace_path); | |
477 replace_path = replace_path.Append( | |
478 "third_party/WebKit/LayoutTests/"); | |
479 new_url = std::string("file://") + replace_path.value() + | |
480 url.substr(kPrefixLen); | |
481 } | |
482 | |
483 return new_url; | |
484 } | |
485 | |
486 // static | |
487 void TestShell::ShowStartupDebuggingDialog() { | |
488 NSAlert* alert = [[[NSAlert alloc] init] autorelease]; | |
489 alert.messageText = @"Attach to me?"; | |
490 alert.informativeText = @"This would probably be a good time to attach your " | |
491 "debugger."; | |
492 [alert addButtonWithTitle:@"OK"]; | |
493 | |
494 [alert runModal]; | |
495 } | |
496 | |
497 base::StringPiece TestShell::ResourceProvider(int key) { | |
498 base::StringPiece res; | |
499 g_resource_data_pack->GetStringPiece(key, &res); | |
500 return res; | |
501 } | |
502 | |
503 //----------------------------------------------------------------------------- | |
504 | |
505 base::string16 TestShellWebKitInit::GetLocalizedString(int message_id) { | |
506 base::StringPiece res; | |
507 if (!g_resource_data_pack->GetStringPiece(message_id, &res)) { | |
508 LOG(FATAL) << "failed to load webkit string with id " << message_id; | |
509 } | |
510 | |
511 // Data packs hold strings as either UTF8 or UTF16. | |
512 base::string16 msg; | |
513 switch (g_resource_data_pack->GetTextEncodingType()) { | |
514 case ui::DataPack::UTF8: | |
515 msg = UTF8ToUTF16(res); | |
516 break; | |
517 case ui::DataPack::UTF16: | |
518 msg = base::string16(reinterpret_cast<const char16*>(res.data()), | |
519 res.length() / 2); | |
520 break; | |
521 case ui::DataPack::BINARY: | |
522 NOTREACHED(); | |
523 break; | |
524 } | |
525 | |
526 return msg; | |
527 } | |
528 | |
529 base::StringPiece TestShellWebKitInit::GetDataResource( | |
530 int resource_id, | |
531 ui::ScaleFactor scale_factor) { | |
532 switch (resource_id) { | |
533 case IDR_BROKENIMAGE: { | |
534 // Use webkit's broken image icon (16x16) | |
535 static std::string broken_image_data; | |
536 if (broken_image_data.empty()) { | |
537 base::FilePath path = GetResourcesFilePath(); | |
538 // In order to match WebKit's colors for the missing image, we have to | |
539 // use a PNG. The GIF doesn't have the color range needed to correctly | |
540 // match the TIFF they use in Safari. | |
541 path = path.AppendASCII("missingImage.png"); | |
542 bool success = file_util::ReadFileToString(path, &broken_image_data); | |
543 if (!success) { | |
544 LOG(FATAL) << "Failed reading: " << path.value(); | |
545 } | |
546 } | |
547 return broken_image_data; | |
548 } | |
549 case IDR_TEXTAREA_RESIZER: { | |
550 // Use webkit's text area resizer image. | |
551 static std::string resize_corner_data; | |
552 if (resize_corner_data.empty()) { | |
553 base::FilePath path = GetResourcesFilePath(); | |
554 path = path.AppendASCII("textAreaResizeCorner.png"); | |
555 bool success = file_util::ReadFileToString(path, &resize_corner_data); | |
556 if (!success) { | |
557 LOG(FATAL) << "Failed reading: " << path.value(); | |
558 } | |
559 } | |
560 return resize_corner_data; | |
561 } | |
562 | |
563 case IDR_SEARCH_CANCEL: | |
564 case IDR_SEARCH_CANCEL_PRESSED: | |
565 case IDR_SEARCH_MAGNIFIER: | |
566 case IDR_SEARCH_MAGNIFIER_RESULTS: | |
567 case IDR_INPUT_SPEECH: | |
568 case IDR_INPUT_SPEECH_RECORDING: | |
569 case IDR_INPUT_SPEECH_WAITING: | |
570 // TODO(flackr): Pass scale_factor to ResourceProvider. | |
571 return TestShell::ResourceProvider(resource_id); | |
572 | |
573 default: | |
574 break; | |
575 } | |
576 | |
577 return base::StringPiece(); | |
578 } | |
579 | |
580 namespace webkit_glue { | |
581 | |
582 bool DownloadUrl(const std::string& url, NSWindow* caller_window) { | |
583 return false; | |
584 } | |
585 | |
586 void DidLoadPlugin(const std::string& filename) { | |
587 } | |
588 | |
589 void DidUnloadPlugin(const std::string& filename) { | |
590 } | |
591 | |
592 } // namespace webkit_glue | |
OLD | NEW |