Merge branch 'webview_native_config' of https://github.com/TcT2k/wxWidgets

Add wxWebView::GetNativeConfiguration().

See #22781.
This commit is contained in:
Vadim Zeitlin 2022-09-10 13:40:07 +02:00
commit d8556bf3ee
8 changed files with 124 additions and 63 deletions

View file

@ -53,6 +53,7 @@ public:
wxCOMPtr<ICoreWebView2Environment> m_webViewEnvironment;
wxCOMPtr<ICoreWebView2_2> m_webView;
wxCOMPtr<ICoreWebView2Controller> m_webViewController;
wxCOMPtr<ICoreWebView2EnvironmentOptions> m_webViewEnvironmentOptions;
bool m_initialized;
bool m_isBusy;

View file

@ -98,6 +98,7 @@ public:
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
virtual void* GetNativeBackend() const wxOVERRIDE;
virtual void* GetNativeConfiguration() const wxOVERRIDE;
static void MSWSetBrowserExecutableDir(const wxString& path);

View file

@ -32,7 +32,7 @@ class WXDLLIMPEXP_WEBVIEW wxWebViewWebKit : public wxWebView
public:
wxDECLARE_DYNAMIC_CLASS(wxWebViewWebKit);
wxWebViewWebKit() {}
wxWebViewWebKit() { Init(); }
wxWebViewWebKit(wxWindow *parent,
wxWindowID winID = wxID_ANY,
const wxString& strURL = wxASCII_STR(wxWebViewDefaultURLStr),
@ -40,6 +40,7 @@ public:
const wxSize& size = wxDefaultSize, long style = 0,
const wxString& name = wxASCII_STR(wxWebViewNameStr))
{
Init();
Create(parent, winID, strURL, pos, size, style, name);
}
bool Create(wxWindow *parent,
@ -105,6 +106,7 @@ public:
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
virtual void* GetNativeBackend() const wxOVERRIDE { return m_webView; }
virtual void* GetNativeConfiguration() const wxOVERRIDE { return m_webViewConfiguration; }
protected:
virtual void DoSetPage(const wxString& html, const wxString& baseUrl) wxOVERRIDE;
@ -112,12 +114,15 @@ protected:
wxDECLARE_EVENT_TABLE();
private:
WX_NSObject m_webViewConfiguration;
OSXWebViewPtr m_webView;
wxStringToWebHandlerMap m_handlers;
wxString m_customUserAgent;
WX_NSObject m_navigationDelegate;
WX_NSObject m_UIDelegate;
void Init();
};
class WXDLLIMPEXP_WEBVIEW wxWebViewFactoryWebKit : public wxWebViewFactory

View file

