| 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 was forked off the Mac port. | |
| 6 | |
| 7 #include "webkit/tools/test_shell/test_webview_delegate.h" | |
| 8 | |
| 9 #include <gdk/gdkx.h> | |
| 10 #include <gtk/gtk.h> | |
| 11 | |
| 12 #include "base/bind.h" | |
| 13 #include "base/message_loop.h" | |
| 14 #include "base/utf_string_conversions.h" | |
| 15 #include "net/base/net_errors.h" | |
| 16 #include "third_party/WebKit/Source/Platform/chromium/public/WebCString.h" | |
| 17 #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h" | |
| 18 #include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" | |
| 19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" | |
| 20 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | |
| 21 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" | |
| 22 #include "ui/base/window_open_disposition.h" | |
| 23 #include "ui/gfx/gtk_util.h" | |
| 24 #include "ui/gfx/point.h" | |
| 25 #include "webkit/glue/webcursor.h" | |
| 26 #include "webkit/glue/webdropdata.h" | |
| 27 #include "webkit/glue/webpreferences.h" | |
| 28 #include "webkit/plugins/npapi/gtk_plugin_container_manager.h" | |
| 29 #include "webkit/plugins/npapi/plugin_list.h" | |
| 30 #include "webkit/plugins/npapi/webplugin.h" | |
| 31 #include "webkit/plugins/npapi/webplugin_delegate_impl.h" | |
| 32 #include "webkit/tools/test_shell/test_navigation_controller.h" | |
| 33 #include "webkit/tools/test_shell/test_shell.h" | |
| 34 | |
| 35 using WebKit::WebCursorInfo; | |
| 36 using WebKit::WebFrame; | |
| 37 using WebKit::WebNavigationPolicy; | |
| 38 using WebKit::WebPopupMenuInfo; | |
| 39 using WebKit::WebRect; | |
| 40 using WebKit::WebWidget; | |
| 41 using WebKit::WebView; | |
| 42 | |
| 43 namespace { | |
| 44 | |
| 45 enum SelectionClipboardType { | |
| 46 TEXT_HTML, | |
| 47 PLAIN_TEXT, | |
| 48 }; | |
| 49 | |
| 50 GdkAtom GetTextHtmlAtom() { | |
| 51 GdkAtom kTextHtmlGdkAtom = gdk_atom_intern_static_string("text/html"); | |
| 52 return kTextHtmlGdkAtom; | |
| 53 } | |
| 54 | |
| 55 void SelectionClipboardGetContents(GtkClipboard* clipboard, | |
| 56 GtkSelectionData* selection_data, guint info, gpointer data) { | |
| 57 // Ignore formats that we don't know about. | |
| 58 if (info != TEXT_HTML && info != PLAIN_TEXT) | |
| 59 return; | |
| 60 | |
| 61 WebView* webview = static_cast<WebView*>(data); | |
| 62 WebFrame* frame = webview->focusedFrame(); | |
| 63 if (!frame) | |
| 64 frame = webview->mainFrame(); | |
| 65 DCHECK(frame); | |
| 66 | |
| 67 std::string selection; | |
| 68 if (TEXT_HTML == info) { | |
| 69 selection = frame->selectionAsMarkup().utf8(); | |
| 70 } else { | |
| 71 selection = frame->selectionAsText().utf8(); | |
| 72 } | |
| 73 if (TEXT_HTML == info) { | |
| 74 gtk_selection_data_set(selection_data, | |
| 75 GetTextHtmlAtom(), | |
| 76 8 /* bits per data unit, ie, char */, | |
| 77 reinterpret_cast<const guchar*>(selection.data()), | |
| 78 selection.length()); | |
| 79 } else { | |
| 80 gtk_selection_data_set_text(selection_data, selection.data(), | |
| 81 selection.length()); | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 } // namespace | |
| 86 | |
| 87 // WebViewClient -------------------------------------------------------------- | |
| 88 | |
| 89 WebWidget* TestWebViewDelegate::createPopupMenu( | |
| 90 const WebPopupMenuInfo& info) { | |
| 91 NOTREACHED(); | |
| 92 return NULL; | |
| 93 } | |
| 94 | |
| 95 // WebWidgetClient ------------------------------------------------------------ | |
| 96 | |
| 97 void TestWebViewDelegate::show(WebNavigationPolicy policy) { | |
| 98 WebWidgetHost* host = GetWidgetHost(); | |
| 99 GtkWidget* drawing_area = host->view_handle(); | |
| 100 GtkWidget* window = | |
| 101 gtk_widget_get_parent(gtk_widget_get_parent(drawing_area)); | |
| 102 gtk_widget_show_all(window); | |
| 103 } | |
| 104 | |
| 105 void TestWebViewDelegate::closeWidgetSoon() { | |
| 106 if (this == shell_->delegate()) { | |
| 107 MessageLoop::current()->PostTask( | |
| 108 FROM_HERE, | |
| 109 base::Bind(>k_widget_destroy, GTK_WIDGET(shell_->mainWnd()))); | |
| 110 } else if (this == shell_->popup_delegate()) { | |
| 111 shell_->ClosePopup(); | |
| 112 } | |
| 113 } | |
| 114 | |
| 115 void TestWebViewDelegate::didChangeCursor(const WebCursorInfo& cursor_info) { | |
| 116 current_cursor_.InitFromCursorInfo(cursor_info); | |
| 117 GdkCursorType cursor_type = | |
| 118 static_cast<GdkCursorType>(current_cursor_.GetCursorType()); | |
| 119 GdkCursor* gdk_cursor; | |
| 120 if (cursor_type == GDK_CURSOR_IS_PIXMAP) { | |
| 121 // TODO(port): WebKit bug https://bugs.webkit.org/show_bug.cgi?id=16388 is | |
| 122 // that calling gdk_window_set_cursor repeatedly is expensive. We should | |
| 123 // avoid it here where possible. | |
| 124 gdk_cursor = current_cursor_.GetCustomCursor(); | |
| 125 } else { | |
| 126 // Optimize the common case, where the cursor hasn't changed. | |
| 127 // However, we can switch between different pixmaps, so only on the | |
| 128 // non-pixmap branch. | |
| 129 if (cursor_type_ == cursor_type) | |
| 130 return; | |
| 131 if (cursor_type == GDK_LAST_CURSOR) | |
| 132 gdk_cursor = NULL; | |
| 133 else | |
| 134 gdk_cursor = gfx::GetCursor(cursor_type); | |
| 135 } | |
| 136 cursor_type_ = cursor_type; | |
| 137 gdk_window_set_cursor(shell_->webViewWnd()->window, gdk_cursor); | |
| 138 } | |
| 139 | |
| 140 WebRect TestWebViewDelegate::windowRect() { | |
| 141 WebWidgetHost* host = GetWidgetHost(); | |
| 142 GtkWidget* drawing_area = host->view_handle(); | |
| 143 GtkWidget* vbox = gtk_widget_get_parent(drawing_area); | |
| 144 GtkWidget* window = gtk_widget_get_parent(vbox); | |
| 145 | |
| 146 gint x, y; | |
| 147 gtk_window_get_position(GTK_WINDOW(window), &x, &y); | |
| 148 x += vbox->allocation.x + drawing_area->allocation.x; | |
| 149 y += vbox->allocation.y + drawing_area->allocation.y; | |
| 150 | |
| 151 return WebRect(x, y, | |
| 152 drawing_area->allocation.width, | |
| 153 drawing_area->allocation.height); | |
| 154 } | |
| 155 | |
| 156 void TestWebViewDelegate::setWindowRect(const WebRect& rect) { | |
| 157 if (this == shell_->delegate()) { | |
| 158 set_fake_window_rect(rect); | |
| 159 } else if (this == shell_->popup_delegate()) { | |
| 160 WebWidgetHost* host = GetWidgetHost(); | |
| 161 GtkWidget* drawing_area = host->view_handle(); | |
| 162 GtkWidget* window = | |
| 163 gtk_widget_get_parent(gtk_widget_get_parent(drawing_area)); | |
| 164 gtk_window_resize(GTK_WINDOW(window), rect.width, rect.height); | |
| 165 gtk_window_move(GTK_WINDOW(window), rect.x, rect.y); | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 WebRect TestWebViewDelegate::rootWindowRect() { | |
| 170 if (using_fake_rect_) { | |
| 171 return fake_window_rect(); | |
| 172 } | |
| 173 if (WebWidgetHost* host = GetWidgetHost()) { | |
| 174 // We are being asked for the x/y and width/height of the entire browser | |
| 175 // window. This means the x/y is the distance from the corner of the | |
| 176 // screen, and the width/height is the size of the entire browser window. | |
| 177 // For example, this is used to implement window.screenX and window.screenY. | |
| 178 GtkWidget* drawing_area = host->view_handle(); | |
| 179 GtkWidget* window = | |
| 180 gtk_widget_get_parent(gtk_widget_get_parent(drawing_area)); | |
| 181 gint x, y, width, height; | |
| 182 gtk_window_get_position(GTK_WINDOW(window), &x, &y); | |
| 183 gtk_window_get_size(GTK_WINDOW(window), &width, &height); | |
| 184 return WebRect(x, y, width, height); | |
| 185 } | |
| 186 return WebRect(); | |
| 187 } | |
| 188 | |
| 189 WebRect TestWebViewDelegate::windowResizerRect() { | |
| 190 // Not necessary on Linux. | |
| 191 return WebRect(); | |
| 192 } | |
| 193 | |
| 194 void TestWebViewDelegate::runModal() { | |
| 195 NOTIMPLEMENTED(); | |
| 196 } | |
| 197 | |
| 198 // WebPluginPageDelegate ------------------------------------------------------ | |
| 199 | |
| 200 webkit::npapi::WebPluginDelegate* TestWebViewDelegate::CreatePluginDelegate( | |
| 201 const base::FilePath& path, | |
| 202 const std::string& mime_type) { | |
| 203 return webkit::npapi::WebPluginDelegateImpl::Create(path, mime_type); | |
| 204 } | |
| 205 | |
| 206 void TestWebViewDelegate::CreatedPluginWindow( | |
| 207 gfx::PluginWindowHandle id) { | |
| 208 shell_->webViewHost()->CreatePluginContainer(id); | |
| 209 } | |
| 210 | |
| 211 void TestWebViewDelegate::WillDestroyPluginWindow( | |
| 212 gfx::PluginWindowHandle id) { | |
| 213 shell_->webViewHost()->DestroyPluginContainer(id); | |
| 214 } | |
| 215 | |
| 216 void TestWebViewDelegate::DidMovePlugin( | |
| 217 const webkit::npapi::WebPluginGeometry& move) { | |
| 218 WebWidgetHost* host = GetWidgetHost(); | |
| 219 webkit::npapi::GtkPluginContainerManager* plugin_container_manager = | |
| 220 static_cast<WebViewHost*>(host)->plugin_container_manager(); | |
| 221 plugin_container_manager->MovePluginContainer(move); | |
| 222 } | |
| 223 | |
| 224 // Public methods ------------------------------------------------------------- | |
| 225 | |
| 226 void TestWebViewDelegate::UpdateSelectionClipboard(bool is_empty_selection) { | |
| 227 if (is_empty_selection) | |
| 228 return; | |
| 229 | |
| 230 GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); | |
| 231 // Put data on the X clipboard. This doesn't actually grab the text from | |
| 232 // the HTML, it just registers a callback for when someone tries to paste. | |
| 233 GtkTargetList* target_list = gtk_target_list_new(NULL, 0); | |
| 234 gtk_target_list_add(target_list, GetTextHtmlAtom(), 0, TEXT_HTML); | |
| 235 gtk_target_list_add_text_targets(target_list, PLAIN_TEXT); | |
| 236 | |
| 237 gint num_targets = 0; | |
| 238 GtkTargetEntry* targets = gtk_target_table_new_from_list(target_list, | |
| 239 &num_targets); | |
| 240 gtk_clipboard_set_with_data(clipboard, targets, num_targets, | |
| 241 SelectionClipboardGetContents, NULL, | |
| 242 shell_->webView()); | |
| 243 gtk_target_list_unref(target_list); | |
| 244 gtk_target_table_free(targets, num_targets); | |
| 245 } | |
| 246 | |
| 247 // Private methods ------------------------------------------------------------ | |
| 248 | |
| 249 void TestWebViewDelegate::ShowJavaScriptAlert(const base::string16& message) { | |
| 250 GtkWidget* dialog = gtk_message_dialog_new( | |
| 251 shell_->mainWnd(), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, | |
| 252 GTK_BUTTONS_OK, "%s", UTF16ToUTF8(message).c_str()); | |
| 253 gtk_window_set_title(GTK_WINDOW(dialog), "JavaScript Alert"); | |
| 254 gtk_dialog_run(GTK_DIALOG(dialog)); // Runs a nested message loop. | |
| 255 gtk_widget_destroy(dialog); | |
| 256 } | |
| 257 | |
| 258 void TestWebViewDelegate::SetPageTitle(const base::string16& title) { | |
| 259 gtk_window_set_title(GTK_WINDOW(shell_->mainWnd()), | |
| 260 ("Test Shell - " + UTF16ToUTF8(title)).c_str()); | |
| 261 } | |
| 262 | |
| 263 void TestWebViewDelegate::SetAddressBarURL(const GURL& url) { | |
| 264 gtk_entry_set_text(GTK_ENTRY(shell_->editWnd()), url.spec().c_str()); | |
| 265 } | |
| OLD | NEW |