X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/906c935a80b10d53cecf57f71ab5f3f4f1d529ec..fe104ff925ac53779d25280112401874089276b0:/src/gtk/webview_webkit.cpp diff --git a/src/gtk/webview_webkit.cpp b/src/gtk/webview_webkit.cpp index 36b3eace96..d4de44070c 100644 --- a/src/gtk/webview_webkit.cpp +++ b/src/gtk/webview_webkit.cpp @@ -16,6 +16,8 @@ #include "wx/gtk/webview_webkit.h" #include "wx/gtk/control.h" #include "wx/gtk/private.h" +#include "wx/filesys.h" +#include "wx/base64.h" #include "webkit/webkit.h" // ---------------------------------------------------------------------------- @@ -62,13 +64,23 @@ wxgtk_webview_webkit_load_status(GtkWidget* widget, } static gboolean -wxgtk_webview_webkit_navigation(WebKitWebView*, +wxgtk_webview_webkit_navigation(WebKitWebView *, WebKitWebFrame *frame, WebKitNetworkRequest *request, - WebKitWebNavigationAction*, + WebKitWebNavigationAction *, WebKitWebPolicyDecision *policy_decision, wxWebViewWebKit *webKitCtrl) { + if(webKitCtrl->m_guard) + { + webKitCtrl->m_guard = false; + //We set this to make sure that we don't try to load the page again from + //the resource request callback + webKitCtrl->m_vfsurl = webkit_network_request_get_uri(request); + webkit_web_policy_decision_use(policy_decision); + return FALSE; + } + webKitCtrl->m_busy = true; const gchar* uri = webkit_network_request_get_uri(request); @@ -91,6 +103,32 @@ wxgtk_webview_webkit_navigation(WebKitWebView*, } else { + wxString wxuri = uri; + wxSharedPtr handler; + wxVector > hanlders = webKitCtrl->GetHandlers(); + //We are not vetoed so see if we match one of the additional handlers + for(wxVector >::iterator it = hanlders.begin(); + it != hanlders.end(); ++it) + { + if(wxuri.substr(0, (*it)->GetName().length()) == (*it)->GetName()) + { + handler = (*it); + } + } + //If we found a handler we can then use it to load the file directly + //ourselves + if(handler) + { + webKitCtrl->m_guard = true; + wxFSFile* file = handler->GetFile(wxuri); + if(file) + { + webKitCtrl->SetPage(*file->GetStream(), wxuri); + } + //We need to throw some sort of error here if file is NULL + webkit_web_policy_decision_ignore(policy_decision); + return TRUE; + } return FALSE; } } @@ -258,15 +296,76 @@ wxgtk_webview_webkit_new_window(WebKitWebView*, if (webKitCtrl && webKitCtrl->GetEventHandler()) webKitCtrl->GetEventHandler()->ProcessEvent(thisEvent); - if (thisEvent.IsVetoed()) + //We always want the user to handle this themselves + webkit_web_policy_decision_ignore(policy_decision); + return TRUE; +} + +static void +wxgtk_webview_webkit_title_changed(WebKitWebView*, + WebKitWebFrame*, + gchar *title, + wxWebViewWebKit *webKitCtrl) +{ + wxWebNavigationEvent thisEvent(wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED, + webKitCtrl->GetId(), + webKitCtrl->GetCurrentURL(), + "", + true); + thisEvent.SetString(wxString(title, wxConvUTF8)); + + if (webKitCtrl && webKitCtrl->GetEventHandler()) + webKitCtrl->GetEventHandler()->ProcessEvent(thisEvent); + +} + +static void +wxgtk_webview_webkit_resource_req(WebKitWebView *, + WebKitWebFrame *, + WebKitWebResource *, + WebKitNetworkRequest *request, + WebKitNetworkResponse *, + wxWebViewWebKit *webKitCtrl) +{ + wxString uri = webkit_network_request_get_uri(request); + + wxSharedPtr handler; + wxVector > hanlders = webKitCtrl->GetHandlers(); + + //We are not vetoed so see if we match one of the additional handlers + for(wxVector >::iterator it = hanlders.begin(); + it != hanlders.end(); ++it) { - webkit_web_policy_decision_ignore(policy_decision); + if(uri.substr(0, (*it)->GetName().length()) == (*it)->GetName()) + { + handler = (*it); + } } - else + //If we found a handler we can then use it to load the file directly + //ourselves + if(handler) { - webkit_web_policy_decision_use(policy_decision); + //If it is requsting the page itself then return as we have already + //loaded it from the archive + if(webKitCtrl->m_vfsurl == uri) + return; + + wxFSFile* file = handler->GetFile(uri); + if(file) + { + //We load the data into a data url to save it being written out again + size_t size = file->GetStream()->GetLength(); + char *buffer = new char[size]; + file->GetStream()->Read(buffer, size); + wxString data = wxBase64Encode(buffer, size); + delete[] buffer; + wxString mime = file->GetMimeType(); + wxString path = "data:" + mime + ";base64," + data; + //Then we can redirect the call + webkit_network_request_set_uri(request, path); + } + } - return TRUE; } } // extern "C" @@ -275,7 +374,7 @@ wxgtk_webview_webkit_new_window(WebKitWebView*, // wxWebViewWebKit //----------------------------------------------------------------------------- -//IMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit, wxControl) +wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit, wxWebView); bool wxWebViewWebKit::Create(wxWindow *parent, wxWindowID id, @@ -287,6 +386,7 @@ bool wxWebViewWebKit::Create(wxWindow *parent, { m_ready = false; m_busy = false; + m_guard = false; if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name )) @@ -320,6 +420,12 @@ bool wxWebViewWebKit::Create(wxWindow *parent, g_signal_connect_after(web_view, "new-window-policy-decision-requested", G_CALLBACK(wxgtk_webview_webkit_new_window), this); + g_signal_connect_after(web_view, "title-changed", + G_CALLBACK(wxgtk_webview_webkit_title_changed), this); + + g_signal_connect_after(web_view, "resource-request-starting", + G_CALLBACK(wxgtk_webview_webkit_resource_req), this); + m_parent->DoAddChild( this ); PostCreation(size); @@ -454,11 +560,12 @@ wxVector > wxWebViewWebKit::GetBackwardHistory() for(int i = g_list_length(list) - 1; i >= 0 ; i--) { WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)g_list_nth_data(list, i); - wxSharedPtr item(new wxWebHistoryItem( - webkit_web_history_item_get_uri(gtkitem), - webkit_web_history_item_get_title(gtkitem))); + wxWebHistoryItem* wxitem = new wxWebHistoryItem( + webkit_web_history_item_get_uri(gtkitem), + webkit_web_history_item_get_title(gtkitem)); + wxitem->m_histItem = gtkitem; + wxSharedPtr item(wxitem); backhist.push_back(item); - m_historyMap[item] = gtkitem; } return backhist; } @@ -473,23 +580,25 @@ wxVector > wxWebViewWebKit::GetForwardHistory() for(guint i = 0; i < g_list_length(list); i++) { WebKitWebHistoryItem* gtkitem = (WebKitWebHistoryItem*)g_list_nth_data(list, i); - wxSharedPtr item(new wxWebHistoryItem( - webkit_web_history_item_get_uri(gtkitem), - webkit_web_history_item_get_title(gtkitem))); + wxWebHistoryItem* wxitem = new wxWebHistoryItem( + webkit_web_history_item_get_uri(gtkitem), + webkit_web_history_item_get_title(gtkitem)); + wxitem->m_histItem = gtkitem; + wxSharedPtr item(wxitem); forwardhist.push_back(item); - m_historyMap[item] = gtkitem; } return forwardhist; } void wxWebViewWebKit::LoadHistoryItem(wxSharedPtr item) { - WebKitWebHistoryItem* gtkitem = m_historyMap[item]; + WebKitWebHistoryItem* gtkitem = item->m_histItem; if(gtkitem) { WebKitWebBackForwardList* history; history = webkit_web_view_get_back_forward_list(WEBKIT_WEB_VIEW(web_view)); - webkit_web_back_forward_list_go_to_item(history, gtkitem); + webkit_web_back_forward_list_go_to_item(WEBKIT_WEB_BACK_FORWARD_LIST(history), + WEBKIT_WEB_HISTORY_ITEM(gtkitem)); } } @@ -802,6 +911,11 @@ void wxWebViewWebKit::RunScript(const wxString& javascript) javascript.mb_str(wxConvUTF8)); } +void wxWebViewWebKit::RegisterHandler(wxSharedPtr handler) +{ + m_handlerList.push_back(handler); +} + // static wxVisualAttributes wxWebViewWebKit::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))