diff --git a/include/wx/osx/webview_webkit.h b/include/wx/osx/webview_webkit.h index 6bd6da02f3..8b31ffdd34 100644 --- a/include/wx/osx/webview_webkit.h +++ b/include/wx/osx/webview_webkit.h @@ -89,6 +89,7 @@ public: virtual bool IsEditable() const wxOVERRIDE; bool RunScript(const wxString& javascript, wxString* output = NULL) const wxOVERRIDE; + virtual void AddScriptMessageHandler(const wxString& name) wxOVERRIDE; //Virtual Filesystem Support virtual void RegisterHandler(wxSharedPtr handler) wxOVERRIDE; diff --git a/include/wx/webview.h b/include/wx/webview.h index 24a96045eb..14f7970919 100644 --- a/include/wx/webview.h +++ b/include/wx/webview.h @@ -182,6 +182,7 @@ public: virtual void RegisterHandler(wxSharedPtr handler) = 0; virtual void Reload(wxWebViewReloadFlags flags = wxWEBVIEW_RELOAD_DEFAULT) = 0; virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const = 0; + virtual void AddScriptMessageHandler(const wxString& name) { } virtual void SetEditable(bool enable = true) = 0; void SetPage(const wxString& html, const wxString& baseUrl) { diff --git a/samples/webview/webview.cpp b/samples/webview/webview.cpp index ac9512ed89..653bd56a6c 100644 --- a/samples/webview/webview.cpp +++ b/samples/webview/webview.cpp @@ -398,6 +398,7 @@ WebFrame::WebFrame(const wxString& url) : m_browser->RegisterHandler(wxSharedPtr(new wxWebViewFSHandler("memory"))); #endif m_browser->Create(this, wxID_ANY, url, wxDefaultPosition, wxDefaultSize); + m_browser->AddScriptMessageHandler("wx"); topsizer->Add(m_browser, wxSizerFlags().Expand().Proportion(1)); #ifndef __WXMAC__ diff --git a/src/osx/webview_webkit.mm b/src/osx/webview_webkit.mm index a788f8c4a3..56647b98ed 100644 --- a/src/osx/webview_webkit.mm +++ b/src/osx/webview_webkit.mm @@ -87,6 +87,15 @@ wxEND_EVENT_TABLE() @end #endif // macOS 10.13+ +@interface WebViewScriptMessageHandler: NSObject +{ + wxWebViewWebKit* webKitWindow; +} + +- (id)initWithWxWindow: (wxWebViewWebKit*)inWindow; + +@end + //----------------------------------------------------------------------------- // wxWebViewFactoryWebKit //----------------------------------------------------------------------------- @@ -385,6 +394,12 @@ bool wxWebViewWebKit::RunScript(const wxString& javascript, wxString* output) co return true; } +void wxWebViewWebKit::AddScriptMessageHandler(const wxString& name) +{ + [m_webView.configuration.userContentController addScriptMessageHandler: + [[WebViewScriptMessageHandler alloc] initWithWxWindow:this] name:wxCFStringRef(name).AsNSString()]; +} + void wxWebViewWebKit::LoadURL(const wxString& url) { [m_webView loadRequest:[NSURLRequest requestWithURL: @@ -891,4 +906,43 @@ WX_API_AVAILABLE_MACOS(10, 12) @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(), + ""); + 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