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