[GTK] Fix some simple gtkdoc warnings for WebKit1
[WebKit-https.git] / Source / WebKit / gtk / webkit / webkitwebview.cpp
1 /*
2  *  Copyright (C) 2007, 2008 Holger Hans Peter Freyther
3  *  Copyright (C) 2007, 2008, 2009 Christian Dywan <christian@imendio.com>
4  *  Copyright (C) 2007 Xan Lopez <xan@gnome.org>
5  *  Copyright (C) 2007, 2008 Alp Toker <alp@atoker.com>
6  *  Copyright (C) 2008 Jan Alonzo <jmalonzo@unpluggable.com>
7  *  Copyright (C) 2008 Gustavo Noronha Silva <gns@gnome.org>
8  *  Copyright (C) 2008 Nuanti Ltd.
9  *  Copyright (C) 2008, 2009, 2010 Collabora Ltd.
10  *  Copyright (C) 2009, 2010, 2012 Igalia S.L.
11  *  Copyright (C) 2009 Movial Creative Technologies Inc.
12  *  Copyright (C) 2009 Bobby Powers
13  *  Copyright (C) 2010 Joone Hur <joone@kldp.org>
14  *  Copyright (C) 2012 Igalia S.L.
15  *  Copyright (C) 2013 Apple Inc. All rights reserved.
16  *
17  *  This library is free software; you can redistribute it and/or
18  *  modify it under the terms of the GNU Lesser General Public
19  *  License as published by the Free Software Foundation; either
20  *  version 2 of the License, or (at your option) any later version.
21  *
22  *  This library is distributed in the hope that it will be useful,
23  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
24  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  *  Lesser General Public License for more details.
26  *
27  *  You should have received a copy of the GNU Lesser General Public
28  *  License along with this library; if not, write to the Free Software
29  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
30  */
31
32 #include "config.h"
33 #include "webkitwebview.h"
34
35 #include "AXObjectCache.h"
36 #include "ArchiveResource.h"
37 #include "BackForwardController.h"
38 #include "BackForwardList.h"
39 #include "BatteryClientGtk.h"
40 #include "CairoUtilities.h"
41 #include "Chrome.h"
42 #include "ChromeClientGtk.h"
43 #include "ClipboardUtilitiesGtk.h"
44 #include "ContextMenu.h"
45 #include "ContextMenuClientGtk.h"
46 #include "ContextMenuController.h"
47 #include "Cursor.h"
48 #include "DatabaseManager.h"
49 #include "Document.h"
50 #include "DocumentLoader.h"
51 #include "DragActions.h"
52 #include "DragClientGtk.h"
53 #include "DragController.h"
54 #include "DragData.h"
55 #include "DragSession.h"
56 #include "DumpRenderTreeSupportGtk.h"
57 #include "Editor.h"
58 #include "EditorClientGtk.h"
59 #include "EventHandler.h"
60 #include "FloatQuad.h"
61 #include "FocusController.h"
62 #include "FrameLoader.h"
63 #include "FrameLoaderClientGtk.h"
64 #include "FrameLoaderTypes.h"
65 #include "FrameView.h"
66 #include "GUniquePtrGtk.h"
67 #include "GeolocationClientGtk.h"
68 #include "GeolocationController.h"
69 #include "GraphicsContext.h"
70 #include "GtkUtilities.h"
71 #include "GtkVersioning.h"
72 #include "HTMLNames.h"
73 #include "HitTestRequest.h"
74 #include "HitTestResult.h"
75 #include "InspectorClientGtk.h"
76 #include "MainFrame.h"
77 #include "MemoryCache.h"
78 #include "MouseEventWithHitTestResults.h"
79 #include "NotImplemented.h"
80 #include "PageCache.h"
81 #include "Pasteboard.h"
82 #include "PasteboardHelper.h"
83 #include "PlatformKeyboardEvent.h"
84 #include "PlatformWheelEvent.h"
85 #include "ProgressTracker.h"
86 #include "ProgressTrackerClientGtk.h"
87 #include "RenderView.h"
88 #include "ResourceHandle.h"
89 #include "RuntimeEnabledFeatures.h"
90 #include "ScriptController.h"
91 #include "Settings.h"
92 #include "WebKitDOMDocumentPrivate.h"
93 #include "webkitdownload.h"
94 #include "webkitdownloadprivate.h"
95 #include "webkitenumtypes.h"
96 #include "webkitfavicondatabase.h"
97 #include "webkitgeolocationpolicydecision.h"
98 #include "webkitglobalsprivate.h"
99 #include "webkithittestresultprivate.h"
100 #include "webkiticondatabase.h"
101 #include "webkitmarshal.h"
102 #include "webkitnetworkrequest.h"
103 #include "webkitnetworkresponse.h"
104 #include "webkitviewportattributes.h"
105 #include "webkitviewportattributesprivate.h"
106 #include "webkitwebbackforwardlist.h"
107 #include "webkitwebframeprivate.h"
108 #include "webkitwebhistoryitem.h"
109 #include "webkitwebhistoryitemprivate.h"
110 #include "webkitwebinspector.h"
111 #include "webkitwebinspectorprivate.h"
112 #include "webkitwebpolicydecision.h"
113 #include "webkitwebresource.h"
114 #include "webkitwebresourceprivate.h"
115 #include "webkitwebsettingsprivate.h"
116 #include "webkitwebplugindatabaseprivate.h"
117 #include "webkitwebwindowfeatures.h"
118 #include "webkitwebviewprivate.h"
119 #include <bindings/ScriptValue.h>
120 #include <gdk/gdkkeysyms.h>
121 #include <glib/gi18n-lib.h>
122 #include <gtk/gtk.h>
123 #include <wtf/text/CString.h>
124
125 #if ENABLE(DEVICE_ORIENTATION)
126 #include "DeviceMotionClientGtk.h"
127 #include "DeviceOrientationClientGtk.h"
128 #endif
129
130 #if PLATFORM(WAYLAND) && defined(GDK_WINDOWING_WAYLAND)
131 #include <gdk/gdkwayland.h>
132 #endif
133
134 /**
135  * SECTION:webkitwebview
136  * @short_description: The central class of the WebKitGTK+ API
137  * @see_also: #WebKitWebSettings, #WebKitWebFrame
138  *
139  * #WebKitWebView is the central class of the WebKitGTK+ API. It is a
140  * #GtkWidget implementing the scrolling interface which means you can
141  * embed in a #GtkScrolledWindow. It is responsible for managing the
142  * drawing of the content, forwarding of events. You can load any URI
143  * into the #WebKitWebView or any kind of data string. With #WebKitWebSettings
144  * you can control various aspects of the rendering and loading of the content.
145  * Each #WebKitWebView has exactly one #WebKitWebFrame as main frame. A
146  * #WebKitWebFrame can have n children.
147  *
148  * <programlisting>
149  * /<!-- -->* Create the widgets *<!-- -->/
150  * GtkWidget *main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
151  * GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
152  * GtkWidget *web_view = webkit_web_view_new ();
153  *
154  * /<!-- -->* Place the WebKitWebView in the GtkScrolledWindow *<!-- -->/
155  * gtk_container_add (GTK_CONTAINER (scrolled_window), web_view);
156  * gtk_container_add (GTK_CONTAINER (main_window), scrolled_window);
157  *
158  * /<!-- -->* Open a webpage *<!-- -->/
159  * webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), "http://www.gnome.org");
160  *
161  * /<!-- -->* Show the result *<!-- -->/
162  * gtk_window_set_default_size (GTK_WINDOW (main_window), 800, 600);
163  * gtk_widget_show_all (main_window);
164  * </programlisting>
165  */
166
167 using namespace WebKit;
168 using namespace WebCore;
169
170 enum {
171     /* normal signals */
172     NAVIGATION_REQUESTED,
173     NEW_WINDOW_POLICY_DECISION_REQUESTED,
174     NAVIGATION_POLICY_DECISION_REQUESTED,
175     MIME_TYPE_POLICY_DECISION_REQUESTED,
176     CREATE_WEB_VIEW,
177     WEB_VIEW_READY,
178     WINDOW_OBJECT_CLEARED,
179     LOAD_STARTED,
180     LOAD_COMMITTED,
181     LOAD_PROGRESS_CHANGED,
182     LOAD_ERROR,
183     LOAD_FINISHED,
184     TITLE_CHANGED,
185     HOVERING_OVER_LINK,
186     POPULATE_POPUP,
187     STATUS_BAR_TEXT_CHANGED,
188     ICON_LOADED,
189     SELECTION_CHANGED,
190     CONSOLE_MESSAGE,
191     SCRIPT_ALERT,
192     SCRIPT_CONFIRM,
193     SCRIPT_PROMPT,
194     SELECT_ALL,
195     COPY_CLIPBOARD,
196     PASTE_CLIPBOARD,
197     CUT_CLIPBOARD,
198     DOWNLOAD_REQUESTED,
199     MOVE_CURSOR,
200     PRINT_REQUESTED,
201     PLUGIN_WIDGET,
202     CLOSE_WEB_VIEW,
203     UNDO,
204     REDO,
205     DATABASE_QUOTA_EXCEEDED,
206     RESOURCE_REQUEST_STARTING,
207     DOCUMENT_LOAD_FINISHED,
208     GEOLOCATION_POLICY_DECISION_REQUESTED,
209     GEOLOCATION_POLICY_DECISION_CANCELLED,
210     ONLOAD_EVENT,
211     FRAME_CREATED,
212     SHOULD_BEGIN_EDITING,
213     SHOULD_END_EDITING,
214     SHOULD_INSERT_NODE,
215     SHOULD_INSERT_TEXT,
216     SHOULD_DELETE_RANGE,
217     SHOULD_SHOW_DELETE_INTERFACE_FOR_ELEMENT,
218     SHOULD_CHANGE_SELECTED_RANGE,
219     SHOULD_APPLY_STYLE,
220     EDITING_BEGAN,
221     USER_CHANGED_CONTENTS,
222     EDITING_ENDED,
223     VIEWPORT_ATTRIBUTES_RECOMPUTE_REQUESTED,
224     VIEWPORT_ATTRIBUTES_CHANGED,
225     RESOURCE_RESPONSE_RECEIVED,
226     RESOURCE_LOAD_FINISHED,
227     RESOURCE_CONTENT_LENGTH_RECEIVED,
228     RESOURCE_LOAD_FAILED,
229     ENTERING_FULLSCREEN,
230     LEAVING_FULLSCREEN,
231     CONTEXT_MENU,
232     RUN_FILE_CHOOSER,
233
234     LAST_SIGNAL
235 };
236
237 enum {
238     PROP_0,
239
240     PROP_TITLE,
241     PROP_URI,
242     PROP_COPY_TARGET_LIST,
243     PROP_PASTE_TARGET_LIST,
244     PROP_EDITABLE,
245     PROP_SETTINGS,
246     PROP_WEB_INSPECTOR,
247     PROP_VIEWPORT_ATTRIBUTES,
248     PROP_WINDOW_FEATURES,
249     PROP_TRANSPARENT,
250     PROP_ZOOM_LEVEL,
251     PROP_FULL_CONTENT_ZOOM,
252     PROP_LOAD_STATUS,
253     PROP_PROGRESS,
254     PROP_ENCODING,
255     PROP_CUSTOM_ENCODING,
256     PROP_ICON_URI,
257     PROP_IM_CONTEXT,
258 #ifdef GTK_API_VERSION_2
259     PROP_VIEW_MODE,
260 #else
261     PROP_VIEW_MODE,
262     PROP_HADJUSTMENT,
263     PROP_VADJUSTMENT,
264     PROP_HSCROLL_POLICY,
265     PROP_VSCROLL_POLICY,
266 #endif
267
268     // Undocumented. Leave these properties at the end of the list
269     // so that we can remove them without breaking ABI compatibility.
270     PROP_SELF_SCROLLING
271 };
272
273 static guint webkit_web_view_signals[LAST_SIGNAL] = { 0, };
274
275 #ifdef GTK_API_VERSION_2
276 G_DEFINE_TYPE(WebKitWebView, webkit_web_view, GTK_TYPE_CONTAINER)
277 #else
278 G_DEFINE_TYPE_WITH_CODE(WebKitWebView, webkit_web_view, GTK_TYPE_CONTAINER,
279                         G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE, 0))
280 #endif
281
282 static void webkit_web_view_settings_notify(WebKitWebSettings* webSettings, GParamSpec* pspec, WebKitWebView* webView);
283 static void webkit_web_view_set_window_features(WebKitWebView* webView, WebKitWebWindowFeatures* webWindowFeatures);
284 static void webkitWebViewDirectionChanged(WebKitWebView*, GtkTextDirection previousDirection, gpointer);
285
286 static inline WebKitWebViewTargetInfo toWebKitWebViewTargetInfo(PasteboardHelper::PasteboardTargetType flags)
287 {
288     switch (flags) {
289     case PasteboardHelper::TargetTypeMarkup:
290         return WEBKIT_WEB_VIEW_TARGET_INFO_HTML;
291         break;
292     case PasteboardHelper::TargetTypeText:
293         return WEBKIT_WEB_VIEW_TARGET_INFO_TEXT;
294         break;
295     case PasteboardHelper::TargetTypeImage:
296         return WEBKIT_WEB_VIEW_TARGET_INFO_IMAGE;
297         break;
298     case PasteboardHelper::TargetTypeURIList:
299         return WEBKIT_WEB_VIEW_TARGET_INFO_URI_LIST;
300         break;
301     case PasteboardHelper::TargetTypeNetscapeURL:
302         return WEBKIT_WEB_VIEW_TARGET_INFO_NETSCAPE_URL;
303         break;
304     default:
305         ASSERT_NOT_REACHED();
306         return WEBKIT_WEB_VIEW_TARGET_INFO_HTML;
307     }
308 }
309
310 static GtkTargetList* copyGtkTargetListConvertingWebCoreEnumValuesToWebKitEnumValues(GtkTargetList* coreGtkTargetList)
311 {
312     g_return_val_if_fail(coreGtkTargetList, nullptr);
313
314     GtkTargetList* targetListWithWebKitEnumValues = nullptr;
315     int tableSize = 0;
316     GtkTargetEntry* table(gtk_target_table_new_from_list(coreGtkTargetList, &tableSize));
317
318     for (int i = 0; i < tableSize; i++)
319         table[i].flags = toWebKitWebViewTargetInfo(static_cast<PasteboardHelper::PasteboardTargetType>(table[i].flags));
320
321     targetListWithWebKitEnumValues = gtk_target_list_new(table, tableSize);
322     gtk_target_table_free(table, tableSize);
323
324     return targetListWithWebKitEnumValues;
325 }
326
327 #if ENABLE(CONTEXT_MENUS)
328 static void PopupMenuPositionFunc(GtkMenu* menu, gint *x, gint *y, gboolean *pushIn, gpointer userData)
329 {
330     WebKitWebView* view = WEBKIT_WEB_VIEW(userData);
331     WebKitWebViewPrivate* priv = view->priv;
332     GdkScreen* screen = gtk_widget_get_screen(GTK_WIDGET(view));
333     GtkRequisition menuSize;
334
335 #ifdef GTK_API_VERSION_2
336     gtk_widget_size_request(GTK_WIDGET(menu), &menuSize);
337 #else
338     gtk_widget_get_preferred_size(GTK_WIDGET(menu), &menuSize, NULL);
339 #endif
340
341     *x = priv->lastPopupXPosition;
342     if ((*x + menuSize.width) >= gdk_screen_get_width(screen))
343       *x -= menuSize.width;
344
345     *y = priv->lastPopupYPosition;
346     if ((*y + menuSize.height) >= gdk_screen_get_height(screen))
347       *y -= menuSize.height;
348
349     *pushIn = FALSE;
350 }
351 #endif
352
353 static Node* getFocusedNode(Frame* frame)
354 {
355     if (Document* doc = frame->document())
356         return doc->focusedElement();
357     return 0;
358 }
359
360 #if ENABLE(CONTEXT_MENUS)
361 static void contextMenuItemActivated(GtkMenuItem* item, ContextMenuController* controller)
362 {
363     ContextMenuItem contextItem(item);
364     controller->contextMenuItemSelected(&contextItem);
365 }
366
367 static void contextMenuConnectActivate(GtkMenuItem* item, ContextMenuController* controller)
368 {
369     if (GTK_IS_SEPARATOR_MENU_ITEM(item))
370         return;
371
372     if (GtkWidget* menu = gtk_menu_item_get_submenu(item)) {
373         gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback)contextMenuConnectActivate, controller);
374         return;
375     }
376
377     g_signal_connect(item, "activate", G_CALLBACK(contextMenuItemActivated), controller);
378 }
379
380 static MouseEventWithHitTestResults prepareMouseEventForFrame(Frame* frame, const PlatformMouseEvent& event)
381 {
382     HitTestRequest request(HitTestRequest::Active| HitTestRequest::DisallowShadowContent);
383     IntPoint point = frame->view()->windowToContents(event.position());
384     return frame->document()->prepareMouseEvent(request, point, event);
385 }
386
387 // Check enable-default-context-menu setting for compatibility.
388 static bool defaultContextMenuEnabled(WebKitWebView* webView)
389 {
390     gboolean enableDefaultContextMenu;
391     g_object_get(webkit_web_view_get_settings(webView), "enable-default-context-menu", &enableDefaultContextMenu, NULL);
392     return enableDefaultContextMenu;
393 }
394
395 static gboolean webkit_web_view_forward_context_menu_event(WebKitWebView* webView, const PlatformMouseEvent& event, bool triggeredWithKeyboard)
396 {
397     Page* page = core(webView);
398     page->contextMenuController().clearContextMenu();
399     Frame* focusedFrame;
400     Frame* mainFrame = &page->mainFrame();
401     gboolean mousePressEventResult = FALSE;
402     GRefPtr<WebKitHitTestResult> hitTestResult;
403
404     if (!mainFrame->view())
405         return FALSE;
406
407     mainFrame->view()->setCursor(pointerCursor());
408     if (page->subframeCount()) {
409         MouseEventWithHitTestResults mev = prepareMouseEventForFrame(mainFrame, event);
410         Frame* targetFrame = EventHandler::subframeForHitTestResult(mev);
411         if (!targetFrame)
412             targetFrame = mainFrame;
413
414         focusedFrame = &page->focusController().focusedOrMainFrame();
415         if (targetFrame != focusedFrame) {
416             page->focusController().setFocusedFrame(targetFrame);
417             focusedFrame = targetFrame;
418         }
419         if (focusedFrame == mainFrame)
420             hitTestResult = adoptGRef(kit(mev.hitTestResult()));
421     } else
422         focusedFrame = mainFrame;
423
424     if (focusedFrame->view() && focusedFrame->eventHandler().handleMousePressEvent(event))
425         mousePressEventResult = TRUE;
426
427     bool handledEvent = focusedFrame->eventHandler().sendContextMenuEvent(event);
428     if (!handledEvent)
429         return FALSE;
430
431     // If coreMenu is NULL, this means WebCore decided to not create
432     // the default context menu; this may happen when the page is
433     // handling the right-click for reasons other than the context menu.
434     ContextMenu* coreMenu = page->contextMenuController().contextMenu();
435     if (!coreMenu)
436         return mousePressEventResult;
437
438     GtkMenu* defaultMenu = coreMenu->platformDescription();
439     ASSERT(defaultMenu);
440
441     // We connect the "activate" signal here rather than in ContextMenuGtk to avoid
442     // a layering violation. ContextMenuGtk should not know about the ContextMenuController.
443     gtk_container_foreach(GTK_CONTAINER(defaultMenu), reinterpret_cast<GtkCallback>(contextMenuConnectActivate), &page->contextMenuController());
444
445     if (!hitTestResult) {
446         MouseEventWithHitTestResults mev = prepareMouseEventForFrame(focusedFrame, event);
447         hitTestResult = adoptGRef(kit(mev.hitTestResult()));
448     }
449
450     gboolean handled;
451     g_signal_emit(webView, webkit_web_view_signals[CONTEXT_MENU], 0, defaultMenu, hitTestResult.get(), triggeredWithKeyboard, &handled);
452     if (handled)
453         return TRUE;
454
455     // Return now if default context menu is disabled by enable-default-context-menu setting.
456     // Check enable-default-context-menu setting for compatibility.
457     if (!defaultContextMenuEnabled(webView))
458         return FALSE;
459
460     // Emit populate-popup signal for compatibility.
461     g_signal_emit(webView, webkit_web_view_signals[POPULATE_POPUP], 0, defaultMenu);
462
463     // If the context menu is now empty, don't show it.
464     GUniquePtr<GList> items(gtk_container_get_children(GTK_CONTAINER(defaultMenu)));
465     if (!items)
466         return FALSE;
467
468     WebKitWebViewPrivate* priv = webView->priv;
469     priv->currentMenu = defaultMenu;
470     priv->lastPopupXPosition = event.globalPosition().x();
471     priv->lastPopupYPosition = event.globalPosition().y();
472
473     gtk_menu_popup(defaultMenu, 0, 0, &PopupMenuPositionFunc, webView, event.button() + 1, gtk_get_current_event_time());
474     return TRUE;
475 }
476
477 static const int gContextMenuMargin = 1;
478 static IntPoint getLocationForKeyboardGeneratedContextMenu(Frame* frame)
479 {
480     FrameSelection& selection = frame->selection();
481     if (!selection.selection().isNonOrphanedCaretOrRange()
482         || (selection.selection().isCaret() && !selection.selection().isContentEditable())) {
483         if (Node* focusedNode = getFocusedNode(frame))
484             return focusedNode->pixelSnappedBoundingBox().location();
485
486         // There was no selection and no focused node, so just put the context
487         // menu into the corner of the view, offset slightly.
488         return IntPoint(gContextMenuMargin, gContextMenuMargin);
489     }
490
491     // selection->selection().firstRange can return 0 here, but if that was the case
492     // selection->selection().isNonOrphanedCaretOrRange() would have returned false
493     // above, so we do not have to check it.
494     IntRect firstRect = frame->editor().firstRectForRange(selection.selection().firstRange().get());
495     return IntPoint(firstRect.x(), firstRect.maxY());
496 }
497
498 static gboolean webkit_web_view_popup_menu_handler(GtkWidget* widget)
499 {
500     Frame& frame = core(WEBKIT_WEB_VIEW(widget))->focusController().focusedOrMainFrame();
501     IntPoint location = getLocationForKeyboardGeneratedContextMenu(&frame);
502
503     FrameView* view = frame.view();
504     if (!view)
505         return FALSE;
506
507     // Never let the context menu touch the very edge of the view.
508     location = view->contentsToWindow(location);
509     location.expandedTo(IntPoint(gContextMenuMargin, gContextMenuMargin));
510     location.shrunkTo(IntPoint(view->width() - gContextMenuMargin, view->height() - gContextMenuMargin));
511
512     IntPoint globalPoint(convertWidgetPointToScreenPoint(widget, location));
513     PlatformMouseEvent event(location, globalPoint, RightButton, PlatformEvent::MousePressed, 0, false, false, false, false, gtk_get_current_event_time());
514     return webkit_web_view_forward_context_menu_event(WEBKIT_WEB_VIEW(widget), event, true);
515 }
516 #endif // ENABLE(CONTEXT_MENUS)
517
518 static void setHorizontalAdjustment(WebKitWebView* webView, GtkAdjustment* adjustment)
519 {
520     // This may be called after the page has been destroyed, in which case we do nothing.
521     Page* page = core(webView);
522     if (page)
523         static_cast<WebKit::ChromeClient&>(page->chrome().client()).adjustmentWatcher()->setHorizontalAdjustment(adjustment);
524 }
525
526 static void setVerticalAdjustment(WebKitWebView* webView, GtkAdjustment* adjustment)
527 {
528     // This may be called after the page has been destroyed, in which case we do nothing.
529     Page* page = core(webView);
530     if (page)
531         static_cast<WebKit::ChromeClient&>(page->chrome().client()).adjustmentWatcher()->setVerticalAdjustment(adjustment);
532 }
533
534 #ifndef GTK_API_VERSION_2
535 static GtkAdjustment* getHorizontalAdjustment(WebKitWebView* webView)
536 {
537     Page* page = core(webView);
538     if (page)
539         return static_cast<WebKit::ChromeClient&>(page->chrome().client()).adjustmentWatcher()->horizontalAdjustment();
540     return 0;
541 }
542
543 static GtkAdjustment* getVerticalAdjustment(WebKitWebView* webView)
544 {
545     Page* page = core(webView);
546     if (page)
547         return static_cast<WebKit::ChromeClient&>(page->chrome().client()).adjustmentWatcher()->verticalAdjustment();
548     return 0;
549 }
550
551 static void setHorizontalScrollPolicy(WebKitWebView* webView, GtkScrollablePolicy policy)
552 {
553     webView->priv->horizontalScrollingPolicy = policy;
554     gtk_widget_queue_resize(GTK_WIDGET(webView));
555 }
556
557 static void setVerticalScrollPolicy(WebKitWebView* webView, GtkScrollablePolicy policy)
558 {
559     webView->priv->verticalScrollingPolicy = policy;
560     gtk_widget_queue_resize(GTK_WIDGET(webView));
561 }
562
563 static GtkScrollablePolicy getHorizontalScrollPolicy(WebKitWebView* webView)
564 {
565     return webView->priv->horizontalScrollingPolicy;
566 }
567
568 static GtkScrollablePolicy getVerticalScrollPolicy(WebKitWebView* webView)
569 {
570     return webView->priv->verticalScrollingPolicy;
571 }
572
573 #endif
574
575 static void webkit_web_view_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
576 {
577     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
578
579     switch(prop_id) {
580     case PROP_TITLE:
581         g_value_set_string(value, webkit_web_view_get_title(webView));
582         break;
583     case PROP_URI:
584         g_value_set_string(value, webkit_web_view_get_uri(webView));
585         break;
586     case PROP_COPY_TARGET_LIST:
587         g_value_set_boxed(value, webkit_web_view_get_copy_target_list(webView));
588         break;
589     case PROP_PASTE_TARGET_LIST:
590         g_value_set_boxed(value, webkit_web_view_get_paste_target_list(webView));
591         break;
592     case PROP_EDITABLE:
593         g_value_set_boolean(value, webkit_web_view_get_editable(webView));
594         break;
595     case PROP_SETTINGS:
596         g_value_set_object(value, webkit_web_view_get_settings(webView));
597         break;
598     case PROP_WEB_INSPECTOR:
599         g_value_set_object(value, webkit_web_view_get_inspector(webView));
600         break;
601     case PROP_VIEWPORT_ATTRIBUTES:
602         g_value_set_object(value, webkit_web_view_get_viewport_attributes(webView));
603         break;
604     case PROP_WINDOW_FEATURES:
605         g_value_set_object(value, webkit_web_view_get_window_features(webView));
606         break;
607     case PROP_TRANSPARENT:
608         g_value_set_boolean(value, webkit_web_view_get_transparent(webView));
609         break;
610     case PROP_ZOOM_LEVEL:
611         g_value_set_float(value, webkit_web_view_get_zoom_level(webView));
612         break;
613     case PROP_FULL_CONTENT_ZOOM:
614         g_value_set_boolean(value, webkit_web_view_get_full_content_zoom(webView));
615         break;
616     case PROP_ENCODING:
617         g_value_set_string(value, webkit_web_view_get_encoding(webView));
618         break;
619     case PROP_CUSTOM_ENCODING:
620         g_value_set_string(value, webkit_web_view_get_custom_encoding(webView));
621         break;
622     case PROP_LOAD_STATUS:
623         g_value_set_enum(value, webkit_web_view_get_load_status(webView));
624         break;
625     case PROP_PROGRESS:
626         g_value_set_double(value, webkit_web_view_get_progress(webView));
627         break;
628     case PROP_ICON_URI:
629         g_value_set_string(value, webkit_web_view_get_icon_uri(webView));
630         break;
631     case PROP_IM_CONTEXT:
632         g_value_set_object(value, webView->priv->imFilter.context());
633         break;
634     case PROP_VIEW_MODE:
635         g_value_set_enum(value, webkit_web_view_get_view_mode(webView));
636         break;
637 #ifndef GTK_API_VERSION_2
638     case PROP_HADJUSTMENT:
639         g_value_set_object(value, getHorizontalAdjustment(webView));
640         break;
641     case PROP_VADJUSTMENT:
642         g_value_set_object(value, getVerticalAdjustment(webView));
643         break;
644     case PROP_HSCROLL_POLICY:
645         g_value_set_enum(value, getHorizontalScrollPolicy(webView));
646         break;
647     case PROP_VSCROLL_POLICY:
648         g_value_set_enum(value, getVerticalScrollPolicy(webView));
649         break;
650 #endif
651     case PROP_SELF_SCROLLING:
652         g_value_set_boolean(value, webView->priv->selfScrolling);
653         break;
654     default:
655         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
656     }
657 }
658
659 static void webkit_web_view_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec *pspec)
660 {
661     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
662
663     switch(prop_id) {
664     case PROP_EDITABLE:
665         webkit_web_view_set_editable(webView, g_value_get_boolean(value));
666         break;
667     case PROP_SETTINGS:
668         webkit_web_view_set_settings(webView, WEBKIT_WEB_SETTINGS(g_value_get_object(value)));
669         break;
670     case PROP_WINDOW_FEATURES:
671         webkit_web_view_set_window_features(webView, WEBKIT_WEB_WINDOW_FEATURES(g_value_get_object(value)));
672         break;
673     case PROP_TRANSPARENT:
674         webkit_web_view_set_transparent(webView, g_value_get_boolean(value));
675         break;
676     case PROP_ZOOM_LEVEL:
677         webkit_web_view_set_zoom_level(webView, g_value_get_float(value));
678         break;
679     case PROP_FULL_CONTENT_ZOOM:
680         webkit_web_view_set_full_content_zoom(webView, g_value_get_boolean(value));
681         break;
682     case PROP_CUSTOM_ENCODING:
683         webkit_web_view_set_custom_encoding(webView, g_value_get_string(value));
684         break;
685     case PROP_VIEW_MODE:
686         webkit_web_view_set_view_mode(webView, static_cast<WebKitWebViewViewMode>(g_value_get_enum(value)));
687         break;
688 #ifndef GTK_API_VERSION_2
689     case PROP_HADJUSTMENT:
690         setHorizontalAdjustment(webView, static_cast<GtkAdjustment*>(g_value_get_object(value)));
691         break;
692     case PROP_VADJUSTMENT:
693         setVerticalAdjustment(webView, static_cast<GtkAdjustment*>(g_value_get_object(value)));
694         break;
695     case PROP_HSCROLL_POLICY:
696         setHorizontalScrollPolicy(webView, static_cast<GtkScrollablePolicy>(g_value_get_enum(value)));
697         break;
698     case PROP_VSCROLL_POLICY:
699         setVerticalScrollPolicy(webView, static_cast<GtkScrollablePolicy>(g_value_get_enum(value)));
700         break;
701 #endif
702     case PROP_SELF_SCROLLING:
703         webView->priv->selfScrolling = g_value_get_boolean(value);
704         break;
705     default:
706         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
707     }
708 }
709
710 #ifdef GTK_API_VERSION_2
711 static gboolean webkit_web_view_expose_event(GtkWidget* widget, GdkEventExpose* event)
712 {
713     int rectCount;
714     GUniqueOutPtr<GdkRectangle> rects;
715     gdk_region_get_rectangles(event->region, &rects.outPtr(), &rectCount);
716
717     RefPtr<cairo_t> cr = adoptRef(gdk_cairo_create(event->window));
718
719     WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(widget)->priv;
720 #if USE(TEXTURE_MAPPER)
721     GdkRectangle clipRect;
722     gdk_region_get_clipbox(event->region, &clipRect);
723     if (priv->acceleratedCompositingContext->renderLayersToWindow(cr.get(), clipRect)) {
724         GTK_WIDGET_CLASS(webkit_web_view_parent_class)->expose_event(widget, event);
725         return FALSE;
726     }
727 #endif
728
729     for (int i = 0; i < rectCount; i++) {
730         copyRectFromCairoSurfaceToContext(WEBKIT_WEB_VIEW(widget)->priv->backingStore->cairoSurface(),
731                                           cr.get(), IntSize(), IntRect(rects.get()[i]));
732     }
733
734     // Chaining up to the parent forces child widgets to be drawn.
735     GTK_WIDGET_CLASS(webkit_web_view_parent_class)->expose_event(widget, event);
736     return FALSE;
737 }
738 #else
739 static gboolean webkit_web_view_draw(GtkWidget* widget, cairo_t* cr)
740 {
741     GdkRectangle clipRect;
742     if (!gdk_cairo_get_clip_rectangle(cr, &clipRect))
743         return FALSE;
744
745     WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(widget)->priv;
746 #if USE(TEXTURE_MAPPER)
747     if (priv->acceleratedCompositingContext->renderLayersToWindow(cr, clipRect)) {
748         GTK_WIDGET_CLASS(webkit_web_view_parent_class)->draw(widget, cr);
749         return FALSE;
750     }
751 #endif
752
753     cairo_rectangle_list_t* rectList = cairo_copy_clip_rectangle_list(cr);
754     if (rectList->status || !rectList->num_rectangles) {
755         cairo_rectangle_list_destroy(rectList);
756         return FALSE;
757     }
758
759     Vector<IntRect> rects;
760     for (int i = 0; i < rectList->num_rectangles; i++) {
761         copyRectFromCairoSurfaceToContext(priv->backingStore->cairoSurface(), cr, IntSize(),
762                                           enclosingIntRect(FloatRect(rectList->rectangles[i])));
763     }
764     cairo_rectangle_list_destroy(rectList);
765
766     // Chaining up to the parent forces child widgets to be drawn.
767     GTK_WIDGET_CLASS(webkit_web_view_parent_class)->draw(widget, cr);
768     return FALSE;
769 }
770 #endif // GTK_API_VERSION_2
771
772 static gboolean webkit_web_view_key_press_event(GtkWidget* widget, GdkEventKey* event)
773 {
774     if (WEBKIT_WEB_VIEW(widget)->priv->imFilter.filterKeyEvent(event))
775         return TRUE;
776     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->key_press_event(widget, event);
777 }
778
779 static gboolean webkit_web_view_key_release_event(GtkWidget* widget, GdkEventKey* event)
780 {
781     if (WEBKIT_WEB_VIEW(widget)->priv->imFilter.filterKeyEvent(event))
782         return TRUE;
783     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->key_release_event(widget, event);
784 }
785
786 static gboolean webkit_web_view_button_press_event(GtkWidget* widget, GdkEventButton* event)
787 {
788     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
789     WebKitWebViewPrivate* priv = webView->priv;
790
791     // FIXME: need to keep track of subframe focus for key events
792     gtk_widget_grab_focus(widget);
793
794     if (!priv->clickCounter.shouldProcessButtonEvent(event))
795         return TRUE;
796
797     PlatformMouseEvent platformEvent(event);
798     int count = priv->clickCounter.clickCountForGdkButtonEvent(widget, event);
799     platformEvent.setClickCount(count);
800
801 #if ENABLE(CONTEXT_MENUS)
802     if (event->button == 3)
803         return webkit_web_view_forward_context_menu_event(webView, PlatformMouseEvent(event), false);
804 #endif
805
806     Frame& frame = core(webView)->mainFrame();
807     if (!frame.view())
808         return FALSE;
809
810     priv->imFilter.notifyMouseButtonPress();
811     gboolean result = frame.eventHandler().handleMousePressEvent(platformEvent);
812
813     return result;
814 }
815
816 static gboolean webkit_web_view_button_release_event(GtkWidget* widget, GdkEventButton* event)
817 {
818     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
819
820     Frame& mainFrame = core(webView)->mainFrame();
821     if (mainFrame.view())
822         mainFrame.eventHandler().handleMouseReleaseEvent(PlatformMouseEvent(event));
823
824     /* We always return FALSE here because WebKit can, for the same click, decide
825      * to not handle press-event but handle release-event, which can totally confuse
826      * some GTK+ containers when there are no other events in between. This way we
827      * guarantee that this case never happens, and that if press-event goes through
828      * release-event also goes through.
829      */
830
831     return FALSE;
832 }
833
834 static gboolean webkit_web_view_motion_event(GtkWidget* widget, GdkEventMotion* event)
835 {
836     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
837
838     Frame& frame = core(webView)->mainFrame();
839     if (!frame.view())
840         return FALSE;
841
842     return frame.eventHandler().mouseMoved(PlatformMouseEvent(event));
843 }
844
845 static gboolean webkit_web_view_scroll_event(GtkWidget* widget, GdkEventScroll* event)
846 {
847     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
848
849     Frame& frame = core(webView)->mainFrame();
850     if (!frame.view())
851         return FALSE;
852
853     PlatformWheelEvent wheelEvent(event);
854     return frame.eventHandler().handleWheelEvent(wheelEvent);
855 }
856
857 #ifdef GTK_API_VERSION_2
858 static void webkit_web_view_size_request(GtkWidget* widget, GtkRequisition* requisition)
859 {
860     WebKitWebView* web_view = WEBKIT_WEB_VIEW(widget);
861     Frame* coreFrame = core(webkit_web_view_get_main_frame(web_view));
862     if (!coreFrame)
863         return;
864
865     FrameView* view = coreFrame->view();
866     if (!view)
867         return;
868
869     requisition->width = view->contentsWidth();
870     requisition->height = view->contentsHeight();
871 }
872 #else
873 static void webkit_web_view_get_preferred_width(GtkWidget* widget, gint* minimum, gint* natural)
874 {
875     WebKitWebView* web_view = WEBKIT_WEB_VIEW(widget);
876     Frame* coreFrame = core(webkit_web_view_get_main_frame(web_view));
877     if (!coreFrame)
878         return;
879
880     FrameView* view = coreFrame->view();
881     if (!view)
882         return;
883
884     *minimum = *natural = view->contentsWidth();
885 }
886
887 static void webkit_web_view_get_preferred_height(GtkWidget* widget, gint* minimum, gint* natural)
888 {
889     WebKitWebView* web_view = WEBKIT_WEB_VIEW(widget);
890     Frame* coreFrame = core(webkit_web_view_get_main_frame(web_view));
891     if (!coreFrame)
892         return;
893
894     FrameView* view = coreFrame->view();
895     if (!view)
896         return;
897
898     *minimum = *natural = view->contentsHeight();
899 }
900 #endif
901
902 static void updateChildAllocationFromPendingAllocation(GtkWidget* child, void*)
903 {
904     if (!gtk_widget_get_visible(child))
905         return;
906
907     GtkAllocation* allocation = static_cast<GtkAllocation*>(g_object_get_data(G_OBJECT(child), "delayed-allocation"));
908     if (!allocation)
909         return;
910
911     g_object_set_data(G_OBJECT(child), "delayed-allocation", 0);
912     gtk_widget_size_allocate(child, allocation);
913     *allocation = IntRect();
914 }
915
916 static void resizeWebViewFromAllocation(WebKitWebView* webView, GtkAllocation* allocation, bool sizeChanged)
917 {
918     Page* page = core(webView);
919     IntSize oldSize;
920     FrameView* frameView = page->mainFrame().view();
921     if (sizeChanged && frameView) {
922         oldSize = frameView->size();
923         frameView->resize(allocation->width, allocation->height);
924     }
925
926     gtk_container_forall(GTK_CONTAINER(webView), updateChildAllocationFromPendingAllocation, 0);
927
928     if (!sizeChanged)
929         return;
930
931     WebKit::ChromeClient& chromeClient = static_cast<WebKit::ChromeClient&>(page->chrome().client());
932     chromeClient.widgetSizeChanged(oldSize, IntSize(allocation->width, allocation->height));
933     chromeClient.adjustmentWatcher()->updateAdjustmentsFromScrollbars();
934 }
935
936 static void webkit_web_view_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
937 {
938     GtkAllocation oldAllocation;
939     gtk_widget_get_allocation(widget, &oldAllocation);
940     bool sizeChanged = allocation->width != oldAllocation.width || allocation->height != oldAllocation.height;
941
942     GTK_WIDGET_CLASS(webkit_web_view_parent_class)->size_allocate(widget, allocation);
943
944     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
945     if (sizeChanged && !gtk_widget_get_mapped(widget)) {
946         webView->priv->needsResizeOnMap = true;
947         return;
948     }
949     resizeWebViewFromAllocation(webView, allocation, sizeChanged);
950 }
951
952 static void webkitWebViewMap(GtkWidget* widget)
953 {
954     GTK_WIDGET_CLASS(webkit_web_view_parent_class)->map(widget);
955
956     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
957     if (!webView->priv->needsResizeOnMap)
958         return;
959
960     GtkAllocation allocation;
961     gtk_widget_get_allocation(widget, &allocation);
962     resizeWebViewFromAllocation(webView, &allocation, true);
963     webView->priv->needsResizeOnMap = false;
964 }
965
966 static void webkit_web_view_grab_focus(GtkWidget* widget)
967 {
968
969     if (gtk_widget_is_sensitive(widget)) {
970         WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
971         FocusController& focusController = core(webView)->focusController();
972
973         focusController.setActive(true);
974
975         if (focusController.focusedFrame())
976             focusController.setFocused(true);
977         else
978             focusController.setFocusedFrame(&core(webView)->mainFrame());
979     }
980
981     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->grab_focus(widget);
982 }
983
984 static gboolean webkit_web_view_focus_in_event(GtkWidget* widget, GdkEventFocus* event)
985 {
986     // TODO: Improve focus handling as suggested in
987     // http://bugs.webkit.org/show_bug.cgi?id=16910
988     GtkWidget* toplevel = gtk_widget_get_toplevel(widget);
989     if (!widgetIsOnscreenToplevelWindow(toplevel) || !gtk_window_has_toplevel_focus(GTK_WINDOW(toplevel)))
990         return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->focus_in_event(widget, event);
991
992     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
993     FocusController& focusController = core(webView)->focusController();
994
995     focusController.setActive(true);
996     if (focusController.focusedFrame())
997         focusController.setFocused(true);
998     else
999         focusController.setFocusedFrame(&core(webView)->mainFrame());
1000
1001     if (focusController.focusedFrame()->editor().canEdit())
1002         webView->priv->imFilter.notifyFocusedIn();
1003     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->focus_in_event(widget, event);
1004 }
1005
1006 static gboolean webkit_web_view_focus_out_event(GtkWidget* widget, GdkEventFocus* event)
1007 {
1008     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1009
1010     // We may hit this code while destroying the widget, and we might
1011     // no longer have a page, then.
1012     if (Page* page = core(webView)) {
1013         page->focusController().setActive(false);
1014         page->focusController().setFocused(false);
1015     }
1016
1017     webView->priv->imFilter.notifyFocusedOut();
1018     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->focus_out_event(widget, event);
1019 }
1020
1021 static void webkit_web_view_realize(GtkWidget* widget)
1022 {
1023     gtk_widget_set_realized(widget, TRUE);
1024
1025     GtkAllocation allocation;
1026     gtk_widget_get_allocation(widget, &allocation);
1027
1028     GdkWindowAttr attributes;
1029     attributes.window_type = GDK_WINDOW_CHILD;
1030     attributes.x = allocation.x;
1031     attributes.y = allocation.y;
1032     attributes.width = allocation.width;
1033     attributes.height = allocation.height;
1034     attributes.wclass = GDK_INPUT_OUTPUT;
1035     attributes.visual = gtk_widget_get_visual(widget);
1036 #ifdef GTK_API_VERSION_2
1037     attributes.colormap = gtk_widget_get_colormap(widget);
1038 #endif
1039     attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK
1040                             | GDK_EXPOSURE_MASK
1041                             | GDK_BUTTON_PRESS_MASK
1042                             | GDK_BUTTON_RELEASE_MASK
1043                             | GDK_SCROLL_MASK
1044 #if GTK_CHECK_VERSION(3, 3, 18)
1045                             | GDK_SMOOTH_SCROLL_MASK
1046 #endif
1047                             | GDK_POINTER_MOTION_MASK
1048                             | GDK_KEY_PRESS_MASK
1049                             | GDK_KEY_RELEASE_MASK
1050                             | GDK_BUTTON_MOTION_MASK
1051                             | GDK_BUTTON1_MOTION_MASK
1052                             | GDK_BUTTON2_MOTION_MASK
1053                             | GDK_BUTTON3_MOTION_MASK;
1054
1055     gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
1056 #ifdef GTK_API_VERSION_2
1057     attributes_mask |= GDK_WA_COLORMAP;
1058 #endif
1059     GdkWindow* window = gdk_window_new(gtk_widget_get_parent_window(widget), &attributes, attributes_mask);
1060
1061     gtk_widget_set_window(widget, window);
1062     gdk_window_set_user_data(window, widget);
1063
1064 #ifdef GTK_API_VERSION_2
1065     gtk_widget_style_attach(widget);
1066     gtk_style_set_background(gtk_widget_get_style(widget), window, GTK_STATE_NORMAL);
1067 #else
1068     gtk_style_context_set_background(gtk_widget_get_style_context(widget), window);
1069 #endif
1070 }
1071
1072 #ifdef GTK_API_VERSION_2
1073 static void webkit_web_view_set_scroll_adjustments(WebKitWebView* webView, GtkAdjustment* horizontalAdjustment, GtkAdjustment* verticalAdjustment)
1074 {
1075     setHorizontalAdjustment(webView, horizontalAdjustment);
1076     setVerticalAdjustment(webView, verticalAdjustment);
1077 }
1078 #endif
1079
1080 static void webkit_web_view_container_add(GtkContainer* container, GtkWidget* widget)
1081 {
1082     WebKitWebView* webView = WEBKIT_WEB_VIEW(container);
1083     WebKitWebViewPrivate* priv = webView->priv;
1084
1085     priv->children.add(widget);
1086     gtk_widget_set_parent(widget, GTK_WIDGET(container));
1087 }
1088
1089 static void webkit_web_view_container_remove(GtkContainer* container, GtkWidget* widget)
1090 {
1091     WebKitWebView* webView = WEBKIT_WEB_VIEW(container);
1092     WebKitWebViewPrivate* priv = webView->priv;
1093
1094     if (priv->children.contains(widget)) {
1095         gtk_widget_unparent(widget);
1096         priv->children.remove(widget);
1097     }
1098 }
1099
1100 static void webkit_web_view_container_forall(GtkContainer* container, gboolean, GtkCallback callback, gpointer callbackData)
1101 {
1102     WebKitWebView* webView = WEBKIT_WEB_VIEW(container);
1103     WebKitWebViewPrivate* priv = webView->priv;
1104
1105     HashSet<GtkWidget*> children = priv->children;
1106     HashSet<GtkWidget*>::const_iterator end = children.end();
1107     for (HashSet<GtkWidget*>::const_iterator current = children.begin(); current != end; ++current)
1108         (*callback)(*current, callbackData);
1109 }
1110
1111 static WebKitWebView* webkit_web_view_real_create_web_view(WebKitWebView*, WebKitWebFrame*)
1112 {
1113     return 0;
1114 }
1115
1116 static gboolean webkit_web_view_real_web_view_ready(WebKitWebView*)
1117 {
1118     return FALSE;
1119 }
1120
1121 static gboolean webkit_web_view_real_close_web_view(WebKitWebView*)
1122 {
1123     return FALSE;
1124 }
1125
1126 static WebKitNavigationResponse webkit_web_view_real_navigation_requested(WebKitWebView*, WebKitWebFrame*, WebKitNetworkRequest*)
1127 {
1128     return WEBKIT_NAVIGATION_RESPONSE_ACCEPT;
1129 }
1130
1131 static void webkit_web_view_real_window_object_cleared(WebKitWebView*, WebKitWebFrame*, JSGlobalContextRef context, JSObjectRef window_object)
1132 {
1133     notImplemented();
1134 }
1135
1136 static gchar* webkit_web_view_real_choose_file(WebKitWebView*, WebKitWebFrame*, const gchar* old_name)
1137 {
1138     notImplemented();
1139     return g_strdup(old_name);
1140 }
1141
1142 typedef enum {
1143     WEBKIT_SCRIPT_DIALOG_ALERT,
1144     WEBKIT_SCRIPT_DIALOG_CONFIRM,
1145     WEBKIT_SCRIPT_DIALOG_PROMPT
1146  } WebKitScriptDialogType;
1147
1148 static gboolean webkit_web_view_script_dialog(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, WebKitScriptDialogType type, const gchar* defaultValue, gchar** value)
1149 {
1150     GtkMessageType messageType;
1151     GtkButtonsType buttons;
1152     gint defaultResponse;
1153     GtkWidget* window;
1154     GtkWidget* dialog;
1155     GtkWidget* entry = 0;
1156     gboolean didConfirm = FALSE;
1157
1158     switch (type) {
1159     case WEBKIT_SCRIPT_DIALOG_ALERT:
1160         messageType = GTK_MESSAGE_WARNING;
1161         buttons = GTK_BUTTONS_CLOSE;
1162         defaultResponse = GTK_RESPONSE_CLOSE;
1163         break;
1164     case WEBKIT_SCRIPT_DIALOG_CONFIRM:
1165         messageType = GTK_MESSAGE_QUESTION;
1166         buttons = GTK_BUTTONS_OK_CANCEL;
1167         defaultResponse = GTK_RESPONSE_OK;
1168         break;
1169     case WEBKIT_SCRIPT_DIALOG_PROMPT:
1170         messageType = GTK_MESSAGE_QUESTION;
1171         buttons = GTK_BUTTONS_OK_CANCEL;
1172         defaultResponse = GTK_RESPONSE_OK;
1173         break;
1174     default:
1175         g_warning("Unknown value for WebKitScriptDialogType.");
1176         return FALSE;
1177     }
1178
1179     window = gtk_widget_get_toplevel(GTK_WIDGET(webView));
1180     dialog = gtk_message_dialog_new(widgetIsOnscreenToplevelWindow(window) ? GTK_WINDOW(window) : 0,
1181                                     GTK_DIALOG_DESTROY_WITH_PARENT,
1182                                     messageType,
1183                                     buttons,
1184                                     "%s",
1185                                     message);
1186     gchar* title = g_strconcat("JavaScript - ", webkit_web_frame_get_uri(frame), NULL);
1187     gtk_window_set_title(GTK_WINDOW(dialog), title);
1188     g_free(title);
1189
1190     if (type == WEBKIT_SCRIPT_DIALOG_PROMPT) {
1191         entry = gtk_entry_new();
1192         gtk_entry_set_text(GTK_ENTRY(entry), defaultValue);
1193         gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry);
1194         gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
1195         gtk_widget_show(entry);
1196     }
1197
1198     gtk_dialog_set_default_response(GTK_DIALOG(dialog), defaultResponse);
1199     gint response = gtk_dialog_run(GTK_DIALOG(dialog));
1200
1201     switch (response) {
1202     case GTK_RESPONSE_OK:
1203         didConfirm = TRUE;
1204         if (entry)
1205             *value = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
1206         break;
1207     case GTK_RESPONSE_CANCEL:
1208         didConfirm = FALSE;
1209         break;
1210
1211     }
1212     gtk_widget_destroy(GTK_WIDGET(dialog));
1213     return didConfirm;
1214 }
1215
1216 static gboolean webkit_web_view_real_script_alert(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message)
1217 {
1218     webkit_web_view_script_dialog(webView, frame, message, WEBKIT_SCRIPT_DIALOG_ALERT, 0, 0);
1219     return TRUE;
1220 }
1221
1222 static gboolean webkit_web_view_real_script_confirm(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, gboolean* didConfirm)
1223 {
1224     *didConfirm = webkit_web_view_script_dialog(webView, frame, message, WEBKIT_SCRIPT_DIALOG_CONFIRM, 0, 0);
1225     return TRUE;
1226 }
1227
1228 static gboolean webkit_web_view_real_script_prompt(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, const gchar* defaultValue, gchar** value)
1229 {
1230     if (!webkit_web_view_script_dialog(webView, frame, message, WEBKIT_SCRIPT_DIALOG_PROMPT, defaultValue, value))
1231         *value = NULL;
1232     return TRUE;
1233 }
1234
1235 static gboolean webkit_web_view_real_console_message(WebKitWebView* webView, const gchar* message, unsigned int line, const gchar* sourceId)
1236 {
1237     g_message("console message: %s @%d: %s\n", sourceId, line, message);
1238     return TRUE;
1239 }
1240
1241 static void webkit_web_view_real_select_all(WebKitWebView* webView)
1242 {
1243     Frame& frame = core(webView)->focusController().focusedOrMainFrame();
1244     frame.editor().command("SelectAll").execute();
1245 }
1246
1247 static void webkit_web_view_real_cut_clipboard(WebKitWebView* webView)
1248 {
1249     Frame& frame = core(webView)->focusController().focusedOrMainFrame();
1250     frame.editor().command("Cut").execute();
1251 }
1252
1253 static void webkit_web_view_real_copy_clipboard(WebKitWebView* webView)
1254 {
1255     Frame& frame = core(webView)->focusController().focusedOrMainFrame();
1256     frame.editor().command("Copy").execute();
1257 }
1258
1259 static void webkit_web_view_real_undo(WebKitWebView* webView)
1260 {
1261     Frame& frame = core(webView)->focusController().focusedOrMainFrame();
1262     frame.editor().command("Undo").execute();
1263 }
1264
1265 static void webkit_web_view_real_redo(WebKitWebView* webView)
1266 {
1267     Frame& frame = core(webView)->focusController().focusedOrMainFrame();
1268     frame.editor().command("Redo").execute();
1269 }
1270
1271 static gboolean webkit_web_view_real_move_cursor (WebKitWebView* webView, GtkMovementStep step, gint count)
1272 {
1273     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW (webView), FALSE);
1274     g_return_val_if_fail(step == GTK_MOVEMENT_VISUAL_POSITIONS ||
1275                          step == GTK_MOVEMENT_DISPLAY_LINES ||
1276                          step == GTK_MOVEMENT_PAGES ||
1277                          step == GTK_MOVEMENT_BUFFER_ENDS, FALSE);
1278     g_return_val_if_fail(count == 1 || count == -1, FALSE);
1279
1280     ScrollDirection direction;
1281     ScrollGranularity granularity;
1282
1283     switch (step) {
1284     case GTK_MOVEMENT_DISPLAY_LINES:
1285         granularity = ScrollByLine;
1286         if (count == 1)
1287             direction = ScrollDown;
1288         else
1289             direction = ScrollUp;
1290         break;
1291     case GTK_MOVEMENT_VISUAL_POSITIONS:
1292         granularity = ScrollByLine;
1293         if (count == 1)
1294             direction = ScrollRight;
1295         else
1296             direction = ScrollLeft;
1297         break;
1298     case GTK_MOVEMENT_PAGES:
1299         granularity = ScrollByPage;
1300         if (count == 1)
1301             direction = ScrollDown;
1302         else
1303             direction = ScrollUp;
1304         break;
1305     case GTK_MOVEMENT_BUFFER_ENDS:
1306         granularity = ScrollByDocument;
1307         if (count == 1)
1308             direction = ScrollDown;
1309         else
1310             direction = ScrollUp;
1311         break;
1312     default:
1313         g_assert_not_reached();
1314         return false;
1315     }
1316
1317     Frame& frame = core(webView)->focusController().focusedOrMainFrame();
1318     if (!frame.eventHandler().scrollOverflow(direction, granularity))
1319         frame.view()->scroll(direction, granularity);
1320
1321     return true;
1322 }
1323
1324 static void webkit_web_view_real_paste_clipboard(WebKitWebView* webView)
1325 {
1326     Frame& frame = core(webView)->focusController().focusedOrMainFrame();
1327     frame.editor().command("Paste").execute();
1328 }
1329
1330 static gboolean webkit_web_view_real_should_allow_editing_action(WebKitWebView*)
1331 {
1332     return TRUE;
1333 }
1334
1335 static gboolean webkit_web_view_real_entering_fullscreen(WebKitWebView* webView)
1336 {
1337     return FALSE;
1338 }
1339
1340 static gboolean webkit_web_view_real_leaving_fullscreen(WebKitWebView* webView)
1341 {
1342     return FALSE;
1343 }
1344
1345 static void fileChooserDialogResponseCallback(GtkDialog* dialog, gint responseID, WebKitFileChooserRequest* request)
1346 {
1347     GRefPtr<WebKitFileChooserRequest> adoptedRequest = adoptGRef(request);
1348     if (responseID == GTK_RESPONSE_ACCEPT) {
1349         GUniquePtr<GSList> filesList(gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog)));
1350         GRefPtr<GPtrArray> filesArray = adoptGRef(g_ptr_array_new());
1351         for (GSList* file = filesList.get(); file; file = g_slist_next(file))
1352             g_ptr_array_add(filesArray.get(), file->data);
1353         g_ptr_array_add(filesArray.get(), 0);
1354         webkit_file_chooser_request_select_files(adoptedRequest.get(), reinterpret_cast<const gchar* const*>(filesArray->pdata));
1355     }
1356
1357     gtk_widget_destroy(GTK_WIDGET(dialog));
1358 }
1359
1360 static gboolean webkitWebViewRealRunFileChooser(WebKitWebView* webView, WebKitFileChooserRequest* request)
1361 {
1362     GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(webView));
1363     if (!widgetIsOnscreenToplevelWindow(toplevel))
1364         toplevel = 0;
1365
1366     gboolean allowsMultipleSelection = webkit_file_chooser_request_get_select_multiple(request);
1367     GtkWidget* dialog = gtk_file_chooser_dialog_new(allowsMultipleSelection ? _("Select Files") : _("Select File"),
1368                                                     toplevel ? GTK_WINDOW(toplevel) : 0,
1369                                                     GTK_FILE_CHOOSER_ACTION_OPEN,
1370                                                     GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
1371                                                     GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
1372                                                     NULL);
1373
1374     if (GtkFileFilter* filter = webkit_file_chooser_request_get_mime_types_filter(request))
1375         gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
1376     gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), allowsMultipleSelection);
1377
1378     if (const gchar* const* selectedFiles = webkit_file_chooser_request_get_selected_files(request))
1379         gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(dialog), selectedFiles[0]);
1380
1381     g_signal_connect(dialog, "response", G_CALLBACK(fileChooserDialogResponseCallback), g_object_ref(request));
1382     gtk_widget_show(dialog);
1383
1384     return TRUE;
1385 }
1386
1387 static void webkit_web_view_dispose(GObject* object)
1388 {
1389     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
1390     WebKitWebViewPrivate* priv = webView->priv;
1391     WebCore::Page* corePagePtr = priv->corePage;
1392
1393     priv->disposing = TRUE;
1394
1395     // Make sure GtkAdjustmentWatcher won't be reacting to adjustment changes after the
1396     // WebView is destroyed.
1397     setHorizontalAdjustment(webView, 0);
1398     setVerticalAdjustment(webView, 0);
1399
1400     // These smart pointers are cleared manually, because some cleanup operations are
1401     // very sensitive to their value. We may crash if these are done in the wrong order.
1402     priv->backForwardList.clear();
1403
1404     if (priv->corePage) {
1405         webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(object));
1406         core(priv->mainFrame)->loader().detachFromParent();
1407         priv->corePage = 0;
1408     }
1409
1410     if (priv->webSettings) {
1411         g_signal_handlers_disconnect_by_func(priv->webSettings.get(), reinterpret_cast<void*>(webkit_web_view_settings_notify), webView);
1412         priv->webSettings.clear();
1413     }
1414
1415     if (priv->currentMenu) {
1416         gtk_widget_destroy(GTK_WIDGET(priv->currentMenu));
1417         priv->currentMenu = 0;
1418     }
1419
1420     priv->webInspector.clear();
1421     priv->viewportAttributes.clear();
1422     priv->webWindowFeatures.clear();
1423     priv->mainResource.clear();
1424     priv->subResources.clear();
1425     priv->targetList.clear();
1426
1427     G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object);
1428
1429     // We need to run the parent's dispose before destroying the Page
1430     // pointer. Otherwise we're triggering the deletion of
1431     // InspectorFrontendClient before it can clean up itself.
1432     delete corePagePtr;
1433 }
1434
1435 static void webkit_web_view_finalize(GObject* object)
1436 {
1437     // We need to manually call the destructor here, since this object's memory is managed
1438     // by GLib. This calls all C++ members' destructors and prevents memory leaks.
1439     WEBKIT_WEB_VIEW(object)->priv->~WebKitWebViewPrivate();
1440     G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object);
1441 }
1442
1443 static gboolean webkit_signal_accumulator_object_handled(GSignalInvocationHint* ihint, GValue* returnAccu, const GValue* handlerReturn, gpointer dummy)
1444 {
1445     gpointer newWebView = g_value_get_object(handlerReturn);
1446     g_value_set_object(returnAccu, newWebView);
1447
1448     // Continue if we don't have a newWebView
1449     return !newWebView;
1450 }
1451
1452 static gboolean webkit_navigation_request_handled(GSignalInvocationHint* ihint, GValue* returnAccu, const GValue* handlerReturn, gpointer dummy)
1453 {
1454     WebKitNavigationResponse navigationResponse = (WebKitNavigationResponse)g_value_get_enum(handlerReturn);
1455     g_value_set_enum(returnAccu, navigationResponse);
1456
1457     if (navigationResponse != WEBKIT_NAVIGATION_RESPONSE_ACCEPT)
1458         return FALSE;
1459
1460     return TRUE;
1461 }
1462
1463 #if HAVE(ACCESSIBILITY)
1464 static AtkObject* webkit_web_view_get_accessible(GtkWidget* widget)
1465 {
1466     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1467     if (!core(webView))
1468         return 0;
1469
1470     if (!AXObjectCache::accessibilityEnabled())
1471         AXObjectCache::enableAccessibility();
1472
1473     Frame& coreFrame = core(webView)->mainFrame();
1474
1475     Document* doc = coreFrame.document();
1476     if (!doc)
1477         return 0;
1478
1479     AccessibilityObject* rootAccessible = doc->axObjectCache()->rootObject();
1480     if (!rootAccessible)
1481         return 0;
1482
1483     AtkObject* axRoot = rootAccessible->wrapper();
1484     if (!axRoot || !ATK_IS_OBJECT(axRoot))
1485         return 0;
1486
1487     // Ensure the parent is set to make top-down and bottom-up navigation work.
1488     GtkWidget* parentWidget = gtk_widget_get_parent(widget);
1489     AtkObject* axParent = parentWidget ? gtk_widget_get_accessible(parentWidget) : 0;
1490     if (axParent)
1491         atk_object_set_parent(axRoot, axParent);
1492
1493     return axRoot;
1494 }
1495 #endif
1496
1497 static double screenDPI(GdkScreen* screen)
1498 {
1499     // gdk_screen_get_resolution() returns -1 when no DPI is set.
1500     double dpi = gdk_screen_get_resolution(screen);
1501     if (dpi != -1)
1502         return dpi;
1503
1504     static const double kMillimetresPerInch = 25.4;
1505     double diagonalSizeInPixels = hypot(gdk_screen_get_width(screen), gdk_screen_get_height(screen));
1506     double diagonalSizeInInches = hypot(gdk_screen_get_width_mm(screen), gdk_screen_get_height_mm(screen)) / kMillimetresPerInch;
1507     return diagonalSizeInPixels / diagonalSizeInInches;
1508 }
1509
1510 static gdouble webViewGetDPI(WebKitWebView* webView)
1511 {
1512     if (webView->priv->webSettings->priv->enforce96DPI)
1513         return 96;
1514
1515     static const double defaultDPI = 96;
1516     GdkScreen* screen = gtk_widget_has_screen(GTK_WIDGET(webView)) ? gtk_widget_get_screen(GTK_WIDGET(webView)) : gdk_screen_get_default();
1517     return screen ? screenDPI(screen) : defaultDPI;
1518 }
1519
1520 static inline gint webViewConvertFontSizeToPixels(WebKitWebView* webView, double fontSize)
1521 {
1522     return fontSize / 72.0 * webViewGetDPI(webView);
1523 }
1524
1525 static void webkit_web_view_screen_changed(GtkWidget* widget, GdkScreen* previousScreen)
1526 {
1527     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1528     WebKitWebViewPrivate* priv = webView->priv;
1529
1530     if (priv->disposing)
1531         return;
1532
1533     WebKitWebSettings* webSettings = priv->webSettings.get();
1534     Settings& settings = core(webView)->settings();
1535     guint defaultFontSize, defaultMonospaceFontSize, minimumFontSize, minimumLogicalFontSize;
1536
1537     g_object_get(webSettings,
1538                  "default-font-size", &defaultFontSize,
1539                  "default-monospace-font-size", &defaultMonospaceFontSize,
1540                  "minimum-font-size", &minimumFontSize,
1541                  "minimum-logical-font-size", &minimumLogicalFontSize,
1542                  NULL);
1543
1544     settings.setDefaultFontSize(webViewConvertFontSizeToPixels(webView, defaultFontSize));
1545     settings.setDefaultFixedFontSize(webViewConvertFontSizeToPixels(webView, defaultMonospaceFontSize));
1546     settings.setMinimumFontSize(webViewConvertFontSizeToPixels(webView, minimumFontSize));
1547     settings.setMinimumLogicalFontSize(webViewConvertFontSizeToPixels(webView, minimumLogicalFontSize));
1548 }
1549
1550 #if ENABLE(DRAG_SUPPORT)
1551 static void webkit_web_view_drag_end(GtkWidget* widget, GdkDragContext* context)
1552 {
1553     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1554     if (!webView->priv->dragAndDropHelper.handleDragEnd(context))
1555         return;
1556
1557     Frame& frame = core(webView)->focusController().focusedOrMainFrame();
1558
1559     // Synthesize a button release event to send with the drag end action.
1560     GUniquePtr<GdkEvent> event(gdk_event_new(GDK_BUTTON_RELEASE));
1561     int x, y, xRoot, yRoot;
1562     GdkModifierType modifiers = static_cast<GdkModifierType>(0);
1563 #ifdef GTK_API_VERSION_2
1564     GdkDisplay* display = gdk_display_get_default();
1565     gdk_display_get_pointer(display, 0, &xRoot, &yRoot, &modifiers);
1566     event->button.window = gdk_display_get_window_at_pointer(display, &x, &y);
1567 #else
1568     GdkDevice* device = gdk_drag_context_get_device(context);
1569     event->button.window = gdk_device_get_window_at_position(device, &x, &y);
1570     gdk_device_get_position(device, 0, &xRoot, &yRoot);
1571 #endif
1572
1573     if (event->button.window)
1574         g_object_ref(event->button.window);
1575     event->button.x = x;
1576     event->button.y = y;
1577     event->button.x_root = xRoot;
1578     event->button.y_root = yRoot;
1579     event->button.state = modifiers;
1580
1581     PlatformMouseEvent platformEvent(&event->button);
1582     frame.eventHandler().dragSourceEndedAt(platformEvent, gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context)));
1583 }
1584
1585 static void webkit_web_view_drag_data_get(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selectionData, guint info, guint)
1586 {
1587     WEBKIT_WEB_VIEW(widget)->priv->dragAndDropHelper.handleGetDragData(context, selectionData, info);
1588 }
1589
1590 static void dragExitedCallback(GtkWidget* widget, DragData& dragData, bool dropHappened)
1591 {
1592     // Don't call dragExited if we have just received a drag-drop signal. This
1593     // happens in the case of a successful drop onto the view.
1594     if (!dropHappened)
1595         core(WEBKIT_WEB_VIEW(widget))->dragController().dragExited(dragData);
1596     core(WEBKIT_WEB_VIEW(widget))->dragController().dragEnded();
1597 }
1598
1599 static void webkit_web_view_drag_leave(GtkWidget* widget, GdkDragContext* context, guint time)
1600 {
1601     WEBKIT_WEB_VIEW(widget)->priv->dragAndDropHelper.handleDragLeave(context, dragExitedCallback);
1602 }
1603
1604 static gboolean webkit_web_view_drag_motion(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time)
1605 {
1606     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1607     IntPoint position(x, y);
1608     DataObjectGtk* dataObject = webView->priv->dragAndDropHelper.handleDragMotion(context, position, time);
1609     if (!dataObject)
1610         return TRUE;
1611
1612     DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
1613     DragOperation operation = core(webView)->dragController().dragUpdated(dragData).operation;
1614     gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time);
1615     return TRUE;
1616 }
1617
1618 static void webkit_web_view_drag_data_received(GtkWidget* widget, GdkDragContext* context, gint x, gint y, GtkSelectionData* selectionData, guint info, guint time)
1619 {
1620     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1621     IntPoint position;
1622     DataObjectGtk* dataObject = webView->priv->dragAndDropHelper.handleDragDataReceived(context, selectionData, info, position);
1623     if (!dataObject)
1624         return;
1625
1626     DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
1627     DragOperation operation = core(webView)->dragController().dragEntered(dragData).operation;
1628     gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time);
1629 }
1630
1631 static gboolean webkit_web_view_drag_drop(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time)
1632 {
1633     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1634     DataObjectGtk* dataObject = webView->priv->dragAndDropHelper.handleDragDrop(context);
1635     if (!dataObject)
1636         return FALSE;
1637
1638     IntPoint position(x, y);
1639     DragData dragData(dataObject, position, convertWidgetPointToScreenPoint(widget, position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
1640     core(webView)->dragController().performDrag(dragData);
1641     gtk_drag_finish(context, TRUE, FALSE, time);
1642     return TRUE;
1643 }
1644 #endif // ENABLE(DRAG_SUPPORT)
1645
1646 static gboolean webkit_web_view_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip)
1647 {
1648     WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(widget)->priv;
1649
1650     if (keyboard_mode) {
1651         WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1652
1653         // Get the title of the current focused element.
1654         Frame& coreFrame = core(webView)->focusController().focusedOrMainFrame();
1655
1656         Node* node = getFocusedNode(&coreFrame);
1657         if (!node)
1658             return FALSE;
1659
1660         for (Node* titleNode = node; titleNode; titleNode = titleNode->parentNode()) {
1661             if (titleNode->isElementNode()) {
1662                 String title = toElement(titleNode)->title();
1663                 if (!title.isEmpty()) {
1664                     if (FrameView* view = coreFrame.view()) {
1665                         GdkRectangle area = view->contentsToWindow(node->pixelSnappedBoundingBox());
1666                         gtk_tooltip_set_tip_area(tooltip, &area);
1667                     }
1668                     gtk_tooltip_set_text(tooltip, title.utf8().data());
1669
1670                     return TRUE;
1671                 }
1672             }
1673         }
1674
1675         return FALSE;
1676     }
1677
1678     if (priv->tooltipText.length() > 0) {
1679         if (!keyboard_mode) {
1680             if (!priv->tooltipArea.isEmpty()) {
1681                 GdkRectangle area = priv->tooltipArea;
1682                 gtk_tooltip_set_tip_area(tooltip, &area);
1683             } else
1684                 gtk_tooltip_set_tip_area(tooltip, 0);
1685         }
1686         gtk_tooltip_set_text(tooltip, priv->tooltipText.data());
1687         return TRUE;
1688     }
1689
1690     return FALSE;
1691 }
1692
1693 static gboolean webkit_web_view_show_help(GtkWidget* widget, GtkWidgetHelpType help_type)
1694 {
1695     if (help_type == GTK_WIDGET_HELP_TOOLTIP)
1696         gtk_widget_set_has_tooltip(widget, TRUE);
1697
1698     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->show_help(widget, help_type);
1699 }
1700
1701 static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
1702 {
1703     GtkBindingSet* binding_set;
1704
1705     webkitInit();
1706
1707     /*
1708      * Signals
1709      */
1710
1711     /**
1712      * WebKitWebView::create-web-view:
1713      * @web_view: the object on which the signal is emitted
1714      * @frame: the #WebKitWebFrame
1715      *
1716      * Emitted when the creation of a new window is requested.
1717      * If this signal is handled the signal handler should return the
1718      * newly created #WebKitWebView.
1719      *
1720      * The new #WebKitWebView should not be displayed to the user
1721      * until the #WebKitWebView::web-view-ready signal is emitted.
1722      *
1723      * The signal handlers should not try to deal with the reference count for
1724      * the new #WebKitWebView. The widget to which the widget is added will
1725      * handle that.
1726      *
1727      * Return value: (transfer full): a newly allocated #WebKitWebView, or %NULL
1728      *
1729      * Since: 1.0.3
1730      */
1731     webkit_web_view_signals[CREATE_WEB_VIEW] = g_signal_new("create-web-view",
1732         G_TYPE_FROM_CLASS(webViewClass),
1733         (GSignalFlags)G_SIGNAL_RUN_LAST,
1734         G_STRUCT_OFFSET (WebKitWebViewClass, create_web_view),
1735         webkit_signal_accumulator_object_handled,
1736         NULL,
1737         webkit_marshal_OBJECT__OBJECT,
1738         WEBKIT_TYPE_WEB_VIEW , 1,
1739         WEBKIT_TYPE_WEB_FRAME);
1740
1741     /**
1742      * WebKitWebView::web-view-ready:
1743      * @web_view: the object on which the signal is emitted
1744      *
1745      * Emitted after #WebKitWebView::create-web-view when the new #WebKitWebView
1746      * should be displayed to the user. When this signal is emitted
1747      * all the information about how the window should look, including
1748      * size, position, whether the location, status and scroll bars
1749      * should be displayed, is already set on the
1750      * #WebKitWebWindowFeatures object contained by the #WebKitWebView.
1751      *
1752      * Notice that some of that information may change during the life
1753      * time of the window, so you may want to connect to the ::notify
1754      * signal of the #WebKitWebWindowFeatures object to handle those.
1755      *
1756      * Return value: %TRUE to stop handlers from being invoked for the event or
1757      * %FALSE to propagate the event furter
1758      *
1759      * Since: 1.0.3
1760      */
1761     webkit_web_view_signals[WEB_VIEW_READY] = g_signal_new("web-view-ready",
1762         G_TYPE_FROM_CLASS(webViewClass),
1763         (GSignalFlags)G_SIGNAL_RUN_LAST,
1764         G_STRUCT_OFFSET (WebKitWebViewClass, web_view_ready),
1765         g_signal_accumulator_true_handled,
1766         NULL,
1767         webkit_marshal_BOOLEAN__VOID,
1768         G_TYPE_BOOLEAN, 0);
1769
1770     /**
1771      * WebKitWebView::close-web-view:
1772      * @web_view: the object on which the signal is emitted
1773      *
1774      * Emitted when closing a #WebKitWebView is requested. This occurs when a
1775      * call is made from JavaScript's window.close function. The default
1776      * signal handler does not do anything. It is the owner's responsibility
1777      * to hide or delete the web view, if necessary.
1778      *
1779      * Return value: %TRUE to stop handlers from being invoked for the event or
1780      * %FALSE to propagate the event furter
1781      *
1782      * Since: 1.1.11
1783      */
1784     webkit_web_view_signals[CLOSE_WEB_VIEW] = g_signal_new("close-web-view",
1785         G_TYPE_FROM_CLASS(webViewClass),
1786         (GSignalFlags)G_SIGNAL_RUN_LAST,
1787         G_STRUCT_OFFSET (WebKitWebViewClass, close_web_view),
1788         g_signal_accumulator_true_handled,
1789         NULL,
1790         webkit_marshal_BOOLEAN__VOID,
1791         G_TYPE_BOOLEAN, 0);
1792
1793     /**
1794      * WebKitWebView::navigation-requested:
1795      * @web_view: the object on which the signal is emitted
1796      * @frame: the #WebKitWebFrame that required the navigation
1797      * @request: a #WebKitNetworkRequest
1798      *
1799      * Emitted when @frame requests a navigation to another page.
1800      *
1801      * Return value: a #WebKitNavigationResponse
1802      *
1803      * Deprecated: Use WebKitWebView::navigation-policy-decision-requested
1804      * instead
1805      */
1806     webkit_web_view_signals[NAVIGATION_REQUESTED] = g_signal_new("navigation-requested",
1807         G_TYPE_FROM_CLASS(webViewClass),
1808         (GSignalFlags)G_SIGNAL_RUN_LAST,
1809         G_STRUCT_OFFSET (WebKitWebViewClass, navigation_requested),
1810         webkit_navigation_request_handled,
1811         NULL,
1812         webkit_marshal_ENUM__OBJECT_OBJECT,
1813         WEBKIT_TYPE_NAVIGATION_RESPONSE, 2,
1814         WEBKIT_TYPE_WEB_FRAME,
1815         WEBKIT_TYPE_NETWORK_REQUEST);
1816
1817     /**
1818      * WebKitWebView::new-window-policy-decision-requested:
1819      * @web_view: the object on which the signal is emitted
1820      * @frame: the #WebKitWebFrame that required the navigation
1821      * @request: a #WebKitNetworkRequest
1822      * @navigation_action: a #WebKitWebNavigationAction
1823      * @policy_decision: a #WebKitWebPolicyDecision
1824      *
1825      * Emitted when @frame requests opening a new window. With this
1826      * signal the browser can use the context of the request to decide
1827      * about the new window. If the request is not handled the default
1828      * behavior is to allow opening the new window to load the URI,
1829      * which will cause a create-web-view signal emission where the
1830      * browser handles the new window action but without information
1831      * of the context that caused the navigation. The following
1832      * navigation-policy-decision-requested emissions will load the
1833      * page after the creation of the new window just with the
1834      * information of this new navigation context, without any
1835      * information about the action that made this new window to be
1836      * opened.
1837      *
1838      * Notice that if you return TRUE, meaning that you handled the
1839      * signal, you are expected to have decided what to do, by calling
1840      * webkit_web_policy_decision_ignore(),
1841      * webkit_web_policy_decision_use(), or
1842      * webkit_web_policy_decision_download() on the @policy_decision
1843      * object.
1844      *
1845      * Return value: %TRUE if a decision was made, %FALSE to have the
1846      * default behavior apply
1847      *
1848      * Since: 1.1.4
1849      */
1850     webkit_web_view_signals[NEW_WINDOW_POLICY_DECISION_REQUESTED] = g_signal_new("new-window-policy-decision-requested",
1851         G_TYPE_FROM_CLASS(webViewClass),
1852         (GSignalFlags)G_SIGNAL_RUN_LAST,
1853         0,
1854         g_signal_accumulator_true_handled,
1855         NULL,
1856         webkit_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT_OBJECT,
1857         G_TYPE_BOOLEAN, 4,
1858         WEBKIT_TYPE_WEB_FRAME,
1859         WEBKIT_TYPE_NETWORK_REQUEST,
1860         WEBKIT_TYPE_WEB_NAVIGATION_ACTION,
1861         WEBKIT_TYPE_WEB_POLICY_DECISION);
1862
1863     /**
1864      * WebKitWebView::navigation-policy-decision-requested:
1865      * @web_view: the object on which the signal is emitted
1866      * @frame: the #WebKitWebFrame that required the navigation
1867      * @request: a #WebKitNetworkRequest
1868      * @navigation_action: a #WebKitWebNavigationAction
1869      * @policy_decision: a #WebKitWebPolicyDecision
1870      *
1871      * Emitted when @frame requests a navigation to another page.
1872      * If this signal is not handled, the default behavior is to allow the
1873      * navigation.
1874      *
1875      * Notice that if you return TRUE, meaning that you handled the
1876      * signal, you are expected to have decided what to do, by calling
1877      * webkit_web_policy_decision_ignore(),
1878      * webkit_web_policy_decision_use(), or
1879      * webkit_web_policy_decision_download() on the @policy_decision
1880      * object.
1881      *
1882      * Return value: %TRUE if a decision was made, %FALSE to have the
1883      * default behavior apply
1884      *
1885      * Since: 1.0.3
1886      */
1887     webkit_web_view_signals[NAVIGATION_POLICY_DECISION_REQUESTED] = g_signal_new("navigation-policy-decision-requested",
1888         G_TYPE_FROM_CLASS(webViewClass),
1889         (GSignalFlags)G_SIGNAL_RUN_LAST,
1890         0,
1891         g_signal_accumulator_true_handled,
1892         NULL,
1893         webkit_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT_OBJECT,
1894         G_TYPE_BOOLEAN, 4,
1895         WEBKIT_TYPE_WEB_FRAME,
1896         WEBKIT_TYPE_NETWORK_REQUEST,
1897         WEBKIT_TYPE_WEB_NAVIGATION_ACTION,
1898         WEBKIT_TYPE_WEB_POLICY_DECISION);
1899
1900     /**
1901      * WebKitWebView::mime-type-policy-decision-requested:
1902      * @web_view: the object on which the signal is emitted
1903      * @frame: the #WebKitWebFrame that required the policy decision
1904      * @request: a WebKitNetworkRequest
1905      * @mimetype: the MIME type attempted to load
1906      * @policy_decision: a #WebKitWebPolicyDecision
1907      *
1908      * Decide whether or not to display the given MIME type.  If this
1909      * signal is not handled, the default behavior is to show the
1910      * content of the requested URI if WebKit can show this MIME
1911      * type and the content disposition is not a download; if WebKit
1912      * is not able to show the MIME type nothing happens.
1913      *
1914      * Notice that if you return TRUE, meaning that you handled the
1915      * signal, you are expected to be aware of the "Content-Disposition"
1916      * header. A value of "attachment" usually indicates a download
1917      * regardless of the MIME type, see also
1918      * soup_message_headers_get_content_disposition(). And you must call
1919      * webkit_web_policy_decision_ignore(),
1920      * webkit_web_policy_decision_use(), or
1921      * webkit_web_policy_decision_download() on the @policy_decision
1922      * object.
1923      *
1924      * Return value: %TRUE if a decision was made, %FALSE to have the
1925      * default behavior apply
1926      *
1927      * Since: 1.0.3
1928      */
1929     webkit_web_view_signals[MIME_TYPE_POLICY_DECISION_REQUESTED] = g_signal_new("mime-type-policy-decision-requested",
1930         G_TYPE_FROM_CLASS(webViewClass),
1931         (GSignalFlags)G_SIGNAL_RUN_LAST,
1932         0,
1933         g_signal_accumulator_true_handled,
1934         NULL,
1935         webkit_marshal_BOOLEAN__OBJECT_OBJECT_STRING_OBJECT,
1936         G_TYPE_BOOLEAN, 4,
1937         WEBKIT_TYPE_WEB_FRAME,
1938         WEBKIT_TYPE_NETWORK_REQUEST,
1939         G_TYPE_STRING,
1940         WEBKIT_TYPE_WEB_POLICY_DECISION);
1941
1942     /**
1943      * WebKitWebView::window-object-cleared:
1944      * @web_view: the object on which the signal is emitted
1945      * @frame: the #WebKitWebFrame to which @window_object belongs
1946      * @context: the #JSGlobalContextRef holding the global object and other
1947      * execution state; equivalent to the return value of
1948      * webkit_web_frame_get_global_context(@frame)
1949      * @window_object: the #JSObjectRef representing the frame's JavaScript
1950      * window object
1951      *
1952      * Emitted when the JavaScript window object in a #WebKitWebFrame has been
1953      * cleared in preparation for a new load. This is the preferred place to
1954      * set custom properties on the window object using the JavaScriptCore API.
1955      */
1956     webkit_web_view_signals[WINDOW_OBJECT_CLEARED] = g_signal_new("window-object-cleared",
1957         G_TYPE_FROM_CLASS(webViewClass),
1958         (GSignalFlags)G_SIGNAL_RUN_LAST,
1959         G_STRUCT_OFFSET (WebKitWebViewClass, window_object_cleared),
1960         NULL,
1961         NULL,
1962         webkit_marshal_VOID__OBJECT_POINTER_POINTER,
1963         G_TYPE_NONE, 3,
1964         WEBKIT_TYPE_WEB_FRAME,
1965         G_TYPE_POINTER,
1966         G_TYPE_POINTER);
1967
1968     /**
1969      * WebKitWebView::download-requested:
1970      * @web_view: the object on which the signal is emitted
1971      * @download: a #WebKitDownload object that lets you control the
1972      * download process
1973      *
1974      * A new Download is being requested. By default, if the signal is
1975      * not handled, the download is cancelled. If you handle the download
1976      * and call webkit_download_set_destination_uri(), it will be
1977      * started for you. If you need to set the destination asynchronously
1978      * you are responsible for starting or cancelling it yourself.
1979      *
1980      * If you intend to handle downloads yourself rather than using
1981      * the #WebKitDownload helper object you must handle this signal,
1982      * and return %FALSE.
1983      *
1984      * Also, keep in mind that the default policy for WebKitGTK+ is to
1985      * ignore files with a MIME type that it does not know how to
1986      * handle, which means this signal won't be emitted in the default
1987      * setup. One way to trigger downloads is to connect to
1988      * WebKitWebView::mime-type-policy-decision-requested and call
1989      * webkit_web_policy_decision_download() on the
1990      * #WebKitWebPolicyDecision in the parameter list for the kind of
1991      * files you want your application to download (a common solution
1992      * is to download anything that WebKit can't handle, which you can
1993      * figure out by using webkit_web_view_can_show_mime_type()).
1994      *
1995      * Return value: TRUE if the download should be performed, %FALSE to
1996      * cancel it
1997      *
1998      * Since: 1.1.2
1999      */
2000     webkit_web_view_signals[DOWNLOAD_REQUESTED] = g_signal_new("download-requested",
2001         G_TYPE_FROM_CLASS(webViewClass),
2002         (GSignalFlags)G_SIGNAL_RUN_LAST,
2003         0,
2004         g_signal_accumulator_true_handled,
2005         NULL,
2006         webkit_marshal_BOOLEAN__OBJECT,
2007         G_TYPE_BOOLEAN, 1,
2008         WEBKIT_TYPE_DOWNLOAD);
2009
2010     /**
2011      * WebKitWebView::load-started:
2012      * @web_view: the object on which the signal is emitted
2013      * @frame: the frame going to do the load
2014      *
2015      * When a #WebKitWebFrame begins to load this signal is emitted.
2016      *
2017      * Deprecated: Use the "load-status" property instead.
2018      */
2019     webkit_web_view_signals[LOAD_STARTED] = g_signal_new("load-started",
2020         G_TYPE_FROM_CLASS(webViewClass),
2021         (GSignalFlags)G_SIGNAL_RUN_LAST,
2022         0,
2023         NULL,
2024         NULL,
2025         g_cclosure_marshal_VOID__OBJECT,
2026         G_TYPE_NONE, 1,
2027         WEBKIT_TYPE_WEB_FRAME);
2028
2029     /**
2030      * WebKitWebView::load-committed:
2031      * @web_view: the object on which the signal is emitted
2032      * @frame: the main frame that received the first data
2033      *
2034      * When a #WebKitWebFrame loaded the first data this signal is emitted.
2035      *
2036      * Deprecated: Use the "load-status" property instead.
2037      */
2038     webkit_web_view_signals[LOAD_COMMITTED] = g_signal_new("load-committed",
2039         G_TYPE_FROM_CLASS(webViewClass),
2040         (GSignalFlags)G_SIGNAL_RUN_LAST,
2041         0,
2042         NULL,
2043         NULL,
2044         g_cclosure_marshal_VOID__OBJECT,
2045         G_TYPE_NONE, 1,
2046         WEBKIT_TYPE_WEB_FRAME);
2047
2048
2049     /**
2050      * WebKitWebView::load-progress-changed:
2051      * @web_view: the #WebKitWebView
2052      * @progress: the global progress
2053      *
2054      * Deprecated: Use the "progress" property instead.
2055      */
2056     webkit_web_view_signals[LOAD_PROGRESS_CHANGED] = g_signal_new("load-progress-changed",
2057         G_TYPE_FROM_CLASS(webViewClass),
2058         (GSignalFlags)G_SIGNAL_RUN_LAST,
2059         0,
2060         NULL,
2061         NULL,
2062         g_cclosure_marshal_VOID__INT,
2063         G_TYPE_NONE, 1,
2064         G_TYPE_INT);
2065
2066     /**
2067      * WebKitWebView::load-error:
2068      * @web_view: the object on which the signal is emitted
2069      * @web_frame: the #WebKitWebFrame
2070      * @uri: the URI that triggered the error
2071      * @web_error: the #GError that was triggered
2072      *
2073      * An error occurred while loading. By default, if the signal is not
2074      * handled, the @web_view will display a stock error page. You need to
2075      * handle the signal if you want to provide your own error page.
2076      *
2077      * Since: 1.1.6
2078      *
2079      * Return value: %TRUE to stop other handlers from being invoked for the
2080      * event. %FALSE to propagate the event further.
2081      */
2082     webkit_web_view_signals[LOAD_ERROR] = g_signal_new("load-error",
2083         G_TYPE_FROM_CLASS(webViewClass),
2084         (GSignalFlags)(G_SIGNAL_RUN_LAST),
2085         0,
2086         g_signal_accumulator_true_handled,
2087         NULL,
2088         webkit_marshal_BOOLEAN__OBJECT_STRING_BOXED,
2089         G_TYPE_BOOLEAN, 3,
2090         WEBKIT_TYPE_WEB_FRAME,
2091         G_TYPE_STRING,
2092         G_TYPE_ERROR);
2093
2094     /**
2095      * WebKitWebView::load-finished:
2096      * @web_view: the #WebKitWebView
2097      * @frame: the #WebKitWebFrame
2098      *
2099      * Deprecated: Use the "load-status" property instead.
2100      */
2101     webkit_web_view_signals[LOAD_FINISHED] = g_signal_new("load-finished",
2102         G_TYPE_FROM_CLASS(webViewClass),
2103         (GSignalFlags)G_SIGNAL_RUN_LAST,
2104         0,
2105         NULL,
2106         NULL,
2107         g_cclosure_marshal_VOID__OBJECT,
2108         G_TYPE_NONE, 1,
2109         WEBKIT_TYPE_WEB_FRAME);
2110
2111     /**
2112      * WebKitWebView::onload-event:
2113      * @web_view: the object on which the signal is emitted
2114      * @frame: the frame
2115      *
2116      * When a #WebKitWebFrame receives an onload event this signal is emitted.
2117      */
2118     webkit_web_view_signals[ONLOAD_EVENT] = g_signal_new("onload-event",
2119         G_TYPE_FROM_CLASS(webViewClass),
2120         (GSignalFlags)G_SIGNAL_RUN_LAST,
2121         0,
2122         NULL,
2123         NULL,
2124         g_cclosure_marshal_VOID__OBJECT,
2125         G_TYPE_NONE, 1,
2126         WEBKIT_TYPE_WEB_FRAME);
2127
2128     /**
2129      * WebKitWebView::title-changed:
2130      * @web_view: the object on which the signal is emitted
2131      * @frame: the main frame
2132      * @title: the new title
2133      *
2134      * When a #WebKitWebFrame changes the document title this signal is emitted.
2135      *
2136      * Deprecated: 1.1.4: Use "notify::title" instead.
2137      */
2138     webkit_web_view_signals[TITLE_CHANGED] = g_signal_new("title-changed",
2139         G_TYPE_FROM_CLASS(webViewClass),
2140         (GSignalFlags)G_SIGNAL_RUN_LAST,
2141         0,
2142         NULL,
2143         NULL,
2144         webkit_marshal_VOID__OBJECT_STRING,
2145         G_TYPE_NONE, 2,
2146         WEBKIT_TYPE_WEB_FRAME,
2147         G_TYPE_STRING);
2148
2149     /**
2150      * WebKitWebView::hovering-over-link:
2151      * @web_view: the object on which the signal is emitted
2152      * @title: the link's title
2153      * @uri: the URI the link points to
2154      *
2155      * When the cursor is over a link, this signal is emitted.
2156      */
2157     webkit_web_view_signals[HOVERING_OVER_LINK] = g_signal_new("hovering-over-link",
2158         G_TYPE_FROM_CLASS(webViewClass),
2159         (GSignalFlags)G_SIGNAL_RUN_LAST,
2160         0,
2161         NULL,
2162         NULL,
2163         webkit_marshal_VOID__STRING_STRING,
2164         G_TYPE_NONE, 2,
2165         G_TYPE_STRING,
2166         G_TYPE_STRING);
2167
2168     /**
2169      * WebKitWebView::populate-popup:
2170      * @web_view: the object on which the signal is emitted
2171      * @menu: the context menu
2172      *
2173      * When a context menu is about to be displayed this signal is emitted.
2174      *
2175      * Add menu items to #menu to extend the context menu.
2176      *
2177      * Deprecated: 1.10: Use #WebKitWebView::context-menu signal instead.
2178      */
2179     webkit_web_view_signals[POPULATE_POPUP] = g_signal_new("populate-popup",
2180         G_TYPE_FROM_CLASS(webViewClass),
2181         (GSignalFlags)G_SIGNAL_RUN_LAST,
2182         0,
2183         NULL,
2184         NULL,
2185         g_cclosure_marshal_VOID__OBJECT,
2186         G_TYPE_NONE, 1,
2187         GTK_TYPE_MENU);
2188
2189     /**
2190      * WebKitWebView::print-requested:
2191      * @web_view: the object in which the signal is emitted
2192      * @web_frame: the frame that is requesting to be printed
2193      *
2194      * Emitted when printing is requested by the frame, usually
2195      * because of a javascript call. When handling this signal you
2196      * should call webkit_web_frame_print_full() or
2197      * webkit_web_frame_print() to do the actual printing.
2198      *
2199      * The default handler will present a print dialog and carry a
2200      * print operation. Notice that this means that if you intend to
2201      * ignore a print request you must connect to this signal, and
2202      * return %TRUE.
2203      *
2204      * Return value: %TRUE if the print request has been handled, %FALSE if
2205      * the default handler should run
2206      *
2207      * Since: 1.1.5
2208      */
2209     webkit_web_view_signals[PRINT_REQUESTED] = g_signal_new("print-requested",
2210         G_TYPE_FROM_CLASS(webViewClass),
2211         (GSignalFlags)G_SIGNAL_RUN_LAST,
2212         0,
2213         g_signal_accumulator_true_handled,
2214         NULL,
2215         webkit_marshal_BOOLEAN__OBJECT,
2216         G_TYPE_BOOLEAN, 1,
2217         WEBKIT_TYPE_WEB_FRAME);
2218
2219     webkit_web_view_signals[STATUS_BAR_TEXT_CHANGED] = g_signal_new("status-bar-text-changed",
2220         G_TYPE_FROM_CLASS(webViewClass),
2221         (GSignalFlags)G_SIGNAL_RUN_LAST,
2222         0,
2223         NULL,
2224         NULL,
2225         g_cclosure_marshal_VOID__STRING,
2226         G_TYPE_NONE, 1,
2227         G_TYPE_STRING);
2228
2229     /**
2230      * WebKitWebView::icon-loaded:
2231      * @web_view: the object on which the signal is emitted
2232      * @icon_uri: the URI for the icon
2233      *
2234      * This signal is emitted when the main frame has got a favicon.
2235      * See WebKitIconDatabase::icon-loaded if you want to keep track of
2236      * icons for child frames.
2237      *
2238      * Since: 1.1.18
2239      */
2240     webkit_web_view_signals[ICON_LOADED] = g_signal_new("icon-loaded",
2241         G_TYPE_FROM_CLASS(webViewClass),
2242         (GSignalFlags)G_SIGNAL_RUN_LAST,
2243         0,
2244         NULL,
2245         NULL,
2246         g_cclosure_marshal_VOID__STRING,
2247         G_TYPE_NONE, 1,
2248         G_TYPE_STRING);
2249
2250     /**
2251      * WebKitWebView::console-message:
2252      * @web_view: the object on which the signal is emitted
2253      * @message: the message text
2254      * @line: the line where the error occured
2255      * @source_id: the source id
2256      *
2257      * A JavaScript console message was created.
2258      *
2259      * Return value: %TRUE to stop other handlers from being invoked for the
2260      * event. %FALSE to propagate the event further.
2261      */
2262     webkit_web_view_signals[CONSOLE_MESSAGE] = g_signal_new("console-message",
2263         G_TYPE_FROM_CLASS(webViewClass),
2264         (GSignalFlags)G_SIGNAL_RUN_LAST,
2265         G_STRUCT_OFFSET(WebKitWebViewClass, console_message),
2266         g_signal_accumulator_true_handled,
2267         NULL,
2268         webkit_marshal_BOOLEAN__STRING_INT_STRING,
2269         G_TYPE_BOOLEAN, 3,
2270         G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
2271
2272     /**
2273      * WebKitWebView::script-alert:
2274      * @web_view: the object on which the signal is emitted
2275      * @frame: the relevant frame
2276      * @message: the message text
2277      *
2278      * A JavaScript alert dialog was created.
2279      *
2280      * Return value: %TRUE to stop other handlers from being invoked for the
2281      * event. %FALSE to propagate the event further.
2282      */
2283     webkit_web_view_signals[SCRIPT_ALERT] = g_signal_new("script-alert",
2284         G_TYPE_FROM_CLASS(webViewClass),
2285         (GSignalFlags)G_SIGNAL_RUN_LAST,
2286         G_STRUCT_OFFSET(WebKitWebViewClass, script_alert),
2287         g_signal_accumulator_true_handled,
2288         NULL,
2289         webkit_marshal_BOOLEAN__OBJECT_STRING,
2290         G_TYPE_BOOLEAN, 2,
2291         WEBKIT_TYPE_WEB_FRAME, G_TYPE_STRING);
2292
2293     /**
2294      * WebKitWebView::script-confirm:
2295      * @web_view: the object on which the signal is emitted
2296      * @frame: the relevant frame
2297      * @message: the message text
2298      * @confirmed: a pointer to a #gboolean where the callback should store
2299      * whether the user confirmed the dialog, when handling this signal
2300      *
2301      * A JavaScript confirm dialog was created, providing Yes and No buttons.
2302      *
2303      * Return value: %TRUE to stop other handlers from being invoked for the
2304      * event. %FALSE to propagate the event further.
2305      */
2306     webkit_web_view_signals[SCRIPT_CONFIRM] = g_signal_new("script-confirm",
2307         G_TYPE_FROM_CLASS(webViewClass),
2308         (GSignalFlags)G_SIGNAL_RUN_LAST,
2309         G_STRUCT_OFFSET(WebKitWebViewClass, script_confirm),
2310         g_signal_accumulator_true_handled,
2311         NULL,
2312         webkit_marshal_BOOLEAN__OBJECT_STRING_POINTER,
2313         G_TYPE_BOOLEAN, 3,
2314         WEBKIT_TYPE_WEB_FRAME, G_TYPE_STRING, G_TYPE_POINTER);
2315
2316     /**
2317      * WebKitWebView::script-prompt:
2318      * @web_view: the object on which the signal is emitted
2319      * @frame: the relevant frame
2320      * @message: the message text
2321      * @default: the default value
2322      * @text: To be filled with the return value or NULL if the dialog was cancelled.
2323      *
2324      * A JavaScript prompt dialog was created, providing an entry to input text.
2325      *
2326      * Return value: %TRUE to stop other handlers from being invoked for the
2327      * event. %FALSE to propagate the event further.
2328      */
2329     webkit_web_view_signals[SCRIPT_PROMPT] = g_signal_new("script-prompt",
2330         G_TYPE_FROM_CLASS(webViewClass),
2331         (GSignalFlags)G_SIGNAL_RUN_LAST,
2332         G_STRUCT_OFFSET(WebKitWebViewClass, script_prompt),
2333         g_signal_accumulator_true_handled,
2334         NULL,
2335         webkit_marshal_BOOLEAN__OBJECT_STRING_STRING_STRING,
2336         G_TYPE_BOOLEAN, 4,
2337         WEBKIT_TYPE_WEB_FRAME, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
2338
2339     /**
2340      * WebKitWebView::select-all:
2341      * @web_view: the object which received the signal
2342      *
2343      * The #WebKitWebView::select-all signal is a keybinding signal which gets emitted to
2344      * select the complete contents of the text view.
2345      *
2346      * The default bindings for this signal is Ctrl-a.
2347      */
2348     webkit_web_view_signals[::SELECT_ALL] = g_signal_new("select-all",
2349         G_TYPE_FROM_CLASS(webViewClass),
2350         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2351         G_STRUCT_OFFSET(WebKitWebViewClass, select_all),
2352         NULL, NULL,
2353         g_cclosure_marshal_VOID__VOID,
2354         G_TYPE_NONE, 0);
2355
2356     /**
2357      * WebKitWebView::cut-clipboard:
2358      * @web_view: the object which received the signal
2359      *
2360      * The #WebKitWebView::cut-clipboard signal is a keybinding signal which gets emitted to
2361      * cut the selection to the clipboard.
2362      *
2363      * The default bindings for this signal are Ctrl-x and Shift-Delete.
2364      */
2365     webkit_web_view_signals[CUT_CLIPBOARD] = g_signal_new("cut-clipboard",
2366         G_TYPE_FROM_CLASS(webViewClass),
2367         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2368         G_STRUCT_OFFSET(WebKitWebViewClass, cut_clipboard),
2369         NULL, NULL,
2370         g_cclosure_marshal_VOID__VOID,
2371         G_TYPE_NONE, 0);
2372
2373     /**
2374      * WebKitWebView::copy-clipboard:
2375      * @web_view: the object which received the signal
2376      *
2377      * The #WebKitWebView::copy-clipboard signal is a keybinding signal which gets emitted to
2378      * copy the selection to the clipboard.
2379      *
2380      * The default bindings for this signal are Ctrl-c and Ctrl-Insert.
2381      */
2382     webkit_web_view_signals[COPY_CLIPBOARD] = g_signal_new("copy-clipboard",
2383         G_TYPE_FROM_CLASS(webViewClass),
2384         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2385         G_STRUCT_OFFSET(WebKitWebViewClass, copy_clipboard),
2386         NULL, NULL,
2387         g_cclosure_marshal_VOID__VOID,
2388         G_TYPE_NONE, 0);
2389
2390     /**
2391      * WebKitWebView::paste-clipboard:
2392      * @web_view: the object which received the signal
2393      *
2394      * The #WebKitWebView::paste-clipboard signal is a keybinding signal which gets emitted to
2395      * paste the contents of the clipboard into the Web view.
2396      *
2397      * The default bindings for this signal are Ctrl-v and Shift-Insert.
2398      */
2399     webkit_web_view_signals[PASTE_CLIPBOARD] = g_signal_new("paste-clipboard",
2400         G_TYPE_FROM_CLASS(webViewClass),
2401         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2402         G_STRUCT_OFFSET(WebKitWebViewClass, paste_clipboard),
2403         NULL, NULL,
2404         g_cclosure_marshal_VOID__VOID,
2405         G_TYPE_NONE, 0);
2406
2407     /**
2408      * WebKitWebView::undo:
2409      * @web_view: the object which received the signal
2410      *
2411      * The #WebKitWebView::undo signal is a keybinding signal which gets emitted to
2412      * undo the last editing command.
2413      *
2414      * The default binding for this signal is Ctrl-z
2415      *
2416      * Since: 1.1.14
2417      */
2418     webkit_web_view_signals[UNDO] = g_signal_new("undo",
2419         G_TYPE_FROM_CLASS(webViewClass),
2420         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2421         G_STRUCT_OFFSET(WebKitWebViewClass, undo),
2422         NULL, NULL,
2423         g_cclosure_marshal_VOID__VOID,
2424         G_TYPE_NONE, 0);
2425
2426     /**
2427      * WebKitWebView::redo:
2428      * @web_view: the object which received the signal
2429      *
2430      * The #WebKitWebView::redo signal is a keybinding signal which gets emitted to
2431      * redo the last editing command.
2432      *
2433      * The default binding for this signal is Ctrl-Shift-z
2434      *
2435      * Since: 1.1.14
2436      */
2437     webkit_web_view_signals[REDO] = g_signal_new("redo",
2438         G_TYPE_FROM_CLASS(webViewClass),
2439         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2440         G_STRUCT_OFFSET(WebKitWebViewClass, redo),
2441         NULL, NULL,
2442         g_cclosure_marshal_VOID__VOID,
2443         G_TYPE_NONE, 0);
2444
2445     /**
2446      * WebKitWebView::move-cursor:
2447      * @web_view: the object which received the signal
2448      * @step: the type of movement, one of #GtkMovementStep
2449      * @count: an integer indicating the subtype of movement. Currently
2450      *         the permitted values are '1' = forward, '-1' = backwards.
2451      *
2452      * The #WebKitWebView::move-cursor will be emitted to apply the
2453      * cursor movement described by its parameters to the @view.
2454      *
2455      * Return value: %TRUE or %FALSE
2456      *
2457      * Since: 1.1.4
2458      */
2459     webkit_web_view_signals[MOVE_CURSOR] = g_signal_new("move-cursor",
2460         G_TYPE_FROM_CLASS(webViewClass),
2461         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2462         G_STRUCT_OFFSET(WebKitWebViewClass, move_cursor),
2463         NULL, NULL,
2464         webkit_marshal_BOOLEAN__ENUM_INT,
2465         G_TYPE_BOOLEAN, 2,
2466         GTK_TYPE_MOVEMENT_STEP,
2467         G_TYPE_INT);
2468
2469     /**
2470      * WebKitWebView::create-plugin-widget:
2471      * @web_view: the object which received the signal
2472      * @mime_type: the mimetype of the requested object
2473      * @uri: the URI to load
2474      * @param: a #GHashTable with additional attributes (strings)
2475      *
2476      * The #WebKitWebView::create-plugin-widget signal will be emitted to
2477      * create a plugin widget for embed or object HTML tags. This
2478      * allows to embed a GtkWidget as a plugin into HTML content. In
2479      * case of a textual selection of the GtkWidget WebCore will attempt
2480      * to set the property value of "webkit-widget-is-selected". This can
2481      * be used to draw a visual indicator of the selection.
2482      *
2483      * Return value: (transfer full): a new #GtkWidget, or %NULL
2484      *
2485      * Since: 1.1.8
2486      */
2487     webkit_web_view_signals[PLUGIN_WIDGET] = g_signal_new("create-plugin-widget",
2488         G_TYPE_FROM_CLASS(webViewClass),
2489         (GSignalFlags) (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2490         0,
2491         webkit_signal_accumulator_object_handled,
2492         NULL,
2493         webkit_marshal_OBJECT__STRING_STRING_POINTER,
2494         GTK_TYPE_WIDGET, 3,
2495         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_HASH_TABLE);
2496
2497     /**
2498      * WebKitWebView::database-quota-exceeded:
2499      * @web_view: the object which received the signal
2500      * @frame: the relevant frame
2501      * @database: the #WebKitWebDatabase which exceeded the quota of its #WebKitSecurityOrigin
2502      *
2503      * The #WebKitWebView::database-quota-exceeded signal will be emitted when
2504      * a Web Database exceeds the quota of its security origin. This signal
2505      * may be used to increase the size of the quota before the originating
2506      * operation fails.
2507      *
2508      * Since: 1.1.14
2509      */
2510     webkit_web_view_signals[DATABASE_QUOTA_EXCEEDED] = g_signal_new("database-quota-exceeded",
2511         G_TYPE_FROM_CLASS(webViewClass),
2512         (GSignalFlags) (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2513         0,
2514         NULL, NULL,
2515         webkit_marshal_VOID__OBJECT_OBJECT,
2516         G_TYPE_NONE, 2,
2517         G_TYPE_OBJECT, G_TYPE_OBJECT);
2518
2519     /**
2520      * WebKitWebView::resource-request-starting:
2521      * @web_view: the object which received the signal
2522      * @web_frame: the #WebKitWebFrame whose load dispatched this request
2523      * @web_resource: an empty #WebKitWebResource object
2524      * @request: the #WebKitNetworkRequest that will be dispatched
2525      * @response: the #WebKitNetworkResponse representing the redirect
2526      * response, if any
2527      *
2528      * Emitted when a request is about to be sent. You can modify the
2529      * request while handling this signal. You can set the URI in the
2530      * #WebKitNetworkRequest object itself, and add/remove/replace
2531      * headers using the #SoupMessage object it carries, if it is
2532      * present. See webkit_network_request_get_message(). Setting the
2533      * request URI to "about:blank" will effectively cause the request
2534      * to load nothing, and can be used to disable the loading of
2535      * specific resources.
2536      *
2537      * Notice that information about an eventual redirect is available
2538      * in @response's #SoupMessage, not in the #SoupMessage carried by
2539      * the @request. If @response is %NULL, then this is not a
2540      * redirected request.
2541      *
2542      * The #WebKitWebResource object will be the same throughout all
2543      * the lifetime of the resource, but the contents may change from
2544      * inbetween signal emissions.
2545      *
2546      * Since: 1.1.14
2547      */
2548     webkit_web_view_signals[RESOURCE_REQUEST_STARTING] = g_signal_new("resource-request-starting",
2549         G_TYPE_FROM_CLASS(webViewClass),
2550         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2551         0,
2552         NULL, NULL,
2553         webkit_marshal_VOID__OBJECT_OBJECT_OBJECT_OBJECT,
2554         G_TYPE_NONE, 4,
2555         WEBKIT_TYPE_WEB_FRAME,
2556         WEBKIT_TYPE_WEB_RESOURCE,
2557         WEBKIT_TYPE_NETWORK_REQUEST,
2558         WEBKIT_TYPE_NETWORK_RESPONSE);
2559
2560     /**
2561      * WebKitWebView::geolocation-policy-decision-requested:
2562      * @web_view: the object on which the signal is emitted
2563      * @frame: the frame that requests permission
2564      * @policy_decision: a WebKitGeolocationPolicyDecision
2565      *
2566      * This signal is emitted when a @frame wants to obtain the user's
2567      * location. The decision can be made asynchronously, but you must
2568      * call g_object_ref() the @policy_decision, and return %TRUE if
2569      * you are going to handle the request. To actually make the
2570      * decision you need to call webkit_geolocation_policy_allow() or
2571      * webkit_geolocation_policy_deny() on @policy_decision.
2572      *
2573      * Since: 1.1.23
2574      */
2575     webkit_web_view_signals[GEOLOCATION_POLICY_DECISION_REQUESTED] = g_signal_new("geolocation-policy-decision-requested",
2576         G_TYPE_FROM_CLASS(webViewClass),
2577         (GSignalFlags)(G_SIGNAL_RUN_LAST),
2578         0,
2579         NULL, NULL,
2580         webkit_marshal_BOOLEAN__OBJECT_OBJECT,
2581         G_TYPE_BOOLEAN, 2,
2582         WEBKIT_TYPE_WEB_FRAME,
2583         WEBKIT_TYPE_GEOLOCATION_POLICY_DECISION);
2584
2585     /**
2586      * WebKitWebView::geolocation-policy-decision-cancelled:
2587      * @web_view: the object on which the signal is emitted
2588      * @frame: the frame that cancels geolocation request.
2589      *
2590      * When a @frame wants to cancel geolocation permission it had requested
2591      * before.
2592      *
2593      * Since: 1.1.23
2594      */
2595     webkit_web_view_signals[GEOLOCATION_POLICY_DECISION_CANCELLED] = g_signal_new("geolocation-policy-decision-cancelled",
2596         G_TYPE_FROM_CLASS(webViewClass),
2597         (GSignalFlags)(G_SIGNAL_RUN_LAST),
2598         0,
2599         NULL, NULL,
2600         g_cclosure_marshal_VOID__OBJECT,
2601         G_TYPE_NONE, 1,
2602         WEBKIT_TYPE_WEB_FRAME);
2603
2604     /*
2605      * DOM-related signals. These signals are experimental, for now,
2606      * and may change API and ABI. Their comments lack one * on
2607      * purpose, to make them not be catched by gtk-doc.
2608      */
2609
2610     /**
2611      * WebKitWebView::document-load-finished:
2612      * @web_view: the object which received the signal
2613      * @web_frame: the #WebKitWebFrame whose load dispatched this request
2614      *
2615      * Emitted when the DOM document object load is finished for the
2616      * given frame.
2617      */
2618     webkit_web_view_signals[DOCUMENT_LOAD_FINISHED] = g_signal_new("document-load-finished",
2619         G_TYPE_FROM_CLASS(webViewClass),
2620         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2621         0,
2622         NULL, NULL,
2623         g_cclosure_marshal_VOID__OBJECT,
2624         G_TYPE_NONE, 1,
2625         WEBKIT_TYPE_WEB_FRAME);
2626
2627     /**
2628      * WebKitWebView::frame-created:
2629      * @web_view: the object which received the signal
2630      * @web_frame: the #WebKitWebFrame which was just created.
2631      *
2632      * Emitted when a WebKitWebView has created a new frame. This signal will
2633      * be emitted for all sub-frames created during page load. It will not be
2634      * emitted for the main frame, which originates in the WebKitWebView constructor
2635      * and may be accessed at any time using webkit_web_view_get_main_frame.
2636      *
2637      * Since: 1.3.4
2638      */
2639     webkit_web_view_signals[FRAME_CREATED] = g_signal_new("frame-created",
2640         G_TYPE_FROM_CLASS(webViewClass),
2641         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2642         0,
2643         NULL, NULL,
2644         g_cclosure_marshal_VOID__OBJECT,
2645         G_TYPE_NONE, 1,
2646         WEBKIT_TYPE_WEB_FRAME);
2647
2648      /**
2649      * WebKitWebView::run-file-chooser:
2650      * @web_view: the #WebKitWebView on which the signal is emitted
2651      * @request: a #WebKitFileChooserRequest
2652      *
2653      * This signal is emitted when the user interacts with a &lt;input
2654      * type='file' /&gt; HTML element, requesting from WebKit to show
2655      * a dialog to select one or more files to be uploaded. To let the
2656      * application know the details of the file chooser, as well as to
2657      * allow the client application to either cancel the request or
2658      * perform an actual selection of files, the signal will pass an
2659      * instance of the #WebKitFileChooserRequest in the @request
2660      * argument.
2661      *
2662      * The default signal handler will asynchronously run a regular
2663      * #GtkFileChooserDialog for the user to interact with.
2664      *
2665      * If this signal is to be handled asynchronously, you must
2666      * call g_object_ref() on the @request, and return %TRUE to indicate
2667      * that the request is being handled. When you are ready to complete the
2668      * request, call webkit_file_chooser_request_select_files().
2669      *
2670      * Returns: %TRUE to stop other handlers from being invoked for the event.
2671      *   %FALSE to propagate the event further.
2672      *
2673      */
2674     webkit_web_view_signals[RUN_FILE_CHOOSER] = g_signal_new("run-file-chooser",
2675         G_TYPE_FROM_CLASS(webViewClass),
2676         G_SIGNAL_RUN_LAST,
2677         G_STRUCT_OFFSET(WebKitWebViewClass, run_file_chooser),
2678         g_signal_accumulator_true_handled, 0 /* accumulator data */,
2679         webkit_marshal_BOOLEAN__OBJECT,
2680         G_TYPE_BOOLEAN, 1, /* number of parameters */
2681         WEBKIT_TYPE_FILE_CHOOSER_REQUEST);
2682
2683     /**
2684      * WebKitWebView::should-begin-editing:
2685      * @web_view: the #WebKitWebView on which the signal is emitted
2686      * @range: a #WebKitDOMRange
2687      *
2688      */
2689     webkit_web_view_signals[SHOULD_BEGIN_EDITING] = g_signal_new("should-begin-editing",
2690         G_TYPE_FROM_CLASS(webViewClass),
2691         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2692         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action),
2693         g_signal_accumulator_first_wins, 0,
2694         webkit_marshal_BOOLEAN__OBJECT,
2695         G_TYPE_BOOLEAN, 1,
2696         WEBKIT_TYPE_DOM_RANGE);
2697
2698     /**
2699      * WebKitWebView::should-end-editing:
2700      * @web_view: the #WebKitWebView on which the signal is emitted
2701      * @range: a #WebKitDOMRange
2702      *
2703      */
2704     webkit_web_view_signals[SHOULD_END_EDITING] = g_signal_new("should-end-editing",
2705         G_TYPE_FROM_CLASS(webViewClass),
2706         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2707         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action),
2708         g_signal_accumulator_first_wins, 0,
2709         webkit_marshal_BOOLEAN__OBJECT,
2710         G_TYPE_BOOLEAN, 1,
2711         WEBKIT_TYPE_DOM_RANGE);
2712
2713     /**
2714      * WebKitWebView::should-insert-node:
2715      * @web_view: the #WebKitWebView on which the signal is emitted
2716      * @node: a #WebKitDOMNode
2717      * @range: a #WebKitDOMRange
2718      * @action: a #WebKitInsertAction
2719      *
2720      */
2721     webkit_web_view_signals[SHOULD_INSERT_NODE] = g_signal_new("should-insert-node",
2722         G_TYPE_FROM_CLASS(webViewClass),
2723         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2724         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action),
2725         g_signal_accumulator_first_wins, 0,
2726         webkit_marshal_BOOLEAN__OBJECT_OBJECT_ENUM,
2727         G_TYPE_BOOLEAN, 3,
2728         WEBKIT_TYPE_DOM_NODE,
2729         WEBKIT_TYPE_DOM_RANGE,
2730         WEBKIT_TYPE_INSERT_ACTION);
2731
2732     /**
2733      * WebKitWebView::should-insert-text:
2734      * @web_view: the #WebKitWebView on which the signal is emitted
2735      * @string: a string
2736      * @range: a #WebKitDOMRange
2737      * @action: a #WebKitInsertAction
2738      *
2739      */
2740     webkit_web_view_signals[SHOULD_INSERT_TEXT] = g_signal_new("should-insert-text",
2741         G_TYPE_FROM_CLASS(webViewClass),
2742         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2743         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action),
2744         g_signal_accumulator_first_wins, 0,
2745         webkit_marshal_BOOLEAN__STRING_OBJECT_ENUM,
2746         G_TYPE_BOOLEAN, 3,
2747         G_TYPE_STRING,
2748         WEBKIT_TYPE_DOM_RANGE,
2749         WEBKIT_TYPE_INSERT_ACTION);
2750
2751     // Only exists for GTK+ API compatibility.
2752     /**
2753      * WebKitWebView::should-delete-range:
2754      * @web_view: the #WebKitWebView on which the signal is emitted
2755      * @range: a #WebKitDOMRange
2756      *
2757      */
2758     webkit_web_view_signals[SHOULD_DELETE_RANGE] = g_signal_new("should-delete-range",
2759         G_TYPE_FROM_CLASS(webViewClass),
2760         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2761         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action),
2762         g_signal_accumulator_first_wins, 0,
2763         webkit_marshal_BOOLEAN__OBJECT,
2764         G_TYPE_BOOLEAN, 1,
2765         WEBKIT_TYPE_DOM_RANGE);
2766
2767     /**
2768      * WebKitWebView::should-show-delete-interface-for-element:
2769      * @web_view: the #WebKitWebView on which the signal is emitted
2770      * @element: a #WebKitDOMHTMLElement
2771      *
2772      */
2773     webkit_web_view_signals[SHOULD_SHOW_DELETE_INTERFACE_FOR_ELEMENT] = g_signal_new("should-show-delete-interface-for-element",
2774         G_TYPE_FROM_CLASS(webViewClass),
2775         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2776         0,
2777         g_signal_accumulator_first_wins, 0,
2778         webkit_marshal_BOOLEAN__OBJECT,
2779         G_TYPE_BOOLEAN, 1,
2780         WEBKIT_TYPE_DOM_HTML_ELEMENT);
2781
2782     /**
2783      * WebKitWebView::should-change-selected-range:
2784      * @web_view: the #WebKitWebView on which the signal is emitted
2785      * @fromRange: a #WebKitDOMRange
2786      * @toRange: a #WebKitDOMRange
2787      * @affinity: a #WebKitSelectionAffinity
2788      * @stillSelecting: bool
2789      *
2790      */
2791     webkit_web_view_signals[SHOULD_CHANGE_SELECTED_RANGE] = g_signal_new("should-change-selected-range",
2792         G_TYPE_FROM_CLASS(webViewClass),
2793         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2794         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action),
2795         g_signal_accumulator_first_wins, 0,
2796         webkit_marshal_BOOLEAN__OBJECT_OBJECT_ENUM_BOOLEAN,
2797         G_TYPE_BOOLEAN, 4,
2798         WEBKIT_TYPE_DOM_RANGE,
2799         WEBKIT_TYPE_DOM_RANGE,
2800         WEBKIT_TYPE_SELECTION_AFFINITY,
2801         G_TYPE_BOOLEAN);
2802
2803     /**
2804      * WebKitWebView::should-apply-style:
2805      * @web_view: the #WebKitWebView on which the signal is emitted
2806      * @set: a #WebKitDOMCSSStyleDeclaration
2807      * @range: a #WebKitDOMRange
2808      *
2809      */
2810     webkit_web_view_signals[SHOULD_APPLY_STYLE] = g_signal_new("should-apply-style",
2811         G_TYPE_FROM_CLASS(webViewClass),
2812         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2813         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action),
2814         g_signal_accumulator_first_wins, 0,
2815         webkit_marshal_BOOLEAN__OBJECT_OBJECT,
2816         G_TYPE_BOOLEAN, 2,
2817         WEBKIT_TYPE_DOM_CSS_STYLE_DECLARATION,
2818         WEBKIT_TYPE_DOM_RANGE);
2819
2820     /**
2821      * WebKitWebView::editing-began:
2822      * @web_view: the #WebKitWebView on which the signal is emitted
2823      *
2824      */
2825     webkit_web_view_signals[EDITING_BEGAN] = g_signal_new("editing-began",
2826         G_TYPE_FROM_CLASS(webViewClass),
2827         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2828         0,
2829         0, 0,
2830         g_cclosure_marshal_VOID__VOID,
2831         G_TYPE_NONE, 0);
2832
2833     /**
2834      * WebKitWebView::user-changed-contents:
2835      * @web_view: the #WebKitWebView on which the signal is emitted
2836      *
2837      */
2838     webkit_web_view_signals[USER_CHANGED_CONTENTS] = g_signal_new("user-changed-contents",
2839         G_TYPE_FROM_CLASS(webViewClass),
2840         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2841         0,
2842         0, 0,
2843         g_cclosure_marshal_VOID__VOID,
2844         G_TYPE_NONE, 0);
2845
2846     /**
2847      * WebKitWebView::editing-ended:
2848      * @web_view: the #WebKitWebView on which the signal is emitted
2849      *
2850      */
2851     webkit_web_view_signals[EDITING_ENDED] = g_signal_new("editing-ended",
2852         G_TYPE_FROM_CLASS(webViewClass),
2853         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2854         0,
2855         0, 0,
2856         g_cclosure_marshal_VOID__VOID,
2857         G_TYPE_NONE, 0);
2858
2859     /**
2860      * WebKitWebView::selection-changed:
2861      * @web_view: the #WebKitWebView on which the signal is emitted
2862      *
2863      */
2864     webkit_web_view_signals[SELECTION_CHANGED] = g_signal_new("selection-changed",
2865         G_TYPE_FROM_CLASS(webViewClass),
2866         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2867         0,
2868         0, 0,
2869         g_cclosure_marshal_VOID__VOID,
2870         G_TYPE_NONE, 0);
2871
2872     /*
2873      * WebKitWebView::viewport-attributes-recompute-requested:
2874      * @web_view: the object which received the signal
2875      * @viewport_attributes: the #WebKitViewportAttributes which has the viewport attributes.
2876      *
2877      * The #WebKitWebView::viewport-attributes-recompute-requested
2878      * signal will be emitted when a page with a viewport meta tag
2879      * loads and when webkit_viewport_attributes_recompute is called.
2880      *
2881      * The #WebKitViewportAttributes will have device size, available size,
2882      * desktop width, and device DPI pre-filled by values that make sense
2883      * for the current screen and widget, but you can override those values
2884      * if you have special requirements (for instance, if you made your
2885      * widget bigger than the available visible area, you should override
2886      * the available-width and available-height properties to the actual
2887      * visible area).
2888      *
2889      * Since: 1.3.8
2890      */
2891     webkit_web_view_signals[VIEWPORT_ATTRIBUTES_RECOMPUTE_REQUESTED] = g_signal_new("viewport-attributes-recompute-requested",
2892         G_TYPE_FROM_CLASS(webViewClass),
2893         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2894         0,
2895         0, 0,
2896         g_cclosure_marshal_VOID__OBJECT,
2897         G_TYPE_NONE, 1,
2898             WEBKIT_TYPE_VIEWPORT_ATTRIBUTES);
2899
2900     /*
2901      * WebKitWebView::viewport-attributes-changed:
2902      * @web_view: the object which received the signal
2903      * @viewport_attributes: the #WebKitViewportAttributes which has the viewport attributes.
2904      *
2905      * The #WebKitWebView::viewport-attributes-changed signal will be emitted
2906      * after the emission of #WebKitWebView::viewport-attributes-recompute-requested
2907      * and the subsequent viewport attribute recomputation. At this point,
2908      * if the #WebKitViewportAttributes are valid, the viewport attributes are available.
2909      *
2910      * Since: 1.3.8
2911      */
2912     webkit_web_view_signals[VIEWPORT_ATTRIBUTES_CHANGED] = g_signal_new("viewport-attributes-changed",
2913         G_TYPE_FROM_CLASS(webViewClass),
2914         (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2915         0,
2916         0, 0,
2917         g_cclosure_marshal_VOID__OBJECT,
2918         G_TYPE_NONE, 1,
2919         WEBKIT_TYPE_VIEWPORT_ATTRIBUTES);
2920
2921     /**
2922      * WebKitWebView::entering-fullscreen:
2923      * @web_view: the #WebKitWebView on which the signal is emitted.
2924      * @element: the #WebKitDOMHTMLElement which has requested full screen display.
2925      *
2926      * Emitted when JavaScript code calls
2927      * <function>element.webkitRequestFullScreen</function>. If the
2928      * signal is not handled the WebView will proceed to full screen
2929      * its top level window. This signal can be used by client code to
2930      * request permission to the user prior doing the full screen
2931      * transition and eventually prepare the top-level window
2932      * (e.g. hide some widgets that would otherwise be part of the
2933      * full screen window).
2934      *
2935      * Returns: %TRUE to stop other handlers from being invoked for the event.
2936      *    %FALSE to continue emission of the event.
2937      *
2938      * Since: 1.9.0
2939      */
2940     webkit_web_view_signals[ENTERING_FULLSCREEN] = g_signal_new("entering-fullscreen",
2941         G_TYPE_FROM_CLASS(webViewClass),
2942         G_SIGNAL_RUN_LAST,
2943         G_STRUCT_OFFSET(WebKitWebViewClass, entering_fullscreen),
2944         g_signal_accumulator_true_handled, 0,
2945         webkit_marshal_BOOLEAN__OBJECT,
2946         G_TYPE_BOOLEAN, 1, WEBKIT_TYPE_DOM_HTML_ELEMENT);
2947
2948
2949     /**
2950      * WebKitWebView::leaving-fullscreen:
2951      * @web_view: the #WebKitWebView on which the signal is emitted.
2952      * @element: the #WebKitDOMHTMLElement which is currently displayed full screen.
2953      *
2954      * Emitted when the WebView is about to restore its top level
2955      * window out of its full screen state. This signal can be used by
2956      * client code to restore widgets hidden during the
2957      * entering-fullscreen stage for instance.
2958      *
2959      * Returns: %TRUE to stop other handlers from being invoked for the event.
2960      *    %FALSE to continue emission of the event.
2961      *
2962      * Since: 1.9.0
2963      */
2964     webkit_web_view_signals[LEAVING_FULLSCREEN] = g_signal_new("leaving-fullscreen",
2965         G_TYPE_FROM_CLASS(webViewClass),
2966         G_SIGNAL_RUN_LAST,
2967         G_STRUCT_OFFSET(WebKitWebViewClass, leaving_fullscreen),
2968         g_signal_accumulator_true_handled, 0,
2969         webkit_marshal_BOOLEAN__OBJECT,
2970         G_TYPE_BOOLEAN, 1, WEBKIT_TYPE_DOM_HTML_ELEMENT);
2971
2972     /**
2973      * WebKitWebView::resource-response-received:
2974      * @web_view: the object which received the signal
2975      * @web_frame: the #WebKitWebFrame the response was received for
2976      * @web_resource: the #WebKitWebResource being loaded
2977      * @response: the #WebKitNetworkResponse that was received
2978      *
2979      * Emitted when the first byte of data arrives
2980      *
2981      * Since: 1.7.5
2982      */
2983     webkit_web_view_signals[RESOURCE_RESPONSE_RECEIVED] = g_signal_new("resource-response-received",
2984         G_TYPE_FROM_CLASS(webViewClass),
2985         G_SIGNAL_RUN_LAST,
2986         0,
2987         0, 0,
2988         webkit_marshal_VOID__OBJECT_OBJECT_OBJECT,
2989         G_TYPE_NONE, 3,
2990         WEBKIT_TYPE_WEB_FRAME,
2991         WEBKIT_TYPE_WEB_RESOURCE,
2992         WEBKIT_TYPE_NETWORK_RESPONSE);
2993
2994     /**
2995      * WebKitWebView::resource-load-finished:
2996      * @web_view: the object which received the signal
2997      * @web_frame: the #WebKitWebFrame the response was received for
2998      * @web_resource: the #WebKitWebResource that was loaded
2999      *
3000      * Emitted when all the data for the resource was loaded
3001      *
3002      * Since: 1.7.5
3003      */
3004     webkit_web_view_signals[RESOURCE_LOAD_FINISHED] = g_signal_new("resource-load-finished",
3005         G_TYPE_FROM_CLASS(webViewClass),
3006         G_SIGNAL_RUN_LAST,
3007         0,
3008         0, 0,
3009         webkit_marshal_VOID__OBJECT_OBJECT,
3010         G_TYPE_NONE, 2,
3011         WEBKIT_TYPE_WEB_FRAME,
3012         WEBKIT_TYPE_WEB_RESOURCE);
3013
3014     /**
3015      * WebKitWebView::resource-content-length-received:
3016      * @web_view: the object which received the signal
3017      * @web_frame: the #WebKitWebFrame the response was received for
3018      * @web_resource: the #WebKitWebResource that was loaded
3019      * @length_received: the amount of data received since the last signal emission
3020      *
3021      * Emitted when new resource data has been received. The
3022      * @length_received variable stores the amount of bytes received
3023      * since the last time this signal was emitted. This is useful to
3024      * provide progress information about the resource load operation.
3025      *
3026      * Since: 1.7.5
3027      */
3028     webkit_web_view_signals[RESOURCE_CONTENT_LENGTH_RECEIVED] = g_signal_new("resource-content-length-received",
3029         G_TYPE_FROM_CLASS(webViewClass),
3030         G_SIGNAL_RUN_LAST,
3031         0,
3032         0, 0,
3033         webkit_marshal_VOID__OBJECT_OBJECT_INT,
3034         G_TYPE_NONE, 3,
3035         WEBKIT_TYPE_WEB_FRAME,
3036         WEBKIT_TYPE_WEB_RESOURCE,
3037         G_TYPE_INT);
3038
3039     /**
3040      * WebKitWebView::resource-load-failed:
3041      * @web_view: the object which received the signal
3042      * @web_frame: the #WebKitWebFrame the response was received for
3043      * @web_resource: the #WebKitWebResource that was loaded
3044      * @error: the #GError that was triggered
3045      *
3046      * Invoked when a resource failed to load
3047      *
3048      * Since: 1.7.5
3049      */
3050     webkit_web_view_signals[RESOURCE_LOAD_FAILED] = g_signal_new("resource-load-failed",
3051         G_TYPE_FROM_CLASS(webViewClass),
3052         G_SIGNAL_RUN_LAST,
3053         0,
3054         0, 0,
3055         webkit_marshal_VOID__OBJECT_OBJECT_BOXED,
3056         G_TYPE_NONE, 3,
3057         WEBKIT_TYPE_WEB_FRAME,
3058         WEBKIT_TYPE_WEB_RESOURCE,
3059         G_TYPE_ERROR);
3060
3061     /**
3062      * WebKitWebView::context-menu:
3063      * @web_view: the object which received the signal
3064      * @default_menu: the default context menu
3065      * @hit_test_result: a #WebKitHitTestResult with the context of the current position.
3066      * @triggered_with_keyboard: %TRUE if the context menu was triggered using the keyboard
3067      *
3068      * Emmited when a context menu is about to be displayed to give the application
3069      * a chance to create and handle its own context menu. If you only want to add custom
3070      * options to the default context menu you can simply modify the given @default_menu.
3071      *
3072      * When @triggered_with_keyboard is %TRUE the coordinates of the given @hit_test_result should be
3073      * used to position the popup menu. When the context menu has been triggered by a
3074      * mouse event you could either use the @hit_test_result coordinates or pass %NULL
3075      * to the #GtkMenuPositionFunc parameter of gtk_menu_popup() function.
3076      * Note that coordinates of @hit_test_result are relative to @web_view window.
3077      *
3078      * If your application will create and display its own popup menu, %TRUE should be returned.
3079      * Note that when the context menu is handled by the application, the #WebKitWebSettings:enable-default-context-menu
3080      * setting will be ignored and the #WebKitWebView::populate-popup signal won't be emitted.
3081      * If you don't want any context menu to be shown, you can simply connect to this signal
3082      * and return %TRUE without doing anything else.
3083      *
3084      * Since: 1.10
3085      */
3086     webkit_web_view_signals[CONTEXT_MENU] = g_signal_new("context-menu",
3087         G_TYPE_FROM_CLASS(webViewClass),
3088         G_SIGNAL_RUN_LAST,
3089         0, 0, 0,
3090         webkit_marshal_BOOLEAN__OBJECT_OBJECT_BOOLEAN,
3091         G_TYPE_BOOLEAN, 3,
3092         GTK_TYPE_WIDGET,
3093         WEBKIT_TYPE_HIT_TEST_RESULT,
3094         G_TYPE_BOOLEAN);
3095
3096     /*
3097      * implementations of virtual methods
3098      */
3099     webViewClass->create_web_view = webkit_web_view_real_create_web_view;
3100     webViewClass->web_view_ready = webkit_web_view_real_web_view_ready;
3101     webViewClass->close_web_view = webkit_web_view_real_close_web_view;
3102     webViewClass->navigation_requested = webkit_web_view_real_navigation_requested;
3103     webViewClass->window_object_cleared = webkit_web_view_real_window_object_cleared;
3104     webViewClass->choose_file = webkit_web_view_real_choose_file;
3105     webViewClass->script_alert = webkit_web_view_real_script_alert;
3106     webViewClass->script_confirm = webkit_web_view_real_script_confirm;
3107     webViewClass->script_prompt = webkit_web_view_real_script_prompt;
3108     webViewClass->console_message = webkit_web_view_real_console_message;
3109     webViewClass->select_all = webkit_web_view_real_select_all;
3110     webViewClass->cut_clipboard = webkit_web_view_real_cut_clipboard;
3111     webViewClass->copy_clipboard = webkit_web_view_real_copy_clipboard;
3112     webViewClass->paste_clipboard = webkit_web_view_real_paste_clipboard;
3113     webViewClass->undo = webkit_web_view_real_undo;
3114     webViewClass->redo = webkit_web_view_real_redo;
3115     webViewClass->move_cursor = webkit_web_view_real_move_cursor;
3116     webViewClass->should_allow_editing_action = webkit_web_view_real_should_allow_editing_action;
3117     webViewClass->entering_fullscreen = webkit_web_view_real_entering_fullscreen;
3118     webViewClass->leaving_fullscreen = webkit_web_view_real_leaving_fullscreen;
3119     webViewClass->run_file_chooser = webkitWebViewRealRunFileChooser;
3120
3121     GObjectClass* objectClass = G_OBJECT_CLASS(webViewClass);
3122     objectClass->dispose = webkit_web_view_dispose;
3123     objectClass->finalize = webkit_web_view_finalize;
3124     objectClass->get_property = webkit_web_view_get_property;
3125     objectClass->set_property = webkit_web_view_set_property;
3126
3127     GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(webViewClass);
3128     widgetClass->realize = webkit_web_view_realize;
3129 #ifdef GTK_API_VERSION_2
3130     widgetClass->expose_event = webkit_web_view_expose_event;
3131 #else
3132     widgetClass->draw = webkit_web_view_draw;
3133 #endif
3134     widgetClass->key_press_event = webkit_web_view_key_press_event;
3135     widgetClass->key_release_event = webkit_web_view_key_release_event;
3136     widgetClass->button_press_event = webkit_web_view_button_press_event;
3137     widgetClass->button_release_event = webkit_web_view_button_release_event;
3138     widgetClass->motion_notify_event = webkit_web_view_motion_event;
3139     widgetClass->scroll_event = webkit_web_view_scroll_event;
3140     widgetClass->size_allocate = webkit_web_view_size_allocate;
3141 #ifdef GTK_API_VERSION_2
3142     widgetClass->size_request = webkit_web_view_size_request;
3143 #else
3144     widgetClass->get_preferred_width = webkit_web_view_get_preferred_width;
3145     widgetClass->get_preferred_height = webkit_web_view_get_preferred_height;
3146 #endif
3147 #if ENABLE(CONTEXT_MENUS)
3148     widgetClass->popup_menu = webkit_web_view_popup_menu_handler;
3149 #else
3150     widgetClass->popup_menu = NULL;
3151 #endif
3152     widgetClass->grab_focus = webkit_web_view_grab_focus;
3153     widgetClass->focus_in_event = webkit_web_view_focus_in_event;
3154     widgetClass->focus_out_event = webkit_web_view_focus_out_event;
3155 #if HAVE(ACCESSIBILITY)
3156     widgetClass->get_accessible = webkit_web_view_get_accessible;
3157 #endif
3158     widgetClass->screen_changed = webkit_web_view_screen_changed;
3159 #if ENABLE(DRAG_SUPPORT)
3160     widgetClass->drag_end = webkit_web_view_drag_end;
3161     widgetClass->drag_data_get = webkit_web_view_drag_data_get;
3162     widgetClass->drag_motion = webkit_web_view_drag_motion;
3163     widgetClass->drag_leave = webkit_web_view_drag_leave;
3164     widgetClass->drag_drop = webkit_web_view_drag_drop;
3165     widgetClass->drag_data_received = webkit_web_view_drag_data_received;
3166 #else
3167     widgetClass->drag_end = NULL;
3168     widgetClass->drag_data_get = NULL;
3169     widgetClass->drag_motion = NULL;
3170     widgetClass->drag_leave = NULL;
3171     widgetClass->drag_drop = NULL;
3172     widgetClass->drag_data_received = NULL;
3173 #endif
3174     widgetClass->query_tooltip = webkit_web_view_query_tooltip;
3175     widgetClass->show_help = webkit_web_view_show_help;
3176     widgetClass->map = webkitWebViewMap;
3177
3178     GtkContainerClass* containerClass = GTK_CONTAINER_CLASS(webViewClass);
3179     containerClass->add = webkit_web_view_container_add;
3180     containerClass->remove = webkit_web_view_container_remove;
3181     containerClass->forall = webkit_web_view_container_forall;
3182
3183     /*
3184      * make us scrollable (e.g. addable to a GtkScrolledWindow)
3185      */
3186 #ifdef GTK_API_VERSION_2
3187     webViewClass->set_scroll_adjustments = webkit_web_view_set_scroll_adjustments;
3188     GTK_WIDGET_CLASS(webViewClass)->set_scroll_adjustments_signal = g_signal_new("set-scroll-adjustments",
3189             G_TYPE_FROM_CLASS(webViewClass),
3190             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
3191             G_STRUCT_OFFSET(WebKitWebViewClass, set_scroll_adjustments),
3192             NULL, NULL,
3193             webkit_marshal_VOID__OBJECT_OBJECT,
3194             G_TYPE_NONE, 2,
3195             GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
3196 #else
3197     g_object_class_override_property(objectClass, PROP_HADJUSTMENT, "hadjustment");
3198     g_object_class_override_property(objectClass, PROP_VADJUSTMENT, "vadjustment");
3199     g_object_class_override_property(objectClass, PROP_HSCROLL_POLICY, "hscroll-policy");
3200     g_object_class_override_property(objectClass, PROP_VSCROLL_POLICY, "vscroll-policy");
3201 #endif
3202
3203     /*
3204      * Key bindings
3205      */
3206
3207     binding_set = gtk_binding_set_by_class(webViewClass);
3208
3209     gtk_binding_entry_add_signal(binding_set, GDK_a, GDK_CONTROL_MASK,
3210                                  "select_all", 0);
3211
3212     /* Cut/copy/paste */
3213
3214     gtk_binding_entry_add_signal(binding_set, GDK_x, GDK_CONTROL_MASK,
3215                                  "cut_clipboard", 0);
3216     gtk_binding_entry_add_signal(binding_set, GDK_c, GDK_CONTROL_MASK,
3217                                  "copy_clipboard", 0);
3218     gtk_binding_entry_add_signal(binding_set, GDK_v, GDK_CONTROL_MASK,
3219                                  "paste_clipboard", 0);
3220     gtk_binding_entry_add_signal(binding_set, GDK_z, GDK_CONTROL_MASK,
3221                                  "undo", 0);
3222     gtk_binding_entry_add_signal(binding_set, GDK_z, static_cast<GdkModifierType>(GDK_CONTROL_MASK | GDK_SHIFT_MASK),
3223                                  "redo", 0);
3224
3225     gtk_binding_entry_add_signal(binding_set, GDK_Delete, GDK_SHIFT_MASK,
3226                                  "cut_clipboard", 0);
3227     gtk_binding_entry_add_signal(binding_set, GDK_Insert, GDK_CONTROL_MASK,
3228                                  "copy_clipboard", 0);
3229     gtk_binding_entry_add_signal(binding_set, GDK_Insert, GDK_SHIFT_MASK,
3230                                  "paste_clipboard", 0);
3231
3232     /* Movement */
3233
3234     gtk_binding_entry_add_signal(binding_set, GDK_Down, static_cast<GdkModifierType>(0),
3235                                  "move-cursor", 2,
3236                                  G_TYPE_ENUM, GTK_MOVEMENT_DISPLAY_LINES,
3237                                  G_TYPE_INT, 1);
3238     gtk_binding_entry_add_signal(binding_set, GDK_Up, static_cast<GdkModifierType>(0),
3239                                  "move-cursor", 2,
3240                                  G_TYPE_ENUM, GTK_MOVEMENT_DISPLAY_LINES,
3241                                  G_TYPE_INT, -1);
3242     gtk_binding_entry_add_signal(binding_set, GDK_Right, static_cast<GdkModifierType>(0),
3243                                  "move-cursor", 2,
3244                                  G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
3245                                  G_TYPE_INT, 1);
3246     gtk_binding_entry_add_signal(binding_set, GDK_Left, static_cast<GdkModifierType>(0),
3247                                  "move-cursor", 2,
3248                                  G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
3249                                  G_TYPE_INT, -1);
3250     gtk_binding_entry_add_signal(binding_set, GDK_space, static_cast<GdkModifierType>(0),
3251                                  "move-cursor", 2,
3252                                  G_TYPE_ENUM, GTK_MOVEMENT_PAGES,
3253                                  G_TYPE_INT, 1);
3254     gtk_binding_entry_add_signal(binding_set, GDK_space, GDK_SHIFT_MASK,
3255                                  "move-cursor", 2,
3256                                  G_TYPE_ENUM, GTK_MOVEMENT_PAGES,
3257                                  G_TYPE_INT, -1);
3258     gtk_binding_entry_add_signal(binding_set, GDK_Page_Down, static_cast<GdkModifierType>(0),
3259                                  "move-cursor", 2,
3260                                  G_TYPE_ENUM, GTK_MOVEMENT_PAGES,
3261                                  G_TYPE_INT, 1);
3262     gtk_binding_entry_add_signal(binding_set, GDK_Page_Up, static_cast<GdkModifierType>(0),
3263                                  "move-cursor", 2,
3264                                  G_TYPE_ENUM, GTK_MOVEMENT_PAGES,
3265                                  G_TYPE_INT, -1);
3266     gtk_binding_entry_add_signal(binding_set, GDK_End, static_cast<GdkModifierType>(0),
3267                                  "move-cursor", 2,
3268                                  G_TYPE_ENUM, GTK_MOVEMENT_BUFFER_ENDS,
3269                                  G_TYPE_INT, 1);
3270     gtk_binding_entry_add_signal(binding_set, GDK_Home, static_cast<GdkModifierType>(0),
3271                                  "move-cursor", 2,
3272                                  G_TYPE_ENUM, GTK_MOVEMENT_BUFFER_ENDS,
3273                                  G_TYPE_INT, -1);
3274
3275     /*
3276      * properties
3277      */
3278
3279     /**
3280     * WebKitWebView:title:
3281     *
3282     * Returns: the @web_view's document title.
3283     *
3284     * Since: 1.1.4
3285     */
3286     g_object_class_install_property(objectClass, PROP_TITLE,
3287                                     g_param_spec_string("title",
3288                                                         _("Title"),
3289                                                         _("Returns the @web_view's document title"),
3290                                                         NULL,
3291                                                         WEBKIT_PARAM_READABLE));
3292
3293     /**
3294     * WebKitWebView:uri:
3295     *
3296     * Returns: the current URI of the contents displayed by the @web_view.
3297     *
3298     * Since: 1.1.4
3299     */
3300     g_object_class_install_property(objectClass, PROP_URI,
3301                                     g_param_spec_string("uri",
3302                                                         _("URI"),
3303                                                         _("Returns the current URI of the contents displayed by the @web_view"),
3304                                                         NULL,
3305                                                         WEBKIT_PARAM_READABLE));
3306
3307     /**
3308     * WebKitWebView:copy-target-list:
3309     *
3310     * The list of targets this web view supports for clipboard copying.
3311     *
3312     * Since: 1.0.2
3313     */
3314     g_object_class_install_property(objectClass, PROP_COPY_TARGET_LIST,
3315                                     g_param_spec_boxed("copy-target-list",
3316                                                        _("Copy target list"),
3317                                                        _("The list of targets this web view supports for clipboard copying"),
3318                                                        GTK_TYPE_TARGET_LIST,
3319                                                        WEBKIT_PARAM_READABLE));
3320
3321     /**
3322     * WebKitWebView:paste-target-list:
3323     *
3324     * The list of targets this web view supports for clipboard pasting.
3325     *
3326     * Since: 1.0.2
3327     */
3328     g_object_class_install_property(objectClass, PROP_PASTE_TARGET_LIST,
3329                                     g_param_spec_boxed("paste-target-list",
3330                                                        _("Paste target list"),
3331                                                        _("The list of targets this web view supports for clipboard pasting"),
3332                                                        GTK_TYPE_TARGET_LIST,
3333                                                        WEBKIT_PARAM_READABLE));
3334
3335     g_object_class_install_property(objectClass, PROP_SETTINGS,
3336                                     g_param_spec_object("settings",
3337                                                         _("Settings"),
3338                                                         _("An associated WebKitWebSettings instance"),
3339                                                         WEBKIT_TYPE_WEB_SETTINGS,
3340                                                         WEBKIT_PARAM_READWRITE));
3341
3342     /**
3343     * WebKitWebView:web-inspector:
3344     *
3345     * The associated WebKitWebInspector instance.
3346     *
3347     * Since: 1.0.3
3348     */
3349     g_object_class_install_property(objectClass, PROP_WEB_INSPECTOR,
3350                                     g_param_spec_object("web-inspector",
3351                                                         _("Web Inspector"),
3352                                                         _("The associated WebKitWebInspector instance"),
3353                                                         WEBKIT_TYPE_WEB_INSPECTOR,
3354                                                         WEBKIT_PARAM_READABLE));
3355
3356     /**
3357     * WebKitWebView:viewport-attributes:
3358     *
3359     * The associated #WebKitViewportAttributes instance.
3360     *
3361     * Since: 1.3.8
3362     */
3363     g_object_class_install_property(objectClass, PROP_VIEWPORT_ATTRIBUTES,
3364                                     g_param_spec_object("viewport-attributes",
3365                                                         _("Viewport Attributes"),
3366                                                         _("The associated WebKitViewportAttributes instance"),