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