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

Add support for custom user agent to wxWebView.

See https://github.com/wxWidgets/wxWidgets/pull/2280
This commit is contained in:
Vadim Zeitlin
2021-03-19 22:39:00 +01:00
11 changed files with 146 additions and 9 deletions

View File

@@ -81,6 +81,7 @@ public:
#if wxUSE_WEBVIEW_WEBKIT2 #if wxUSE_WEBVIEW_WEBKIT2
virtual void EnableAccessToDevTools(bool enable = true) wxOVERRIDE; virtual void EnableAccessToDevTools(bool enable = true) wxOVERRIDE;
virtual bool IsAccessToDevToolsEnabled() const wxOVERRIDE; virtual bool IsAccessToDevToolsEnabled() const wxOVERRIDE;
virtual bool SetUserAgent(const wxString& userAgent) wxOVERRIDE;
#endif #endif
void SetZoomType(wxWebViewZoomType) wxOVERRIDE; void SetZoomType(wxWebViewZoomType) wxOVERRIDE;
@@ -176,6 +177,7 @@ private:
#endif #endif
WebKitWebView *m_web_view; WebKitWebView *m_web_view;
wxString m_customUserAgent;
int m_historyLimit; int m_historyLimit;
wxVector<wxSharedPtr<wxWebViewHandler> > m_handlerList; wxVector<wxSharedPtr<wxWebViewHandler> > m_handlerList;

View File

@@ -58,6 +58,7 @@ public:
wxVector<wxString> m_pendingUserScripts; wxVector<wxString> m_pendingUserScripts;
wxVector<wxString> m_userScriptIds; wxVector<wxString> m_userScriptIds;
wxString m_scriptMsgHandlerName; wxString m_scriptMsgHandlerName;
wxString m_customUserAgent;
// WebView Events tokens // WebView Events tokens
EventRegistrationToken m_navigationStartingToken = { }; EventRegistrationToken m_navigationStartingToken = { };

View File

@@ -23,7 +23,7 @@ class WXDLLIMPEXP_WEBVIEW wxWebViewEdge : public wxWebView
{ {
public: public:
wxWebViewEdge() {} wxWebViewEdge();
wxWebViewEdge(wxWindow* parent, wxWebViewEdge(wxWindow* parent,
wxWindowID id, wxWindowID id,
@@ -31,10 +31,7 @@ public:
const wxPoint& pos = wxDefaultPosition, const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize, const wxSize& size = wxDefaultSize,
long style = 0, long style = 0,
const wxString& name = wxWebViewNameStr) const wxString& name = wxWebViewNameStr);
{
Create(parent, id, url, pos, size, style, name);
}
~wxWebViewEdge(); ~wxWebViewEdge();
@@ -89,6 +86,8 @@ public:
virtual void EnableAccessToDevTools(bool enable = true) wxOVERRIDE; virtual void EnableAccessToDevTools(bool enable = true) wxOVERRIDE;
virtual bool IsAccessToDevToolsEnabled() const wxOVERRIDE; virtual bool IsAccessToDevToolsEnabled() const wxOVERRIDE;
virtual bool SetUserAgent(const wxString& userAgent) wxOVERRIDE;
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const wxOVERRIDE; virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const wxOVERRIDE;
virtual bool AddScriptMessageHandler(const wxString& name) wxOVERRIDE; virtual bool AddScriptMessageHandler(const wxString& name) wxOVERRIDE;
virtual bool RemoveScriptMessageHandler(const wxString& name) wxOVERRIDE; virtual bool RemoveScriptMessageHandler(const wxString& name) wxOVERRIDE;

View File

@@ -73,6 +73,7 @@ public:
virtual bool IsAccessToDevToolsEnabled() const wxOVERRIDE; virtual bool IsAccessToDevToolsEnabled() const wxOVERRIDE;
virtual void EnableAccessToDevTools(bool enable = true) wxOVERRIDE; virtual void EnableAccessToDevTools(bool enable = true) wxOVERRIDE;
virtual bool SetUserAgent(const wxString& userAgent) wxOVERRIDE;
//History functions //History functions
virtual void ClearHistory() wxOVERRIDE; virtual void ClearHistory() wxOVERRIDE;
@@ -111,6 +112,7 @@ protected:
private: private:
OSXWebViewPtr m_webView; OSXWebViewPtr m_webView;
wxStringToWebHandlerMap m_handlers; wxStringToWebHandlerMap m_handlers;
wxString m_customUserAgent;
WX_NSObject m_navigationDelegate; WX_NSObject m_navigationDelegate;
WX_NSObject m_UIDelegate; WX_NSObject m_UIDelegate;

View File

@@ -187,6 +187,8 @@ public:
virtual void Print() = 0; virtual void Print() = 0;
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) = 0; virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) = 0;
virtual void Reload(wxWebViewReloadFlags flags = wxWEBVIEW_RELOAD_DEFAULT) = 0; virtual void Reload(wxWebViewReloadFlags flags = wxWEBVIEW_RELOAD_DEFAULT) = 0;
virtual bool SetUserAgent(const wxString& userAgent) { wxUnusedVar(userAgent); return false; }
virtual wxString GetUserAgent() const;
// Script // Script
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const = 0; virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const = 0;

