Implement RunScriptAsync for webkit2

This commit is contained in:
Tobias Taschner
2021-04-09 22:56:09 +02:00
committed by Tobias Taschner
parent e1bd17d883
commit 93f7df50d5
2 changed files with 42 additions and 47 deletions

View File

@@ -27,6 +27,8 @@ typedef struct _WebKitWebView WebKitWebView;
// wxWebViewWebKit // wxWebViewWebKit
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
class wxWebKitRunScriptParams;
class WXDLLIMPEXP_WEBVIEW wxWebViewWebKit : public wxWebView class WXDLLIMPEXP_WEBVIEW wxWebViewWebKit : public wxWebView
{ {
public: public:
@@ -119,13 +121,15 @@ public:
virtual wxString GetSelectedSource() const wxOVERRIDE; virtual wxString GetSelectedSource() const wxOVERRIDE;
virtual void ClearSelection() wxOVERRIDE; virtual void ClearSelection() wxOVERRIDE;
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const wxOVERRIDE;
#if wxUSE_WEBVIEW_WEBKIT2 #if wxUSE_WEBVIEW_WEBKIT2
virtual void RunScriptAsync(const wxString& javascript, void* clientData = 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;
virtual bool AddUserScript(const wxString& javascript, virtual bool AddUserScript(const wxString& javascript,
wxWebViewUserScriptInjectionTime injectionTime = wxWEBVIEW_INJECT_AT_DOCUMENT_START) wxOVERRIDE; wxWebViewUserScriptInjectionTime injectionTime = wxWEBVIEW_INJECT_AT_DOCUMENT_START) wxOVERRIDE;
virtual void RemoveAllUserScripts() wxOVERRIDE; virtual void RemoveAllUserScripts() wxOVERRIDE;
#else
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const wxOVERRIDE;
#endif #endif
//Virtual Filesystem Support //Virtual Filesystem Support
@@ -151,6 +155,11 @@ public:
//create-web-view signal and so we need to send a new window event //create-web-view signal and so we need to send a new window event
bool m_creating; bool m_creating;
#if wxUSE_WEBVIEW_WEBKIT2
// This methods needs to be public to make it callable from a callback
void ProcessJavaScriptResult(GAsyncResult *res, wxWebKitRunScriptParams* params) const;
#endif
protected: protected:
virtual void DoSetPage(const wxString& html, const wxString& baseUrl) wxOVERRIDE; virtual void DoSetPage(const wxString& html, const wxString& baseUrl) wxOVERRIDE;
@@ -173,7 +182,6 @@ private:
bool CanExecuteEditingCommand(const gchar* command) const; bool CanExecuteEditingCommand(const gchar* command) const;
void SetupWebExtensionServer(); void SetupWebExtensionServer();
GDBusProxy *GetExtensionProxy() const; GDBusProxy *GetExtensionProxy() const;
bool RunScriptSync(const wxString& javascript, wxString* output = NULL) const;
#endif #endif
WebKitWebView *m_web_view; WebKitWebView *m_web_view;

View File

@@ -1231,6 +1231,13 @@ wxString wxWebViewWebKit::GetPageText() const
return wxString(); return wxString();
} }
class wxWebKitRunScriptParams
{
public:
const wxWebViewWebKit* webKitCtrl;
void* clientData;
};
extern "C" extern "C"
{ {
@@ -1238,75 +1245,55 @@ static void wxgtk_run_javascript_cb(GObject *,
GAsyncResult *res, GAsyncResult *res,
void *user_data) void *user_data)
{ {
g_object_ref(res); wxWebKitRunScriptParams* params = static_cast<wxWebKitRunScriptParams*>(user_data);
params->webKitCtrl->ProcessJavaScriptResult(res, params);
GAsyncResult** res_out = static_cast<GAsyncResult**>(user_data);
*res_out = res;
} }
} // extern "C" } // extern "C"
// Run the given script synchronously and return its result in output. void wxWebViewWebKit::ProcessJavaScriptResult(GAsyncResult *res, wxWebKitRunScriptParams* params) const
bool wxWebViewWebKit::RunScriptSync(const wxString& javascript, wxString* output) const
{ {
GAsyncResult *result = NULL;
webkit_web_view_run_javascript(m_web_view,
javascript.utf8_str(),
NULL,
wxgtk_run_javascript_cb,
&result);
GMainContext *main_context = g_main_context_get_thread_default();
while ( !result )
g_main_context_iteration(main_context, TRUE);
wxGtkError error; wxGtkError error;
wxWebKitJavascriptResult js_result wxWebKitJavascriptResult js_result
( (
webkit_web_view_run_javascript_finish webkit_web_view_run_javascript_finish
( (
m_web_view, m_web_view,
result, res,
error.Out() error.Out()
) )
); );
// Match g_object_ref() in wxgtk_run_javascript_cb() if ( js_result )
g_object_unref(result);
if ( !js_result )
{ {
if ( output ) wxString scriptResult;
*output = error.GetMessage(); if ( wxGetStringFromJSResult(js_result, &scriptResult) )
return false; {
wxString scriptOutput;
bool success = wxJSScriptWrapper::ExtractOutput(scriptResult, &scriptOutput);
SendScriptResult(params->clientData, success, scriptOutput);
}
} }
else
SendScriptResult(params->clientData, false, error.GetMessage());
return wxGetStringFromJSResult(js_result, output); delete params;
} }
bool wxWebViewWebKit::RunScript(const wxString& javascript, wxString* output) const void wxWebViewWebKit::RunScriptAsync(const wxString& javascript, void* clientData) const
{ {
wxJSScriptWrapper wrapJS(javascript, wxJSScriptWrapper::JS_OUTPUT_STRING); wxJSScriptWrapper wrapJS(javascript, wxJSScriptWrapper::JS_OUTPUT_STRING);
bool success = false; // Collect parameters for access from the callback
wxString result; wxWebKitRunScriptParams* params = new wxWebKitRunScriptParams;
wxString scriptOutput; params->webKitCtrl = this;
if (RunScriptSync(wrapJS.GetWrappedCode(), &result)) params->clientData = clientData;
{
success = wxJSScriptWrapper::ExtractOutput(result, &scriptOutput);
}
if (output) webkit_web_view_run_javascript(m_web_view,
output->assign(scriptOutput); wrapJS.GetWrappedCode().utf8_str(),
NULL,
if (!success) wxgtk_run_javascript_cb,
{ params);
wxLogWarning(_("Error running JavaScript: %s"), scriptOutput);
return false;
}
else
return true;
} }
bool wxWebViewWebKit::AddScriptMessageHandler(const wxString& name) bool wxWebViewWebKit::AddScriptMessageHandler(const wxString& name)