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