X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e1efca652844273c3e8d32c7e5f442b87e455ca7..ad653fa23069c5d9378247084f03c9a718c3ad62:/src/common/webview.cpp diff --git a/src/common/webview.cpp b/src/common/webview.cpp index 9c0c88f0ba..4b2e7dc8ce 100644 --- a/src/common/webview.cpp +++ b/src/common/webview.cpp @@ -3,14 +3,14 @@ // Purpose: Common interface and events for web view component // Author: Marianne Gagnon // Id: $Id$ -// Copyright: (c) 2010 Marianne Gagnon +// Copyright: (c) 2010 Marianne Gagnon, 2011 Steven Lamerton // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#if wxUSE_WEB +#if wxUSE_WEBVIEW #if defined(__BORLANDC__) #pragma hdrstop @@ -18,289 +18,95 @@ #include "wx/webview.h" +#if defined(__WXOSX_COCOA__) || defined(__WXOSX_CARBON__) #include "wx/osx/webview_webkit.h" +#elif defined(__WXGTK__) #include "wx/gtk/webview_webkit.h" +#elif defined(__WXMSW__) #include "wx/msw/webview_ie.h" -#include "wx/filesys.h" -#include "wx/tokenzr.h" +#endif // DLL options compatibility check: #include "wx/app.h" -WX_CHECK_BUILD_OPTIONS("wxWEB") - -extern WXDLLIMPEXP_DATA_WEB(const char) wxWebViewNameStr[] = "wxWebView"; -extern WXDLLIMPEXP_DATA_WEB(const char) wxWebViewDefaultURLStr[] = "about:blank"; +WX_CHECK_BUILD_OPTIONS("wxWEBVIEW") -IMPLEMENT_DYNAMIC_CLASS(wxWebNavigationEvent, wxCommandEvent) +extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewNameStr[] = "wxWebView"; +extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewDefaultURLStr[] = "about:blank"; +extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewBackendIE[] = "wxWebViewIE"; +extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewBackendWebKit[] = "wxWebViewWebKit"; -wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_NAVIGATING, wxWebNavigationEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_NAVIGATED, wxWebNavigationEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_LOADED, wxWebNavigationEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_ERROR, wxWebNavigationEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_NEWWINDOW, wxWebNavigationEvent ); - -//Taken from wx/filesys.cpp -static wxString EscapeFileNameCharsInURL(const char *in) -{ - wxString s; +#ifdef __WXMSW__ +extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewBackendDefault[] = "wxWebViewIE"; +#else +extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewBackendDefault[] = "wxWebViewWebKit"; +#endif - for ( const unsigned char *p = (const unsigned char*)in; *p; ++p ) - { - const unsigned char c = *p; +wxIMPLEMENT_ABSTRACT_CLASS(wxWebView, wxControl); +wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewEvent, wxCommandEvent); - if ( c == '/' || c == '-' || c == '.' || c == '_' || c == '~' || - (c >= '0' && c <= '9') || - (c >= 'a' && c <= 'z') || - (c >= 'A' && c <= 'Z') ) - { - s << c; - } - else - { - s << wxString::Format("%%%02x", c); - } - } +wxDEFINE_EVENT( wxEVT_WEBVIEW_NAVIGATING, wxWebViewEvent ); +wxDEFINE_EVENT( wxEVT_WEBVIEW_NAVIGATED, wxWebViewEvent ); +wxDEFINE_EVENT( wxEVT_WEBVIEW_LOADED, wxWebViewEvent ); +wxDEFINE_EVENT( wxEVT_WEBVIEW_ERROR, wxWebViewEvent ); +wxDEFINE_EVENT( wxEVT_WEBVIEW_NEWWINDOW, wxWebViewEvent ); +wxDEFINE_EVENT( wxEVT_WEBVIEW_TITLE_CHANGED, wxWebViewEvent ); - return s; -} +wxStringWebViewFactoryMap wxWebView::m_factoryMap; -wxWebFileProtocolHandler::wxWebFileProtocolHandler() -{ - m_protocol = "test"; - m_fileSystem = new wxFileSystem(); -} - -wxFSFile* wxWebFileProtocolHandler::GetFile(const wxString &uri) +// static +wxWebView* wxWebView::New(const wxString& backend) { - size_t pos = uri.find('?'); - //There is no query string so we can load the file directly - if(pos == wxString::npos) - { - size_t doubleslash = uri.find("//"); - //The path is incorrectly formed without // after the first protocol - if(doubleslash == wxString::npos) - return NULL; + wxStringWebViewFactoryMap::iterator iter = FindFactory(backend); - wxString fspath = "file:" + - EscapeFileNameCharsInURL(uri.substr(doubleslash + 2)); - return m_fileSystem->OpenFile(fspath); - } - //Otherwise we have a query string of some kind that we need to extract - else{ - //First we extract the query string, this should have two parameters, - //protocol=type and path=path - wxString query = uri.substr(pos + 1), protocol, path; - //We also trim the query off the end as we handle it alone - wxString lefturi = uri.substr(0, pos); - wxStringTokenizer tokenizer(query, ";"); - while(tokenizer.HasMoreTokens() && (protocol == "" || path == "")) - { - wxString token = tokenizer.GetNextToken(); - if(token.substr(0, 9) == "protocol=") - { - protocol = token.substr(9); - } - else if(token.substr(0, 5) == "path=") - { - path = token.substr(5); - } - } - if(protocol == "" || path == "") - return NULL; - - //We now have the path and the protocol and so can format a correct uri - //to pass to wxFileSystem to get a wxFSFile - size_t doubleslash = uri.find("//"); - //The path is incorrectly formed without // after the first protocol - if(doubleslash == wxString::npos) - return NULL; - - wxString fspath = "file:" + - EscapeFileNameCharsInURL(lefturi.substr(doubleslash + 2)) - + "#" + protocol +":" + path; - return m_fileSystem->OpenFile(fspath); - } + if(iter == m_factoryMap.end()) + return NULL; + else + return (*iter).second->Create(); } -wxString wxWebFileProtocolHandler::CombineURIs(const wxString &baseuri, - const wxString &newuri) +// static +wxWebView* wxWebView::New(wxWindow* parent, wxWindowID id, const wxString& url, + const wxPoint& pos, const wxSize& size, + const wxString& backend, long style, + const wxString& name) { - //If there is a colon in the path then we just return it - if(newuri.find(':') != wxString::npos) - { - return newuri; - } - //We have an absolute path and no query string - else if(newuri.substr(0, 1) == "/" && baseuri.find('?') == wxString::npos) - { - //By finding the next / after file:// we get to the end of the - //(optional) hostname - size_t pos = baseuri.find('/', 7); - //So we return up to the end of the hostname, plus the newuri - return baseuri.substr(0, pos) + newuri; - } - //We have an absolute path and a query string - else if(newuri.substr(0, 1) == "/" && baseuri.find('?') != wxString::npos) - { - wxString query = baseuri.substr(baseuri.find('?') + 1); - wxString newquery; - wxStringTokenizer tokenizer(query, ";"); - while(tokenizer.HasMoreTokens()) - { - wxString token = tokenizer.GetNextToken(); - if(token.substr(0, 5) == "path=") - { - //As the path is absolue simply replace the old path with the - //new one - newquery = newquery + "path=" + newuri; - } - else - { - newquery += token; - } - //We need to add the separators back - if(tokenizer.HasMoreTokens()) - newquery += ';'; - } - return baseuri.substr(0, baseuri.find('?')) + "?" + newquery; - } - //We have a relative path and no query string - else if(baseuri.find('?') == wxString::npos) - { - //By finding the next / after file:// we get to the end of the - //(optional) hostname - size_t pos = baseuri.find('/', 7); - wxString path = baseuri.substr(pos); - //Then we remove the last filename - path = path.BeforeLast('/') + '/'; - //Ensure that we have the leading / so we can normalise properly - if(path.substr(0, 1) != "/") - path = "/" + path; + wxStringWebViewFactoryMap::iterator iter = FindFactory(backend); - //If we have a colon in the path (i.e. we are on windows) we need to - //handle it specially - if(path.find(':') != wxString::npos) - { - wxFileName fn(path.AfterFirst('/').AfterFirst('/') + newuri); - fn.Normalize(wxPATH_NORM_DOTS, "", wxPATH_UNIX); - return baseuri.substr(0, pos) + '/' + - path.AfterFirst('/').BeforeFirst('/') + '/' + - fn.GetFullPath(wxPATH_UNIX); - } - else - { - //We can now use wxFileName to perform the normalisation - wxFileName fn(path + newuri); - fn.Normalize(wxPATH_NORM_DOTS, "", wxPATH_UNIX); - return baseuri.substr(0, pos) + fn.GetFullPath(wxPATH_UNIX); - } - } - //We have a relative path and a query string + if(iter == m_factoryMap.end()) + return NULL; else - { - wxString query = baseuri.substr(baseuri.find('?') + 1); - wxString newquery; - wxStringTokenizer tokenizer(query, ";"); - while(tokenizer.HasMoreTokens()) - { - wxString token = tokenizer.GetNextToken(); - if(token.substr(0, 5) == "path=") - { - wxString path = token.substr(6); - //Then we remove the last filename - path = path.BeforeLast('/') + '/'; - //Ensure that we have the leading / so we can normalise properly - //if(path.substr(0, 1) != "/") - // path = "/" + path; + return (*iter).second->Create(parent, id, url, pos, size, style, name); - //We can now use wxFileName to perform the normalisation - wxFileName fn(path + newuri); - fn.Normalize(wxPATH_NORM_DOTS, "", wxPATH_UNIX); - newquery = newquery + "path=" + fn.GetFullPath(wxPATH_UNIX); - } - else - { - newquery += token; - } - //We need to add the separators back - if(tokenizer.HasMoreTokens()) - newquery += ';'; - } - return baseuri.substr(0, baseuri.find('?')) + "?" + newquery; - } } // static -wxWebView* wxWebView::New(wxWebViewBackend backend) +void wxWebView::RegisterFactory(const wxString& backend, + wxSharedPtr factory) { - switch (backend) - { - #if defined(wxUSE_WEBVIEW_WEBKIT) && \ - (defined(__WXGTK__) || defined(__WXOSX__)) - case wxWEB_VIEW_BACKEND_WEBKIT: - return new wxWebViewWebKit(); - #endif - - #if wxUSE_WEBVIEW_IE - case wxWEB_VIEW_BACKEND_IE: - return new wxWebViewIE(); - #endif - - case wxWEB_VIEW_BACKEND_DEFAULT: - - #if defined(wxUSE_WEBVIEW_WEBKIT) && \ - (defined(__WXGTK__) || defined(__WXOSX__)) - return new wxWebViewWebKit(); - #endif + m_factoryMap[backend] = factory; +} - #if wxUSE_WEBVIEW_IE - return new wxWebViewIE(); - #endif +// static +wxStringWebViewFactoryMap::iterator wxWebView::FindFactory(const wxString &backend) +{ + // Initialise the map, it checks internally for existing factories + InitFactoryMap(); - // fall-through intended - default: - return NULL; - } + return m_factoryMap.find(backend); } - + // static -wxWebView* wxWebView::New(wxWindow* parent, - wxWindowID id, - const wxString& url, - const wxPoint& pos, - const wxSize& size, - wxWebViewBackend backend, - long style, - const wxString& name) +void wxWebView::InitFactoryMap() { - switch (backend) - { - #if defined(wxUSE_WEBVIEW_WEBKIT) && \ - (defined(__WXGTK__) || defined(__WXOSX__)) - case wxWEB_VIEW_BACKEND_WEBKIT: - return new wxWebViewWebKit(parent, id, url, pos, size, style, name); - #endif - - #if wxUSE_WEBVIEW_IE - case wxWEB_VIEW_BACKEND_IE: - return new wxWebViewIE(parent, id, url, pos, size, style, name); - #endif - - case wxWEB_VIEW_BACKEND_DEFAULT: - - #if defined(wxUSE_WEBVIEW_WEBKIT) && \ - (defined(__WXGTK__) || defined(__WXOSX__)) - return new wxWebViewWebKit(parent, id, url, pos, size, style, name); - #endif - - #if wxUSE_WEBVIEW_IE - return new wxWebViewIE(parent, id, url, pos, size, style, name); - #endif - - // fall-through intended - default: - return NULL; - } +#ifdef __WXMSW__ + if(m_factoryMap.find(wxWebViewBackendIE) == m_factoryMap.end()) + RegisterFactory(wxWebViewBackendIE, wxSharedPtr + (new wxWebViewFactoryIE)); +#else + if(m_factoryMap.find(wxWebViewBackendWebKit) == m_factoryMap.end()) + RegisterFactory(wxWebViewBackendWebKit, wxSharedPtr + (new wxWebViewFactoryWebKit)); +#endif } -#endif // wxUSE_WEB +#endif // wxUSE_WEBVIEW