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