X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1f7c17f4054a0ea33551262b57061be4847d58ff..30a7e91fb03558a4ffb6c5c6206ea25e53905e22:/src/gtk/webview_webkit.cpp diff --git a/src/gtk/webview_webkit.cpp b/src/gtk/webview_webkit.cpp index ea5abe7c0a..faaf4be807 100644 --- a/src/gtk/webview_webkit.cpp +++ b/src/gtk/webview_webkit.cpp @@ -2,7 +2,6 @@ // Name: src/gtk/webview_webkit.cpp // Purpose: GTK WebKit backend for web view component // Author: Marianne Gagnon, Robert Roebling -// Id: $Id$ // Copyright: (c) 2010 Marianne Gagnon, 1998 Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -18,6 +17,7 @@ #include "wx/gtk/private.h" #include "wx/filesys.h" #include "wx/base64.h" +#include "wx/log.h" #include // ---------------------------------------------------------------------------- @@ -32,11 +32,6 @@ wxgtk_webview_webkit_load_status(GtkWidget* widget, GParamSpec*, wxWebViewWebKit *webKitCtrl) { - // We can be called from webkit_web_view_dispose() during the window - // destruction, don't use half-destroyed object in this case. - if ( webKitCtrl->IsBeingDeleted() ) - return; - wxString url = webKitCtrl->GetCurrentURL(); WebKitLoadStatus status; @@ -51,7 +46,8 @@ wxgtk_webview_webkit_load_status(GtkWidget* widget, //We have to check if we are actually storing history //If the item isn't added we add it ourselves, it isn't added otherwise //with a custom scheme. - if(WEBKIT_IS_WEB_HISTORY_ITEM(item) && webkit_web_history_item_get_uri(item) != url) + if(!item || (WEBKIT_IS_WEB_HISTORY_ITEM(item) && + webkit_web_history_item_get_uri(item) != url)) { WebKitWebHistoryItem* newitem = webkit_web_history_item_new_with_data @@ -63,7 +59,7 @@ wxgtk_webview_webkit_load_status(GtkWidget* widget, } webKitCtrl->m_busy = false; - wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_LOADED, + wxWebViewEvent event(wxEVT_WEBVIEW_LOADED, webKitCtrl->GetId(), url, target); @@ -73,7 +69,7 @@ wxgtk_webview_webkit_load_status(GtkWidget* widget, else if (status == WEBKIT_LOAD_COMMITTED) { webKitCtrl->m_busy = true; - wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATED, + wxWebViewEvent event(wxEVT_WEBVIEW_NAVIGATED, webKitCtrl->GetId(), url, target); @@ -90,6 +86,26 @@ wxgtk_webview_webkit_navigation(WebKitWebView *, WebKitWebPolicyDecision *policy_decision, wxWebViewWebKit *webKitCtrl) { + const gchar* uri = webkit_network_request_get_uri(request); + wxString target = webkit_web_frame_get_name (frame); + + //If m_creating is true then we are the result of a new window + //and so we need to send the event and veto the load + if(webKitCtrl->m_creating) + { + webKitCtrl->m_creating = false; + wxWebViewEvent event(wxEVT_WEBVIEW_NEWWINDOW, + webKitCtrl->GetId(), + wxString(uri, wxConvUTF8), + target); + + if(webKitCtrl && webKitCtrl->GetEventHandler()) + webKitCtrl->GetEventHandler()->ProcessEvent(event); + + webkit_web_policy_decision_ignore(policy_decision); + return TRUE; + } + if(webKitCtrl->m_guard) { webKitCtrl->m_guard = false; @@ -102,10 +118,7 @@ wxgtk_webview_webkit_navigation(WebKitWebView *, webKitCtrl->m_busy = true; - const gchar* uri = webkit_network_request_get_uri(request); - - wxString target = webkit_web_frame_get_name (frame); - wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NAVIGATING, + wxWebViewEvent event(wxEVT_WEBVIEW_NAVIGATING, webKitCtrl->GetId(), wxString( uri, wxConvUTF8 ), target); @@ -159,7 +172,7 @@ wxgtk_webview_webkit_error(WebKitWebView*, wxWebViewWebKit* webKitWindow) { webKitWindow->m_busy = false; - wxWebViewNavigationError type = wxWEB_NAV_ERR_OTHER; + wxWebViewNavigationError type = wxWEBVIEW_NAV_ERR_OTHER; GError* error = (GError*)web_error; wxString description(error->message, wxConvUTF8); @@ -169,12 +182,12 @@ wxgtk_webview_webkit_error(WebKitWebView*, switch (error->code) { case SOUP_STATUS_CANCELLED: - type = wxWEB_NAV_ERR_USER_CANCELLED; + type = wxWEBVIEW_NAV_ERR_USER_CANCELLED; break; case SOUP_STATUS_CANT_RESOLVE: case SOUP_STATUS_NOT_FOUND: - type = wxWEB_NAV_ERR_NOT_FOUND; + type = wxWEBVIEW_NAV_ERR_NOT_FOUND; break; case SOUP_STATUS_CANT_RESOLVE_PROXY: @@ -182,54 +195,54 @@ wxgtk_webview_webkit_error(WebKitWebView*, case SOUP_STATUS_CANT_CONNECT_PROXY: case SOUP_STATUS_SSL_FAILED: case SOUP_STATUS_IO_ERROR: - type = wxWEB_NAV_ERR_CONNECTION; + type = wxWEBVIEW_NAV_ERR_CONNECTION; break; case SOUP_STATUS_MALFORMED: //case SOUP_STATUS_TOO_MANY_REDIRECTS: - type = wxWEB_NAV_ERR_REQUEST; + type = wxWEBVIEW_NAV_ERR_REQUEST; break; //case SOUP_STATUS_NO_CONTENT: //case SOUP_STATUS_RESET_CONTENT: case SOUP_STATUS_BAD_REQUEST: - type = wxWEB_NAV_ERR_REQUEST; + type = wxWEBVIEW_NAV_ERR_REQUEST; break; case SOUP_STATUS_UNAUTHORIZED: case SOUP_STATUS_FORBIDDEN: - type = wxWEB_NAV_ERR_AUTH; + type = wxWEBVIEW_NAV_ERR_AUTH; break; case SOUP_STATUS_METHOD_NOT_ALLOWED: case SOUP_STATUS_NOT_ACCEPTABLE: - type = wxWEB_NAV_ERR_SECURITY; + type = wxWEBVIEW_NAV_ERR_SECURITY; break; case SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED: - type = wxWEB_NAV_ERR_AUTH; + type = wxWEBVIEW_NAV_ERR_AUTH; break; case SOUP_STATUS_REQUEST_TIMEOUT: - type = wxWEB_NAV_ERR_CONNECTION; + type = wxWEBVIEW_NAV_ERR_CONNECTION; break; //case SOUP_STATUS_PAYMENT_REQUIRED: case SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE: case SOUP_STATUS_REQUEST_URI_TOO_LONG: case SOUP_STATUS_UNSUPPORTED_MEDIA_TYPE: - type = wxWEB_NAV_ERR_REQUEST; + type = wxWEBVIEW_NAV_ERR_REQUEST; break; case SOUP_STATUS_BAD_GATEWAY: case SOUP_STATUS_SERVICE_UNAVAILABLE: case SOUP_STATUS_GATEWAY_TIMEOUT: - type = wxWEB_NAV_ERR_CONNECTION; + type = wxWEBVIEW_NAV_ERR_CONNECTION; break; case SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED: - type = wxWEB_NAV_ERR_REQUEST; + type = wxWEBVIEW_NAV_ERR_REQUEST; break; //case SOUP_STATUS_INSUFFICIENT_STORAGE: //case SOUP_STATUS_NOT_EXTENDED: @@ -244,15 +257,15 @@ wxgtk_webview_webkit_error(WebKitWebView*, //WEBKIT_NETWORK_ERROR_TRANSPORT: case WEBKIT_NETWORK_ERROR_UNKNOWN_PROTOCOL: - type = wxWEB_NAV_ERR_REQUEST; + type = wxWEBVIEW_NAV_ERR_REQUEST; break; case WEBKIT_NETWORK_ERROR_CANCELLED: - type = wxWEB_NAV_ERR_USER_CANCELLED; + type = wxWEBVIEW_NAV_ERR_USER_CANCELLED; break; case WEBKIT_NETWORK_ERROR_FILE_DOES_NOT_EXIST: - type = wxWEB_NAV_ERR_NOT_FOUND; + type = wxWEBVIEW_NAV_ERR_NOT_FOUND; break; } } @@ -266,7 +279,7 @@ wxgtk_webview_webkit_error(WebKitWebView*, //case WEBKIT_POLICY_ERROR_CANNOT_SHOW_URL: //case WEBKIT_POLICY_ERROR_FRAME_LOAD_INTERRUPTED_BY_POLICY_CHANGE: case WEBKIT_POLICY_ERROR_CANNOT_USE_RESTRICTED_PORT: - type = wxWEB_NAV_ERR_SECURITY; + type = wxWEBVIEW_NAV_ERR_SECURITY; break; } } @@ -278,7 +291,7 @@ wxgtk_webview_webkit_error(WebKitWebView*, } */ - wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_ERROR, + wxWebViewEvent event(wxEVT_WEBVIEW_ERROR, webKitWindow->GetId(), uri, ""); event.SetString(description); @@ -303,7 +316,7 @@ wxgtk_webview_webkit_new_window(WebKitWebView*, const gchar* uri = webkit_network_request_get_uri(request); wxString target = webkit_web_frame_get_name (frame); - wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_NEWWINDOW, + wxWebViewEvent event(wxEVT_WEBVIEW_NEWWINDOW, webKitCtrl->GetId(), wxString( uri, wxConvUTF8 ), target); @@ -322,7 +335,7 @@ wxgtk_webview_webkit_title_changed(WebKitWebView*, gchar *title, wxWebViewWebKit *webKitCtrl) { - wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED, + wxWebViewEvent event(wxEVT_WEBVIEW_TITLE_CHANGED, webKitCtrl->GetId(), webKitCtrl->GetCurrentURL(), ""); @@ -382,6 +395,34 @@ wxgtk_webview_webkit_resource_req(WebKitWebView *, } } +#if WEBKIT_CHECK_VERSION(1, 10, 0) + +static gboolean +wxgtk_webview_webkit_context_menu(WebKitWebView *, + GtkWidget *, + WebKitHitTestResult *, + gboolean, + wxWebViewWebKit *webKitCtrl) +{ + if(webKitCtrl->IsContextMenuEnabled()) + return FALSE; + else + return TRUE; +} + +#endif + +static WebKitWebView* +wxgtk_webview_webkit_create_webview(WebKitWebView *web_view, + WebKitWebFrame *frame, + wxWebViewWebKit *webKitCtrl) +{ + //As we do not know the uri being loaded at this point allow the load to + //continue and catch it in navigation-policy-decision-requested + webKitCtrl->m_creating = true; + return web_view; +} + } // extern "C" //----------------------------------------------------------------------------- @@ -390,6 +431,11 @@ wxgtk_webview_webkit_resource_req(WebKitWebView *, wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit, wxWebView); +wxWebViewWebKit::wxWebViewWebKit() +{ + m_web_view = NULL; +} + bool wxWebViewWebKit::Create(wxWindow *parent, wxWindowID id, const wxString &url, @@ -400,6 +446,8 @@ bool wxWebViewWebKit::Create(wxWindow *parent, { m_busy = false; m_guard = false; + m_creating = false; + FindClear(); // We currently unconditionally impose scrolling in both directions as it's // necessary to show arbitrary pages. @@ -431,6 +479,14 @@ bool wxWebViewWebKit::Create(wxWindow *parent, g_signal_connect_after(m_web_view, "resource-request-starting", G_CALLBACK(wxgtk_webview_webkit_resource_req), this); + +#if WEBKIT_CHECK_VERSION(1, 10, 0) + g_signal_connect_after(m_web_view, "context-menu", + G_CALLBACK(wxgtk_webview_webkit_context_menu), this); +#endif + + g_signal_connect_after(m_web_view, "create-web-view", + G_CALLBACK(wxgtk_webview_webkit_create_webview), this); m_parent->DoAddChild( this ); @@ -454,11 +510,8 @@ bool wxWebViewWebKit::Create(wxWindow *parent, wxWebViewWebKit::~wxWebViewWebKit() { - // The main goal here is to set m_isBeingDeleted to true to avoid the use - // of this -- already half-destroyed -- object from WebKit callbacks, but - // just setting it would prevent wxWindowDestroyEvent from being sent, so - // send it now instead. - SendDestroyEvent(); + if (m_web_view) + GTKDisconnect(m_web_view); } bool wxWebViewWebKit::Enable( bool enable ) @@ -508,7 +561,7 @@ void wxWebViewWebKit::Stop() void wxWebViewWebKit::Reload(wxWebViewReloadFlags flags) { - if (flags & wxWEB_VIEW_RELOAD_NO_CACHE) + if (flags & wxWEBVIEW_RELOAD_NO_CACHE) { webkit_web_view_reload_bypass_cache(m_web_view); } @@ -701,28 +754,28 @@ wxWebViewZoom wxWebViewWebKit::GetZoom() const // arbitrary way to map float zoom to our common zoom enum if (zoom <= 0.65) { - return wxWEB_VIEW_ZOOM_TINY; + return wxWEBVIEW_ZOOM_TINY; } else if (zoom > 0.65 && zoom <= 0.90) { - return wxWEB_VIEW_ZOOM_SMALL; + return wxWEBVIEW_ZOOM_SMALL; } else if (zoom > 0.90 && zoom <= 1.15) { - return wxWEB_VIEW_ZOOM_MEDIUM; + return wxWEBVIEW_ZOOM_MEDIUM; } else if (zoom > 1.15 && zoom <= 1.45) { - return wxWEB_VIEW_ZOOM_LARGE; + return wxWEBVIEW_ZOOM_LARGE; } else if (zoom > 1.45) { - return wxWEB_VIEW_ZOOM_LARGEST; + return wxWEBVIEW_ZOOM_LARGEST; } // to shut up compilers, this can never be reached logically wxASSERT(false); - return wxWEB_VIEW_ZOOM_MEDIUM; + return wxWEBVIEW_ZOOM_MEDIUM; } @@ -731,23 +784,23 @@ void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom) // arbitrary way to map our common zoom enum to float zoom switch (zoom) { - case wxWEB_VIEW_ZOOM_TINY: + case wxWEBVIEW_ZOOM_TINY: SetWebkitZoom(0.6f); break; - case wxWEB_VIEW_ZOOM_SMALL: + case wxWEBVIEW_ZOOM_SMALL: SetWebkitZoom(0.8f); break; - case wxWEB_VIEW_ZOOM_MEDIUM: + case wxWEBVIEW_ZOOM_MEDIUM: SetWebkitZoom(1.0f); break; - case wxWEB_VIEW_ZOOM_LARGE: + case wxWEBVIEW_ZOOM_LARGE: SetWebkitZoom(1.3); break; - case wxWEB_VIEW_ZOOM_LARGEST: + case wxWEBVIEW_ZOOM_LARGEST: SetWebkitZoom(1.6); break; @@ -759,7 +812,7 @@ void wxWebViewWebKit::SetZoom(wxWebViewZoom zoom) void wxWebViewWebKit::SetZoomType(wxWebViewZoomType type) { webkit_web_view_set_full_content_zoom(m_web_view, - (type == wxWEB_VIEW_ZOOM_TYPE_LAYOUT ? + (type == wxWEBVIEW_ZOOM_TYPE_LAYOUT ? TRUE : FALSE)); } @@ -767,8 +820,8 @@ wxWebViewZoomType wxWebViewWebKit::GetZoomType() const { gboolean fczoom = webkit_web_view_get_full_content_zoom(m_web_view); - if (fczoom) return wxWEB_VIEW_ZOOM_TYPE_LAYOUT; - else return wxWEB_VIEW_ZOOM_TYPE_TEXT; + if (fczoom) return wxWEBVIEW_ZOOM_TYPE_LAYOUT; + else return wxWEBVIEW_ZOOM_TYPE_TEXT; } bool wxWebViewWebKit::CanSetZoomType(wxWebViewZoomType) const @@ -927,11 +980,94 @@ void wxWebViewWebKit::RegisterHandler(wxSharedPtr handler) m_handlerList.push_back(handler); } +void wxWebViewWebKit::EnableContextMenu(bool enable) +{ +#if !WEBKIT_CHECK_VERSION(1, 10, 0) //If we are using an older version + g_object_set(webkit_web_view_get_settings(m_web_view), + "enable-default-context-menu", enable, NULL); +#endif + wxWebView::EnableContextMenu(enable); +} + +long wxWebViewWebKit::Find(const wxString& text, int flags) +{ + bool newSearch = false; + if(text != m_findText || + (flags & wxWEBVIEW_FIND_MATCH_CASE) != (m_findFlags & wxWEBVIEW_FIND_MATCH_CASE)) + { + newSearch = true; + //If it is a new search we need to clear existing highlights + webkit_web_view_unmark_text_matches(m_web_view); + webkit_web_view_set_highlight_text_matches(m_web_view, false); + } + + m_findFlags = flags; + m_findText = text; + + //If the search string is empty then we clear any selection and highlight + if(text == "") + { + webkit_web_view_unmark_text_matches(m_web_view); + webkit_web_view_set_highlight_text_matches(m_web_view, false); + ClearSelection(); + return wxNOT_FOUND; + } + + bool wrap = false, matchCase = false, forward = true; + if(flags & wxWEBVIEW_FIND_WRAP) + wrap = true; + if(flags & wxWEBVIEW_FIND_MATCH_CASE) + matchCase = true; + if(flags & wxWEBVIEW_FIND_BACKWARDS) + forward = false; + + if(newSearch) + { + //Initially we mark the matches to know how many we have + m_findCount = webkit_web_view_mark_text_matches(m_web_view, wxGTK_CONV(text), matchCase, 0); + //In this case we return early to match IE behaviour + m_findPosition = -1; + return m_findCount; + } + else + { + if(forward) + m_findPosition++; + else + m_findPosition--; + if(m_findPosition < 0) + m_findPosition += m_findCount; + if(m_findPosition > m_findCount) + m_findPosition -= m_findCount; + } + + //Highlight them if needed + bool highlight = flags & wxWEBVIEW_FIND_HIGHLIGHT_RESULT ? true : false; + webkit_web_view_set_highlight_text_matches(m_web_view, highlight); + + if(!webkit_web_view_search_text(m_web_view, wxGTK_CONV(text), matchCase, forward, wrap)) + { + m_findPosition = -1; + ClearSelection(); + return wxNOT_FOUND; + } + wxLogMessage(wxString::Format("Returning %d", m_findPosition)); + return newSearch ? m_findCount : m_findPosition; +} + +void wxWebViewWebKit::FindClear() +{ + m_findCount = 0; + m_findFlags = 0; + m_findText = ""; + m_findPosition = -1; +} + // static wxVisualAttributes wxWebViewWebKit::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) { - return GetDefaultAttributesFromGTKWidget(webkit_web_view_new); + return GetDefaultAttributesFromGTKWidget(webkit_web_view_new()); }