Add wxWebViewChromium::SetRoot()

This allows to define a prefix for all the files used by the application
in the browser.
This commit is contained in:
Vadim Zeitlin 2023-12-20 01:39:02 +01:00
parent 322677ad38
commit 6f130c121f
3 changed files with 121 additions and 2 deletions

View file

@ -14,6 +14,8 @@
#include "wx/webview.h"
#include "wx/timer.h"
class WXDLLIMPEXP_FWD_BASE wxFileName;
extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewBackendChromium[];
// Private namespace containing classes used only in the implementation.
@ -123,6 +125,9 @@ public:
//Virtual Filesystem Support
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) override;
// Chromium-specific functions.
void SetRoot(const wxFileName& rootDir);
#ifdef __WXGTK__
virtual void GTKHandleRealized() override;
#endif

View file

@ -250,6 +250,10 @@
- RunScript: Retrieving the result of JavaScript execution is not supported and
if the @a output parameter is non-null, the function will always return false.
wxWebView also provides some functions not available in the base class:
- SetRoot() allows to use the given directory for all application files.
@since 3.3.0
@library{wxwebview}
@category{webview}
@ -279,4 +283,12 @@ public:
const wxSize& size = wxDefaultSize,
long style = 0,
const wxString& name = wxWebViewNameStr);
/**
Use the specified directory as root for the file:// URLs.
After calling this function, all file paths will be resolved relatively
to the given @a rootDir rather than to the actual file system root.
*/
void SetRoot(const wxFileName& rootDir);
};

View file

@ -57,6 +57,7 @@ wxGCC_WARNING_SUPPRESS(unused-parameter)
#include "include/cef_string_visitor.h"
#include "include/cef_version.h"
#include "include/base/cef_lock.h"
#include "include/wrapper/cef_resource_manager.h"
wxGCC_WARNING_RESTORE(unused-parameter)
@ -251,17 +252,21 @@ class ClientHandler : public CefClient,
public CefContextMenuHandler,
public CefDisplayHandler,
public CefLifeSpanHandler,
public CefLoadHandler
public CefLoadHandler,
public CefRequestHandler,
public CefResourceRequestHandler
{
public:
// Ctor must be given a backpointer to wxWebView which must remain valid
// for the entire lifetime of this object.
explicit ClientHandler(wxWebViewChromium& webview) : m_webview{webview} {}
// Overridden CefClient methods
virtual CefRefPtr<CefContextMenuHandler> GetContextMenuHandler() override { return this; }
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() override { return this; }
virtual CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this; }
virtual CefRefPtr<CefLoadHandler> GetLoadHandler() override { return this; }
virtual CefRefPtr<CefDisplayHandler> GetDisplayHandler() override { return this; }
virtual CefRefPtr<CefRequestHandler> GetRequestHandler() override { return this; }
// CefDisplayHandler methods
virtual void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
@ -321,6 +326,43 @@ public:
const CefString& errorText,
const CefString& failedUrl) override;
// CefRequestHandler methods
virtual CefRefPtr<CefResourceRequestHandler> GetResourceRequestHandler(
CefRefPtr<CefBrowser> WXUNUSED(browser),
CefRefPtr<CefFrame> WXUNUSED(frame),
CefRefPtr<CefRequest> WXUNUSED(request),
bool WXUNUSED(is_navigation),
bool WXUNUSED(is_download),
const CefString& WXUNUSED(request_initiator),
bool& WXUNUSED(disable_default_handling)) override
{
return this;
}
// CefResourceRequestHandler methods
virtual cef_return_value_t OnBeforeResourceLoad(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback) override;
virtual CefRefPtr<CefResourceHandler> GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request) override;
// Our own functions.
// Initialize the resource manager, creating it if necessary (so don't call
// this if you don't want it to be created).
CefRefPtr<CefResourceManager> GetResourceManager()
{
if ( !m_resourceManager )
m_resourceManager = new CefResourceManager{};
return m_resourceManager;
}
CefRefPtr<CefBrowser> GetBrowser() const { return m_browser; }
// Return the main frame. May be null.
@ -361,6 +403,9 @@ private:
// Record the load error code: enum wxWebViewNavigationError
// -1 means no error.
int m_loadErrorCode = -1;
CefRefPtr<CefResourceManager> m_resourceManager;
IMPLEMENT_REFCOUNTING(ClientHandler);
};
@ -1272,6 +1317,39 @@ void wxWebViewChromium::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
new SchemeHandlerFactory(handler) );
}
namespace
{
// Called only by wxWebViewChromium::SetRoot() which ensures that it's called
// on the appropriate thread.
void
SetResourceRoot(
const CefRefPtr<CefResourceManager>& resourceManager,
const wxFileName& rootDir
)
{
resourceManager->AddDirectoryProvider(
"file:///",
rootDir.GetFullPath().utf8_string(),
0,
"wxRootProvider"
);
}
} // anonymous namespace
void wxWebViewChromium::SetRoot(const wxFileName& rootDir)
{
CefPostTask(
TID_IO,
base::BindOnce(
&SetResourceRoot,
m_clientHandler->GetResourceManager(),
rootDir
)
);
}
// CefDisplayHandler methods
void ClientHandler::OnLoadingStateChange(CefRefPtr<CefBrowser> WXUNUSED(browser),
bool WXUNUSED(isLoading),
@ -1528,6 +1606,30 @@ void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> WXUNUSED(browser),
}
}
// CefResourceRequestHandler methods
cef_return_value_t ClientHandler::OnBeforeResourceLoad(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback)
{
if ( !m_resourceManager )
return RV_CONTINUE;
return m_resourceManager->OnBeforeResourceLoad(browser, frame, request, callback);
}
CefRefPtr<CefResourceHandler> ClientHandler::GetResourceHandler(
CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefRequest> request)
{
if ( !m_resourceManager )
return {};
return m_resourceManager->GetResourceHandler(browser, frame, request);
}
bool SchemeHandler::ProcessRequest(CefRefPtr<CefRequest> request,
CefRefPtr<CefCallback> callback)
{