From b82af43361497402ca6e054e69608a75fe26b380 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 22 Oct 2017 18:17:56 +0200 Subject: [PATCH] Improve RunScript() and MSWSetModernEmulationLevel() documentation Try to explain things better and add a couple of examples. --- interface/wx/webview.h | 116 +++++++++++++++++++++++++++++------------ 1 file changed, 82 insertions(+), 34 deletions(-) diff --git a/interface/wx/webview.h b/interface/wx/webview.h index 1eea09b681..148d427360 100644 --- a/interface/wx/webview.h +++ b/interface/wx/webview.h @@ -460,47 +460,95 @@ public: virtual void Reload(wxWebViewReloadFlags flags = wxWEBVIEW_RELOAD_DEFAULT) = 0; /** - Sets IE emulation level to a modern one, changing MSW registry. It is used to enable - JSON object on Runscript(), because it wouldn't work with default emulation level. - @see RunScript() for further details. - @param modernLevel @true to set level to IE8, @false to set level to old mode. - @return @true if level can be set, @false if it is not. + Sets emulation level to more modern level. + + This function is useful to enable some minimally modern emulation level + of the system browser control used for wxWebView implementation under + MSW, rather than using the currently default, IE7-compatible, + emulation level. Currently the modern emulation level is only IE8, but + this could change in the future and shouldn't be relied on. + + Please notice that this function works by modifying the per-user part + of MSW registry, which has several implications: first, it is + sufficient to call it only once (per user) as the changes done by it + are persistent and, second, if you do not want them to be persistent, + you need to call it with @false argument explicitly. + + In particular, this function should be called to allow RunScript() to + work for JavaScript code returning arbitrary objects, which is not + supported at the default emulation level. + + This function is MSW-specific and doesn't exist under other platforms. + + See https://msdn.microsoft.com/en-us/library/ee330730#browser_emulation + for more information about browser control emulation levels. + + @param modernLevel @true to set level to a level modern enough to allow + all wxWebView features to work (currently IE8), @false to reset the + emulation level to its default, compatible value. + @return @true on success, @false on failure (a warning message is also + logged in the latter case). + @since 3.1.1 */ - bool MSWSetModernEmulationLevel(bool modernLevel = true) = 0; + bool MSWSetModernEmulationLevel(bool modernLevel = true); /** - Runs the given JavaScript. It returns true if the script was run successfully and - additionally returns the script return value in output. - It returns strings, integers, floating point numbers, booleans and objects (as JSON). - @note When using wxWEBVIEW_WEBKIT (GTK), it returns true always unless you pass - an output param to the method. In that case, it would return false. RunScript - outputs are supported on wxWEBVIEW_WEBKIT2 (GTK3). + Runs the given JavaScript code. - When using wxWEBVIEW_WEBKIT (OSX), there are two limits: - 1) JavaScript allocations greater than 10MB. - 2) JavaScript that takes longer than 10 seconds to execute. + JavaScript code is executed inside the browser control and has full + access to DOM and other browser-provided functionality. For example, + this code + @code + webview->RunScript("document.write('Hello from wxWidgets!')"); + @endcode + will replace the current page contents with the provided string. - When using wxWEBVIEW_BACKEND_IE you must wait for the current - page to finish loading before calling RunScript(). - It is compulsory to have a script tag inside HTML to run JavaScript, on MSW. + If @a output is non-null, it is filled with the result of executing + this code on success, e.g. a JavaScript value such as a string, a + number (integer or floating point), a boolean or JSON representation + for non-primitive types such as arrays and objects. For example: + @code + wxString result; + if ( webview->RunScript + ( + "document.getElementById('some_id').innderHTML", + &result + ) ) + { + ... result contains the contents of the given element ... + } + //else: the element with this ID probably doesn't exist. + @endcode - When using wxWEBVIEW_BACKEND_IE, JSON is not available in Quirks or - IE6/7 standards mode, which is unfortunately the default one for the embedded browser control, see - https://docs.microsoft.com/en-us/scripting/javascript/reference/json-object-javascript#requirements - and see here how to make a program run use "modern" modes - https://msdn.microsoft.com/en-us/library/ee330730(v=vs.85)#browser_emulation - There are two ways to get JSON working: - 1) You can use MSWModernEmulationLevel to change emulation level (recommended), for example: - @code - MSWModernEmulationLevel(); - wxString result; - browser->RunScript("some JS code that uses JSON", &result); - @endcode - 2) There is an implementation of JSON.stringify on RunScript that helps to return objects. - You don't need to change IE emulation level but it could not work for some cases. - @param javascript A wxString containing the JavaScript. - @param output wxString result pointer. It can be NULL and it is new in wxWidgets 3.1.1. + This function has a few platform-specific limitations: + + - When using WebKit v1 in wxGTK2, retrieving the result of JavaScript + execution is unsupported and this function will always return false + if @a output is non-null to indicate this. This functionality is + fully supported when using WebKit v2 or later in wxGTK3. + + - When using WebKit under macOS, code execution is limited to at most + 10MiB of memory and 10 seconds of execution time. + + - When using IE backend under MSW, scripts can only be executed when + the current page is fully loaded (i.e. @c wxEVT_WEBVIEW_LOADED event + was received). A script tag inside the page HTML is required in order + to run JavaScript. + + Also notice that under MSW converting JavaScript objects to JSON is not + supported in the default emulation mode. wxWebView implements its own + object-to-JSON conversion as a fallback for this case, however it is + not as full-featured, well-tested or performing as the implementation + of this functionality in the browser control itself, so it is + recommended to use MSWSetModernEmulationLevel() to change emulation + level to a more modern one in which JSON conversion is done by the + control itself. + + @param javascript JavaScript code to execute. + @param output Pointer to a string to be filled with the result value or + @NULL if it is not needed. This parameter is new since wxWidgets + version 3.1.1. @return @true if there is a result, @false if there is an error. */ virtual bool RunScript(const wxString& javascript, wxString* output = NULL) = 0;