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