View File

@@ -889,6 +889,28 @@ public:
*/ */
virtual bool IsAccessToDevToolsEnabled() const; 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 @name History
*/ */

View File

@@ -161,6 +161,7 @@ public:
void OnRunScriptMessage(wxCommandEvent& evt); void OnRunScriptMessage(wxCommandEvent& evt);
void OnRunScriptCustom(wxCommandEvent& evt); void OnRunScriptCustom(wxCommandEvent& evt);
void OnAddUserScript(wxCommandEvent& evt); void OnAddUserScript(wxCommandEvent& evt);
void OnSetCustomUserAgent(wxCommandEvent& evt);
void OnClearSelection(wxCommandEvent& evt); void OnClearSelection(wxCommandEvent& evt);
void OnDeleteSelection(wxCommandEvent& evt); void OnDeleteSelection(wxCommandEvent& evt);
void OnSelectAll(wxCommandEvent& evt); void OnSelectAll(wxCommandEvent& evt);
@@ -393,9 +394,6 @@ WebFrame::WebFrame(const wxString& url) :
#endif #endif
// Create the webview // Create the webview
m_browser = wxWebView::New(); m_browser = wxWebView::New();
// Log backend information
wxLogMessage("Backend: %s Version: %s", m_browser->GetClassInfo()->GetClassName(),
wxWebView::GetBackendVersionInfo().ToString());
#ifdef __WXMAC__ #ifdef __WXMAC__
// With WKWebView handlers need to be registered before creation // With WKWebView handlers need to be registered before creation
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewArchiveHandler("wxfs"))); m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewArchiveHandler("wxfs")));
@@ -404,6 +402,11 @@ WebFrame::WebFrame(const wxString& url) :
m_browser->Create(this, wxID_ANY, url, wxDefaultPosition, wxDefaultSize); m_browser->Create(this, wxID_ANY, url, wxDefaultPosition, wxDefaultSize);
topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1)); topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1));
// Log backend information
wxLogMessage("Backend: %s Version: %s", m_browser->GetClassInfo()->GetClassName(),
wxWebView::GetBackendVersionInfo().ToString());
wxLogMessage("User Agent: %s", m_browser->GetUserAgent());
#ifndef __WXMAC__ #ifndef __WXMAC__
//We register the wxfs:// protocol for testing purposes //We register the wxfs:// protocol for testing purposes
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewArchiveHandler("wxfs"))); m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewArchiveHandler("wxfs")));
@@ -493,6 +496,7 @@ WebFrame::WebFrame(const wxString& url) :
m_script_custom = script_menu->Append(wxID_ANY, "Custom script"); m_script_custom = script_menu->Append(wxID_ANY, "Custom script");
m_tools_menu->AppendSubMenu(script_menu, _("Run Script")); m_tools_menu->AppendSubMenu(script_menu, _("Run Script"));
wxMenuItem* addUserScript = m_tools_menu->Append(wxID_ANY, _("Add user script")); wxMenuItem* addUserScript = m_tools_menu->Append(wxID_ANY, _("Add user script"));
wxMenuItem* setCustomUserAgent = m_tools_menu->Append(wxID_ANY, _("Set custom user agent"));
//Selection menu //Selection menu
wxMenu* selection = new wxMenu(); wxMenu* selection = new wxMenu();
@@ -593,6 +597,7 @@ WebFrame::WebFrame(const wxString& url) :
Bind(wxEVT_MENU, &WebFrame::OnRunScriptMessage, this, m_script_message->GetId()); Bind(wxEVT_MENU, &WebFrame::OnRunScriptMessage, this, m_script_message->GetId());
Bind(wxEVT_MENU, &WebFrame::OnRunScriptCustom, this, m_script_custom->GetId()); Bind(wxEVT_MENU, &WebFrame::OnRunScriptCustom, this, m_script_custom->GetId());
Bind(wxEVT_MENU, &WebFrame::OnAddUserScript, this, addUserScript->GetId()); Bind(wxEVT_MENU, &WebFrame::OnAddUserScript, this, addUserScript->GetId());
Bind(wxEVT_MENU, &WebFrame::OnSetCustomUserAgent, this, setCustomUserAgent->GetId());
Bind(wxEVT_MENU, &WebFrame::OnClearSelection, this, m_selection_clear->GetId()); Bind(wxEVT_MENU, &WebFrame::OnClearSelection, this, m_selection_clear->GetId());
Bind(wxEVT_MENU, &WebFrame::OnDeleteSelection, this, m_selection_delete->GetId()); Bind(wxEVT_MENU, &WebFrame::OnDeleteSelection, this, m_selection_delete->GetId());
Bind(wxEVT_MENU, &WebFrame::OnSelectAll, this, selectall->GetId()); Bind(wxEVT_MENU, &WebFrame::OnSelectAll, this, selectall->GetId());
@@ -1230,6 +1235,24 @@ void WebFrame::OnAddUserScript(wxCommandEvent & WXUNUSED(evt))
wxLogError("Could not add user script"); wxLogError("Could not add user script");
} }
void WebFrame::OnSetCustomUserAgent(wxCommandEvent& WXUNUSED(evt))
{
wxString customUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.1 Mobile/15E148 Safari/604.1";
wxTextEntryDialog dialog
(
this,
"Enter the custom user agent string you would like to use.",
wxGetTextFromUserPromptStr,
customUserAgent,
wxOK | wxCANCEL | wxCENTRE
);
if (dialog.ShowModal() != wxID_OK)
return;
if (!m_browser->SetUserAgent(customUserAgent))
wxLogError("Could not set custom user agent");
}
void WebFrame::OnClearSelection(wxCommandEvent& WXUNUSED(evt)) void WebFrame::OnClearSelection(wxCommandEvent& WXUNUSED(evt))
{ {
m_browser->ClearSelection(); m_browser->ClearSelection();

View File

@@ -217,6 +217,13 @@ long wxWebView::Find(const wxString& text, int flags)
return 1; return 1;
} }
wxString wxWebView::GetUserAgent() const
{
wxString userAgent;
RunScript("navigator.userAgent", &userAgent);
return userAgent;
}
// static // static
wxWebView* wxWebView::New(const wxString& backend) wxWebView* wxWebView::New(const wxString& backend)
{ {

View File

@@ -651,6 +651,9 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
GTKCreateScrolledWindowWith(GTK_WIDGET(m_web_view)); GTKCreateScrolledWindowWith(GTK_WIDGET(m_web_view));
g_object_ref(m_widget); g_object_ref(m_widget);
if (!m_customUserAgent.empty())
SetUserAgent(m_customUserAgent);
g_signal_connect(m_web_view, "decide-policy", g_signal_connect(m_web_view, "decide-policy",
G_CALLBACK(wxgtk_webview_webkit_decide_policy), G_CALLBACK(wxgtk_webview_webkit_decide_policy),
this); this);
@@ -756,6 +759,18 @@ bool wxWebViewWebKit::IsAccessToDevToolsEnabled() const
return webkit_settings_get_enable_developer_extras(settings); return webkit_settings_get_enable_developer_extras(settings);
} }
bool wxWebViewWebKit::SetUserAgent(const wxString& userAgent)
{
if (m_web_view)
{
WebKitSettings* settings = webkit_web_view_get_settings(m_web_view);
webkit_settings_set_user_agent(settings, userAgent.utf8_str());
}
else
m_customUserAgent = userAgent;
return true;
}
void wxWebViewWebKit::Stop() void wxWebViewWebKit::Stop()
{ {
webkit_web_view_stop_loading(m_web_view); webkit_web_view_stop_loading(m_web_view);

View File

@@ -29,6 +29,7 @@
#ifdef __VISUALC__ #ifdef __VISUALC__
#include <wrl/event.h> #include <wrl/event.h>
using namespace Microsoft::WRL; using namespace Microsoft::WRL;
#include "WebView2EnvironmentOptions.h"
#else #else
#include <wx/msw/wrl/event.h> #include <wx/msw/wrl/event.h>
#endif // !__VISUALC__ #endif // !__VISUALC__
@@ -91,11 +92,23 @@ bool wxWebViewEdgeImpl::Create()
m_historyPosition = -1; m_historyPosition = -1;
wxString userDataPath = wxStandardPaths::Get().GetUserLocalDataDir(); wxString userDataPath = wxStandardPaths::Get().GetUserLocalDataDir();
#ifdef __VISUALC__
auto options =
Make<CoreWebView2EnvironmentOptions>();
if (!m_customUserAgent.empty())
options->put_AdditionalBrowserArguments(
wxString::Format("--user-agent=\"%s\"", m_customUserAgent).wc_str());
#endif
HRESULT hr = wxCreateCoreWebView2EnvironmentWithOptions( HRESULT hr = wxCreateCoreWebView2EnvironmentWithOptions(
ms_browserExecutableDir.wc_str(), ms_browserExecutableDir.wc_str(),
userDataPath.wc_str(), userDataPath.wc_str(),
#ifdef __VISUALC__
options.Get(),
#else
nullptr, nullptr,
#endif
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(this, Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(this,
&wxWebViewEdgeImpl::OnEnvironmentCreated).Get()); &wxWebViewEdgeImpl::OnEnvironmentCreated).Get());
if (FAILED(hr)) if (FAILED(hr))
@@ -476,6 +489,24 @@ ICoreWebView2Settings* wxWebViewEdgeImpl::GetSettings()
return settings; return settings;
} }
wxWebViewEdge::wxWebViewEdge():
m_impl(new wxWebViewEdgeImpl(this))
{
}
wxWebViewEdge::wxWebViewEdge(wxWindow* parent,
wxWindowID id,
const wxString& url,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString& name):
m_impl(new wxWebViewEdgeImpl(this))
{
Create(parent, id, url, pos, size, style, name);
}
wxWebViewEdge::~wxWebViewEdge() wxWebViewEdge::~wxWebViewEdge()
{ {
wxWindow* topLevelParent = wxGetTopLevelParent(this); wxWindow* topLevelParent = wxGetTopLevelParent(this);
@@ -501,7 +532,6 @@ bool wxWebViewEdge::Create(wxWindow* parent,
return false; return false;
} }
m_impl = new wxWebViewEdgeImpl(this);
if (!m_impl->Create()) if (!m_impl->Create())
return false; return false;
Bind(wxEVT_SIZE, &wxWebViewEdge::OnSize, this); Bind(wxEVT_SIZE, &wxWebViewEdge::OnSize, this);
@@ -761,6 +791,20 @@ bool wxWebViewEdge::IsAccessToDevToolsEnabled() const
return true; return true;
} }
bool wxWebViewEdge::SetUserAgent(const wxString& userAgent)
{
m_impl->m_customUserAgent = userAgent;
// Can currently only be set before Create()
wxCHECK_MSG(!m_impl->m_webViewController, false, "Can't be called after Create()");
if (m_impl->m_webViewController)
return false;
else
return true;
// TODO: As of Edge SDK 1.0.790 an experimental API to set the user agent
// is available. Reimplement using m_impl->GetSettings() when it's stable.
}
void* wxWebViewEdge::GetNativeBackend() const void* wxWebViewEdge::GetNativeBackend() const
{ {
return m_impl->m_webView; return m_impl->m_webView;
@@ -774,6 +818,8 @@ void wxWebViewEdge::MSWSetBrowserExecutableDir(const wxString & path)
bool wxWebViewEdge::RunScriptSync(const wxString& javascript, wxString* output) const bool wxWebViewEdge::RunScriptSync(const wxString& javascript, wxString* output) const
{ {
bool scriptExecuted = false; bool scriptExecuted = false;
if (!m_impl->m_webView)
return false;
// Start script execution // Start script execution
HRESULT executionResult = m_impl->m_webView->ExecuteScript(javascript.wc_str(), Callback<ICoreWebView2ExecuteScriptCompletedHandler>( HRESULT executionResult = m_impl->m_webView->ExecuteScript(javascript.wc_str(), Callback<ICoreWebView2ExecuteScriptCompletedHandler>(

View File

@@ -151,6 +151,9 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
MacPostControlCreate(pos, size); MacPostControlCreate(pos, size);
if (!m_customUserAgent.empty())
SetUserAgent(m_customUserAgent);
[m_webView setHidden:false]; [m_webView setHidden:false];
@@ -328,6 +331,21 @@ void wxWebViewWebKit::EnableAccessToDevTools(bool enable)
[prefs performSelector:devToolsSelector withObject:(id)enable]; [prefs performSelector:devToolsSelector withObject:(id)enable];
} }
bool wxWebViewWebKit::SetUserAgent(const wxString& userAgent)
{
if (WX_IS_MACOS_AVAILABLE(10, 11))
{
if (m_webView)
m_webView.customUserAgent = wxCFStringRef(userAgent).AsNSString();
else
m_customUserAgent = userAgent;
return true;
}
else
return false;
}
void wxWebViewWebKit::SetZoomType(wxWebViewZoomType zoomType) void wxWebViewWebKit::SetZoomType(wxWebViewZoomType zoomType)
{ {
// there is only one supported zoom type at the moment so this setter // there is only one supported zoom type at the moment so this setter