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

Add wxWebViewConfiguration.

See #23349.
This commit is contained in:
Vadim Zeitlin
2023-03-18 20:55:39 +01:00
9 changed files with 408 additions and 134 deletions
+5 -4
View File
@@ -51,6 +51,7 @@ class wxWebViewEdgeParentWindowInfo;
class wxWebViewEdgeImpl
{
public:
explicit wxWebViewEdgeImpl(wxWebViewEdge* webview, const wxWebViewConfiguration& config);
explicit wxWebViewEdgeImpl(wxWebViewEdge* webview);
~wxWebViewEdgeImpl();
@@ -59,11 +60,11 @@ public:
wxWebViewEdge* CreateChildWebView(std::shared_ptr<wxWebViewEdgeParentWindowInfo> parentWindowInfo);
wxWebViewEdge* m_ctrl;
wxWebViewConfiguration m_config;
wxCOMPtr<ICoreWebView2Environment> m_webViewEnvironment;
wxCOMPtr<ICoreWebView2_2> m_webView;
wxCOMPtr<ICoreWebView2Controller> m_webViewController;
wxCOMPtr<ICoreWebView2EnvironmentOptions> m_webViewEnvironmentOptions;
std::shared_ptr<wxWebViewEdgeParentWindowInfo> m_parentWindowInfo;
bool m_initialized;
@@ -107,11 +108,13 @@ public:
HRESULT OnAddScriptToExecuteOnDocumentedCreatedCompleted(HRESULT errorCode, LPCWSTR id);
HRESULT OnWindowCloseRequested(ICoreWebView2* sender, IUnknown* args);
HRESULT OnEnvironmentCreated(HRESULT result, ICoreWebView2Environment* environment);
void EnvironmentAvailable(ICoreWebView2Environment* environment);
HRESULT OnWebViewCreated(HRESULT result, ICoreWebView2Controller* webViewController);
HRESULT HandleNavigationStarting(ICoreWebView2NavigationStartingEventArgs* args, bool mainFrame);
void SendErrorEventForAPI(const wxString& api, HRESULT errorCode);
wxVector<wxSharedPtr<wxWebViewHistoryItem> > m_historyList;
int m_historyPosition;
bool m_historyLoadingFromList;
@@ -127,8 +130,6 @@ public:
#if !wxUSE_WEBVIEW_EDGE_STATIC
static wxDynamicLibrary ms_loaderDll;
#endif
static wxString ms_browserExecutableDir;
static bool Initialize();
static void Uninitialize();
+4 -1
View File
@@ -25,6 +25,8 @@ public:
wxWebViewEdge();
explicit wxWebViewEdge(const wxWebViewConfiguration& config);
wxWebViewEdge(wxWindow* parent,
wxWindowID id,
const wxString& url = wxWebViewDefaultURLStr,
@@ -103,7 +105,6 @@ public:
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) override;
virtual void* GetNativeBackend() const override;
virtual void* GetNativeConfiguration() const override;
static void MSWSetBrowserExecutableDir(const wxString& path);
@@ -128,6 +129,7 @@ class WXDLLIMPEXP_WEBVIEW wxWebViewFactoryEdge : public wxWebViewFactory
{
public:
virtual wxWebView* Create() override { return new wxWebViewEdge; }
virtual wxWebView* CreateWithConfig(const wxWebViewConfiguration& config) override;
virtual wxWebView* Create(wxWindow* parent,
wxWindowID id,
const wxString& url = wxWebViewDefaultURLStr,
@@ -140,6 +142,7 @@ public:
}
virtual bool IsAvailable() override;
virtual wxVersionInfo GetVersionInfo() override;
virtual wxWebViewConfiguration CreateConfiguration() override;
};
#endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_EDGE && defined(__WXMSW__)
+13 -20
View File
@@ -28,27 +28,13 @@
WX_DECLARE_STRING_HASH_MAP(wxSharedPtr<wxWebViewHandler>, wxStringToWebHandlerMap);
class wxWebViewWindowInfoWebKit;
class wxWebViewConfigurationImplWebKit;
class WXDLLIMPEXP_WEBVIEW wxWebViewWebKit : public wxWebView
{
public:
wxDECLARE_DYNAMIC_CLASS(wxWebViewWebKit);
explicit wxWebViewWebKit(const wxWebViewConfiguration& config, wxWebViewWindowInfoWebKit* parentWindowInfo = nullptr);
wxWebViewWebKit(wxWebViewWindowInfoWebKit* parentWindowInfo = nullptr)
{
m_parentWindowInfo = parentWindowInfo;
Init();
}
wxWebViewWebKit(wxWindow *parent,
wxWindowID winID = wxID_ANY,
const wxString& strURL = wxASCII_STR(wxWebViewDefaultURLStr),
const wxPoint& pos = wxDefaultPosition,
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,
wxWindowID winID = wxID_ANY,
const wxString& strURL = wxASCII_STR(wxWebViewDefaultURLStr),
@@ -112,7 +98,6 @@ public:
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) override;
virtual void* GetNativeBackend() const override { return m_webView; }
virtual void* GetNativeConfiguration() const override { return m_webViewConfiguration; }
protected:
virtual void DoSetPage(const wxString& html, const wxString& baseUrl) override;
@@ -120,7 +105,7 @@ protected:
wxDECLARE_EVENT_TABLE();
private:
WX_NSObject m_webViewConfiguration;
wxWebViewConfiguration m_configuration;
OSXWebViewPtr m_webView;
wxStringToWebHandlerMap m_handlers;
wxString m_customUserAgent;
@@ -135,7 +120,8 @@ private:
class WXDLLIMPEXP_WEBVIEW wxWebViewFactoryWebKit : public wxWebViewFactory
{
public:
virtual wxWebView* Create() override { return new wxWebViewWebKit; }
virtual wxWebView* Create() override { return CreateWithConfig(CreateConfiguration()); }
virtual wxWebView* CreateWithConfig(const wxWebViewConfiguration& config) override { return new wxWebViewWebKit(config); }
virtual wxWebView* Create(wxWindow* parent,
wxWindowID id,
const wxString& url = wxWebViewDefaultURLStr,
@@ -143,8 +129,15 @@ public:
const wxSize& size = wxDefaultSize,
long style = 0,
const wxString& name = wxASCII_STR(wxWebViewNameStr)) override
{ return new wxWebViewWebKit(parent, id, url, pos, size, style, name); }
{
auto webView = CreateWithConfig(CreateConfiguration());
if (webView->Create(parent, id, url, pos, size, style, name))
return webView;
else
return nullptr;
}
virtual wxVersionInfo GetVersionInfo() override;
virtual wxWebViewConfiguration CreateConfiguration() override;
};
#endif // wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT
+22
View File
@@ -0,0 +1,22 @@
///////////////////////////////////////////////////////////////////////////////
// Name: wx/private/webview.h
// Purpose: wxWebView implementation classes
// Author: Tobias Taschner
// Created: 2023-03-16
// Copyright: (c) 2023 wxWidgets development team
// Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////////
#ifndef _WX_PRIVATE_WEBVIEW_H_
#define _WX_PRIVATE_WEBVIEW_H_
class WXDLLIMPEXP_WEBVIEW wxWebViewConfigurationImpl
{
public:
virtual ~wxWebViewConfigurationImpl() = default;
virtual void* GetNativeConfiguration() const { return nullptr; }
virtual void SetDataPath(const wxString& WXUNUSED(path)) {}
virtual wxString GetDataPath() const { return wxString{}; }
};
#endif // _WX_PRIVATE_WEBVIEW_H_
+22 -1
View File
@@ -144,6 +144,24 @@ private:
wxString m_virtualHost;
};
class wxWebViewConfigurationImpl;
class WXDLLIMPEXP_WEBVIEW wxWebViewConfiguration
{
public:
explicit wxWebViewConfiguration(const wxString& backend, wxWebViewConfigurationImpl* impl);
void* GetNativeConfiguration() const;
void SetDataPath(const wxString& path);
wxString GetDataPath() const;
const wxString& GetBackend() const { return m_backend; }
wxWebViewConfigurationImpl* GetImpl() const { return m_impl.get(); }
private:
wxString m_backend;
std::shared_ptr<wxWebViewConfigurationImpl> m_impl;
};
extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewNameStr[];
extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewDefaultURLStr[];
extern WXDLLIMPEXP_DATA_WEBVIEW(const char) wxWebViewBackendDefault[];
@@ -155,6 +173,7 @@ class WXDLLIMPEXP_WEBVIEW wxWebViewFactory : public wxObject
{
public:
virtual wxWebView* Create() = 0;
virtual wxWebView* CreateWithConfig(const wxWebViewConfiguration& WXUNUSED(config)) { return Create(); }
virtual wxWebView* Create(wxWindow* parent,
wxWindowID id,
const wxString& url = wxASCII_STR(wxWebViewDefaultURLStr),
@@ -164,6 +183,7 @@ public:
const wxString& name = wxASCII_STR(wxWebViewNameStr)) = 0;
virtual bool IsAvailable() { return true; }
virtual wxVersionInfo GetVersionInfo() { return wxVersionInfo(); }
virtual wxWebViewConfiguration CreateConfiguration();
};
WX_DECLARE_STRING_HASH_MAP(wxSharedPtr<wxWebViewFactory>, wxStringWebViewFactoryMap);
@@ -190,6 +210,7 @@ public:
// Factory methods allowing the use of custom factories registered with
// RegisterFactory
static wxWebView* New(const wxString& backend = wxASCII_STR(wxWebViewBackendDefault));
static wxWebView* New(const wxWebViewConfiguration& config);
static wxWebView* New(wxWindow* parent,
wxWindowID id,
const wxString& url = wxASCII_STR(wxWebViewDefaultURLStr),
@@ -203,6 +224,7 @@ public:
wxSharedPtr<wxWebViewFactory> factory);
static bool IsBackendAvailable(const wxString& backend);
static wxVersionInfo GetBackendVersionInfo(const wxString& backend = wxASCII_STR(wxWebViewBackendDefault));
static wxWebViewConfiguration NewConfiguration(const wxString& backend = wxASCII_STR(wxWebViewBackendDefault));
// General methods
virtual void EnableContextMenu(bool enable = true)
@@ -297,7 +319,6 @@ public:
//Get the pointer to the underlying native engine.
virtual void* GetNativeBackend() const = 0;
virtual void* GetNativeConfiguration() const { return nullptr; }
//Find function
virtual long Find(const wxString& text, int flags = wxWEBVIEW_FIND_DEFAULT);
+131 -42
View File
@@ -246,6 +246,100 @@ public:
virtual wxWebView* CreateChildWebView() = 0;
};
/**
@class wxWebViewConfiguration
This class allows access to web view configuration options and settings,
that have to be specified before placing a webview in a window with
wxWebView::Create().
@since 3.3.0
@library{wxwebview}
@category{webview}
@see wxWebView::NewConfiguration()
*/
class WXDLLIMPEXP_WEBVIEW wxWebViewConfiguration
{
public:
/**
Return the pointer to the native configuration used during creation of
a wxWebView.
When using two-step creation this method can be used to customize
configuration options not available via GetNativeBackend()
after using Create().
Additional instances of wxWebView must be created using the same
wxWebViewConfiguration instance.
All settings @b must be set before creating a new web view with
wxWebView::New().
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 "webview2EnvironmentOptions.h"
#elif defined(__WXOSX__)
#import "WebKit/WebKit.h"
#endif
wxWebViewConfiguration config = wxWebView::NewConfiguration();
#if defined(__WXMSW__)
ICoreWebView2EnvironmentOptions* webViewOptions =
(ICoreWebView2EnvironmentOptions*) config->GetNativeConfiguration();
webViewOptions->put_AdditionalBrowserArguments("--autoplay-policy=no-user-gesture-required");
#elif defined(__WXOSX__)
WKWebViewConfiguration* webViewConfiguration =
(WKWebViewConfiguration*) config->GetNativeConfiguration();
webViewConfiguration.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypeNone;
#endif
wxWebView* webView = wxWebView::New(config);
webView->Create(this, wxID_ANY, "https://www.wxwidgets.org");
@endcode
*/
virtual void* GetNativeConfiguration() const { return nullptr; }
/**
Returns the backend identifier for which this configuration was created.
*/
wxString GetBackend() const;
/**
Set the data path for the webview.
This is the path where the webview stores its data, such as cookies,
local storage, etc.
@param path The path to the data directory.
@note This is only used by the Edge backend.
*/
void SetDataPath(const wxString& path);
/**
Returns the data path for the webview.
This is the path where the webview stores its data, such as cookies,
local storage, etc.
@return The path to the data directory.
@note This is only used by the Edge backend.
*/
wxString GetDataPath() const;
};
/**
@class wxWebViewHandlerRequest
@@ -450,6 +544,18 @@ public:
*/
virtual wxWebView* Create() = 0;
/**
Function to create a new wxWebView with two-step creation
with a wxWebViewConfiguration, wxWebView::Create should be
called on the returned object.
@return the created wxWebView
@since 3.3.0
@see CreateConfiguration()
*/
virtual wxWebView* CreateWithConfig(const wxWebViewConfiguration& config);
/**
Function to create a new wxWebView with parameters.
@param parent Parent window for the control
@@ -487,6 +593,14 @@ public:
@since 3.1.5
*/
virtual wxVersionInfo GetVersionInfo();
/**
Create a wxWebViewConfiguration object for wxWebView instances
created by this factory.
@since 3.3.0
*/
virtual wxWebViewConfiguration CreateConfiguration();
};
/**
@@ -847,6 +961,16 @@ public:
*/
static wxWebView* New(const wxString& backend = wxWebViewBackendDefault);
/**
Factory function to create a new wxWebView with two-step creation,
wxWebView::Create should be called on the returned object.
@param config a configuration object create with NewConfiguration().
@return The created wxWebView
@since 3.3.0
*/
static wxWebView* New(const wxWebViewConfiguration& config);
/**
Factory function to create a new wxWebView using a wxWebViewFactory.
@param parent Parent window for the control
@@ -906,6 +1030,13 @@ public:
*/
static wxVersionInfo GetBackendVersionInfo(const wxString& backend = wxWebViewBackendDefault);
/**
Create a new wxWebViewConfiguration object.
@since 3.3.0
*/
static wxWebViewConfiguration NewConfiguration(const wxString& backend = wxWebViewBackendDefault);
/**
Get the title of the current web page, or its URL/path if title is not
available.
@@ -945,48 +1076,6 @@ 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
+56
View File
@@ -15,6 +15,7 @@
#include "wx/webview.h"
#include "wx/filesys.h"
#include "wx/mstream.h"
#include "wx/private/webview.h"
#if defined(__WXOSX__)
#include "wx/osx/webview_webkit.h"
@@ -55,6 +56,36 @@ wxDEFINE_EVENT( wxEVT_WEBVIEW_FULLSCREEN_CHANGED, wxWebViewEvent);
wxDEFINE_EVENT( wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, wxWebViewEvent);
wxDEFINE_EVENT( wxEVT_WEBVIEW_SCRIPT_RESULT, wxWebViewEvent);
// wxWebViewConfigurationDefault
class wxWebViewConfigurationImplDefault : public wxWebViewConfigurationImpl
{
public:
virtual void* GetNativeConfiguration() const override
{
return nullptr;
}
};
// wxWebViewConfiguration
wxWebViewConfiguration::wxWebViewConfiguration(const wxString& backend, wxWebViewConfigurationImpl* impl):
m_backend(backend), m_impl(impl)
{ }
void* wxWebViewConfiguration::GetNativeConfiguration() const
{
return m_impl->GetNativeConfiguration();
}
void wxWebViewConfiguration::SetDataPath(const wxString &path)
{
m_impl->SetDataPath(path);
}
wxString wxWebViewConfiguration::GetDataPath() const
{
return m_impl->GetDataPath();
}
// wxWebViewHandlerRequest
wxString wxWebViewHandlerRequest::GetDataString(const wxMBConv& conv) const
{
@@ -370,6 +401,17 @@ wxWebView* wxWebView::New(const wxString& backend)
return (*iter).second->Create();
}
// static
wxWebView* wxWebView::New(const wxWebViewConfiguration& config)
{
wxStringWebViewFactoryMap::iterator iter = FindFactory(config.GetBackend());
if(iter == m_factoryMap.end())
return nullptr;
else
return (*iter).second->CreateWithConfig(config);
}
// static
wxWebView* wxWebView::New(wxWindow* parent, wxWindowID id, const wxString& url,
const wxPoint& pos, const wxSize& size,
@@ -411,6 +453,15 @@ wxVersionInfo wxWebView::GetBackendVersionInfo(const wxString& backend)
return wxVersionInfo();
}
wxWebViewConfiguration wxWebView::NewConfiguration(const wxString& backend)
{
wxStringWebViewFactoryMap::iterator iter = FindFactory(backend);
if (iter != m_factoryMap.end())
return iter->second->CreateConfiguration();
else
return wxWebViewConfiguration(backend, new wxWebViewConfigurationImplDefault);
}
// static
wxStringWebViewFactoryMap::iterator wxWebView::FindFactory(const wxString &backend)
{
@@ -458,4 +509,9 @@ void wxWebView::InitFactoryMap()
#endif
}
wxWebViewConfiguration wxWebViewFactory::CreateConfiguration()
{
return wxWebViewConfiguration(wxWebViewBackendDefault, new wxWebViewConfigurationImplDefault);
}
#endif // wxUSE_WEBVIEW
+118 -52
View File
@@ -22,9 +22,11 @@
#include "wx/stdpaths.h"
#include "wx/thread.h"
#include "wx/tokenzr.h"
#include "wx/uilocale.h"
#include "wx/uri.h"
#include "wx/private/jsscriptwrapper.h"
#include "wx/private/json.h"
#include "wx/private/webview.h"
#include "wx/msw/private.h"
#include "wx/msw/private/cotaskmemptr.h"
#include "wx/msw/private/webview_edge.h"
@@ -252,6 +254,72 @@ public:
wxCOMPtr<ICoreWebView2WebResourceRequestedEventArgs> m_args;
};
// wxWebViewConfigurationImplEdge
class wxWebViewConfigurationImplEdge : public wxWebViewConfigurationImpl
{
public:
wxWebViewConfigurationImplEdge(ICoreWebView2Environment* environment = nullptr):
m_webViewEnvironment(environment)
{
m_dataPath = wxStandardPaths::Get().GetUserLocalDataDir();
#ifdef __VISUALC__
m_webViewEnvironmentOptions = Make<CoreWebView2EnvironmentOptions>().Get();
m_webViewEnvironmentOptions->put_Language(wxUILocale::GetCurrent().GetLocaleId().GetName().wc_str());
#endif
}
virtual void* GetNativeConfiguration() const override
{
return m_webViewEnvironmentOptions;
}
virtual void SetDataPath(const wxString& path) override { m_dataPath = path;}
virtual wxString GetDataPath() const override { return m_dataPath; }
bool CreateOrGetEnvironment(wxWebViewEdgeImpl* impl)
{
if (!m_webViewEnvironment)
{
m_webViewsWaitingForEnvironment.push_back(impl);
HRESULT hr = wxCreateCoreWebView2EnvironmentWithOptions(
ms_browserExecutableDir.wc_str(),
GetDataPath().wc_str(),
m_webViewEnvironmentOptions,
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(this,
&wxWebViewConfigurationImplEdge::OnEnvironmentCreated).Get());
if (FAILED(hr))
{
wxLogApiError("CreateWebView2EnvironmentWithOptions", hr);
return false;
}
else
return true;
}
else
{
impl->EnvironmentAvailable(m_webViewEnvironment);
return true;
}
}
HRESULT OnEnvironmentCreated(HRESULT WXUNUSED(result), ICoreWebView2Environment* environment)
{
m_webViewEnvironment = environment;
for (auto impl : m_webViewsWaitingForEnvironment)
impl->EnvironmentAvailable(m_webViewEnvironment);
m_webViewsWaitingForEnvironment.clear();
return S_OK;
}
static wxString ms_browserExecutableDir;
std::vector<wxWebViewEdgeImpl*> m_webViewsWaitingForEnvironment;
wxCOMPtr<ICoreWebView2EnvironmentOptions> m_webViewEnvironmentOptions;
wxCOMPtr<ICoreWebView2Environment> m_webViewEnvironment;
wxString m_dataPath;
};
wxString wxWebViewConfigurationImplEdge::ms_browserExecutableDir;
// wxWebViewNewWindowInfoEdge
class wxWebViewNewWindowInfoEdge : public wxWebViewWindowInfo
@@ -330,7 +398,7 @@ public:
virtual wxWebView* CreateChildWebView() override
{
return m_impl->CreateChildWebView(
std::make_shared<wxWebViewEdgeParentWindowInfo>(m_impl, m_args));
std::make_shared<wxWebViewEdgeParentWindowInfo>(m_args));
}
private:
@@ -342,9 +410,7 @@ private:
class wxWebViewEdgeParentWindowInfo
{
public:
wxWebViewEdgeParentWindowInfo(wxWebViewEdgeImpl* impl,
ICoreWebView2NewWindowRequestedEventArgs* args):
m_impl(impl),
wxWebViewEdgeParentWindowInfo(ICoreWebView2NewWindowRequestedEventArgs* args):
m_args(args)
{
HRESULT hr = m_args->GetDeferral(&m_deferral);
@@ -354,7 +420,6 @@ public:
virtual ~wxWebViewEdgeParentWindowInfo() = default;
wxWebViewEdgeImpl* m_impl;
wxCOMPtr<ICoreWebView2NewWindowRequestedEventArgs> m_args;
wxCOMPtr<ICoreWebView2Deferral> m_deferral;
};
@@ -364,14 +429,16 @@ public:
m_inEventCallback = true; \
wxON_BLOCK_EXIT_SET(m_inEventCallback, false);
wxString wxWebViewEdgeImpl::ms_browserExecutableDir;
wxWebViewEdgeImpl::wxWebViewEdgeImpl(wxWebViewEdge* webview):
m_ctrl(webview)
wxWebViewEdgeImpl::wxWebViewEdgeImpl(wxWebViewEdge* webview, const wxWebViewConfiguration& config):
m_ctrl(webview),
m_config(config)
{
}
wxWebViewEdgeImpl::wxWebViewEdgeImpl(wxWebViewEdge* webview) :
m_ctrl(webview),
m_config(wxWebViewConfiguration(wxWebViewBackendEdge, new wxWebViewConfigurationImplEdge))
{
#ifdef __VISUALC__
m_webViewEnvironmentOptions = Make<CoreWebView2EnvironmentOptions>().Get();
#endif
}
wxWebViewEdgeImpl::~wxWebViewEdgeImpl()
@@ -405,47 +472,24 @@ bool wxWebViewEdgeImpl::Create()
m_historyEnabled = true;
m_historyPosition = -1;
wxString userDataPath = wxStandardPaths::Get().GetUserLocalDataDir();
if (m_parentWindowInfo)
{
OnEnvironmentCreated(S_OK, m_parentWindowInfo->m_impl->m_webViewEnvironment);
return true;
}
else
{
HRESULT hr = wxCreateCoreWebView2EnvironmentWithOptions(
ms_browserExecutableDir.wc_str(),
userDataPath.wc_str(),
m_webViewEnvironmentOptions,
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(this,
&wxWebViewEdgeImpl::OnEnvironmentCreated).Get());
if (FAILED(hr))
{
wxLogApiError("CreateWebView2EnvironmentWithOptions", hr);
return false;
}
else
return true;
}
return static_cast<wxWebViewConfigurationImplEdge*>(m_config.GetImpl())->
CreateOrGetEnvironment(this);
}
wxWebViewEdge* wxWebViewEdgeImpl::CreateChildWebView(std::shared_ptr<wxWebViewEdgeParentWindowInfo> parentWindowInfo)
{
wxWebViewEdge* childWebView = new wxWebViewEdge();
wxWebViewEdge* childWebView = new wxWebViewEdge(m_config);
childWebView->m_impl->m_parentWindowInfo = parentWindowInfo;
return childWebView;
}
HRESULT wxWebViewEdgeImpl::OnEnvironmentCreated(
HRESULT WXUNUSED(result), ICoreWebView2Environment* environment)
void wxWebViewEdgeImpl::EnvironmentAvailable(ICoreWebView2Environment* environment)
{
environment->QueryInterface(IID_PPV_ARGS(&m_webViewEnvironment));
m_webViewEnvironment->CreateCoreWebView2Controller(
m_ctrl->GetHWND(),
Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
this, &wxWebViewEdgeImpl::OnWebViewCreated).Get());
return S_OK;
}
bool wxWebViewEdgeImpl::Initialize()
@@ -467,7 +511,7 @@ bool wxWebViewEdgeImpl::Initialize()
// Check if a Edge browser can be found by the loader DLL
wxCoTaskMemPtr<wchar_t> versionStr;
HRESULT hr = wxGetAvailableCoreWebView2BrowserVersionString(
ms_browserExecutableDir.wc_str(), &versionStr);
wxWebViewConfigurationImplEdge::ms_browserExecutableDir.wc_str(), &versionStr);
if (FAILED(hr) || !versionStr)
{
wxLogApiError("GetCoreWebView2BrowserVersionInfo", hr);
@@ -527,6 +571,18 @@ HRESULT wxWebViewEdgeImpl::HandleNavigationStarting(ICoreWebView2NavigationStart
return S_OK;
}
void wxWebViewEdgeImpl::SendErrorEventForAPI(const wxString& api, HRESULT errorCode)
{
wxLogApiError(api, errorCode);
wxWebViewEvent event(wxEVT_WEBVIEW_ERROR, m_ctrl->GetId(), wxString(), wxString());
event.SetEventObject(m_ctrl);
event.SetInt(wxWEBVIEW_NAV_ERR_OTHER);
event.SetString(wxSysErrorMsgStr(errorCode));
m_ctrl->GetEventHandler()->AddPendingEvent(event);
}
HRESULT wxWebViewEdgeImpl::OnSourceChanged(ICoreWebView2 * WXUNUSED(sender), ICoreWebView2SourceChangedEventArgs * args)
{
BOOL isNewDocument;
@@ -744,7 +800,7 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control
{
if (FAILED(result))
{
wxLogApiError("WebView2::WebViewCreated", result);
SendErrorEventForAPI("WebView2::WebViewCreated", result);
return result;
}
@@ -752,13 +808,13 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control
HRESULT hr = webViewController->get_CoreWebView2(&baseWebView);
if (FAILED(hr))
{
wxLogApiError("WebView2::WebViewCreated (get_CoreWebView2)", hr);
SendErrorEventForAPI("WebView2::WebViewCreated (get_CoreWebView2)", hr);
return result;
}
hr = baseWebView->QueryInterface(IID_PPV_ARGS(&m_webView));
if (FAILED(hr))
{
wxLogApiError("WebView2::WebViewCreated (QueryInterface)", hr);
SendErrorEventForAPI("WebView2::WebViewCreated (QueryInterface)", hr);
return result;
}
@@ -863,9 +919,9 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control
if (m_parentWindowInfo)
{
if (FAILED(m_parentWindowInfo->m_args->put_NewWindow(baseWebView)))
wxLogApiError("WebView2::WebViewCreated (put_NewWindow)", hr);
SendErrorEventForAPI("WebView2::WebViewCreated (put_NewWindow)", hr);
if (FAILED(m_parentWindowInfo->m_deferral->Complete()))
wxLogApiError("WebView2::WebViewCreated (Complete)", hr);
SendErrorEventForAPI("WebView2::WebViewCreated (Complete)", hr);
m_parentWindowInfo.reset();
return S_OK;
@@ -943,6 +999,11 @@ wxWebViewEdge::wxWebViewEdge():
}
wxWebViewEdge::wxWebViewEdge(const wxWebViewConfiguration& config):
m_impl(new wxWebViewEdgeImpl(this, config))
{
}
wxWebViewEdge::wxWebViewEdge(wxWindow* parent,
wxWindowID id,
const wxString& url,
@@ -1321,14 +1382,9 @@ 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;
wxWebViewConfigurationImplEdge::ms_browserExecutableDir = path;
}
bool wxWebViewEdge::RunScript(const wxString& javascript, wxString* output) const
@@ -1466,6 +1522,11 @@ void wxWebViewEdge::DoSetPage(const wxString& html, const wxString& WXUNUSED(bas
// wxWebViewFactoryEdge
wxWebView* wxWebViewFactoryEdge::CreateWithConfig(const wxWebViewConfiguration& config)
{
return new wxWebViewEdge(config);
}
bool wxWebViewFactoryEdge::IsAvailable()
{
return wxWebViewEdgeImpl::Initialize();
@@ -1482,7 +1543,7 @@ wxVersionInfo wxWebViewFactoryEdge::GetVersionInfo()
{
wxCoTaskMemPtr<wchar_t> nativeVersionStr;
HRESULT hr = wxGetAvailableCoreWebView2BrowserVersionString(
wxWebViewEdgeImpl::ms_browserExecutableDir.wc_str(), &nativeVersionStr);
wxWebViewConfigurationImplEdge::ms_browserExecutableDir.wc_str(), &nativeVersionStr);
if (SUCCEEDED(hr) && nativeVersionStr)
{
wxStringTokenizer tk(wxString(nativeVersionStr), ". ");
@@ -1499,6 +1560,11 @@ wxVersionInfo wxWebViewFactoryEdge::GetVersionInfo()
return wxVersionInfo("Microsoft Edge WebView2", major, minor, micro, revision);
}
wxWebViewConfiguration wxWebViewFactoryEdge::CreateConfiguration()
{
return wxWebViewConfiguration(wxWebViewBackendEdge, new wxWebViewConfigurationImplEdge);
}
// ----------------------------------------------------------------------------
// Module ensuring all global/singleton objects are destroyed on shutdown.
// ----------------------------------------------------------------------------
+37 -14
View File
@@ -26,6 +26,7 @@
#include "wx/osx/core/cfref.h"
#include "wx/osx/private/available.h"
#include "wx/private/jsscriptwrapper.h"
#include "wx/private/webview.h"
#include "wx/hashmap.h"
#include "wx/filesys.h"
@@ -45,8 +46,6 @@
// macros
// ----------------------------------------------------------------------------
wxIMPLEMENT_DYNAMIC_CLASS(wxWebViewWebKit, wxWebView);
wxBEGIN_EVENT_TABLE(wxWebViewWebKit, wxControl)
wxEND_EVENT_TABLE()
@@ -99,6 +98,30 @@ wxEND_EVENT_TABLE()
@end
//-----------------------------------------------------------------------------
// wxWebViewConfigurationImplWebKit
//-----------------------------------------------------------------------------
class wxWebViewConfigurationImplWebKit: public wxWebViewConfigurationImpl
{
public:
wxWebViewConfigurationImplWebKit(WKWebViewConfiguration* config):
m_webViewConfiguration([config retain])
{
}
~wxWebViewConfigurationImplWebKit()
{
[m_webViewConfiguration release];
}
virtual void* GetNativeConfiguration() const override
{
return m_webViewConfiguration;
}
WKWebViewConfiguration* m_webViewConfiguration;
};
//-----------------------------------------------------------------------------
// wxWebViewFactoryWebKit
//-----------------------------------------------------------------------------
@@ -110,6 +133,12 @@ wxVersionInfo wxWebViewFactoryWebKit::GetVersionInfo()
return wxVersionInfo("WKWebView", verMaj, verMin, verMicro);
}
wxWebViewConfiguration wxWebViewFactoryWebKit::CreateConfiguration()
{
return wxWebViewConfiguration(wxWebViewBackendWebKit,
new wxWebViewConfigurationImplWebKit([[WKWebViewConfiguration alloc] init]));
}
//-----------------------------------------------------------------------------
// wxWebViewWindowInfoWebKit
//-----------------------------------------------------------------------------
@@ -179,7 +208,8 @@ public:
virtual wxWebView* CreateChildWebView() override
{
m_childWebView = new wxWebViewWebKit(this);
m_childWebView = new wxWebViewWebKit(wxWebViewConfiguration(wxWebViewBackendWebKit,
new wxWebViewConfigurationImplWebKit(m_configuration)), this);
return m_childWebView;
}
@@ -194,9 +224,10 @@ public:
// creation/destruction
// ----------------------------------------------------------------------------
void wxWebViewWebKit::Init()
wxWebViewWebKit::wxWebViewWebKit(const wxWebViewConfiguration& config, wxWebViewWindowInfoWebKit* parentWindowInfo):
m_configuration(config),
m_parentWindowInfo(parentWindowInfo)
{
m_webViewConfiguration = [[WKWebViewConfiguration alloc] init];
}
bool wxWebViewWebKit::Create(wxWindow *parent,
@@ -210,8 +241,7 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
wxControl::Create(parent, winID, pos, size, style, wxDefaultValidator, name);
NSRect r = wxOSXGetFrameForControl( this, pos , size ) ;
WKWebViewConfiguration* webViewConfig = (m_parentWindowInfo) ?
m_parentWindowInfo->m_configuration : (WKWebViewConfiguration*) m_webViewConfiguration;
WKWebViewConfiguration* webViewConfig = (WKWebViewConfiguration*) m_configuration.GetNativeConfiguration();
if (!m_handlers.empty() && !m_parentWindowInfo)
{
@@ -235,13 +265,6 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
MacPostControlCreate(pos, size);
if (!m_parentWindowInfo)
{
// WKWebView configuration is only used during creation
[m_webViewConfiguration release];
m_webViewConfiguration = nil;
}
if (!m_customUserAgent.empty())
SetUserAgent(m_customUserAgent);