@ -33,38 +33,42 @@ public:
};
wxJSScriptWrapper(const wxString& js, OutputType outputType)
: m_escapedCode(js), m_outputType(outputType)
: m_outputType(outputType)
{
// Adds one escape level.
const char *charsNeededToBeEscaped = "\\\"\n\r\v\t\b\f";
for (
size_t pos = m_escapedCode.find_first_of(charsNeededToBeEscaped, 0);
pos != wxString::npos;
pos = m_escapedCode.find_first_of(charsNeededToBeEscaped, pos)
) {
switch (m_escapedCode[pos].GetValue())
m_escapedCode.reserve(js.size());
for (wxString::const_iterator it = js.begin(); it != js.end(); ++it)
{
if (wxStrchr(charsNeededToBeEscaped, *it))
{
case 0x0A: // '\n'
m_escapedCode[pos] = 'n';
break;
case 0x0D: // '\r'
m_escapedCode[pos] = 'r';
break;
case 0x0B: // '\v'
m_escapedCode[pos] = 'v';
break;
case 0x09: // '\t'
m_escapedCode[pos] = 't';
break;
case 0x08: // '\b'
m_escapedCode[pos] = 'b';
break;
case 0x0C: // '\f'
m_escapedCode[pos] = 'f';
break;
m_escapedCode += '\\';
switch ((wxChar) *it)
{
case 0x0A: // '\n'
m_escapedCode += 'n';
break;
case 0x0D: // '\r'
m_escapedCode += 'r';
break;
case 0x0B: // '\v'
m_escapedCode += 'v';
break;
case 0x09: // '\t'
m_escapedCode += 't';
break;
case 0x08: // '\b'
m_escapedCode += 'b';
break;
case 0x0C: // '\f'
m_escapedCode += 'f';
break;
default:
m_escapedCode += *it;
}
}
m_escapedCode.insert(pos, '\\');
pos += 2;
else
m_escapedCode += *it;
}
}

View file

@ -259,6 +259,7 @@ public:
//Get the pointer to the underlying native engine.
virtual void* GetNativeBackend() const = 0;
virtual void* GetNativeConfiguration() const { return NULL; }
//Find function
virtual long Find(const wxString& text, int flags = wxWEBVIEW_FIND_DEFAULT);

View file

@ -623,6 +623,48 @@ public:
*/
virtual void* GetNativeBackend() const = 0;
/**
Return the pointer to the native configuration used during creation of
this control.
When using two-step creation this method can be used to customize
configuration options not available via GetNativeBackend()
after using Create().
The return value needs to be down-casted to the appropriate type
depending on the platform: under macOS, it's a
<a href="https://developer.apple.com/documentation/webkit/wkwebviewconfiguration">WKWebViewConfiguration</a>
pointer, under Windows with Edge it's a pointer to
<a href="https://docs.microsoft.com/en-us/microsoft-edge/webview2/reference/win32/icorewebview2environmentoptions">ICoreWebView2EnvironmentOptions</a>.
With other backends/platforms it's not implemented.
The following pseudo code shows how to use this method with two-step
creation to set no user action requirement to play video in a
web view:
@code
#if defined(__WXMSW__)
#include "webview2.h"
#elif defined(__WXOSX__)
#import "WebKit/WebKit.h"
#endif
wxWebView* webView = wxWebView::New();
#if defined(__WXMSW__)
ICoreWebView2EnvironmentOptions* webViewOptions =
(ICoreWebView2EnvironmentOptions*) webView->GetNativeConfiguration();
webViewOptions->put_AdditionalBrowserArguments("--autoplay-policy=no-user-gesture-required");
#elif defined(__WXOSX__)
WKWebViewConfiguration* webViewConfiguration =
(WKWebViewConfiguration*) webView->GetNativeConfiguration();
webViewConfiguration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
#endif
webView->Create(this, wxID_ANY, "https://www.wxwidgets.org");
@endcode
@since 3.3.0
*/
virtual void* GetNativeConfiguration() const;
/**
Get the HTML source code of the currently displayed document.
@return The HTML source code, or an empty string if no page is currently
@ -711,6 +753,27 @@ public:
*/
virtual void Stop() = 0;
/**
Specify a custom user agent string for the web view.
Returns @true the user agent could be set.
If your first request should already use the custom user agent
please use two step creation and call SetUserAgent() before Create().
@note This is not implemented for IE. For Edge SetUserAgent()
MUST be called before Create().
@since 3.1.5
*/
virtual bool SetUserAgent(const wxString& userAgent);
/**
Returns the current user agent string for the web view.
@since 3.1.5
*/
virtual wxString GetUserAgent() const;
/**
@name Scripting
*/
@ -953,28 +1016,6 @@ public:
*/
virtual bool IsAccessToDevToolsEnabled() const;
/**
Specify a custom user agent string for the web view.
Returns @true the user agent could be set.
If your first request should already use the custom user agent
please use two step creation and call SetUserAgent() before Create().
@note This is not implemented for IE. For Edge SetUserAgent()
MUST be called before Create().
@since 3.1.5
*/
virtual bool SetUserAgent(const wxString& userAgent);
/**
Returns the current user agent string for the web view.
@since 3.1.5
*/
virtual wxString GetUserAgent() const;
/**
@name History
*/

View file

@ -69,7 +69,9 @@ wxString wxWebViewEdgeImpl::ms_browserExecutableDir;
wxWebViewEdgeImpl::wxWebViewEdgeImpl(wxWebViewEdge* webview):
m_ctrl(webview)
{
#ifdef __VISUALC__
m_webViewEnvironmentOptions = Make<CoreWebView2EnvironmentOptions>().Get();
#endif
}
wxWebViewEdgeImpl::~wxWebViewEdgeImpl()
@ -99,23 +101,15 @@ bool wxWebViewEdgeImpl::Create()
m_historyPosition = -1;
wxString userDataPath = wxStandardPaths::Get().GetUserLocalDataDir();
#ifdef __VISUALC__
auto options =
Make<CoreWebView2EnvironmentOptions>();
if (!m_customUserAgent.empty())
options->put_AdditionalBrowserArguments(
if (m_webViewEnvironmentOptions && !m_customUserAgent.empty())
m_webViewEnvironmentOptions->put_AdditionalBrowserArguments(
wxString::Format("--user-agent=\"%s\"", m_customUserAgent).wc_str());
#endif
HRESULT hr = wxCreateCoreWebView2EnvironmentWithOptions(
ms_browserExecutableDir.wc_str(),
userDataPath.wc_str(),
#ifdef __VISUALC__
options.Get(),
#else
nullptr,
#endif
m_webViewEnvironmentOptions,
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(this,
&wxWebViewEdgeImpl::OnEnvironmentCreated).Get());
if (FAILED(hr))
@ -844,6 +838,11 @@ void* wxWebViewEdge::GetNativeBackend() const
return m_impl->m_webView;
}
void* wxWebViewEdge::GetNativeConfiguration() const
{
return m_impl->m_webViewEnvironmentOptions;
}
void wxWebViewEdge::MSWSetBrowserExecutableDir(const wxString & path)
{
wxWebViewEdgeImpl::ms_browserExecutableDir = path;

View file

@ -111,6 +111,11 @@ wxVersionInfo wxWebViewFactoryWebKit::GetVersionInfo()
// creation/destruction
// ----------------------------------------------------------------------------
void wxWebViewWebKit::Init()
{
m_webViewConfiguration = [[WKWebViewConfiguration alloc] init];
}
bool wxWebViewWebKit::Create(wxWindow *parent,
wxWindowID winID,
const wxString& strURL,
@ -122,7 +127,7 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
wxControl::Create(parent, winID, pos, size, style, wxDefaultValidator, name);
NSRect r = wxOSXGetFrameForControl( this, pos , size ) ;
WKWebViewConfiguration* webViewConfig = [[WKWebViewConfiguration alloc] init];
WKWebViewConfiguration* webViewConfig = (WKWebViewConfiguration*) m_webViewConfiguration;
if (!m_handlers.empty())
{
@ -146,6 +151,10 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
MacPostControlCreate(pos, size);
// WKWebView configuration is only used during creation
[m_webViewConfiguration release];
m_webViewConfiguration = nil;
if (!m_customUserAgent.empty())
SetUserAgent(m_customUserAgent);