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