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