Merge wxWebView JavaScript improvements branch
This is a squashed commit of the SOC2017_WEBVIEW_JS branch from https://github.com/joseeloren/wxWidgets.git Closes https://github.com/wxWidgets/wxWidgets/pull/538
This commit is contained in:
committed by
Vadim Zeitlin
parent
9f4f075034
commit
af8f7f33c3
57
include/wx/gtk/private/webkit.h
Normal file
57
include/wx/gtk/private/webkit.h
Normal file
@@ -0,0 +1,57 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/gtk/private/webkit.h
|
||||
// Purpose: wxWebKitGtk RAII wrappers declaration
|
||||
// Author: Jose Lorenzo
|
||||
// Created: 2017-08-21
|
||||
// Copyright: (c) 2017 Jose Lorenzo <josee.loren@gmail.com>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_GTK_PRIVATE_WEBKIT_H_
|
||||
#define _WX_GTK_PRIVATE_WEBKIT_H_
|
||||
|
||||
#include <webkit2/webkit2.h>
|
||||
#include <JavaScriptCore/JSStringRef.h>
|
||||
#include <wx/buffer.h>
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Convenience class for WebKitJavascriptResult on scope exit automatically
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class wxWebKitJavascriptResult
|
||||
{
|
||||
public:
|
||||
explicit wxWebKitJavascriptResult(WebKitJavascriptResult *r) : m_jsresult(r) { }
|
||||
~wxWebKitJavascriptResult() { webkit_javascript_result_unref (m_jsresult); }
|
||||
|
||||
operator WebKitJavascriptResult *() const { return m_jsresult; }
|
||||
|
||||
private:
|
||||
WebKitJavascriptResult *m_jsresult;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxWebKitJavascriptResult);
|
||||
};
|
||||
|
||||
class wxJSStringRef
|
||||
{
|
||||
public:
|
||||
explicit wxJSStringRef(JSStringRef r) : m_jssref(r) { }
|
||||
~wxJSStringRef() { JSStringRelease (m_jssref); }
|
||||
|
||||
const wxString ToWxString()
|
||||
{
|
||||
size_t length = JSStringGetMaximumUTF8CStringSize(m_jssref);
|
||||
wxCharBuffer str(length);
|
||||
|
||||
JSStringGetUTF8CString(m_jssref, str.data(), length);
|
||||
|
||||
return wxString::FromUTF8(str);
|
||||
}
|
||||
|
||||
private:
|
||||
JSStringRef m_jssref;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxJSStringRef);
|
||||
};
|
||||
|
||||
#endif // _WX_GTK_PRIVATE_WEBKIT_H_
|
@@ -114,7 +114,7 @@ public:
|
||||
virtual wxString GetSelectedSource() const wxOVERRIDE;
|
||||
virtual void ClearSelection() wxOVERRIDE;
|
||||
|
||||
virtual void RunScript(const wxString& javascript) wxOVERRIDE;
|
||||
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) wxOVERRIDE;
|
||||
|
||||
//Virtual Filesystem Support
|
||||
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
|
||||
@@ -160,6 +160,7 @@ private:
|
||||
#if wxUSE_WEBVIEW_WEBKIT2
|
||||
bool CanExecuteEditingCommand(const gchar* command) const;
|
||||
void SetupWebExtensionServer();
|
||||
bool RunScriptInternal(const wxString& javascript, wxString* output = NULL);
|
||||
#endif
|
||||
|
||||
WebKitWebView *m_web_view;
|
||||
|
@@ -24,6 +24,7 @@
|
||||
#include "wx/msw/webview_missing.h"
|
||||
#include "wx/sharedptr.h"
|
||||
#include "wx/vector.h"
|
||||
#include "wx/msw/private.h"
|
||||
|
||||
struct IHTMLDocument2;
|
||||
struct IHTMLElement;
|
||||
@@ -35,6 +36,11 @@ class DocHostUIHandler;
|
||||
class wxFindPointers;
|
||||
class wxIInternetProtocol;
|
||||
|
||||
#define wxIE_EMULATION_LEVEL 8000
|
||||
|
||||
//Registry key where emulation level for programs are set
|
||||
#define wxREGISTRY_IE_PATH wxT("SOFTWARE\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION")
|
||||
|
||||
class WXDLLIMPEXP_WEBVIEW wxWebViewIE : public wxWebView
|
||||
{
|
||||
public:
|
||||
@@ -121,7 +127,7 @@ public:
|
||||
virtual wxString GetSelectedSource() const wxOVERRIDE;
|
||||
virtual void ClearSelection() wxOVERRIDE;
|
||||
|
||||
virtual void RunScript(const wxString& javascript) wxOVERRIDE;
|
||||
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) wxOVERRIDE;
|
||||
|
||||
//Virtual Filesystem Support
|
||||
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
|
||||
@@ -143,6 +149,9 @@ public:
|
||||
void onActiveXEvent(wxActiveXEvent& evt);
|
||||
void onEraseBg(wxEraseEvent&) {}
|
||||
|
||||
//Establish EmulationLevel for RunScript IE
|
||||
static bool MSWSetModernEmulationLevel(bool modernLevel = true);
|
||||
|
||||
wxDECLARE_EVENT_TABLE();
|
||||
|
||||
protected:
|
||||
@@ -191,6 +200,9 @@ private:
|
||||
//Toggles control features see INTERNETFEATURELIST for values.
|
||||
bool EnableControlFeature(long flag, bool enable = true);
|
||||
|
||||
bool RunScriptInternal(wxVariant varJavascript,
|
||||
wxAutomationObject* scriptAO, wxVariant* varResult);
|
||||
|
||||
wxDECLARE_DYNAMIC_CLASS(wxWebViewIE);
|
||||
};
|
||||
|
||||
|
@@ -112,7 +112,7 @@ public:
|
||||
virtual wxString GetSelectedSource() const wxOVERRIDE;
|
||||
virtual void ClearSelection() wxOVERRIDE;
|
||||
|
||||
void RunScript(const wxString& javascript) wxOVERRIDE;
|
||||
bool RunScript(const wxString& javascript, wxString* output = NULL) wxOVERRIDE;
|
||||
|
||||
//Virtual Filesystem Support
|
||||
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) wxOVERRIDE;
|
||||
|
146
include/wx/private/jsscriptwrapper.h
Normal file
146
include/wx/private/jsscriptwrapper.h
Normal file
@@ -0,0 +1,146 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/private/jsscriptwrapper.h
|
||||
// Purpose: JS Script Wrapper for wxWebView
|
||||
// Author: Jose Lorenzo
|
||||
// Created: 2017-08-12
|
||||
// Copyright: (c) 2017 Jose Lorenzo <josee.loren@gmail.com>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_PRIVATE_JSSCRIPTWRAPPER_H_
|
||||
#define _WX_PRIVATE_JSSCRIPTWRAPPER_H_
|
||||
|
||||
#include "wx/regex.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// JS Script Wrapper for wxWebView
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class wxJSScriptWrapper
|
||||
{
|
||||
public:
|
||||
|
||||
explicit wxJSScriptWrapper(const wxString& js, int* runScriptCount) : m_jsscript(js)
|
||||
{
|
||||
// __wx$counter is used to have a different variable on every
|
||||
// RunScript call, to not lose variable values between calls
|
||||
m_wx$counter = wxString::Format("__wx$%i", (*runScriptCount)++);
|
||||
}
|
||||
|
||||
// This method is used to add a double quote level into a JavasSript code
|
||||
// in order to get it working when eval is called programmatically.
|
||||
const wxString GetWrappedCode()
|
||||
{
|
||||
// Adds one escape level if there is a single quote, double quotes or
|
||||
// esacape characters
|
||||
wxRegEx escapeDoubleQuotes("(\\\\*)(['\"\n\r\v\t\b\f])");
|
||||
escapeDoubleQuotes.Replace(&m_jsscript,"\\1\\1\\\\\\2");
|
||||
|
||||
return wxString::Format("try { var %s = eval(\"%s\"); true; } \
|
||||
catch (e) { e.name + \": \" + e.message; }", m_wx$counter, m_jsscript);;
|
||||
}
|
||||
|
||||
const wxString GetOutputCode()
|
||||
{
|
||||
#if wxUSE_WEBVIEW && wxUSE_WEBVIEW_WEBKIT && defined(__WXOSX__)
|
||||
return wxString::Format("if (typeof %s == 'object') \
|
||||
JSON.stringify(%s); \
|
||||
else if (typeof %s == 'undefined') \
|
||||
'undefined'; \
|
||||
else \
|
||||
%s;",
|
||||
m_wx$counter, m_wx$counter, m_wx$counter, m_wx$counter);
|
||||
#elif wxUSE_WEBVIEW && wxUSE_WEBVIEW_IE
|
||||
return wxString::Format("try {(%s == null || typeof %s != 'object') ? String(%s) : JSON.stringify(%s);} \
|
||||
catch (e) { \
|
||||
try \
|
||||
{ \
|
||||
function __wx$stringifyJSON(obj) \
|
||||
{ \
|
||||
var objElements = []; \
|
||||
if (!(obj instanceof Object)) \
|
||||
return typeof obj === \"string\" \
|
||||
? \'\"\' + obj + \'\"\' : \'\' + obj; \
|
||||
else if (obj instanceof Array) \
|
||||
{ \
|
||||
if (obj[0] === undefined) \
|
||||
return \'[]\'; \
|
||||
else \
|
||||
{ \
|
||||
var arr = []; \
|
||||
for (var i = 0; i < obj.length; i++) \
|
||||
arr.push(__wx$stringifyJSON(obj[i])); \
|
||||
return \'[\' + arr + \']\'; \
|
||||
} \
|
||||
} \
|
||||
else if (typeof obj === \"object\") \
|
||||
{ \
|
||||
if (obj instanceof Date) \
|
||||
{ \
|
||||
if (!Date.prototype.toISOString) \
|
||||
{ \
|
||||
(function() \
|
||||
{ \
|
||||
function pad(number) \
|
||||
{ \
|
||||
if (number < 10) \
|
||||
return '0' + number; \
|
||||
return number; \
|
||||
} \
|
||||
\
|
||||
Date.prototype.toISOString = function() \
|
||||
{ \
|
||||
return this.getUTCFullYear() + \
|
||||
'-' + pad(this.getUTCMonth() + 1) + \
|
||||
'-' + pad(this.getUTCDate()) + \
|
||||
'T' + pad(this.getUTCHours()) + \
|
||||
':' + pad(this.getUTCMinutes()) + \
|
||||
':' + pad(this.getUTCSeconds()) + \
|
||||
'.' + (this.getUTCMilliseconds() / 1000).toFixed(3).slice(2, 5) + \
|
||||
'Z\"'; \
|
||||
}; \
|
||||
\
|
||||
}()); \
|
||||
} \
|
||||
return '\"' + obj.toISOString(); + '\"' \
|
||||
} \
|
||||
for (var key in obj) \
|
||||
{ \
|
||||
if (typeof obj[key] === \"function\") \
|
||||
return \'{}\'; \
|
||||
else \
|
||||
objElements.push(\'\"\' \
|
||||
+ key + \'\":\' + \
|
||||
__wx$stringifyJSON(obj[key])); \
|
||||
} \
|
||||
return \'{\' + objElements + \'}\'; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
__wx$stringifyJSON(%s); \
|
||||
} \
|
||||
catch (e) { e.name + \": \" + e.message; }}",
|
||||
m_wx$counter, m_wx$counter, m_wx$counter, m_wx$counter, m_wx$counter);
|
||||
#else
|
||||
return m_wx$counter;
|
||||
#endif
|
||||
}
|
||||
|
||||
const wxString GetCleanUpCode()
|
||||
{
|
||||
return wxString::Format("%s = undefined;", m_wx$counter);
|
||||
}
|
||||
|
||||
const wxString GetOutputJSVariable()
|
||||
{
|
||||
return m_wx$counter;
|
||||
}
|
||||
|
||||
private:
|
||||
wxString m_jsscript;
|
||||
wxString m_wx$counter;
|
||||
|
||||
wxDECLARE_NO_COPY_CLASS(wxJSScriptWrapper);
|
||||
};
|
||||
|
||||
#endif // _WX_PRIVATE_JSSCRIPTWRAPPER_H_
|
@@ -117,6 +117,7 @@ public:
|
||||
wxWebView()
|
||||
{
|
||||
m_showMenu = true;
|
||||
m_runScriptCount = 0;
|
||||
}
|
||||
|
||||
virtual ~wxWebView() {}
|
||||
@@ -161,7 +162,7 @@ public:
|
||||
virtual void Print() = 0;
|
||||
virtual void RegisterHandler(wxSharedPtr<wxWebViewHandler> handler) = 0;
|
||||
virtual void Reload(wxWebViewReloadFlags flags = wxWEBVIEW_RELOAD_DEFAULT) = 0;
|
||||
virtual void RunScript(const wxString& javascript) = 0;
|
||||
virtual bool RunScript(const wxString& javascript, wxString* output = NULL) = 0;
|
||||
virtual void SetEditable(bool enable = true) = 0;
|
||||
void SetPage(const wxString& html, const wxString& baseUrl)
|
||||
{
|
||||
@@ -223,6 +224,10 @@ public:
|
||||
protected:
|
||||
virtual void DoSetPage(const wxString& html, const wxString& baseUrl) = 0;
|
||||
|
||||
// Count the number of calls to RunScript() in order to prevent
|
||||
// the_same variable from being used twice in more than one call.
|
||||
int m_runScriptCount;
|
||||
|
||||
private:
|
||||
static void InitFactoryMap();
|
||||
static wxStringWebViewFactoryMap::iterator FindFactory(const wxString &backend);
|
||||
|
Reference in New Issue
Block a user