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