diff options
Diffstat (limited to 'WebKit/gtk')
-rw-r--r-- | WebKit/gtk/ChangeLog | 381 | ||||
-rw-r--r-- | WebKit/gtk/JSCore.gir.in | 12 | ||||
-rw-r--r-- | WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp | 2 | ||||
-rw-r--r-- | WebKit/gtk/WebCoreSupport/DragClientGtk.cpp | 48 | ||||
-rw-r--r-- | WebKit/gtk/WebCoreSupport/DragClientGtk.h | 7 | ||||
-rw-r--r-- | WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp | 71 | ||||
-rw-r--r-- | WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp | 142 | ||||
-rw-r--r-- | WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h | 1 | ||||
-rw-r--r-- | WebKit/gtk/WebCoreSupport/FullscreenVideoController.cpp | 1 | ||||
-rw-r--r-- | WebKit/gtk/tests/testatk.c | 146 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitdownload.cpp | 7 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitprivate.cpp | 10 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitprivate.h | 44 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebsettings.cpp | 56 | ||||
-rw-r--r-- | WebKit/gtk/webkit/webkitwebview.cpp | 357 |
15 files changed, 950 insertions, 335 deletions
diff --git a/WebKit/gtk/ChangeLog b/WebKit/gtk/ChangeLog index 25fe4fd..16f4063 100644 --- a/WebKit/gtk/ChangeLog +++ b/WebKit/gtk/ChangeLog @@ -1,3 +1,384 @@ +2010-09-17 Darin Adler <darin@apple.com> + + Reviewed by Sam Weinig. + + REGRESSION (r60104): Zoom level is unexpectedly reset on page reload + https://bugs.webkit.org/show_bug.cgi?id=42863 + + * webkit/webkitwebview.cpp: + (webkit_web_view_get_zoom_level): + (webkit_web_view_apply_zoom_level): + (webkit_web_view_set_full_content_zoom): + Call functions on Frame instead of FrameView. + +2010-09-16 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + [GTK] Implement dissolveDragImageToFraction + https://bugs.webkit.org/show_bug.cgi?id=45826 + + To support full alpha in the drag icon, changed the drag icon to be a + GtkWindow with an RGBA colormap. Added logic to support painting the drag + image to this window during the expose event. + + * WebCoreSupport/DragClientGtk.cpp: + (WebKit::dragIconWindowExposeEventCallback): Added. + (WebKit::DragClient::DragClient): Initialize the new drag icon window. + (WebKit::DragClient::~DragClient): Disconnect the expose event signal. + (WebKit::DragClient::startDrag): Resize the drag icon window the appropriate size and + if necessary, set its colormap. + (WebKit::DragClient::dragIconWindowExposeEvent): Added. + * WebCoreSupport/DragClientGtk.h: Added new member and method declarations. + +2010-09-14 Philippe Normand <pnormand@igalia.com> + + Reviewed by Eric Carlson and Martin Robinson. + + [GTK] eventSender.contextClick() should return the contents of the context menu + https://bugs.webkit.org/show_bug.cgi?id=39102 + + New private WebView API to retrieve the context-menu widget. This + is used by DRT only. + + * webkit/webkitprivate.h: + * webkit/webkitwebview.cpp: + (webkit_web_view_get_context_menu): + +2010-09-16 Alejandro G. Castro <alex@igalia.com> + + Reviewed by Xan Lopez. + + GTK+ 3.x. updates, gtk_widget_size_request is deprecated and + "activate-slider" style property for scrollbars is gone. + + * webkit/webkitwebview.cpp: + (PopupMenuPositionFunc): + +2010-09-15 Martin Robinson <mrobinson@igalia.com> + + Reviewed by David Levin. + + [GTK] [REGRESSION] r67591 broke the testwebbackforwardlist API test and introduced a memory leak + https://bugs.webkit.org/show_bug.cgi?id=45865 + + When initializing the backForwardList private member of the WebView, do + so with adoptPlatformRef to prevent a memory leak. + + * webkit/webkitwebview.cpp: + (webkit_web_view_init): Initialize member with adoptPlatformRef. + +2010-09-15 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Eric Seidel. + + [Gtk] Use GOwnPtr for code that needs it + https://bugs.webkit.org/show_bug.cgi?id=21594 + + Convert as reference counted private members of WebKitWebView to + smart pointers as possible. This removes a lot of unecessary manual + memory management. Also convert some pointer members away from pointer + types, now that we are sure their destructors are called. + + * WebCoreSupport/ContextMenuClientGtk.cpp: + (WebKit::inputMethodsMenuItem): Updated to reflect PlatformRefPtr changes. + * WebCoreSupport/DragClientGtk.cpp: + (WebKit::DragClient::startDrag): Ditto. + * WebCoreSupport/EditorClientGtk.cpp: + (WebKit::EditorClient::setInputMethodState): Ditto. + (WebKit::EditorClient::respondToChangedSelection): Ditto. + (WebKit::EditorClient::handleInputMethodKeydown): Ditto. + (WebKit::EditorClient::handleInputMethodMousePress): Ditto. + (WebKit::EditorClient::EditorClient): Ditto. + (WebKit::EditorClient::~EditorClient): Ditto. + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::postCommitFrameViewSetup): Ditto. + * webkit/webkitprivate.h: Ditto. + * webkit/webkitwebview.cpp: Ditto. + (destroy_menu_cb): Ditto. + (webkit_web_view_forward_context_menu_event): Ditto. + (webkit_web_view_key_release_event): Ditto. + (webkit_web_view_button_press_event): Ditto. + (webkit_web_view_button_release_event): Ditto. + (webkit_web_view_focus_in_event): Ditto. + (webkit_web_view_focus_out_event): Ditto. + (webkit_web_view_realize): Ditto. + (webkit_web_view_set_scroll_adjustments): Ditto. + (webkit_web_view_dispose): Changed all g_object_unref calls to + PlatformRefPtr.clear(). Although this will also be done by the manual + call to the WebKitWebViewPrivate destructor, the order that these + fields are zero'd in is still very sensitive. + (webkit_web_view_finalize): Updated to reflect PlatformRefPtr changes. + (webViewGetDPI): Ditto. + (webkit_web_view_screen_changed): Ditto. + (webkit_web_view_drag_end): Ditto. + (webkit_web_view_drag_data_get): Ditto. + (doDragLeaveLater): Ditto. + (webkit_web_view_drag_leave): Ditto. + (webkit_web_view_drag_motion): Ditto. + (webkit_web_view_drag_data_received): Ditto. + (webkit_web_view_drag_drop): Ditto. + (webkit_web_view_get_im_context): Ditto. + (webkit_web_view_update_settings): Ditto. + (webkit_web_view_init): Ditto. + (webkit_web_view_set_settings): Ditto. + (webkit_web_view_get_settings): Ditto. + (webkit_web_view_get_inspector): Ditto. + (webkit_web_view_set_window_features): Ditto. + (webkit_web_view_get_window_features): Ditto. + (webkit_web_view_get_back_forward_list): Ditto. + (webkit_web_view_zoom_in): Ditto. + (webkit_web_view_zoom_out): Ditto. + (webkit_web_view_add_resource): Ditto. + (webkit_web_view_get_resource): Ditto. + (webkit_web_view_get_main_resource): Ditto. + (webkit_web_view_clear_resources): Ditto. + (webkit_web_view_get_subresources): Ditto. + +2010-09-14 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + [GTK] fast/events/keydown-numpad-keys.html produces many GLib warnings + https://bugs.webkit.org/show_bug.cgi?id=45775 + + Handle the toggle-overwrite signal on the GtkTextView used for generating editing + commands. Ignore this signals, as the default handler assumes that the GtkTextView + has a layout and this one does not. + + * WebCoreSupport/EditorClientGtk.cpp: + (WebKit::toggleOverwriteCallback): Added. Cancels the default handler. + (WebKit::EditorClient::EditorClient): Attach a handler for toggle-overwrite. + +2010-09-14 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Yury Semikhatsky. + + Web Inspector: Provide network-based load timing. + Before this change, inspector used timers taken from + within WebCore notifications (that are by definition + synchronous and serialized). As a result, timing was + affected by the routines running on the main thread + (JavaScript and such). + https://bugs.webkit.org/show_bug.cgi?id=45664 + + * webkit/webkitdownload.cpp: + (DownloadClient::didFinishLoading): + +2010-09-15 Sheriff Bot <webkit.review.bot@gmail.com> + + Unreviewed, rolling out r67551. + http://trac.webkit.org/changeset/67551 + https://bugs.webkit.org/show_bug.cgi?id=45816 + + "Plugin tests fail" (Requested by yurys on #webkit). + + * webkit/webkitdownload.cpp: + (DownloadClient::didFinishLoading): + +2010-09-14 Pavel Feldman <pfeldman@chromium.org> + + Reviewed by Yury Semikhatsky. + + Web Inspector: Provide network-based load timing. + Before this change, inspector used timers taken from + within WebCore notifications (that are by definition + synchronous and serialized). As a result, timing was + affected by the routines running on the main thread + (JavaScript and such). + https://bugs.webkit.org/show_bug.cgi?id=45664 + + * webkit/webkitdownload.cpp: + (DownloadClient::didFinishLoading): + +2010-09-13 Enrica Casucci <enrica@apple.com> + + Reviewed by Sam Weinig. + + Paste should be implemented in WebCore like Copy and Cut for Mac also. + https://bugs.webkit.org/show_bug.cgi?id=45494 + <rdar://problem/7660537> + + On the Mac platform, the implementation of the paste operation is all done + at the WebKit level. In order to support it on WebKit2 it is necessary to + refactor the code and move this functionality at the level of WebCore like + we already have on Windows. + The original code relies on some in AppKit functions that call back into + WebKit causing problems in WebKit2. All this functionality has been moved + at the level of the editor client where it can be dealt with appropriately. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::canShowMIMETypeAsHTML): Added stub. + * WebCoreSupport/FrameLoaderClientGtk.h: + +2010-09-13 Mario Sanchez Prada <msanchez@igalia.com> + + Reviewed by Martin Robinson. + + [GTK] Provide unit tests for AtkText's text selection functions + https://bugs.webkit.org/show_bug.cgi?id=43919 + + New tests to check getting, setting and removing text selections + + * tests/testatk.c: + (testWekitAtkTextSelections): New unit tests to check all the text + selection related functions altogether through a single test + function. + (main): + + Make sure that code dependant on getting information from the + clipboard gets executed only when there's a GDK window associated + to the webview widget, as that's not the case when executing the + unit tests (the wedbview is not inside of any toplevel window) and + will make the tests crash if not taken into account. + + * WebCoreSupport/EditorClientGtk.cpp: + (WebKit::EditorClient::respondToChangedSelection): + +2010-09-11 Xan Lopez <xlopez@igalia.com> + + Reviewed by Martin Robinson. + + [GTK] Make introspection work with g-o-i 0.9.5 + https://bugs.webkit.org/show_bug.cgi?id=45590 + + Use new type syntax and bump version number of the gir file. + + * JSCore.gir.in: + +2010-09-10 Jesus Sanchez-Palencia <jesus.palencia@openbossa.org> + + Reviewed by Darin Adler. + + Add NetworkingContext to avoid layer violations + https://bugs.webkit.org/show_bug.cgi?id=42292 + + * webkit/webkitdownload.cpp: + (webkit_download_start): + * webkit/webkitprivate.cpp: + (currentToplevelCallback): + +2010-09-10 Sam Weinig <sam@webkit.org> + + Fix GTK build. + + * webkit/webkitwebview.cpp: + (webkit_web_view_set_full_content_zoom): + +2010-09-10 Sam Weinig <sam@webkit.org> + + Reviewed by Darin Adler. + + Remove unnecessary constraint in WebCore of choosing either text zoom or full page zoom. + Precursor to <rdar://problem/7660657> + https://bugs.webkit.org/show_bug.cgi?id=45522 + + * webkit/webkitwebview.cpp: + (webkit_web_view_get_zoom_level): + (webkit_web_view_apply_zoom_level): + (webkit_web_view_set_full_content_zoom): + +2010-09-10 Mario Sanchez Prada <msanchez@igalia.com> + + Reviewed by Gustavo Noronha Silva. + + [GTK] Fix warnings because of bad assignments in testatk.c + https://bugs.webkit.org/show_bug.cgi?id=45538 + + Use AtkObject and AtkText instances properly in the code. + + * tests/testatk.c: + (testWebkitAtkListsOfItems): + +2010-09-10 Adam Barth <abarth@webkit.org> + + Reviewed by Darin Fisher. + + Move code from WebKit-layer to DocumentLoader + https://bugs.webkit.org/show_bug.cgi?id=45569 + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::committedLoad): + +2010-09-10 Adam Barth <abarth@webkit.org> + + Reviewed by Eric Seidel. + + Main resource bytes shouldn't bounce through FrameLoader + https://bugs.webkit.org/show_bug.cgi?id=45496 + + Now return the bytes to the DocumentLoader. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::FrameLoaderClient::committedLoad): + +2010-09-10 Martin Robinson <mrobinson@igalia.com> + + Reviewed by Xan Lopez. + + [GTK] Placement new / manual destructor invocation should be used on private GObject memory + https://bugs.webkit.org/show_bug.cgi?id=45550 + + GLib allocates and deallocates GObject private data structs itself. When + those structs contain C++ members, their constructors and destructors are not + called. This is not only dangerous, it makes RefPtr-type smart pointers much + less useful. We can fix this problem by calling placement new on the private + data struct during instance initialization and calling the destructor during + finalization. + + This patch takes that approach and switches plain char* members of + WebKitWebView (with manual memory allocation) to use CString. + + * webkit/webkitprivate.h: Switch char* members to CString. + * webkit/webkitwebview.cpp: + (webkit_web_view_finalize): Manually call the destructor on the private + data. Remove manual deallocation of members which are now CString. + (webkit_web_view_query_tooltip): Update to reflect CString change. + (webkit_web_view_init): Use placement new to initialize C++ members of + the private data section. + (webkit_web_view_get_encoding): Update to reflect CString change. + (webkit_web_view_get_custom_encoding): Ditto. + (webkit_web_view_add_resource): Ditto. + (webkit_web_view_get_resource): Ditto. + (webkit_web_view_clear_resources): Ditto. + (webkit_web_view_set_tooltip_text): Ditto. + (webkit_web_view_get_icon_uri): Ditto. + +2010-09-10 Gustavo Noronha Silva <gns@gnome.org> + + Reviewed by Martin Robinson. + + [GTK] Google sites do not like WebKitGTK+ + https://bugs.webkit.org/show_bug.cgi?id=39617 + + Special-case Google domains, and spoof User-Agent when talking to + them, to stop being treated as a second-class citizen. + + * WebCoreSupport/FrameLoaderClientGtk.cpp: + (WebKit::initializeDomainsList): + (WebKit::isGoogleDomain): + (WebKit::FrameLoaderClient::userAgent): If enable-site-specific-quirks + is enabled, send the standard WebKit User-Agent string, disregarding the + custom one set by the browser for Google domains. + * webkit/webkitprivate.h: + * webkit/webkitwebsettings.cpp: + (webkitPlatform): Fix style, and simplify. + (webkitOSVersion): Ditto. + (webkitUserAgent): Add the Version/x.y string Safari has been + using since Safari 2.2. + +2010-09-10 Xan Lopez <xlopez@igalia.com> + + Reviewed by Martin Robinson. + + Fix compilation with GTK+ 3.x. + + GDK key macros were renamed from GDK_FOO to GDK_KEY_FOO, we need + to include the compat header provided if we want to keep using the + old names. + + * WebCoreSupport/FullscreenVideoController.cpp: include GtkVersioning.h + 2010-09-08 Darin Adler <darin@apple.com> Reviewed by Adam Barth. diff --git a/WebKit/gtk/JSCore.gir.in b/WebKit/gtk/JSCore.gir.in index e979c33..e143982 100644 --- a/WebKit/gtk/JSCore.gir.in +++ b/WebKit/gtk/JSCore.gir.in @@ -1,12 +1,14 @@ <?xml version="1.0"?> -<repository version="1.1" +<repository version="1.2" xmlns="http://www.gtk.org/introspection/core/1.0" xmlns:c="http://www.gtk.org/introspection/c/1.0"> <namespace name="JSCore" version="@WEBKITGTK_API_VERSION@" shared-library="webkitgtk-@WEBKITGTK_API_VERSION@"> - <alias name="GlobalContextRef" - target="none" - c:type="JSGlobalContextRef"/> - <alias name="ObjectRef" target="none" c:type="JSObjectRef"/> + <alias name="GlobalContextRef" target="none"> + <type name="JSGlobalContextRef" c:type="JSGlobalContextRef"/> + </alias> + <alias name="ObjectRef" target="none"> + <type name="JSObjectRef" c:type="JSObjectRef"/> + </alias> <function name="EvaluateScript" c:identifier="JSEvaluateScript"> <return-value transfer-ownership="none"> <type name="none" c:type="void"/> diff --git a/WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp b/WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp index 5c1bc0b..069fb19 100644 --- a/WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/ContextMenuClientGtk.cpp @@ -62,7 +62,7 @@ static GtkWidget* inputMethodsMenuItem (WebKitWebView* webView) WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView); GtkWidget* imContextMenu = gtk_menu_new(); - gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(priv->imContext), GTK_MENU_SHELL(imContextMenu)); + gtk_im_multicontext_append_menuitems(GTK_IM_MULTICONTEXT(priv->imContext.get()), GTK_MENU_SHELL(imContextMenu)); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), imContextMenu); diff --git a/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp b/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp index b6075b6..cc75d36 100644 --- a/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/DragClientGtk.cpp @@ -34,16 +34,30 @@ #include "RenderObject.h" #include "webkitprivate.h" #include "webkitwebview.h" +#include <gdk/gdk.h> #include <gtk/gtk.h> using namespace WebCore; namespace WebKit { +static gboolean dragIconWindowExposeEventCallback(GtkWidget* widget, GdkEventExpose* event, DragClient* client) +{ + client->dragIconWindowExposeEvent(widget, event); + return TRUE; +} + DragClient::DragClient(WebKitWebView* webView) : m_webView(webView) , m_startPos(0, 0) + , m_dragIconWindow(gtk_window_new(GTK_WINDOW_POPUP)) { + g_signal_connect(m_dragIconWindow.get(), "expose-event", G_CALLBACK(dragIconWindowExposeEventCallback), this); +} + +DragClient::~DragClient() +{ + g_signal_handlers_disconnect_by_func(m_dragIconWindow.get(), (gpointer) dragIconWindowExposeEventCallback, this); } void DragClient::willPerformDragDestinationAction(DragDestinationAction, DragData*) @@ -77,18 +91,44 @@ void DragClient::startDrag(DragImageRef image, const IntPoint& dragImageOrigin, GOwnPtr<GdkEvent> currentEvent(gtk_get_current_event()); GdkDragContext* context = gtk_drag_begin(GTK_WIDGET(m_webView), targetList.get(), dragOperationToGdkDragActions(clipboard->sourceOperation()), 1, currentEvent.get()); - webView->priv->draggingDataObjects->set(context, dataObject); + webView->priv->draggingDataObjects.set(context, dataObject); // A drag starting should prevent a double-click from happening. This might // happen if a drag is followed very quickly by another click (like in the DRT). webView->priv->previousClickTime = 0; - if (image) - gtk_drag_set_icon_pixbuf(context, image, eventPos.x() - dragImageOrigin.x(), eventPos.y() - dragImageOrigin.y()); - else + // This strategy originally comes from Chromium: + // src/chrome/browser/gtk/tab_contents_drag_source.cc + if (image) { + m_dragImage = image; + IntSize imageSize(cairo_image_surface_get_width(image), cairo_image_surface_get_height(image)); + gtk_window_resize(GTK_WINDOW(m_dragIconWindow.get()), imageSize.width(), imageSize.height()); + + if (!gtk_widget_get_realized(m_dragIconWindow.get())) { + GdkScreen* screen = gtk_widget_get_screen(m_dragIconWindow.get()); + GdkColormap* rgba = gdk_screen_get_rgba_colormap(screen); + if (rgba) + gtk_widget_set_colormap(m_dragIconWindow.get(), rgba); + } + + IntSize origin = eventPos - dragImageOrigin; + gtk_drag_set_icon_widget(context, m_dragIconWindow.get(), + origin.width(), origin.height()); + } else gtk_drag_set_icon_default(context); } +void DragClient::dragIconWindowExposeEvent(GtkWidget* widget, GdkEventExpose* event) +{ + PlatformRefPtr<cairo_t> context = adoptPlatformRef(gdk_cairo_create(event->window)); + cairo_rectangle(context.get(), 0, 0, + cairo_image_surface_get_width(m_dragImage.get()), + cairo_image_surface_get_height(m_dragImage.get())); + cairo_set_operator(context.get(), CAIRO_OPERATOR_SOURCE); + cairo_set_source_surface(context.get(), m_dragImage.get(), 0, 0); + cairo_fill(context.get()); +} + DragImageRef DragClient::createDragImageForLink(KURL&, const String&, Frame*) { notImplemented(); diff --git a/WebKit/gtk/WebCoreSupport/DragClientGtk.h b/WebKit/gtk/WebCoreSupport/DragClientGtk.h index 514852e..2ab7e2d 100644 --- a/WebKit/gtk/WebCoreSupport/DragClientGtk.h +++ b/WebKit/gtk/WebCoreSupport/DragClientGtk.h @@ -31,6 +31,8 @@ #define DragClientGtk_h #include "DragClient.h" +#include "GRefPtr.h" +#include "PlatformRefPtrCairo.h" typedef struct _WebKitWebView WebKitWebView; @@ -39,6 +41,7 @@ namespace WebKit { class DragClient : public WebCore::DragClient { public: DragClient(WebKitWebView*); + ~DragClient(); virtual void willPerformDragDestinationAction(WebCore::DragDestinationAction, WebCore::DragData*); virtual void willPerformDragSourceAction(WebCore::DragSourceAction, const WebCore::IntPoint&, WebCore::Clipboard*); @@ -51,9 +54,13 @@ namespace WebKit { virtual void dragControllerDestroyed(); + void dragIconWindowExposeEvent(GtkWidget*, GdkEventExpose*); + private: WebKitWebView* m_webView; WebCore::IntPoint m_startPos; + PlatformRefPtr<GtkWidget> m_dragIconWindow; + PlatformRefPtr<cairo_surface_t> m_dragImage; }; } diff --git a/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp b/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp index 8a019b4..d4e70b6 100644 --- a/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp @@ -122,6 +122,13 @@ static void pasteClipboardCallback(GtkWidget* widget, EditorClient* client) client->addPendingEditorCommand("Paste"); } +static void toggleOverwriteCallback(GtkWidget* widget, EditorClient* client) +{ + // We don't support toggling the overwrite mode, but the default callback expects + // the GtkTextView to have a layout, so we handle this signal just to stop it. + g_signal_stop_emission_by_name(widget, "toggle-overwrite"); +} + static const char* const gtkDeleteCommands[][2] = { { "DeleteBackward", "DeleteForward" }, // Characters { "DeleteWordBackward", "DeleteWordForward" }, // Word ends @@ -229,15 +236,15 @@ void EditorClient::setInputMethodState(bool active) WebKitWebViewPrivate* priv = m_webView->priv; if (active) - gtk_im_context_focus_in(priv->imContext); + gtk_im_context_focus_in(priv->imContext.get()); else - gtk_im_context_focus_out(priv->imContext); + gtk_im_context_focus_out(priv->imContext.get()); #ifdef MAEMO_CHANGES if (active) - hildon_gtk_im_context_show(priv->imContext); + hildon_gtk_im_context_show(priv->imContext.get()); else - hildon_gtk_im_context_hide(priv->imContext); + hildon_gtk_im_context_hide(priv->imContext.get()); #endif } @@ -341,6 +348,31 @@ static void collapseSelection(GtkClipboard* clipboard, WebKitWebView* webView) frame->selection()->setBase(frame->selection()->extent(), frame->selection()->affinity()); } +#if PLATFORM(X11) +static void setSelectionPrimaryClipboardIfNeeded(WebKitWebView* webView) +{ + if (!gtk_widget_has_screen(GTK_WIDGET(webView))) + return; + + GtkClipboard* clipboard = gtk_widget_get_clipboard(GTK_WIDGET(webView), GDK_SELECTION_PRIMARY); + DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard); + WebCore::Page* corePage = core(webView); + Frame* targetFrame = corePage->focusController()->focusedOrMainFrame(); + + if (!targetFrame->selection()->isRange()) + return; + + dataObject->clear(); + dataObject->setRange(targetFrame->selection()->toNormalizedRange()); + + viewSettingClipboard = webView; + GClosure* callback = g_cclosure_new_object(G_CALLBACK(collapseSelection), G_OBJECT(webView)); + g_closure_set_marshal(callback, g_cclosure_marshal_VOID__VOID); + pasteboardHelperInstance()->writeClipboardContents(clipboard, callback); + viewSettingClipboard = 0; +} +#endif + void EditorClient::respondToChangedSelection() { WebKitWebViewPrivate* priv = m_webView->priv; @@ -354,19 +386,7 @@ void EditorClient::respondToChangedSelection() return; #if PLATFORM(X11) - GtkClipboard* clipboard = gtk_widget_get_clipboard(GTK_WIDGET(m_webView), GDK_SELECTION_PRIMARY); - DataObjectGtk* dataObject = DataObjectGtk::forClipboard(clipboard); - - if (targetFrame->selection()->isRange()) { - dataObject->clear(); - dataObject->setRange(targetFrame->selection()->toNormalizedRange()); - - viewSettingClipboard = m_webView; - GClosure* callback = g_cclosure_new_object(G_CALLBACK(collapseSelection), G_OBJECT(m_webView)); - g_closure_set_marshal(callback, g_cclosure_marshal_VOID__VOID); - pasteboardHelperInstance()->writeClipboardContents(clipboard, callback); - viewSettingClipboard = 0; - } + setSelectionPrimaryClipboardIfNeeded(m_webView); #endif if (!targetFrame->editor()->hasComposition()) @@ -376,7 +396,7 @@ void EditorClient::respondToChangedSelection() unsigned end; if (!targetFrame->editor()->getCompositionSelection(start, end)) { // gtk_im_context_reset() clears the composition for us. - gtk_im_context_reset(priv->imContext); + gtk_im_context_reset(priv->imContext.get()); targetFrame->editor()->confirmCompositionWithoutDisturbingSelection(); } } @@ -710,7 +730,7 @@ void EditorClient::handleInputMethodKeydown(KeyboardEvent* event) m_treatContextCommitAsKeyEvent = (!targetFrame->editor()->hasComposition()) && event->keyEvent()->gdkEventKey()->keyval; clearPendingComposition(); - if ((gtk_im_context_filter_keypress(priv->imContext, event->keyEvent()->gdkEventKey()) && !m_pendingComposition) + if ((gtk_im_context_filter_keypress(priv->imContext.get(), event->keyEvent()->gdkEventKey()) && !m_pendingComposition) || (!m_treatContextCommitAsKeyEvent && !targetFrame->editor()->hasComposition())) event->preventDefault(); @@ -730,12 +750,12 @@ void EditorClient::handleInputMethodMousePress() // In this case, if the focused node is changed, the commit signal happens in a diffrent node. // Therefore, we need to confirm the current compositon and ignore the next commit signal. GOwnPtr<gchar> newPreedit(0); - gtk_im_context_get_preedit_string(priv->imContext, &newPreedit.outPtr(), 0, 0); + gtk_im_context_get_preedit_string(priv->imContext.get(), &newPreedit.outPtr(), 0, 0); if (g_utf8_strlen(newPreedit.get(), -1)) { targetFrame->editor()->confirmComposition(); m_preventNextCompositionCommit = true; - gtk_im_context_reset(priv->imContext); + gtk_im_context_reset(priv->imContext.get()); } } @@ -747,8 +767,8 @@ EditorClient::EditorClient(WebKitWebView* webView) , m_nativeWidget(gtk_text_view_new()) { WebKitWebViewPrivate* priv = m_webView->priv; - g_signal_connect(priv->imContext, "commit", G_CALLBACK(imContextCommitted), this); - g_signal_connect(priv->imContext, "preedit-changed", G_CALLBACK(imContextPreeditChanged), this); + g_signal_connect(priv->imContext.get(), "commit", G_CALLBACK(imContextCommitted), this); + g_signal_connect(priv->imContext.get(), "preedit-changed", G_CALLBACK(imContextPreeditChanged), this); g_signal_connect(m_nativeWidget.get(), "backspace", G_CALLBACK(backspaceCallback), this); g_signal_connect(m_nativeWidget.get(), "cut-clipboard", G_CALLBACK(cutClipboardCallback), this); @@ -757,13 +777,14 @@ EditorClient::EditorClient(WebKitWebView* webView) g_signal_connect(m_nativeWidget.get(), "select-all", G_CALLBACK(selectAllCallback), this); g_signal_connect(m_nativeWidget.get(), "move-cursor", G_CALLBACK(moveCursorCallback), this); g_signal_connect(m_nativeWidget.get(), "delete-from-cursor", G_CALLBACK(deleteFromCursorCallback), this); + g_signal_connect(m_nativeWidget.get(), "toggle-overwrite", G_CALLBACK(toggleOverwriteCallback), this); } EditorClient::~EditorClient() { WebKitWebViewPrivate* priv = m_webView->priv; - g_signal_handlers_disconnect_by_func(priv->imContext, (gpointer)imContextCommitted, this); - g_signal_handlers_disconnect_by_func(priv->imContext, (gpointer)imContextPreeditChanged, this); + g_signal_handlers_disconnect_by_func(priv->imContext.get(), (gpointer)imContextCommitted, this); + g_signal_handlers_disconnect_by_func(priv->imContext.get(), (gpointer)imContextPreeditChanged, this); } void EditorClient::textFieldDidBeginEditing(Element*) diff --git a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp index 4b0da3d..93b4cc2 100644 --- a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp +++ b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.cpp @@ -49,6 +49,7 @@ #include "MIMETypeRegistry.h" #include "MouseEvent.h" #include "NotImplemented.h" +#include "Page.h" #include "PlatformString.h" #include "PluginDatabase.h" #include "RenderPart.h" @@ -93,9 +94,115 @@ FrameLoaderClient::~FrameLoaderClient() g_object_unref(m_policyDecision); } -String FrameLoaderClient::userAgent(const KURL&) +static void initializeDomainsList(HashSet<String>& googleDomains) +{ + // Google search domains. + googleDomains.add("biz"); + googleDomains.add("com"); + googleDomains.add("net"); + googleDomains.add("org"); + googleDomains.add("ae"); + googleDomains.add("ag"); + googleDomains.add("am"); + googleDomains.add("at"); + googleDomains.add("az"); + googleDomains.add("be"); + googleDomains.add("bi"); + googleDomains.add("ca"); + googleDomains.add("cc"); + googleDomains.add("cd"); + googleDomains.add("cg"); + googleDomains.add("ch"); + googleDomains.add("cl"); + googleDomains.add("com.br"); + googleDomains.add("co.uk"); + googleDomains.add("co.jp"); + googleDomains.add("de"); + googleDomains.add("dj"); + googleDomains.add("dk"); + googleDomains.add("es"); + googleDomains.add("fi"); + googleDomains.add("fm"); + googleDomains.add("fr"); + googleDomains.add("gg"); + googleDomains.add("gl"); + googleDomains.add("gm"); + googleDomains.add("gs"); + googleDomains.add("hn"); + googleDomains.add("hu"); + googleDomains.add("ie"); + googleDomains.add("it"); + googleDomains.add("je"); + googleDomains.add("kz"); + googleDomains.add("li"); + googleDomains.add("lt"); + googleDomains.add("lu"); + googleDomains.add("lv"); + googleDomains.add("ma"); + googleDomains.add("ms"); + googleDomains.add("mu"); + googleDomains.add("mw"); + googleDomains.add("nl"); + googleDomains.add("no"); + googleDomains.add("nu"); + googleDomains.add("pl"); + googleDomains.add("pn"); + googleDomains.add("pt"); + googleDomains.add("ru"); + googleDomains.add("rw"); + googleDomains.add("sh"); + googleDomains.add("sk"); + googleDomains.add("sm"); + googleDomains.add("st"); + googleDomains.add("td"); + googleDomains.add("tk"); + googleDomains.add("tp"); + googleDomains.add("tv"); + googleDomains.add("us"); + googleDomains.add("uz"); + googleDomains.add("ws"); +} + +static bool isGoogleDomain(String host) +{ + DEFINE_STATIC_LOCAL(HashSet<String>, googleDomains, ()); + DEFINE_STATIC_LOCAL(Vector<String>, otherGoogleDomains, ()); + + if (googleDomains.isEmpty()) { + otherGoogleDomains.append("gmail.com"); + otherGoogleDomains.append("youtube.com"); + otherGoogleDomains.append("gstatic.com"); + otherGoogleDomains.append("ytimg.com"); + + initializeDomainsList(googleDomains); + } + + // First check if this is one of the various google.com international domains. + int position = host.find(".google."); + if (position > 0 && googleDomains.contains(host.substring(position + sizeof(".google.")))) + return true; + + // Then we check the possibility of it being one of the other, .com-only google domains. + for (unsigned int i = 0; i < otherGoogleDomains.size(); i++) { + if (host.endsWith(otherGoogleDomains.at(i))) + return true; + } + + return false; +} + +String FrameLoaderClient::userAgent(const KURL& url) { WebKitWebSettings* settings = webkit_web_view_get_settings(getViewFromFrame(m_frame)); + + gboolean useQuirks; + g_object_get(settings, "enable-site-specific-quirks", &useQuirks, NULL); + + // For Google domains, drop the browser's custom User Agent string, and use the standard + // WebKit/Safari one, so they don't give us a broken experience. + if (useQuirks && isGoogleDomain(url.host())) + return webkitUserAgent(); + return String::fromUTF8(webkit_web_settings_get_user_agent(settings)); } @@ -138,26 +245,15 @@ void FrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction policyFunctio (core(m_frame)->loader()->policyChecker()->*policyFunction)(PolicyUse); } - void FrameLoaderClient::committedLoad(WebCore::DocumentLoader* loader, const char* data, int length) { if (!m_pluginView) { ASSERT(loader->frame()); - // Setting the encoding on the frame loader is our way to get work done that is normally done - // when the first bit of data is received, even for the case of a document with no data (like about:blank). - String encoding = loader->overrideEncoding(); - bool userChosen = !encoding.isNull(); - if (!userChosen) - encoding = loader->response().textEncodingName(); - - FrameLoader* frameLoader = loader->frameLoader(); - frameLoader->writer()->setEncoding(encoding, userChosen); - if (data) - frameLoader->addData(data, length); + loader->commitData(data, length); Frame* coreFrame = loader->frame(); - if (coreFrame && coreFrame->document() && coreFrame->document()->isMediaDocument()) - loader->cancelMainResourceLoad(frameLoader->client()->pluginWillHandleLoadError(loader->response())); + if (coreFrame && coreFrame->document()->isMediaDocument()) + loader->cancelMainResourceLoad(coreFrame->loader()->client()->pluginWillHandleLoadError(loader->response())); } if (m_pluginView) { @@ -859,6 +955,12 @@ bool FrameLoaderClient::canHandleRequest(const ResourceRequest&) const return true; } +bool FrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const +{ + notImplemented(); + return false; +} + bool FrameLoaderClient::canShowMIMEType(const String& type) const { return (MIMETypeRegistry::isSupportedImageMIMEType(type) @@ -1145,14 +1247,12 @@ static void postCommitFrameViewSetup(WebKitWebFrame *frame, FrameView *view, boo { WebKitWebView* containingWindow = getViewFromFrame(frame); WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(containingWindow); - view->setGtkAdjustments(priv->horizontalAdjustment, priv->verticalAdjustment, resetValues); + view->setGtkAdjustments(priv->horizontalAdjustment.get(), priv->verticalAdjustment.get(), resetValues); if (priv->currentMenu) { - GtkMenu* menu = priv->currentMenu; - priv->currentMenu = 0; - - gtk_menu_popdown(menu); - g_object_unref(menu); + PlatformRefPtr<GtkMenu> menu(priv->currentMenu); + priv->currentMenu.clear(); + gtk_menu_popdown(menu.get()); } // Do not allow click counting between main frame loads. diff --git a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h index 753576b..c5ffc6a 100644 --- a/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h +++ b/WebKit/gtk/WebCoreSupport/FrameLoaderClientGtk.h @@ -160,6 +160,7 @@ namespace WebKit { virtual bool canHandleRequest(const WebCore::ResourceRequest&) const; virtual bool canShowMIMEType(const WTF::String&) const; + virtual bool canShowMIMETypeAsHTML(const String& MIMEType) const; virtual bool representationExistsForURLScheme(const WTF::String&) const; virtual WTF::String generatedMIMETypeForURLScheme(const WTF::String&) const; diff --git a/WebKit/gtk/WebCoreSupport/FullscreenVideoController.cpp b/WebKit/gtk/WebCoreSupport/FullscreenVideoController.cpp index c95dcff..cf9a548 100644 --- a/WebKit/gtk/WebCoreSupport/FullscreenVideoController.cpp +++ b/WebKit/gtk/WebCoreSupport/FullscreenVideoController.cpp @@ -23,6 +23,7 @@ #include "FullscreenVideoController.h" +#include "GtkVersioning.h" #include "MediaPlayer.h" #include <gdk/gdk.h> diff --git a/WebKit/gtk/tests/testatk.c b/WebKit/gtk/tests/testatk.c index 9930bc2..9ca7c05 100644 --- a/WebKit/gtk/tests/testatk.c +++ b/WebKit/gtk/tests/testatk.c @@ -44,10 +44,12 @@ static const char* contentsInTable = "<html><body><table><tr><td>foo</td><td>bar static const char* contentsInTableWithHeaders = "<html><body><table><tr><th>foo</th><th>bar</th><th colspan='2'>baz</th></tr><tr><th>qux</th><td>1</td><td>2</td><td>3</td></tr><tr><th rowspan='2'>quux</th><td>4</td><td>5</td><td>6</td></tr><tr><td>6</td><td>7</td><td>8</td></tr><tr><th>corge</th><td>9</td><td>10</td><td>11</td></tr></table><table><tr><td>1</td><td>2</td></tr><tr><td>3</td><td>4</td></tr></table></body></html>"; -static const char* textWithAttributes = "<html><head><style>.st1 {font-family: monospace; color:rgb(120,121,122);} .st2 {text-decoration:underline; background-color:rgb(80,81,82);}</style></head><body><p style=\"font-size:14; text-align:right;\">This is the <i>first</i><b> sentence of this text.</b></p><p class=\"st1\">This sentence should have an style applied <span class=\"st2\">and this part should have another one</span>.</p><p>x<sub>1</sub><sup>2</sup>=x<sub>2</sub><sup>3</sup></p><p style=\"text-align:center;\">This sentence is the <strike>last</strike> one.</p></body></html>"; - static const char* listsOfItems = "<html><body><ul><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ul><ol><li>text only</li><li><a href='foo'>link only</a></li><li>text and a <a href='bar'>link</a></li></ol></body></html>"; +static const char* textForSelections = "<html><body><p>A paragraph with plain text</p><p>A paragraph with <a href='http://webkit.org'>a link</a> in the middle</p></body></html>"; + +static const char* textWithAttributes = "<html><head><style>.st1 {font-family: monospace; color:rgb(120,121,122);} .st2 {text-decoration:underline; background-color:rgb(80,81,82);}</style></head><body><p style=\"font-size:14; text-align:right;\">This is the <i>first</i><b> sentence of this text.</b></p><p class=\"st1\">This sentence should have an style applied <span class=\"st2\">and this part should have another one</span>.</p><p>x<sub>1</sub><sup>2</sup>=x<sub>2</sub><sup>3</sup></p><p style=\"text-align:center;\">This sentence is the <strike>last</strike> one.</p></body></html>"; + static gboolean bail_out(GMainLoop* loop) { if (g_main_loop_is_running(loop)) @@ -742,6 +744,121 @@ static void testWebkitAtkTextAttributes(void) atk_attribute_set_free(set3); } +static void testWekitAtkTextSelections(void) +{ + WebKitWebView* webView; + AtkObject* obj; + GMainLoop* loop; + gchar* selectedText; + gint startOffset; + gint endOffset; + gboolean result; + + webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g_object_ref_sink(webView); + GtkAllocation alloc = { 0, 0, 800, 600 }; + gtk_widget_size_allocate(GTK_WIDGET(webView), &alloc); + webkit_web_view_load_string(webView, textForSelections, NULL, NULL, NULL); + loop = g_main_loop_new(NULL, TRUE); + + g_timeout_add(100, (GSourceFunc)bail_out, loop); + g_main_loop_run(loop); + + obj = gtk_widget_get_accessible(GTK_WIDGET(webView)); + g_assert(obj); + + AtkText* paragraph1 = ATK_TEXT(atk_object_ref_accessible_child(obj, 0)); + g_assert(ATK_IS_TEXT(paragraph1)); + AtkText* paragraph2 = ATK_TEXT(atk_object_ref_accessible_child(obj, 1)); + g_assert(ATK_IS_TEXT(paragraph2)); + AtkText* link = ATK_TEXT(atk_object_ref_accessible_child(ATK_OBJECT(paragraph2), 0)); + g_assert(ATK_IS_TEXT(link)); + + // First paragraph (simple text) + + // Basic initial checks + g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 0); + selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 0); + g_assert_cmpint(endOffset, ==, 0); + g_assert_cmpstr(selectedText, ==, NULL); + g_free (selectedText); + // Try removing a non existing (yet) selection + result = atk_text_remove_selection(paragraph1, 0); + g_assert(!result); + // Try setting a 0-char selection + result = atk_text_set_selection(paragraph1, 0, 5, 5); + g_assert(result); + + // Make a selection and test it + result = atk_text_set_selection(paragraph1, 0, 5, 25); + g_assert(result); + g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 1); + selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 5); + g_assert_cmpint(endOffset, ==, 25); + g_assert_cmpstr(selectedText, ==, "agraph with plain te"); + g_free (selectedText); + // Try removing the selection from other AtkText object (should fail) + result = atk_text_remove_selection(paragraph2, 0); + g_assert(!result); + + // Remove the selection and test everything again + result = atk_text_remove_selection(paragraph1, 0); + g_assert(result); + g_assert_cmpint(atk_text_get_n_selections(paragraph1), ==, 0); + selectedText = atk_text_get_selection(paragraph1, 0, &startOffset, &endOffset); + // Now offsets should be the same, set to the last position of the caret + g_assert_cmpint(startOffset, ==, endOffset); + g_assert_cmpint(startOffset, ==, 25); + g_assert_cmpint(endOffset, ==, 25); + g_assert_cmpstr(selectedText, ==, NULL); + g_free (selectedText); + + // Second paragraph (text + link + text) + + // Set a selection partially covering the link and test it + result = atk_text_set_selection(paragraph2, 0, 7, 21); + g_assert(result); + + // Test the paragraph first + g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 1); + selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 7); + g_assert_cmpint(endOffset, ==, 21); + g_assert_cmpstr(selectedText, ==, "raph with a li"); + g_free (selectedText); + + // Now test just the link + g_assert_cmpint(atk_text_get_n_selections(link), ==, 1); + selectedText = atk_text_get_selection(link, 0, &startOffset, &endOffset); + g_assert_cmpint(startOffset, ==, 0); + g_assert_cmpint(endOffset, ==, 4); + g_assert_cmpstr(selectedText, ==, "a li"); + g_free (selectedText); + + // Remove selections and text everything again + result = atk_text_remove_selection(paragraph2, 0); + g_assert(result); + g_assert_cmpint(atk_text_get_n_selections(paragraph2), ==, 0); + selectedText = atk_text_get_selection(paragraph2, 0, &startOffset, &endOffset); + // Now offsets should be the same (no selection) + g_assert_cmpint(startOffset, ==, endOffset); + g_assert_cmpstr(selectedText, ==, NULL); + g_free (selectedText); + + g_assert_cmpint(atk_text_get_n_selections(link), ==, 0); + selectedText = atk_text_get_selection(link, 0, &startOffset, &endOffset); + // Now offsets should be the same (no selection) + g_assert_cmpint(startOffset, ==, endOffset); + g_assert_cmpstr(selectedText, ==, NULL); + g_free (selectedText); + + g_object_unref(paragraph1); + g_object_unref(paragraph2); + g_object_unref(webView); +} + static void test_webkit_atk_get_extents(void) { WebKitWebView* webView; @@ -876,17 +993,17 @@ static void testWebkitAtkListsOfItems(void) g_assert(atk_object_get_role(uList) == ATK_ROLE_LIST); g_assert_cmpint(atk_object_get_n_accessible_children(uList), ==, 3); - item1 = ATK_TEXT(atk_object_ref_accessible_child(uList, 0)); - item2 = ATK_TEXT(atk_object_ref_accessible_child(uList, 1)); - item3 = ATK_TEXT(atk_object_ref_accessible_child(uList, 2)); + item1 = atk_object_ref_accessible_child(uList, 0); + item2 = atk_object_ref_accessible_child(uList, 1); + item3 = atk_object_ref_accessible_child(uList, 2); g_assert_cmpint(atk_object_get_n_accessible_children(item1), ==, 0); g_assert_cmpint(atk_object_get_n_accessible_children(item2), ==, 1); g_assert_cmpint(atk_object_get_n_accessible_children(item3), ==, 1); - g_assert_cmpstr(atk_text_get_text(item1, 0, -1), ==, "\342\200\242 text only"); - g_assert_cmpstr(atk_text_get_text(item2, 0, -1), ==, "\342\200\242 link only"); - g_assert_cmpstr(atk_text_get_text(item3, 0, -1), ==, "\342\200\242 text and a link"); + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item1), 0, -1), ==, "\342\200\242 text only"); + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item2), 0, -1), ==, "\342\200\242 link only"); + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item3), 0, -1), ==, "\342\200\242 text and a link"); g_object_unref(item1); g_object_unref(item2); @@ -899,13 +1016,13 @@ static void testWebkitAtkListsOfItems(void) g_assert(atk_object_get_role(oList) == ATK_ROLE_LIST); g_assert_cmpint(atk_object_get_n_accessible_children(oList), ==, 3); - item1 = ATK_TEXT(atk_object_ref_accessible_child(oList, 0)); - item2 = ATK_TEXT(atk_object_ref_accessible_child(oList, 1)); - item3 = ATK_TEXT(atk_object_ref_accessible_child(oList, 2)); + item1 = atk_object_ref_accessible_child(oList, 0); + item2 = atk_object_ref_accessible_child(oList, 1); + item3 = atk_object_ref_accessible_child(oList, 2); - g_assert_cmpstr(atk_text_get_text(item1, 0, -1), ==, "1 text only"); - g_assert_cmpstr(atk_text_get_text(item2, 0, -1), ==, "2 link only"); - g_assert_cmpstr(atk_text_get_text(item3, 0, -1), ==, "3 text and a link"); + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item1), 0, -1), ==, "1 text only"); + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item2), 0, -1), ==, "2 link only"); + g_assert_cmpstr(atk_text_get_text(ATK_TEXT(item3), 0, -1), ==, "3 text and a link"); g_assert_cmpint(atk_object_get_n_accessible_children(item1), ==, 0); g_assert_cmpint(atk_object_get_n_accessible_children(item2), ==, 1); @@ -936,6 +1053,7 @@ int main(int argc, char** argv) g_test_add_func("/webkit/atk/getTextInTable", testWebkitAtkGetTextInTable); g_test_add_func("/webkit/atk/getHeadersInTable", testWebkitAtkGetHeadersInTable); g_test_add_func("/webkit/atk/textAttributes", testWebkitAtkTextAttributes); + g_test_add_func("/webkit/atk/textSelections", testWekitAtkTextSelections); g_test_add_func("/webkit/atk/get_extents", test_webkit_atk_get_extents); g_test_add_func("/webkit/atk/listsOfItems", testWebkitAtkListsOfItems); return g_test_run (); diff --git a/WebKit/gtk/webkit/webkitdownload.cpp b/WebKit/gtk/webkit/webkitdownload.cpp index 9bcb739..1e45250 100644 --- a/WebKit/gtk/webkit/webkitdownload.cpp +++ b/WebKit/gtk/webkit/webkitdownload.cpp @@ -60,7 +60,7 @@ class DownloadClient : public Noncopyable, public ResourceHandleClient { virtual void didReceiveResponse(ResourceHandle*, const ResourceResponse&); virtual void didReceiveData(ResourceHandle*, const char*, int, int); - virtual void didFinishLoading(ResourceHandle*); + virtual void didFinishLoading(ResourceHandle*, double); virtual void didFail(ResourceHandle*, const ResourceError&); virtual void wasBlocked(ResourceHandle*); virtual void cannotShowURL(ResourceHandle*); @@ -485,8 +485,9 @@ void webkit_download_start(WebKitDownload* download) g_return_if_fail(priv->status == WEBKIT_DOWNLOAD_STATUS_CREATED); g_return_if_fail(priv->timer == NULL); + // For GTK, when downloading a file NetworkingContext is null if (!priv->resourceHandle) - priv->resourceHandle = ResourceHandle::create(core(priv->networkRequest), priv->downloadClient, 0, false, false); + priv->resourceHandle = ResourceHandle::create(/* Null NetworkingContext */ NULL, core(priv->networkRequest), priv->downloadClient, false, false); else { priv->resourceHandle->setClient(priv->downloadClient); @@ -929,7 +930,7 @@ void DownloadClient::didReceiveData(ResourceHandle*, const char* data, int lengt webkit_download_received_data(m_download, data, length); } -void DownloadClient::didFinishLoading(ResourceHandle*) +void DownloadClient::didFinishLoading(ResourceHandle*, double) { webkit_download_finished_loading(m_download); } diff --git a/WebKit/gtk/webkit/webkitprivate.cpp b/WebKit/gtk/webkit/webkitprivate.cpp index 1b7f7a3..aa3d3da 100644 --- a/WebKit/gtk/webkit/webkitprivate.cpp +++ b/WebKit/gtk/webkit/webkitprivate.cpp @@ -27,6 +27,7 @@ #include "Frame.h" #include "FrameLoader.h" #include "FrameLoaderClientGtk.h" +#include "FrameNetworkingContextGtk.h" #include "GtkVersioning.h" #include "HTMLMediaElement.h" #include "HTMLNames.h" @@ -205,11 +206,14 @@ static GtkWidget* currentToplevelCallback(WebKitSoupAuthDialog* feature, SoupMes if (!d) return NULL; - WebCore::Frame* frame = d->m_frame; - if (!frame) + WebKit::FrameNetworkingContextGtk* context = static_cast<WebKit::FrameNetworkingContextGtk*>(d->m_context.get()); + if (!context) + return NULL; + + if (!context->coreFrame()) return NULL; - GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(frame->page()->chrome()->platformPageClient())); + GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(context->coreFrame()->page()->chrome()->platformPageClient())); if (gtk_widget_is_toplevel(toplevel)) return toplevel; else diff --git a/WebKit/gtk/webkit/webkitprivate.h b/WebKit/gtk/webkit/webkitprivate.h index bde5b55..616ee6b 100644 --- a/WebKit/gtk/webkit/webkitprivate.h +++ b/WebKit/gtk/webkit/webkitprivate.h @@ -59,6 +59,7 @@ #include "FullscreenVideoController.h" #include "Node.h" #include "Page.h" +#include "PlatformString.h" #include "ResourceHandle.h" #include "ResourceRequest.h" #include "ResourceResponse.h" @@ -133,32 +134,32 @@ extern "C" { typedef struct _WebKitWebViewPrivate WebKitWebViewPrivate; struct _WebKitWebViewPrivate { WebCore::Page* corePage; - WebKitWebSettings* webSettings; - WebKitWebInspector* webInspector; - WebKitWebWindowFeatures* webWindowFeatures; + PlatformRefPtr<WebKitWebSettings> webSettings; + PlatformRefPtr<WebKitWebInspector> webInspector; + PlatformRefPtr<WebKitWebWindowFeatures> webWindowFeatures; WebKitWebFrame* mainFrame; - WebKitWebBackForwardList* backForwardList; + PlatformRefPtr<WebKitWebBackForwardList> backForwardList; - GtkMenu* currentMenu; + PlatformRefPtr<GtkMenu> currentMenu; gint lastPopupXPosition; gint lastPopupYPosition; HashSet<GtkWidget*> children; bool editable; - GtkIMContext* imContext; + PlatformRefPtr<GtkIMContext> imContext; gboolean transparent; - GtkAdjustment* horizontalAdjustment; - GtkAdjustment* verticalAdjustment; + PlatformRefPtr<GtkAdjustment> horizontalAdjustment; + PlatformRefPtr<GtkAdjustment> verticalAdjustment; gboolean zoomFullContent; WebKitLoadStatus loadStatus; - char* encoding; - char* customEncoding; + CString encoding; + CString customEncoding; - char* iconURI; + CString iconURI; gboolean disposing; gboolean usePrimaryForPaste; @@ -169,18 +170,17 @@ extern "C" { // These are hosted here because the DataSource object is // created too late in the frame loading process. - WebKitWebResource* mainResource; - char* mainResourceIdentifier; - GHashTable* subResources; - char* tooltipText; + PlatformRefPtr<WebKitWebResource> mainResource; + CString mainResourceIdentifier; + PlatformRefPtr<GHashTable> subResources; + CString tooltipText; int currentClickCount; - WebCore::IntPoint* previousClickPoint; + WebCore::IntPoint previousClickPoint; guint previousClickButton; guint32 previousClickTime; - - HashMap<GdkDragContext*, RefPtr<WebCore::DataObjectGtk> >* draggingDataObjects; - HashMap<GdkDragContext*, WebKit::DroppingContext*>* droppingContexts; + HashMap<GdkDragContext*, RefPtr<WebCore::DataObjectGtk> > draggingDataObjects; + HashMap<GdkDragContext*, WebKit::DroppingContext*> droppingContexts; }; #define WEBKIT_WEB_FRAME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), WEBKIT_TYPE_WEB_FRAME, WebKitWebFramePrivate)) @@ -206,6 +206,9 @@ extern "C" { gboolean disposed; }; + WTF::String + webkitUserAgent(); + void webkit_web_frame_core_frame_gone(WebKitWebFrame*); @@ -283,6 +286,9 @@ extern "C" { void webkit_web_view_set_tooltip_text(WebKitWebView*, const char*); + GtkMenu* + webkit_web_view_get_context_menu(WebKitWebView*); + WEBKIT_API void webkit_web_view_execute_core_command_by_name(WebKitWebView* webView, const gchar* name, const gchar* value); diff --git a/WebKit/gtk/webkit/webkitwebsettings.cpp b/WebKit/gtk/webkit/webkitwebsettings.cpp index 71a338c..767fce1 100644 --- a/WebKit/gtk/webkit/webkitwebsettings.cpp +++ b/WebKit/gtk/webkit/webkitwebsettings.cpp @@ -163,56 +163,62 @@ enum { // Create a default user agent string // This is a liberal interpretation of http://www.mozilla.org/build/revised-user-agent-strings.html // See also http://developer.apple.com/internet/safari/faq.html#anchor2 -static String webkit_get_user_agent() +static String webkitPlatform() { - gchar* platform; - gchar* osVersion; - #if PLATFORM(X11) - platform = g_strdup("X11"); + DEFINE_STATIC_LOCAL(const String, uaPlatform, (String("X11"))); #elif OS(WINDOWS) - platform = g_strdup("Windows"); + DEFINE_STATIC_LOCAL(const String, uaPlatform, (String("Windows"))); #elif PLATFORM(MAC) - platform = g_strdup("Macintosh"); + DEFINE_STATIC_LOCAL(const String, uaPlatform, (String("Macintosh"))); #elif defined(GDK_WINDOWING_DIRECTFB) - platform = g_strdup("DirectFB"); + DEFINE_STATIC_LOCAL(const String, uaPlatform, (String("DirectFB"))); #else - platform = g_strdup("Unknown"); + DEFINE_STATIC_LOCAL(const String, uaPlatform, (String("Unknown"))); #endif + return uaPlatform; +} + +static String webkitOSVersion() +{ // FIXME: platform/version detection can be shared. #if OS(DARWIN) #if CPU(X86) - osVersion = g_strdup("Intel Mac OS X"); + DEFINE_STATIC_LOCAL(const String, uaOSVersion, (String("Intel Mac OS X"))); #else - osVersion = g_strdup("PPC Mac OS X"); + DEFINE_STATIC_LOCAL(const String, uaOSVersion, (String("PPC Mac OS X"))); #endif #elif OS(UNIX) + DEFINE_STATIC_LOCAL(String, uaOSVersion, (String())); + + if (!uaOSVersion.isEmpty()) + return uaOSVersion; + struct utsname name; if (uname(&name) != -1) - osVersion = g_strdup_printf("%s %s", name.sysname, name.machine); + uaOSVersion = String::format("%s %s", name.sysname, name.machine); else - osVersion = g_strdup("Unknown"); - + uaOSVersion = String("Unknown"); #elif OS(WINDOWS) - // FIXME: Compute the Windows version - osVersion = g_strdup("Windows"); - + DEFINE_STATIC_LOCAL(const String, uaOSVersion, (String("Windows"))); #else - osVersion = g_strdup("Unknown"); + DEFINE_STATIC_LOCAL(const String, uaOSVersion, (String("Unknown"))); #endif + return uaOSVersion; +} + +String webkitUserAgent() +{ // We mention Safari since many broken sites check for it (OmniWeb does this too) // We re-use the WebKit version, though it doesn't seem to matter much in practice DEFINE_STATIC_LOCAL(const String, uaVersion, (String::format("%d.%d+", WEBKIT_USER_AGENT_MAJOR_VERSION, WEBKIT_USER_AGENT_MINOR_VERSION))); - DEFINE_STATIC_LOCAL(const String, staticUA, (String::format("Mozilla/5.0 (%s; U; %s; %s) AppleWebKit/%s (KHTML, like Gecko) Safari/%s", - platform, osVersion, defaultLanguage().utf8().data(), uaVersion.utf8().data(), uaVersion.utf8().data()))); - - g_free(osVersion); - g_free(platform); + DEFINE_STATIC_LOCAL(const String, staticUA, (String::format("Mozilla/5.0 (%s; U; %s; %s) AppleWebKit/%s (KHTML, like Gecko) Version/5.0 Safari/%s", + webkitPlatform().utf8().data(), webkitOSVersion().utf8().data(), defaultLanguage().utf8().data(), uaVersion.utf8().data(), uaVersion.utf8().data()))); return staticUA; } @@ -607,7 +613,7 @@ static void webkit_web_settings_class_init(WebKitWebSettingsClass* klass) g_param_spec_string("user-agent", _("User Agent"), _("The User-Agent string used by WebKitGtk"), - webkit_get_user_agent().utf8().data(), + webkitUserAgent().utf8().data(), flags)); /** @@ -1034,7 +1040,7 @@ static void webkit_web_settings_set_property(GObject* object, guint prop_id, con case PROP_USER_AGENT: g_free(priv->user_agent); if (!g_value_get_string(value) || !strlen(g_value_get_string(value))) - priv->user_agent = g_strdup(webkit_get_user_agent().utf8().data()); + priv->user_agent = g_strdup(webkitUserAgent().utf8().data()); else priv->user_agent = g_strdup(g_value_get_string(value)); break; diff --git a/WebKit/gtk/webkit/webkitwebview.cpp b/WebKit/gtk/webkit/webkitwebview.cpp index 480983f..3212450 100644 --- a/WebKit/gtk/webkit/webkitwebview.cpp +++ b/WebKit/gtk/webkit/webkitwebview.cpp @@ -210,11 +210,7 @@ static GtkIMContext* webkit_web_view_get_im_context(WebKitWebView*); static void destroy_menu_cb(GtkObject* object, gpointer data) { - WebKitWebView* webView = WEBKIT_WEB_VIEW(data); - WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView); - - g_object_unref(priv->currentMenu); - priv->currentMenu = NULL; + WEBKIT_WEB_VIEW(data)->priv->currentMenu = 0; } static void PopupMenuPositionFunc(GtkMenu* menu, gint *x, gint *y, gboolean *pushIn, gpointer userData) @@ -224,7 +220,11 @@ static void PopupMenuPositionFunc(GtkMenu* menu, gint *x, gint *y, gboolean *pus GdkScreen* screen = gtk_widget_get_screen(GTK_WIDGET(view)); GtkRequisition menuSize; +#ifdef GTK_API_VERSION_2 gtk_widget_size_request(GTK_WIDGET(menu), &menuSize); +#else + gtk_size_request_get_size(GTK_SIZE_REQUEST(menu), &menuSize, NULL); +#endif *x = priv->lastPopupXPosition; if ((*x + menuSize.width) >= gdk_screen_get_width(screen)) @@ -304,7 +304,7 @@ static gboolean webkit_web_view_forward_context_menu_event(WebKitWebView* webVie return FALSE; WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView); - priv->currentMenu = GTK_MENU(g_object_ref(menu)); + priv->currentMenu = menu; priv->lastPopupXPosition = event.globalX(); priv->lastPopupYPosition = event.globalY(); @@ -592,7 +592,7 @@ static gboolean webkit_web_view_key_release_event(GtkWidget* widget, GdkEventKey // the event if we don't have a pending composition, because that means we // are using a context like 'simple' which marks every keystroke as filtered. WebKit::EditorClient* client = static_cast<WebKit::EditorClient*>(core(webView)->editorClient()); - if (gtk_im_context_filter_keypress(webView->priv->imContext, event) && !client->hasPendingComposition()) + if (gtk_im_context_filter_keypress(webView->priv->imContext.get(), event) && !client->hasPendingComposition()) return TRUE; Frame* frame = core(webView)->focusController()->focusedOrMainFrame(); @@ -651,8 +651,8 @@ static gboolean webkit_web_view_button_press_event(GtkWidget* widget, GdkEventBu // GDK logic for counting clicks. guint32 eventTime = getEventTime(reinterpret_cast<GdkEvent*>(event)); if ((event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) - || ((abs(event->x - priv->previousClickPoint->x()) < doubleClickDistance) - && (abs(event->y - priv->previousClickPoint->y()) < doubleClickDistance) + || ((abs(event->x - priv->previousClickPoint.x()) < doubleClickDistance) + && (abs(event->y - priv->previousClickPoint.y()) < doubleClickDistance) && (eventTime - priv->previousClickTime < static_cast<guint>(doubleClickTime)) && (event->button == priv->previousClickButton))) priv->currentClickCount++; @@ -661,7 +661,7 @@ static gboolean webkit_web_view_button_press_event(GtkWidget* widget, GdkEventBu PlatformMouseEvent platformEvent(event); platformEvent.setClickCount(priv->currentClickCount); - *priv->previousClickPoint = platformEvent.pos(); + priv->previousClickPoint = platformEvent.pos(); priv->previousClickButton = event->button; priv->previousClickTime = eventTime; @@ -702,7 +702,7 @@ static gboolean webkit_web_view_button_release_event(GtkWidget* widget, GdkEvent if (focusedFrame && focusedFrame->editor()->canEdit()) { #ifdef MAEMO_CHANGES WebKitWebViewPrivate* priv = webView->priv; - hildon_gtk_im_context_filter_event(priv->imContext, (GdkEvent*)event); + hildon_gtk_im_context_filter_event(priv->imContext.get(), (GdkEvent*)event); #endif } @@ -806,7 +806,7 @@ static gboolean webkit_web_view_focus_in_event(GtkWidget* widget, GdkEventFocus* focusController->setFocusedFrame(core(webView)->mainFrame()); if (focusController->focusedFrame()->editor()->canEdit()) - gtk_im_context_focus_in(webView->priv->imContext); + gtk_im_context_focus_in(webView->priv->imContext.get()); } return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->focus_in_event(widget, event); } @@ -824,7 +824,7 @@ static gboolean webkit_web_view_focus_out_event(GtkWidget* widget, GdkEventFocus } if (webView->priv->imContext) - gtk_im_context_focus_out(webView->priv->imContext); + gtk_im_context_focus_out(webView->priv->imContext.get()); return GTK_WIDGET_CLASS(webkit_web_view_parent_class)->focus_out_event(widget, event); } @@ -875,7 +875,7 @@ static void webkit_web_view_realize(GtkWidget* widget) WebKitWebView* webView = WEBKIT_WEB_VIEW(widget); WebKitWebViewPrivate* priv = webView->priv; - gtk_im_context_set_client_window(priv->imContext, window); + gtk_im_context_set_client_window(priv->imContext.get(), window); } static void webkit_web_view_set_scroll_adjustments(WebKitWebView* webView, GtkAdjustment* hadj, GtkAdjustment* vadj) @@ -883,26 +883,12 @@ static void webkit_web_view_set_scroll_adjustments(WebKitWebView* webView, GtkAd if (!core(webView)) return; - FrameView* view = core(webkit_web_view_get_main_frame(webView))->view(); - - if (hadj) - g_object_ref(hadj); - if (vadj) - g_object_ref(vadj); - - WebKitWebViewPrivate* priv = webView->priv; - - if (priv->horizontalAdjustment) - g_object_unref(priv->horizontalAdjustment); - if (priv->verticalAdjustment) - g_object_unref(priv->verticalAdjustment); - - priv->horizontalAdjustment = hadj; - priv->verticalAdjustment = vadj; + webView->priv->horizontalAdjustment = hadj; + webView->priv->verticalAdjustment = vadj; + FrameView* view = core(webkit_web_view_get_main_frame(webView))->view(); if (!view) return; - view->setGtkAdjustments(hadj, vadj); } @@ -1158,78 +1144,42 @@ static void webkit_web_view_dispose(GObject* object) priv->disposing = TRUE; - if (priv->horizontalAdjustment) { - g_object_unref(priv->horizontalAdjustment); - priv->horizontalAdjustment = NULL; - } - - if (priv->verticalAdjustment) { - g_object_unref(priv->verticalAdjustment); - priv->verticalAdjustment = NULL; - } - - if (priv->backForwardList) { - g_object_unref(priv->backForwardList); - priv->backForwardList = NULL; - } + // These smart pointers are cleared manually, because some cleanup operations are + // very sensitive to their value. We may crash if these are done in the wrong order. + priv->horizontalAdjustment.clear(); + priv->verticalAdjustment.clear(); + priv->backForwardList.clear(); if (priv->corePage) { webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(object)); - core(priv->mainFrame)->loader()->detachFromParent(); delete priv->corePage; - priv->corePage = NULL; + priv->corePage = 0; } if (priv->webSettings) { - g_signal_handlers_disconnect_by_func(priv->webSettings, (gpointer)webkit_web_view_settings_notify, webView); - g_object_unref(priv->webSettings); - priv->webSettings = NULL; - - g_object_unref(priv->webInspector); - priv->webInspector = NULL; - - g_object_unref(priv->webWindowFeatures); - priv->webWindowFeatures = NULL; - - g_object_unref(priv->imContext); - priv->imContext = NULL; - } - - if (priv->mainResource) { - g_object_unref(priv->mainResource); - priv->mainResource = NULL; + g_signal_handlers_disconnect_by_func(priv->webSettings.get(), (gpointer)webkit_web_view_settings_notify, webView); + priv->webSettings.clear(); } - if (priv->subResources) { - g_hash_table_unref(priv->subResources); - priv->subResources = NULL; - } + priv->webInspector.clear(); + priv->webWindowFeatures.clear(); + priv->mainResource.clear(); + priv->subResources.clear(); - priv->draggingDataObjects->clear(); - HashMap<GdkDragContext*, DroppingContext*>::iterator endDroppingContexts = priv->droppingContexts->end(); - for (HashMap<GdkDragContext*, DroppingContext*>::iterator iter = priv->droppingContexts->begin(); iter != endDroppingContexts; ++iter) + HashMap<GdkDragContext*, DroppingContext*>::iterator endDroppingContexts = priv->droppingContexts.end(); + for (HashMap<GdkDragContext*, DroppingContext*>::iterator iter = priv->droppingContexts.begin(); iter != endDroppingContexts; ++iter) delete (iter->second); - priv->droppingContexts->clear(); + priv->droppingContexts.clear(); G_OBJECT_CLASS(webkit_web_view_parent_class)->dispose(object); } static void webkit_web_view_finalize(GObject* object) { - WebKitWebView* webView = WEBKIT_WEB_VIEW(object); - WebKitWebViewPrivate* priv = webView->priv; - - g_free(priv->tooltipText); - g_free(priv->mainResourceIdentifier); - g_free(priv->encoding); - g_free(priv->customEncoding); - g_free(priv->iconURI); - - delete priv->previousClickPoint; - delete priv->draggingDataObjects; - delete priv->droppingContexts; - + // We need to manually call the destructor here, since this object's memory is managed + // by GLib. This calls all C++ members' destructors and prevents memory leaks. + WEBKIT_WEB_VIEW(object)->priv->~WebKitWebViewPrivate(); G_OBJECT_CLASS(webkit_web_view_parent_class)->finalize(object); } @@ -1279,7 +1229,7 @@ static AtkObject* webkit_web_view_get_accessible(GtkWidget* widget) static gdouble webViewGetDPI(WebKitWebView* webView) { WebKitWebViewPrivate* priv = webView->priv; - WebKitWebSettings* webSettings = priv->webSettings; + WebKitWebSettings* webSettings = priv->webSettings.get(); gboolean enforce96DPI; g_object_get(webSettings, "enforce-96-dpi", &enforce96DPI, NULL); if (enforce96DPI) @@ -1305,7 +1255,7 @@ static void webkit_web_view_screen_changed(GtkWidget* widget, GdkScreen* previou if (priv->disposing) return; - WebKitWebSettings* webSettings = priv->webSettings; + WebKitWebSettings* webSettings = priv->webSettings.get(); Settings* settings = core(webView)->settings(); gdouble DPI = webViewGetDPI(webView); @@ -1339,10 +1289,10 @@ static void webkit_web_view_drag_end(GtkWidget* widget, GdkDragContext* context) // This might happen if a drag is still in progress after a WebKitWebView // is disposed and before it is finalized. - if (!priv->draggingDataObjects->contains(context)) + if (!priv->draggingDataObjects.contains(context)) return; - priv->draggingDataObjects->remove(context); + priv->draggingDataObjects.remove(context); Frame* frame = core(webView)->focusController()->focusedOrMainFrame(); if (!frame) @@ -1377,10 +1327,10 @@ static void webkit_web_view_drag_data_get(GtkWidget* widget, GdkDragContext* con // This might happen if a drag is still in progress after a WebKitWebView // is diposed and before it is finalized. - if (!priv->draggingDataObjects->contains(context)) + if (!priv->draggingDataObjects.contains(context)) return; - pasteboardHelperInstance()->fillSelectionData(selectionData, info, priv->draggingDataObjects->get(context).get()); + pasteboardHelperInstance()->fillSelectionData(selectionData, info, priv->draggingDataObjects.get(context).get()); } static gboolean doDragLeaveLater(DroppingContext* context) @@ -1388,7 +1338,7 @@ static gboolean doDragLeaveLater(DroppingContext* context) WebKitWebView* webView = context->webView; WebKitWebViewPrivate* priv = webView->priv; - if (!priv->droppingContexts->contains(context->gdkContext)) + if (!priv->droppingContexts.contains(context->gdkContext)) return FALSE; // If the view doesn't know about the drag yet (there are still pending data) @@ -1405,7 +1355,7 @@ static gboolean doDragLeaveLater(DroppingContext* context) } core(webView)->dragController()->dragEnded(); - priv->droppingContexts->remove(context->gdkContext); + priv->droppingContexts.remove(context->gdkContext); delete context; return FALSE; } @@ -1415,13 +1365,13 @@ static void webkit_web_view_drag_leave(GtkWidget* widget, GdkDragContext* contex WebKitWebView* webView = WEBKIT_WEB_VIEW(widget); WebKitWebViewPrivate* priv = webView->priv; - if (!priv->droppingContexts->contains(context)) + if (!priv->droppingContexts.contains(context)) return; // During a drop GTK+ will fire a drag-leave signal right before firing // the drag-drop signal. We want the actions for drag-leave to happen after // those for drag-drop, so schedule them to happen asynchronously here. - g_timeout_add(0, reinterpret_cast<GSourceFunc>(doDragLeaveLater), priv->droppingContexts->get(context)); + g_timeout_add(0, reinterpret_cast<GSourceFunc>(doDragLeaveLater), priv->droppingContexts.get(context)); } static gboolean webkit_web_view_drag_motion(GtkWidget* widget, GdkDragContext* context, gint x, gint y, guint time) @@ -1431,21 +1381,21 @@ static gboolean webkit_web_view_drag_motion(GtkWidget* widget, GdkDragContext* c DroppingContext* droppingContext = 0; IntPoint position = IntPoint(x, y); - if (!priv->droppingContexts->contains(context)) { + if (!priv->droppingContexts.contains(context)) { droppingContext = new DroppingContext; droppingContext->webView = webView; droppingContext->gdkContext = context; droppingContext->dataObject = WebCore::DataObjectGtk::create(); droppingContext->dropHappened = false; droppingContext->lastMotionPosition = position; - priv->droppingContexts->set(context, droppingContext); + priv->droppingContexts.set(context, droppingContext); Vector<GdkAtom> acceptableTargets(pasteboardHelperInstance()->dropAtomsForContext(widget, context)); droppingContext->pendingDataRequests = acceptableTargets.size(); for (size_t i = 0; i < acceptableTargets.size(); i++) gtk_drag_get_data(widget, context, acceptableTargets.at(i), time); } else { - droppingContext = priv->droppingContexts->get(context); + droppingContext = priv->droppingContexts.get(context); droppingContext->lastMotionPosition = position; } @@ -1468,10 +1418,10 @@ static void webkit_web_view_drag_data_received(GtkWidget* widget, GdkDragContext WebKitWebView* webView = WEBKIT_WEB_VIEW(widget); WebKitWebViewPrivate* priv = webView->priv; - if (!priv->droppingContexts->contains(context)) + if (!priv->droppingContexts.contains(context)) return; - DroppingContext* droppingContext = priv->droppingContexts->get(context); + DroppingContext* droppingContext = priv->droppingContexts.get(context); droppingContext->pendingDataRequests--; pasteboardHelperInstance()->fillDataObjectFromDropData(selectionData, info, droppingContext->dataObject.get()); @@ -1493,10 +1443,10 @@ static gboolean webkit_web_view_drag_drop(GtkWidget* widget, GdkDragContext* con WebKitWebView* webView = WEBKIT_WEB_VIEW(widget); WebKitWebViewPrivate* priv = webView->priv; - if (!priv->droppingContexts->contains(context)) + if (!priv->droppingContexts.contains(context)) return FALSE; - DroppingContext* droppingContext = priv->droppingContexts->get(context); + DroppingContext* droppingContext = priv->droppingContexts.get(context); droppingContext->dropHappened = true; IntPoint position(x, y); @@ -1512,8 +1462,8 @@ static gboolean webkit_web_view_query_tooltip(GtkWidget *widget, gint x, gint y, { WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(widget); - if (priv->tooltipText) { - gtk_tooltip_set_text(tooltip, priv->tooltipText); + if (priv->tooltipText.length() > 0) { + gtk_tooltip_set_text(tooltip, priv->tooltipText.data()); return TRUE; } @@ -1524,7 +1474,7 @@ static gboolean webkit_web_view_query_tooltip(GtkWidget *widget, gint x, gint y, static GtkIMContext* webkit_web_view_get_im_context(WebKitWebView* webView) { g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); - return GTK_IM_CONTEXT(webView->priv->imContext); + return GTK_IM_CONTEXT(webView->priv->imContext.get()); } static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) @@ -2892,7 +2842,7 @@ static void webkit_web_view_class_init(WebKitWebViewClass* webViewClass) static void webkit_web_view_update_settings(WebKitWebView* webView) { WebKitWebViewPrivate* priv = webView->priv; - WebKitWebSettings* webSettings = priv->webSettings; + WebKitWebSettings* webSettings = priv->webSettings.get(); Settings* settings = core(webView)->settings(); gchar* defaultEncoding, *cursiveFontFamily, *defaultFontFamily, *fantasyFontFamily, *monospaceFontFamily, *sansSerifFontFamily, *serifFontFamily, *userStylesheetUri; @@ -3095,8 +3045,14 @@ static void webkit_web_view_init(WebKitWebView* webView) { WebKitWebViewPrivate* priv = WEBKIT_WEB_VIEW_GET_PRIVATE(webView); webView->priv = priv; + // This is the placement new syntax: http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10 + // It allows us to call a constructor on manually allocated locations in memory. We must use it + // in this case, because GLib manages the memory for the private data section, but we wish it + // to contain C++ object members. The use of placement new calls the constructor on all C++ data + // members, which ensures they are initialized properly. + new (priv) WebKitWebViewPrivate(); - priv->imContext = gtk_im_multicontext_new(); + priv->imContext = adoptPlatformRef(gtk_im_multicontext_new()); Page::PageClients pageClients; pageClients.chromeClient = new WebKit::ChromeClient(webView); @@ -3108,40 +3064,33 @@ static void webkit_web_view_init(WebKitWebView* webView) // We also add a simple wrapper class to provide the public // interface for the Web Inspector. - priv->webInspector = WEBKIT_WEB_INSPECTOR(g_object_new(WEBKIT_TYPE_WEB_INSPECTOR, NULL)); - webkit_web_inspector_set_inspector_client(priv->webInspector, priv->corePage); + priv->webInspector = adoptPlatformRef(WEBKIT_WEB_INSPECTOR(g_object_new(WEBKIT_TYPE_WEB_INSPECTOR, NULL))); + webkit_web_inspector_set_inspector_client(priv->webInspector.get(), priv->corePage); + // The smart pointer will call g_object_ref_sink on these adjustments. priv->horizontalAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); priv->verticalAdjustment = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 0.0, 0.0, 0.0, 0.0)); - g_object_ref_sink(priv->horizontalAdjustment); - g_object_ref_sink(priv->verticalAdjustment); - gtk_widget_set_can_focus(GTK_WIDGET(webView), TRUE); priv->mainFrame = WEBKIT_WEB_FRAME(webkit_web_frame_new(webView)); priv->lastPopupXPosition = priv->lastPopupYPosition = -1; priv->editable = false; - priv->backForwardList = webkit_web_back_forward_list_new_with_web_view(webView); + priv->backForwardList = adoptPlatformRef(webkit_web_back_forward_list_new_with_web_view(webView)); priv->zoomFullContent = FALSE; - priv->webSettings = webkit_web_settings_new(); + priv->webSettings = adoptPlatformRef(webkit_web_settings_new()); webkit_web_view_update_settings(webView); - g_signal_connect(priv->webSettings, "notify", G_CALLBACK(webkit_web_view_settings_notify), webView); + g_signal_connect(priv->webSettings.get(), "notify", G_CALLBACK(webkit_web_view_settings_notify), webView); - priv->webWindowFeatures = webkit_web_window_features_new(); + priv->webWindowFeatures = adoptPlatformRef(webkit_web_window_features_new()); - priv->subResources = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref); + priv->subResources = adoptPlatformRef(g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_object_unref)); - priv->tooltipText = 0; priv->currentClickCount = 0; - priv->previousClickPoint = new IntPoint(0, 0); priv->previousClickButton = 0; priv->previousClickTime = 0; - - priv->draggingDataObjects = new HashMap<GdkDragContext*, RefPtr<WebCore::DataObjectGtk> >(); - priv->droppingContexts = new HashMap<GdkDragContext*, DroppingContext*>(); gtk_drag_dest_set(GTK_WIDGET(webView), static_cast<GtkDestDefaults>(0), 0, 0, static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_LINK | GDK_ACTION_PRIVATE)); gtk_drag_dest_set_target_list(GTK_WIDGET(webView), pasteboardHelperInstance()->targetList()); } @@ -3211,9 +3160,7 @@ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitWebSettings* web g_return_if_fail(WEBKIT_IS_WEB_SETTINGS(webSettings)); WebKitWebViewPrivate* priv = webView->priv; - g_signal_handlers_disconnect_by_func(priv->webSettings, (gpointer)webkit_web_view_settings_notify, webView); - g_object_unref(priv->webSettings); - g_object_ref(webSettings); + g_signal_handlers_disconnect_by_func(priv->webSettings.get(), (gpointer)webkit_web_view_settings_notify, webView); priv->webSettings = webSettings; webkit_web_view_update_settings(webView); g_signal_connect(webSettings, "notify", G_CALLBACK(webkit_web_view_settings_notify), webView); @@ -3235,10 +3182,8 @@ void webkit_web_view_set_settings(WebKitWebView* webView, WebKitWebSettings* web */ WebKitWebSettings* webkit_web_view_get_settings(WebKitWebView* webView) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); - - WebKitWebViewPrivate* priv = webView->priv; - return priv->webSettings; + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); + return webView->priv->webSettings.get(); } /** @@ -3257,26 +3202,18 @@ WebKitWebSettings* webkit_web_view_get_settings(WebKitWebView* webView) */ WebKitWebInspector* webkit_web_view_get_inspector(WebKitWebView* webView) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); - - WebKitWebViewPrivate* priv = webView->priv; - return priv->webInspector; + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); + return webView->priv->webInspector.get(); } // internal static void webkit_web_view_set_window_features(WebKitWebView* webView, WebKitWebWindowFeatures* webWindowFeatures) { - WebKitWebViewPrivate* priv = webView->priv; - if (!webWindowFeatures) return; - - if (webkit_web_window_features_equal(priv->webWindowFeatures, webWindowFeatures)) + if (webkit_web_window_features_equal(webView->priv->webWindowFeatures.get(), webWindowFeatures)) return; - - g_object_unref(priv->webWindowFeatures); - g_object_ref(webWindowFeatures); - priv->webWindowFeatures = webWindowFeatures; + webView->priv->webWindowFeatures = webWindowFeatures; } /** @@ -3292,10 +3229,8 @@ static void webkit_web_view_set_window_features(WebKitWebView* webView, WebKitWe */ WebKitWebWindowFeatures* webkit_web_view_get_window_features(WebKitWebView* webView) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); - - WebKitWebViewPrivate* priv = webView->priv; - return priv->webWindowFeatures; + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); + return webView->priv->webWindowFeatures.get(); } /** @@ -3359,14 +3294,10 @@ void webkit_web_view_set_maintains_back_forward_list(WebKitWebView* webView, gbo */ WebKitWebBackForwardList* webkit_web_view_get_back_forward_list(WebKitWebView* webView) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); - - WebKitWebViewPrivate* priv = webView->priv; - + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); if (!core(webView) || !core(webView)->backForwardList()->enabled()) - return NULL; - - return priv->backForwardList; + return 0; + return webView->priv->backForwardList.get(); } /** @@ -4075,11 +4006,8 @@ gfloat webkit_web_view_get_zoom_level(WebKitWebView* webView) if (!frame) return 1.0f; - FrameView* view = frame->view(); - if (!view) - return 1; - - return view->zoomFactor(); + WebKitWebViewPrivate* priv = webView->priv; + return priv->zoomFullContent ? frame->pageZoomFactor() : frame->textZoomFactor(); } static void webkit_web_view_apply_zoom_level(WebKitWebView* webView, gfloat zoomLevel) @@ -4088,12 +4016,11 @@ static void webkit_web_view_apply_zoom_level(WebKitWebView* webView, gfloat zoom if (!frame) return; - FrameView* view = frame->view(); - if (!view) - return; - WebKitWebViewPrivate* priv = webView->priv; - view->setZoomFactor(zoomLevel, priv->zoomFullContent ? ZoomPage : ZoomTextOnly); + if (priv->zoomFullContent) + frame->setPageZoomFactor(zoomLevel); + else + frame->setTextZoomFactor(zoomLevel); } /** @@ -4133,7 +4060,7 @@ void webkit_web_view_zoom_in(WebKitWebView* webView) WebKitWebViewPrivate* priv = webView->priv; gfloat zoomMultiplierRatio; - g_object_get(priv->webSettings, "zoom-step", &zoomMultiplierRatio, NULL); + g_object_get(priv->webSettings.get(), "zoom-step", &zoomMultiplierRatio, NULL); webkit_web_view_set_zoom_level(webView, webkit_web_view_get_zoom_level(webView) + zoomMultiplierRatio); } @@ -4154,7 +4081,7 @@ void webkit_web_view_zoom_out(WebKitWebView* webView) WebKitWebViewPrivate* priv = webView->priv; gfloat zoomMultiplierRatio; - g_object_get(priv->webSettings, "zoom-step", &zoomMultiplierRatio, NULL); + g_object_get(priv->webSettings.get(), "zoom-step", &zoomMultiplierRatio, NULL); webkit_web_view_set_zoom_level(webView, webkit_web_view_get_zoom_level(webView) - zoomMultiplierRatio); } @@ -4196,8 +4123,17 @@ void webkit_web_view_set_full_content_zoom(WebKitWebView* webView, gboolean zoom if (priv->zoomFullContent == zoomFullContent) return; + Frame* frame = core(webView)->mainFrame(); + if (!frame) + return; + + gfloat zoomLevel = priv->zoomFullContent ? frame->pageZoomFactor() : frame->textZoomFactor(); + priv->zoomFullContent = zoomFullContent; - webkit_web_view_apply_zoom_level(webView, webkit_web_view_get_zoom_level(webView)); + if (priv->zoomFullContent) + frame->setPageAndTextZoomFactors(zoomLevel, 1); + else + frame->setPageAndTextZoomFactors(1, zoomLevel); g_object_notify(G_OBJECT(webView), "full-content-zoom"); } @@ -4246,16 +4182,11 @@ gdouble webkit_web_view_get_progress(WebKitWebView* webView) const gchar* webkit_web_view_get_encoding(WebKitWebView* webView) { g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); - String encoding = core(webView)->mainFrame()->loader()->writer()->encoding(); - - if (!encoding.isEmpty()) { - WebKitWebViewPrivate* priv = webView->priv; - g_free(priv->encoding); - priv->encoding = g_strdup(encoding.utf8().data()); - return priv->encoding; - } else - return NULL; + if (encoding.isEmpty()) + return 0; + webView->priv->encoding = encoding.utf8(); + return webView->priv->encoding.data(); } /** @@ -4289,16 +4220,11 @@ void webkit_web_view_set_custom_encoding(WebKitWebView* webView, const char* enc const char* webkit_web_view_get_custom_encoding(WebKitWebView* webView) { g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); - String overrideEncoding = core(webView)->mainFrame()->loader()->documentLoader()->overrideEncoding(); - - if (!overrideEncoding.isEmpty()) { - WebKitWebViewPrivate* priv = webView->priv; - g_free (priv->customEncoding); - priv->customEncoding = g_strdup(overrideEncoding.utf8().data()); - return priv->customEncoding; - } else - return NULL; + if (overrideEncoding.isEmpty()) + return 0; + webView->priv->customEncoding = overrideEncoding.utf8(); + return webView->priv->customEncoding.data(); } /** @@ -4520,27 +4446,26 @@ void webkit_web_view_add_resource(WebKitWebView* webView, const char* identifier WebKitWebViewPrivate* priv = webView->priv; if (!priv->mainResource) { - priv->mainResource = webResource; - priv->mainResourceIdentifier = g_strdup(identifier); + priv->mainResource = adoptPlatformRef(webResource); + priv->mainResourceIdentifier = identifier; return; } - g_hash_table_insert(priv->subResources, g_strdup(identifier), webResource); + g_hash_table_insert(priv->subResources.get(), g_strdup(identifier), webResource); } WebKitWebResource* webkit_web_view_get_resource(WebKitWebView* webView, char* identifier) { WebKitWebViewPrivate* priv = webView->priv; - gpointer webResource = NULL; - - gboolean resourceFound = g_hash_table_lookup_extended(priv->subResources, identifier, NULL, &webResource); + gpointer webResource = 0; + gboolean resourceFound = g_hash_table_lookup_extended(priv->subResources.get(), identifier, NULL, &webResource); // The only resource we do not store in this hash table is the // main! If we did not find a request, it probably means the load // has been interrupted while while a resource was still being // loaded. - if (!resourceFound && !g_str_equal(identifier, priv->mainResourceIdentifier)) - return NULL; + if (!resourceFound && !g_str_equal(identifier, priv->mainResourceIdentifier.data())) + return 0; if (!webResource) return webkit_web_view_get_main_resource(webView); @@ -4550,30 +4475,24 @@ WebKitWebResource* webkit_web_view_get_resource(WebKitWebView* webView, char* id WebKitWebResource* webkit_web_view_get_main_resource(WebKitWebView* webView) { - return webView->priv->mainResource; + return webView->priv->mainResource.get(); } void webkit_web_view_clear_resources(WebKitWebView* webView) { WebKitWebViewPrivate* priv = webView->priv; - - g_free(priv->mainResourceIdentifier); - priv->mainResourceIdentifier = NULL; - - if (priv->mainResource) { - g_object_unref(priv->mainResource); - priv->mainResource = NULL; - } + priv->mainResourceIdentifier = ""; + priv->mainResource = 0; if (priv->subResources) - g_hash_table_remove_all(priv->subResources); + g_hash_table_remove_all(priv->subResources.get()); } GList* webkit_web_view_get_subresources(WebKitWebView* webView) { WebKitWebViewPrivate* priv = webView->priv; - GList* subResources = g_hash_table_get_values(priv->subResources); - return g_list_remove(subResources, priv->mainResource); + GList* subResources = g_hash_table_get_values(priv->subResources.get()); + return g_list_remove(subResources, priv->mainResource.get()); } /* From EventHandler.cpp */ @@ -4589,12 +4508,11 @@ void webkit_web_view_set_tooltip_text(WebKitWebView* webView, const char* toolti { #if GTK_CHECK_VERSION(2, 12, 0) WebKitWebViewPrivate* priv = webView->priv; - g_free(priv->tooltipText); if (tooltip && *tooltip != '\0') { - priv->tooltipText = g_strdup(tooltip); + priv->tooltipText = tooltip; gtk_widget_set_has_tooltip(GTK_WIDGET(webView), TRUE); } else { - priv->tooltipText = 0; + priv->tooltipText = ""; gtk_widget_set_has_tooltip(GTK_WIDGET(webView), FALSE); } @@ -4646,15 +4564,10 @@ WebKitHitTestResult* webkit_web_view_get_hit_test_result(WebKitWebView* webView, */ G_CONST_RETURN gchar* webkit_web_view_get_icon_uri(WebKitWebView* webView) { - g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), NULL); - - Page* corePage = core(webView); - String iconURL = iconDatabase()->iconURLForPageURL(corePage->mainFrame()->loader()->url().prettyURL()); - - WebKitWebViewPrivate* priv = webView->priv; - g_free(priv->iconURI); - priv->iconURI = g_strdup(iconURL.utf8().data()); - return priv->iconURI; + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); + String iconURL = iconDatabase()->iconURLForPageURL(core(webView)->mainFrame()->loader()->url().prettyURL()); + webView->priv->iconURI = iconURL.utf8(); + return webView->priv->iconURI.data(); } /** @@ -4805,3 +4718,17 @@ gboolean webkit_web_view_is_command_enabled(WebKitWebView* webView, const gchar* return core(webView)->focusController()->focusedOrMainFrame()->editor()->command(name).isEnabled(); } + +GtkMenu* webkit_web_view_get_context_menu(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); + +#if ENABLE(CONTEXT_MENUS) + ContextMenu* menu = core(webView)->contextMenuController()->contextMenu(); + if (!menu) + return 0; + return menu->platformDescription(); +#else + return 0; +#endif +} |