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