OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "webkit/tools/test_shell/test_shell.h" | 5 #include "webkit/tools/test_shell/test_shell.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <fontconfig/fontconfig.h> | 9 #include <fontconfig/fontconfig.h> |
10 #include <gtk/gtk.h> | 10 #include <gtk/gtk.h> |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 TestShell::windowList()->push_back(shell->m_mainWnd); | 146 TestShell::windowList()->push_back(shell->m_mainWnd); |
147 return true; | 147 return true; |
148 } | 148 } |
149 | 149 |
150 void TestShell::PlatformCleanUp() { | 150 void TestShell::PlatformCleanUp() { |
151 // The GTK widgets will be destroyed, which will free the associated | 151 // The GTK widgets will be destroyed, which will free the associated |
152 // objects. So we don't need the scoped_ptr to free the webViewHost. | 152 // objects. So we don't need the scoped_ptr to free the webViewHost. |
153 m_webViewHost.release(); | 153 m_webViewHost.release(); |
154 } | 154 } |
155 | 155 |
| 156 namespace { |
| 157 |
156 // GTK callbacks ------------------------------------------------------ | 158 // GTK callbacks ------------------------------------------------------ |
157 namespace { | |
158 | 159 |
159 // Callback for when the main window is destroyed. | 160 // Callback for when the main window is destroyed. |
160 gboolean MainWindowDestroyed(GtkWindow* window, TestShell* shell) { | 161 gboolean MainWindowDestroyed(GtkWindow* window, TestShell* shell) { |
161 | 162 |
162 TestShell::RemoveWindowFromList(GTK_WIDGET(window)); | 163 TestShell::RemoveWindowFromList(GTK_WIDGET(window)); |
163 | 164 |
164 if (TestShell::windowList()->empty() || shell->is_modal()) { | 165 if (TestShell::windowList()->empty() || shell->is_modal()) { |
165 MessageLoop::current()->PostTask(FROM_HERE, | 166 MessageLoop::current()->PostTask(FROM_HERE, |
166 new MessageLoop::QuitTask()); | 167 new MessageLoop::QuitTask()); |
167 } | 168 } |
(...skipping 28 matching lines...) Expand all Loading... |
196 void ReloadButtonClicked(GtkButton* button, TestShell* shell) { | 197 void ReloadButtonClicked(GtkButton* button, TestShell* shell) { |
197 shell->Reload(); | 198 shell->Reload(); |
198 } | 199 } |
199 | 200 |
200 // Callback for when you press enter in the URL box. | 201 // Callback for when you press enter in the URL box. |
201 void URLEntryActivate(GtkEntry* entry, TestShell* shell) { | 202 void URLEntryActivate(GtkEntry* entry, TestShell* shell) { |
202 const gchar* url = gtk_entry_get_text(entry); | 203 const gchar* url = gtk_entry_get_text(entry); |
203 shell->LoadURL(UTF8ToWide(url).c_str()); | 204 shell->LoadURL(UTF8ToWide(url).c_str()); |
204 } | 205 } |
205 | 206 |
| 207 // Callback for Debug > Dump body text... menu item. |
| 208 gboolean DumpBodyTextActivated(GtkWidget* widget, TestShell* shell) { |
| 209 shell->DumpDocumentText(); |
| 210 return FALSE; // Don't stop this message. |
| 211 } |
| 212 |
| 213 // Callback for Debug > Dump render tree... menu item. |
| 214 gboolean DumpRenderTreeActivated(GtkWidget* widget, TestShell* shell) { |
| 215 shell->DumpRenderTree(); |
| 216 return FALSE; // Don't stop this message. |
| 217 } |
| 218 |
| 219 // Callback for Debug > Show web inspector... menu item. |
| 220 gboolean ShowWebInspectorActivated(GtkWidget* widget, TestShell* shell) { |
| 221 shell->webView()->InspectElement(0, 0); |
| 222 return FALSE; // Don't stop this message. |
| 223 } |
| 224 |
| 225 // GTK utility functions ---------------------------------------------- |
| 226 |
| 227 GtkWidget* AddMenuEntry(GtkWidget* menu_widget, const char* text, |
| 228 GCallback callback, TestShell* shell) { |
| 229 GtkWidget* entry = gtk_menu_item_new_with_label(text); |
| 230 g_signal_connect(G_OBJECT(entry), "activate", callback, shell); |
| 231 gtk_menu_shell_append(GTK_MENU_SHELL(menu_widget), entry); |
| 232 return entry; |
| 233 } |
| 234 |
| 235 GtkWidget* CreateMenu(GtkWidget* menu_bar, const char* text) { |
| 236 GtkWidget* menu_widget = gtk_menu_new(); |
| 237 GtkWidget* menu_header = gtk_menu_item_new_with_label(text); |
| 238 gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_header), menu_widget); |
| 239 gtk_menu_shell_append(GTK_MENU_SHELL(menu_bar), menu_header); |
| 240 return menu_widget; |
| 241 } |
| 242 |
| 243 GtkWidget* CreateMenuBar(TestShell* shell) { |
| 244 GtkWidget* menu_bar = gtk_menu_bar_new(); |
| 245 GtkWidget* debug_menu = CreateMenu(menu_bar, "Debug"); |
| 246 AddMenuEntry(debug_menu, "Dump body text...", |
| 247 G_CALLBACK(DumpBodyTextActivated), shell); |
| 248 AddMenuEntry(debug_menu, "Dump render tree...", |
| 249 G_CALLBACK(DumpRenderTreeActivated), shell); |
| 250 AddMenuEntry(debug_menu, "Show web inspector...", |
| 251 G_CALLBACK(ShowWebInspectorActivated), shell); |
| 252 return menu_bar; |
| 253 } |
| 254 |
206 } | 255 } |
207 | 256 |
208 bool TestShell::Initialize(const std::wstring& startingURL) { | 257 bool TestShell::Initialize(const std::wstring& startingURL) { |
209 m_mainWnd = gtk_window_new(GTK_WINDOW_TOPLEVEL); | 258 m_mainWnd = gtk_window_new(GTK_WINDOW_TOPLEVEL); |
210 gtk_window_set_title(GTK_WINDOW(m_mainWnd), "Test Shell"); | 259 gtk_window_set_title(GTK_WINDOW(m_mainWnd), "Test Shell"); |
211 gtk_window_set_default_size(GTK_WINDOW(m_mainWnd), 640, 480); | 260 gtk_window_set_default_size(GTK_WINDOW(m_mainWnd), 640, 480); |
212 g_signal_connect(G_OBJECT(m_mainWnd), "destroy", | 261 g_signal_connect(G_OBJECT(m_mainWnd), "destroy", |
213 G_CALLBACK(MainWindowDestroyed), this); | 262 G_CALLBACK(MainWindowDestroyed), this); |
214 g_signal_connect(G_OBJECT(m_mainWnd), "focus-out-event", | 263 g_signal_connect(G_OBJECT(m_mainWnd), "focus-out-event", |
215 G_CALLBACK(MainWindowLostFocus), this); | 264 G_CALLBACK(MainWindowLostFocus), this); |
216 g_object_set_data(G_OBJECT(m_mainWnd), "test-shell", this); | 265 g_object_set_data(G_OBJECT(m_mainWnd), "test-shell", this); |
217 | 266 |
218 GtkWidget* vbox = gtk_vbox_new(FALSE, 0); | 267 GtkWidget* vbox = gtk_vbox_new(FALSE, 0); |
219 | 268 |
| 269 gtk_box_pack_start(GTK_BOX(vbox), CreateMenuBar(this), FALSE, FALSE, 0); |
| 270 |
220 GtkWidget* toolbar = gtk_toolbar_new(); | 271 GtkWidget* toolbar = gtk_toolbar_new(); |
221 // Turn off the labels on the toolbar buttons. | 272 // Turn off the labels on the toolbar buttons. |
222 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS); | 273 gtk_toolbar_set_style(GTK_TOOLBAR(toolbar), GTK_TOOLBAR_ICONS); |
223 | 274 |
224 GtkToolItem* back = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK); | 275 GtkToolItem* back = gtk_tool_button_new_from_stock(GTK_STOCK_GO_BACK); |
225 g_signal_connect(G_OBJECT(back), "clicked", | 276 g_signal_connect(G_OBJECT(back), "clicked", |
226 G_CALLBACK(BackButtonClicked), this); | 277 G_CALLBACK(BackButtonClicked), this); |
227 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), back, -1 /* append */); | 278 gtk_toolbar_insert(GTK_TOOLBAR(toolbar), back, -1 /* append */); |
228 | 279 |
229 GtkToolItem* forward = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD); | 280 GtkToolItem* forward = gtk_tool_button_new_from_stock(GTK_STOCK_GO_FORWARD); |
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
511 // as well as empty strings. | 562 // as well as empty strings. |
512 if (file_util::AbsolutePath(&path)) | 563 if (file_util::AbsolutePath(&path)) |
513 gurl = net::FilePathToFileURL(path); | 564 gurl = net::FilePathToFileURL(path); |
514 else | 565 else |
515 gurl = GURL(WideToUTF8(url)); | 566 gurl = GURL(WideToUTF8(url)); |
516 | 567 |
517 navigation_controller_->LoadEntry(new TestNavigationEntry( | 568 navigation_controller_->LoadEntry(new TestNavigationEntry( |
518 -1, gurl, std::wstring(), frame_string)); | 569 -1, gurl, std::wstring(), frame_string)); |
519 } | 570 } |
520 | 571 |
521 static void WriteTextToFile(const std::wstring& data, | 572 // TODO(agl): PromptForSaveFile should use FilePath |
522 const FilePath& filepath) | 573 bool TestShell::PromptForSaveFile(const wchar_t* prompt_title, |
523 { | 574 std::wstring* result) { |
524 // This function does the same thing as the Windows version except that it | 575 GtkWidget* dialog; |
525 // takes a FilePath. We should be using WriteFile in base/file_util.h, but | 576 dialog = gtk_file_chooser_dialog_new(WideToUTF8(prompt_title).c_str(), |
526 // the patch to add the FilePath version of that file hasn't landed yet, so | 577 GTK_WINDOW(m_mainWnd), |
527 // this is another TODO(agl) for the merging. | 578 GTK_FILE_CHOOSER_ACTION_SAVE, |
528 const int fd = open(filepath.value().c_str(), O_TRUNC | O_WRONLY | O_CREAT, 06
00); | 579 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, |
529 if (fd < 0) | 580 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, |
530 return; | 581 NULL); // Terminate (button, id) pairs. |
531 const std::string data_utf8 = WideToUTF8(data); | 582 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), |
532 ssize_t n; | 583 TRUE); |
533 do { | 584 int dialog_result = gtk_dialog_run(GTK_DIALOG(dialog)); |
534 n = write(fd, data_utf8.data(), data.size()); | 585 if (dialog_result != GTK_RESPONSE_ACCEPT) { |
535 } while (n == -1 && errno == EINTR); | 586 gtk_widget_destroy(dialog); |
536 close(fd); | 587 return false; |
537 } | 588 } |
538 | 589 char* path = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); |
539 | 590 gtk_widget_destroy(dialog); |
540 // TODO(agl): | 591 *result = UTF8ToWide(path); |
541 // This version of PromptForSaveFile uses FilePath, which is what the real | 592 g_free(path); |
542 // version should be using. However, I don't want to step on tony's toes (as he | |
543 // is also editing this file), so this is a hack until we merge the files again. | |
544 // (There is also a PromptForSaveFile member in TestShell which returns a wstrin
g) | |
545 static bool PromptForSaveFile(const char* prompt_title, | |
546 FilePath* result) | |
547 { | |
548 char filenamebuffer[512]; | |
549 printf("Enter filename for \"%s\"\n", prompt_title); | |
550 if (!fgets(filenamebuffer, sizeof(filenamebuffer), stdin)) | |
551 return false; // EOF on stdin | |
552 *result = FilePath(filenamebuffer); | |
553 return true; | 593 return true; |
554 } | 594 } |
555 | 595 |
556 void TestShell::DumpDocumentText() | |
557 { | |
558 FilePath file_path; | |
559 if (!::PromptForSaveFile("Dump document text", &file_path)) | |
560 return; | |
561 | |
562 WriteTextToFile(webkit_glue::DumpDocumentText(webView()->GetMainFrame()), | |
563 file_path); | |
564 } | |
565 | |
566 void TestShell::DumpRenderTree() | |
567 { | |
568 FilePath file_path; | |
569 if (!::PromptForSaveFile("Dump render tree", &file_path)) | |
570 return; | |
571 | |
572 WriteTextToFile(webkit_glue::DumpRenderer(webView()->GetMainFrame()), | |
573 file_path); | |
574 } | |
575 | |
576 // static | 596 // static |
577 std::string TestShell::RewriteLocalUrl(const std::string& url) { | 597 std::string TestShell::RewriteLocalUrl(const std::string& url) { |
578 // Convert file:///tmp/LayoutTests urls to the actual location on disk. | 598 // Convert file:///tmp/LayoutTests urls to the actual location on disk. |
579 const char kPrefix[] = "file:///tmp/LayoutTests/"; | 599 const char kPrefix[] = "file:///tmp/LayoutTests/"; |
580 const int kPrefixLen = arraysize(kPrefix) - 1; | 600 const int kPrefixLen = arraysize(kPrefix) - 1; |
581 | 601 |
582 std::string new_url(url); | 602 std::string new_url(url); |
583 if (url.compare(0, kPrefixLen, kPrefix, kPrefixLen) == 0) { | 603 if (url.compare(0, kPrefixLen, kPrefix, kPrefixLen) == 0) { |
584 FilePath replace_path; | 604 FilePath replace_path; |
585 PathService::Get(base::DIR_EXE, &replace_path); | 605 PathService::Get(base::DIR_EXE, &replace_path); |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 } | 761 } |
742 | 762 |
743 bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { | 763 bool GetPlugins(bool refresh, std::vector<WebPluginInfo>* plugins) { |
744 // TODO(port): Implement plugins someday. Don't let the error message | 764 // TODO(port): Implement plugins someday. Don't let the error message |
745 // of NOTIMPLEMENTED into our layout test diffs. | 765 // of NOTIMPLEMENTED into our layout test diffs. |
746 // NOTIMPLEMENTED(); | 766 // NOTIMPLEMENTED(); |
747 return false; | 767 return false; |
748 } | 768 } |
749 | 769 |
750 } // namespace webkit_glue | 770 } // namespace webkit_glue |
OLD | NEW |