Rename a variable to remove the ugly "sz" prefix. Also don't use "s_" prefix for non-static variables.
		
			
				
	
	
		
			197 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			8.1 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.
 | |
|         const char *charsNeededToBeEscaped = "\\\"\n\r\v\t\b\f";
 | |
|         for (
 | |
|             size_t pos = m_escapedCode.find_first_of(charsNeededToBeEscaped, 0);
 | |
|             pos != wxString::npos;
 | |
|             pos = m_escapedCode.find_first_of(charsNeededToBeEscaped, pos)
 | |
|         ) {
 | |
|             switch (m_escapedCode[pos].GetValue())
 | |
|             {
 | |
|             case 0x0A: // '\n'
 | |
|                 m_escapedCode[pos] = 'n';
 | |
|                 break;
 | |
|             case 0x0D: // '\r'
 | |
|                 m_escapedCode[pos] = 'r';
 | |
|                 break;
 | |
|             case 0x0B: // '\v'
 | |
|                 m_escapedCode[pos] = 'v';
 | |
|                 break;
 | |
|             case 0x09: // '\t'
 | |
|                 m_escapedCode[pos] = 't';
 | |
|                 break;
 | |
|             case 0x08: // '\b'
 | |
|                 m_escapedCode[pos] = 'b';
 | |
|                 break;
 | |
|             case 0x0C: // '\f'
 | |
|                 m_escapedCode[pos] = 'f';
 | |
|                 break;
 | |
|             }
 | |
|             m_escapedCode.insert(pos, '\\');
 | |
|             pos += 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) {"
 | |
|                             "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(); + '\"'"
 | |
|                                 "}"
 | |
|                                 "var objElements = [];"
 | |
|                                 "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
 | |
|     }
 | |
| 
 | |
|     const wxString& GetUnwrappedOutputCode() { return m_outputVarName; }
 | |
| 
 | |
|     // 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_
 |