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

View File

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

View File

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

View File

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

View File

@@ -187,6 +187,8 @@ public:
virtual void Print() = 0;
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) = 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
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const = 0;

View File

@@ -889,6 +889,28 @@ 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

@@ -161,6 +161,7 @@ public:
void OnRunScriptMessage(wxCommandEvent& evt);
void OnRunScriptCustom(wxCommandEvent& evt);
void OnAddUserScript(wxCommandEvent& evt);
void OnSetCustomUserAgent(wxCommandEvent& evt);
void OnClearSelection(wxCommandEvent& evt);
void OnDeleteSelection(wxCommandEvent& evt);
void OnSelectAll(wxCommandEvent& evt);
@@ -393,9 +394,6 @@ WebFrame::WebFrame(const wxString& url) :
#endif
// Create the webview
m_browser = wxWebView::New();
// Log backend information
wxLogMessage("Backend: %s Version: %s", m_browser->GetClassInfo()->GetClassName(),
wxWebView::GetBackendVersionInfo().ToString());
#ifdef __WXMAC__
// With WKWebView handlers need to be registered before creation
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);
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__
//We register the wxfs:// protocol for testing purposes
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_tools_menu->AppendSubMenu(script_menu, _("Run 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
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::OnRunScriptCustom, this, m_script_custom->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::OnDeleteSelection, this, m_selection_delete->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");
}
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))
{
m_browser->ClearSelection();

View File

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

View File

@@ -651,6 +651,9 @@ bool wxWebViewWebKit::Create(wxWindow *parent,
GTKCreateScrolledWindowWith(GTK_WIDGET(m_web_view));
g_object_ref(m_widget);
if (!m_customUserAgent.empty())
SetUserAgent(m_customUserAgent);
g_signal_connect(m_web_view, "decide-policy",
G_CALLBACK(wxgtk_webview_webkit_decide_policy),
this);
@@ -756,6 +759,18 @@ bool wxWebViewWebKit::IsAccessToDevToolsEnabled() const
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()
{
webkit_web_view_stop_loading(m_web_view);

View File

@@ -29,6 +29,7 @@
#ifdef __VISUALC__
#include <wrl/event.h>
using namespace Microsoft::WRL;
#include "WebView2EnvironmentOptions.h"
#else
#include <wx/msw/wrl/event.h>
#endif // !__VISUALC__
@@ -91,11 +92,23 @@ bool wxWebViewEdgeImpl::Create()
m_historyPosition = -1;
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(
ms_browserExecutableDir.wc_str(),
userDataPath.wc_str(),
#ifdef __VISUALC__
options.Get(),
#else
nullptr,
#endif
Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(this,
&wxWebViewEdgeImpl::OnEnvironmentCreated).Get());
if (FAILED(hr))
@@ -476,6 +489,24 @@ ICoreWebView2Settings* wxWebViewEdgeImpl::GetSettings()
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()
{
wxWindow* topLevelParent = wxGetTopLevelParent(this);
@@ -501,7 +532,6 @@ bool wxWebViewEdge::Create(wxWindow* parent,
return false;
}
m_impl = new wxWebViewEdgeImpl(this);
if (!m_impl->Create())
return false;
Bind(wxEVT_SIZE, &wxWebViewEdge::OnSize, this);
@@ -761,6 +791,20 @@ bool wxWebViewEdge::IsAccessToDevToolsEnabled() const
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
{
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 scriptExecuted = false;
if (!m_impl->m_webView)
return false;
// Start script execution
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);
if (!m_customUserAgent.empty())
SetUserAgent(m_customUserAgent);
[m_webView setHidden:false];
@@ -328,6 +331,21 @@ void wxWebViewWebKit::EnableAccessToDevTools(bool 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)
{
// there is only one supported zoom type at the moment so this setter