Add wxWebView::RunScriptAsync()
This commit is contained in:
committed by
Tobias Taschner
parent
cf6a947dab
commit
e9dc74cb6d
@@ -88,7 +88,7 @@ public:
|
||||
|
||||
virtual bool SetUserAgent(const wxString& userAgent) wxOVERRIDE;
|
||||
|
||||
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const wxOVERRIDE;
|
||||
virtual void RunScriptAsync(const wxString& javascript, void* clientData = NULL) const wxOVERRIDE;
|
||||
virtual bool AddScriptMessageHandler(const wxString& name) wxOVERRIDE;
|
||||
virtual bool RemoveScriptMessageHandler(const wxString& name) wxOVERRIDE;
|
||||
virtual bool AddUserScript(const wxString& javascript,
|
||||
|
@@ -191,7 +191,8 @@ public:
|
||||
virtual wxString GetUserAgent() const;
|
||||
|
||||
// Script
|
||||
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const = 0;
|
||||
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) const;
|
||||
virtual void RunScriptAsync(const wxString& javascript, void* clientData = NULL) const;
|
||||
virtual bool AddScriptMessageHandler(const wxString& name)
|
||||
{ wxUnusedVar(name); return false; }
|
||||
virtual bool RemoveScriptMessageHandler(const wxString& name)
|
||||
@@ -267,6 +268,9 @@ protected:
|
||||
bool QueryCommandEnabled(const wxString& command) const;
|
||||
void ExecCommand(const wxString& command);
|
||||
|
||||
void SendScriptResult(void* clientData, bool success,
|
||||
const wxString& output) const;
|
||||
|
||||
// Count the number of calls to RunScript() in order to prevent
|
||||
// the_same variable from being used twice in more than one call.
|
||||
mutable int m_runScriptCount;
|
||||
@@ -276,6 +280,8 @@ private:
|
||||
static wxStringWebViewFactoryMap::iterator FindFactory(const wxString &backend);
|
||||
|
||||
bool m_showMenu;
|
||||
mutable int m_syncScriptResult;
|
||||
mutable wxString m_syncScriptOutput;
|
||||
wxString m_findText;
|
||||
static wxStringWebViewFactoryMap m_factoryMap;
|
||||
|
||||
@@ -319,6 +325,7 @@ wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_NEWWINDOW, wxWebVie
|
||||
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_SCRIPT_MESSAGE_RECEIVED, wxWebViewEvent);
|
||||
wxDECLARE_EXPORTED_EVENT( WXDLLIMPEXP_WEBVIEW, wxEVT_WEBVIEW_SCRIPT_RESULT, wxWebViewEvent);
|
||||
|
||||
typedef void (wxEvtHandler::*wxWebViewEventFunction)
|
||||
(wxWebViewEvent&);
|
||||
|
@@ -50,6 +50,7 @@ wxDEFINE_EVENT( wxEVT_WEBVIEW_NEWWINDOW, wxWebViewEvent );
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_TITLE_CHANGED, wxWebViewEvent );
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_FULLSCREEN_CHANGED, wxWebViewEvent);
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, wxWebViewEvent);
|
||||
wxDEFINE_EVENT( wxEVT_WEBVIEW_SCRIPT_RESULT, wxWebViewEvent);
|
||||
|
||||
wxStringWebViewFactoryMap wxWebView::m_factoryMap;
|
||||
|
||||
@@ -224,6 +225,51 @@ wxString wxWebView::GetUserAgent() const
|
||||
return userAgent;
|
||||
}
|
||||
|
||||
bool wxWebView::RunScript(const wxString& javascript, wxString* output) const
|
||||
{
|
||||
m_syncScriptResult = -1;
|
||||
m_syncScriptOutput.Clear();
|
||||
RunScriptAsync(javascript, (void*)this);
|
||||
|
||||
// Wait for script exection
|
||||
while (m_syncScriptResult == -1)
|
||||
wxYield();
|
||||
|
||||
if (m_syncScriptResult && output)
|
||||
*output = m_syncScriptOutput;
|
||||
return m_syncScriptResult == 1;
|
||||
}
|
||||
|
||||
void wxWebView::RunScriptAsync(const wxString& WXUNUSED(javascript),
|
||||
void* WXUNUSED(clientData)) const
|
||||
{
|
||||
wxLogError(_("RunScriptAsync not supported"));
|
||||
}
|
||||
|
||||
void wxWebView::SendScriptResult(void* clientData, bool success,
|
||||
const wxString& output) const
|
||||
{
|
||||
// If currently running sync RunScript() don't send an event, but use
|
||||
// the scripts result directly
|
||||
if (m_syncScriptResult == -1)
|
||||
{
|
||||
if (!success)
|
||||
wxLogWarning(_("Error running JavaScript: %s"), output);
|
||||
m_syncScriptOutput = output;
|
||||
m_syncScriptResult = success;
|
||||
}
|
||||
else
|
||||
{
|
||||
wxWebViewEvent evt(wxEVT_WEBVIEW_SCRIPT_RESULT, GetId(), "", "",
|
||||
wxWEBVIEW_NAV_ACTION_NONE);
|
||||
evt.SetEventObject(const_cast<wxWebView*>(this));
|
||||
evt.SetClientData(clientData);
|
||||
evt.SetInt(success);
|
||||
evt.SetString(output);
|
||||
HandleWindowEvent(evt);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
wxWebView* wxWebView::New(const wxString& backend)
|
||||
{
|
||||
|
@@ -831,61 +831,46 @@ void wxWebViewEdge::MSWSetBrowserExecutableDir(const wxString & path)
|
||||
wxWebViewEdgeImpl::ms_browserExecutableDir = path;
|
||||
}
|
||||
|
||||
bool wxWebViewEdge::RunScript(const wxString& javascript, wxString* output) const
|
||||
void wxWebViewEdge::RunScriptAsync(const wxString& javascript, void* clientData) const
|
||||
{
|
||||
if (!m_impl->m_webView)
|
||||
return false;
|
||||
{
|
||||
SendScriptResult(clientData, false, "");
|
||||
return; // TODO: postpone execution
|
||||
}
|
||||
|
||||
wxJSScriptWrapper wrapJS(javascript, wxJSScriptWrapper::JS_OUTPUT_STRING);
|
||||
|
||||
int scriptResult = -1;
|
||||
wxString scriptOutput;
|
||||
|
||||
// Start script execution
|
||||
HRESULT executionResult = m_impl->m_webView->ExecuteScript(wrapJS.GetWrappedCode().wc_str(), Callback<ICoreWebView2ExecuteScriptCompletedHandler>(
|
||||
[&scriptResult, &executionResult, &scriptOutput](HRESULT error, PCWSTR result) -> HRESULT
|
||||
[this, clientData](HRESULT error, PCWSTR result) -> HRESULT
|
||||
{
|
||||
// Handle script execution callback
|
||||
if (error == S_OK)
|
||||
{
|
||||
scriptOutput.assign(result);
|
||||
scriptResult = 1;
|
||||
wxString scriptDecodedResult;
|
||||
// Try to decode JSON string or return original
|
||||
// result if it's not a valid JSON string
|
||||
if (!wxJSON::DecodeString(result, &scriptDecodedResult))
|
||||
scriptDecodedResult = result;
|
||||
|
||||
wxString scriptExtractedOutput;
|
||||
bool success = wxJSScriptWrapper::ExtractOutput(scriptDecodedResult, &scriptExtractedOutput);
|
||||
SendScriptResult(clientData, success, scriptExtractedOutput);
|
||||
}
|
||||
else
|
||||
{
|
||||
executionResult = error;
|
||||
scriptResult = 0;
|
||||
SendScriptResult(clientData, false, wxString::Format("%s (0x%08lx)",
|
||||
wxSysErrorMsgStr(error), error));
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}).Get());
|
||||
|
||||
// Wait for script exection
|
||||
while (scriptResult == -1)
|
||||
wxYield();
|
||||
|
||||
if (FAILED(executionResult))
|
||||
{
|
||||
if (output)
|
||||
output->Printf("%s (0x%08lx)", wxSysErrorMsgStr(executionResult), executionResult);
|
||||
return false;
|
||||
SendScriptResult(clientData, false, wxString::Format("%s (0x%08lx)",
|
||||
wxSysErrorMsgStr(executionResult), executionResult));
|
||||
}
|
||||
|
||||
wxString scriptDecodedResult;
|
||||
// Try to decode JSON string or return original
|
||||
// result if it's not a valid JSON string
|
||||
if (!wxJSON::DecodeString(scriptOutput, &scriptDecodedResult))
|
||||
scriptDecodedResult = scriptOutput;
|
||||
|
||||
wxString scriptExtractedOutput;
|
||||
bool success = wxJSScriptWrapper::ExtractOutput(scriptDecodedResult, &scriptExtractedOutput);
|
||||
if (!success)
|
||||
wxLogWarning(_("Error running JavaScript: %s"), scriptExtractedOutput);
|
||||
|
||||
if (output)
|
||||
*output = scriptDecodedResult;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool wxWebViewEdge::AddScriptMessageHandler(const wxString& name)
|
||||
|
Reference in New Issue
Block a user