2 * Copyright (C) 2007 Holger Hans Peter Freyther
3 * Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
4 * Copyright (C) 2007 Xan Lopez <xan@gnome.org>
5 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of Apple, Inc. ("Apple") nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include "webkitwebview.h"
35 #include "webkit-marshal.h"
36 #include "webkitprivate.h"
38 #include "NotImplemented.h"
39 #include "ChromeClientGtk.h"
40 #include "ContextMenuClientGtk.h"
41 #include "DragClientGtk.h"
42 #include "EditorClientGtk.h"
43 #include "EventHandler.h"
44 #include "HitTestRequest.h"
45 #include "HitTestResult.h"
46 #include "GraphicsContext.h"
47 #include "InspectorClientGtk.h"
48 #include "FrameLoader.h"
49 #include "FrameView.h"
50 #include "PlatformKeyboardEvent.h"
51 #include "PlatformWheelEvent.h"
52 #include "SubstituteData.h"
54 #include <gdk/gdkkeysyms.h>
56 using namespace WebKit;
57 using namespace WebCore;
64 WINDOW_OBJECT_CLEARED,
66 LOAD_PROGRESS_CHANGED,
70 STATUS_BAR_TEXT_CHANGED,
80 static guint webkit_web_view_signals[LAST_SIGNAL] = { 0, };
82 G_DEFINE_TYPE(WebKitWebView, webkit_web_view, GTK_TYPE_CONTAINER)
84 static gboolean webkit_web_view_expose_event(GtkWidget* widget, GdkEventExpose* event)
86 Frame* frame = core(getFrameFromView(WEBKIT_WEB_VIEW(widget)));
88 gdk_region_get_clipbox(event->region, &clip);
89 cairo_t* cr = gdk_cairo_create(event->window);
90 GraphicsContext ctx(cr);
91 ctx.setGdkExposeEvent(event);
92 if (frame->renderer()) {
93 frame->view()->layoutIfNeededRecursive();
94 frame->view()->paint(&ctx, clip);
101 static gboolean webkit_web_view_key_event(GtkWidget* widget, GdkEventKey* event)
103 Frame* frame = core(getFrameFromView(WEBKIT_WEB_VIEW(widget)));
104 PlatformKeyboardEvent keyboardEvent(event);
106 if (frame->eventHandler()->keyEvent(keyboardEvent))
109 if (event->type != GDK_KEY_PRESS)
112 FrameView* view = frame->view();
114 /* FIXME: at the very least we should be using the same code than the
115 Windows port here, but our ScrollView file diverges enough to make
116 that impossible. A short term solution would be to unify ScrollViewWin
117 and ScrollViewGtk. Long-term ScrollView and FrameView should be
118 unified and used everywhere for scrollbars */
120 switch (event->keyval) {
122 view->scrollBy(0, LINE_STEP);
125 view->scrollBy(0, -LINE_STEP);
128 view->scrollBy(LINE_STEP, 0);
131 view->scrollBy(-LINE_STEP, 0);
138 static gboolean webkit_web_view_button_event(GtkWidget* widget, GdkEventButton* event)
140 Frame* frame = core(getFrameFromView(WEBKIT_WEB_VIEW(widget)));
142 if (event->type == GDK_BUTTON_RELEASE)
143 return frame->eventHandler()->handleMouseReleaseEvent(PlatformMouseEvent(event));
145 // FIXME: need to keep track of subframe focus for key events
146 gtk_widget_grab_focus(GTK_WIDGET(widget));
147 return frame->eventHandler()->handleMousePressEvent(PlatformMouseEvent(event));
150 static gboolean webkit_web_view_motion_event(GtkWidget* widget, GdkEventMotion* event)
152 Frame* frame = core(getFrameFromView(WEBKIT_WEB_VIEW(widget)));
153 return frame->eventHandler()->mouseMoved(PlatformMouseEvent(event));
156 static gboolean webkit_web_view_scroll_event(GtkWidget* widget, GdkEventScroll* event)
158 Frame* frame = core(getFrameFromView(WEBKIT_WEB_VIEW(widget)));
159 PlatformWheelEvent wheelEvent(event);
160 return frame->eventHandler()->handleWheelEvent(wheelEvent);
163 static void webkit_web_view_size_allocate(GtkWidget* widget, GtkAllocation* allocation)
165 GTK_WIDGET_CLASS(webkit_web_view_parent_class)->size_allocate(widget,allocation);
167 Frame* frame = core(getFrameFromView(WEBKIT_WEB_VIEW(widget)));
168 frame->view()->resize(allocation->width, allocation->height);
169 frame->forceLayout();
170 frame->view()->adjustViewSize();
171 frame->sendResizeEvent();
174 static void webkit_web_view_realize(GtkWidget* widget)
176 GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
178 GdkWindowAttr attributes;
179 attributes.window_type = GDK_WINDOW_CHILD;
180 attributes.x = widget->allocation.x;
181 attributes.y = widget->allocation.y;
182 attributes.width = widget->allocation.width;
183 attributes.height = widget->allocation.height;
184 attributes.wclass = GDK_INPUT_OUTPUT;
185 attributes.visual = gtk_widget_get_visual (widget);
186 attributes.colormap = gtk_widget_get_colormap (widget);
187 attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK
189 | GDK_BUTTON_PRESS_MASK
190 | GDK_BUTTON_RELEASE_MASK
191 | GDK_POINTER_MOTION_MASK
193 | GDK_KEY_RELEASE_MASK
194 | GDK_BUTTON_MOTION_MASK
195 | GDK_BUTTON1_MOTION_MASK
196 | GDK_BUTTON2_MOTION_MASK
197 | GDK_BUTTON3_MOTION_MASK;
199 gint attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
200 widget->window = gdk_window_new(gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
201 gdk_window_set_user_data(widget->window, widget);
204 static void webkit_web_view_set_scroll_adjustments(WebKitWebView* webView, GtkAdjustment* hadj, GtkAdjustment* vadj)
206 FrameView* view = core(getFrameFromView(webView))->view();
207 view->setGtkAdjustments(hadj, vadj);
210 static void webkit_web_view_container_add(GtkContainer* container, GtkWidget* widget)
212 WebKitWebView* webView = WEBKIT_WEB_VIEW(container);
213 WebKitWebViewPrivate* private_data = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
215 private_data->children.add(widget);
216 if (GTK_WIDGET_REALIZED(container))
217 gtk_widget_set_parent_window(widget, GTK_WIDGET(webView)->window);
218 gtk_widget_set_parent(widget, GTK_WIDGET(container));
221 static void webkit_web_view_container_remove(GtkContainer* container, GtkWidget* widget)
223 WebKitWebViewPrivate* private_data = WEBKIT_WEB_VIEW_GET_PRIVATE(WEBKIT_WEB_VIEW(container));
225 if (private_data->children.contains(widget)) {
226 gtk_widget_unparent(widget);
227 private_data->children.remove(widget);
231 static void webkit_web_view_container_forall(GtkContainer* container, gboolean, GtkCallback callback, gpointer callbackData)
233 WebKitWebViewPrivate* privateData = WEBKIT_WEB_VIEW_GET_PRIVATE(WEBKIT_WEB_VIEW(container));
235 HashSet<GtkWidget*> children = privateData->children;
236 HashSet<GtkWidget*>::const_iterator end = children.end();
237 for (HashSet<GtkWidget*>::const_iterator current = children.begin(); current != end; ++current)
238 (*callback)(*current, callbackData);
241 static WebKitWebView* webkit_web_view_real_create_web_view(WebKitWebView*)
247 static WebKitNavigationResponse webkit_web_view_real_navigation_requested(WebKitWebView*, WebKitWebFrame* frame, WebKitNetworkRequest*)
250 return WEBKIT_NAVIGATION_RESPONSE_ACCEPT;
253 static void webkit_web_view_real_window_object_cleared(WebKitWebView*, WebKitWebFrame*, JSGlobalContextRef context, JSObjectRef window_object)
258 static gchar* webkit_web_view_real_choose_file(WebKitWebView*, WebKitWebFrame*, const gchar* old_name)
261 return g_strdup(old_name);
265 WEBKIT_SCRIPT_DIALOG_ALERT,
266 WEBKIT_SCRIPT_DIALOG_CONFIRM,
267 WEBKIT_SCRIPT_DIALOG_PROMPT
268 } WebKitScriptDialogType;
270 static gboolean webkit_web_view_script_dialog(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, WebKitScriptDialogType type, const gchar* defaultValue, gchar** value)
272 GtkMessageType messageType;
273 GtkButtonsType buttons;
274 gint defaultResponse;
277 GtkWidget* entry = 0;
278 gboolean didConfirm = FALSE;
281 case WEBKIT_SCRIPT_DIALOG_ALERT:
282 messageType = GTK_MESSAGE_WARNING;
283 buttons = GTK_BUTTONS_CLOSE;
284 defaultResponse = GTK_RESPONSE_CLOSE;
286 case WEBKIT_SCRIPT_DIALOG_CONFIRM:
287 messageType = GTK_MESSAGE_QUESTION;
288 buttons = GTK_BUTTONS_YES_NO;
289 defaultResponse = GTK_RESPONSE_YES;
291 case WEBKIT_SCRIPT_DIALOG_PROMPT:
292 messageType = GTK_MESSAGE_QUESTION;
293 buttons = GTK_BUTTONS_OK_CANCEL;
294 defaultResponse = GTK_RESPONSE_OK;
297 g_warning("Unknown value for WebKitScriptDialogType.");
301 window = gtk_widget_get_toplevel(GTK_WIDGET(webView));
302 dialog = gtk_message_dialog_new(GTK_WIDGET_TOPLEVEL(window) ? GTK_WINDOW(window) : 0, GTK_DIALOG_DESTROY_WITH_PARENT, messageType, buttons, "%s", message);
303 gchar* title = g_strconcat("JavaScript - ", webkit_web_frame_get_location(frame), NULL);
304 gtk_window_set_title(GTK_WINDOW(dialog), title);
307 if (type == WEBKIT_SCRIPT_DIALOG_PROMPT) {
308 entry = gtk_entry_new();
309 gtk_entry_set_text(GTK_ENTRY(entry), defaultValue);
310 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), entry);
311 gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
312 gtk_widget_show(entry);
315 gtk_dialog_set_default_response(GTK_DIALOG(dialog), defaultResponse);
316 gint response = gtk_dialog_run(GTK_DIALOG(dialog));
319 case GTK_RESPONSE_YES:
322 case GTK_RESPONSE_OK:
325 *value = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
329 case GTK_RESPONSE_NO:
330 case GTK_RESPONSE_CANCEL:
335 gtk_widget_destroy(GTK_WIDGET(dialog));
339 static gboolean webkit_web_view_real_script_alert(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message)
341 webkit_web_view_script_dialog(webView, frame, message, WEBKIT_SCRIPT_DIALOG_ALERT, 0, 0);
345 static gboolean webkit_web_view_real_script_confirm(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, gboolean* didConfirm)
347 *didConfirm = webkit_web_view_script_dialog(webView, frame, message, WEBKIT_SCRIPT_DIALOG_CONFIRM, 0, 0);
351 static gboolean webkit_web_view_real_script_prompt(WebKitWebView* webView, WebKitWebFrame* frame, const gchar* message, const gchar* defaultValue, gchar** value)
353 if (!webkit_web_view_script_dialog(webView, frame, message, WEBKIT_SCRIPT_DIALOG_PROMPT, defaultValue, value))
358 static gboolean webkit_web_view_real_console_message(WebKitWebView* webView, const gchar* message, unsigned int line, const gchar* sourceId)
360 g_print("console message: %s @%d: %s\n", sourceId, line, message);
364 static void webkit_web_view_finalize(GObject* object)
366 webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(object));
368 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(WEBKIT_WEB_VIEW(object));
369 delete webViewData->corePage;
370 delete webViewData->settings;
371 g_object_unref(webViewData->mainFrame);
372 delete webViewData->userAgent;
374 G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object);
377 static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass)
379 g_type_class_add_private(webViewClass, sizeof(WebKitWebViewPrivate));
385 webkit_web_view_signals[NAVIGATION_REQUESTED] = g_signal_new("navigation_requested",
386 G_TYPE_FROM_CLASS(webViewClass),
387 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
388 G_STRUCT_OFFSET (WebKitWebViewClass, navigation_requested),
391 webkit_marshal_INT__OBJECT_OBJECT,
397 * WebKitWebView::window-object-cleared:
398 * @web_view: the object on which the signal is emitted
399 * @frame: the #WebKitWebFrame to which @window_object belongs
400 * @context: the #JSGlobalContextRef holding the global object and other
401 * execution state; equivalent to the return value of
402 * webkit_web_frame_get_global_context(@frame)
404 * @window_object: the #JSObjectRef representing the frame's JavaScript
407 * Emitted when the JavaScript window object in a #WebKitWebFrame has been
408 * cleared in preparation for a new load. This is the preferred place to
409 * set custom properties on the window object using the JavaScriptCore API.
411 webkit_web_view_signals[WINDOW_OBJECT_CLEARED] = g_signal_new("window_object_cleared",
412 G_TYPE_FROM_CLASS(webViewClass),
413 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
414 G_STRUCT_OFFSET (WebKitWebViewClass, window_object_cleared),
417 webkit_marshal_VOID__OBJECT_POINTER_POINTER,
419 WEBKIT_TYPE_WEB_FRAME,
424 * WebKitWebView::load-started:
425 * @web_view: the object on which the signal is emitted
426 * @frame: the frame going to do the load
428 * When a #WebKitWebFrame begins to load this signal is emitted.
430 webkit_web_view_signals[LOAD_STARTED] = g_signal_new("load_started",
431 G_TYPE_FROM_CLASS(webViewClass),
432 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
436 g_cclosure_marshal_VOID__OBJECT,
438 WEBKIT_TYPE_WEB_FRAME);
441 * WebKitWebView::load-progress-changed:
442 * @web_view: the #WebKitWebView
443 * @progress: the global progress
445 webkit_web_view_signals[LOAD_PROGRESS_CHANGED] = g_signal_new("load_progress_changed",
446 G_TYPE_FROM_CLASS(webViewClass),
447 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
451 g_cclosure_marshal_VOID__INT,
455 webkit_web_view_signals[LOAD_FINISHED] = g_signal_new("load_finished",
456 G_TYPE_FROM_CLASS(webViewClass),
457 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
461 g_cclosure_marshal_VOID__OBJECT,
463 WEBKIT_TYPE_WEB_FRAME);
465 webkit_web_view_signals[TITLE_CHANGED] = g_signal_new("title_changed",
466 G_TYPE_FROM_CLASS(webViewClass),
467 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
471 webkit_marshal_VOID__STRING_STRING,
473 G_TYPE_STRING, G_TYPE_STRING);
475 webkit_web_view_signals[HOVERING_OVER_LINK] = g_signal_new("hovering_over_link",
476 G_TYPE_FROM_CLASS(webViewClass),
477 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
481 webkit_marshal_VOID__STRING_STRING,
486 webkit_web_view_signals[STATUS_BAR_TEXT_CHANGED] = g_signal_new("status_bar_text_changed",
487 G_TYPE_FROM_CLASS(webViewClass),
488 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
492 g_cclosure_marshal_VOID__STRING,
496 webkit_web_view_signals[ICOND_LOADED] = g_signal_new("icon_loaded",
497 G_TYPE_FROM_CLASS(webViewClass),
498 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
502 g_cclosure_marshal_VOID__VOID,
505 webkit_web_view_signals[SELECTION_CHANGED] = g_signal_new("selection_changed",
506 G_TYPE_FROM_CLASS(webViewClass),
507 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
511 g_cclosure_marshal_VOID__VOID,
515 * WebKitWebView::console-message:
516 * @web_view: the object on which the signal is emitted
517 * @message: the message text
518 * @line: the line where the error occured
519 * @source_id: the source id
520 * @return: TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
522 * A JavaScript console message was created.
524 webkit_web_view_signals[CONSOLE_MESSAGE] = g_signal_new("console_message",
525 G_TYPE_FROM_CLASS(webViewClass),
526 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
527 G_STRUCT_OFFSET(WebKitWebViewClass, console_message),
528 g_signal_accumulator_true_handled,
530 webkit_marshal_BOOLEAN__STRING_INT_STRING,
532 G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
535 * WebKitWebView::script-alert:
536 * @web_view: the object on which the signal is emitted
537 * @frame: the relevant frame
538 * @message: the message text
539 * @return: TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
541 * A JavaScript alert dialog was created.
543 webkit_web_view_signals[SCRIPT_ALERT] = g_signal_new("script-alert",
544 G_TYPE_FROM_CLASS(webViewClass),
545 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
546 G_STRUCT_OFFSET(WebKitWebViewClass, script_alert),
547 g_signal_accumulator_true_handled,
549 webkit_marshal_BOOLEAN__OBJECT_STRING,
551 G_TYPE_OBJECT, G_TYPE_STRING);
554 * WebKitWebView::script-confirm:
555 * @web_view: the object on which the signal is emitted
556 * @frame: the relevant frame
557 * @message: the message text
558 * @confirmed: whether the dialog has been confirmed
559 * @return: TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
561 * A JavaScript confirm dialog was created, providing Yes and No buttons.
563 webkit_web_view_signals[SCRIPT_CONFIRM] = g_signal_new("script_confirm",
564 G_TYPE_FROM_CLASS(webViewClass),
565 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
566 G_STRUCT_OFFSET(WebKitWebViewClass, script_confirm),
567 g_signal_accumulator_true_handled,
569 webkit_marshal_BOOLEAN__OBJECT_STRING_BOOLEAN,
571 G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_BOOLEAN);
574 * WebKitWebView::script-prompt:
575 * @web_view: the object on which the signal is emitted
576 * @frame: the relevant frame
577 * @message: the message text
578 * @default: the default value
579 * @text: To be filled with the return value or NULL if the dialog was cancelled.
580 * @return: TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
582 * A JavaScript prompt dialog was created, providing an entry to input text.
584 webkit_web_view_signals[SCRIPT_PROMPT] = g_signal_new("script_prompt",
585 G_TYPE_FROM_CLASS(webViewClass),
586 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
587 G_STRUCT_OFFSET(WebKitWebViewClass, script_prompt),
588 g_signal_accumulator_true_handled,
590 webkit_marshal_BOOLEAN__OBJECT_STRING_STRING_STRING,
592 G_TYPE_OBJECT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
596 * implementations of virtual methods
598 webViewClass->create_web_view = webkit_web_view_real_create_web_view;
599 webViewClass->navigation_requested = webkit_web_view_real_navigation_requested;
600 webViewClass->window_object_cleared = webkit_web_view_real_window_object_cleared;
601 webViewClass->choose_file = webkit_web_view_real_choose_file;
602 webViewClass->script_alert = webkit_web_view_real_script_alert;
603 webViewClass->script_confirm = webkit_web_view_real_script_confirm;
604 webViewClass->script_prompt = webkit_web_view_real_script_prompt;
605 webViewClass->console_message = webkit_web_view_real_console_message;
607 G_OBJECT_CLASS(webViewClass)->finalize = webkit_web_view_finalize;
609 GtkWidgetClass* widgetClass = GTK_WIDGET_CLASS(webViewClass);
610 widgetClass->realize = webkit_web_view_realize;
611 widgetClass->expose_event = webkit_web_view_expose_event;
612 widgetClass->key_press_event = webkit_web_view_key_event;
613 widgetClass->key_release_event = webkit_web_view_key_event;
614 widgetClass->button_press_event = webkit_web_view_button_event;
615 widgetClass->button_release_event = webkit_web_view_button_event;
616 widgetClass->motion_notify_event = webkit_web_view_motion_event;
617 widgetClass->scroll_event = webkit_web_view_scroll_event;
618 widgetClass->size_allocate = webkit_web_view_size_allocate;
620 GtkContainerClass* containerClass = GTK_CONTAINER_CLASS(webViewClass);
621 containerClass->add = webkit_web_view_container_add;
622 containerClass->remove = webkit_web_view_container_remove;
623 containerClass->forall = webkit_web_view_container_forall;
626 * make us scrollable (e.g. addable to a GtkScrolledWindow)
628 webViewClass->set_scroll_adjustments = webkit_web_view_set_scroll_adjustments;
629 GTK_WIDGET_CLASS(webViewClass)->set_scroll_adjustments_signal = g_signal_new("set_scroll_adjustments",
630 G_TYPE_FROM_CLASS(webViewClass),
631 (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
632 G_STRUCT_OFFSET(WebKitWebViewClass, set_scroll_adjustments),
634 webkit_marshal_VOID__OBJECT_OBJECT,
636 GTK_TYPE_ADJUSTMENT, GTK_TYPE_ADJUSTMENT);
639 static void webkit_web_view_init(WebKitWebView* webView)
641 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(WEBKIT_WEB_VIEW(webView));
642 webViewData->corePage = new Page(new WebKit::ChromeClient(webView), new WebKit::ContextMenuClient, new WebKit::EditorClient(webView), new WebKit::DragClient, new WebKit::InspectorClient);
644 Settings* settings = webViewData->corePage->settings();
645 settings->setLoadsImagesAutomatically(true);
646 settings->setMinimumFontSize(5);
647 settings->setMinimumLogicalFontSize(5);
648 settings->setShouldPrintBackgrounds(true);
649 settings->setJavaScriptEnabled(true);
650 settings->setDefaultFixedFontSize(14);
651 settings->setDefaultFontSize(14);
652 settings->setSerifFontFamily("Times New Roman");
653 settings->setSansSerifFontFamily("Arial");
654 settings->setFixedFontFamily("Courier New");
655 settings->setStandardFontFamily("Arial");
657 GTK_WIDGET_SET_FLAGS(webView, GTK_CAN_FOCUS);
658 webViewData->mainFrame = WEBKIT_WEB_FRAME(webkit_web_frame_new(webView));
659 webViewData->editable = false;
662 GtkWidget* webkit_web_view_new(void)
664 WebKitWebView* webView = WEBKIT_WEB_VIEW(g_object_new(WEBKIT_TYPE_WEB_VIEW, NULL));
666 return GTK_WIDGET(webView);
669 void webkit_web_view_set_settings(WebKitWebView* webView, WebKitSettings* settings)
671 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
672 g_return_if_fail(settings);
677 WebKitSettings* webkit_web_view_get_settings(WebKitWebView* webView)
679 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
685 void webkit_web_view_go_backward(WebKitWebView* webView)
687 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
689 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
690 WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(webViewData->mainFrame);
691 frameData->frame->loader()->goBackOrForward(-1);
694 void webkit_web_view_go_forward(WebKitWebView* webView)
696 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
698 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
699 WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(webViewData->mainFrame);
700 frameData->frame->loader()->goBackOrForward(1);
703 gboolean webkit_web_view_can_go_backward(WebKitWebView* webView)
705 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
707 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
708 WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(webViewData->mainFrame);
709 return frameData->frame->loader()->canGoBackOrForward(-1);
712 gboolean webkit_web_view_can_go_forward(WebKitWebView* webView)
714 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
716 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
717 WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(webViewData->mainFrame);
718 return frameData->frame->loader()->canGoBackOrForward(1);
721 void webkit_web_view_open(WebKitWebView* webView, const gchar* uri)
723 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
725 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
726 WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(webViewData->mainFrame);
728 DeprecatedString string = DeprecatedString::fromUtf8(uri);
729 frameData->frame->loader()->load(ResourceRequest(KURL(string)));
732 void webkit_web_view_reload(WebKitWebView* webView)
734 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
736 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
737 WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(webViewData->mainFrame);
738 frameData->frame->loader()->reload();
741 void webkit_web_view_load_string(WebKitWebView* webView, const gchar* content, const gchar* contentMimeType, const gchar* contentEncoding, const gchar* baseUri)
743 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
745 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
746 WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(webViewData->mainFrame);
748 KURL url(DeprecatedString::fromUtf8(baseUri));
749 RefPtr<SharedBuffer> sharedBuffer = new SharedBuffer(strdup(content), strlen(content));
750 SubstituteData substituteData(sharedBuffer.release(), String(contentMimeType), String(contentEncoding), KURL("about:blank"), url);
752 frameData->frame->loader()->load(ResourceRequest(url), substituteData);
755 void webkit_web_view_load_html_string(WebKitWebView* webView, const gchar* content, const gchar* baseUrl)
757 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
759 webkit_web_view_load_string(webView, content, "text/html", "UTF-8", baseUrl);
762 void webkit_web_view_stop_loading(WebKitWebView* webView)
764 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
766 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
767 WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(webViewData->mainFrame);
769 if (FrameLoader* loader = frameData->frame->loader())
770 loader->stopAllLoaders();
773 WebKitWebFrame* webkit_web_view_get_main_frame(WebKitWebView* webView)
775 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL);
777 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
778 return webViewData->mainFrame;
781 void webkit_web_view_execute_script(WebKitWebView* webView, const gchar* script)
783 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
784 g_return_if_fail(script);
786 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
787 WebKitWebFramePrivate* frameData = WEBKIT_WEB_FRAME_GET_PRIVATE(webViewData->mainFrame);
789 if (FrameLoader* loader = frameData->frame->loader())
790 loader->executeScript(String::fromUTF8(script), true);
794 * webkit_web_view_get_editable:
795 * @web_view: a #WebKitWebView
797 * Returns whether the user is allowed to edit the document.
799 * Returns %TRUE if @web_view allows the user to edit the HTML document, %FALSE if
800 * it doesn't. You can change @web_view's document programmatically regardless of
803 * Return value: a #gboolean indicating the editable state
805 gboolean webkit_web_view_get_editable(WebKitWebView* webView)
807 g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), FALSE);
809 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
812 return webViewData->editable;
816 * webkit_web_view_set_editable:
817 * @web_view: a #WebKitWebView
818 * @flag: a #gboolean indicating the editable state
820 * Sets whether @web_view allows the user to edit its HTML document.
822 * If @flag is %TRUE, @web_view allows the user to edit the document. If @flag is
823 * %FALSE, an element in @web_view's document can only be edited if the
824 * CONTENTEDITABLE attribute has been set on the element or one of its parent
825 * elements. You can change @web_view's document programmatically regardless of
826 * this setting. By default a #WebKitWebView is not editable.
828 * Normally, an HTML document is not editable unless the elements within the
829 * document are editable. This function provides a low-level way to make the
830 * contents of a #WebKitWebView editable without altering the document or DOM
833 void webkit_web_view_set_editable(WebKitWebView* webView, gboolean flag)
835 g_return_if_fail(WEBKIT_IS_WEB_VIEW(webView));
836 flag = flag != FALSE;
838 WebKitWebViewPrivate* webViewData = WEBKIT_WEB_VIEW_GET_PRIVATE(webView);
841 Frame* mainFrame = core(webViewData->mainFrame);
842 g_return_if_fail(mainFrame);
844 // TODO: What happens when the frame is replaced?
845 if (flag == webViewData->editable)
848 webViewData->editable = flag;
851 mainFrame->applyEditingStyleToBodyElement();
852 // TODO: If the WebKitWebView is made editable and the selection is empty, set it to something.
853 //if (!webkit_web_view_get_selected_dom_range(webView))
854 // mainFrame->setSelectionFromNone();
856 mainFrame->removeEditingStyleFromBodyElement();