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