• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "PasteboardHelperGtk.h"
73 #include "PlatformKeyboardEvent.h"
74 #include "PlatformWheelEvent.h"
75 #include "ProgressTracker.h"
76 #include "RenderView.h"
77 #include "ResourceHandle.h"
78 #include "ScriptValue.h"
79 #include "Scrollbar.h"
80 #include "Settings.h"
81 #include "webkit/WebKitDOMDocumentPrivate.h"
82 #include "webkitdownload.h"
83 #include "webkitdownloadprivate.h"
84 #include "webkitenumtypes.h"
85 #include "webkitgeolocationpolicydecision.h"
86 #include "webkitglobalsprivate.h"
87 #include "webkithittestresultprivate.h"
88 #include "webkiticondatabase.h"
89 #include "webkitmarshal.h"
90 #include "webkitnetworkrequest.h"
91 #include "webkitnetworkresponse.h"
92 #include "webkitviewportattributes.h"
93 #include "webkitviewportattributesprivate.h"
94 #include "webkitwebbackforwardlist.h"
95 #include "webkitwebframeprivate.h"
96 #include "webkitwebhistoryitem.h"
97 #include "webkitwebhistoryitemprivate.h"
98 #include "webkitwebinspector.h"
99 #include "webkitwebinspectorprivate.h"
100 #include "webkitwebpolicydecision.h"
101 #include "webkitwebresource.h"
102 #include "webkitwebsettingsprivate.h"
103 #include "webkitwebplugindatabaseprivate.h"
104 #include "webkitwebwindowfeatures.h"
105 #include "webkitwebviewprivate.h"
106 #include <gdk/gdkkeysyms.h>
107 #include <glib/gi18n-lib.h>
108 #include <wtf/gobject/GOwnPtr.h>
109 #include <wtf/text/CString.h>
110 
111 /**
112  * SECTION:webkitwebview
113  * @short_description: The central class of the WebKitGTK+ API
114  * @see_also: #WebKitWebSettings, #WebKitWebFrame
115  *
116  * #WebKitWebView is the central class of the WebKitGTK+ API. It is a
117  * #GtkWidget implementing the scrolling interface which means you can
118  * embed in a #GtkScrolledWindow. It is responsible for managing the
119  * drawing of the content, forwarding of events. You can load any URI
120  * into the #WebKitWebView or any kind of data string. With #WebKitWebSettings
121  * you can control various aspects of the rendering and loading of the content.
122  * Each #WebKitWebView has exactly one #WebKitWebFrame as main frame. A
123  * #WebKitWebFrame can have n children.
124  *
125  * <programlisting>
126  * /<!-- -->* Create the widgets *<!-- -->/
127  * GtkWidget *main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
128  * GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
129  * GtkWidget *web_view = webkit_web_view_new ();
130  *
131  * /<!-- -->* Place the WebKitWebView in the GtkScrolledWindow *<!-- -->/
132  * gtk_container_add (GTK_CONTAINER (scrolled_window), web_view);
133  * gtk_container_add (GTK_CONTAINER (main_window), scrolled_window);
134  *
135  * /<!-- -->* Open a webpage *<!-- -->/
136  * webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), "http://www.gnome.org");
137  *
138  * /<!-- -->* Show the result *<!-- -->/
139  * gtk_window_set_default_size (GTK_WINDOW (main_window), 800, 600);
140  * gtk_widget_show_all (main_window);
141  * </programlisting>
142  */
143 
144 static const double defaultDPI = 96.0;
145 static IntPoint globalPointForClientPoint(GdkWindow* window, const IntPoint& clientPoint);
146 
147 using namespace WebKit;
148 using namespace WebCore;
149 
150 enum {
151     /* normal signals */
152     NAVIGATION_REQUESTED,
153     NEW_WINDOW_POLICY_DECISION_REQUESTED,
154     NAVIGATION_POLICY_DECISION_REQUESTED,
155     MIME_TYPE_POLICY_DECISION_REQUESTED,
156     CREATE_WEB_VIEW,
157     WEB_VIEW_READY,
158     WINDOW_OBJECT_CLEARED,
159     LOAD_STARTED,
160     LOAD_COMMITTED,
161     LOAD_PROGRESS_CHANGED,
162     LOAD_ERROR,
163     LOAD_FINISHED,
164     TITLE_CHANGED,
165     HOVERING_OVER_LINK,
166     POPULATE_POPUP,
167     STATUS_BAR_TEXT_CHANGED,
168     ICON_LOADED,
169     SELECTION_CHANGED,
170     CONSOLE_MESSAGE,
171     SCRIPT_ALERT,
172     SCRIPT_CONFIRM,
173     SCRIPT_PROMPT,
174     SELECT_ALL,
175     COPY_CLIPBOARD,
176     PASTE_CLIPBOARD,
177     CUT_CLIPBOARD,
178     DOWNLOAD_REQUESTED,
179     MOVE_CURSOR,
180     PRINT_REQUESTED,
181     PLUGIN_WIDGET,
182     CLOSE_WEB_VIEW,
183     UNDO,
184     REDO,
185     DATABASE_QUOTA_EXCEEDED,
186     RESOURCE_REQUEST_STARTING,
187     DOCUMENT_LOAD_FINISHED,
188     GEOLOCATION_POLICY_DECISION_REQUESTED,
189     GEOLOCATION_POLICY_DECISION_CANCELLED,
190     ONLOAD_EVENT,
191     FRAME_CREATED,
192     SHOULD_BEGIN_EDITING,
193     SHOULD_END_EDITING,
194     SHOULD_INSERT_NODE,
195     SHOULD_INSERT_TEXT,
196     SHOULD_DELETE_RANGE,
197     SHOULD_SHOW_DELETE_INTERFACE_FOR_ELEMENT,
198     SHOULD_CHANGE_SELECTED_RANGE,
199     SHOULD_APPLY_STYLE,
200     EDITING_BEGAN,
201     USER_CHANGED_CONTENTS,
202     EDITING_ENDED,
203     VIEWPORT_ATTRIBUTES_RECOMPUTE_REQUESTED,
204     VIEWPORT_ATTRIBUTES_CHANGED,
205 
206     LAST_SIGNAL
207 };
208 
209 enum {
210     PROP_0,
211 
212     PROP_TITLE,
213     PROP_URI,
214     PROP_COPY_TARGET_LIST,
215     PROP_PASTE_TARGET_LIST,
216     PROP_EDITABLE,
217     PROP_SETTINGS,
218     PROP_WEB_INSPECTOR,
219     PROP_VIEWPORT_ATTRIBUTES,
220     PROP_WINDOW_FEATURES,
221     PROP_TRANSPARENT,
222     PROP_ZOOM_LEVEL,
223     PROP_FULL_CONTENT_ZOOM,
224     PROP_LOAD_STATUS,
225     PROP_PROGRESS,
226     PROP_ENCODING,
227     PROP_CUSTOM_ENCODING,
228     PROP_ICON_URI,
229     PROP_IM_CONTEXT,
230 #ifdef GTK_API_VERSION_2
231     PROP_VIEW_MODE
232 #else
233     PROP_VIEW_MODE,
234     PROP_HADJUSTMENT,
235     PROP_VADJUSTMENT,
236     PROP_HSCROLL_POLICY,
237     PROP_VSCROLL_POLICY
238 #endif
239 };
240 
241 static guint webkit_web_view_signals[LAST_SIGNAL] = { 0, };
242 
243 #ifdef GTK_API_VERSION_2
244 G_DEFINE_TYPE(WebKitWebView, webkit_web_view, GTK_TYPE_CONTAINER)
245 #else
246 G_DEFINE_TYPE_WITH_CODE(WebKitWebView, webkit_web_view, GTK_TYPE_CONTAINER,
247                         G_IMPLEMENT_INTERFACE(GTK_TYPE_SCROLLABLE, 0))
248 #endif
249 
250 static void webkit_web_view_settings_notify(WebKitWebSettings* webSettings, GParamSpec* pspec, WebKitWebView* webView);
251 static void webkit_web_view_set_window_features(WebKitWebView* webView, WebKitWebWindowFeatures* webWindowFeatures);
252 
253 static GtkIMContext* webkit_web_view_get_im_context(WebKitWebView*);
254 
PopupMenuPositionFunc(GtkMenu * menu,gint * x,gint * y,gboolean * pushIn,gpointer userData)255 static void PopupMenuPositionFunc(GtkMenu* menu, gint *x, gint *y, gboolean *pushIn, gpointer userData)
256 {
257     WebKitWebView* view = WEBKIT_WEB_VIEW(userData);
258     WebKitWebViewPrivate* priv = view->priv;
259     GdkScreen* screen = gtk_widget_get_screen(GTK_WIDGET(view));
260     GtkRequisition menuSize;
261 
262 #ifdef GTK_API_VERSION_2
263     gtk_widget_size_request(GTK_WIDGET(menu), &menuSize);
264 #else
265     gtk_widget_get_preferred_size(GTK_WIDGET(menu), &menuSize, NULL);
266 #endif
267 
268     *x = priv->lastPopupXPosition;
269     if ((*x + menuSize.width) >= gdk_screen_get_width(screen))
270       *x -= menuSize.width;
271 
272     *y = priv->lastPopupYPosition;
273     if ((*y + menuSize.height) >= gdk_screen_get_height(screen))
274       *y -= menuSize.height;
275 
276     *pushIn = FALSE;
277 }
278 
getFocusedNode(Frame * frame)279 static Node* getFocusedNode(Frame* frame)
280 {
281     if (Document* doc = frame->document())
282         return doc->focusedNode();
283     return 0;
284 }
285 
contextMenuItemActivated(GtkMenuItem * item,ContextMenuController * controller)286 static void contextMenuItemActivated(GtkMenuItem* item, ContextMenuController* controller)
287 {
288     ContextMenuItem contextItem(item);
289     controller->contextMenuItemSelected(&contextItem);
290 }
291 
contextMenuConnectActivate(GtkMenuItem * item,ContextMenuController * controller)292 static void contextMenuConnectActivate(GtkMenuItem* item, ContextMenuController* controller)
293 {
294     if (GTK_IS_SEPARATOR_MENU_ITEM(item))
295         return;
296 
297     if (GtkWidget* menu = gtk_menu_item_get_submenu(item)) {
298         gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback)contextMenuConnectActivate, controller);
299         return;
300     }
301 
302     g_signal_connect(item, "activate", G_CALLBACK(contextMenuItemActivated), controller);
303 }
304 
webkit_web_view_forward_context_menu_event(WebKitWebView * webView,const PlatformMouseEvent & event)305 static gboolean webkit_web_view_forward_context_menu_event(WebKitWebView* webView, const PlatformMouseEvent& event)
306 {
307     Page* page = core(webView);
308     page->contextMenuController()->clearContextMenu();
309     Frame* focusedFrame;
310     Frame* mainFrame = page->mainFrame();
311     gboolean mousePressEventResult = FALSE;
312 
313     if (!mainFrame->view())
314         return FALSE;
315 
316     mainFrame->view()->setCursor(pointerCursor());
317     if (page->frameCount()) {
318         HitTestRequest request(HitTestRequest::Active);
319         IntPoint point = mainFrame->view()->windowToContents(event.pos());
320         MouseEventWithHitTestResults mev = mainFrame->document()->prepareMouseEvent(request, point, event);
321 
322         Frame* targetFrame = EventHandler::subframeForHitTestResult(mev);
323         if (!targetFrame)
324             targetFrame = mainFrame;
325 
326         focusedFrame = page->focusController()->focusedOrMainFrame();
327         if (targetFrame != focusedFrame) {
328             page->focusController()->setFocusedFrame(targetFrame);
329             focusedFrame = targetFrame;
330         }
331     } else
332         focusedFrame = mainFrame;
333 
334     if (focusedFrame->view() && focusedFrame->eventHandler()->handleMousePressEvent(event))
335         mousePressEventResult = TRUE;
336 
337 
338     bool handledEvent = focusedFrame->eventHandler()->sendContextMenuEvent(event);
339     if (!handledEvent)
340         return FALSE;
341 
342     // If coreMenu is NULL, this means WebCore decided to not create
343     // the default context menu; this may happen when the page is
344     // handling the right-click for reasons other than the context menu.
345     ContextMenuController* controller = page->contextMenuController();
346     ContextMenu* coreMenu = controller->contextMenu();
347     if (!coreMenu)
348         return mousePressEventResult;
349 
350     // If we reach here, it's because WebCore is going to show the
351     // default context menu. We check our setting to figure out
352     // whether we want it or not.
353     WebKitWebSettings* settings = webkit_web_view_get_settings(webView);
354     gboolean enableDefaultContextMenu;
355     g_object_get(settings, "enable-default-context-menu", &enableDefaultContextMenu, NULL);
356 
357     if (!enableDefaultContextMenu)
358         return FALSE;
359 
360     GtkMenu* menu = GTK_MENU(coreMenu->platformDescription());
361     if (!menu)
362         return FALSE;
363 
364     // We connect the "activate" signal here rather than in ContextMenuGtk to avoid
365     // a layering violation. ContextMenuGtk should not know about the ContextMenuController.
366     gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback)contextMenuConnectActivate, controller);
367 
368     g_signal_emit(webView, webkit_web_view_signals[POPULATE_POPUP], 0, menu);
369 
370     // If the context menu is now empty, don't show it.
371     GOwnPtr<GList> items(gtk_container_get_children(GTK_CONTAINER(menu)));
372     if (!items)
373         return FALSE;
374 
375     WebKitWebViewPrivate* priv = webView->priv;
376     priv->currentMenu = menu;
377     priv->lastPopupXPosition = event.globalX();
378     priv->lastPopupYPosition = event.globalY();
379 
380     gtk_menu_popup(menu, 0, 0, &PopupMenuPositionFunc, webView, event.button() + 1, gtk_get_current_event_time());
381     return TRUE;
382 }
383 
384 static const int gContextMenuMargin = 1;
getLocationForKeyboardGeneratedContextMenu(Frame * frame)385 static IntPoint getLocationForKeyboardGeneratedContextMenu(Frame* frame)
386 {
387     SelectionController* selection = frame->selection();
388     if (!selection->selection().isNonOrphanedCaretOrRange()
389          || (selection->selection().isCaret() && !selection->selection().isContentEditable())) {
390         if (Node* focusedNode = getFocusedNode(frame))
391             return focusedNode->getRect().location();
392 
393         // There was no selection and no focused node, so just put the context
394         // menu into the corner of the view, offset slightly.
395         return IntPoint(gContextMenuMargin, gContextMenuMargin);
396     }
397 
398     // selection->selection().firstRange can return 0 here, but if that was the case
399     // selection->selection().isNonOrphanedCaretOrRange() would have returned false
400     // above, so we do not have to check it.
401     IntRect firstRect = frame->editor()->firstRectForRange(selection->selection().firstRange().get());
402     return IntPoint(firstRect.x(), firstRect.maxY());
403 }
404 
webkit_web_view_popup_menu_handler(GtkWidget * widget)405 static gboolean webkit_web_view_popup_menu_handler(GtkWidget* widget)
406 {
407     Frame* frame = core(WEBKIT_WEB_VIEW(widget))->focusController()->focusedOrMainFrame();
408     IntPoint location = getLocationForKeyboardGeneratedContextMenu(frame);
409 
410     FrameView* view = frame->view();
411     if (!view)
412         return FALSE;
413 
414     // Never let the context menu touch the very edge of the view.
415     location = view->contentsToWindow(location);
416     location.expandedTo(IntPoint(gContextMenuMargin, gContextMenuMargin));
417     location.shrunkTo(IntPoint(view->width() - gContextMenuMargin, view->height() - gContextMenuMargin));
418 
419     IntPoint globalPoint(globalPointForClientPoint(gtk_widget_get_window(widget), location));
420     PlatformMouseEvent event(location, globalPoint, RightButton, MouseEventPressed, 0, false, false, false, false, gtk_get_current_event_time());
421     return webkit_web_view_forward_context_menu_event(WEBKIT_WEB_VIEW(widget), event);
422 }
423 
424 #ifndef GTK_API_VERSION_2
setHorizontalAdjustment(WebKitWebView * webView,GtkAdjustment * adjustment)425 static void setHorizontalAdjustment(WebKitWebView* webView, GtkAdjustment* adjustment)
426 {
427     if (!core(webView))
428         return;
429 
430     webView->priv->horizontalAdjustment = adjustment;
431     FrameView* view = core(webkit_web_view_get_main_frame(webView))->view();
432     if (!view)
433         return;
434     view->setHorizontalAdjustment(adjustment);
435 }
436 
setVerticalAdjustment(WebKitWebView * webView,GtkAdjustment * adjustment)437 static void setVerticalAdjustment(WebKitWebView* webView, GtkAdjustment* adjustment)
438 {
439     if (!core(webView))
440         return;
441 
442     webView->priv->verticalAdjustment = adjustment;
443     FrameView* view = core(webkit_web_view_get_main_frame(webView))->view();
444     if (!view)
445         return;
446     view->setVerticalAdjustment(adjustment);
447 }
448 
getHorizontalAdjustment(WebKitWebView * webView)449 static GtkAdjustment* getHorizontalAdjustment(WebKitWebView* webView)
450 {
451     return webView->priv->horizontalAdjustment.get();
452 }
453 
getVerticalAdjustment(WebKitWebView * webView)454 static GtkAdjustment* getVerticalAdjustment(WebKitWebView* webView)
455 {
456     return webView->priv->verticalAdjustment.get();
457 }
458 
setHorizontalScrollPolicy(WebKitWebView * webView,GtkScrollablePolicy policy)459 static void setHorizontalScrollPolicy(WebKitWebView* webView, GtkScrollablePolicy policy)
460 {
461     webView->priv->horizontalScrollingPolicy = policy;
462     gtk_widget_queue_resize(GTK_WIDGET(webView));
463 }
464 
setVerticalScrollPolicy(WebKitWebView * webView,GtkScrollablePolicy policy)465 static void setVerticalScrollPolicy(WebKitWebView* webView, GtkScrollablePolicy policy)
466 {
467     webView->priv->verticalScrollingPolicy = policy;
468     gtk_widget_queue_resize(GTK_WIDGET(webView));
469 }
470 
getHorizontalScrollPolicy(WebKitWebView * webView)471 static GtkScrollablePolicy getHorizontalScrollPolicy(WebKitWebView* webView)
472 {
473     return webView->priv->horizontalScrollingPolicy;
474 }
475 
getVerticalScrollPolicy(WebKitWebView * webView)476 static GtkScrollablePolicy getVerticalScrollPolicy(WebKitWebView* webView)
477 {
478     return webView->priv->verticalScrollingPolicy;
479 }
480 
481 #endif
482 
webkit_web_view_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)483 static void webkit_web_view_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
484 {
485     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
486 
487     switch(prop_id) {
488     case PROP_TITLE:
489         g_value_set_string(value, webkit_web_view_get_title(webView));
490         break;
491     case PROP_URI:
492         g_value_set_string(value, webkit_web_view_get_uri(webView));
493         break;
494     case PROP_COPY_TARGET_LIST:
495         g_value_set_boxed(value, webkit_web_view_get_copy_target_list(webView));
496         break;
497     case PROP_PASTE_TARGET_LIST:
498         g_value_set_boxed(value, webkit_web_view_get_paste_target_list(webView));
499         break;
500     case PROP_EDITABLE:
501         g_value_set_boolean(value, webkit_web_view_get_editable(webView));
502         break;
503     case PROP_SETTINGS:
504         g_value_set_object(value, webkit_web_view_get_settings(webView));
505         break;
506     case PROP_WEB_INSPECTOR:
507         g_value_set_object(value, webkit_web_view_get_inspector(webView));
508         break;
509     case PROP_VIEWPORT_ATTRIBUTES:
510         g_value_set_object(value, webkit_web_view_get_viewport_attributes(webView));
511         break;
512     case PROP_WINDOW_FEATURES:
513         g_value_set_object(value, webkit_web_view_get_window_features(webView));
514         break;
515     case PROP_TRANSPARENT:
516         g_value_set_boolean(value, webkit_web_view_get_transparent(webView));
517         break;
518     case PROP_ZOOM_LEVEL:
519         g_value_set_float(value, webkit_web_view_get_zoom_level(webView));
520         break;
521     case PROP_FULL_CONTENT_ZOOM:
522         g_value_set_boolean(value, webkit_web_view_get_full_content_zoom(webView));
523         break;
524     case PROP_ENCODING:
525         g_value_set_string(value, webkit_web_view_get_encoding(webView));
526         break;
527     case PROP_CUSTOM_ENCODING:
528         g_value_set_string(value, webkit_web_view_get_custom_encoding(webView));
529         break;
530     case PROP_LOAD_STATUS:
531         g_value_set_enum(value, webkit_web_view_get_load_status(webView));
532         break;
533     case PROP_PROGRESS:
534         g_value_set_double(value, webkit_web_view_get_progress(webView));
535         break;
536     case PROP_ICON_URI:
537         g_value_set_string(value, webkit_web_view_get_icon_uri(webView));
538         break;
539     case PROP_IM_CONTEXT:
540         g_value_set_object(value, webkit_web_view_get_im_context(webView));
541         break;
542     case PROP_VIEW_MODE:
543         g_value_set_enum(value, webkit_web_view_get_view_mode(webView));
544         break;
545 #ifndef GTK_API_VERSION_2
546     case PROP_HADJUSTMENT:
547         g_value_set_object(value, getHorizontalAdjustment(webView));
548         break;
549     case PROP_VADJUSTMENT:
550         g_value_set_object(value, getVerticalAdjustment(webView));
551         break;
552     case PROP_HSCROLL_POLICY:
553         g_value_set_enum(value, getHorizontalScrollPolicy(webView));
554         break;
555     case PROP_VSCROLL_POLICY:
556         g_value_set_enum(value, getVerticalScrollPolicy(webView));
557         break;
558 #endif
559     default:
560         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
561     }
562 }
563 
webkit_web_view_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)564 static void webkit_web_view_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec *pspec)
565 {
566     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
567 
568     switch(prop_id) {
569     case PROP_EDITABLE:
570         webkit_web_view_set_editable(webView, g_value_get_boolean(value));
571         break;
572     case PROP_SETTINGS:
573         webkit_web_view_set_settings(webView, WEBKIT_WEB_SETTINGS(g_value_get_object(value)));
574         break;
575     case PROP_WINDOW_FEATURES:
576         webkit_web_view_set_window_features(webView, WEBKIT_WEB_WINDOW_FEATURES(g_value_get_object(value)));
577         break;
578     case PROP_TRANSPARENT:
579         webkit_web_view_set_transparent(webView, g_value_get_boolean(value));
580         break;
581     case PROP_ZOOM_LEVEL:
582         webkit_web_view_set_zoom_level(webView, g_value_get_float(value));
583         break;
584     case PROP_FULL_CONTENT_ZOOM:
585         webkit_web_view_set_full_content_zoom(webView, g_value_get_boolean(value));
586         break;
587     case PROP_CUSTOM_ENCODING:
588         webkit_web_view_set_custom_encoding(webView, g_value_get_string(value));
589         break;
590     case PROP_VIEW_MODE:
591         webkit_web_view_set_view_mode(webView, static_cast<WebKitWebViewViewMode>(g_value_get_enum(value)));
592         break;
593 #ifndef GTK_API_VERSION_2
594     case PROP_HADJUSTMENT:
595         setHorizontalAdjustment(webView, static_cast<GtkAdjustment*>(g_value_get_object(value)));
596         break;
597     case PROP_VADJUSTMENT:
598         setVerticalAdjustment(webView, static_cast<GtkAdjustment*>(g_value_get_object(value)));
599         break;
600     case PROP_HSCROLL_POLICY:
601         setHorizontalScrollPolicy(webView, static_cast<GtkScrollablePolicy>(g_value_get_enum(value)));
602         break;
603     case PROP_VSCROLL_POLICY:
604         setVerticalScrollPolicy(webView, static_cast<GtkScrollablePolicy>(g_value_get_enum(value)));
605         break;
606 #endif
607     default:
608         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
609     }
610 }
611 
shouldCoalesce(const IntRect & rect,const Vector<IntRect> & rects)612 static bool shouldCoalesce(const IntRect& rect, const Vector<IntRect>& rects)
613 {
614     const unsigned int cRectThreshold = 10;
615     const float cWastedSpaceThreshold = 0.75f;
616     bool useUnionedRect = (rects.size() <= 1) || (rects.size() > cRectThreshold);
617     if (useUnionedRect)
618         return true;
619     // Attempt to guess whether or not we should use the unioned rect or the individual rects.
620     // We do this by computing the percentage of "wasted space" in the union.  If that wasted space
621     // is too large, then we will do individual rect painting instead.
622     float unionPixels = (rect.width() * rect.height());
623     float singlePixels = 0;
624     for (size_t i = 0; i < rects.size(); ++i)
625         singlePixels += rects[i].width() * rects[i].height();
626     float wastedSpace = 1 - (singlePixels / unionPixels);
627     if (wastedSpace <= cWastedSpaceThreshold)
628         useUnionedRect = true;
629     return useUnionedRect;
630 }
631 
paintWebView(Frame * frame,gboolean transparent,GraphicsContext & context,const IntRect & clipRect,const Vector<IntRect> & rects)632 static void paintWebView(Frame* frame, gboolean transparent, GraphicsContext& context, const IntRect& clipRect, const Vector<IntRect>& rects)
633 {
634     bool coalesce = true;
635 
636     if (rects.size() > 0)
637         coalesce = shouldCoalesce(clipRect, rects);
638 
639     if (coalesce) {
640         context.clip(clipRect);
641         if (transparent)
642             context.clearRect(clipRect);
643         frame->view()->paint(&context, clipRect);
644     } else {
645         for (size_t i = 0; i < rects.size(); i++) {
646             IntRect rect = rects[i];
647             context.save();
648             context.clip(rect);
649             if (transparent)
650                 context.clearRect(rect);
651             frame->view()->paint(&context, rect);
652             context.restore();
653         }
654     }
655 
656     context.save();
657     context.clip(clipRect);
658     frame->page()->inspectorController()->drawNodeHighlight(context);
659     context.restore();
660 }
661 #ifdef GTK_API_VERSION_2
webkit_web_view_expose_event(GtkWidget * widget,GdkEventExpose * event)662 static gboolean webkit_web_view_expose_event(GtkWidget* widget, GdkEventExpose* event)
663 {
664     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
665     WebKitWebViewPrivate* priv = webView->priv;
666 
667     Frame* frame = core(webView)->mainFrame();
668     if (frame->contentRenderer() && frame->view()) {
669         frame->view()->updateLayoutAndStyleIfNeededRecursive();
670 
671         RefPtr<cairo_t> cr = adoptRef(gdk_cairo_create(event->window));
672         GraphicsContext gc(cr.get());
673         gc.setGdkExposeEvent(event);
674 
675         int rectCount;
676         GOwnPtr<GdkRectangle> rects;
677         gdk_region_get_rectangles(event->region, &rects.outPtr(), &rectCount);
678         Vector<IntRect> paintRects;
679         for (int i = 0; i < rectCount; i++)
680             paintRects.append(IntRect(rects.get()[i]));
681 
682         paintWebView(frame, priv->transparent, gc, static_cast<IntRect>(event->area), paintRects);
683     }
684 
685     return FALSE;
686 }
687 #else
webkit_web_view_draw(GtkWidget * widget,cairo_t * cr)688 static gboolean webkit_web_view_draw(GtkWidget* widget, cairo_t* cr)
689 {
690     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
691     WebKitWebViewPrivate* priv = webView->priv;
692     GdkRectangle clipRect;
693 
694     if (!gdk_cairo_get_clip_rectangle(cr, &clipRect))
695         return FALSE;
696 
697     Frame* frame = core(webView)->mainFrame();
698     if (frame->contentRenderer() && frame->view()) {
699         GraphicsContext gc(cr);
700         IntRect rect = clipRect;
701         cairo_rectangle_list_t* rectList = cairo_copy_clip_rectangle_list(cr);
702 
703         frame->view()->updateLayoutAndStyleIfNeededRecursive();
704 
705         Vector<IntRect> rects;
706         if (!rectList->status && rectList->num_rectangles > 0) {
707             for (int i = 0; i < rectList->num_rectangles; i++)
708                 rects.append(enclosingIntRect(FloatRect(rectList->rectangles[i])));
709         }
710         paintWebView(frame, priv->transparent, gc, rect, rects);
711 
712         cairo_rectangle_list_destroy(rectList);
713     }
714 
715     return FALSE;
716 }
717 #endif // GTK_API_VERSION_2
718 
webkit_web_view_key_press_event(GtkWidget * widget,GdkEventKey * event)719 static gboolean webkit_web_view_key_press_event(GtkWidget* widget, GdkEventKey* event)
720 {
721     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
722 
723     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
724     PlatformKeyboardEvent keyboardEvent(event);
725 
726     if (!frame->view())
727         return FALSE;
728 
729     if (frame->eventHandler()->keyEvent(keyboardEvent))
730         return TRUE;
731 
732     /* Chain up to our parent class for binding activation */
733     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->key_press_event(widget, event);
734 }
735 
webkit_web_view_key_release_event(GtkWidget * widget,GdkEventKey * event)736 static gboolean webkit_web_view_key_release_event(GtkWidget* widget, GdkEventKey* event)
737 {
738     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
739 
740     // GTK+ IM contexts often require us to filter key release events, which
741     // WebCore does not do by default, so we filter the event here. We only block
742     // the event if we don't have a pending composition, because that means we
743     // are using a context like 'simple' which marks every keystroke as filtered.
744     WebKit::EditorClient* client = static_cast<WebKit::EditorClient*>(core(webView)->editorClient());
745     if (gtk_im_context_filter_keypress(webView->priv->imContext.get(), event) && !client->hasPendingComposition())
746         return TRUE;
747 
748     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
749     if (!frame->view())
750         return FALSE;
751 
752     PlatformKeyboardEvent keyboardEvent(event);
753     if (frame->eventHandler()->keyEvent(keyboardEvent))
754         return TRUE;
755 
756     /* Chain up to our parent class for binding activation */
757     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->key_release_event(widget, event);
758 }
759 
getEventTime(GdkEvent * event)760 static guint32 getEventTime(GdkEvent* event)
761 {
762     guint32 time = gdk_event_get_time(event);
763     if (time)
764         return time;
765 
766     // Real events always have a non-zero time, but events synthesized
767     // by the DRT do not and we must calculate a time manually. This time
768     // is not calculated in the DRT, because GTK+ does not work well with
769     // anything other than GDK_CURRENT_TIME on synthesized events.
770     GTimeVal timeValue;
771     g_get_current_time(&timeValue);
772     return (timeValue.tv_sec * 1000) + (timeValue.tv_usec / 1000);
773 }
774 
webkit_web_view_button_press_event(GtkWidget * widget,GdkEventButton * event)775 static gboolean webkit_web_view_button_press_event(GtkWidget* widget, GdkEventButton* event)
776 {
777     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
778     WebKitWebViewPrivate* priv = webView->priv;
779 
780     // FIXME: need to keep track of subframe focus for key events
781     gtk_widget_grab_focus(widget);
782 
783     // For double and triple clicks GDK sends both a normal button press event
784     // and a specific type (like GDK_2BUTTON_PRESS). If we detect a special press
785     // coming up, ignore this event as it certainly generated the double or triple
786     // click. The consequence of not eating this event is two DOM button press events
787     // are generated.
788     GOwnPtr<GdkEvent> nextEvent(gdk_event_peek());
789     if (nextEvent && (nextEvent->any.type == GDK_2BUTTON_PRESS || nextEvent->any.type == GDK_3BUTTON_PRESS))
790         return TRUE;
791 
792     gint doubleClickDistance = 250;
793     gint doubleClickTime = 5;
794     GtkSettings* settings = gtk_settings_get_for_screen(gtk_widget_get_screen(widget));
795     g_object_get(settings,
796         "gtk-double-click-distance", &doubleClickDistance,
797         "gtk-double-click-time", &doubleClickTime, NULL);
798 
799     // GTK+ only counts up to triple clicks, but WebCore wants to know about
800     // quadruple clicks, quintuple clicks, ad infinitum. Here, we replicate the
801     // GDK logic for counting clicks.
802     guint32 eventTime = getEventTime(reinterpret_cast<GdkEvent*>(event));
803     if ((event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS)
804         || ((abs(event->x - priv->previousClickPoint.x()) < doubleClickDistance)
805             && (abs(event->y - priv->previousClickPoint.y()) < doubleClickDistance)
806             && (eventTime - priv->previousClickTime < static_cast<guint>(doubleClickTime))
807             && (event->button == priv->previousClickButton)))
808         priv->currentClickCount++;
809     else
810         priv->currentClickCount = 1;
811 
812     PlatformMouseEvent platformEvent(event);
813     platformEvent.setClickCount(priv->currentClickCount);
814     priv->previousClickPoint = platformEvent.pos();
815     priv->previousClickButton = event->button;
816     priv->previousClickTime = eventTime;
817 
818     if (event->button == 3)
819         return webkit_web_view_forward_context_menu_event(webView, PlatformMouseEvent(event));
820 
821     Frame* frame = core(webView)->mainFrame();
822     if (!frame->view())
823         return FALSE;
824 
825     gboolean result = frame->eventHandler()->handleMousePressEvent(platformEvent);
826     // Handle the IM context when a mouse press fires
827     static_cast<WebKit::EditorClient*>(core(webView)->editorClient())->handleInputMethodMousePress();
828 
829 #if PLATFORM(X11)
830     /* Copy selection to the X11 selection clipboard */
831     if (event->button == 2) {
832         bool primary = webView->priv->usePrimaryForPaste;
833         webView->priv->usePrimaryForPaste = true;
834 
835         Editor* editor = webView->priv->corePage->focusController()->focusedOrMainFrame()->editor();
836         result = result || editor->canPaste() || editor->canDHTMLPaste();
837         editor->paste();
838 
839         webView->priv->usePrimaryForPaste = primary;
840     }
841 #endif
842 
843     return result;
844 }
845 
webkit_web_view_button_release_event(GtkWidget * widget,GdkEventButton * event)846 static gboolean webkit_web_view_button_release_event(GtkWidget* widget, GdkEventButton* event)
847 {
848     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
849 
850     Frame* focusedFrame = core(webView)->focusController()->focusedFrame();
851 
852     if (focusedFrame && focusedFrame->editor()->canEdit()) {
853 #ifdef MAEMO_CHANGES
854         WebKitWebViewPrivate* priv = webView->priv;
855         hildon_gtk_im_context_filter_event(priv->imContext.get(), (GdkEvent*)event);
856 #endif
857     }
858 
859     Frame* mainFrame = core(webView)->mainFrame();
860     if (mainFrame->view())
861         mainFrame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(event));
862 
863     /* We always return FALSE here because WebKit can, for the same click, decide
864      * to not handle press-event but handle release-event, which can totally confuse
865      * some GTK+ containers when there are no other events in between. This way we
866      * guarantee that this case never happens, and that if press-event goes through
867      * release-event also goes through.
868      */
869 
870     return FALSE;
871 }
872 
webkit_web_view_motion_event(GtkWidget * widget,GdkEventMotion * event)873 static gboolean webkit_web_view_motion_event(GtkWidget* widget, GdkEventMotion* event)
874 {
875     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
876 
877     Frame* frame = core(webView)->mainFrame();
878     if (!frame->view())
879         return FALSE;
880 
881     return frame->eventHandler()->mouseMoved(PlatformMouseEvent(event));
882 }
883 
webkit_web_view_scroll_event(GtkWidget * widget,GdkEventScroll * event)884 static gboolean webkit_web_view_scroll_event(GtkWidget* widget, GdkEventScroll* event)
885 {
886     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
887 
888     Frame* frame = core(webView)->mainFrame();
889     if (!frame->view())
890         return FALSE;
891 
892     PlatformWheelEvent wheelEvent(event);
893     return frame->eventHandler()->handleWheelEvent(wheelEvent);
894 }
895 
896 #ifdef GTK_API_VERSION_2
webkit_web_view_size_request(GtkWidget * widget,GtkRequisition * requisition)897 static void webkit_web_view_size_request(GtkWidget* widget, GtkRequisition* requisition)
898 {
899     WebKitWebView* web_view = WEBKIT_WEB_VIEW(widget);
900     Frame* coreFrame = core(webkit_web_view_get_main_frame(web_view));
901     if (!coreFrame)
902         return;
903 
904     FrameView* view = coreFrame->view();
905     if (!view)
906         return;
907 
908     requisition->width = view->contentsWidth();
909     requisition->height = view->contentsHeight();
910 }
911 #else
webkit_web_view_get_preferred_width(GtkWidget * widget,gint * minimum,gint * natural)912 static void webkit_web_view_get_preferred_width(GtkWidget* widget, gint* minimum, gint* natural)
913 {
914     WebKitWebView* web_view = WEBKIT_WEB_VIEW(widget);
915     Frame* coreFrame = core(webkit_web_view_get_main_frame(web_view));
916     if (!coreFrame)
917         return;
918 
919     FrameView* view = coreFrame->view();
920     if (!view)
921         return;
922 
923     *minimum = *natural = view->contentsWidth();
924 }
925 
webkit_web_view_get_preferred_height(GtkWidget * widget,gint * minimum,gint * natural)926 static void webkit_web_view_get_preferred_height(GtkWidget* widget, gint* minimum, gint* natural)
927 {
928     WebKitWebView* web_view = WEBKIT_WEB_VIEW(widget);
929     Frame* coreFrame = core(webkit_web_view_get_main_frame(web_view));
930     if (!coreFrame)
931         return;
932 
933     FrameView* view = coreFrame->view();
934     if (!view)
935         return;
936 
937     *minimum = *natural = view->contentsHeight();
938 }
939 #endif
940 
webkit_web_view_size_allocate(GtkWidget * widget,GtkAllocation * allocation)941 static void webkit_web_view_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
942 {
943     GTK_WIDGET_CLASS(webkit_web_view_parent_class)->size_allocate(widget,allocation);
944 
945     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
946 
947     Frame* frame = core(webView)->mainFrame();
948     if (!frame->view())
949         return;
950 
951     frame->view()->resize(allocation->width, allocation->height);
952 }
953 
webkit_web_view_grab_focus(GtkWidget * widget)954 static void webkit_web_view_grab_focus(GtkWidget* widget)
955 {
956 
957     if (gtk_widget_is_sensitive(widget)) {
958         WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
959         FocusController* focusController = core(webView)->focusController();
960 
961         focusController->setActive(true);
962 
963         if (focusController->focusedFrame())
964             focusController->setFocused(true);
965         else
966             focusController->setFocusedFrame(core(webView)->mainFrame());
967     }
968 
969     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->grab_focus(widget);
970 }
971 
webkit_web_view_focus_in_event(GtkWidget * widget,GdkEventFocus * event)972 static gboolean webkit_web_view_focus_in_event(GtkWidget* widget, GdkEventFocus* event)
973 {
974     // TODO: Improve focus handling as suggested in
975     // http://bugs.webkit.org/show_bug.cgi?id=16910
976     GtkWidget* toplevel = gtk_widget_get_toplevel(widget);
977     if (gtk_widget_is_toplevel(toplevel) && gtk_window_has_toplevel_focus(GTK_WINDOW(toplevel))) {
978         WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
979         FocusController* focusController = core(webView)->focusController();
980 
981         focusController->setActive(true);
982 
983         if (focusController->focusedFrame())
984             focusController->setFocused(true);
985         else
986             focusController->setFocusedFrame(core(webView)->mainFrame());
987 
988         if (focusController->focusedFrame()->editor()->canEdit())
989             gtk_im_context_focus_in(webView->priv->imContext.get());
990     }
991     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->focus_in_event(widget, event);
992 }
993 
webkit_web_view_focus_out_event(GtkWidget * widget,GdkEventFocus * event)994 static gboolean webkit_web_view_focus_out_event(GtkWidget* widget, GdkEventFocus* event)
995 {
996     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
997 
998     // We may hit this code while destroying the widget, and we might
999     // no longer have a page, then.
1000     Page* page = core(webView);
1001     if (page) {
1002         page->focusController()->setActive(false);
1003         page->focusController()->setFocused(false);
1004     }
1005 
1006     if (webView->priv->imContext)
1007         gtk_im_context_focus_out(webView->priv->imContext.get());
1008 
1009     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->focus_out_event(widget, event);
1010 }
1011 
webkit_web_view_realize(GtkWidget * widget)1012 static void webkit_web_view_realize(GtkWidget* widget)
1013 {
1014     gtk_widget_set_realized(widget, TRUE);
1015 
1016     GtkAllocation allocation;
1017 #if GTK_CHECK_VERSION(2, 18, 0)
1018     gtk_widget_get_allocation(widget, &allocation);
1019 #else
1020     allocation = widget->allocation;
1021 #endif
1022 
1023     GdkWindowAttr attributes;
1024     attributes.window_type = GDK_WINDOW_CHILD;
1025     attributes.x = allocation.x;
1026     attributes.y = allocation.y;
1027     attributes.width = allocation.width;
1028     attributes.height = allocation.height;
1029     attributes.wclass = GDK_INPUT_OUTPUT;
1030     attributes.visual = gtk_widget_get_visual(widget);
1031 #ifdef GTK_API_VERSION_2
1032     attributes.colormap = gtk_widget_get_colormap(widget);
1033 #endif
1034     attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK
1035                             | GDK_EXPOSURE_MASK
1036                             | GDK_BUTTON_PRESS_MASK
1037                             | GDK_BUTTON_RELEASE_MASK
1038                             | GDK_POINTER_MOTION_MASK
1039                             | GDK_KEY_PRESS_MASK
1040                             | GDK_KEY_RELEASE_MASK
1041                             | GDK_BUTTON_MOTION_MASK
1042                             | GDK_BUTTON1_MOTION_MASK
1043                             | GDK_BUTTON2_MOTION_MASK
1044                             | GDK_BUTTON3_MOTION_MASK;
1045 
1046     gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
1047 #ifdef GTK_API_VERSION_2
1048     attributes_mask |= GDK_WA_COLORMAP;
1049 #endif
1050     GdkWindow* window = gdk_window_new(gtk_widget_get_parent_window(widget), &attributes, attributes_mask);
1051     gtk_widget_set_window(widget, window);
1052     gdk_window_set_user_data(window, widget);
1053 
1054 #ifdef GTK_API_VERSION_2
1055 #if GTK_CHECK_VERSION(2, 20, 0)
1056     gtk_widget_style_attach(widget);
1057 #else
1058     widget->style = gtk_style_attach(gtk_widget_get_style(widget), window);
1059 #endif
1060     gtk_style_set_background(gtk_widget_get_style(widget), window, GTK_STATE_NORMAL);
1061 #else
1062     gtk_style_context_set_background(gtk_widget_get_style_context(widget), window);
1063 #endif
1064 
1065     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1066     WebKitWebViewPrivate* priv = webView->priv;
1067     gtk_im_context_set_client_window(priv->imContext.get(), window);
1068 }
1069 
1070 #ifdef GTK_API_VERSION_2
webkit_web_view_set_scroll_adjustments(WebKitWebView * webView,GtkAdjustment * hadj,GtkAdjustment * vadj)1071 static void webkit_web_view_set_scroll_adjustments(WebKitWebView* webView, GtkAdjustment* hadj, GtkAdjustment* vadj)
1072 {
1073     if (!core(webView))
1074         return;
1075 
1076     webView->priv->horizontalAdjustment = hadj;
1077     webView->priv->verticalAdjustment = vadj;
1078 
1079     FrameView* view = core(webkit_web_view_get_main_frame(webView))->view();
1080     if (!view)
1081         return;
1082     view->setGtkAdjustments(hadj, vadj);
1083 }
1084 #endif
1085 
webkit_web_view_container_add(GtkContainer * container,GtkWidget * widget)1086 static void webkit_web_view_container_add(GtkContainer* container, GtkWidget* widget)
1087 {
1088     WebKitWebView* webView = WEBKIT_WEB_VIEW(container);
1089     WebKitWebViewPrivate* priv = webView->priv;
1090 
1091     priv->children.add(widget);
1092     gtk_widget_set_parent(widget, GTK_WIDGET(container));
1093 }
1094 
webkit_web_view_container_remove(GtkContainer * container,GtkWidget * widget)1095 static void webkit_web_view_container_remove(GtkContainer* container, GtkWidget* widget)
1096 {
1097     WebKitWebView* webView = WEBKIT_WEB_VIEW(container);
1098     WebKitWebViewPrivate* priv = webView->priv;
1099 
1100     if (priv->children.contains(widget)) {
1101         gtk_widget_unparent(widget);
1102         priv->children.remove(widget);
1103     }
1104 }
1105 
webkit_web_view_container_forall(GtkContainer * container,gboolean,GtkCallback callback,gpointer callbackData)1106 static void webkit_web_view_container_forall(GtkContainer* container, gboolean, GtkCallback callback, gpointer callbackData)
1107 {
1108     WebKitWebView* webView = WEBKIT_WEB_VIEW(container);
1109     WebKitWebViewPrivate* priv = webView->priv;
1110 
1111     HashSet<GtkWidget*> children = priv->children;
1112     HashSet<GtkWidget*>::const_iterator end = children.end();
1113     for (HashSet<GtkWidget*>::const_iterator current = children.begin(); current != end; ++current)
1114         (*callback)(*current, callbackData);
1115 }
1116 
webkit_web_view_real_create_web_view(WebKitWebView *,WebKitWebFrame *)1117 static WebKitWebView* webkit_web_view_real_create_web_view(WebKitWebView*, WebKitWebFrame*)
1118 {
1119     return 0;
1120 }
1121 
webkit_web_view_real_web_view_ready(WebKitWebView *)1122 static gboolean webkit_web_view_real_web_view_ready(WebKitWebView*)
1123 {
1124     return FALSE;
1125 }
1126 
webkit_web_view_real_close_web_view(WebKitWebView *)1127 static gboolean webkit_web_view_real_close_web_view(WebKitWebView*)
1128 {
1129     return FALSE;
1130 }
1131 
webkit_web_view_real_navigation_requested(WebKitWebView *,WebKitWebFrame *,WebKitNetworkRequest *)1132 static WebKitNavigationResponse webkit_web_view_real_navigation_requested(WebKitWebView*, WebKitWebFrame*, WebKitNetworkRequest*)
1133 {
1134     return WEBKIT_NAVIGATION_RESPONSE_ACCEPT;
1135 }
1136 
webkit_web_view_real_window_object_cleared(WebKitWebView *,WebKitWebFrame *,JSGlobalContextRef context,JSObjectRef window_object)1137 static void webkit_web_view_real_window_object_cleared(WebKitWebView*, WebKitWebFrame*, JSGlobalContextRef context, JSObjectRef window_object)
1138 {
1139     notImplemented();
1140 }
1141 
webkit_web_view_real_choose_file(WebKitWebView *,WebKitWebFrame *,const gchar * old_name)1142 static gchar* webkit_web_view_real_choose_file(WebKitWebView*, WebKitWebFrame*, const gchar* old_name)
1143 {
1144     notImplemented();
1145     return g_strdup(old_name);
1146 }
1147 
1148 typedef enum {
1149     WEBKIT_SCRIPT_DIALOG_ALERT,
1150     WEBKIT_SCRIPT_DIALOG_CONFIRM,
1151     WEBKIT_SCRIPT_DIALOG_PROMPT
1152  } WebKitScriptDialogType;
1153 
webkit_web_view_script_dialog(WebKitWebView * webView,WebKitWebFrame * frame,const gchar * message,WebKitScriptDialogType type,const gchar * defaultValue,gchar ** value)1154 static gboolean webkit_web_view_script_dialog(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, WebKitScriptDialogType type, const gchar* defaultValue, gchar** value)
1155 {
1156     GtkMessageType messageType;
1157     GtkButtonsType buttons;
1158     gint defaultResponse;
1159     GtkWidget* window;
1160     GtkWidget* dialog;
1161     GtkWidget* entry = 0;
1162     gboolean didConfirm = FALSE;
1163 
1164     switch (type) {
1165     case WEBKIT_SCRIPT_DIALOG_ALERT:
1166         messageType = GTK_MESSAGE_WARNING;
1167         buttons = GTK_BUTTONS_CLOSE;
1168         defaultResponse = GTK_RESPONSE_CLOSE;
1169         break;
1170     case WEBKIT_SCRIPT_DIALOG_CONFIRM:
1171         messageType = GTK_MESSAGE_QUESTION;
1172         buttons = GTK_BUTTONS_OK_CANCEL;
1173         defaultResponse = GTK_RESPONSE_OK;
1174         break;
1175     case WEBKIT_SCRIPT_DIALOG_PROMPT:
1176         messageType = GTK_MESSAGE_QUESTION;
1177         buttons = GTK_BUTTONS_OK_CANCEL;
1178         defaultResponse = GTK_RESPONSE_OK;
1179         break;
1180     default:
1181         g_warning("Unknown value for WebKitScriptDialogType.");
1182         return FALSE;
1183     }
1184 
1185     window = gtk_widget_get_toplevel(GTK_WIDGET(webView));
1186     dialog = gtk_message_dialog_new(gtk_widget_is_toplevel(window) ? GTK_WINDOW(window) : 0, GTK_DIALOG_DESTROY_WITH_PARENT, messageType, buttons, "%s", message);
1187     gchar* title = g_strconcat("JavaScript - ", webkit_web_frame_get_uri(frame), NULL);
1188     gtk_window_set_title(GTK_WINDOW(dialog), title);
1189     g_free(title);
1190 
1191     if (type == WEBKIT_SCRIPT_DIALOG_PROMPT) {
1192         entry = gtk_entry_new();
1193         gtk_entry_set_text(GTK_ENTRY(entry), defaultValue);
1194         gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), entry);
1195         gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
1196         gtk_widget_show(entry);
1197     }
1198 
1199     gtk_dialog_set_default_response(GTK_DIALOG(dialog), defaultResponse);
1200     gint response = gtk_dialog_run(GTK_DIALOG(dialog));
1201 
1202     switch (response) {
1203     case GTK_RESPONSE_OK:
1204         didConfirm = TRUE;
1205         if (entry)
1206             *value = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
1207         break;
1208     case GTK_RESPONSE_CANCEL:
1209         didConfirm = FALSE;
1210         break;
1211 
1212     }
1213     gtk_widget_destroy(GTK_WIDGET(dialog));
1214     return didConfirm;
1215 }
1216 
webkit_web_view_real_script_alert(WebKitWebView * webView,WebKitWebFrame * frame,const gchar * message)1217 static gboolean webkit_web_view_real_script_alert(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message)
1218 {
1219     webkit_web_view_script_dialog(webView, frame, message, WEBKIT_SCRIPT_DIALOG_ALERT, 0, 0);
1220     return TRUE;
1221 }
1222 
webkit_web_view_real_script_confirm(WebKitWebView * webView,WebKitWebFrame * frame,const gchar * message,gboolean * didConfirm)1223 static gboolean webkit_web_view_real_script_confirm(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, gboolean* didConfirm)
1224 {
1225     *didConfirm = webkit_web_view_script_dialog(webView, frame, message, WEBKIT_SCRIPT_DIALOG_CONFIRM, 0, 0);
1226     return TRUE;
1227 }
1228 
webkit_web_view_real_script_prompt(WebKitWebView * webView,WebKitWebFrame * frame,const gchar * message,const gchar * defaultValue,gchar ** value)1229 static gboolean webkit_web_view_real_script_prompt(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, const gchar* defaultValue, gchar** value)
1230 {
1231     if (!webkit_web_view_script_dialog(webView, frame, message, WEBKIT_SCRIPT_DIALOG_PROMPT, defaultValue, value))
1232         *value = NULL;
1233     return TRUE;
1234 }
1235 
webkit_web_view_real_console_message(WebKitWebView * webView,const gchar * message,unsigned int line,const gchar * sourceId)1236 static gboolean webkit_web_view_real_console_message(WebKitWebView* webView, const gchar* message, unsigned int line, const gchar* sourceId)
1237 {
1238     g_message("console message: %s @%d: %s\n", sourceId, line, message);
1239     return TRUE;
1240 }
1241 
webkit_web_view_real_select_all(WebKitWebView * webView)1242 static void webkit_web_view_real_select_all(WebKitWebView* webView)
1243 {
1244     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
1245     frame->editor()->command("SelectAll").execute();
1246 }
1247 
webkit_web_view_real_cut_clipboard(WebKitWebView * webView)1248 static void webkit_web_view_real_cut_clipboard(WebKitWebView* webView)
1249 {
1250     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
1251     frame->editor()->command("Cut").execute();
1252 }
1253 
webkit_web_view_real_copy_clipboard(WebKitWebView * webView)1254 static void webkit_web_view_real_copy_clipboard(WebKitWebView* webView)
1255 {
1256     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
1257     frame->editor()->command("Copy").execute();
1258 }
1259 
webkit_web_view_real_undo(WebKitWebView * webView)1260 static void webkit_web_view_real_undo(WebKitWebView* webView)
1261 {
1262     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
1263     frame->editor()->command("Undo").execute();
1264 }
1265 
webkit_web_view_real_redo(WebKitWebView * webView)1266 static void webkit_web_view_real_redo(WebKitWebView* webView)
1267 {
1268     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
1269     frame->editor()->command("Redo").execute();
1270 }
1271 
webkit_web_view_real_move_cursor(WebKitWebView * webView,GtkMovementStep step,gint count)1272 static gboolean webkit_web_view_real_move_cursor (WebKitWebView* webView, GtkMovementStep step, gint count)
1273 {
1274     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW (webView), FALSE);
1275     g_return_val_if_fail(step == GTK_MOVEMENT_VISUAL_POSITIONS ||
1276                          step == GTK_MOVEMENT_DISPLAY_LINES ||
1277                          step == GTK_MOVEMENT_PAGES ||
1278                          step == GTK_MOVEMENT_BUFFER_ENDS, FALSE);
1279     g_return_val_if_fail(count == 1 || count == -1, FALSE);
1280 
1281     ScrollDirection direction;
1282     ScrollGranularity granularity;
1283 
1284     switch (step) {
1285     case GTK_MOVEMENT_DISPLAY_LINES:
1286         granularity = ScrollByLine;
1287         if (count == 1)
1288             direction = ScrollDown;
1289         else
1290             direction = ScrollUp;
1291         break;
1292     case GTK_MOVEMENT_VISUAL_POSITIONS:
1293         granularity = ScrollByLine;
1294         if (count == 1)
1295             direction = ScrollRight;
1296         else
1297             direction = ScrollLeft;
1298         break;
1299     case GTK_MOVEMENT_PAGES:
1300         granularity = ScrollByPage;
1301         if (count == 1)
1302             direction = ScrollDown;
1303         else
1304             direction = ScrollUp;
1305         break;
1306     case GTK_MOVEMENT_BUFFER_ENDS:
1307         granularity = ScrollByDocument;
1308         if (count == 1)
1309             direction = ScrollDown;
1310         else
1311             direction = ScrollUp;
1312         break;
1313     default:
1314         g_assert_not_reached();
1315         return false;
1316     }
1317 
1318     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
1319     if (!frame->eventHandler()->scrollOverflow(direction, granularity))
1320         frame->view()->scroll(direction, granularity);
1321 
1322     return true;
1323 }
1324 
webkit_web_view_real_paste_clipboard(WebKitWebView * webView)1325 static void webkit_web_view_real_paste_clipboard(WebKitWebView* webView)
1326 {
1327     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
1328     frame->editor()->command("Paste").execute();
1329 }
1330 
webkit_web_view_real_should_allow_editing_action(WebKitWebView *)1331 static gboolean webkit_web_view_real_should_allow_editing_action(WebKitWebView*)
1332 {
1333     return TRUE;
1334 }
1335 
webkit_web_view_dispose(GObject * object)1336 static void webkit_web_view_dispose(GObject* object)
1337 {
1338     WebKitWebView* webView = WEBKIT_WEB_VIEW(object);
1339     WebKitWebViewPrivate* priv = webView->priv;
1340 
1341     priv->disposing = TRUE;
1342 
1343     // These smart pointers are cleared manually, because some cleanup operations are
1344     // very sensitive to their value. We may crash if these are done in the wrong order.
1345     priv->horizontalAdjustment.clear();
1346     priv->verticalAdjustment.clear();
1347     priv->backForwardList.clear();
1348 
1349     if (priv->corePage) {
1350         webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(object));
1351         core(priv->mainFrame)->loader()->detachFromParent();
1352         delete priv->corePage;
1353         priv->corePage = 0;
1354     }
1355 
1356     if (priv->webSettings) {
1357         g_signal_handlers_disconnect_by_func(priv->webSettings.get(), (gpointer)webkit_web_view_settings_notify, webView);
1358         priv->webSettings.clear();
1359     }
1360 
1361     if (priv->currentMenu) {
1362         gtk_widget_destroy(GTK_WIDGET(priv->currentMenu));
1363         priv->currentMenu = 0;
1364     }
1365 
1366     priv->webInspector.clear();
1367     priv->viewportAttributes.clear();
1368     priv->webWindowFeatures.clear();
1369     priv->mainResource.clear();
1370     priv->subResources.clear();
1371 
1372     HashMap<GdkDragContext*, DroppingContext*>::iterator endDroppingContexts = priv->droppingContexts.end();
1373     for (HashMap<GdkDragContext*, DroppingContext*>::iterator iter = priv->droppingContexts.begin(); iter != endDroppingContexts; ++iter)
1374         delete (iter->second);
1375     priv->droppingContexts.clear();
1376 
1377     G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object);
1378 }
1379 
webkit_web_view_finalize(GObject * object)1380 static void webkit_web_view_finalize(GObject* object)
1381 {
1382     // We need to manually call the destructor here, since this object's memory is managed
1383     // by GLib. This calls all C++ members' destructors and prevents memory leaks.
1384     WEBKIT_WEB_VIEW(object)->priv->~WebKitWebViewPrivate();
1385     G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object);
1386 }
1387 
webkit_signal_accumulator_object_handled(GSignalInvocationHint * ihint,GValue * returnAccu,const GValue * handlerReturn,gpointer dummy)1388 static gboolean webkit_signal_accumulator_object_handled(GSignalInvocationHint* ihint, GValue* returnAccu, const GValue* handlerReturn, gpointer dummy)
1389 {
1390     gpointer newWebView = g_value_get_object(handlerReturn);
1391     g_value_set_object(returnAccu, newWebView);
1392 
1393     // Continue if we don't have a newWebView
1394     return !newWebView;
1395 }
1396 
webkit_navigation_request_handled(GSignalInvocationHint * ihint,GValue * returnAccu,const GValue * handlerReturn,gpointer dummy)1397 static gboolean webkit_navigation_request_handled(GSignalInvocationHint* ihint, GValue* returnAccu, const GValue* handlerReturn, gpointer dummy)
1398 {
1399     WebKitNavigationResponse navigationResponse = (WebKitNavigationResponse)g_value_get_enum(handlerReturn);
1400     g_value_set_enum(returnAccu, navigationResponse);
1401 
1402     if (navigationResponse != WEBKIT_NAVIGATION_RESPONSE_ACCEPT)
1403         return FALSE;
1404 
1405     return TRUE;
1406 }
1407 
webkit_web_view_get_accessible(GtkWidget * widget)1408 static AtkObject* webkit_web_view_get_accessible(GtkWidget* widget)
1409 {
1410     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1411     if (!core(webView))
1412         return 0;
1413 
1414     AXObjectCache::enableAccessibility();
1415 
1416     Frame* coreFrame = core(webView)->mainFrame();
1417     if (!coreFrame)
1418         return 0;
1419 
1420     Document* doc = coreFrame->document();
1421     if (!doc)
1422         return 0;
1423 
1424     AccessibilityObject* rootAccessible = doc->axObjectCache()->rootObject();
1425     if (!rootAccessible)
1426         return 0;
1427 
1428     // We need to return the root accessibility object's first child
1429     // to get to the actual ATK Object associated with the web view.
1430     // See https://bugs.webkit.org/show_bug.cgi?id=51932
1431     AtkObject* axRoot = rootAccessible->wrapper();
1432     if (!axRoot || !ATK_IS_OBJECT(axRoot))
1433         return 0;
1434 
1435     AtkObject* axWebView = atk_object_ref_accessible_child(ATK_OBJECT(axRoot), 0);
1436     if (!axWebView || !ATK_IS_OBJECT(axWebView))
1437         return 0;
1438 
1439     // We don't want the extra reference returned by ref_accessible_child.
1440     g_object_unref(axWebView);
1441     return axWebView;
1442 }
1443 
webViewGetDPI(WebKitWebView * webView)1444 static gdouble webViewGetDPI(WebKitWebView* webView)
1445 {
1446     WebKitWebViewPrivate* priv = webView->priv;
1447     WebKitWebSettings* webSettings = priv->webSettings.get();
1448     gboolean enforce96DPI;
1449     g_object_get(webSettings, "enforce-96-dpi", &enforce96DPI, NULL);
1450     if (enforce96DPI)
1451         return 96.0;
1452 
1453     gdouble DPI = defaultDPI;
1454     GdkScreen* screen = gtk_widget_has_screen(GTK_WIDGET(webView)) ? gtk_widget_get_screen(GTK_WIDGET(webView)) : gdk_screen_get_default();
1455     if (screen) {
1456         DPI = gdk_screen_get_resolution(screen);
1457         // gdk_screen_get_resolution() returns -1 when no DPI is set.
1458         if (DPI == -1)
1459             DPI = defaultDPI;
1460     }
1461     ASSERT(DPI > 0);
1462     return DPI;
1463 }
1464 
webkit_web_view_screen_changed(GtkWidget * widget,GdkScreen * previousScreen)1465 static void webkit_web_view_screen_changed(GtkWidget* widget, GdkScreen* previousScreen)
1466 {
1467     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1468     WebKitWebViewPrivate* priv = webView->priv;
1469 
1470     if (priv->disposing)
1471         return;
1472 
1473     WebKitWebSettings* webSettings = priv->webSettings.get();
1474     Settings* settings = core(webView)->settings();
1475     gdouble DPI = webViewGetDPI(webView);
1476 
1477     guint defaultFontSize, defaultMonospaceFontSize, minimumFontSize, minimumLogicalFontSize;
1478 
1479     g_object_get(webSettings,
1480                  "default-font-size", &defaultFontSize,
1481                  "default-monospace-font-size", &defaultMonospaceFontSize,
1482                  "minimum-font-size", &minimumFontSize,
1483                  "minimum-logical-font-size", &minimumLogicalFontSize,
1484                  NULL);
1485 
1486     settings->setDefaultFontSize(defaultFontSize / 72.0 * DPI);
1487     settings->setDefaultFixedFontSize(defaultMonospaceFontSize / 72.0 * DPI);
1488     settings->setMinimumFontSize(minimumFontSize / 72.0 * DPI);
1489     settings->setMinimumLogicalFontSize(minimumLogicalFontSize / 72.0 * DPI);
1490 }
1491 
globalPointForClientPoint(GdkWindow * window,const IntPoint & clientPoint)1492 static IntPoint globalPointForClientPoint(GdkWindow* window, const IntPoint& clientPoint)
1493 {
1494     int x, y;
1495     gdk_window_get_origin(window, &x, &y);
1496     return clientPoint + IntSize(x, y);
1497 }
1498 
1499 
webkit_web_view_drag_end(GtkWidget * widget,GdkDragContext * context)1500 static void webkit_web_view_drag_end(GtkWidget* widget, GdkDragContext* context)
1501 {
1502     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1503     WebKitWebViewPrivate* priv = webView->priv;
1504 
1505     // This might happen if a drag is still in progress after a WebKitWebView
1506     // is disposed and before it is finalized.
1507     if (!priv->draggingDataObjects.contains(context))
1508         return;
1509 
1510     priv->draggingDataObjects.remove(context);
1511 
1512     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
1513     if (!frame)
1514         return;
1515 
1516     GOwnPtr<GdkEvent> event(gdk_event_new(GDK_BUTTON_RELEASE));
1517     int x, y, xRoot, yRoot;
1518     GdkModifierType modifiers = static_cast<GdkModifierType>(0);
1519 #ifdef GTK_API_VERSION_2
1520     GdkDisplay* display = gdk_display_get_default();
1521     gdk_display_get_pointer(display, 0, &xRoot, &yRoot, &modifiers);
1522     event->button.window = gdk_display_get_window_at_pointer(display, &x, &y);
1523 #else
1524     GdkDevice* device = gdk_drag_context_get_device(context);
1525     event->button.window = gdk_device_get_window_at_position(device, &x, &y);
1526     gdk_device_get_position(device, 0, &xRoot, &yRoot);
1527 #endif
1528 
1529     if (event->button.window)
1530         g_object_ref(event->button.window);
1531     event->button.x = x;
1532     event->button.y = y;
1533     event->button.x_root = xRoot;
1534     event->button.y_root = yRoot;
1535     event->button.state = modifiers;
1536 
1537     PlatformMouseEvent platformEvent(&event->button);
1538     frame->eventHandler()->dragSourceEndedAt(platformEvent, gdkDragActionToDragOperation(gdk_drag_context_get_selected_action(context)));
1539 }
1540 
webkit_web_view_drag_data_get(GtkWidget * widget,GdkDragContext * context,GtkSelectionData * selectionData,guint info,guint)1541 static void webkit_web_view_drag_data_get(GtkWidget* widget, GdkDragContext* context, GtkSelectionData* selectionData, guint info, guint)
1542 {
1543     WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(widget)->priv;
1544 
1545     // This might happen if a drag is still in progress after a WebKitWebView
1546     // is diposed and before it is finalized.
1547     if (!priv->draggingDataObjects.contains(context))
1548         return;
1549 
1550     pasteboardHelperInstance()->fillSelectionData(selectionData, info, priv->draggingDataObjects.get(context).get());
1551 }
1552 
doDragLeaveLater(DroppingContext * context)1553 static gboolean doDragLeaveLater(DroppingContext* context)
1554 {
1555     WebKitWebView* webView = context->webView;
1556     WebKitWebViewPrivate* priv = webView->priv;
1557 
1558     if (!priv->droppingContexts.contains(context->gdkContext))
1559         return FALSE;
1560 
1561     // If the view doesn't know about the drag yet (there are still pending data)
1562     // requests, don't update it with information about the drag.
1563     if (context->pendingDataRequests)
1564         return FALSE;
1565 
1566     // Don't call dragExited if we have just received a drag-drop signal. This
1567     // happens in the case of a successful drop onto the view.
1568     if (!context->dropHappened) {
1569         const IntPoint& position = context->lastMotionPosition;
1570         DragData dragData(context->dataObject.get(), position, globalPointForClientPoint(gtk_widget_get_window(GTK_WIDGET(webView)), position), DragOperationNone);
1571         core(webView)->dragController()->dragExited(&dragData);
1572     }
1573 
1574     core(webView)->dragController()->dragEnded();
1575     priv->droppingContexts.remove(context->gdkContext);
1576     delete context;
1577     return FALSE;
1578 }
1579 
webkit_web_view_drag_leave(GtkWidget * widget,GdkDragContext * context,guint time)1580 static void webkit_web_view_drag_leave(GtkWidget* widget, GdkDragContext* context, guint time)
1581 {
1582     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1583     WebKitWebViewPrivate* priv = webView->priv;
1584 
1585     if (!priv->droppingContexts.contains(context))
1586         return;
1587 
1588     // During a drop GTK+ will fire a drag-leave signal right before firing
1589     // the drag-drop signal. We want the actions for drag-leave to happen after
1590     // those for drag-drop, so schedule them to happen asynchronously here.
1591     g_timeout_add(0, reinterpret_cast<GSourceFunc>(doDragLeaveLater), priv->droppingContexts.get(context));
1592 }
1593 
webkit_web_view_drag_motion(GtkWidget * widget,GdkDragContext * context,gint x,gint y,guint time)1594 static gboolean webkit_web_view_drag_motion(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time)
1595 {
1596     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1597     WebKitWebViewPrivate* priv = webView->priv;
1598 
1599     DroppingContext* droppingContext = 0;
1600     IntPoint position = IntPoint(x, y);
1601     if (!priv->droppingContexts.contains(context)) {
1602         droppingContext = new DroppingContext;
1603         droppingContext->webView = webView;
1604         droppingContext->gdkContext = context;
1605         droppingContext->dataObject = WebCore::DataObjectGtk::create();
1606         droppingContext->dropHappened = false;
1607         droppingContext->lastMotionPosition = position;
1608         priv->droppingContexts.set(context, droppingContext);
1609 
1610         Vector<GdkAtom> acceptableTargets(pasteboardHelperInstance()->dropAtomsForContext(widget, context));
1611         droppingContext->pendingDataRequests = acceptableTargets.size();
1612         for (size_t i = 0; i < acceptableTargets.size(); i++)
1613             gtk_drag_get_data(widget, context, acceptableTargets.at(i), time);
1614     } else {
1615         droppingContext = priv->droppingContexts.get(context);
1616         droppingContext->lastMotionPosition = position;
1617     }
1618 
1619     // Don't send any drag information to WebCore until we've retrieved all
1620     // the data for this drag operation. Otherwise we'd have to block to wait
1621     // for the drag's data.
1622     ASSERT(droppingContext);
1623     if (droppingContext->pendingDataRequests > 0)
1624         return TRUE;
1625 
1626     DragData dragData(droppingContext->dataObject.get(), position, globalPointForClientPoint(gtk_widget_get_window(widget), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
1627     DragOperation operation = core(webView)->dragController()->dragUpdated(&dragData);
1628     gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time);
1629 
1630     return TRUE;
1631 }
1632 
webkit_web_view_drag_data_received(GtkWidget * widget,GdkDragContext * context,gint x,gint y,GtkSelectionData * selectionData,guint info,guint time)1633 static void webkit_web_view_drag_data_received(GtkWidget* widget, GdkDragContext* context, gint x, gint y, GtkSelectionData* selectionData, guint info, guint time)
1634 {
1635     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1636     WebKitWebViewPrivate* priv = webView->priv;
1637 
1638     if (!priv->droppingContexts.contains(context))
1639         return;
1640 
1641     DroppingContext* droppingContext = priv->droppingContexts.get(context);
1642     droppingContext->pendingDataRequests--;
1643     pasteboardHelperInstance()->fillDataObjectFromDropData(selectionData, info, droppingContext->dataObject.get());
1644 
1645     if (droppingContext->pendingDataRequests)
1646         return;
1647 
1648     // The coordinates passed to drag-data-received signal are sometimes
1649     // inaccurate in DRT, so use the coordinates of the last motion event.
1650     const IntPoint& position = droppingContext->lastMotionPosition;
1651 
1652     // If there are no more pending requests, start sending dragging data to WebCore.
1653     DragData dragData(droppingContext->dataObject.get(), position, globalPointForClientPoint(gtk_widget_get_window(widget), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
1654     DragOperation operation = core(webView)->dragController()->dragEntered(&dragData);
1655     gdk_drag_status(context, dragOperationToSingleGdkDragAction(operation), time);
1656 }
1657 
webkit_web_view_drag_drop(GtkWidget * widget,GdkDragContext * context,gint x,gint y,guint time)1658 static gboolean webkit_web_view_drag_drop(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time)
1659 {
1660     WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1661     WebKitWebViewPrivate* priv = webView->priv;
1662 
1663     if (!priv->droppingContexts.contains(context))
1664         return FALSE;
1665 
1666     DroppingContext* droppingContext = priv->droppingContexts.get(context);
1667     droppingContext->dropHappened = true;
1668 
1669     IntPoint position(x, y);
1670     DragData dragData(droppingContext->dataObject.get(), position, globalPointForClientPoint(gtk_widget_get_window(widget), position), gdkDragActionToDragOperation(gdk_drag_context_get_actions(context)));
1671     core(webView)->dragController()->performDrag(&dragData);
1672 
1673     gtk_drag_finish(context, TRUE, FALSE, time);
1674     return TRUE;
1675 }
1676 
1677 #if GTK_CHECK_VERSION(2, 12, 0)
webkit_web_view_query_tooltip(GtkWidget * widget,gint x,gint y,gboolean keyboard_mode,GtkTooltip * tooltip)1678 static gboolean webkit_web_view_query_tooltip(GtkWidget *widget, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip)
1679 {
1680     WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW(widget)->priv;
1681 
1682     if (keyboard_mode) {
1683         WebKitWebView* webView = WEBKIT_WEB_VIEW(widget);
1684 
1685         // Get the title of the current focused element.
1686         Frame* coreFrame = core(webView)->focusController()->focusedOrMainFrame();
1687         if (!coreFrame)
1688             return FALSE;
1689 
1690         Node* node = getFocusedNode(coreFrame);
1691         if (!node)
1692             return FALSE;
1693 
1694         for (Node* titleNode = node; titleNode; titleNode = titleNode->parentNode()) {
1695             if (titleNode->isElementNode()) {
1696                 String title = static_cast<Element*>(titleNode)->title();
1697                 if (!title.isEmpty()) {
1698                     if (FrameView* view = coreFrame->view()) {
1699                         GdkRectangle area = view->contentsToWindow(node->getRect());
1700                         gtk_tooltip_set_tip_area(tooltip, &area);
1701                     }
1702                     gtk_tooltip_set_text(tooltip, title.utf8().data());
1703 
1704                     return TRUE;
1705                 }
1706             }
1707         }
1708 
1709         return FALSE;
1710     }
1711 
1712     if (priv->tooltipText.length() > 0) {
1713         if (!keyboard_mode) {
1714             if (!priv->tooltipArea.isEmpty()) {
1715                 GdkRectangle area = priv->tooltipArea;
1716                 gtk_tooltip_set_tip_area(tooltip, &area);
1717             } else
1718                 gtk_tooltip_set_tip_area(tooltip, 0);
1719         }
1720         gtk_tooltip_set_text(tooltip, priv->tooltipText.data());
1721         return TRUE;
1722     }
1723 
1724     return FALSE;
1725 }
1726 
webkit_web_view_show_help(GtkWidget * widget,GtkWidgetHelpType help_type)1727 static gboolean webkit_web_view_show_help(GtkWidget* widget, GtkWidgetHelpType help_type)
1728 {
1729     if (help_type == GTK_WIDGET_HELP_TOOLTIP)
1730         gtk_widget_set_has_tooltip(widget, TRUE);
1731 
1732     return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->show_help(widget, help_type);
1733 }
1734 #endif
1735 
webkit_web_view_get_im_context(WebKitWebView * webView)1736 static GtkIMContext* webkit_web_view_get_im_context(WebKitWebView* webView)
1737 {
1738     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
1739     return GTK_IM_CONTEXT(webView->priv->imContext.get());
1740 }
1741 
webkit_web_view_class_init(WebKitWebViewClass * webViewClass)1742 static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
1743 {
1744     GtkBindingSet* binding_set;
1745 
1746     webkitInit();
1747 
1748     /*
1749      * Signals
1750      */
1751 
1752     /**
1753      * WebKitWebView::create-web-view:
1754      * @webView: the object on which the signal is emitted
1755      * @frame: the #WebKitWebFrame
1756      *
1757      * Emitted when the creation of a new window is requested.
1758      * If this signal is handled the signal handler should return the
1759      * newly created #WebKitWebView.
1760      *
1761      * The new #WebKitWebView should not be displayed to the user
1762      * until the #WebKitWebView::web-view-ready signal is emitted.
1763      *
1764      * The signal handlers should not try to deal with the reference count for
1765      * the new #WebKitWebView. The widget to which the widget is added will
1766      * handle that.
1767      *
1768      * Return value: (transfer full): a newly allocated #WebKitWebView, or %NULL
1769      *
1770      * Since: 1.0.3
1771      */
1772     webkit_web_view_signals[CREATE_WEB_VIEW] = g_signal_new("create-web-view",
1773             G_TYPE_FROM_CLASS(webViewClass),
1774             (GSignalFlags)G_SIGNAL_RUN_LAST,
1775             G_STRUCT_OFFSET (WebKitWebViewClass, create_web_view),
1776             webkit_signal_accumulator_object_handled,
1777             NULL,
1778             webkit_marshal_OBJECT__OBJECT,
1779             WEBKIT_TYPE_WEB_VIEW , 1,
1780             WEBKIT_TYPE_WEB_FRAME);
1781 
1782     /**
1783      * WebKitWebView::web-view-ready:
1784      * @webView: the object on which the signal is emitted
1785      *
1786      * Emitted after #WebKitWebView::create-web-view when the new #WebKitWebView
1787      * should be displayed to the user. When this signal is emitted
1788      * all the information about how the window should look, including
1789      * size, position, whether the location, status and scroll bars
1790      * should be displayed, is already set on the
1791      * #WebKitWebWindowFeatures object contained by the #WebKitWebView.
1792      *
1793      * Notice that some of that information may change during the life
1794      * time of the window, so you may want to connect to the ::notify
1795      * signal of the #WebKitWebWindowFeatures object to handle those.
1796      *
1797      * Return value: %TRUE to stop handlers from being invoked for the event or
1798      * %FALSE to propagate the event furter
1799      *
1800      * Since: 1.0.3
1801      */
1802     webkit_web_view_signals[WEB_VIEW_READY] = g_signal_new("web-view-ready",
1803             G_TYPE_FROM_CLASS(webViewClass),
1804             (GSignalFlags)G_SIGNAL_RUN_LAST,
1805             G_STRUCT_OFFSET (WebKitWebViewClass, web_view_ready),
1806             g_signal_accumulator_true_handled,
1807             NULL,
1808             webkit_marshal_BOOLEAN__VOID,
1809             G_TYPE_BOOLEAN, 0);
1810 
1811     /**
1812      * WebKitWebView::close-web-view:
1813      * @webView: the object on which the signal is emitted
1814      *
1815      * Emitted when closing a #WebKitWebView is requested. This occurs when a
1816      * call is made from JavaScript's window.close function. The default
1817      * signal handler does not do anything. It is the owner's responsibility
1818      * to hide or delete the web view, if necessary.
1819      *
1820      * Return value: %TRUE to stop handlers from being invoked for the event or
1821      * %FALSE to propagate the event furter
1822      *
1823      * Since: 1.1.11
1824      */
1825     webkit_web_view_signals[CLOSE_WEB_VIEW] = g_signal_new("close-web-view",
1826             G_TYPE_FROM_CLASS(webViewClass),
1827             (GSignalFlags)G_SIGNAL_RUN_LAST,
1828             G_STRUCT_OFFSET (WebKitWebViewClass, close_web_view),
1829             g_signal_accumulator_true_handled,
1830             NULL,
1831             webkit_marshal_BOOLEAN__VOID,
1832             G_TYPE_BOOLEAN, 0);
1833 
1834     /**
1835      * WebKitWebView::navigation-requested:
1836      * @webView: the object on which the signal is emitted
1837      * @frame: the #WebKitWebFrame that required the navigation
1838      * @request: a #WebKitNetworkRequest
1839      *
1840      * Emitted when @frame requests a navigation to another page.
1841      *
1842      * Return value: a #WebKitNavigationResponse
1843      *
1844      * Deprecated: Use WebKitWebView::navigation-policy-decision-requested
1845      * instead
1846      */
1847     webkit_web_view_signals[NAVIGATION_REQUESTED] = g_signal_new("navigation-requested",
1848             G_TYPE_FROM_CLASS(webViewClass),
1849             (GSignalFlags)G_SIGNAL_RUN_LAST,
1850             G_STRUCT_OFFSET (WebKitWebViewClass, navigation_requested),
1851             webkit_navigation_request_handled,
1852             NULL,
1853             webkit_marshal_ENUM__OBJECT_OBJECT,
1854             WEBKIT_TYPE_NAVIGATION_RESPONSE, 2,
1855             WEBKIT_TYPE_WEB_FRAME,
1856             WEBKIT_TYPE_NETWORK_REQUEST);
1857 
1858     /**
1859      * WebKitWebView::new-window-policy-decision-requested:
1860      * @webView: the object on which the signal is emitted
1861      * @frame: the #WebKitWebFrame that required the navigation
1862      * @request: a #WebKitNetworkRequest
1863      * @navigation_action: a #WebKitWebNavigationAction
1864      * @policy_decision: a #WebKitWebPolicyDecision
1865      *
1866      * Emitted when @frame requests opening a new window. With this
1867      * signal the browser can use the context of the request to decide
1868      * about the new window. If the request is not handled the default
1869      * behavior is to allow opening the new window to load the URI,
1870      * which will cause a create-web-view signal emission where the
1871      * browser handles the new window action but without information
1872      * of the context that caused the navigation. The following
1873      * navigation-policy-decision-requested emissions will load the
1874      * page after the creation of the new window just with the
1875      * information of this new navigation context, without any
1876      * information about the action that made this new window to be
1877      * opened.
1878      *
1879      * Notice that if you return TRUE, meaning that you handled the
1880      * signal, you are expected to have decided what to do, by calling
1881      * webkit_web_policy_decision_ignore(),
1882      * webkit_web_policy_decision_use(), or
1883      * webkit_web_policy_decision_download() on the @policy_decision
1884      * object.
1885      *
1886      * Return value: %TRUE if a decision was made, %FALSE to have the
1887      * default behavior apply
1888      *
1889      * Since: 1.1.4
1890      */
1891     webkit_web_view_signals[NEW_WINDOW_POLICY_DECISION_REQUESTED] =
1892         g_signal_new("new-window-policy-decision-requested",
1893             G_TYPE_FROM_CLASS(webViewClass),
1894             (GSignalFlags)G_SIGNAL_RUN_LAST,
1895             0,
1896             g_signal_accumulator_true_handled,
1897             NULL,
1898             webkit_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT_OBJECT,
1899             G_TYPE_BOOLEAN, 4,
1900             WEBKIT_TYPE_WEB_FRAME,
1901             WEBKIT_TYPE_NETWORK_REQUEST,
1902             WEBKIT_TYPE_WEB_NAVIGATION_ACTION,
1903             WEBKIT_TYPE_WEB_POLICY_DECISION);
1904 
1905     /**
1906      * WebKitWebView::navigation-policy-decision-requested:
1907      * @webView: the object on which the signal is emitted
1908      * @frame: the #WebKitWebFrame that required the navigation
1909      * @request: a #WebKitNetworkRequest
1910      * @navigation_action: a #WebKitWebNavigationAction
1911      * @policy_decision: a #WebKitWebPolicyDecision
1912      *
1913      * Emitted when @frame requests a navigation to another page.
1914      * If this signal is not handled, the default behavior is to allow the
1915      * navigation.
1916      *
1917      * Notice that if you return TRUE, meaning that you handled the
1918      * signal, you are expected to have decided what to do, by calling
1919      * webkit_web_policy_decision_ignore(),
1920      * webkit_web_policy_decision_use(), or
1921      * webkit_web_policy_decision_download() on the @policy_decision
1922      * object.
1923      *
1924      * Return value: %TRUE if a decision was made, %FALSE to have the
1925      * default behavior apply
1926      *
1927      * Since: 1.0.3
1928      */
1929     webkit_web_view_signals[NAVIGATION_POLICY_DECISION_REQUESTED] = g_signal_new("navigation-policy-decision-requested",
1930             G_TYPE_FROM_CLASS(webViewClass),
1931             (GSignalFlags)G_SIGNAL_RUN_LAST,
1932             0,
1933             g_signal_accumulator_true_handled,
1934             NULL,
1935             webkit_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT_OBJECT,
1936             G_TYPE_BOOLEAN, 4,
1937             WEBKIT_TYPE_WEB_FRAME,
1938             WEBKIT_TYPE_NETWORK_REQUEST,
1939             WEBKIT_TYPE_WEB_NAVIGATION_ACTION,
1940             WEBKIT_TYPE_WEB_POLICY_DECISION);
1941 
1942     /**
1943      * WebKitWebView::mime-type-policy-decision-requested:
1944      * @webView: the object on which the signal is emitted
1945      * @frame: the #WebKitWebFrame that required the policy decision
1946      * @request: a WebKitNetworkRequest
1947      * @mimetype: the MIME type attempted to load
1948      * @policy_decision: a #WebKitWebPolicyDecision
1949      *
1950      * Decide whether or not to display the given MIME type.  If this
1951      * signal is not handled, the default behavior is to show the
1952      * content of the requested URI if WebKit can show this MIME
1953      * type and the content disposition is not a download; if WebKit
1954      * is not able to show the MIME type nothing happens.
1955      *
1956      * Notice that if you return TRUE, meaning that you handled the
1957      * signal, you are expected to be aware of the "Content-Disposition"
1958      * header. A value of "attachment" usually indicates a download
1959      * regardless of the MIME type, see also
1960      * soup_message_headers_get_content_disposition(). And you must call
1961      * webkit_web_policy_decision_ignore(),
1962      * webkit_web_policy_decision_use(), or
1963      * webkit_web_policy_decision_download() on the @policy_decision
1964      * object.
1965      *
1966      * Return value: %TRUE if a decision was made, %FALSE to have the
1967      * default behavior apply
1968      *
1969      * Since: 1.0.3
1970      */
1971     webkit_web_view_signals[MIME_TYPE_POLICY_DECISION_REQUESTED] = g_signal_new("mime-type-policy-decision-requested",
1972             G_TYPE_FROM_CLASS(webViewClass),
1973             (GSignalFlags)G_SIGNAL_RUN_LAST,
1974             0,
1975             g_signal_accumulator_true_handled,
1976             NULL,
1977             webkit_marshal_BOOLEAN__OBJECT_OBJECT_STRING_OBJECT,
1978             G_TYPE_BOOLEAN, 4,
1979             WEBKIT_TYPE_WEB_FRAME,
1980             WEBKIT_TYPE_NETWORK_REQUEST,
1981             G_TYPE_STRING,
1982             WEBKIT_TYPE_WEB_POLICY_DECISION);
1983 
1984     /**
1985      * WebKitWebView::window-object-cleared:
1986      * @webView: the object on which the signal is emitted
1987      * @frame: the #WebKitWebFrame to which @window_object belongs
1988      * @context: the #JSGlobalContextRef holding the global object and other
1989      * execution state; equivalent to the return value of
1990      * webkit_web_frame_get_global_context(@frame)
1991      * @window_object: the #JSObjectRef representing the frame's JavaScript
1992      * window object
1993      *
1994      * Emitted when the JavaScript window object in a #WebKitWebFrame has been
1995      * cleared in preparation for a new load. This is the preferred place to
1996      * set custom properties on the window object using the JavaScriptCore API.
1997      */
1998     webkit_web_view_signals[WINDOW_OBJECT_CLEARED] = g_signal_new("window-object-cleared",
1999             G_TYPE_FROM_CLASS(webViewClass),
2000             (GSignalFlags)G_SIGNAL_RUN_LAST,
2001             G_STRUCT_OFFSET (WebKitWebViewClass, window_object_cleared),
2002             NULL,
2003             NULL,
2004             webkit_marshal_VOID__OBJECT_POINTER_POINTER,
2005             G_TYPE_NONE, 3,
2006             WEBKIT_TYPE_WEB_FRAME,
2007             G_TYPE_POINTER,
2008             G_TYPE_POINTER);
2009 
2010     /**
2011      * WebKitWebView::download-requested:
2012      * @webView: the object on which the signal is emitted
2013      * @download: a #WebKitDownload object that lets you control the
2014      * download process
2015      *
2016      * A new Download is being requested. By default, if the signal is
2017      * not handled, the download is cancelled. If you handle the download
2018      * and call webkit_download_set_destination_uri(), it will be
2019      * started for you. If you need to set the destination asynchronously
2020      * you are responsible for starting or cancelling it yourself.
2021      *
2022      * If you intend to handle downloads yourself rather than using
2023      * the #WebKitDownload helper object you must handle this signal,
2024      * and return %FALSE.
2025      *
2026      * Also, keep in mind that the default policy for WebKitGTK+ is to
2027      * ignore files with a MIME type that it does not know how to
2028      * handle, which means this signal won't be emitted in the default
2029      * setup. One way to trigger downloads is to connect to
2030      * WebKitWebView::mime-type-policy-decision-requested and call
2031      * webkit_web_policy_decision_download() on the
2032      * #WebKitWebPolicyDecision in the parameter list for the kind of
2033      * files you want your application to download (a common solution
2034      * is to download anything that WebKit can't handle, which you can
2035      * figure out by using webkit_web_view_can_show_mime_type()).
2036      *
2037      * Return value: TRUE if the download should be performed, %FALSE to
2038      * cancel it
2039      *
2040      * Since: 1.1.2
2041      */
2042     webkit_web_view_signals[DOWNLOAD_REQUESTED] = g_signal_new("download-requested",
2043             G_TYPE_FROM_CLASS(webViewClass),
2044             (GSignalFlags)G_SIGNAL_RUN_LAST,
2045             0,
2046             g_signal_accumulator_true_handled,
2047             NULL,
2048             webkit_marshal_BOOLEAN__OBJECT,
2049             G_TYPE_BOOLEAN, 1,
2050             G_TYPE_OBJECT);
2051 
2052     /**
2053      * WebKitWebView::load-started:
2054      * @webView: the object on which the signal is emitted
2055      * @frame: the frame going to do the load
2056      *
2057      * When a #WebKitWebFrame begins to load this signal is emitted.
2058      *
2059      * Deprecated: Use the "load-status" property instead.
2060      */
2061     webkit_web_view_signals[LOAD_STARTED] = g_signal_new("load-started",
2062             G_TYPE_FROM_CLASS(webViewClass),
2063             (GSignalFlags)G_SIGNAL_RUN_LAST,
2064             0,
2065             NULL,
2066             NULL,
2067             g_cclosure_marshal_VOID__OBJECT,
2068             G_TYPE_NONE, 1,
2069             WEBKIT_TYPE_WEB_FRAME);
2070 
2071     /**
2072      * WebKitWebView::load-committed:
2073      * @webView: the object on which the signal is emitted
2074      * @frame: the main frame that received the first data
2075      *
2076      * When a #WebKitWebFrame loaded the first data this signal is emitted.
2077      *
2078      * Deprecated: Use the "load-status" property instead.
2079      */
2080     webkit_web_view_signals[LOAD_COMMITTED] = g_signal_new("load-committed",
2081             G_TYPE_FROM_CLASS(webViewClass),
2082             (GSignalFlags)G_SIGNAL_RUN_LAST,
2083             0,
2084             NULL,
2085             NULL,
2086             g_cclosure_marshal_VOID__OBJECT,
2087             G_TYPE_NONE, 1,
2088             WEBKIT_TYPE_WEB_FRAME);
2089 
2090 
2091     /**
2092      * WebKitWebView::load-progress-changed:
2093      * @webView: the #WebKitWebView
2094      * @progress: the global progress
2095      *
2096      * Deprecated: Use the "progress" property instead.
2097      */
2098     webkit_web_view_signals[LOAD_PROGRESS_CHANGED] = g_signal_new("load-progress-changed",
2099             G_TYPE_FROM_CLASS(webViewClass),
2100             (GSignalFlags)G_SIGNAL_RUN_LAST,
2101             0,
2102             NULL,
2103             NULL,
2104             g_cclosure_marshal_VOID__INT,
2105             G_TYPE_NONE, 1,
2106             G_TYPE_INT);
2107 
2108     /**
2109      * WebKitWebView::load-error
2110      * @webView: the object on which the signal is emitted
2111      * @web_frame: the #WebKitWebFrame
2112      * @uri: the URI that triggered the error
2113      * @web_error: the #GError that was triggered
2114      *
2115      * An error occurred while loading. By default, if the signal is not
2116      * handled, the @web_view will display a stock error page. You need to
2117      * handle the signal if you want to provide your own error page.
2118      *
2119      * Since: 1.1.6
2120      *
2121      * Return value: %TRUE to stop other handlers from being invoked for the
2122      * event. %FALSE to propagate the event further.
2123      */
2124     webkit_web_view_signals[LOAD_ERROR] = g_signal_new("load-error",
2125             G_TYPE_FROM_CLASS(webViewClass),
2126             (GSignalFlags)(G_SIGNAL_RUN_LAST),
2127             0,
2128             g_signal_accumulator_true_handled,
2129             NULL,
2130             webkit_marshal_BOOLEAN__OBJECT_STRING_POINTER,
2131             G_TYPE_BOOLEAN, 3,
2132             WEBKIT_TYPE_WEB_FRAME,
2133             G_TYPE_STRING,
2134             G_TYPE_POINTER);
2135 
2136     /**
2137      * WebKitWebView::load-finished:
2138      * @webView: the #WebKitWebView
2139      * @frame: the #WebKitWebFrame
2140      *
2141      * Deprecated: Use the "load-status" property instead.
2142      */
2143     webkit_web_view_signals[LOAD_FINISHED] = g_signal_new("load-finished",
2144             G_TYPE_FROM_CLASS(webViewClass),
2145             (GSignalFlags)G_SIGNAL_RUN_LAST,
2146             0,
2147             NULL,
2148             NULL,
2149             g_cclosure_marshal_VOID__OBJECT,
2150             G_TYPE_NONE, 1,
2151             WEBKIT_TYPE_WEB_FRAME);
2152 
2153     /**
2154      * WebKitWebView::onload-event:
2155      * @webView: the object on which the signal is emitted
2156      * @frame: the frame
2157      *
2158      * When a #WebKitWebFrame receives an onload event this signal is emitted.
2159      */
2160     webkit_web_view_signals[ONLOAD_EVENT] = g_signal_new("onload-event",
2161             G_TYPE_FROM_CLASS(webViewClass),
2162             (GSignalFlags)G_SIGNAL_RUN_LAST,
2163             0,
2164             NULL,
2165             NULL,
2166             g_cclosure_marshal_VOID__OBJECT,
2167             G_TYPE_NONE, 1,
2168             WEBKIT_TYPE_WEB_FRAME);
2169 
2170     /**
2171      * WebKitWebView::title-changed:
2172      * @webView: the object on which the signal is emitted
2173      * @frame: the main frame
2174      * @title: the new title
2175      *
2176      * When a #WebKitWebFrame changes the document title this signal is emitted.
2177      *
2178      * Deprecated: 1.1.4: Use "notify::title" instead.
2179      */
2180     webkit_web_view_signals[TITLE_CHANGED] = g_signal_new("title-changed",
2181             G_TYPE_FROM_CLASS(webViewClass),
2182             (GSignalFlags)G_SIGNAL_RUN_LAST,
2183             0,
2184             NULL,
2185             NULL,
2186             webkit_marshal_VOID__OBJECT_STRING,
2187             G_TYPE_NONE, 2,
2188             WEBKIT_TYPE_WEB_FRAME,
2189             G_TYPE_STRING);
2190 
2191     /**
2192      * WebKitWebView::hovering-over-link:
2193      * @webView: the object on which the signal is emitted
2194      * @title: the link's title
2195      * @uri: the URI the link points to
2196      *
2197      * When the cursor is over a link, this signal is emitted.
2198      */
2199     webkit_web_view_signals[HOVERING_OVER_LINK] = g_signal_new("hovering-over-link",
2200             G_TYPE_FROM_CLASS(webViewClass),
2201             (GSignalFlags)G_SIGNAL_RUN_LAST,
2202             0,
2203             NULL,
2204             NULL,
2205             webkit_marshal_VOID__STRING_STRING,
2206             G_TYPE_NONE, 2,
2207             G_TYPE_STRING,
2208             G_TYPE_STRING);
2209 
2210     /**
2211      * WebKitWebView::populate-popup:
2212      * @webView: the object on which the signal is emitted
2213      * @menu: the context menu
2214      *
2215      * When a context menu is about to be displayed this signal is emitted.
2216      *
2217      * Add menu items to #menu to extend the context menu.
2218      */
2219     webkit_web_view_signals[POPULATE_POPUP] = g_signal_new("populate-popup",
2220             G_TYPE_FROM_CLASS(webViewClass),
2221             (GSignalFlags)G_SIGNAL_RUN_LAST,
2222             0,
2223             NULL,
2224             NULL,
2225             g_cclosure_marshal_VOID__OBJECT,
2226             G_TYPE_NONE, 1,
2227             GTK_TYPE_MENU);
2228 
2229     /**
2230      * WebKitWebView::print-requested
2231      * @webView: the object in which the signal is emitted
2232      * @web_frame: the frame that is requesting to be printed
2233      *
2234      * Emitted when printing is requested by the frame, usually
2235      * because of a javascript call. When handling this signal you
2236      * should call webkit_web_frame_print_full() or
2237      * webkit_web_frame_print() to do the actual printing.
2238      *
2239      * The default handler will present a print dialog and carry a
2240      * print operation. Notice that this means that if you intend to
2241      * ignore a print request you must connect to this signal, and
2242      * return %TRUE.
2243      *
2244      * Return value: %TRUE if the print request has been handled, %FALSE if
2245      * the default handler should run
2246      *
2247      * Since: 1.1.5
2248      */
2249     webkit_web_view_signals[PRINT_REQUESTED] = g_signal_new("print-requested",
2250             G_TYPE_FROM_CLASS(webViewClass),
2251             (GSignalFlags)G_SIGNAL_RUN_LAST,
2252             0,
2253             g_signal_accumulator_true_handled,
2254             NULL,
2255             webkit_marshal_BOOLEAN__OBJECT,
2256             G_TYPE_BOOLEAN, 1,
2257             WEBKIT_TYPE_WEB_FRAME);
2258 
2259     webkit_web_view_signals[STATUS_BAR_TEXT_CHANGED] = g_signal_new("status-bar-text-changed",
2260             G_TYPE_FROM_CLASS(webViewClass),
2261             (GSignalFlags)G_SIGNAL_RUN_LAST,
2262             0,
2263             NULL,
2264             NULL,
2265             g_cclosure_marshal_VOID__STRING,
2266             G_TYPE_NONE, 1,
2267             G_TYPE_STRING);
2268 
2269     /**
2270      * WebKitWebView::icon-loaded:
2271      * @webView: the object on which the signal is emitted
2272      * @icon_uri: the URI for the icon
2273      *
2274      * This signal is emitted when the main frame has got a favicon.
2275      * See WebKitIconDatabase::icon-loaded if you want to keep track of
2276      * icons for child frames.
2277      *
2278      * Since: 1.1.18
2279      */
2280     webkit_web_view_signals[ICON_LOADED] = g_signal_new("icon-loaded",
2281             G_TYPE_FROM_CLASS(webViewClass),
2282             (GSignalFlags)G_SIGNAL_RUN_LAST,
2283             0,
2284             NULL,
2285             NULL,
2286             g_cclosure_marshal_VOID__STRING,
2287             G_TYPE_NONE, 1,
2288             G_TYPE_STRING);
2289 
2290     /**
2291      * WebKitWebView::console-message:
2292      * @webView: the object on which the signal is emitted
2293      * @message: the message text
2294      * @line: the line where the error occured
2295      * @source_id: the source id
2296      *
2297      * A JavaScript console message was created.
2298      *
2299      * Return value: %TRUE to stop other handlers from being invoked for the
2300      * event. %FALSE to propagate the event further.
2301      */
2302     webkit_web_view_signals[CONSOLE_MESSAGE] = g_signal_new("console-message",
2303             G_TYPE_FROM_CLASS(webViewClass),
2304             (GSignalFlags)G_SIGNAL_RUN_LAST,
2305             G_STRUCT_OFFSET(WebKitWebViewClass, console_message),
2306             g_signal_accumulator_true_handled,
2307             NULL,
2308             webkit_marshal_BOOLEAN__STRING_INT_STRING,
2309             G_TYPE_BOOLEAN, 3,
2310             G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
2311 
2312     /**
2313      * WebKitWebView::script-alert:
2314      * @webView: the object on which the signal is emitted
2315      * @frame: the relevant frame
2316      * @message: the message text
2317      *
2318      * A JavaScript alert dialog was created.
2319      *
2320      * Return value: %TRUE to stop other handlers from being invoked for the
2321      * event. %FALSE to propagate the event further.
2322      */
2323     webkit_web_view_signals[SCRIPT_ALERT] = g_signal_new("script-alert",
2324             G_TYPE_FROM_CLASS(webViewClass),
2325             (GSignalFlags)G_SIGNAL_RUN_LAST,
2326             G_STRUCT_OFFSET(WebKitWebViewClass, script_alert),
2327             g_signal_accumulator_true_handled,
2328             NULL,
2329             webkit_marshal_BOOLEAN__OBJECT_STRING,
2330             G_TYPE_BOOLEAN, 2,
2331             WEBKIT_TYPE_WEB_FRAME, G_TYPE_STRING);
2332 
2333     /**
2334      * WebKitWebView::script-confirm:
2335      * @webView: the object on which the signal is emitted
2336      * @frame: the relevant frame
2337      * @message: the message text
2338      * @confirmed: whether the dialog has been confirmed
2339      *
2340      * A JavaScript confirm dialog was created, providing Yes and No buttons.
2341      *
2342      * Return value: %TRUE to stop other handlers from being invoked for the
2343      * event. %FALSE to propagate the event further.
2344      */
2345     webkit_web_view_signals[SCRIPT_CONFIRM] = g_signal_new("script-confirm",
2346             G_TYPE_FROM_CLASS(webViewClass),
2347             (GSignalFlags)G_SIGNAL_RUN_LAST,
2348             G_STRUCT_OFFSET(WebKitWebViewClass, script_confirm),
2349             g_signal_accumulator_true_handled,
2350             NULL,
2351             webkit_marshal_BOOLEAN__OBJECT_STRING_POINTER,
2352             G_TYPE_BOOLEAN, 3,
2353             WEBKIT_TYPE_WEB_FRAME, G_TYPE_STRING, G_TYPE_POINTER);
2354 
2355     /**
2356      * WebKitWebView::script-prompt:
2357      * @webView: the object on which the signal is emitted
2358      * @frame: the relevant frame
2359      * @message: the message text
2360      * @default: the default value
2361      * @text: To be filled with the return value or NULL if the dialog was cancelled.
2362      *
2363      * A JavaScript prompt dialog was created, providing an entry to input text.
2364      *
2365      * Return value: %TRUE to stop other handlers from being invoked for the
2366      * event. %FALSE to propagate the event further.
2367      */
2368     webkit_web_view_signals[SCRIPT_PROMPT] = g_signal_new("script-prompt",
2369             G_TYPE_FROM_CLASS(webViewClass),
2370             (GSignalFlags)G_SIGNAL_RUN_LAST,
2371             G_STRUCT_OFFSET(WebKitWebViewClass, script_prompt),
2372             g_signal_accumulator_true_handled,
2373             NULL,
2374             webkit_marshal_BOOLEAN__OBJECT_STRING_STRING_STRING,
2375             G_TYPE_BOOLEAN, 4,
2376             WEBKIT_TYPE_WEB_FRAME, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
2377 
2378     /**
2379      * WebKitWebView::select-all:
2380      * @webView: the object which received the signal
2381      *
2382      * The #WebKitWebView::select-all signal is a keybinding signal which gets emitted to
2383      * select the complete contents of the text view.
2384      *
2385      * The default bindings for this signal is Ctrl-a.
2386      */
2387     webkit_web_view_signals[SELECT_ALL] = g_signal_new("select-all",
2388             G_TYPE_FROM_CLASS(webViewClass),
2389             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2390             G_STRUCT_OFFSET(WebKitWebViewClass, select_all),
2391             NULL, NULL,
2392             g_cclosure_marshal_VOID__VOID,
2393             G_TYPE_NONE, 0);
2394 
2395     /**
2396      * WebKitWebView::cut-clipboard:
2397      * @webView: the object which received the signal
2398      *
2399      * The #WebKitWebView::cut-clipboard signal is a keybinding signal which gets emitted to
2400      * cut the selection to the clipboard.
2401      *
2402      * The default bindings for this signal are Ctrl-x and Shift-Delete.
2403      */
2404     webkit_web_view_signals[CUT_CLIPBOARD] = g_signal_new("cut-clipboard",
2405             G_TYPE_FROM_CLASS(webViewClass),
2406             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2407             G_STRUCT_OFFSET(WebKitWebViewClass, cut_clipboard),
2408             NULL, NULL,
2409             g_cclosure_marshal_VOID__VOID,
2410             G_TYPE_NONE, 0);
2411 
2412     /**
2413      * WebKitWebView::copy-clipboard:
2414      * @webView: the object which received the signal
2415      *
2416      * The #WebKitWebView::copy-clipboard signal is a keybinding signal which gets emitted to
2417      * copy the selection to the clipboard.
2418      *
2419      * The default bindings for this signal are Ctrl-c and Ctrl-Insert.
2420      */
2421     webkit_web_view_signals[COPY_CLIPBOARD] = g_signal_new("copy-clipboard",
2422             G_TYPE_FROM_CLASS(webViewClass),
2423             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2424             G_STRUCT_OFFSET(WebKitWebViewClass, copy_clipboard),
2425             NULL, NULL,
2426             g_cclosure_marshal_VOID__VOID,
2427             G_TYPE_NONE, 0);
2428 
2429     /**
2430      * WebKitWebView::paste-clipboard:
2431      * @webView: the object which received the signal
2432      *
2433      * The #WebKitWebView::paste-clipboard signal is a keybinding signal which gets emitted to
2434      * paste the contents of the clipboard into the Web view.
2435      *
2436      * The default bindings for this signal are Ctrl-v and Shift-Insert.
2437      */
2438     webkit_web_view_signals[PASTE_CLIPBOARD] = g_signal_new("paste-clipboard",
2439             G_TYPE_FROM_CLASS(webViewClass),
2440             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2441             G_STRUCT_OFFSET(WebKitWebViewClass, paste_clipboard),
2442             NULL, NULL,
2443             g_cclosure_marshal_VOID__VOID,
2444             G_TYPE_NONE, 0);
2445 
2446     /**
2447      * WebKitWebView::undo
2448      * @webView: the object which received the signal
2449      *
2450      * The #WebKitWebView::undo signal is a keybinding signal which gets emitted to
2451      * undo the last editing command.
2452      *
2453      * The default binding for this signal is Ctrl-z
2454      *
2455      * Since: 1.1.14
2456      */
2457     webkit_web_view_signals[UNDO] = g_signal_new("undo",
2458             G_TYPE_FROM_CLASS(webViewClass),
2459             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2460             G_STRUCT_OFFSET(WebKitWebViewClass, undo),
2461             NULL, NULL,
2462             g_cclosure_marshal_VOID__VOID,
2463             G_TYPE_NONE, 0);
2464 
2465     /**
2466      * WebKitWebView::redo
2467      * @webView: the object which received the signal
2468      *
2469      * The #WebKitWebView::redo signal is a keybinding signal which gets emitted to
2470      * redo the last editing command.
2471      *
2472      * The default binding for this signal is Ctrl-Shift-z
2473      *
2474      * Since: 1.1.14
2475      */
2476     webkit_web_view_signals[REDO] = g_signal_new("redo",
2477             G_TYPE_FROM_CLASS(webViewClass),
2478             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2479             G_STRUCT_OFFSET(WebKitWebViewClass, redo),
2480             NULL, NULL,
2481             g_cclosure_marshal_VOID__VOID,
2482             G_TYPE_NONE, 0);
2483 
2484     /**
2485      * WebKitWebView::move-cursor:
2486      * @webView: the object which received the signal
2487      * @step: the type of movement, one of #GtkMovementStep
2488      * @count: an integer indicating the subtype of movement. Currently
2489      *         the permitted values are '1' = forward, '-1' = backwards.
2490      *
2491      * The #WebKitWebView::move-cursor will be emitted to apply the
2492      * cursor movement described by its parameters to the @view.
2493      *
2494      * Return value: %TRUE or %FALSE
2495      *
2496      * Since: 1.1.4
2497      */
2498     webkit_web_view_signals[MOVE_CURSOR] = g_signal_new("move-cursor",
2499             G_TYPE_FROM_CLASS(webViewClass),
2500             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2501             G_STRUCT_OFFSET(WebKitWebViewClass, move_cursor),
2502             NULL, NULL,
2503             webkit_marshal_BOOLEAN__ENUM_INT,
2504             G_TYPE_BOOLEAN, 2,
2505             GTK_TYPE_MOVEMENT_STEP,
2506             G_TYPE_INT);
2507 
2508     /**
2509      * WebKitWebView::create-plugin-widget:
2510      * @webView: the object which received the signal
2511      * @mime_type: the mimetype of the requested object
2512      * @uri: the URI to load
2513      * @param: a #GHashTable with additional attributes (strings)
2514      *
2515      * The #WebKitWebView::create-plugin-widget signal will be emitted to
2516      * create a plugin widget for embed or object HTML tags. This
2517      * allows to embed a GtkWidget as a plugin into HTML content. In
2518      * case of a textual selection of the GtkWidget WebCore will attempt
2519      * to set the property value of "webkit-widget-is-selected". This can
2520      * be used to draw a visual indicator of the selection.
2521      *
2522      * Return value: (transfer full): a new #GtkWidget, or %NULL
2523      *
2524      * Since: 1.1.8
2525      */
2526     webkit_web_view_signals[PLUGIN_WIDGET] = g_signal_new("create-plugin-widget",
2527             G_TYPE_FROM_CLASS(webViewClass),
2528             (GSignalFlags) (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2529             0,
2530             webkit_signal_accumulator_object_handled,
2531             NULL,
2532             webkit_marshal_OBJECT__STRING_STRING_POINTER,
2533             GTK_TYPE_WIDGET, 3,
2534             G_TYPE_STRING, G_TYPE_STRING, G_TYPE_HASH_TABLE);
2535 
2536     /**
2537      * WebKitWebView::database-quota-exceeded
2538      * @webView: the object which received the signal
2539      * @frame: the relevant frame
2540      * @database: the #WebKitWebDatabase which exceeded the quota of its #WebKitSecurityOrigin
2541      *
2542      * The #WebKitWebView::database-quota-exceeded signal will be emitted when
2543      * a Web Database exceeds the quota of its security origin. This signal
2544      * may be used to increase the size of the quota before the originating
2545      * operation fails.
2546      *
2547      * Since: 1.1.14
2548      */
2549     webkit_web_view_signals[DATABASE_QUOTA_EXCEEDED] = g_signal_new("database-quota-exceeded",
2550             G_TYPE_FROM_CLASS(webViewClass),
2551             (GSignalFlags) (G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2552             0,
2553             NULL, NULL,
2554             webkit_marshal_VOID__OBJECT_OBJECT,
2555             G_TYPE_NONE, 2,
2556             G_TYPE_OBJECT, G_TYPE_OBJECT);
2557 
2558     /**
2559      * WebKitWebView::resource-request-starting:
2560      * @webView: the object which received the signal
2561      * @web_frame: the #WebKitWebFrame whose load dispatched this request
2562      * @web_resource: an empty #WebKitWebResource object
2563      * @request: the #WebKitNetworkRequest that will be dispatched
2564      * @response: the #WebKitNetworkResponse representing the redirect
2565      * response, if any
2566      *
2567      * Emitted when a request is about to be sent. You can modify the
2568      * request while handling this signal. You can set the URI in the
2569      * #WebKitNetworkRequest object itself, and add/remove/replace
2570      * headers using the #SoupMessage object it carries, if it is
2571      * present. See webkit_network_request_get_message(). Setting the
2572      * request URI to "about:blank" will effectively cause the request
2573      * to load nothing, and can be used to disable the loading of
2574      * specific resources.
2575      *
2576      * Notice that information about an eventual redirect is available
2577      * in @response's #SoupMessage, not in the #SoupMessage carried by
2578      * the @request. If @response is %NULL, then this is not a
2579      * redirected request.
2580      *
2581      * The #WebKitWebResource object will be the same throughout all
2582      * the lifetime of the resource, but the contents may change from
2583      * inbetween signal emissions.
2584      *
2585      * Since: 1.1.14
2586      */
2587     webkit_web_view_signals[RESOURCE_REQUEST_STARTING] = g_signal_new("resource-request-starting",
2588             G_TYPE_FROM_CLASS(webViewClass),
2589             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2590             0,
2591             NULL, NULL,
2592             webkit_marshal_VOID__OBJECT_OBJECT_OBJECT_OBJECT,
2593             G_TYPE_NONE, 4,
2594             WEBKIT_TYPE_WEB_FRAME,
2595             WEBKIT_TYPE_WEB_RESOURCE,
2596             WEBKIT_TYPE_NETWORK_REQUEST,
2597             WEBKIT_TYPE_NETWORK_RESPONSE);
2598 
2599     /**
2600      * WebKitWebView::geolocation-policy-decision-requested:
2601      * @webView: the object on which the signal is emitted
2602      * @frame: the frame that requests permission
2603      * @policy_decision: a WebKitGeolocationPolicyDecision
2604      *
2605      * This signal is emitted when a @frame wants to obtain the user's
2606      * location. The decision can be made asynchronously, but you must
2607      * call g_object_ref() the @policy_decision, and return %TRUE if
2608      * you are going to handle the request. To actually make the
2609      * decision you need to call webkit_geolocation_policy_allow() or
2610      * webkit_geolocation_policy_deny() on @policy_decision.
2611      *
2612      * Since: 1.1.23
2613      */
2614     webkit_web_view_signals[GEOLOCATION_POLICY_DECISION_REQUESTED] = g_signal_new("geolocation-policy-decision-requested",
2615             G_TYPE_FROM_CLASS(webViewClass),
2616             (GSignalFlags)(G_SIGNAL_RUN_LAST),
2617             0,
2618             NULL, NULL,
2619             webkit_marshal_BOOLEAN__OBJECT_OBJECT,
2620             G_TYPE_BOOLEAN, 2,
2621             WEBKIT_TYPE_WEB_FRAME,
2622             WEBKIT_TYPE_GEOLOCATION_POLICY_DECISION);
2623 
2624     /**
2625      * WebKitWebView::geolocation-policy-decision-cancelled:
2626      * @webView: the object on which the signal is emitted
2627      * @frame: the frame that cancels geolocation request.
2628      *
2629      * When a @frame wants to cancel geolocation permission it had requested
2630      * before.
2631      *
2632      * Since: 1.1.23
2633      */
2634     webkit_web_view_signals[GEOLOCATION_POLICY_DECISION_CANCELLED] = g_signal_new("geolocation-policy-decision-cancelled",
2635             G_TYPE_FROM_CLASS(webViewClass),
2636             (GSignalFlags)(G_SIGNAL_RUN_LAST),
2637             0,
2638             NULL, NULL,
2639             g_cclosure_marshal_VOID__OBJECT,
2640             G_TYPE_NONE, 1,
2641             WEBKIT_TYPE_WEB_FRAME);
2642 
2643     /*
2644      * DOM-related signals. These signals are experimental, for now,
2645      * and may change API and ABI. Their comments lack one * on
2646      * purpose, to make them not be catched by gtk-doc.
2647      */
2648 
2649     /*
2650      * WebKitWebView::document-load-finished
2651      * @webView: the object which received the signal
2652      * @web_frame: the #WebKitWebFrame whose load dispatched this request
2653      *
2654      * Emitted when the DOM document object load is finished for the
2655      * given frame.
2656      */
2657     webkit_web_view_signals[DOCUMENT_LOAD_FINISHED] = g_signal_new("document-load-finished",
2658             G_TYPE_FROM_CLASS(webViewClass),
2659             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2660             0,
2661             NULL, NULL,
2662             g_cclosure_marshal_VOID__OBJECT,
2663             G_TYPE_NONE, 1,
2664             WEBKIT_TYPE_WEB_FRAME);
2665 
2666     /*
2667      * WebKitWebView::frame-created
2668      * @webView: the object which received the signal
2669      * @web_frame: the #WebKitWebFrame which was just created.
2670      *
2671      * Emitted when a WebKitWebView has created a new frame. This signal will
2672      * be emitted for all sub-frames created during page load. It will not be
2673      * emitted for the main frame, which originates in the WebKitWebView constructor
2674      * and may be accessed at any time using webkit_web_view_get_main_frame.
2675      *
2676      * Since: 1.3.4
2677      */
2678     webkit_web_view_signals[FRAME_CREATED] = g_signal_new("frame-created",
2679             G_TYPE_FROM_CLASS(webViewClass),
2680             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2681             0,
2682             NULL, NULL,
2683             g_cclosure_marshal_VOID__OBJECT,
2684             G_TYPE_NONE, 1,
2685             WEBKIT_TYPE_WEB_FRAME);
2686 
2687     webkit_web_view_signals[SHOULD_BEGIN_EDITING] = g_signal_new("should-begin-editing",
2688         G_TYPE_FROM_CLASS(webViewClass), static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2689         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action), g_signal_accumulator_first_wins, 0,
2690         webkit_marshal_BOOLEAN__OBJECT, G_TYPE_BOOLEAN, 1, WEBKIT_TYPE_DOM_RANGE);
2691 
2692     webkit_web_view_signals[SHOULD_END_EDITING] = g_signal_new("should-end-editing", G_TYPE_FROM_CLASS(webViewClass),
2693         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2694         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action), g_signal_accumulator_first_wins, 0,
2695         webkit_marshal_BOOLEAN__OBJECT, G_TYPE_BOOLEAN, 1, WEBKIT_TYPE_DOM_RANGE);
2696 
2697     webkit_web_view_signals[SHOULD_INSERT_NODE] = g_signal_new("should-insert-node", G_TYPE_FROM_CLASS(webViewClass),
2698         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2699         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action), g_signal_accumulator_first_wins, 0,
2700         webkit_marshal_BOOLEAN__OBJECT_OBJECT_ENUM, G_TYPE_BOOLEAN,
2701         3, WEBKIT_TYPE_DOM_NODE, WEBKIT_TYPE_DOM_RANGE, WEBKIT_TYPE_INSERT_ACTION);
2702 
2703     webkit_web_view_signals[SHOULD_INSERT_TEXT] = g_signal_new("should-insert-text", G_TYPE_FROM_CLASS(webViewClass),
2704         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2705         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action), g_signal_accumulator_first_wins, 0,
2706         webkit_marshal_BOOLEAN__STRING_OBJECT_ENUM, G_TYPE_BOOLEAN,
2707         3, G_TYPE_STRING, WEBKIT_TYPE_DOM_RANGE, WEBKIT_TYPE_INSERT_ACTION);
2708 
2709     webkit_web_view_signals[SHOULD_DELETE_RANGE] = g_signal_new("should-delete-range", G_TYPE_FROM_CLASS(webViewClass),
2710         static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2711         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action), g_signal_accumulator_first_wins, 0,
2712         webkit_marshal_BOOLEAN__OBJECT, G_TYPE_BOOLEAN, 1, WEBKIT_TYPE_DOM_RANGE);
2713 
2714     webkit_web_view_signals[SHOULD_SHOW_DELETE_INTERFACE_FOR_ELEMENT] = g_signal_new("should-show-delete-interface-for-element",
2715         G_TYPE_FROM_CLASS(webViewClass), static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2716         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action), g_signal_accumulator_first_wins, 0,
2717         webkit_marshal_BOOLEAN__OBJECT, G_TYPE_BOOLEAN, 1, WEBKIT_TYPE_DOM_HTML_ELEMENT);
2718 
2719     webkit_web_view_signals[SHOULD_CHANGE_SELECTED_RANGE] = g_signal_new("should-change-selected-range",
2720         G_TYPE_FROM_CLASS(webViewClass), static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2721         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action), g_signal_accumulator_first_wins, 0,
2722         webkit_marshal_BOOLEAN__OBJECT_OBJECT_ENUM_BOOLEAN, G_TYPE_BOOLEAN,
2723          4, WEBKIT_TYPE_DOM_RANGE, WEBKIT_TYPE_DOM_RANGE, WEBKIT_TYPE_SELECTION_AFFINITY, G_TYPE_BOOLEAN);
2724 
2725     webkit_web_view_signals[SHOULD_APPLY_STYLE] = g_signal_new("should-apply-style",
2726         G_TYPE_FROM_CLASS(webViewClass), static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2727         G_STRUCT_OFFSET(WebKitWebViewClass, should_allow_editing_action), g_signal_accumulator_first_wins, 0,
2728         webkit_marshal_BOOLEAN__OBJECT_OBJECT, G_TYPE_BOOLEAN,
2729          2, WEBKIT_TYPE_DOM_CSS_STYLE_DECLARATION, WEBKIT_TYPE_DOM_RANGE);
2730 
2731     webkit_web_view_signals[EDITING_BEGAN] = g_signal_new("editing-began",
2732         G_TYPE_FROM_CLASS(webViewClass), static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), 0, 0, 0,
2733         g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
2734 
2735     webkit_web_view_signals[USER_CHANGED_CONTENTS] = g_signal_new("user-changed-contents",
2736         G_TYPE_FROM_CLASS(webViewClass), static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), 0, 0, 0,
2737         g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
2738 
2739     webkit_web_view_signals[EDITING_ENDED] = g_signal_new("editing-ended",
2740         G_TYPE_FROM_CLASS(webViewClass), static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), 0, 0, 0,
2741         g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
2742 
2743     webkit_web_view_signals[SELECTION_CHANGED] = g_signal_new("selection-changed",
2744         G_TYPE_FROM_CLASS(webViewClass), static_cast<GSignalFlags>(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION), 0, 0, 0,
2745         g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
2746 
2747     /*
2748      * WebKitWebView::viewport-attributes-recompute-requested
2749      * @web_view: the object which received the signal
2750      * @viewport_attributes: the #WebKitViewportAttributes which has the viewport attributes.
2751      *
2752      * The #WebKitWebView::viewport-attributes-recompute-requested
2753      * signal will be emitted when a page with a viewport meta tag
2754      * loads and when webkit_viewport_attributes_recompute is called.
2755      *
2756      * The #WebKitViewportAttributes will have device size, available size,
2757      * desktop width, and device DPI pre-filled by values that make sense
2758      * for the current screen and widget, but you can override those values
2759      * if you have special requirements (for instance, if you made your
2760      * widget bigger than the available visible area, you should override
2761      * the available-width and available-height properties to the actual
2762      * visible area).
2763      *
2764      * Since: 1.3.8
2765      */
2766     webkit_web_view_signals[VIEWPORT_ATTRIBUTES_RECOMPUTE_REQUESTED] = g_signal_new("viewport-attributes-recompute-requested",
2767             G_TYPE_FROM_CLASS(webViewClass),
2768             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2769             0,
2770             0, 0,
2771             g_cclosure_marshal_VOID__OBJECT,
2772             G_TYPE_NONE, 1,
2773             WEBKIT_TYPE_VIEWPORT_ATTRIBUTES);
2774 
2775     /*
2776      * WebKitWebView::viewport-attributes-changed
2777      * @web_view: the object which received the signal
2778      * @viewport_attributes: the #WebKitViewportAttributes which has the viewport attributes.
2779      *
2780      * The #WebKitWebView::viewport-attributes-changed signal will be emitted
2781      * after the emission of #WebKitWebView::viewport-attributes-recompute-requested
2782      * and the subsequent viewport attribute recomputation. At this point,
2783      * if the #WebKitViewportAttributes are valid, the viewport attributes are available.
2784      *
2785      * Since: 1.3.8
2786      */
2787     webkit_web_view_signals[VIEWPORT_ATTRIBUTES_CHANGED] = g_signal_new("viewport-attributes-changed",
2788             G_TYPE_FROM_CLASS(webViewClass),
2789             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2790             0,
2791             0, 0,
2792             g_cclosure_marshal_VOID__OBJECT,
2793             G_TYPE_NONE, 1,
2794             WEBKIT_TYPE_VIEWPORT_ATTRIBUTES);
2795 
2796     /*
2797      * implementations of virtual methods
2798      */
2799     webViewClass->create_web_view = webkit_web_view_real_create_web_view;
2800     webViewClass->web_view_ready = webkit_web_view_real_web_view_ready;
2801     webViewClass->close_web_view = webkit_web_view_real_close_web_view;
2802     webViewClass->navigation_requested = webkit_web_view_real_navigation_requested;
2803     webViewClass->window_object_cleared = webkit_web_view_real_window_object_cleared;
2804     webViewClass->choose_file = webkit_web_view_real_choose_file;
2805     webViewClass->script_alert = webkit_web_view_real_script_alert;
2806     webViewClass->script_confirm = webkit_web_view_real_script_confirm;
2807     webViewClass->script_prompt = webkit_web_view_real_script_prompt;
2808     webViewClass->console_message = webkit_web_view_real_console_message;
2809     webViewClass->select_all = webkit_web_view_real_select_all;
2810     webViewClass->cut_clipboard = webkit_web_view_real_cut_clipboard;
2811     webViewClass->copy_clipboard = webkit_web_view_real_copy_clipboard;
2812     webViewClass->paste_clipboard = webkit_web_view_real_paste_clipboard;
2813     webViewClass->undo = webkit_web_view_real_undo;
2814     webViewClass->redo = webkit_web_view_real_redo;
2815     webViewClass->move_cursor = webkit_web_view_real_move_cursor;
2816     webViewClass->should_allow_editing_action = webkit_web_view_real_should_allow_editing_action;
2817 
2818     GObjectClass* objectClass = G_OBJECT_CLASS(webViewClass);
2819     objectClass->dispose = webkit_web_view_dispose;
2820     objectClass->finalize = webkit_web_view_finalize;
2821     objectClass->get_property = webkit_web_view_get_property;
2822     objectClass->set_property = webkit_web_view_set_property;
2823 
2824     GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(webViewClass);
2825     widgetClass->realize = webkit_web_view_realize;
2826 #ifdef GTK_API_VERSION_2
2827     widgetClass->expose_event = webkit_web_view_expose_event;
2828 #else
2829     widgetClass->draw = webkit_web_view_draw;
2830 #endif
2831     widgetClass->key_press_event = webkit_web_view_key_press_event;
2832     widgetClass->key_release_event = webkit_web_view_key_release_event;
2833     widgetClass->button_press_event = webkit_web_view_button_press_event;
2834     widgetClass->button_release_event = webkit_web_view_button_release_event;
2835     widgetClass->motion_notify_event = webkit_web_view_motion_event;
2836     widgetClass->scroll_event = webkit_web_view_scroll_event;
2837     widgetClass->size_allocate = webkit_web_view_size_allocate;
2838 #ifdef GTK_API_VERSION_2
2839     widgetClass->size_request = webkit_web_view_size_request;
2840 #else
2841     widgetClass->get_preferred_width = webkit_web_view_get_preferred_width;
2842     widgetClass->get_preferred_height = webkit_web_view_get_preferred_height;
2843 #endif
2844     widgetClass->popup_menu = webkit_web_view_popup_menu_handler;
2845     widgetClass->grab_focus = webkit_web_view_grab_focus;
2846     widgetClass->focus_in_event = webkit_web_view_focus_in_event;
2847     widgetClass->focus_out_event = webkit_web_view_focus_out_event;
2848     widgetClass->get_accessible = webkit_web_view_get_accessible;
2849     widgetClass->screen_changed = webkit_web_view_screen_changed;
2850     widgetClass->drag_end = webkit_web_view_drag_end;
2851     widgetClass->drag_data_get = webkit_web_view_drag_data_get;
2852     widgetClass->drag_motion = webkit_web_view_drag_motion;
2853     widgetClass->drag_leave = webkit_web_view_drag_leave;
2854     widgetClass->drag_drop = webkit_web_view_drag_drop;
2855     widgetClass->drag_data_received = webkit_web_view_drag_data_received;
2856 #if GTK_CHECK_VERSION(2, 12, 0)
2857     widgetClass->query_tooltip = webkit_web_view_query_tooltip;
2858     widgetClass->show_help = webkit_web_view_show_help;
2859 #endif
2860 
2861     GtkContainerClass* containerClass = GTK_CONTAINER_CLASS(webViewClass);
2862     containerClass->add = webkit_web_view_container_add;
2863     containerClass->remove = webkit_web_view_container_remove;
2864     containerClass->forall = webkit_web_view_container_forall;
2865 
2866     /*
2867      * make us scrollable (e.g. addable to a GtkScrolledWindow)
2868      */
2869 #ifdef GTK_API_VERSION_2
2870     webViewClass->set_scroll_adjustments = webkit_web_view_set_scroll_adjustments;
2871     GTK_WIDGET_CLASS(webViewClass)->set_scroll_adjustments_signal = g_signal_new("set-scroll-adjustments",
2872             G_TYPE_FROM_CLASS(webViewClass),
2873             (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
2874             G_STRUCT_OFFSET(WebKitWebViewClass, set_scroll_adjustments),
2875             NULL, NULL,
2876             webkit_marshal_VOID__OBJECT_OBJECT,
2877             G_TYPE_NONE, 2,
2878             GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
2879 #else
2880     g_object_class_override_property(objectClass, PROP_HADJUSTMENT, "hadjustment");
2881     g_object_class_override_property(objectClass, PROP_VADJUSTMENT, "vadjustment");
2882     g_object_class_override_property(objectClass, PROP_HSCROLL_POLICY, "hscroll-policy");
2883     g_object_class_override_property(objectClass, PROP_VSCROLL_POLICY, "vscroll-policy");
2884 #endif
2885 
2886     /*
2887      * Key bindings
2888      */
2889 
2890     binding_set = gtk_binding_set_by_class(webViewClass);
2891 
2892     gtk_binding_entry_add_signal(binding_set, GDK_a, GDK_CONTROL_MASK,
2893                                  "select_all", 0);
2894 
2895     /* Cut/copy/paste */
2896 
2897     gtk_binding_entry_add_signal(binding_set, GDK_x, GDK_CONTROL_MASK,
2898                                  "cut_clipboard", 0);
2899     gtk_binding_entry_add_signal(binding_set, GDK_c, GDK_CONTROL_MASK,
2900                                  "copy_clipboard", 0);
2901     gtk_binding_entry_add_signal(binding_set, GDK_v, GDK_CONTROL_MASK,
2902                                  "paste_clipboard", 0);
2903     gtk_binding_entry_add_signal(binding_set, GDK_z, GDK_CONTROL_MASK,
2904                                  "undo", 0);
2905     gtk_binding_entry_add_signal(binding_set, GDK_z, static_cast<GdkModifierType>(GDK_CONTROL_MASK | GDK_SHIFT_MASK),
2906                                  "redo", 0);
2907 
2908     gtk_binding_entry_add_signal(binding_set, GDK_Delete, GDK_SHIFT_MASK,
2909                                  "cut_clipboard", 0);
2910     gtk_binding_entry_add_signal(binding_set, GDK_Insert, GDK_CONTROL_MASK,
2911                                  "copy_clipboard", 0);
2912     gtk_binding_entry_add_signal(binding_set, GDK_Insert, GDK_SHIFT_MASK,
2913                                  "paste_clipboard", 0);
2914 
2915     /* Movement */
2916 
2917     gtk_binding_entry_add_signal(binding_set, GDK_Down, static_cast<GdkModifierType>(0),
2918                                  "move-cursor", 2,
2919                                  G_TYPE_ENUM, GTK_MOVEMENT_DISPLAY_LINES,
2920                                  G_TYPE_INT, 1);
2921     gtk_binding_entry_add_signal(binding_set, GDK_Up, static_cast<GdkModifierType>(0),
2922                                  "move-cursor", 2,
2923                                  G_TYPE_ENUM, GTK_MOVEMENT_DISPLAY_LINES,
2924                                  G_TYPE_INT, -1);
2925     gtk_binding_entry_add_signal(binding_set, GDK_Right, static_cast<GdkModifierType>(0),
2926                                  "move-cursor", 2,
2927                                  G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
2928                                  G_TYPE_INT, 1);
2929     gtk_binding_entry_add_signal(binding_set, GDK_Left, static_cast<GdkModifierType>(0),
2930                                  "move-cursor", 2,
2931                                  G_TYPE_ENUM, GTK_MOVEMENT_VISUAL_POSITIONS,
2932                                  G_TYPE_INT, -1);
2933     gtk_binding_entry_add_signal(binding_set, GDK_space, static_cast<GdkModifierType>(0),
2934                                  "move-cursor", 2,
2935                                  G_TYPE_ENUM, GTK_MOVEMENT_PAGES,
2936                                  G_TYPE_INT, 1);
2937     gtk_binding_entry_add_signal(binding_set, GDK_space, GDK_SHIFT_MASK,
2938                                  "move-cursor", 2,
2939                                  G_TYPE_ENUM, GTK_MOVEMENT_PAGES,
2940                                  G_TYPE_INT, -1);
2941     gtk_binding_entry_add_signal(binding_set, GDK_Page_Down, static_cast<GdkModifierType>(0),
2942                                  "move-cursor", 2,
2943                                  G_TYPE_ENUM, GTK_MOVEMENT_PAGES,
2944                                  G_TYPE_INT, 1);
2945     gtk_binding_entry_add_signal(binding_set, GDK_Page_Up, static_cast<GdkModifierType>(0),
2946                                  "move-cursor", 2,
2947                                  G_TYPE_ENUM, GTK_MOVEMENT_PAGES,
2948                                  G_TYPE_INT, -1);
2949     gtk_binding_entry_add_signal(binding_set, GDK_End, static_cast<GdkModifierType>(0),
2950                                  "move-cursor", 2,
2951                                  G_TYPE_ENUM, GTK_MOVEMENT_BUFFER_ENDS,
2952                                  G_TYPE_INT, 1);
2953     gtk_binding_entry_add_signal(binding_set, GDK_Home, static_cast<GdkModifierType>(0),
2954                                  "move-cursor", 2,
2955                                  G_TYPE_ENUM, GTK_MOVEMENT_BUFFER_ENDS,
2956                                  G_TYPE_INT, -1);
2957 
2958     /*
2959      * properties
2960      */
2961 
2962     /**
2963     * WebKitWebView:title:
2964     *
2965     * Returns the @web_view's document title.
2966     *
2967     * Since: 1.1.4
2968     */
2969     g_object_class_install_property(objectClass, PROP_TITLE,
2970                                     g_param_spec_string("title",
2971                                                         _("Title"),
2972                                                         _("Returns the @web_view's document title"),
2973                                                         NULL,
2974                                                         WEBKIT_PARAM_READABLE));
2975 
2976     /**
2977     * WebKitWebView:uri:
2978     *
2979     * Returns the current URI of the contents displayed by the @web_view.
2980     *
2981     * Since: 1.1.4
2982     */
2983     g_object_class_install_property(objectClass, PROP_URI,
2984                                     g_param_spec_string("uri",
2985                                                         _("URI"),
2986                                                         _("Returns the current URI of the contents displayed by the @web_view"),
2987                                                         NULL,
2988                                                         WEBKIT_PARAM_READABLE));
2989 
2990     /**
2991     * WebKitWebView:copy-target-list:
2992     *
2993     * The list of targets this web view supports for clipboard copying.
2994     *
2995     * Since: 1.0.2
2996     */
2997     g_object_class_install_property(objectClass, PROP_COPY_TARGET_LIST,
2998                                     g_param_spec_boxed("copy-target-list",
2999                                                        _("Copy target list"),
3000                                                        _("The list of targets this web view supports for clipboard copying"),
3001                                                        GTK_TYPE_TARGET_LIST,
3002                                                        WEBKIT_PARAM_READABLE));
3003 
3004     /**
3005     * WebKitWebView:paste-target-list:
3006     *
3007     * The list of targets this web view supports for clipboard pasting.
3008     *
3009     * Since: 1.0.2
3010     */
3011     g_object_class_install_property(objectClass, PROP_PASTE_TARGET_LIST,
3012                                     g_param_spec_boxed("paste-target-list",
3013                                                        _("Paste target list"),
3014                                                        _("The list of targets this web view supports for clipboard pasting"),
3015                                                        GTK_TYPE_TARGET_LIST,
3016                                                        WEBKIT_PARAM_READABLE));
3017 
3018     g_object_class_install_property(objectClass, PROP_SETTINGS,
3019                                     g_param_spec_object("settings",
3020                                                         _("Settings"),
3021                                                         _("An associated WebKitWebSettings instance"),
3022                                                         WEBKIT_TYPE_WEB_SETTINGS,
3023                                                         WEBKIT_PARAM_READWRITE));
3024 
3025     /**
3026     * WebKitWebView:web-inspector:
3027     *
3028     * The associated WebKitWebInspector instance.
3029     *
3030     * Since: 1.0.3
3031     */
3032     g_object_class_install_property(objectClass, PROP_WEB_INSPECTOR,
3033                                     g_param_spec_object("web-inspector",
3034                                                         _("Web Inspector"),
3035                                                         _("The associated WebKitWebInspector instance"),
3036                                                         WEBKIT_TYPE_WEB_INSPECTOR,
3037                                                         WEBKIT_PARAM_READABLE));
3038 
3039     /**
3040     * WebKitWebView:viewport-attributes:
3041     *
3042     * The associated #WebKitViewportAttributes instance.
3043     *
3044     * Since: 1.3.8
3045     */
3046     g_object_class_install_property(objectClass, PROP_VIEWPORT_ATTRIBUTES,
3047                                     g_param_spec_object("viewport-attributes",
3048                                                         _("Viewport Attributes"),
3049                                                         _("The associated WebKitViewportAttributes instance"),
3050                                                         WEBKIT_TYPE_VIEWPORT_ATTRIBUTES,
3051                                                         WEBKIT_PARAM_READABLE));
3052 
3053     /**
3054     * WebKitWebView:window-features:
3055     *
3056     * An associated WebKitWebWindowFeatures instance.
3057     *
3058     * Since: 1.0.3
3059     */
3060     g_object_class_install_property(objectClass, PROP_WINDOW_FEATURES,
3061                                     g_param_spec_object("window-features",
3062                                                         "Window Features",
3063                                                         "An associated WebKitWebWindowFeatures instance",
3064                                                         WEBKIT_TYPE_WEB_WINDOW_FEATURES,
3065                                                         WEBKIT_PARAM_READWRITE));
3066 
3067     g_object_class_install_property(objectClass, PROP_EDITABLE,
3068                                     g_param_spec_boolean("editable",
3069                                                          _("Editable"),
3070                                                          _("Whether content can be modified by the user"),
3071                                                          FALSE,
3072                                                          WEBKIT_PARAM_READWRITE));
3073 
3074     g_object_class_install_property(objectClass, PROP_TRANSPARENT,
3075                                     g_param_spec_boolean("transparent",
3076                                                          _("Transparent"),
3077                                                          _("Whether content has a transparent background"),
3078                                                          FALSE,
3079                                                          WEBKIT_PARAM_READWRITE));
3080 
3081     /**
3082     * WebKitWebView:zoom-level:
3083     *
3084     * The level of zoom of the content.
3085     *
3086     * Since: 1.0.1
3087     */
3088     g_object_class_install_property(objectClass, PROP_ZOOM_LEVEL,
3089                                     g_param_spec_float("zoom-level",
3090                                                        _("Zoom level"),
3091                                                        _("The level of zoom of the content"),
3092                                                        G_MINFLOAT,
3093                                                        G_MAXFLOAT,
3094                                                        1.0f,
3095                                                        WEBKIT_PARAM_READWRITE));
3096 
3097     /**
3098     * WebKitWebView:full-content-zoom:
3099     *
3100     * Whether the full content is scaled when zooming.
3101     *
3102     * Since: 1.0.1
3103     */
3104     g_object_class_install_property(objectClass, PROP_FULL_CONTENT_ZOOM,
3105                                     g_param_spec_boolean("full-content-zoom",
3106                                                          _("Full content zoom"),
3107                                                          _("Whether the full content is scaled when zooming"),
3108                                                          FALSE,
3109                                                          WEBKIT_PARAM_READWRITE));
3110 
3111     /**
3112      * WebKitWebView:encoding:
3113      *
3114      * The default encoding of the web view.
3115      *
3116      * Since: 1.1.2
3117      */
3118     g_object_class_install_property(objectClass, PROP_ENCODING,
3119                                     g_param_spec_string("encoding",
3120                                                         _("Encoding"),
3121                                                         _("The default encoding of the web view"),
3122                                                         NULL,
3123                                                         WEBKIT_PARAM_READABLE));
3124 
3125     /**
3126      * WebKitWebView:custom-encoding:
3127      *
3128      * The custom encoding of the web view.
3129      *
3130      * Since: 1.1.2
3131      */
3132     g_object_class_install_property(objectClass, PROP_CUSTOM_ENCODING,
3133                                     g_param_spec_string("custom-encoding",
3134                                                         _("Custom Encoding"),
3135                                                         _("The custom encoding of the web view"),
3136                                                         NULL,
3137                                                         WEBKIT_PARAM_READWRITE));
3138 
3139     /**
3140     * WebKitWebView:load-status:
3141     *
3142     * Determines the current status of the load.
3143     *
3144     * Connect to "notify::load-status" to monitor loading.
3145     *
3146     * Some versions of WebKitGTK+ emitted this signal for the default
3147     * error page, while loading it. This behavior was considered bad,
3148     * because it was essentially exposing an implementation
3149     * detail. From 1.1.19 onwards this signal is no longer emitted for
3150     * the default error pages, but keep in mind that if you override
3151     * the error pages by using webkit_web_frame_load_alternate_string()
3152     * the signals will be emitted.
3153     *
3154     * Since: 1.1.7
3155     */
3156     g_object_class_install_property(objectClass, PROP_LOAD_STATUS,
3157                                     g_param_spec_enum("load-status",
3158                                                       "Load Status",
3159                                                       "Determines the current status of the load",
3160                                                       WEBKIT_TYPE_LOAD_STATUS,
3161                                                       WEBKIT_LOAD_FINISHED,
3162                                                       WEBKIT_PARAM_READABLE));
3163 
3164     /**
3165     * WebKitWebView:progress:
3166     *
3167     * Determines the current progress of the load.
3168     *
3169     * Since: 1.1.7
3170     */
3171     g_object_class_install_property(objectClass, PROP_PROGRESS,
3172                                     g_param_spec_double("progress",
3173                                                         "Progress",
3174                                                         "Determines the current progress of the load",
3175                                                         0.0, 1.0, 1.0,
3176                                                         WEBKIT_PARAM_READABLE));
3177 
3178     /**
3179      * WebKitWebView:icon-uri:
3180      *
3181      * The URI for the favicon for the #WebKitWebView.
3182      *
3183      * Since: 1.1.18
3184      */
3185     g_object_class_install_property(objectClass, PROP_ICON_URI,
3186                                     g_param_spec_string("icon-uri",
3187                                                         _("Icon URI"),
3188                                                         _("The URI for the favicon for the #WebKitWebView."),
3189                                                         NULL,
3190                                                         WEBKIT_PARAM_READABLE));
3191     /**
3192     * WebKitWebView:im-context:
3193     *
3194     * The GtkIMMulticontext for the #WebKitWebView.
3195     *
3196     * This is the input method context used for all text entry widgets inside
3197     * the #WebKitWebView. It can be used to generate context menu items for
3198     * controlling the active input method.
3199     *
3200     * Since: 1.1.20
3201     */
3202     g_object_class_install_property(objectClass, PROP_IM_CONTEXT,
3203                                     g_param_spec_object("im-context",
3204                                                         "IM Context",
3205                                                         "The GtkIMMultiContext for the #WebKitWebView.",
3206                                                         GTK_TYPE_IM_CONTEXT,
3207                                                         WEBKIT_PARAM_READABLE));
3208 
3209     /**
3210     * WebKitWebView:view-mode:
3211     *
3212     * The "view-mode" media feature for the #WebKitWebView.
3213     *
3214     * The "view-mode" media feature is additional information for web
3215     * applications about how the application is running, when it comes
3216     * to user experience. Whether the application is running inside a
3217     * regular browser window, in a dedicated window, fullscreen, for
3218     * instance.
3219     *
3220     * This property stores a %WebKitWebViewViewMode value that matches
3221     * the "view-mode" media feature the web application will see.
3222     *
3223     * See http://www.w3.org/TR/view-mode/ for more information.
3224     *
3225     * Since: 1.3.4
3226     */
3227     g_object_class_install_property(objectClass, PROP_VIEW_MODE,
3228                                     g_param_spec_enum("view-mode",
3229                                                       "View Mode",
3230                                                       "The view-mode media feature for the #WebKitWebView.",
3231                                                       WEBKIT_TYPE_WEB_VIEW_VIEW_MODE,
3232                                                       WEBKIT_WEB_VIEW_VIEW_MODE_WINDOWED,
3233                                                       WEBKIT_PARAM_READWRITE));
3234 
3235     g_type_class_add_private(webViewClass, sizeof(WebKitWebViewPrivate));
3236 }
3237 
webkit_web_view_update_settings(WebKitWebView * webView)3238 static void webkit_web_view_update_settings(WebKitWebView* webView)
3239 {
3240     WebKitWebViewPrivate* priv = webView->priv;
3241     WebKitWebSettings* webSettings = priv->webSettings.get();
3242     Settings* settings = core(webView)->settings();
3243 
3244     gchar* defaultEncoding, *cursiveFontFamily, *defaultFontFamily, *fantasyFontFamily, *monospaceFontFamily, *sansSerifFontFamily, *serifFontFamily, *userStylesheetUri, *defaultSpellCheckingLanguages;
3245     gboolean autoLoadImages, autoShrinkImages, printBackgrounds,
3246         enableScripts, enablePlugins, enableDeveloperExtras, resizableTextAreas,
3247         enablePrivateBrowsing, enableCaretBrowsing, enableHTML5Database, enableHTML5LocalStorage,
3248         enableXSSAuditor, enableSpatialNavigation, enableFrameFlattening, javascriptCanOpenWindows,
3249         javaScriptCanAccessClipboard, enableOfflineWebAppCache,
3250         enableUniversalAccessFromFileURI, enableFileAccessFromFileURI,
3251         enableDOMPaste, tabKeyCyclesThroughElements, enableWebGL,
3252         enableSiteSpecificQuirks, usePageCache, enableJavaApplet,
3253         enableHyperlinkAuditing, enableFullscreen, enableDNSPrefetching;
3254 
3255     WebKitEditingBehavior editingBehavior;
3256 
3257     g_object_get(webSettings,
3258                  "default-encoding", &defaultEncoding,
3259                  "cursive-font-family", &cursiveFontFamily,
3260                  "default-font-family", &defaultFontFamily,
3261                  "fantasy-font-family", &fantasyFontFamily,
3262                  "monospace-font-family", &monospaceFontFamily,
3263                  "sans-serif-font-family", &sansSerifFontFamily,
3264                  "serif-font-family", &serifFontFamily,
3265                  "auto-load-images", &autoLoadImages,
3266                  "auto-shrink-images", &autoShrinkImages,
3267                  "print-backgrounds", &printBackgrounds,
3268                  "enable-scripts", &enableScripts,
3269                  "enable-plugins", &enablePlugins,
3270                  "resizable-text-areas", &resizableTextAreas,
3271                  "user-stylesheet-uri", &userStylesheetUri,
3272                  "enable-developer-extras", &enableDeveloperExtras,
3273                  "enable-private-browsing", &enablePrivateBrowsing,
3274                  "enable-caret-browsing", &enableCaretBrowsing,
3275                  "enable-html5-database", &enableHTML5Database,
3276                  "enable-html5-local-storage", &enableHTML5LocalStorage,
3277                  "enable-xss-auditor", &enableXSSAuditor,
3278                  "enable-spatial-navigation", &enableSpatialNavigation,
3279                  "enable-frame-flattening", &enableFrameFlattening,
3280                  "javascript-can-open-windows-automatically", &javascriptCanOpenWindows,
3281                  "javascript-can-access-clipboard", &javaScriptCanAccessClipboard,
3282                  "enable-offline-web-application-cache", &enableOfflineWebAppCache,
3283                  "editing-behavior", &editingBehavior,
3284                  "enable-universal-access-from-file-uris", &enableUniversalAccessFromFileURI,
3285                  "enable-file-access-from-file-uris", &enableFileAccessFromFileURI,
3286                  "enable-dom-paste", &enableDOMPaste,
3287                  "tab-key-cycles-through-elements", &tabKeyCyclesThroughElements,
3288                  "enable-site-specific-quirks", &enableSiteSpecificQuirks,
3289                  "enable-page-cache", &usePageCache,
3290                  "enable-java-applet", &enableJavaApplet,
3291                  "enable-hyperlink-auditing", &enableHyperlinkAuditing,
3292                  "spell-checking-languages", &defaultSpellCheckingLanguages,
3293                  "enable-fullscreen", &enableFullscreen,
3294                  "enable-dns-prefetching", &enableDNSPrefetching,
3295                  "enable-webgl", &enableWebGL,
3296                  NULL);
3297 
3298     settings->setDefaultTextEncodingName(defaultEncoding);
3299     settings->setCursiveFontFamily(cursiveFontFamily);
3300     settings->setStandardFontFamily(defaultFontFamily);
3301     settings->setFantasyFontFamily(fantasyFontFamily);
3302     settings->setFixedFontFamily(monospaceFontFamily);
3303     settings->setSansSerifFontFamily(sansSerifFontFamily);
3304     settings->setSerifFontFamily(serifFontFamily);
3305     settings->setLoadsImagesAutomatically(autoLoadImages);
3306     settings->setShrinksStandaloneImagesToFit(autoShrinkImages);
3307     settings->setShouldPrintBackgrounds(printBackgrounds);
3308     settings->setJavaScriptEnabled(enableScripts);
3309     settings->setPluginsEnabled(enablePlugins);
3310     settings->setTextAreasAreResizable(resizableTextAreas);
3311     settings->setUserStyleSheetLocation(KURL(KURL(), userStylesheetUri));
3312     settings->setDeveloperExtrasEnabled(enableDeveloperExtras);
3313     settings->setPrivateBrowsingEnabled(enablePrivateBrowsing);
3314     settings->setCaretBrowsingEnabled(enableCaretBrowsing);
3315 #if ENABLE(DATABASE)
3316     AbstractDatabase::setIsAvailable(enableHTML5Database);
3317 #endif
3318     settings->setLocalStorageEnabled(enableHTML5LocalStorage);
3319     settings->setXSSAuditorEnabled(enableXSSAuditor);
3320     settings->setSpatialNavigationEnabled(enableSpatialNavigation);
3321     settings->setFrameFlatteningEnabled(enableFrameFlattening);
3322     settings->setJavaScriptCanOpenWindowsAutomatically(javascriptCanOpenWindows);
3323     settings->setJavaScriptCanAccessClipboard(javaScriptCanAccessClipboard);
3324     settings->setOfflineWebApplicationCacheEnabled(enableOfflineWebAppCache);
3325     settings->setEditingBehaviorType(static_cast<WebCore::EditingBehaviorType>(editingBehavior));
3326     settings->setAllowUniversalAccessFromFileURLs(enableUniversalAccessFromFileURI);
3327     settings->setAllowFileAccessFromFileURLs(enableFileAccessFromFileURI);
3328     settings->setDOMPasteAllowed(enableDOMPaste);
3329     settings->setNeedsSiteSpecificQuirks(enableSiteSpecificQuirks);
3330     settings->setUsesPageCache(usePageCache);
3331     settings->setJavaEnabled(enableJavaApplet);
3332     settings->setHyperlinkAuditingEnabled(enableHyperlinkAuditing);
3333     settings->setDNSPrefetchingEnabled(enableDNSPrefetching);
3334 
3335 #if ENABLE(FULLSCREEN_API)
3336     settings->setFullScreenEnabled(enableFullscreen);
3337 #endif
3338 
3339 #if ENABLE(SPELLCHECK)
3340     WebKit::EditorClient* client = static_cast<WebKit::EditorClient*>(core(webView)->editorClient());
3341     static_cast<WebKit::TextCheckerClientEnchant*>(client->textChecker())->updateSpellCheckingLanguage(defaultSpellCheckingLanguages);
3342 #endif
3343 
3344 #if ENABLE(WEBGL)
3345     settings->setWebGLEnabled(enableWebGL);
3346 #endif
3347 
3348     Page* page = core(webView);
3349     if (page)
3350         page->setTabKeyCyclesThroughElements(tabKeyCyclesThroughElements);
3351 
3352     g_free(defaultEncoding);
3353     g_free(cursiveFontFamily);
3354     g_free(defaultFontFamily);
3355     g_free(fantasyFontFamily);
3356     g_free(monospaceFontFamily);
3357     g_free(sansSerifFontFamily);
3358     g_free(serifFontFamily);
3359     g_free(userStylesheetUri);
3360 
3361     webkit_web_view_screen_changed(GTK_WIDGET(webView), NULL);
3362 }
3363 
pixelsFromSize(WebKitWebView * webView,gint size)3364 static inline gint pixelsFromSize(WebKitWebView* webView, gint size)
3365 {
3366     gdouble DPI = webViewGetDPI(webView);
3367     return size / 72.0 * DPI;
3368 }
3369 
webkit_web_view_settings_notify(WebKitWebSettings * webSettings,GParamSpec * pspec,WebKitWebView * webView)3370 static void webkit_web_view_settings_notify(WebKitWebSettings* webSettings, GParamSpec* pspec, WebKitWebView* webView)
3371 {
3372     Settings* settings = core(webView)->settings();
3373 
3374     const gchar* name = g_intern_string(pspec->name);
3375     GValue value = { 0, { { 0 } } };
3376     g_value_init(&value, pspec->value_type);
3377     g_object_get_property(G_OBJECT(webSettings), name, &value);
3378 
3379     if (name == g_intern_string("default-encoding"))
3380         settings->setDefaultTextEncodingName(g_value_get_string(&value));
3381     else if (name == g_intern_string("cursive-font-family"))
3382         settings->setCursiveFontFamily(g_value_get_string(&value));
3383     else if (name == g_intern_string("default-font-family"))
3384         settings->setStandardFontFamily(g_value_get_string(&value));
3385     else if (name == g_intern_string("fantasy-font-family"))
3386         settings->setFantasyFontFamily(g_value_get_string(&value));
3387     else if (name == g_intern_string("monospace-font-family"))
3388         settings->setFixedFontFamily(g_value_get_string(&value));
3389     else if (name == g_intern_string("sans-serif-font-family"))
3390         settings->setSansSerifFontFamily(g_value_get_string(&value));
3391     else if (name == g_intern_string("serif-font-family"))
3392         settings->setSerifFontFamily(g_value_get_string(&value));
3393     else if (name == g_intern_string("default-font-size"))
3394         settings->setDefaultFontSize(pixelsFromSize(webView, g_value_get_int(&value)));
3395     else if (name == g_intern_string("default-monospace-font-size"))
3396         settings->setDefaultFixedFontSize(pixelsFromSize(webView, g_value_get_int(&value)));
3397     else if (name == g_intern_string("minimum-font-size"))
3398         settings->setMinimumFontSize(pixelsFromSize(webView, g_value_get_int(&value)));
3399     else if (name == g_intern_string("minimum-logical-font-size"))
3400         settings->setMinimumLogicalFontSize(pixelsFromSize(webView, g_value_get_int(&value)));
3401     else if (name == g_intern_string("enforce-96-dpi"))
3402         webkit_web_view_screen_changed(GTK_WIDGET(webView), NULL);
3403     else if (name == g_intern_string("auto-load-images"))
3404         settings->setLoadsImagesAutomatically(g_value_get_boolean(&value));
3405     else if (name == g_intern_string("auto-shrink-images"))
3406         settings->setShrinksStandaloneImagesToFit(g_value_get_boolean(&value));
3407     else if (name == g_intern_string("print-backgrounds"))
3408         settings->setShouldPrintBackgrounds(g_value_get_boolean(&value));
3409     else if (name == g_intern_string("enable-scripts"))
3410         settings->setJavaScriptEnabled(g_value_get_boolean(&value));
3411     else if (name == g_intern_string("enable-plugins"))
3412         settings->setPluginsEnabled(g_value_get_boolean(&value));
3413     else if (name == g_intern_string("enable-dns-prefetching"))
3414         settings->setDNSPrefetchingEnabled(g_value_get_boolean(&value));
3415     else if (name == g_intern_string("resizable-text-areas"))
3416         settings->setTextAreasAreResizable(g_value_get_boolean(&value));
3417     else if (name == g_intern_string("user-stylesheet-uri"))
3418         settings->setUserStyleSheetLocation(KURL(KURL(), g_value_get_string(&value)));
3419     else if (name == g_intern_string("enable-developer-extras"))
3420         settings->setDeveloperExtrasEnabled(g_value_get_boolean(&value));
3421     else if (name == g_intern_string("enable-private-browsing"))
3422         settings->setPrivateBrowsingEnabled(g_value_get_boolean(&value));
3423     else if (name == g_intern_string("enable-caret-browsing"))
3424         settings->setCaretBrowsingEnabled(g_value_get_boolean(&value));
3425 #if ENABLE(DATABASE)
3426     else if (name == g_intern_string("enable-html5-database")) {
3427         AbstractDatabase::setIsAvailable(g_value_get_boolean(&value));
3428     }
3429 #endif
3430     else if (name == g_intern_string("enable-html5-local-storage"))
3431         settings->setLocalStorageEnabled(g_value_get_boolean(&value));
3432     else if (name == g_intern_string("enable-xss-auditor"))
3433         settings->setXSSAuditorEnabled(g_value_get_boolean(&value));
3434     else if (name == g_intern_string("enable-spatial-navigation"))
3435         settings->setSpatialNavigationEnabled(g_value_get_boolean(&value));
3436     else if (name == g_intern_string("enable-frame-flattening"))
3437         settings->setFrameFlatteningEnabled(g_value_get_boolean(&value));
3438     else if (name == g_intern_string("javascript-can-open-windows-automatically"))
3439         settings->setJavaScriptCanOpenWindowsAutomatically(g_value_get_boolean(&value));
3440     else if (name == g_intern_string("javascript-can-access-clipboard"))
3441         settings->setJavaScriptCanAccessClipboard(g_value_get_boolean(&value));
3442     else if (name == g_intern_string("enable-offline-web-application-cache"))
3443         settings->setOfflineWebApplicationCacheEnabled(g_value_get_boolean(&value));
3444     else if (name == g_intern_string("editing-behavior"))
3445         settings->setEditingBehaviorType(static_cast<WebCore::EditingBehaviorType>(g_value_get_enum(&value)));
3446     else if (name == g_intern_string("enable-universal-access-from-file-uris"))
3447         settings->setAllowUniversalAccessFromFileURLs(g_value_get_boolean(&value));
3448     else if (name == g_intern_string("enable-file-access-from-file-uris"))
3449         settings->setAllowFileAccessFromFileURLs(g_value_get_boolean(&value));
3450     else if (name == g_intern_string("enable-dom-paste"))
3451         settings->setDOMPasteAllowed(g_value_get_boolean(&value));
3452     else if (name == g_intern_string("tab-key-cycles-through-elements")) {
3453         Page* page = core(webView);
3454         if (page)
3455             page->setTabKeyCyclesThroughElements(g_value_get_boolean(&value));
3456     } else if (name == g_intern_string("enable-site-specific-quirks"))
3457         settings->setNeedsSiteSpecificQuirks(g_value_get_boolean(&value));
3458     else if (name == g_intern_string("enable-page-cache"))
3459         settings->setUsesPageCache(g_value_get_boolean(&value));
3460     else if (name == g_intern_string("enable-java-applet"))
3461         settings->setJavaEnabled(g_value_get_boolean(&value));
3462     else if (name == g_intern_string("enable-hyperlink-auditing"))
3463         settings->setHyperlinkAuditingEnabled(g_value_get_boolean(&value));
3464 
3465 #if ENABLE(SPELLCHECK)
3466     else if (name == g_intern_string("spell-checking-languages")) {
3467         WebKit::EditorClient* client = static_cast<WebKit::EditorClient*>(core(webView)->editorClient());
3468         static_cast<WebKit::TextCheckerClientEnchant*>(client->textChecker())->updateSpellCheckingLanguage(g_value_get_string(&value));
3469     }
3470 #endif
3471 
3472 #if ENABLE(WEBGL)
3473     else if (name == g_intern_string("enable-webgl"))
3474         settings->setWebGLEnabled(g_value_get_boolean(&value));
3475 #endif
3476 
3477     else if (!g_object_class_find_property(G_OBJECT_GET_CLASS(webSettings), name))
3478         g_warning("Unexpected setting '%s'", name);
3479     g_value_unset(&value);
3480 }
3481 
webkit_web_view_init(WebKitWebView * webView)3482 static void webkit_web_view_init(WebKitWebView* webView)
3483 {
3484     WebKitWebViewPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(webView, WEBKIT_TYPE_WEB_VIEW, WebKitWebViewPrivate);
3485     webView->priv = priv;
3486     // This is the placement new syntax: http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10
3487     // It allows us to call a constructor on manually allocated locations in memory. We must use it
3488     // in this case, because GLib manages the memory for the private data section, but we wish it
3489     // to contain C++ object members. The use of placement new calls the constructor on all C++ data
3490     // members, which ensures they are initialized properly.
3491     new (priv) WebKitWebViewPrivate();
3492 
3493     priv->imContext = adoptGRef(gtk_im_multicontext_new());
3494 
3495     Page::PageClients pageClients;
3496     pageClients.chromeClient = new WebKit::ChromeClient(webView);
3497     pageClients.contextMenuClient = new WebKit::ContextMenuClient(webView);
3498     pageClients.editorClient = new WebKit::EditorClient(webView);
3499     pageClients.dragClient = new WebKit::DragClient(webView);
3500     pageClients.inspectorClient = new WebKit::InspectorClient(webView);
3501     priv->corePage = new Page(pageClients);
3502 
3503     // Pages within a same session need to be linked together otherwise some functionalities such
3504     // as visited link coloration (across pages) and changing popup window location will not work.
3505     // To keep the default behavior simple (and because no PageGroup API exist in WebKitGTK at the
3506     // time of writing this comment), we simply set all the pages to the same group.
3507     priv->corePage->setGroupName("org.webkit.gtk.WebKitGTK");
3508 
3509     // We also add a simple wrapper class to provide the public
3510     // interface for the Web Inspector.
3511     priv->webInspector = adoptGRef(WEBKIT_WEB_INSPECTOR(g_object_new(WEBKIT_TYPE_WEB_INSPECTOR, NULL)));
3512     webkit_web_inspector_set_inspector_client(priv->webInspector.get(), priv->corePage);
3513 
3514     // And our ViewportAttributes friend.
3515     priv->viewportAttributes = adoptGRef(WEBKIT_VIEWPORT_ATTRIBUTES(g_object_new(WEBKIT_TYPE_VIEWPORT_ATTRIBUTES, NULL)));
3516     priv->viewportAttributes->priv->webView = webView;
3517 
3518     // The smart pointer will call g_object_ref_sink on these adjustments.
3519     priv->horizontalAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
3520     priv->verticalAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
3521 
3522     gtk_widget_set_can_focus(GTK_WIDGET(webView), TRUE);
3523     priv->mainFrame = WEBKIT_WEB_FRAME(webkit_web_frame_new(webView));
3524     priv->lastPopupXPosition = priv->lastPopupYPosition = -1;
3525 
3526     priv->backForwardList = adoptGRef(webkit_web_back_forward_list_new_with_web_view(webView));
3527 
3528     priv->zoomFullContent = FALSE;
3529 
3530     priv->webSettings = adoptGRef(webkit_web_settings_new());
3531     webkit_web_view_update_settings(webView);
3532     g_signal_connect(priv->webSettings.get(), "notify", G_CALLBACK(webkit_web_view_settings_notify), webView);
3533 
3534     priv->webWindowFeatures = adoptGRef(webkit_web_window_features_new());
3535 
3536     priv->subResources = adoptGRef(g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref));
3537 
3538     priv->currentClickCount = 0;
3539     priv->previousClickButton = 0;
3540     priv->previousClickTime = 0;
3541     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));
3542     gtk_drag_dest_set_target_list(GTK_WIDGET(webView), pasteboardHelperInstance()->targetList());
3543 }
3544 
webkit_web_view_new(void)3545 GtkWidget* webkit_web_view_new(void)
3546 {
3547     WebKitWebView* webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, NULL));
3548 
3549     return GTK_WIDGET(webView);
3550 }
3551 
3552 // for internal use only
webkit_web_view_notify_ready(WebKitWebView * webView)3553 void webkit_web_view_notify_ready(WebKitWebView* webView)
3554 {
3555     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3556 
3557     gboolean isHandled = FALSE;
3558     g_signal_emit(webView, webkit_web_view_signals[WEB_VIEW_READY], 0, &isHandled);
3559 }
3560 
webkit_web_view_request_download(WebKitWebView * webView,WebKitNetworkRequest * request,const ResourceResponse & response,ResourceHandle * handle)3561 void webkit_web_view_request_download(WebKitWebView* webView, WebKitNetworkRequest* request, const ResourceResponse& response, ResourceHandle* handle)
3562 {
3563     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3564 
3565     WebKitDownload* download;
3566 
3567     if (handle)
3568         download = webkit_download_new_with_handle(request, handle, response);
3569     else
3570         download = webkit_download_new(request);
3571 
3572     gboolean handled;
3573     g_signal_emit(webView, webkit_web_view_signals[DOWNLOAD_REQUESTED], 0, download, &handled);
3574 
3575     if (!handled) {
3576         webkit_download_cancel(download);
3577         g_object_unref(download);
3578         return;
3579     }
3580 
3581     /* Start the download now if it has a destination URI, otherwise it
3582         may be handled asynchronously by the application. */
3583     if (webkit_download_get_destination_uri(download))
3584         webkit_download_start(download);
3585 }
3586 
webkit_web_view_use_primary_for_paste(WebKitWebView * webView)3587 bool webkit_web_view_use_primary_for_paste(WebKitWebView* webView)
3588 {
3589     return webView->priv->usePrimaryForPaste;
3590 }
3591 
3592 /**
3593  * webkit_web_view_set_settings:
3594  * @webView: a #WebKitWebView
3595  * @settings: (transfer none): the #WebKitWebSettings to be set
3596  *
3597  * Replaces the #WebKitWebSettings instance that is currently attached
3598  * to @web_view with @settings. The reference held by the @web_view on
3599  * the old #WebKitWebSettings instance is dropped, and the reference
3600  * count of @settings is inscreased.
3601  *
3602  * The settings are automatically applied to @web_view.
3603  */
webkit_web_view_set_settings(WebKitWebView * webView,WebKitWebSettings * webSettings)3604 void webkit_web_view_set_settings(WebKitWebView* webView, WebKitWebSettings* webSettings)
3605 {
3606     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3607     g_return_if_fail(WEBKIT_IS_WEB_SETTINGS(webSettings));
3608 
3609     WebKitWebViewPrivate* priv = webView->priv;
3610     g_signal_handlers_disconnect_by_func(priv->webSettings.get(), (gpointer)webkit_web_view_settings_notify, webView);
3611     priv->webSettings = webSettings;
3612     webkit_web_view_update_settings(webView);
3613     g_signal_connect(webSettings, "notify", G_CALLBACK(webkit_web_view_settings_notify), webView);
3614     g_object_notify(G_OBJECT(webView), "settings");
3615 }
3616 
3617 /**
3618  * webkit_web_view_get_settings:
3619  * @webView: a #WebKitWebView
3620  *
3621  * Obtains the #WebKitWebSettings associated with the
3622  * #WebKitWebView. The #WebKitWebView always has an associated
3623  * instance of #WebKitWebSettings. The reference that is returned by
3624  * this call is owned by the #WebKitWebView. You may need to increase
3625  * its reference count if you intend to keep it alive for longer than
3626  * the #WebKitWebView.
3627  *
3628  * Return value: (transfer none): the #WebKitWebSettings instance
3629  */
webkit_web_view_get_settings(WebKitWebView * webView)3630 WebKitWebSettings* webkit_web_view_get_settings(WebKitWebView* webView)
3631 {
3632     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3633     return webView->priv->webSettings.get();
3634 }
3635 
3636 /**
3637  * webkit_web_view_get_inspector:
3638  * @webView: a #WebKitWebView
3639  *
3640  * Obtains the #WebKitWebInspector associated with the
3641  * #WebKitWebView. Every #WebKitWebView object has a
3642  * #WebKitWebInspector object attached to it as soon as it is created,
3643  * so this function will only return NULL if the argument is not a
3644  * valid #WebKitWebView.
3645  *
3646  * Return value: (transfer none): the #WebKitWebInspector instance.
3647  *
3648  * Since: 1.0.3
3649  */
webkit_web_view_get_inspector(WebKitWebView * webView)3650 WebKitWebInspector* webkit_web_view_get_inspector(WebKitWebView* webView)
3651 {
3652     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3653     return webView->priv->webInspector.get();
3654 }
3655 
3656 /**
3657  * webkit_web_view_get_viewport_attributes:
3658  * @webView: a #WebKitWebView
3659  *
3660  * Obtains the #WebKitViewportAttributes associated with the
3661  * #WebKitWebView. Every #WebKitWebView object has a
3662  * #WebKitWebViewporAttributes object attached to it as soon as it is
3663  * created, so this function will only return NULL if the argument is
3664  * not a valid #WebKitWebView. Do note however that the viewport
3665  * attributes object only contains valid information when the current
3666  * page has a viewport meta tag. You can check whether the data should
3667  * be used by checking the #WebKitViewport:valid property.
3668  *
3669  * Return value: (transfer none): the #WebKitViewportAttributes instance.
3670  *
3671  * Since: 1.3.8
3672  */
webkit_web_view_get_viewport_attributes(WebKitWebView * webView)3673 WebKitViewportAttributes* webkit_web_view_get_viewport_attributes(WebKitWebView* webView)
3674 {
3675     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3676     return webView->priv->viewportAttributes.get();
3677 }
3678 
3679 // internal
webkit_web_view_set_window_features(WebKitWebView * webView,WebKitWebWindowFeatures * webWindowFeatures)3680 static void webkit_web_view_set_window_features(WebKitWebView* webView, WebKitWebWindowFeatures* webWindowFeatures)
3681 {
3682     if (!webWindowFeatures)
3683       return;
3684     if (webkit_web_window_features_equal(webView->priv->webWindowFeatures.get(), webWindowFeatures))
3685       return;
3686     webView->priv->webWindowFeatures = webWindowFeatures;
3687 }
3688 
3689 /**
3690  * webkit_web_view_get_window_features:
3691  * @webView: a #WebKitWebView
3692  *
3693  * Returns the instance of #WebKitWebWindowFeatures held by the given
3694  * #WebKitWebView.
3695  *
3696  * Return value: (transfer none): the #WebKitWebWindowFeatures
3697  *
3698  * Since: 1.0.3
3699  */
webkit_web_view_get_window_features(WebKitWebView * webView)3700 WebKitWebWindowFeatures* webkit_web_view_get_window_features(WebKitWebView* webView)
3701 {
3702     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3703     return webView->priv->webWindowFeatures.get();
3704 }
3705 
3706 /**
3707  * webkit_web_view_get_title:
3708  * @webView: a #WebKitWebView
3709  *
3710  * Returns the @web_view's document title
3711  *
3712  * Since: 1.1.4
3713  *
3714  * Return value: the title of @web_view
3715  */
webkit_web_view_get_title(WebKitWebView * webView)3716 G_CONST_RETURN gchar* webkit_web_view_get_title(WebKitWebView* webView)
3717 {
3718     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
3719 
3720     WebKitWebViewPrivate* priv = webView->priv;
3721     return priv->mainFrame->priv->title;
3722 }
3723 
3724 /**
3725  * webkit_web_view_get_uri:
3726  * @webView: a #WebKitWebView
3727  *
3728  * Returns the current URI of the contents displayed by the @web_view
3729  *
3730  * Since: 1.1.4
3731  *
3732  * Return value: the URI of @web_view
3733  */
webkit_web_view_get_uri(WebKitWebView * webView)3734 G_CONST_RETURN gchar* webkit_web_view_get_uri(WebKitWebView* webView)
3735 {
3736     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
3737 
3738     WebKitWebViewPrivate* priv = webView->priv;
3739     return priv->mainFrame->priv->uri;
3740 }
3741 
3742 /**
3743  * webkit_web_view_set_maintains_back_forward_list:
3744  * @webView: a #WebKitWebView
3745  * @flag: to tell the view to maintain a back or forward list
3746  *
3747  * Set the view to maintain a back or forward list of history items.
3748  */
webkit_web_view_set_maintains_back_forward_list(WebKitWebView * webView,gboolean flag)3749 void webkit_web_view_set_maintains_back_forward_list(WebKitWebView* webView, gboolean flag)
3750 {
3751     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3752 
3753     static_cast<BackForwardListImpl*>(core(webView)->backForwardList())->setEnabled(flag);
3754 }
3755 
3756 /**
3757  * webkit_web_view_get_back_forward_list:
3758  * @webView: a #WebKitWebView
3759  *
3760  * Obtains the #WebKitWebBackForwardList associated with the given #WebKitWebView. The
3761  * #WebKitWebBackForwardList is owned by the #WebKitWebView.
3762  *
3763  * Return value: (transfer none): the #WebKitWebBackForwardList
3764  */
webkit_web_view_get_back_forward_list(WebKitWebView * webView)3765 WebKitWebBackForwardList* webkit_web_view_get_back_forward_list(WebKitWebView* webView)
3766 {
3767     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
3768     if (!core(webView) || !static_cast<BackForwardListImpl*>(core(webView)->backForwardList())->enabled())
3769         return 0;
3770     return webView->priv->backForwardList.get();
3771 }
3772 
3773 /**
3774  * webkit_web_view_go_to_back_forward_item:
3775  * @webView: a #WebKitWebView
3776  * @item: a #WebKitWebHistoryItem*
3777  *
3778  * Go to the specified #WebKitWebHistoryItem
3779  *
3780  * Return value: %TRUE if loading of item is successful, %FALSE if not
3781  */
webkit_web_view_go_to_back_forward_item(WebKitWebView * webView,WebKitWebHistoryItem * item)3782 gboolean webkit_web_view_go_to_back_forward_item(WebKitWebView* webView, WebKitWebHistoryItem* item)
3783 {
3784     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
3785     g_return_val_if_fail(WEBKIT_IS_WEB_HISTORY_ITEM(item), FALSE);
3786 
3787     WebKitWebBackForwardList* backForwardList = webkit_web_view_get_back_forward_list(webView);
3788     if (!webkit_web_back_forward_list_contains_item(backForwardList, item))
3789         return FALSE;
3790 
3791     core(webView)->goToItem(core(item), FrameLoadTypeIndexedBackForward);
3792     return TRUE;
3793 }
3794 
3795 /**
3796  * webkit_web_view_go_back:
3797  * @webView: a #WebKitWebView
3798  *
3799  * Loads the previous history item.
3800  */
webkit_web_view_go_back(WebKitWebView * webView)3801 void webkit_web_view_go_back(WebKitWebView* webView)
3802 {
3803     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3804 
3805     core(webView)->goBack();
3806 }
3807 
3808 /**
3809  * webkit_web_view_go_back_or_forward:
3810  * @webView: a #WebKitWebView
3811  * @steps: the number of steps
3812  *
3813  * Loads the history item that is the number of @steps away from the current
3814  * item. Negative values represent steps backward while positive values
3815  * represent steps forward.
3816  */
webkit_web_view_go_back_or_forward(WebKitWebView * webView,gint steps)3817 void webkit_web_view_go_back_or_forward(WebKitWebView* webView, gint steps)
3818 {
3819     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3820 
3821     core(webView)->goBackOrForward(steps);
3822 }
3823 
3824 /**
3825  * webkit_web_view_go_forward:
3826  * @webView: a #WebKitWebView
3827  *
3828  * Loads the next history item.
3829  */
webkit_web_view_go_forward(WebKitWebView * webView)3830 void webkit_web_view_go_forward(WebKitWebView* webView)
3831 {
3832     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3833 
3834     core(webView)->goForward();
3835 }
3836 
3837 /**
3838  * webkit_web_view_can_go_back:
3839  * @webView: a #WebKitWebView
3840  *
3841  * Determines whether #web_view has a previous history item.
3842  *
3843  * Return value: %TRUE if able to move back, %FALSE otherwise
3844  */
webkit_web_view_can_go_back(WebKitWebView * webView)3845 gboolean webkit_web_view_can_go_back(WebKitWebView* webView)
3846 {
3847     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
3848 
3849     if (!core(webView) || !core(webView)->backForwardList()->backItem())
3850         return FALSE;
3851 
3852     return TRUE;
3853 }
3854 
3855 /**
3856  * webkit_web_view_can_go_back_or_forward:
3857  * @webView: a #WebKitWebView
3858  * @steps: the number of steps
3859  *
3860  * Determines whether #web_view has a history item of @steps. Negative values
3861  * represent steps backward while positive values represent steps forward.
3862  *
3863  * Return value: %TRUE if able to move back or forward the given number of
3864  * steps, %FALSE otherwise
3865  */
webkit_web_view_can_go_back_or_forward(WebKitWebView * webView,gint steps)3866 gboolean webkit_web_view_can_go_back_or_forward(WebKitWebView* webView, gint steps)
3867 {
3868     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
3869 
3870     return core(webView)->canGoBackOrForward(steps);
3871 }
3872 
3873 /**
3874  * webkit_web_view_can_go_forward:
3875  * @webView: a #WebKitWebView
3876  *
3877  * Determines whether #web_view has a next history item.
3878  *
3879  * Return value: %TRUE if able to move forward, %FALSE otherwise
3880  */
webkit_web_view_can_go_forward(WebKitWebView * webView)3881 gboolean webkit_web_view_can_go_forward(WebKitWebView* webView)
3882 {
3883     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
3884 
3885     Page* page = core(webView);
3886 
3887     if (!page)
3888         return FALSE;
3889 
3890     if (!page->backForwardList()->forwardItem())
3891         return FALSE;
3892 
3893     return TRUE;
3894 }
3895 
3896 /**
3897  * webkit_web_view_open:
3898  * @webView: a #WebKitWebView
3899  * @uri: an URI
3900  *
3901  * Requests loading of the specified URI string.
3902  *
3903  * Deprecated: 1.1.1: Use webkit_web_view_load_uri() instead.
3904   */
webkit_web_view_open(WebKitWebView * webView,const gchar * uri)3905 void webkit_web_view_open(WebKitWebView* webView, const gchar* uri)
3906 {
3907     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3908     g_return_if_fail(uri);
3909 
3910     // We used to support local paths, unlike the newer
3911     // function webkit_web_view_load_uri
3912     if (g_path_is_absolute(uri)) {
3913         gchar* fileUri = g_filename_to_uri(uri, NULL, NULL);
3914         webkit_web_view_load_uri(webView, fileUri);
3915         g_free(fileUri);
3916     }
3917     else
3918         webkit_web_view_load_uri(webView, uri);
3919 }
3920 
webkit_web_view_reload(WebKitWebView * webView)3921 void webkit_web_view_reload(WebKitWebView* webView)
3922 {
3923     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3924 
3925     core(webView)->mainFrame()->loader()->reload();
3926 }
3927 
3928 /**
3929  * webkit_web_view_reload_bypass_cache:
3930  * @webView: a #WebKitWebView
3931  *
3932  * Reloads the @web_view without using any cached data.
3933  *
3934  * Since: 1.0.3
3935  */
webkit_web_view_reload_bypass_cache(WebKitWebView * webView)3936 void webkit_web_view_reload_bypass_cache(WebKitWebView* webView)
3937 {
3938     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3939 
3940     core(webView)->mainFrame()->loader()->reload(true);
3941 }
3942 
3943 /**
3944  * webkit_web_view_load_uri:
3945  * @webView: a #WebKitWebView
3946  * @uri: an URI string
3947  *
3948  * Requests loading of the specified URI string.
3949  *
3950  * Since: 1.1.1
3951  */
webkit_web_view_load_uri(WebKitWebView * webView,const gchar * uri)3952 void webkit_web_view_load_uri(WebKitWebView* webView, const gchar* uri)
3953 {
3954     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3955     g_return_if_fail(uri);
3956 
3957     WebKitWebFrame* frame = webView->priv->mainFrame;
3958     webkit_web_frame_load_uri(frame, uri);
3959 }
3960 
3961 /**
3962   * webkit_web_view_load_string:
3963   * @webView: a #WebKitWebView
3964   * @content: an URI string
3965   * @mime_type: the MIME type, or %NULL
3966   * @encoding: the encoding, or %NULL
3967   * @base_uri: the base URI for relative locations
3968   *
3969   * Requests loading of the given @content with the specified @mime_type,
3970   * @encoding and @base_uri.
3971   *
3972   * If @mime_type is %NULL, "text/html" is assumed.
3973   *
3974   * If @encoding is %NULL, "UTF-8" is assumed.
3975   */
webkit_web_view_load_string(WebKitWebView * webView,const gchar * content,const gchar * mimeType,const gchar * encoding,const gchar * baseUri)3976 void webkit_web_view_load_string(WebKitWebView* webView, const gchar* content, const gchar* mimeType, const gchar* encoding, const gchar* baseUri)
3977 {
3978     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3979     g_return_if_fail(content);
3980 
3981     WebKitWebFrame* frame = webView->priv->mainFrame;
3982     webkit_web_frame_load_string(frame, content, mimeType, encoding, baseUri);
3983 }
3984 /**
3985  * webkit_web_view_load_html_string:
3986  * @webView: a #WebKitWebView
3987  * @content: an URI string
3988  * @base_uri: the base URI for relative locations
3989  *
3990  * Requests loading of the given @content with the specified @base_uri.
3991  *
3992  * Deprecated: 1.1.1: Use webkit_web_view_load_string() instead.
3993  */
webkit_web_view_load_html_string(WebKitWebView * webView,const gchar * content,const gchar * baseUri)3994 void webkit_web_view_load_html_string(WebKitWebView* webView, const gchar* content, const gchar* baseUri)
3995 {
3996     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
3997     g_return_if_fail(content);
3998 
3999     webkit_web_view_load_string(webView, content, NULL, NULL, baseUri);
4000 }
4001 
4002 /**
4003  * webkit_web_view_load_request:
4004  * @webView: a #WebKitWebView
4005  * @request: a #WebKitNetworkRequest
4006  *
4007  * Requests loading of the specified asynchronous client request.
4008  *
4009  * Creates a provisional data source that will transition to a committed data
4010  * source once any data has been received. Use webkit_web_view_stop_loading() to
4011  * stop the load.
4012  *
4013  * Since: 1.1.1
4014  */
webkit_web_view_load_request(WebKitWebView * webView,WebKitNetworkRequest * request)4015 void webkit_web_view_load_request(WebKitWebView* webView, WebKitNetworkRequest* request)
4016 {
4017     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4018     g_return_if_fail(WEBKIT_IS_NETWORK_REQUEST(request));
4019 
4020     WebKitWebFrame* frame = webView->priv->mainFrame;
4021     webkit_web_frame_load_request(frame, request);
4022 }
4023 
4024 /**
4025  * webkit_web_view_stop_loading:
4026  * @webView: a #WebKitWebView
4027  *
4028  * Stops any ongoing load in the @webView.
4029  **/
webkit_web_view_stop_loading(WebKitWebView * webView)4030 void webkit_web_view_stop_loading(WebKitWebView* webView)
4031 {
4032     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4033 
4034     Frame* frame = core(webView)->mainFrame();
4035 
4036     if (FrameLoader* loader = frame->loader())
4037         loader->stopForUserCancel();
4038 }
4039 
4040 /**
4041  * webkit_web_view_search_text:
4042  * @webView: a #WebKitWebView
4043  * @text: a string to look for
4044  * @forward: whether to find forward or not
4045  * @case_sensitive: whether to respect the case of text
4046  * @wrap: whether to continue looking at the beginning after reaching the end
4047  *
4048  * Looks for a specified string inside #web_view.
4049  *
4050  * Return value: %TRUE on success or %FALSE on failure
4051  */
webkit_web_view_search_text(WebKitWebView * webView,const gchar * string,gboolean caseSensitive,gboolean forward,gboolean shouldWrap)4052 gboolean webkit_web_view_search_text(WebKitWebView* webView, const gchar* string, gboolean caseSensitive, gboolean forward, gboolean shouldWrap)
4053 {
4054     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4055     g_return_val_if_fail(string, FALSE);
4056 
4057     TextCaseSensitivity caseSensitivity = caseSensitive ? TextCaseSensitive : TextCaseInsensitive;
4058     FindDirection direction = forward ? FindDirectionForward : FindDirectionBackward;
4059 
4060     return core(webView)->findString(String::fromUTF8(string), caseSensitivity, direction, shouldWrap);
4061 }
4062 
4063 /**
4064  * webkit_web_view_mark_text_matches:
4065  * @webView: a #WebKitWebView
4066  * @string: a string to look for
4067  * @case_sensitive: whether to respect the case of text
4068  * @limit: the maximum number of strings to look for or 0 for all
4069  *
4070  * Attempts to highlight all occurances of #string inside #web_view.
4071  *
4072  * Return value: the number of strings highlighted
4073  */
webkit_web_view_mark_text_matches(WebKitWebView * webView,const gchar * string,gboolean caseSensitive,guint limit)4074 guint webkit_web_view_mark_text_matches(WebKitWebView* webView, const gchar* string, gboolean caseSensitive, guint limit)
4075 {
4076     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
4077     g_return_val_if_fail(string, 0);
4078 
4079     TextCaseSensitivity caseSensitivity = caseSensitive ? TextCaseSensitive : TextCaseInsensitive;
4080 
4081     return core(webView)->markAllMatchesForText(String::fromUTF8(string), caseSensitivity, false, limit);
4082 }
4083 
4084 /**
4085  * webkit_web_view_set_highlight_text_matches:
4086  * @webView: a #WebKitWebView
4087  * @highlight: whether to highlight text matches
4088  *
4089  * Highlights text matches previously marked by webkit_web_view_mark_text_matches.
4090  */
webkit_web_view_set_highlight_text_matches(WebKitWebView * webView,gboolean shouldHighlight)4091 void webkit_web_view_set_highlight_text_matches(WebKitWebView* webView, gboolean shouldHighlight)
4092 {
4093     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4094 
4095     Frame *frame = core(webView)->mainFrame();
4096     do {
4097         frame->editor()->setMarkedTextMatchesAreHighlighted(shouldHighlight);
4098         frame = frame->tree()->traverseNextWithWrap(false);
4099     } while (frame);
4100 }
4101 
4102 /**
4103  * webkit_web_view_unmark_text_matches:
4104  * @webView: a #WebKitWebView
4105  *
4106  * Removes highlighting previously set by webkit_web_view_mark_text_matches.
4107  */
webkit_web_view_unmark_text_matches(WebKitWebView * webView)4108 void webkit_web_view_unmark_text_matches(WebKitWebView* webView)
4109 {
4110     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4111 
4112     return core(webView)->unmarkAllTextMatches();
4113 }
4114 
4115 /**
4116  * webkit_web_view_get_main_frame:
4117  * @webView: a #WebKitWebView
4118  *
4119  * Returns the main frame for the @webView.
4120  *
4121  * Return value: (transfer none): the main #WebKitWebFrame for @webView
4122  */
webkit_web_view_get_main_frame(WebKitWebView * webView)4123 WebKitWebFrame* webkit_web_view_get_main_frame(WebKitWebView* webView)
4124 {
4125     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
4126 
4127     return webView->priv->mainFrame;
4128 }
4129 
4130 /**
4131  * webkit_web_view_get_focused_frame:
4132  * @webView: a #WebKitWebView
4133  *
4134  * Returns the frame that has focus or an active text selection.
4135  *
4136  * Return value: (transfer none): The focused #WebKitWebFrame or %NULL if no frame is focused
4137  */
webkit_web_view_get_focused_frame(WebKitWebView * webView)4138 WebKitWebFrame* webkit_web_view_get_focused_frame(WebKitWebView* webView)
4139 {
4140     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
4141 
4142     Frame* focusedFrame = core(webView)->focusController()->focusedFrame();
4143     return kit(focusedFrame);
4144 }
4145 
webkit_web_view_execute_script(WebKitWebView * webView,const gchar * script)4146 void webkit_web_view_execute_script(WebKitWebView* webView, const gchar* script)
4147 {
4148     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4149     g_return_if_fail(script);
4150 
4151     core(webView)->mainFrame()->script()->executeScript(String::fromUTF8(script), true);
4152 }
4153 
4154 /**
4155  * webkit_web_view_can_cut_clipboard:
4156  * @webView: a #WebKitWebView
4157  *
4158  * Determines whether or not it is currently possible to cut to the clipboard.
4159  *
4160  * Return value: %TRUE if a selection can be cut, %FALSE if not
4161  */
webkit_web_view_can_cut_clipboard(WebKitWebView * webView)4162 gboolean webkit_web_view_can_cut_clipboard(WebKitWebView* webView)
4163 {
4164     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4165 
4166     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
4167     return frame->editor()->canCut() || frame->editor()->canDHTMLCut();
4168 }
4169 
4170 /**
4171  * webkit_web_view_can_copy_clipboard:
4172  * @webView: a #WebKitWebView
4173  *
4174  * Determines whether or not it is currently possible to copy to the clipboard.
4175  *
4176  * Return value: %TRUE if a selection can be copied, %FALSE if not
4177  */
webkit_web_view_can_copy_clipboard(WebKitWebView * webView)4178 gboolean webkit_web_view_can_copy_clipboard(WebKitWebView* webView)
4179 {
4180     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4181 
4182     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
4183     return frame->editor()->canCopy() || frame->editor()->canDHTMLCopy();
4184 }
4185 
4186 /**
4187  * webkit_web_view_can_paste_clipboard:
4188  * @webView: a #WebKitWebView
4189  *
4190  * Determines whether or not it is currently possible to paste from the clipboard.
4191  *
4192  * Return value: %TRUE if a selection can be pasted, %FALSE if not
4193  */
webkit_web_view_can_paste_clipboard(WebKitWebView * webView)4194 gboolean webkit_web_view_can_paste_clipboard(WebKitWebView* webView)
4195 {
4196     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4197 
4198     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
4199     return frame->editor()->canPaste() || frame->editor()->canDHTMLPaste();
4200 }
4201 
4202 /**
4203  * webkit_web_view_cut_clipboard:
4204  * @webView: a #WebKitWebView
4205  *
4206  * Cuts the current selection inside the @web_view to the clipboard.
4207  */
webkit_web_view_cut_clipboard(WebKitWebView * webView)4208 void webkit_web_view_cut_clipboard(WebKitWebView* webView)
4209 {
4210     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4211 
4212     if (webkit_web_view_can_cut_clipboard(webView))
4213         g_signal_emit(webView, webkit_web_view_signals[CUT_CLIPBOARD], 0);
4214 }
4215 
4216 /**
4217  * webkit_web_view_copy_clipboard:
4218  * @webView: a #WebKitWebView
4219  *
4220  * Copies the current selection inside the @web_view to the clipboard.
4221  */
webkit_web_view_copy_clipboard(WebKitWebView * webView)4222 void webkit_web_view_copy_clipboard(WebKitWebView* webView)
4223 {
4224     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4225 
4226     if (webkit_web_view_can_copy_clipboard(webView))
4227         g_signal_emit(webView, webkit_web_view_signals[COPY_CLIPBOARD], 0);
4228 }
4229 
4230 /**
4231  * webkit_web_view_paste_clipboard:
4232  * @webView: a #WebKitWebView
4233  *
4234  * Pastes the current contents of the clipboard to the @web_view.
4235  */
webkit_web_view_paste_clipboard(WebKitWebView * webView)4236 void webkit_web_view_paste_clipboard(WebKitWebView* webView)
4237 {
4238     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4239 
4240     if (webkit_web_view_can_paste_clipboard(webView))
4241         g_signal_emit(webView, webkit_web_view_signals[PASTE_CLIPBOARD], 0);
4242 }
4243 
4244 /**
4245  * webkit_web_view_delete_selection:
4246  * @webView: a #WebKitWebView
4247  *
4248  * Deletes the current selection inside the @web_view.
4249  */
webkit_web_view_delete_selection(WebKitWebView * webView)4250 void webkit_web_view_delete_selection(WebKitWebView* webView)
4251 {
4252     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4253 
4254     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
4255     frame->editor()->performDelete();
4256 }
4257 
4258 /**
4259  * webkit_web_view_has_selection:
4260  * @webView: a #WebKitWebView
4261  *
4262  * Determines whether text was selected.
4263  *
4264  * Return value: %TRUE if there is selected text, %FALSE if not
4265  */
webkit_web_view_has_selection(WebKitWebView * webView)4266 gboolean webkit_web_view_has_selection(WebKitWebView* webView)
4267 {
4268     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4269 
4270     return !core(webView)->selection().isNone();
4271 }
4272 
4273 /**
4274  * webkit_web_view_get_selected_text:
4275  * @webView: a #WebKitWebView
4276  *
4277  * Retrieves the selected text if any.
4278  *
4279  * Return value: a newly allocated string with the selection or %NULL
4280  */
webkit_web_view_get_selected_text(WebKitWebView * webView)4281 gchar* webkit_web_view_get_selected_text(WebKitWebView* webView)
4282 {
4283     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
4284 
4285     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
4286     return g_strdup(frame->editor()->selectedText().utf8().data());
4287 }
4288 
4289 /**
4290  * webkit_web_view_select_all:
4291  * @webView: a #WebKitWebView
4292  *
4293  * Attempts to select everything inside the @web_view.
4294  */
webkit_web_view_select_all(WebKitWebView * webView)4295 void webkit_web_view_select_all(WebKitWebView* webView)
4296 {
4297     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4298 
4299     g_signal_emit(webView, webkit_web_view_signals[SELECT_ALL], 0);
4300 }
4301 
4302 /**
4303  * webkit_web_view_get_editable:
4304  * @webView: a #WebKitWebView
4305  *
4306  * Returns whether the user is allowed to edit the document.
4307  *
4308  * Returns %TRUE if @web_view allows the user to edit the HTML document, %FALSE if
4309  * it doesn't. You can change @web_view's document programmatically regardless of
4310  * this setting.
4311  *
4312  * Return value: a #gboolean indicating the editable state
4313  */
webkit_web_view_get_editable(WebKitWebView * webView)4314 gboolean webkit_web_view_get_editable(WebKitWebView* webView)
4315 {
4316     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4317 
4318     return core(webView)->isEditable();
4319 }
4320 
4321 /**
4322  * webkit_web_view_set_editable:
4323  * @webView: a #WebKitWebView
4324  * @flag: a #gboolean indicating the editable state
4325  *
4326  * Sets whether @web_view allows the user to edit its HTML document.
4327  *
4328  * If @flag is %TRUE, @web_view allows the user to edit the document. If @flag is
4329  * %FALSE, an element in @web_view's document can only be edited if the
4330  * CONTENTEDITABLE attribute has been set on the element or one of its parent
4331  * elements. You can change @web_view's document programmatically regardless of
4332  * this setting. By default a #WebKitWebView is not editable.
4333 
4334  * Normally, an HTML document is not editable unless the elements within the
4335  * document are editable. This function provides a low-level way to make the
4336  * contents of a #WebKitWebView editable without altering the document or DOM
4337  * structure.
4338  */
webkit_web_view_set_editable(WebKitWebView * webView,gboolean flag)4339 void webkit_web_view_set_editable(WebKitWebView* webView, gboolean flag)
4340 {
4341     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4342 
4343     flag = flag != FALSE;
4344     if (flag == webkit_web_view_get_editable(webView))
4345         return;
4346 
4347     core(webView)->setEditable(flag);
4348 
4349     Frame* frame = core(webView)->mainFrame();
4350     g_return_if_fail(frame);
4351 
4352     if (flag) {
4353         frame->editor()->applyEditingStyleToBodyElement();
4354         // TODO: If the WebKitWebView is made editable and the selection is empty, set it to something.
4355         //if (!webkit_web_view_get_selected_dom_range(webView))
4356         //    mainFrame->setSelectionFromNone();
4357     }
4358     g_object_notify(G_OBJECT(webView), "editable");
4359 }
4360 
4361 /**
4362  * webkit_web_view_get_copy_target_list:
4363  * @webView: a #WebKitWebView
4364  *
4365  * This function returns the list of targets this #WebKitWebView can
4366  * provide for clipboard copying and as DND source. The targets in the list are
4367  * added with values from the #WebKitWebViewTargetInfo enum,
4368  * using gtk_target_list_add() and
4369  * gtk_target_list_add_text_targets().
4370  *
4371  * Return value: the #GtkTargetList
4372  **/
webkit_web_view_get_copy_target_list(WebKitWebView * webView)4373 GtkTargetList* webkit_web_view_get_copy_target_list(WebKitWebView* webView)
4374 {
4375     return pasteboardHelperInstance()->targetList();
4376 }
4377 
4378 /**
4379  * webkit_web_view_get_paste_target_list:
4380  * @webView: a #WebKitWebView
4381  *
4382  * This function returns the list of targets this #WebKitWebView can
4383  * provide for clipboard pasting and as DND destination. The targets in the list are
4384  * added with values from the #WebKitWebViewTargetInfo enum,
4385  * using gtk_target_list_add() and
4386  * gtk_target_list_add_text_targets().
4387  *
4388  * Return value: the #GtkTargetList
4389  **/
webkit_web_view_get_paste_target_list(WebKitWebView * webView)4390 GtkTargetList* webkit_web_view_get_paste_target_list(WebKitWebView* webView)
4391 {
4392     return pasteboardHelperInstance()->targetList();
4393 }
4394 
4395 /**
4396  * webkit_web_view_can_show_mime_type:
4397  * @webView: a #WebKitWebView
4398  * @mime_type: a MIME type
4399  *
4400  * This functions returns whether or not a MIME type can be displayed using this view.
4401  *
4402  * Return value: a #gboolean indicating if the MIME type can be displayed
4403  *
4404  * Since: 1.0.3
4405  **/
4406 
webkit_web_view_can_show_mime_type(WebKitWebView * webView,const gchar * mimeType)4407 gboolean webkit_web_view_can_show_mime_type(WebKitWebView* webView, const gchar* mimeType)
4408 {
4409     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4410 
4411     Frame* frame = core(webkit_web_view_get_main_frame(webView));
4412     if (FrameLoader* loader = frame->loader())
4413         return loader->canShowMIMEType(String::fromUTF8(mimeType));
4414     else
4415         return FALSE;
4416 }
4417 
4418 /**
4419  * webkit_web_view_get_transparent:
4420  * @webView: a #WebKitWebView
4421  *
4422  * Returns whether the #WebKitWebView has a transparent background.
4423  *
4424  * Return value: %FALSE when the #WebKitWebView draws a solid background
4425  * (the default), otherwise %TRUE.
4426  */
webkit_web_view_get_transparent(WebKitWebView * webView)4427 gboolean webkit_web_view_get_transparent(WebKitWebView* webView)
4428 {
4429     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4430 
4431     WebKitWebViewPrivate* priv = webView->priv;
4432     return priv->transparent;
4433 }
4434 
4435 /**
4436  * webkit_web_view_set_transparent:
4437  * @webView: a #WebKitWebView
4438  *
4439  * Sets whether the #WebKitWebView has a transparent background.
4440  *
4441  * Pass %FALSE to have the #WebKitWebView draw a solid background
4442  * (the default), otherwise %TRUE.
4443  */
webkit_web_view_set_transparent(WebKitWebView * webView,gboolean flag)4444 void webkit_web_view_set_transparent(WebKitWebView* webView, gboolean flag)
4445 {
4446     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4447 
4448     WebKitWebViewPrivate* priv = webView->priv;
4449     priv->transparent = flag;
4450 
4451     // TODO: This needs to be made persistent or it could become a problem when
4452     // the main frame is replaced.
4453     Frame* frame = core(webView)->mainFrame();
4454     g_return_if_fail(frame);
4455     frame->view()->setTransparent(flag);
4456     g_object_notify(G_OBJECT(webView), "transparent");
4457 }
4458 
4459 /**
4460  * webkit_web_view_get_zoom_level:
4461  * @webView: a #WebKitWebView
4462  *
4463  * Returns the zoom level of @web_view, i.e. the factor by which elements in
4464  * the page are scaled with respect to their original size.
4465  * If the "full-content-zoom" property is set to %FALSE (the default)
4466  * the zoom level changes the text size, or if %TRUE, scales all
4467  * elements in the page.
4468  *
4469  * Return value: the zoom level of @web_view
4470  *
4471  * Since: 1.0.1
4472  */
webkit_web_view_get_zoom_level(WebKitWebView * webView)4473 gfloat webkit_web_view_get_zoom_level(WebKitWebView* webView)
4474 {
4475     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 1.0f);
4476 
4477     Frame* frame = core(webView)->mainFrame();
4478     if (!frame)
4479         return 1.0f;
4480 
4481     WebKitWebViewPrivate* priv = webView->priv;
4482     return priv->zoomFullContent ? frame->pageZoomFactor() : frame->textZoomFactor();
4483 }
4484 
webkit_web_view_apply_zoom_level(WebKitWebView * webView,gfloat zoomLevel)4485 static void webkit_web_view_apply_zoom_level(WebKitWebView* webView, gfloat zoomLevel)
4486 {
4487     Frame* frame = core(webView)->mainFrame();
4488     if (!frame)
4489         return;
4490 
4491     WebKitWebViewPrivate* priv = webView->priv;
4492     if (priv->zoomFullContent)
4493         frame->setPageZoomFactor(zoomLevel);
4494     else
4495         frame->setTextZoomFactor(zoomLevel);
4496 }
4497 
4498 /**
4499  * webkit_web_view_set_zoom_level:
4500  * @webView: a #WebKitWebView
4501  * @zoom_level: the new zoom level
4502  *
4503  * Sets the zoom level of @web_view, i.e. the factor by which elements in
4504  * the page are scaled with respect to their original size.
4505  * If the "full-content-zoom" property is set to %FALSE (the default)
4506  * the zoom level changes the text size, or if %TRUE, scales all
4507  * elements in the page.
4508  *
4509  * Since: 1.0.1
4510  */
webkit_web_view_set_zoom_level(WebKitWebView * webView,gfloat zoomLevel)4511 void webkit_web_view_set_zoom_level(WebKitWebView* webView, gfloat zoomLevel)
4512 {
4513     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4514 
4515     webkit_web_view_apply_zoom_level(webView, zoomLevel);
4516     g_object_notify(G_OBJECT(webView), "zoom-level");
4517 }
4518 
4519 /**
4520  * webkit_web_view_zoom_in:
4521  * @webView: a #WebKitWebView
4522  *
4523  * Increases the zoom level of @web_view. The current zoom
4524  * level is incremented by the value of the "zoom-step"
4525  * property of the #WebKitWebSettings associated with @web_view.
4526  *
4527  * Since: 1.0.1
4528  */
webkit_web_view_zoom_in(WebKitWebView * webView)4529 void webkit_web_view_zoom_in(WebKitWebView* webView)
4530 {
4531     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4532 
4533     WebKitWebViewPrivate* priv = webView->priv;
4534     gfloat zoomMultiplierRatio;
4535     g_object_get(priv->webSettings.get(), "zoom-step", &zoomMultiplierRatio, NULL);
4536 
4537     webkit_web_view_set_zoom_level(webView, webkit_web_view_get_zoom_level(webView) + zoomMultiplierRatio);
4538 }
4539 
4540 /**
4541  * webkit_web_view_zoom_out:
4542  * @webView: a #WebKitWebView
4543  *
4544  * Decreases the zoom level of @web_view. The current zoom
4545  * level is decremented by the value of the "zoom-step"
4546  * property of the #WebKitWebSettings associated with @web_view.
4547  *
4548  * Since: 1.0.1
4549  */
webkit_web_view_zoom_out(WebKitWebView * webView)4550 void webkit_web_view_zoom_out(WebKitWebView* webView)
4551 {
4552     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4553 
4554     WebKitWebViewPrivate* priv = webView->priv;
4555     gfloat zoomMultiplierRatio;
4556     g_object_get(priv->webSettings.get(), "zoom-step", &zoomMultiplierRatio, NULL);
4557 
4558     webkit_web_view_set_zoom_level(webView, webkit_web_view_get_zoom_level(webView) - zoomMultiplierRatio);
4559 }
4560 
4561 /**
4562  * webkit_web_view_get_full_content_zoom:
4563  * @webView: a #WebKitWebView
4564  *
4565  * Returns whether the zoom level affects only text or all elements.
4566  *
4567  * Return value: %FALSE if only text should be scaled (the default),
4568  * %TRUE if the full content of the view should be scaled.
4569  *
4570  * Since: 1.0.1
4571  */
webkit_web_view_get_full_content_zoom(WebKitWebView * webView)4572 gboolean webkit_web_view_get_full_content_zoom(WebKitWebView* webView)
4573 {
4574     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4575 
4576     WebKitWebViewPrivate* priv = webView->priv;
4577     return priv->zoomFullContent;
4578 }
4579 
4580 /**
4581  * webkit_web_view_set_full_content_zoom:
4582  * @webView: a #WebKitWebView
4583  * @full_content_zoom: %FALSE if only text should be scaled (the default),
4584  * %TRUE if the full content of the view should be scaled.
4585  *
4586  * Sets whether the zoom level affects only text or all elements.
4587  *
4588  * Since: 1.0.1
4589  */
webkit_web_view_set_full_content_zoom(WebKitWebView * webView,gboolean zoomFullContent)4590 void webkit_web_view_set_full_content_zoom(WebKitWebView* webView, gboolean zoomFullContent)
4591 {
4592     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4593 
4594     WebKitWebViewPrivate* priv = webView->priv;
4595     if (priv->zoomFullContent == zoomFullContent)
4596       return;
4597 
4598     Frame* frame = core(webView)->mainFrame();
4599     if (!frame)
4600       return;
4601 
4602     gfloat zoomLevel = priv->zoomFullContent ? frame->pageZoomFactor() : frame->textZoomFactor();
4603 
4604     priv->zoomFullContent = zoomFullContent;
4605     if (priv->zoomFullContent)
4606         frame->setPageAndTextZoomFactors(zoomLevel, 1);
4607     else
4608         frame->setPageAndTextZoomFactors(1, zoomLevel);
4609 
4610     g_object_notify(G_OBJECT(webView), "full-content-zoom");
4611 }
4612 
4613 /**
4614  * webkit_web_view_get_load_status:
4615  * @webView: a #WebKitWebView
4616  *
4617  * Determines the current status of the load.
4618  *
4619  * Since: 1.1.7
4620  */
webkit_web_view_get_load_status(WebKitWebView * webView)4621 WebKitLoadStatus webkit_web_view_get_load_status(WebKitWebView* webView)
4622 {
4623     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), WEBKIT_LOAD_FINISHED);
4624 
4625     WebKitWebViewPrivate* priv = webView->priv;
4626     return priv->loadStatus;
4627 }
4628 
4629 /**
4630  * webkit_web_view_get_progress:
4631  * @webView: a #WebKitWebView
4632  *
4633  * Determines the current progress of the load.
4634  *
4635  * Since: 1.1.7
4636  */
webkit_web_view_get_progress(WebKitWebView * webView)4637 gdouble webkit_web_view_get_progress(WebKitWebView* webView)
4638 {
4639     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 1.0);
4640 
4641     return core(webView)->progress()->estimatedProgress();
4642 }
4643 
4644 /**
4645  * webkit_web_view_get_encoding:
4646  * @webView: a #WebKitWebView
4647  *
4648  * Returns the default encoding of the #WebKitWebView.
4649  *
4650  * Return value: the default encoding
4651  *
4652  * Since: 1.1.1
4653  */
webkit_web_view_get_encoding(WebKitWebView * webView)4654 const gchar* webkit_web_view_get_encoding(WebKitWebView* webView)
4655 {
4656     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
4657     String encoding = core(webView)->mainFrame()->document()->loader()->writer()->encoding();
4658     if (encoding.isEmpty())
4659         return 0;
4660     webView->priv->encoding = encoding.utf8();
4661     return webView->priv->encoding.data();
4662 }
4663 
4664 /**
4665  * webkit_web_view_set_custom_encoding:
4666  * @webView: a #WebKitWebView
4667  * @encoding: the new encoding, or %NULL to restore the default encoding
4668  *
4669  * Sets the current #WebKitWebView encoding, without modifying the default one,
4670  * and reloads the page.
4671  *
4672  * Since: 1.1.1
4673  */
webkit_web_view_set_custom_encoding(WebKitWebView * webView,const char * encoding)4674 void webkit_web_view_set_custom_encoding(WebKitWebView* webView, const char* encoding)
4675 {
4676     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4677 
4678     core(webView)->mainFrame()->loader()->reloadWithOverrideEncoding(String::fromUTF8(encoding));
4679 }
4680 
4681 /**
4682  * webkit_web_view_get_custom_encoding:
4683  * @webView: a #WebKitWebView
4684  *
4685  * Returns the current encoding of the #WebKitWebView, not the default-encoding
4686  * of WebKitWebSettings.
4687  *
4688  * Return value: a string containing the current custom encoding for @web_view, or %NULL if there's none set.
4689  *
4690  * Since: 1.1.1
4691  */
webkit_web_view_get_custom_encoding(WebKitWebView * webView)4692 const char* webkit_web_view_get_custom_encoding(WebKitWebView* webView)
4693 {
4694     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
4695     String overrideEncoding = core(webView)->mainFrame()->loader()->documentLoader()->overrideEncoding();
4696     if (overrideEncoding.isEmpty())
4697         return 0;
4698     webView->priv->customEncoding = overrideEncoding.utf8();
4699     return webView->priv->customEncoding.data();
4700 }
4701 
4702 /**
4703  * webkit_web_view_set_view_mode:
4704  * @webView: the #WebKitWebView that will have its view mode set
4705  * @mode: the %WebKitWebViewViewMode to be set
4706  *
4707  * Sets the view-mode property of the #WebKitWebView. Check the
4708  * property's documentation for more information.
4709  *
4710  * Since: 1.3.4
4711  */
webkit_web_view_set_view_mode(WebKitWebView * webView,WebKitWebViewViewMode mode)4712 void webkit_web_view_set_view_mode(WebKitWebView* webView, WebKitWebViewViewMode mode)
4713 {
4714     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4715 
4716     Page* page = core(webView);
4717 
4718     switch (mode) {
4719     case WEBKIT_WEB_VIEW_VIEW_MODE_FLOATING:
4720         page->setViewMode(Page::ViewModeFloating);
4721         break;
4722     case WEBKIT_WEB_VIEW_VIEW_MODE_FULLSCREEN:
4723         page->setViewMode(Page::ViewModeFullscreen);
4724         break;
4725     case WEBKIT_WEB_VIEW_VIEW_MODE_MAXIMIZED:
4726         page->setViewMode(Page::ViewModeMaximized);
4727         break;
4728     case WEBKIT_WEB_VIEW_VIEW_MODE_MINIMIZED:
4729         page->setViewMode(Page::ViewModeMinimized);
4730         break;
4731     default:
4732         page->setViewMode(Page::ViewModeWindowed);
4733         break;
4734     }
4735 }
4736 
4737 /**
4738  * webkit_web_view_get_view_mode:
4739  * @webView: the #WebKitWebView to obtain the view mode from
4740  *
4741  * Gets the value of the view-mode property of the
4742  * #WebKitWebView. Check the property's documentation for more
4743  * information.
4744  *
4745  * Return value: the %WebKitWebViewViewMode currently set for the
4746  * #WebKitWebView.
4747  *
4748  * Since: 1.3.4
4749  */
webkit_web_view_get_view_mode(WebKitWebView * webView)4750 WebKitWebViewViewMode webkit_web_view_get_view_mode(WebKitWebView* webView)
4751 {
4752     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), WEBKIT_WEB_VIEW_VIEW_MODE_WINDOWED);
4753 
4754     Page* page = core(webView);
4755     Page::ViewMode mode = page->viewMode();
4756 
4757     if (mode == Page::ViewModeFloating)
4758         return WEBKIT_WEB_VIEW_VIEW_MODE_FLOATING;
4759 
4760     if (mode == Page::ViewModeFullscreen)
4761         return WEBKIT_WEB_VIEW_VIEW_MODE_FULLSCREEN;
4762 
4763     if (mode == Page::ViewModeMaximized)
4764         return WEBKIT_WEB_VIEW_VIEW_MODE_MAXIMIZED;
4765 
4766     if (mode == Page::ViewModeMinimized)
4767         return WEBKIT_WEB_VIEW_VIEW_MODE_MINIMIZED;
4768 
4769     return WEBKIT_WEB_VIEW_VIEW_MODE_WINDOWED;
4770 }
4771 
4772 /**
4773  * webkit_web_view_move_cursor:
4774  * @webView: a #WebKitWebView
4775  * @step: a #GtkMovementStep
4776  * @count: integer describing the direction of the movement. 1 for forward, -1 for backwards.
4777  *
4778  * Move the cursor in @view as described by @step and @count.
4779  *
4780  * Since: 1.1.4
4781  */
webkit_web_view_move_cursor(WebKitWebView * webView,GtkMovementStep step,gint count)4782 void webkit_web_view_move_cursor(WebKitWebView* webView, GtkMovementStep step, gint count)
4783 {
4784     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4785     g_return_if_fail(step == GTK_MOVEMENT_VISUAL_POSITIONS ||
4786                      step == GTK_MOVEMENT_DISPLAY_LINES ||
4787                      step == GTK_MOVEMENT_PAGES ||
4788                      step == GTK_MOVEMENT_BUFFER_ENDS);
4789     g_return_if_fail(count == 1 || count == -1);
4790 
4791     gboolean handled;
4792     g_signal_emit(webView, webkit_web_view_signals[MOVE_CURSOR], 0, step, count, &handled);
4793 }
4794 
4795 /**
4796  * webkit_web_view_can_undo:
4797  * @webView: a #WebKitWebView
4798  *
4799  * Determines whether or not it is currently possible to undo the last
4800  * editing command in the view.
4801  *
4802  * Return value: %TRUE if a undo can be done, %FALSE if not
4803  *
4804  * Since: 1.1.14
4805  */
webkit_web_view_can_undo(WebKitWebView * webView)4806 gboolean webkit_web_view_can_undo(WebKitWebView* webView)
4807 {
4808     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4809 
4810     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
4811     return frame->editor()->canUndo();
4812 }
4813 
4814 /**
4815  * webkit_web_view_undo:
4816  * @webView: a #WebKitWebView
4817  *
4818  * Undoes the last editing command in the view, if possible.
4819  *
4820  * Since: 1.1.14
4821  */
webkit_web_view_undo(WebKitWebView * webView)4822 void webkit_web_view_undo(WebKitWebView* webView)
4823 {
4824     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4825 
4826     if (webkit_web_view_can_undo(webView))
4827         g_signal_emit(webView, webkit_web_view_signals[UNDO], 0);
4828 }
4829 
4830 /**
4831  * webkit_web_view_can_redo:
4832  * @webView: a #WebKitWebView
4833  *
4834  * Determines whether or not it is currently possible to redo the last
4835  * editing command in the view.
4836  *
4837  * Return value: %TRUE if a redo can be done, %FALSE if not
4838  *
4839  * Since: 1.1.14
4840  */
webkit_web_view_can_redo(WebKitWebView * webView)4841 gboolean webkit_web_view_can_redo(WebKitWebView* webView)
4842 {
4843     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4844 
4845     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
4846     return frame->editor()->canRedo();
4847 }
4848 
4849 /**
4850  * webkit_web_view_redo:
4851  * @webView: a #WebKitWebView
4852  *
4853  * Redoes the last editing command in the view, if possible.
4854  *
4855  * Since: 1.1.14
4856  */
webkit_web_view_redo(WebKitWebView * webView)4857 void webkit_web_view_redo(WebKitWebView* webView)
4858 {
4859     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4860 
4861     if (webkit_web_view_can_redo(webView))
4862         g_signal_emit(webView, webkit_web_view_signals[REDO], 0);
4863 }
4864 
4865 
4866 /**
4867  * webkit_web_view_set_view_source_mode:
4868  * @webView: a #WebKitWebView
4869  * @view_source_mode: the mode to turn on or off view source mode
4870  *
4871  * Set whether the view should be in view source mode. Setting this mode to
4872  * %TRUE before loading a URI will display the source of the web page in a
4873  * nice and readable format.
4874  *
4875  * Since: 1.1.14
4876  */
webkit_web_view_set_view_source_mode(WebKitWebView * webView,gboolean mode)4877 void webkit_web_view_set_view_source_mode (WebKitWebView* webView, gboolean mode)
4878 {
4879     g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
4880 
4881     if (Frame* mainFrame = core(webView)->mainFrame())
4882         mainFrame->setInViewSourceMode(mode);
4883 }
4884 
4885 /**
4886  * webkit_web_view_get_view_source_mode:
4887  * @webView: a #WebKitWebView
4888  *
4889  * Return value: %TRUE if @web_view is in view source mode, %FALSE otherwise.
4890  *
4891  * Since: 1.1.14
4892  */
webkit_web_view_get_view_source_mode(WebKitWebView * webView)4893 gboolean webkit_web_view_get_view_source_mode (WebKitWebView* webView)
4894 {
4895     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
4896 
4897     if (Frame* mainFrame = core(webView)->mainFrame())
4898         return mainFrame->inViewSourceMode();
4899 
4900     return FALSE;
4901 }
4902 
4903 // Internal subresource management
webkit_web_view_add_main_resource(WebKitWebView * webView,const char * identifier,WebKitWebResource * webResource)4904 void webkit_web_view_add_main_resource(WebKitWebView* webView, const char* identifier, WebKitWebResource* webResource)
4905 {
4906     WebKitWebViewPrivate* priv = webView->priv;
4907 
4908     priv->mainResource = adoptGRef(webResource);
4909     priv->mainResourceIdentifier = identifier;
4910 }
4911 
webkit_web_view_add_resource(WebKitWebView * webView,const char * identifier,WebKitWebResource * webResource)4912 void webkit_web_view_add_resource(WebKitWebView* webView, const char* identifier, WebKitWebResource* webResource)
4913 {
4914     WebKitWebViewPrivate* priv = webView->priv;
4915     g_hash_table_insert(priv->subResources.get(), g_strdup(identifier), webResource);
4916 }
4917 
webkit_web_view_remove_resource(WebKitWebView * webView,const char * identifier)4918 void webkit_web_view_remove_resource(WebKitWebView* webView, const char* identifier)
4919 {
4920     WebKitWebViewPrivate* priv = webView->priv;
4921     if (g_str_equal(identifier, priv->mainResourceIdentifier.data())) {
4922         priv->mainResourceIdentifier = "";
4923         priv->mainResource = 0;
4924     } else
4925       g_hash_table_remove(priv->subResources.get(), identifier);
4926 }
4927 
webkit_web_view_get_resource(WebKitWebView * webView,char * identifier)4928 WebKitWebResource* webkit_web_view_get_resource(WebKitWebView* webView, char* identifier)
4929 {
4930     WebKitWebViewPrivate* priv = webView->priv;
4931     gpointer webResource = 0;
4932     gboolean resourceFound = g_hash_table_lookup_extended(priv->subResources.get(), identifier, NULL, &webResource);
4933 
4934     // The only resource we do not store in this hash table is the
4935     // main!  If we did not find a request, it probably means the load
4936     // has been interrupted while while a resource was still being
4937     // loaded.
4938     if (!resourceFound && !g_str_equal(identifier, priv->mainResourceIdentifier.data()))
4939         return 0;
4940 
4941     if (!webResource)
4942         return webkit_web_view_get_main_resource(webView);
4943 
4944     return WEBKIT_WEB_RESOURCE(webResource);
4945 }
4946 
webkit_web_view_get_main_resource(WebKitWebView * webView)4947 WebKitWebResource* webkit_web_view_get_main_resource(WebKitWebView* webView)
4948 {
4949     return webView->priv->mainResource.get();
4950 }
4951 
webkit_web_view_clear_resources(WebKitWebView * webView)4952 void webkit_web_view_clear_resources(WebKitWebView* webView)
4953 {
4954     WebKitWebViewPrivate* priv = webView->priv;
4955 
4956     if (priv->subResources)
4957         g_hash_table_remove_all(priv->subResources.get());
4958 }
4959 
webkit_web_view_get_subresources(WebKitWebView * webView)4960 GList* webkit_web_view_get_subresources(WebKitWebView* webView)
4961 {
4962     WebKitWebViewPrivate* priv = webView->priv;
4963     GList* subResources = g_hash_table_get_values(priv->subResources.get());
4964     return g_list_remove(subResources, priv->mainResource.get());
4965 }
4966 
4967 /* From EventHandler.cpp */
documentPointForWindowPoint(Frame * frame,const IntPoint & windowPoint)4968 static IntPoint documentPointForWindowPoint(Frame* frame, const IntPoint& windowPoint)
4969 {
4970     FrameView* view = frame->view();
4971     // FIXME: Is it really OK to use the wrong coordinates here when view is 0?
4972     // Historically the code would just crash; this is clearly no worse than that.
4973     return view ? view->windowToContents(windowPoint) : windowPoint;
4974 }
4975 
webkit_web_view_set_tooltip_text(WebKitWebView * webView,const char * tooltip)4976 void webkit_web_view_set_tooltip_text(WebKitWebView* webView, const char* tooltip)
4977 {
4978 #if GTK_CHECK_VERSION(2, 12, 0)
4979     WebKitWebViewPrivate* priv = webView->priv;
4980     if (tooltip && *tooltip != '\0') {
4981         priv->tooltipText = tooltip;
4982         gtk_widget_set_has_tooltip(GTK_WIDGET(webView), TRUE);
4983     } else {
4984         priv->tooltipText = "";
4985         gtk_widget_set_has_tooltip(GTK_WIDGET(webView), FALSE);
4986     }
4987 
4988     gtk_widget_trigger_tooltip_query(GTK_WIDGET(webView));
4989 #else
4990     // TODO: Support older GTK+ versions
4991     // See http://bugs.webkit.org/show_bug.cgi?id=15793
4992     notImplemented();
4993 #endif
4994 }
4995 
4996 /**
4997  * webkit_web_view_get_hit_test_result:
4998  * @webView: a #WebKitWebView
4999  * @event: a #GdkEventButton
5000  *
5001  * Does a 'hit test' in the coordinates specified by @event to figure
5002  * out context information about that position in the @webView.
5003  *
5004  * Returns: (transfer none): a newly created #WebKitHitTestResult with the context of the
5005  * specified position.
5006  *
5007  * Since: 1.1.15
5008  **/
webkit_web_view_get_hit_test_result(WebKitWebView * webView,GdkEventButton * event)5009 WebKitHitTestResult* webkit_web_view_get_hit_test_result(WebKitWebView* webView, GdkEventButton* event)
5010 {
5011     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
5012     g_return_val_if_fail(event, NULL);
5013 
5014     PlatformMouseEvent mouseEvent = PlatformMouseEvent(event);
5015     Frame* frame = core(webView)->focusController()->focusedOrMainFrame();
5016     HitTestRequest request(HitTestRequest::Active);
5017     IntPoint documentPoint = documentPointForWindowPoint(frame, mouseEvent.pos());
5018     MouseEventWithHitTestResults mev = frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
5019 
5020     return kit(mev.hitTestResult());
5021 }
5022 
5023 /**
5024  * webkit_web_view_get_icon_uri:
5025  * @webView: the #WebKitWebView object
5026  *
5027  * Obtains the URI for the favicon for the given #WebKitWebView, or
5028  * %NULL if there is none.
5029  *
5030  * Return value: the URI for the favicon, or %NULL
5031  *
5032  * Since: 1.1.18
5033  */
webkit_web_view_get_icon_uri(WebKitWebView * webView)5034 G_CONST_RETURN gchar* webkit_web_view_get_icon_uri(WebKitWebView* webView)
5035 {
5036     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
5037     String iconURL = iconDatabase().synchronousIconURLForPageURL(core(webView)->mainFrame()->document()->url().string());
5038     webView->priv->iconURI = iconURL.utf8();
5039     return webView->priv->iconURI.data();
5040 }
5041 
5042 /**
5043  * webkit_web_view_get_icon_pixbuf:
5044  * @webView: the #WebKitWebView object
5045  *
5046  * Obtains a #GdkPixbuf of the favicon for the given #WebKitWebView, or
5047  * a default icon if there is no icon for the given page. Use
5048  * webkit_web_view_get_icon_uri() if you need to distinguish these cases.
5049  * Usually you want to connect to WebKitWebView::icon-loaded and call this
5050  * method in the callback.
5051  *
5052  * The pixbuf will have the largest size provided by the server and should
5053  * be resized before it is displayed.
5054  * See also webkit_icon_database_get_icon_pixbuf().
5055  *
5056  * Returns: (transfer full): a new reference to a #GdkPixbuf, or %NULL
5057  *
5058  * Since: 1.3.13
5059  */
webkit_web_view_get_icon_pixbuf(WebKitWebView * webView)5060 GdkPixbuf* webkit_web_view_get_icon_pixbuf(WebKitWebView* webView)
5061 {
5062     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
5063 
5064     const gchar* pageURI = webkit_web_view_get_uri(webView);
5065     WebKitIconDatabase* database = webkit_get_icon_database();
5066     return webkit_icon_database_get_icon_pixbuf(database, pageURI);
5067 }
5068 
5069 
5070 
5071 /**
5072  * webkit_web_view_get_dom_document:
5073  * @webView: a #WebKitWebView
5074  *
5075  * Returns: (transfer none): the #WebKitDOMDocument currently loaded in the @webView
5076  *
5077  * Since: 1.3.1
5078  **/
5079 WebKitDOMDocument*
webkit_web_view_get_dom_document(WebKitWebView * webView)5080 webkit_web_view_get_dom_document(WebKitWebView* webView)
5081 {
5082     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
5083 
5084     Frame* coreFrame = core(webView)->mainFrame();
5085     if (!coreFrame)
5086         return 0;
5087 
5088     Document* doc = coreFrame->document();
5089     if (!doc)
5090         return 0;
5091 
5092     return kit(doc);
5093 }
5094 
webkit_web_view_get_context_menu(WebKitWebView * webView)5095 GtkMenu* webkit_web_view_get_context_menu(WebKitWebView* webView)
5096 {
5097     g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0);
5098 
5099 #if ENABLE(CONTEXT_MENUS)
5100     ContextMenu* menu = core(webView)->contextMenuController()->contextMenu();
5101     if (!menu)
5102         return 0;
5103     return menu->platformDescription();
5104 #else
5105     return 0;
5106 #endif
5107 }
5108 
webViewEnterFullscreen(WebKitWebView * webView,Node * node)5109 void webViewEnterFullscreen(WebKitWebView* webView, Node* node)
5110 {
5111     if (!node->hasTagName(HTMLNames::videoTag))
5112         return;
5113 
5114 #if ENABLE(VIDEO)
5115     HTMLMediaElement* videoElement = static_cast<HTMLMediaElement*>(node);
5116     WebKitWebViewPrivate* priv = webView->priv;
5117 
5118     // First exit Fullscreen for the old mediaElement.
5119     if (priv->fullscreenVideoController)
5120         priv->fullscreenVideoController->exitFullscreen();
5121 
5122     priv->fullscreenVideoController = new FullscreenVideoController;
5123     priv->fullscreenVideoController->setMediaElement(videoElement);
5124     priv->fullscreenVideoController->enterFullscreen();
5125 #endif
5126 }
5127 
webViewExitFullscreen(WebKitWebView * webView)5128 void webViewExitFullscreen(WebKitWebView* webView)
5129 {
5130 #if ENABLE(VIDEO)
5131     WebKitWebViewPrivate* priv = webView->priv;
5132     if (priv->fullscreenVideoController)
5133         priv->fullscreenVideoController->exitFullscreen();
5134 #endif
5135 }
5136 
5137 namespace WebKit {
5138 
core(WebKitWebView * webView)5139 WebCore::Page* core(WebKitWebView* webView)
5140 {
5141     if (!webView)
5142         return 0;
5143 
5144     WebKitWebViewPrivate* priv = webView->priv;
5145     return priv ? priv->corePage : 0;
5146 }
5147 
kit(WebCore::Page * corePage)5148 WebKitWebView* kit(WebCore::Page* corePage)
5149 {
5150     if (!corePage)
5151         return 0;
5152 
5153     ASSERT(corePage->chrome());
5154     WebKit::ChromeClient* client = static_cast<WebKit::ChromeClient*>(corePage->chrome()->client());
5155     return client ? client->webView() : 0;
5156 }
5157 
5158 }
5159