No real changes, but just use string concatenation instead of line continuation backslashes and also replace hard TABs with spaces. Notice that the code is still completely unreadable as JavaScript, but this shouldn't be a problem as nobody will see it there anyhow, so it's quite enough to have it more readable in its string form in C++.
168 lines
7.2 KiB
C++
168 lines
7.2 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// 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"
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Helper for wxWebView::RunScript()
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// This class provides GetWrappedCode(), GetOutputCode() and GetCleanUpCode()
|
|
// functions that should be executed in the backend-appropriate way by each
|
|
// wxWebView implementation in order to actually execute the user-provided
|
|
// JavaScript code, retrieve its result (if it executed successfully) and
|
|
// perform the cleanup at the end.
|
|
class wxJSScriptWrapper
|
|
{
|
|
public:
|
|
wxJSScriptWrapper(const wxString& js, int* runScriptCount)
|
|
: m_escapedCode(js)
|
|
{
|
|
// We assign the return value of JavaScript snippet we execute to the
|
|
// variable with this name in order to be able to access it later if
|
|
// needed.
|
|
//
|
|
// Note that we use a different name for it for each call to
|
|
// RunScript() (which creates a new wxJSScriptWrapper every time) to
|
|
// avoid any possible conflict between different calls.
|
|
m_outputVarName = wxString::Format("__wxOut%i", (*runScriptCount)++);
|
|
|
|
// Adds one escape level if there is a single quote, double quotes or
|
|
// escape characters
|
|
wxRegEx escapeDoubleQuotes("(\\\\*)(['\"\n\r\v\t\b\f])");
|
|
escapeDoubleQuotes.Replace(&m_escapedCode,"\\1\\1\\\\\\2");
|
|
}
|
|
|
|
// Get the code to execute, its returned value will be either boolean true,
|
|
// if it executed successfully, or the exception message if an error
|
|
// occurred.
|
|
//
|
|
// Execute GetOutputCode() later to get the real output after successful
|
|
// execution of this code.
|
|
wxString GetWrappedCode() const
|
|
{
|
|
return wxString::Format
|
|
(
|
|
"try { var %s = eval(\"%s\"); true; } "
|
|
"catch (e) { e.name + \": \" + e.message; }",
|
|
m_outputVarName,
|
|
m_escapedCode
|
|
);
|
|
}
|
|
|
|
// Get code returning the result of the last successful execution of the
|
|
// code returned by GetWrappedCode().
|
|
wxString GetOutputCode() const
|
|
{
|
|
#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_outputVarName,
|
|
m_outputVarName,
|
|
m_outputVarName,
|
|
m_outputVarName
|
|
);
|
|
#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) {"
|
|
"return number < 10"
|
|
"? '0' + number"
|
|
": 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_outputVarName,
|
|
m_outputVarName,
|
|
m_outputVarName,
|
|
m_outputVarName,
|
|
m_outputVarName
|
|
);
|
|
#else
|
|
return m_outputVarName;
|
|
#endif
|
|
}
|
|
|
|
// Execute the code returned by this function to let the output of the code
|
|
// we executed be garbage-collected.
|
|
wxString GetCleanUpCode() const
|
|
{
|
|
return wxString::Format("%s = undefined;", m_outputVarName);
|
|
}
|
|
|
|
private:
|
|
wxString m_escapedCode;
|
|
wxString m_outputVarName;
|
|
|
|
wxDECLARE_NO_COPY_CLASS(wxJSScriptWrapper);
|
|
};
|
|
|
|
#endif // _WX_PRIVATE_JSSCRIPTWRAPPER_H_
|