Merge branch 'webview_script_message' of https://github.com/TcT2k/wxWidgets
Add WebView script message and user scripts. See https://github.com/wxWidgets/wxWidgets/pull/2237
This commit is contained in:
@@ -78,6 +78,10 @@ public:
|
|||||||
virtual wxString GetPageText() const wxOVERRIDE;
|
virtual wxString GetPageText() const wxOVERRIDE;
|
||||||
virtual void Print() wxOVERRIDE;
|
virtual void Print() wxOVERRIDE;
|
||||||
virtual bool IsBusy() const wxOVERRIDE;
|
virtual bool IsBusy() const wxOVERRIDE;
|
||||||
|
#if wxUSE_WEBVIEW_WEBKIT2
|
||||||
|
virtual void EnableAccessToDevTools(bool enable = true) wxOVERRIDE;
|
||||||
|
virtual bool IsAccessToDevToolsEnabled() const wxOVERRIDE;
|
||||||
|
#endif
|
||||||
|
|
||||||
void SetZoomType(wxWebViewZoomType) wxOVERRIDE;
|
void SetZoomType(wxWebViewZoomType) wxOVERRIDE;
|
||||||
wxWebViewZoomType GetZoomType() const wxOVERRIDE;
|
wxWebViewZoomType GetZoomType() const wxOVERRIDE;
|
||||||
@@ -115,6 +119,13 @@ public:
|
|||||||
virtual void ClearSelection() wxOVERRIDE;
|
virtual void ClearSelection() wxOVERRIDE;
|
||||||
|
|
||||||
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const wxOVERRIDE;
|
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const wxOVERRIDE;
|
||||||
|
#if wxUSE_WEBVIEW_WEBKIT2
|
||||||
|
virtual bool AddScriptMessageHandler(const wxString& name) wxOVERRIDE;
|
||||||
|
virtual bool RemoveScriptMessageHandler(const wxString& name) wxOVERRIDE;
|
||||||
|
virtual bool AddUserScript(const wxString& javascript,
|
||||||
|
wxWebViewUserScriptInjectionTime injectionTime = wxWEBVIEW_INJECT_AT_DOCUMENT_START) wxOVERRIDE;
|
||||||
|
virtual void RemoveAllUserScripts() wxOVERRIDE;
|
||||||
|
#endif
|
||||||
|
|
||||||
//Virtual Filesystem Support
|
//Virtual Filesystem Support
|
||||||
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
|
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
|
||||||
|
@@ -55,6 +55,9 @@ public:
|
|||||||
wxString m_pendingURL;
|
wxString m_pendingURL;
|
||||||
int m_pendingContextMenuEnabled;
|
int m_pendingContextMenuEnabled;
|
||||||
int m_pendingAccessToDevToolsEnabled;
|
int m_pendingAccessToDevToolsEnabled;
|
||||||
|
wxVector<wxString> m_pendingUserScripts;
|
||||||
|
wxVector<wxString> m_userScriptIds;
|
||||||
|
wxString m_scriptMsgHandlerName;
|
||||||
|
|
||||||
// WebView Events tokens
|
// WebView Events tokens
|
||||||
EventRegistrationToken m_navigationStartingToken = { };
|
EventRegistrationToken m_navigationStartingToken = { };
|
||||||
@@ -64,6 +67,7 @@ public:
|
|||||||
EventRegistrationToken m_documentTitleChangedToken = { };
|
EventRegistrationToken m_documentTitleChangedToken = { };
|
||||||
EventRegistrationToken m_contentLoadingToken = { };
|
EventRegistrationToken m_contentLoadingToken = { };
|
||||||
EventRegistrationToken m_containsFullScreenElementChangedToken = { };
|
EventRegistrationToken m_containsFullScreenElementChangedToken = { };
|
||||||
|
EventRegistrationToken m_webMessageReceivedToken = { };
|
||||||
|
|
||||||
// WebView Event handlers
|
// WebView Event handlers
|
||||||
HRESULT OnNavigationStarting(ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args);
|
HRESULT OnNavigationStarting(ICoreWebView2* sender, ICoreWebView2NavigationStartingEventArgs* args);
|
||||||
@@ -73,6 +77,8 @@ public:
|
|||||||
HRESULT OnDocumentTitleChanged(ICoreWebView2* sender, IUnknown* args);
|
HRESULT OnDocumentTitleChanged(ICoreWebView2* sender, IUnknown* args);
|
||||||
HRESULT OnContentLoading(ICoreWebView2* sender, ICoreWebView2ContentLoadingEventArgs* args);
|
HRESULT OnContentLoading(ICoreWebView2* sender, ICoreWebView2ContentLoadingEventArgs* args);
|
||||||
HRESULT OnContainsFullScreenElementChanged(ICoreWebView2* sender, IUnknown* args);
|
HRESULT OnContainsFullScreenElementChanged(ICoreWebView2* sender, IUnknown* args);
|
||||||
|
HRESULT OnWebMessageReceived(ICoreWebView2* sender, ICoreWebView2WebMessageReceivedEventArgs* args);
|
||||||
|
HRESULT OnAddScriptToExecuteOnDocumentedCreatedCompleted(HRESULT errorCode, LPCWSTR id);
|
||||||
|
|
||||||
HRESULT OnEnvironmentCreated(HRESULT result, ICoreWebView2Environment* environment);
|
HRESULT OnEnvironmentCreated(HRESULT result, ICoreWebView2Environment* environment);
|
||||||
HRESULT OnWebViewCreated(HRESULT result, ICoreWebView2Controller* webViewController);
|
HRESULT OnWebViewCreated(HRESULT result, ICoreWebView2Controller* webViewController);
|
||||||
@@ -86,6 +92,8 @@ public:
|
|||||||
|
|
||||||
ICoreWebView2Settings* GetSettings();
|
ICoreWebView2Settings* GetSettings();
|
||||||
|
|
||||||
|
void UpdateWebMessageHandler();
|
||||||
|
|
||||||
static wxDynamicLibrary ms_loaderDll;
|
static wxDynamicLibrary ms_loaderDll;
|
||||||
static wxString ms_browserExecutableDir;
|
static wxString ms_browserExecutableDir;
|
||||||
static wxString ms_version;
|
static wxString ms_version;
|
||||||
|
@@ -90,6 +90,11 @@ public:
|
|||||||
virtual bool IsAccessToDevToolsEnabled() const wxOVERRIDE;
|
virtual bool IsAccessToDevToolsEnabled() const 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 RemoveScriptMessageHandler(const wxString& name) wxOVERRIDE;
|
||||||
|
virtual bool AddUserScript(const wxString& javascript,
|
||||||
|
wxWebViewUserScriptInjectionTime injectionTime = wxWEBVIEW_INJECT_AT_DOCUMENT_START) wxOVERRIDE;
|
||||||
|
virtual void RemoveAllUserScripts() wxOVERRIDE;
|
||||||
|
|
||||||
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
|
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
|
||||||
|
|
||||||
|
@@ -89,6 +89,11 @@ public:
|
|||||||
virtual bool IsEditable() const wxOVERRIDE;
|
virtual bool IsEditable() const wxOVERRIDE;
|
||||||
|
|
||||||
bool RunScript(const wxString& javascript, wxString* output = NULL) const wxOVERRIDE;
|
bool RunScript(const wxString& javascript, wxString* output = NULL) const wxOVERRIDE;
|
||||||
|
virtual bool AddScriptMessageHandler(const wxString& name) wxOVERRIDE;
|
||||||
|
virtual bool RemoveScriptMessageHandler(const wxString& name) wxOVERRIDE;
|
||||||
|
virtual bool AddUserScript(const wxString& javascript,
|
||||||
|
wxWebViewUserScriptInjectionTime injectionTime = wxWEBVIEW_INJECT_AT_DOCUMENT_START) wxOVERRIDE;
|
||||||
|
virtual void RemoveAllUserScripts() wxOVERRIDE;
|
||||||
|
|
||||||
//Virtual Filesystem Support
|
//Virtual Filesystem Support
|
||||||
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
|
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
|
||||||
|
@@ -86,6 +86,12 @@ enum wxWebViewNavigationActionFlags
|
|||||||
wxWEBVIEW_NAV_ACTION_OTHER
|
wxWEBVIEW_NAV_ACTION_OTHER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum wxWebViewUserScriptInjectionTime
|
||||||
|
{
|
||||||
|
wxWEBVIEW_INJECT_AT_DOCUMENT_START,
|
||||||
|
wxWEBVIEW_INJECT_AT_DOCUMENT_END
|
||||||
|
};
|
||||||
|
|
||||||
//Base class for custom scheme handlers
|
//Base class for custom scheme handlers
|
||||||
class WXDLLIMPEXP_WEBVIEW wxWebViewHandler
|
class WXDLLIMPEXP_WEBVIEW wxWebViewHandler
|
||||||
{
|
{
|
||||||
@@ -181,7 +187,18 @@ 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;
|
||||||
|
|
||||||
|
// Script
|
||||||
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const = 0;
|
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const = 0;
|
||||||
|
virtual bool AddScriptMessageHandler(const wxString& name)
|
||||||
|
{ wxUnusedVar(name); return false; }
|
||||||
|
virtual bool RemoveScriptMessageHandler(const wxString& name)
|
||||||
|
{ wxUnusedVar(name); return false; }
|
||||||
|
virtual bool AddUserScript(const wxString& javascript,
|
||||||
|
wxWebViewUserScriptInjectionTime injectionTime = wxWEBVIEW_INJECT_AT_DOCUMENT_START)
|
||||||
|
{ wxUnusedVar(javascript); wxUnusedVar(injectionTime); return false; }
|
||||||
|
virtual void RemoveAllUserScripts() {}
|
||||||
|
|
||||||
virtual void SetEditable(bool enable = true) = 0;
|
virtual void SetEditable(bool enable = true) = 0;
|
||||||
void SetPage(const wxString& html, const wxString& baseUrl)
|
void SetPage(const wxString& html, const wxString& baseUrl)
|
||||||
{
|
{
|
||||||
@@ -269,9 +286,10 @@ public:
|
|||||||
wxWebViewEvent() {}
|
wxWebViewEvent() {}
|
||||||
wxWebViewEvent(wxEventType type, int id, const wxString& url,
|
wxWebViewEvent(wxEventType type, int id, const wxString& url,
|
||||||
const wxString target,
|
const wxString target,
|
||||||
wxWebViewNavigationActionFlags flags = wxWEBVIEW_NAV_ACTION_NONE)
|
wxWebViewNavigationActionFlags flags = wxWEBVIEW_NAV_ACTION_NONE,
|
||||||
|
const wxString& messageHandler = wxString())
|
||||||
: wxNotifyEvent(type, id), m_url(url), m_target(target),
|
: wxNotifyEvent(type, id), m_url(url), m_target(target),
|
||||||
m_actionFlags(flags)
|
m_actionFlags(flags), m_messageHandler(messageHandler)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
@@ -279,12 +297,14 @@ public:
|
|||||||
const wxString& GetTarget() const { return m_target; }
|
const wxString& GetTarget() const { return m_target; }
|
||||||
|
|
||||||
wxWebViewNavigationActionFlags GetNavigationAction() const { return m_actionFlags; }
|
wxWebViewNavigationActionFlags GetNavigationAction() const { return m_actionFlags; }
|
||||||
|
const wxString& GetMessageHandler() const { return m_messageHandler; }
|
||||||
|
|
||||||
virtual wxEvent* Clone() const wxOVERRIDE { return new wxWebViewEvent(*this); }
|
virtual wxEvent* Clone() const wxOVERRIDE { return new wxWebViewEvent(*this); }
|
||||||
private:
|
private:
|
||||||
wxString m_url;
|
wxString m_url;
|
||||||
wxString m_target;
|
wxString m_target;
|
||||||
wxWebViewNavigationActionFlags m_actionFlags;
|
wxWebViewNavigationActionFlags m_actionFlags;
|
||||||
|
wxString m_messageHandler;
|
||||||
|
|
||||||
wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxWebViewEvent);
|
wxDECLARE_DYNAMIC_CLASS_NO_ASSIGN(wxWebViewEvent);
|
||||||
};
|
};
|
||||||
@@ -296,6 +316,7 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_ERROR, wxWebViewEve
|
|||||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_NEWWINDOW, wxWebViewEvent );
|
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_NEWWINDOW, wxWebViewEvent );
|
||||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_TITLE_CHANGED, wxWebViewEvent );
|
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_TITLE_CHANGED, wxWebViewEvent );
|
||||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_FULLSCREEN_CHANGED, wxWebViewEvent);
|
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_FULLSCREEN_CHANGED, wxWebViewEvent);
|
||||||
|
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, wxWebViewEvent);
|
||||||
|
|
||||||
typedef void (wxEvtHandler::*wxWebViewEventFunction)
|
typedef void (wxEvtHandler::*wxWebViewEventFunction)
|
||||||
(wxWebViewEvent&);
|
(wxWebViewEvent&);
|
||||||
|
@@ -107,6 +107,19 @@ enum wxWebViewNavigationActionFlags
|
|||||||
wxWEBVIEW_NAV_ACTION_OTHER
|
wxWEBVIEW_NAV_ACTION_OTHER
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Specifies at which place of documents an user script will be inserted.
|
||||||
|
|
||||||
|
@since 3.1.5
|
||||||
|
*/
|
||||||
|
enum wxWebViewUserScriptInjectionTime
|
||||||
|
{
|
||||||
|
/** Insert the code of the user script at the beginning of loaded documents. */
|
||||||
|
wxWEBVIEW_INJECT_AT_DOCUMENT_START,
|
||||||
|
/** Insert the code of the user script at the end of the loaded documents. */
|
||||||
|
wxWEBVIEW_INJECT_AT_DOCUMENT_END
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Internet Explorer emulation modes for wxWebViewIE.
|
Internet Explorer emulation modes for wxWebViewIE.
|
||||||
|
|
||||||
@@ -374,6 +387,12 @@ public:
|
|||||||
systems on macOS 10.13+. In order to use handlers two-step creation has to be used
|
systems on macOS 10.13+. In order to use handlers two-step creation has to be used
|
||||||
and RegisterHandler() has to be called before Create().
|
and RegisterHandler() has to be called before Create().
|
||||||
|
|
||||||
|
Starting with macOS 10.11 and iOS 9 an application cannot create unsecure
|
||||||
|
connections (this includes HTTP and unverified HTTPS). You have to include
|
||||||
|
additional fields in your Info.plist to enable such connections.
|
||||||
|
For further details see the documentation on NSAppTransportSecurity
|
||||||
|
<a target=_new href="https://developer.apple.com/documentation/bundleresources/information_property_list/nsapptransportsecurity">here</a>
|
||||||
|
|
||||||
@section async Asynchronous Notifications
|
@section async Asynchronous Notifications
|
||||||
|
|
||||||
Many of the methods in wxWebView are asynchronous, i.e. they return
|
Many of the methods in wxWebView are asynchronous, i.e. they return
|
||||||
@@ -433,6 +452,10 @@ public:
|
|||||||
the page wants to enter or leave fullscreen. Use GetInt to get the status.
|
the page wants to enter or leave fullscreen. Use GetInt to get the status.
|
||||||
Currently only implemented for the edge and WebKit2GTK+ backend
|
Currently only implemented for the edge and WebKit2GTK+ backend
|
||||||
and is only available in wxWidgets 3.1.5 or later.
|
and is only available in wxWidgets 3.1.5 or later.
|
||||||
|
@event{EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED(id, func)}
|
||||||
|
Process a @c wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED event
|
||||||
|
only available in wxWidgets 3.1.5 or later. For usage details see
|
||||||
|
AddScriptMessageHandler().
|
||||||
@endEventTable
|
@endEventTable
|
||||||
|
|
||||||
@since 2.9.3
|
@since 2.9.3
|
||||||
@@ -609,6 +632,44 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual void Reload(wxWebViewReloadFlags flags = wxWEBVIEW_RELOAD_DEFAULT) = 0;
|
virtual void Reload(wxWebViewReloadFlags flags = wxWEBVIEW_RELOAD_DEFAULT) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the editable property of the web control. Enabling allows the user
|
||||||
|
to edit the page even if the @c contenteditable attribute is not set.
|
||||||
|
The exact capabilities vary with the backend being used.
|
||||||
|
|
||||||
|
@note This is not implemented on macOS.
|
||||||
|
*/
|
||||||
|
virtual void SetEditable(bool enable = true) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the displayed page source to the contents of the given string.
|
||||||
|
@param html The string that contains the HTML data to display.
|
||||||
|
@param baseUrl URL assigned to the HTML data, to be used to resolve
|
||||||
|
relative paths, for instance.
|
||||||
|
@note When using @c wxWEBVIEW_BACKEND_IE you must wait for the current
|
||||||
|
page to finish loading before calling SetPage(). The baseURL
|
||||||
|
parameter is not used in this backend and the edge backend.
|
||||||
|
*/
|
||||||
|
virtual void SetPage(const wxString& html, const wxString& baseUrl) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Set the displayed page source to the contents of the given stream.
|
||||||
|
@param html The stream to read HTML data from.
|
||||||
|
@param baseUrl URL assigned to the HTML data, to be used to resolve
|
||||||
|
relative paths, for instance.
|
||||||
|
*/
|
||||||
|
virtual void SetPage(wxInputStream& html, wxString baseUrl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Stop the current page loading process, if any.
|
||||||
|
May trigger an error event of type @c wxWEBVIEW_NAV_ERR_USER_CANCELLED.
|
||||||
|
TODO: make @c wxWEBVIEW_NAV_ERR_USER_CANCELLED errors uniform across ports.
|
||||||
|
*/
|
||||||
|
virtual void Stop() = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
@name Scripting
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
Runs the given JavaScript code.
|
Runs the given JavaScript code.
|
||||||
|
|
||||||
@@ -670,39 +731,78 @@ public:
|
|||||||
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const = 0;
|
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set the editable property of the web control. Enabling allows the user
|
Add a script message handler with the given name.
|
||||||
to edit the page even if the @c contenteditable attribute is not set.
|
|
||||||
The exact capabilities vary with the backend being used.
|
|
||||||
|
|
||||||
@note This is not implemented on macOS.
|
To use the script message handler from javascript use
|
||||||
|
@c window.<name>.postMessage(<messageBody>) where <name> corresponds the the value
|
||||||
|
of the name parameter. The <messageBody> will be available to the application
|
||||||
|
via a @c wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED event.
|
||||||
|
|
||||||
|
Sample C++ code receiving a script message:
|
||||||
|
@code
|
||||||
|
// Install message handler with the name wx_msg
|
||||||
|
m_webView->AddScriptMessageHandler('wx_msg');
|
||||||
|
// Bind handler
|
||||||
|
m_webView->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, [](wxWebViewEvent& evt) {
|
||||||
|
wxLogMessage("Script message received; value = %s, handler = %s", evt.GetString(), evt.GetMessageHandler());
|
||||||
|
});
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
Sample javascript sending a script message:
|
||||||
|
@code
|
||||||
|
// Send sample message body
|
||||||
|
window.wx_msg.postMessage('This is a message body');
|
||||||
|
@endcode
|
||||||
|
|
||||||
|
@param name Name of the message handler that can be used from javascript
|
||||||
|
@return @true if the handler could be added, @false if it could not be added.
|
||||||
|
|
||||||
|
@see RemoveScriptMessageHandler()
|
||||||
|
|
||||||
|
@note The Edge (Chromium) backend only supports a single message handler and
|
||||||
|
the IE backend does not support script message handlers.
|
||||||
|
|
||||||
|
@since 3.1.5
|
||||||
*/
|
*/
|
||||||
virtual void SetEditable(bool enable = true) = 0;
|
virtual bool AddScriptMessageHandler(const wxString& name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set the displayed page source to the contents of the given string.
|
Remove a script message handler with the given name that was previously added via
|
||||||
@param html The string that contains the HTML data to display.
|
AddScriptMessageHandler().
|
||||||
@param baseUrl URL assigned to the HTML data, to be used to resolve
|
|
||||||
relative paths, for instance.
|
@return @true if the handler could be removed, @false if it could not be removed.
|
||||||
@note When using @c wxWEBVIEW_BACKEND_IE you must wait for the current
|
|
||||||
page to finish loading before calling SetPage(). The baseURL
|
@see AddScriptMessageHandler()
|
||||||
parameter is not used in this backend and the edge backend.
|
|
||||||
|
@since 3.1.5
|
||||||
*/
|
*/
|
||||||
virtual void SetPage(const wxString& html, const wxString& baseUrl) = 0;
|
virtual bool RemoveScriptMessageHandler(const wxString& name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set the displayed page source to the contents of the given stream.
|
Injects the specified script into the webpage’s content.
|
||||||
@param html The stream to read HTML data from.
|
|
||||||
@param baseUrl URL assigned to the HTML data, to be used to resolve
|
@param javascript The javascript code to add.
|
||||||
relative paths, for instance.
|
@param injectionTime Specifies when the script will be executed.
|
||||||
|
@return Returns true if the script was added successfully.
|
||||||
|
|
||||||
|
@note Please note that this is unsupported by the IE backend and
|
||||||
|
the Edge (Chromium) backend does only support wxWEBVIEW_INJECT_AT_DOCUMENT_START.
|
||||||
|
|
||||||
|
@see RemoveAllUserScripts()
|
||||||
|
|
||||||
|
@since 3.1.5
|
||||||
*/
|
*/
|
||||||
virtual void SetPage(wxInputStream& html, wxString baseUrl);
|
virtual bool AddUserScript(const wxString& javascript,
|
||||||
|
wxWebViewUserScriptInjectionTime injectionTime = wxWEBVIEW_INJECT_AT_DOCUMENT_START);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Stop the current page loading process, if any.
|
Removes all user scripts from the web view.
|
||||||
May trigger an error event of type @c wxWEBVIEW_NAV_ERR_USER_CANCELLED.
|
|
||||||
TODO: make @c wxWEBVIEW_NAV_ERR_USER_CANCELLED errors uniform across ports.
|
@see AddUserScript()
|
||||||
|
|
||||||
|
@since 3.1.5
|
||||||
*/
|
*/
|
||||||
virtual void Stop() = 0;
|
virtual void RemoveAllUserScripts();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@name Clipboard
|
@name Clipboard
|
||||||
@@ -772,8 +872,8 @@ public:
|
|||||||
/**
|
/**
|
||||||
Enable or disable access to dev tools for the user.
|
Enable or disable access to dev tools for the user.
|
||||||
|
|
||||||
This is currently only implemented for the Edge (Chromium) backend
|
This is currently only implemented for the Edge (Chromium) backend and
|
||||||
where the dev tools are enabled by default.
|
the WebKit2GTK+ backend. Dev tools are disabled by default.
|
||||||
|
|
||||||
@since 3.1.4
|
@since 3.1.4
|
||||||
*/
|
*/
|
||||||
@@ -1094,6 +1194,10 @@ public:
|
|||||||
@event{EVT_WEBVIEW_TITLE_CHANGED(id, func)}
|
@event{EVT_WEBVIEW_TITLE_CHANGED(id, func)}
|
||||||
Process a @c wxEVT_WEBVIEW_TITLE_CHANGED event, generated when
|
Process a @c wxEVT_WEBVIEW_TITLE_CHANGED event, generated when
|
||||||
the page title changes. Use GetString to get the title.
|
the page title changes. Use GetString to get the title.
|
||||||
|
@event{EVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED(id, func)}
|
||||||
|
Process a @c wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED event
|
||||||
|
only available in wxWidgets 3.1.5 or later. For usage details see
|
||||||
|
wxWebView::AddScriptMessageHandler().
|
||||||
@endEventTable
|
@endEventTable
|
||||||
|
|
||||||
@since 2.9.3
|
@since 2.9.3
|
||||||
@@ -1108,7 +1212,8 @@ public:
|
|||||||
wxWebViewEvent();
|
wxWebViewEvent();
|
||||||
wxWebViewEvent(wxEventType type, int id, const wxString href,
|
wxWebViewEvent(wxEventType type, int id, const wxString href,
|
||||||
const wxString target,
|
const wxString target,
|
||||||
wxWebViewNavigationActionFlags flags = wxWEBVIEW_NAV_ACTION_NONE);
|
wxWebViewNavigationActionFlags flags = wxWEBVIEW_NAV_ACTION_NONE,
|
||||||
|
const wxString& messageHandler = wxString());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get the name of the target frame which the url of this event
|
Get the name of the target frame which the url of this event
|
||||||
@@ -1129,6 +1234,14 @@ public:
|
|||||||
@since 3.1.2
|
@since 3.1.2
|
||||||
*/
|
*/
|
||||||
wxWebViewNavigationActionFlags GetNavigationAction() const;
|
wxWebViewNavigationActionFlags GetNavigationAction() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get the name of the script handler. Only valid for events of type
|
||||||
|
@c wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED
|
||||||
|
|
||||||
|
@since 3.1.5
|
||||||
|
*/
|
||||||
|
const wxString& GetMessageHandler() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@@ -121,6 +121,7 @@ public:
|
|||||||
void OnNewWindow(wxWebViewEvent& evt);
|
void OnNewWindow(wxWebViewEvent& evt);
|
||||||
void OnTitleChanged(wxWebViewEvent& evt);
|
void OnTitleChanged(wxWebViewEvent& evt);
|
||||||
void OnFullScreenChanged(wxWebViewEvent& evt);
|
void OnFullScreenChanged(wxWebViewEvent& evt);
|
||||||
|
void OnScriptMessage(wxWebViewEvent& evt);
|
||||||
void OnSetPage(wxCommandEvent& evt);
|
void OnSetPage(wxCommandEvent& evt);
|
||||||
void OnViewSourceRequest(wxCommandEvent& evt);
|
void OnViewSourceRequest(wxCommandEvent& evt);
|
||||||
void OnViewTextRequest(wxCommandEvent& evt);
|
void OnViewTextRequest(wxCommandEvent& evt);
|
||||||
@@ -157,7 +158,9 @@ public:
|
|||||||
void OnRunScriptDateWithEmulationLevel(wxCommandEvent& evt);
|
void OnRunScriptDateWithEmulationLevel(wxCommandEvent& evt);
|
||||||
void OnRunScriptArrayWithEmulationLevel(wxCommandEvent& evt);
|
void OnRunScriptArrayWithEmulationLevel(wxCommandEvent& evt);
|
||||||
#endif
|
#endif
|
||||||
|
void OnRunScriptMessage(wxCommandEvent& evt);
|
||||||
void OnRunScriptCustom(wxCommandEvent& evt);
|
void OnRunScriptCustom(wxCommandEvent& evt);
|
||||||
|
void OnAddUserScript(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);
|
||||||
@@ -227,6 +230,7 @@ private:
|
|||||||
wxMenuItem* m_script_date_el;
|
wxMenuItem* m_script_date_el;
|
||||||
wxMenuItem* m_script_array_el;
|
wxMenuItem* m_script_array_el;
|
||||||
#endif
|
#endif
|
||||||
|
wxMenuItem* m_script_message;
|
||||||
wxMenuItem* m_script_custom;
|
wxMenuItem* m_script_custom;
|
||||||
wxMenuItem* m_selection_clear;
|
wxMenuItem* m_selection_clear;
|
||||||
wxMenuItem* m_selection_delete;
|
wxMenuItem* m_selection_delete;
|
||||||
@@ -406,6 +410,8 @@ WebFrame::WebFrame(const wxString& url) :
|
|||||||
//And the memory: file system
|
//And the memory: file system
|
||||||
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewFSHandler("memory")));
|
m_browser->RegisterHandler(wxSharedPtr<wxWebViewHandler>(new wxWebViewFSHandler("memory")));
|
||||||
#endif
|
#endif
|
||||||
|
if (!m_browser->AddScriptMessageHandler("wx"))
|
||||||
|
wxLogError("Could not add script message handler");
|
||||||
|
|
||||||
SetSizer(topsizer);
|
SetSizer(topsizer);
|
||||||
|
|
||||||
@@ -483,8 +489,10 @@ WebFrame::WebFrame(const wxString& url) :
|
|||||||
m_script_array_el = script_menu->Append(wxID_ANY, "Return array changing emulation level");
|
m_script_array_el = script_menu->Append(wxID_ANY, "Return array changing emulation level");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
m_script_message = script_menu->Append(wxID_ANY, "Send script message");
|
||||||
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"));
|
||||||
|
|
||||||
//Selection menu
|
//Selection menu
|
||||||
wxMenu* selection = new wxMenu();
|
wxMenu* selection = new wxMenu();
|
||||||
@@ -538,6 +546,7 @@ WebFrame::WebFrame(const wxString& url) :
|
|||||||
Bind(wxEVT_WEBVIEW_NEWWINDOW, &WebFrame::OnNewWindow, this, m_browser->GetId());
|
Bind(wxEVT_WEBVIEW_NEWWINDOW, &WebFrame::OnNewWindow, this, m_browser->GetId());
|
||||||
Bind(wxEVT_WEBVIEW_TITLE_CHANGED, &WebFrame::OnTitleChanged, this, m_browser->GetId());
|
Bind(wxEVT_WEBVIEW_TITLE_CHANGED, &WebFrame::OnTitleChanged, this, m_browser->GetId());
|
||||||
Bind(wxEVT_WEBVIEW_FULLSCREEN_CHANGED, &WebFrame::OnFullScreenChanged, this, m_browser->GetId());
|
Bind(wxEVT_WEBVIEW_FULLSCREEN_CHANGED, &WebFrame::OnFullScreenChanged, this, m_browser->GetId());
|
||||||
|
Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, &WebFrame::OnScriptMessage, this, m_browser->GetId());
|
||||||
|
|
||||||
// Connect the menu events
|
// Connect the menu events
|
||||||
Bind(wxEVT_MENU, &WebFrame::OnSetPage, this, setPage->GetId());
|
Bind(wxEVT_MENU, &WebFrame::OnSetPage, this, setPage->GetId());
|
||||||
@@ -581,7 +590,9 @@ WebFrame::WebFrame(const wxString& url) :
|
|||||||
Bind(wxEVT_MENU, &WebFrame::OnRunScriptArrayWithEmulationLevel, this, m_script_array_el->GetId());
|
Bind(wxEVT_MENU, &WebFrame::OnRunScriptArrayWithEmulationLevel, this, m_script_array_el->GetId());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
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::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());
|
||||||
@@ -905,6 +916,11 @@ void WebFrame::OnFullScreenChanged(wxWebViewEvent & evt)
|
|||||||
ShowFullScreen(evt.GetInt() != 0);
|
ShowFullScreen(evt.GetInt() != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebFrame::OnScriptMessage(wxWebViewEvent& evt)
|
||||||
|
{
|
||||||
|
wxLogMessage("Script message received; value = %s, handler = %s", evt.GetString(), evt.GetMessageHandler());
|
||||||
|
}
|
||||||
|
|
||||||
void WebFrame::OnSetPage(wxCommandEvent& WXUNUSED(evt))
|
void WebFrame::OnSetPage(wxCommandEvent& WXUNUSED(evt))
|
||||||
{
|
{
|
||||||
m_browser->SetPage
|
m_browser->SetPage
|
||||||
@@ -1175,6 +1191,11 @@ void WebFrame::OnRunScriptArrayWithEmulationLevel(wxCommandEvent& WXUNUSED(evt))
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void WebFrame::OnRunScriptMessage(wxCommandEvent& WXUNUSED(evt))
|
||||||
|
{
|
||||||
|
RunScript("window.wx.postMessage('This is a web message');");
|
||||||
|
}
|
||||||
|
|
||||||
void WebFrame::OnRunScriptCustom(wxCommandEvent& WXUNUSED(evt))
|
void WebFrame::OnRunScriptCustom(wxCommandEvent& WXUNUSED(evt))
|
||||||
{
|
{
|
||||||
wxTextEntryDialog dialog
|
wxTextEntryDialog dialog
|
||||||
@@ -1191,6 +1212,24 @@ void WebFrame::OnRunScriptCustom(wxCommandEvent& WXUNUSED(evt))
|
|||||||
RunScript(dialog.GetValue());
|
RunScript(dialog.GetValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WebFrame::OnAddUserScript(wxCommandEvent & WXUNUSED(evt))
|
||||||
|
{
|
||||||
|
wxString userScript = "window.wx_test_var = 'wxWidgets webview sample';";
|
||||||
|
wxTextEntryDialog dialog
|
||||||
|
(
|
||||||
|
this,
|
||||||
|
"Enter the JavaScript code to run as the initialization script that runs before any script in the HTML document.",
|
||||||
|
wxGetTextFromUserPromptStr,
|
||||||
|
userScript,
|
||||||
|
wxOK | wxCANCEL | wxCENTRE | wxTE_MULTILINE
|
||||||
|
);
|
||||||
|
if (dialog.ShowModal() != wxID_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!m_browser->AddUserScript(dialog.GetValue()))
|
||||||
|
wxLogError("Could not add user script");
|
||||||
|
}
|
||||||
|
|
||||||
void WebFrame::OnClearSelection(wxCommandEvent& WXUNUSED(evt))
|
void WebFrame::OnClearSelection(wxCommandEvent& WXUNUSED(evt))
|
||||||
{
|
{
|
||||||
m_browser->ClearSelection();
|
m_browser->ClearSelection();
|
||||||
|
@@ -49,6 +49,7 @@ wxDEFINE_EVENT( wxEVT_WEBVIEW_ERROR, wxWebViewEvent );
|
|||||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_NEWWINDOW, wxWebViewEvent );
|
wxDEFINE_EVENT( wxEVT_WEBVIEW_NEWWINDOW, wxWebViewEvent );
|
||||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_TITLE_CHANGED, wxWebViewEvent );
|
wxDEFINE_EVENT( wxEVT_WEBVIEW_TITLE_CHANGED, wxWebViewEvent );
|
||||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_FULLSCREEN_CHANGED, wxWebViewEvent);
|
wxDEFINE_EVENT( wxEVT_WEBVIEW_FULLSCREEN_CHANGED, wxWebViewEvent);
|
||||||
|
wxDEFINE_EVENT( wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, wxWebViewEvent);
|
||||||
|
|
||||||
wxStringWebViewFactoryMap wxWebView::m_factoryMap;
|
wxStringWebViewFactoryMap wxWebView::m_factoryMap;
|
||||||
|
|
||||||
|
@@ -31,6 +31,37 @@
|
|||||||
#include <JavaScriptCore/JSValueRef.h>
|
#include <JavaScriptCore/JSValueRef.h>
|
||||||
#include <JavaScriptCore/JSStringRef.h>
|
#include <JavaScriptCore/JSStringRef.h>
|
||||||
|
|
||||||
|
// Helper function to get string from Webkit JS result
|
||||||
|
bool wxGetStringFromJSResult(WebKitJavascriptResult* js_result, wxString* output)
|
||||||
|
{
|
||||||
|
JSGlobalContextRef context = webkit_javascript_result_get_global_context(js_result);
|
||||||
|
JSValueRef value = webkit_javascript_result_get_value(js_result);
|
||||||
|
|
||||||
|
JSValueRef exception = NULL;
|
||||||
|
wxJSStringRef js_value
|
||||||
|
(
|
||||||
|
JSValueIsObject(context, value)
|
||||||
|
? JSValueCreateJSONString(context, value, 0, &exception)
|
||||||
|
: JSValueToStringCopy(context, value, &exception)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( exception )
|
||||||
|
{
|
||||||
|
if ( output )
|
||||||
|
{
|
||||||
|
wxJSStringRef ex_value(JSValueToStringCopy(context, exception, NULL));
|
||||||
|
*output = ex_value.ToWxString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( output != NULL )
|
||||||
|
*output = js_value.ToWxString();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// GTK callbacks
|
// GTK callbacks
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@@ -290,6 +321,21 @@ wxgtk_webview_webkit_leave_fullscreen(WebKitWebView *WXUNUSED(web_view),
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
wxgtk_webview_webkit_script_message_received(WebKitUserContentManager *WXUNUSED(content_manager),
|
||||||
|
WebKitJavascriptResult *js_result,
|
||||||
|
wxWebViewWebKit *webKitCtrl)
|
||||||
|
{
|
||||||
|
wxWebViewEvent event(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED,
|
||||||
|
webKitCtrl->GetId(),
|
||||||
|
webKitCtrl->GetCurrentURL(),
|
||||||
|
"");
|
||||||
|
wxString msgStr;
|
||||||
|
if (wxGetStringFromJSResult(js_result, &msgStr))
|
||||||
|
event.SetString(msgStr);
|
||||||
|
webKitCtrl->HandleWindowEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
wxgtk_webview_webkit_decide_policy(WebKitWebView *web_view,
|
wxgtk_webview_webkit_decide_policy(WebKitWebView *web_view,
|
||||||
WebKitPolicyDecision *decision,
|
WebKitPolicyDecision *decision,
|
||||||
@@ -698,6 +744,18 @@ float wxWebViewWebKit::GetWebkitZoom() const
|
|||||||
return webkit_web_view_get_zoom_level(m_web_view);
|
return webkit_web_view_get_zoom_level(m_web_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxWebViewWebKit::EnableAccessToDevTools(bool enable)
|
||||||
|
{
|
||||||
|
WebKitSettings* settings = webkit_web_view_get_settings(m_web_view);
|
||||||
|
webkit_settings_set_enable_developer_extras(settings, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxWebViewWebKit::IsAccessToDevToolsEnabled() const
|
||||||
|
{
|
||||||
|
WebKitSettings* settings = webkit_web_view_get_settings(m_web_view);
|
||||||
|
return webkit_settings_get_enable_developer_extras(settings);
|
||||||
|
}
|
||||||
|
|
||||||
void wxWebViewWebKit::Stop()
|
void wxWebViewWebKit::Stop()
|
||||||
{
|
{
|
||||||
webkit_web_view_stop_loading(m_web_view);
|
webkit_web_view_stop_loading(m_web_view);
|
||||||
@@ -1209,32 +1267,7 @@ bool wxWebViewWebKit::RunScriptSync(const wxString& javascript, wxString* output
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSGlobalContextRef context = webkit_javascript_result_get_global_context(js_result);
|
return wxGetStringFromJSResult(js_result, output);
|
||||||
JSValueRef value = webkit_javascript_result_get_value(js_result);
|
|
||||||
|
|
||||||
JSValueRef exception = NULL;
|
|
||||||
wxJSStringRef js_value
|
|
||||||
(
|
|
||||||
JSValueIsObject(context, value)
|
|
||||||
? JSValueCreateJSONString(context, value, 0, &exception)
|
|
||||||
: JSValueToStringCopy(context, value, &exception)
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( exception )
|
|
||||||
{
|
|
||||||
if ( output )
|
|
||||||
{
|
|
||||||
wxJSStringRef ex_value(JSValueToStringCopy(context, exception, NULL));
|
|
||||||
*output = ex_value.ToWxString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( output != NULL )
|
|
||||||
*output = js_value.ToWxString();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxWebViewWebKit::RunScript(const wxString& javascript, wxString* output) const
|
bool wxWebViewWebKit::RunScript(const wxString& javascript, wxString* output) const
|
||||||
@@ -1266,6 +1299,57 @@ bool wxWebViewWebKit::RunScript(const wxString& javascript, wxString* output) co
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxWebViewWebKit::AddScriptMessageHandler(const wxString& name)
|
||||||
|
{
|
||||||
|
if (!m_web_view)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
WebKitUserContentManager *ucm = webkit_web_view_get_user_content_manager(m_web_view);
|
||||||
|
g_signal_connect(ucm, wxString::Format("script-message-received::%s", name).utf8_str(),
|
||||||
|
G_CALLBACK(wxgtk_webview_webkit_script_message_received), this);
|
||||||
|
bool res = webkit_user_content_manager_register_script_message_handler(ucm, name.utf8_str());
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
// Make webkit message handler available under common name
|
||||||
|
wxString js = wxString::Format("window.%s = window.webkit.messageHandlers.%s;",
|
||||||
|
name, name);
|
||||||
|
AddUserScript(js);
|
||||||
|
RunScript(js);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxWebViewWebKit::RemoveScriptMessageHandler(const wxString& name)
|
||||||
|
{
|
||||||
|
WebKitUserContentManager *ucm = webkit_web_view_get_user_content_manager(m_web_view);
|
||||||
|
webkit_user_content_manager_unregister_script_message_handler(ucm, name.utf8_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxWebViewWebKit::AddUserScript(const wxString& javascript,
|
||||||
|
wxWebViewUserScriptInjectionTime injectionTime)
|
||||||
|
{
|
||||||
|
WebKitUserScript* userScript = webkit_user_script_new(
|
||||||
|
javascript.utf8_str(),
|
||||||
|
WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES,
|
||||||
|
(injectionTime == wxWEBVIEW_INJECT_AT_DOCUMENT_START) ?
|
||||||
|
WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_START : WEBKIT_USER_SCRIPT_INJECT_AT_DOCUMENT_END,
|
||||||
|
NULL, NULL
|
||||||
|
);
|
||||||
|
WebKitUserContentManager *ucm = webkit_web_view_get_user_content_manager(m_web_view);
|
||||||
|
webkit_user_content_manager_add_script(ucm, userScript);
|
||||||
|
webkit_user_script_unref(userScript);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWebViewWebKit::RemoveAllUserScripts()
|
||||||
|
{
|
||||||
|
WebKitUserContentManager *ucm = webkit_web_view_get_user_content_manager(m_web_view);
|
||||||
|
webkit_user_content_manager_remove_all_scripts(ucm);
|
||||||
|
}
|
||||||
|
|
||||||
void wxWebViewWebKit::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
|
void wxWebViewWebKit::RegisterHandler(wxSharedPtr<wxWebViewHandler> handler)
|
||||||
{
|
{
|
||||||
m_handlerList.push_back(handler);
|
m_handlerList.push_back(handler);
|
||||||
|
@@ -75,6 +75,7 @@ wxWebViewEdgeImpl::~wxWebViewEdgeImpl()
|
|||||||
m_webView->remove_DocumentTitleChanged(m_documentTitleChangedToken);
|
m_webView->remove_DocumentTitleChanged(m_documentTitleChangedToken);
|
||||||
m_webView->remove_ContentLoading(m_contentLoadingToken);
|
m_webView->remove_ContentLoading(m_contentLoadingToken);
|
||||||
m_webView->remove_ContainsFullScreenElementChanged(m_containsFullScreenElementChangedToken);
|
m_webView->remove_ContainsFullScreenElementChanged(m_containsFullScreenElementChangedToken);
|
||||||
|
m_webView->remove_WebMessageReceived(m_webMessageReceivedToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +84,7 @@ bool wxWebViewEdgeImpl::Create()
|
|||||||
m_initialized = false;
|
m_initialized = false;
|
||||||
m_isBusy = false;
|
m_isBusy = false;
|
||||||
m_pendingContextMenuEnabled = -1;
|
m_pendingContextMenuEnabled = -1;
|
||||||
m_pendingAccessToDevToolsEnabled = -1;
|
m_pendingAccessToDevToolsEnabled = 0;
|
||||||
|
|
||||||
m_historyLoadingFromList = false;
|
m_historyLoadingFromList = false;
|
||||||
m_historyEnabled = true;
|
m_historyEnabled = true;
|
||||||
@@ -320,6 +321,37 @@ HRESULT wxWebViewEdgeImpl::OnContainsFullScreenElementChanged(ICoreWebView2* WXU
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT
|
||||||
|
wxWebViewEdgeImpl::OnWebMessageReceived(ICoreWebView2* WXUNUSED(sender),
|
||||||
|
ICoreWebView2WebMessageReceivedEventArgs* args)
|
||||||
|
{
|
||||||
|
wxCoTaskMemPtr<wchar_t> msgContent;
|
||||||
|
|
||||||
|
HRESULT hr = args->get_WebMessageAsJson(&msgContent);
|
||||||
|
if (FAILED(hr))
|
||||||
|
{
|
||||||
|
wxLogApiError("get_WebMessageAsJson", hr);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxWebViewEvent event(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, m_ctrl->GetId(),
|
||||||
|
m_ctrl->GetCurrentURL(), wxString(),
|
||||||
|
wxWEBVIEW_NAV_ACTION_NONE, m_scriptMsgHandlerName);
|
||||||
|
event.SetEventObject(m_ctrl);
|
||||||
|
|
||||||
|
// Try to decode JSON string or return original
|
||||||
|
// result if it's not a valid JSON string
|
||||||
|
wxString msgStr;
|
||||||
|
wxString msgJson(msgContent);
|
||||||
|
if (!wxJSON::DecodeString(msgJson, &msgStr))
|
||||||
|
msgStr = msgJson;
|
||||||
|
event.SetString(msgStr);
|
||||||
|
|
||||||
|
m_ctrl->HandleWindowEvent(event);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Controller* webViewController)
|
HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Controller* webViewController)
|
||||||
{
|
{
|
||||||
if (FAILED(result))
|
if (FAILED(result))
|
||||||
@@ -369,6 +401,10 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control
|
|||||||
Callback<ICoreWebView2ContainsFullScreenElementChangedEventHandler>(
|
Callback<ICoreWebView2ContainsFullScreenElementChangedEventHandler>(
|
||||||
this, &wxWebViewEdgeImpl::OnContainsFullScreenElementChanged).Get(),
|
this, &wxWebViewEdgeImpl::OnContainsFullScreenElementChanged).Get(),
|
||||||
&m_containsFullScreenElementChangedToken);
|
&m_containsFullScreenElementChangedToken);
|
||||||
|
m_webView->add_WebMessageReceived(
|
||||||
|
Callback<ICoreWebView2WebMessageReceivedEventHandler>(
|
||||||
|
this, &wxWebViewEdgeImpl::OnWebMessageReceived).Get(),
|
||||||
|
&m_webMessageReceivedToken);
|
||||||
|
|
||||||
if (m_pendingContextMenuEnabled != -1)
|
if (m_pendingContextMenuEnabled != -1)
|
||||||
{
|
{
|
||||||
@@ -384,7 +420,18 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control
|
|||||||
|
|
||||||
wxCOMPtr<ICoreWebView2Settings> settings(GetSettings());
|
wxCOMPtr<ICoreWebView2Settings> settings(GetSettings());
|
||||||
if (settings)
|
if (settings)
|
||||||
|
{
|
||||||
settings->put_IsStatusBarEnabled(false);
|
settings->put_IsStatusBarEnabled(false);
|
||||||
|
}
|
||||||
|
UpdateWebMessageHandler();
|
||||||
|
|
||||||
|
if (!m_pendingUserScripts.empty())
|
||||||
|
{
|
||||||
|
for (wxVector<wxString>::iterator it = m_pendingUserScripts.begin();
|
||||||
|
it != m_pendingUserScripts.end(); ++it)
|
||||||
|
m_ctrl->AddUserScript(*it);
|
||||||
|
m_pendingUserScripts.clear();
|
||||||
|
}
|
||||||
|
|
||||||
if (!m_pendingURL.empty())
|
if (!m_pendingURL.empty())
|
||||||
{
|
{
|
||||||
@@ -395,6 +442,24 @@ HRESULT wxWebViewEdgeImpl::OnWebViewCreated(HRESULT result, ICoreWebView2Control
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wxWebViewEdgeImpl::UpdateWebMessageHandler()
|
||||||
|
{
|
||||||
|
wxCOMPtr<ICoreWebView2Settings> settings(GetSettings());
|
||||||
|
if (!settings)
|
||||||
|
return;
|
||||||
|
|
||||||
|
settings->put_IsWebMessageEnabled(!m_scriptMsgHandlerName.empty());
|
||||||
|
|
||||||
|
if (!m_scriptMsgHandlerName.empty())
|
||||||
|
{
|
||||||
|
// Make edge message handler available under common name
|
||||||
|
wxString js = wxString::Format("window.%s = window.chrome.webview;",
|
||||||
|
m_scriptMsgHandlerName);
|
||||||
|
m_ctrl->AddUserScript(js);
|
||||||
|
m_webView->ExecuteScript(js.wc_str(), NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ICoreWebView2Settings* wxWebViewEdgeImpl::GetSettings()
|
ICoreWebView2Settings* wxWebViewEdgeImpl::GetSettings()
|
||||||
{
|
{
|
||||||
if (!m_webView)
|
if (!m_webView)
|
||||||
@@ -774,6 +839,65 @@ bool wxWebViewEdge::RunScript(const wxString& javascript, wxString* output) cons
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxWebViewEdge::AddScriptMessageHandler(const wxString& name)
|
||||||
|
{
|
||||||
|
// Edge only supports a single message handler
|
||||||
|
if (!m_impl->m_scriptMsgHandlerName.empty())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_impl->m_scriptMsgHandlerName = name;
|
||||||
|
m_impl->UpdateWebMessageHandler();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxWebViewEdge::RemoveScriptMessageHandler(const wxString& WXUNUSED(name))
|
||||||
|
{
|
||||||
|
m_impl->m_scriptMsgHandlerName.clear();
|
||||||
|
m_impl->UpdateWebMessageHandler();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT wxWebViewEdgeImpl::OnAddScriptToExecuteOnDocumentedCreatedCompleted(HRESULT errorCode, LPCWSTR id)
|
||||||
|
{
|
||||||
|
if (SUCCEEDED(errorCode))
|
||||||
|
m_userScriptIds.push_back(id);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxWebViewEdge::AddUserScript(const wxString& javascript,
|
||||||
|
wxWebViewUserScriptInjectionTime injectionTime)
|
||||||
|
{
|
||||||
|
// Currently only AT_DOCUMENT_START is supported
|
||||||
|
if (injectionTime != wxWEBVIEW_INJECT_AT_DOCUMENT_START)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (m_impl->m_webView)
|
||||||
|
{
|
||||||
|
HRESULT hr = m_impl->m_webView->AddScriptToExecuteOnDocumentCreated(javascript.wc_str(),
|
||||||
|
Callback<ICoreWebView2AddScriptToExecuteOnDocumentCreatedCompletedHandler>(m_impl,
|
||||||
|
&wxWebViewEdgeImpl::OnAddScriptToExecuteOnDocumentedCreatedCompleted).Get());
|
||||||
|
if (FAILED(hr))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_impl->m_pendingUserScripts.push_back(javascript);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWebViewEdge::RemoveAllUserScripts()
|
||||||
|
{
|
||||||
|
m_impl->m_pendingUserScripts.clear();
|
||||||
|
for (auto& scriptId : m_impl->m_userScriptIds)
|
||||||
|
{
|
||||||
|
HRESULT hr = m_impl->m_webView->RemoveScriptToExecuteOnDocumentCreated(scriptId.wc_str());
|
||||||
|
if (FAILED(hr))
|
||||||
|
wxLogApiError("RemoveScriptToExecuteOnDocumentCreated", hr);
|
||||||
|
}
|
||||||
|
m_impl->m_userScriptIds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void wxWebViewEdge::RegisterHandler(wxSharedPtr<wxWebViewHandler> WXUNUSED(handler))
|
void wxWebViewEdge::RegisterHandler(wxSharedPtr<wxWebViewHandler> WXUNUSED(handler))
|
||||||
{
|
{
|
||||||
// TODO: could maybe be implemented via IWebView2WebView5::add_WebResourceRequested
|
// TODO: could maybe be implemented via IWebView2WebView5::add_WebResourceRequested
|
||||||
|
@@ -87,6 +87,15 @@ wxEND_EVENT_TABLE()
|
|||||||
@end
|
@end
|
||||||
#endif // macOS 10.13+
|
#endif // macOS 10.13+
|
||||||
|
|
||||||
|
@interface WebViewScriptMessageHandler: NSObject<WKScriptMessageHandler>
|
||||||
|
{
|
||||||
|
wxWebViewWebKit* webKitWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)initWithWxWindow: (wxWebViewWebKit*)inWindow;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// wxWebViewFactoryWebKit
|
// wxWebViewFactoryWebKit
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -385,6 +394,41 @@ bool wxWebViewWebKit::RunScript(const wxString& javascript, wxString* output) co
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wxWebViewWebKit::AddScriptMessageHandler(const wxString& name)
|
||||||
|
{
|
||||||
|
[m_webView.configuration.userContentController addScriptMessageHandler:
|
||||||
|
[[WebViewScriptMessageHandler alloc] initWithWxWindow:this] name:wxCFStringRef(name).AsNSString()];
|
||||||
|
// Make webkit message handler available under common name
|
||||||
|
wxString js = wxString::Format("window.%s = window.webkit.messageHandlers.%s;",
|
||||||
|
name, name);
|
||||||
|
AddUserScript(js);
|
||||||
|
RunScript(js);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxWebViewWebKit::RemoveScriptMessageHandler(const wxString& name)
|
||||||
|
{
|
||||||
|
[m_webView.configuration.userContentController removeScriptMessageHandlerForName:wxCFStringRef(name).AsNSString()];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wxWebViewWebKit::AddUserScript(const wxString& javascript,
|
||||||
|
wxWebViewUserScriptInjectionTime injectionTime)
|
||||||
|
{
|
||||||
|
WKUserScript* userScript =
|
||||||
|
[[WKUserScript alloc] initWithSource:wxCFStringRef(javascript).AsNSString()
|
||||||
|
injectionTime:(injectionTime == wxWEBVIEW_INJECT_AT_DOCUMENT_START) ?
|
||||||
|
WKUserScriptInjectionTimeAtDocumentStart : WKUserScriptInjectionTimeAtDocumentEnd
|
||||||
|
forMainFrameOnly:NO];
|
||||||
|
[m_webView.configuration.userContentController addUserScript:userScript];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxWebViewWebKit::RemoveAllUserScripts()
|
||||||
|
{
|
||||||
|
[m_webView.configuration.userContentController removeAllUserScripts];
|
||||||
|
}
|
||||||
|
|
||||||
void wxWebViewWebKit::LoadURL(const wxString& url)
|
void wxWebViewWebKit::LoadURL(const wxString& url)
|
||||||
{
|
{
|
||||||
[m_webView loadRequest:[NSURLRequest requestWithURL:
|
[m_webView loadRequest:[NSURLRequest requestWithURL:
|
||||||
@@ -891,4 +935,45 @@ WX_API_AVAILABLE_MACOS(10, 12)
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@implementation WebViewScriptMessageHandler
|
||||||
|
|
||||||
|
- (id)initWithWxWindow: (wxWebViewWebKit*)inWindow
|
||||||
|
{
|
||||||
|
if (self = [super init])
|
||||||
|
{
|
||||||
|
webKitWindow = inWindow; // non retained
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)userContentController:(nonnull WKUserContentController *)userContentController
|
||||||
|
didReceiveScriptMessage:(nonnull WKScriptMessage *)message
|
||||||
|
{
|
||||||
|
wxWebViewEvent event(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED,
|
||||||
|
webKitWindow->GetId(),
|
||||||
|
webKitWindow->GetCurrentURL(),
|
||||||
|
"",
|
||||||
|
wxWEBVIEW_NAV_ACTION_NONE,
|
||||||
|
wxCFStringRef::AsString(message.name));
|
||||||
|
if ([message.body isKindOfClass:NSString.class])
|
||||||
|
event.SetString(wxCFStringRef::AsString(message.body));
|
||||||
|
else if ([message.body isKindOfClass:NSNumber.class])
|
||||||
|
event.SetString(wxCFStringRef::AsString(((NSNumber*)message.body).stringValue));
|
||||||
|
else if ([message.body isKindOfClass:NSDate.class])
|
||||||
|
event.SetString(wxCFStringRef::AsString(((NSDate*)message.body).description));
|
||||||
|
else if ([message.body isKindOfClass:NSNull.class])
|
||||||
|
event.SetString("null");
|
||||||
|
else if ([message.body isKindOfClass:NSDictionary.class] || [message.body isKindOfClass:NSArray.class])
|
||||||
|
{
|
||||||
|
NSError* error = nil;
|
||||||
|
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:message.body options:0 error:&error];
|
||||||
|
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
|
||||||
|
event.SetString(wxCFStringRef::AsString(jsonString));
|
||||||
|
}
|
||||||
|
|
||||||
|
webKitWindow->ProcessWindowEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
#endif //wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT
|
#endif //wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT
|
||||||
|
Reference in New Issue
Block a user