From 9e3d4a32106c8c0f85695f68856da137c14d2b5c Mon Sep 17 00:00:00 2001 From: Steve Lamerton Date: Sat, 30 Jul 2011 14:22:15 +0000 Subject: [PATCH] Overhaul wxWebHandler naming to try and make it consistent with the rest of wxWidgets. Split wxWebFileHandler into its own file. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/SOC2011_WEBVIEW@68461 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- build/bakefiles/files.bkl | 2 + include/wx/gtk/webview_webkit.h | 2 +- include/wx/msw/webview_ie.h | 10 +- include/wx/osx/webview_webkit.h | 2 +- include/wx/webview.h | 22 +-- include/wx/webviewfilehandler.h | 39 ++++++ samples/web/web.cpp | 3 +- src/common/webview.cpp | 193 --------------------------- src/common/webviewfilehandler.cpp | 213 ++++++++++++++++++++++++++++++ src/msw/webview_ie.cpp | 6 +- 10 files changed, 270 insertions(+), 222 deletions(-) create mode 100644 include/wx/webviewfilehandler.h create mode 100644 src/common/webviewfilehandler.cpp diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 2aed8c9f3a..bcdbd3c225 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -3357,6 +3357,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! $(WEB_SRC_PLATFORM) src/common/webview.cpp + src/common/webviewfilehandler.cpp @@ -3367,6 +3368,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! $(WEB_HDR_PLATFORM) wx/webview.h + wx/webviewfilehandler.h diff --git a/include/wx/gtk/webview_webkit.h b/include/wx/gtk/webview_webkit.h index fbbf5da936..1775b704f8 100644 --- a/include/wx/gtk/webview_webkit.h +++ b/include/wx/gtk/webview_webkit.h @@ -152,7 +152,7 @@ public: virtual void RunScript(const wxString& javascript); //Virtual Filesystem Support - virtual void RegisterProtocol(wxWebProtocolHandler* hanlder); + virtual void RegisterHandler(wxWebHandler* handler); /** FIXME: hack to work around signals being received too early */ bool m_ready; diff --git a/include/wx/msw/webview_ie.h b/include/wx/msw/webview_ie.h index f8245644fc..938cf0ce41 100644 --- a/include/wx/msw/webview_ie.h +++ b/include/wx/msw/webview_ie.h @@ -110,7 +110,7 @@ public: virtual void RunScript(const wxString& javascript); //Virtual Filesystem Support - virtual void RegisterProtocol(wxWebProtocolHandler* hanlder); + virtual void RegisterHandler(wxWebHandler* handler); // ---- IE-specific methods @@ -168,10 +168,10 @@ protected: VOID * fileP; wxFSFile* m_file; - wxWebProtocolHandler* m_handler; + wxWebHandler* m_handler; public: - VirtualProtocol(wxWebProtocolHandler *handler); + VirtualProtocol(wxWebHandler *handler); ~VirtualProtocol(); //IUnknown @@ -229,7 +229,7 @@ class ClassFactory : public IClassFactory private: ULONG m_refCount; public: - ClassFactory(wxWebProtocolHandler* handler) : m_handler(handler) {} + ClassFactory(wxWebHandler* handler) : m_handler(handler) {} //IUnknown ULONG STDMETHODCALLTYPE AddRef(); HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject); @@ -240,7 +240,7 @@ public: REFIID riid, void** ppvObject); HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock); private: - wxWebProtocolHandler* m_handler; + wxWebHandler* m_handler; }; #endif // wxUSE_WEBVIEW_IE diff --git a/include/wx/osx/webview_webkit.h b/include/wx/osx/webview_webkit.h index 8ce778ba97..e83b1ccdb5 100644 --- a/include/wx/osx/webview_webkit.h +++ b/include/wx/osx/webview_webkit.h @@ -117,7 +117,7 @@ public: void RunScript(const wxString& javascript); //Virtual Filesystem Support - virtual void RegisterProtocol(wxWebProtocolHandler* hanlder) {}; + virtual void RegisterHandler(wxWebHandler* handler) {}; // ---- methods not from the parent (common) interface bool CanGetPageSource(); diff --git a/include/wx/webview.h b/include/wx/webview.h index da306c1be1..bb1a8fbcb7 100644 --- a/include/wx/webview.h +++ b/include/wx/webview.h @@ -107,29 +107,15 @@ enum wxWebViewBackend wxWEB_VIEW_BACKEND_IE }; -//Base class for custom protocol handlers -class WXDLLIMPEXP_WEB wxWebProtocolHandler +//Base class for custom scheme handlers +class WXDLLIMPEXP_WEB wxWebHandler { public: - virtual wxString GetProtocol() = 0; + virtual wxString GetName() const = 0; virtual wxFSFile* GetFile(const wxString &uri) = 0; virtual wxString CombineURIs(const wxString &baseuri, const wxString &newuri) = 0; }; -//Loads from uris such as file:///C:/example/example.html or archives such as -//file:///C:/example/example.zip?protocol=zip;path=example.html -class WXDLLIMPEXP_WEB wxWebFileProtocolHandler : public wxWebProtocolHandler -{ -public: - wxWebFileProtocolHandler(); - virtual wxString GetProtocol() { return m_protocol; } - virtual wxFSFile* GetFile(const wxString &uri); - virtual wxString CombineURIs(const wxString &baseuri, const wxString &newuri); -private: - wxString m_protocol; - wxFileSystem* m_fileSystem; -}; - extern WXDLLIMPEXP_DATA_WEB(const char) wxWebViewNameStr[]; extern WXDLLIMPEXP_DATA_WEB(const char) wxWebViewDefaultURLStr[]; @@ -361,7 +347,7 @@ public: virtual void Redo() = 0; //Virtual Filesystem Support - virtual void RegisterProtocol(wxWebProtocolHandler* handler) = 0; + virtual void RegisterHandler(wxWebHandler* handler) = 0; }; class WXDLLIMPEXP_WEB wxWebNavigationEvent : public wxCommandEvent diff --git a/include/wx/webviewfilehandler.h b/include/wx/webviewfilehandler.h new file mode 100644 index 0000000000..a3ea4367e1 --- /dev/null +++ b/include/wx/webviewfilehandler.h @@ -0,0 +1,39 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: webviewfilehandler.h +// Purpose: Custom handler for the file scheme to allow archive browsing +// Author: Steven Lamerton +// Id: $Id$ +// Copyright: (c) 2011 Steven Lamerton +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_WEB_VIEW_FILE_HANDLER_H_ +#define _WX_WEB_VIEW_FILE_HANDLER_H_ + +#include "wx/setup.h" + +#if wxUSE_WEB + +class wxFSFile; +class wxFileSystem; + +#include "wx/webview.h" + +//Loads from uris such as file:///C:/example/example.html or archives such as +//file:///C:/example/example.zip?protocol=zip;path=example.html + +class WXDLLIMPEXP_WEB wxWebFileHandler : public wxWebHandler +{ +public: + wxWebFileHandler(); + virtual wxString GetName() const { return m_name; } + virtual wxFSFile* GetFile(const wxString &uri); + virtual wxString CombineURIs(const wxString &baseuri, const wxString &newuri); +private: + wxString m_name; + wxFileSystem* m_fileSystem; +}; + +#endif + +#endif // _WX_WEB_VIEW_FILE_HANDLER_H_ diff --git a/samples/web/web.cpp b/samples/web/web.cpp index 97f20bf99a..a5d4598076 100644 --- a/samples/web/web.cpp +++ b/samples/web/web.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -191,7 +192,7 @@ WebFrame::WebFrame() : wxFrame(NULL, wxID_ANY, "wxWebView Sample") topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1)); //We register the test:// protocol for testing purposes - m_browser->RegisterProtocol(new wxWebFileProtocolHandler()); + m_browser->RegisterHandler(new wxWebFileHandler()); SetSizer(topsizer); diff --git a/src/common/webview.cpp b/src/common/webview.cpp index 113f96ad68..8abac2300c 100644 --- a/src/common/webview.cpp +++ b/src/common/webview.cpp @@ -21,8 +21,6 @@ #include "wx/osx/webview_webkit.h" #include "wx/gtk/webview_webkit.h" #include "wx/msw/webview_ie.h" -#include "wx/filesys.h" -#include "wx/tokenzr.h" // DLL options compatibility check: #include "wx/app.h" @@ -40,197 +38,6 @@ wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_ERROR, wxWebNavigationEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_NEWWINDOW, wxWebNavigationEvent ); wxDEFINE_EVENT( wxEVT_COMMAND_WEB_VIEW_TITLE_CHANGED, wxWebNavigationEvent ); -//Taken from wx/filesys.cpp -static wxString EscapeFileNameCharsInURL(const char *in) -{ - wxString s; - - for ( const unsigned char *p = (const unsigned char*)in; *p; ++p ) - { - const unsigned char c = *p; - - 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); - } - } - - return s; -} - -wxWebFileProtocolHandler::wxWebFileProtocolHandler() -{ - m_protocol = "test"; - m_fileSystem = new wxFileSystem(); -} - -wxFSFile* wxWebFileProtocolHandler::GetFile(const wxString &uri) -{ - 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; - - 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); - } -} - -wxString wxWebFileProtocolHandler::CombineURIs(const wxString &baseuri, - const wxString &newuri) -{ - //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; - - //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 - 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; - - //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) { diff --git a/src/common/webviewfilehandler.cpp b/src/common/webviewfilehandler.cpp new file mode 100644 index 0000000000..2f35f738cc --- /dev/null +++ b/src/common/webviewfilehandler.cpp @@ -0,0 +1,213 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: webviewfilehandler.cpp +// Purpose: Custom handler for the file scheme to allow archive browsing +// Author: Steven Lamerton +// Id: $Id$ +// Copyright: (c) 2011 Steven Lamerton +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#if wxUSE_WEB + +#if defined(__BORLANDC__) + #pragma hdrstop +#endif + +#include "wx/webviewfilehandler.h" +#include "wx/filesys.h" +#include "wx/tokenzr.h" + +//Taken from wx/filesys.cpp +static wxString EscapeFileNameCharsInURL(const char *in) +{ + wxString s; + + for ( const unsigned char *p = (const unsigned char*)in; *p; ++p ) + { + const unsigned char c = *p; + + 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); + } + } + + return s; +} + +wxWebFileHandler::wxWebFileHandler() +{ + m_name = "test"; + m_fileSystem = new wxFileSystem(); +} + +wxFSFile* wxWebFileHandler::GetFile(const wxString &uri) +{ + 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; + + 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); + } +} + +wxString wxWebFileHandler::CombineURIs(const wxString &baseuri, + const wxString &newuri) +{ + //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; + + //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 + 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; + + //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; + } +} +#endif // wxUSE_WEB diff --git a/src/msw/webview_ie.cpp b/src/msw/webview_ie.cpp index 07cda9f9d5..f8e01432e6 100644 --- a/src/msw/webview_ie.cpp +++ b/src/msw/webview_ie.cpp @@ -663,7 +663,7 @@ void wxWebViewIE::RunScript(const wxString& javascript) document->Release(); } -void wxWebViewIE::RegisterProtocol(wxWebProtocolHandler* handler) +void wxWebViewIE::RegisterHandler(wxWebHandler* handler) { ClassFactory* cf = new ClassFactory(handler); IInternetSession* session; @@ -672,7 +672,7 @@ void wxWebViewIE::RegisterProtocol(wxWebProtocolHandler* handler) wxFAIL_MSG("Could not retrive internet session"); } - HRESULT hr = session->RegisterNameSpace(cf, CLSID_FileProtocol, handler->GetProtocol(), 0, NULL, 0); + HRESULT hr = session->RegisterNameSpace(cf, CLSID_FileProtocol, handler->GetName(), 0, NULL, 0); if(FAILED(hr)) { wxFAIL_MSG("Could not register protocol"); @@ -957,7 +957,7 @@ void wxWebViewIE::onActiveXEvent(wxActiveXEvent& evt) evt.Skip(); } -VirtualProtocol::VirtualProtocol(wxWebProtocolHandler *handler) +VirtualProtocol::VirtualProtocol(wxWebHandler *handler) { m_refCount = 0; m_file = NULL; -- 2.45.2