Skip to content

Commit 0837d84

Browse files
authored
Update ExecuteScriptWithResult.md
1 parent 82e8903 commit 0837d84

File tree

1 file changed

+100
-84
lines changed

1 file changed

+100
-84
lines changed

specs/ExecuteScriptWithResult.md

Lines changed: 100 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ The following code snippets demonstrate how the ExecuteScriptWithResult can be u
2121
// Using std::wstringstream to generate script code,
2222
// it will generate the code like
2323
// 'let str_0 = "This is a string"; let n_0= str_0.replace(/a/i, "microsoft"); n_0;'
24-
static std::wstring GenerateScriptCode(LPCWSTR str, LPCWSTR reg, LPCWSTR item)
24+
std::wstring GenerateScriptCode(LPCWSTR str, LPCWSTR reg, LPCWSTR item)
2525
{
2626
if (str == nullptr || reg == nullptr || item == nullptr)
2727
{
@@ -42,7 +42,7 @@ static std::wstring GenerateScriptCode(LPCWSTR str, LPCWSTR reg, LPCWSTR item)
4242
}
4343

4444
// This is a demo that uses regular expressions in
45-
// javascript to complete string replacement, it will handle
45+
// JavaScript to complete string replacement, it will handle
4646
// the case of successful execution and execution exception
4747
void MatchRegWithScript(wil::com_ptr<ICoreWebView2> webView
4848
, LPCWSTR str
@@ -51,80 +51,83 @@ void MatchRegWithScript(wil::com_ptr<ICoreWebView2> webView
5151
{
5252
wil::com_ptr<ICoreWebView2_10> webview2 = webView.try_query<ICoreWebView2_10>();
5353

54+
if (!webview2)
55+
{
56+
// ExecuteScriptWithResult is not supported by this WebView.
57+
return;
58+
}
59+
5460
auto scriptCode = GenerateScriptCode(str, reg, item);
5561
webview2->ExecuteScriptWithResult(
5662
scriptCode.c_str(),
5763
Callback<ICoreWebView2ExecuteScriptWithResultCompletedHandler>(
5864
[](
5965
HRESULT errorCode, ICoreWebView2ExecuteScriptResult* result) -> HRESULT
6066
{
61-
if (errorCode != S_OK || result == nullptr)
62-
{
63-
MessageBox(
64-
nullptr, L"Get execute status failed!", L"ExecuteScript Result", MB_OK);
65-
}
66-
else
67-
{
68-
wil::unique_cotaskmem_string stringData;
67+
// There is usually no failure here, if the assertion fails,
68+
// the runtime environment has an exception and needs to fail fast.
69+
CHECK_FAILURE(errorCode);
6970

70-
BOOL isSuccess;
71-
result->get_IsSuccess(&isSuccess);
72-
// Here is the successful execution.
73-
// We will use a MessageBox to print the replaced result.
74-
if (isSuccess)
71+
wil::unique_cotaskmem_string stringData;
72+
73+
BOOL isSuccess;
74+
result->get_Succeeded(&isSuccess);
75+
// Here is the successful execution.
76+
// We will use a MessageBox to print the replaced result.
77+
if (isSuccess)
78+
{
79+
// We try to use TryGetResultAsString to get the string result here.
80+
// Since the JavaScript platform's `string.replace` returns a string,
81+
// the call here will succeed.
82+
// If the script is replaced by `string.search`, the function will
83+
// return an int and the call will fail here.
84+
if (result->TryGetResultAsString(&stringData) != S_OK)
7585
{
76-
// We try to use TryGetResultAsString to get the string result here.
77-
// Since the javascript platform's `string.replace` returns a string,
78-
// the call here will succeed.
79-
// If the script is replaced by `string.search`, the function will
80-
// return an int and the call will fail here.
81-
if (result->TryGetResultAsString(&stringData) != S_OK)
82-
{
83-
MessageBox(
84-
nullptr, L"Get string failed", L"ExecuteScript Result", MB_OK);
85-
}
86-
else
87-
{
88-
MessageBox(nullptr, stringData.get(), L"ExecuteScript Result",
89-
MB_OK);
90-
}
86+
MessageBox(
87+
nullptr, L"Get string failed", L"ExecuteScript Result", MB_OK);
9188
}
92-
// Here is the case of execution exception.
93-
// We will use MessageBox to print exception-related information
9489
else
9590
{
96-
wil::com_ptr<ICoreWebView2ExecuteScriptException> exception;
97-
98-
result->get_Exception(&exception);
99-
100-
// The ExceptionName property could be the empty string if script throws a non-Error object,
101-
// such as `throw 1`.
102-
wil::unique_cotaskmem_string exceptionName;
103-
exception->get_Name(&exceptionName);
104-
105-
// The ExceptionMessage property could be the empty string if script throws a non-Error object,
106-
// such as `throw 1`.
107-
wil::unique_cotaskmem_string exceptionMessage;
108-
exception->get_Message(&exceptionMessage)
109-
110-
// Get the location of the exception, note that the coordinates
111-
// here are 0 as the starting position.
112-
uint32_t lineNumber = 0;
113-
uint32_t columnNumber = 0;
114-
exception->get_LineNumber(&lineNumber);
115-
exception->get_ColumnNumber(&columnNumber);
116-
117-
auto exceptionInfo =
118-
L"The script execution failed." +
119-
L"\nName: " + exceptionName.get() +
120-
L"\nMessage: " + exceptionMessage.get() +
121-
L"\nLineNumber: " + std::to_wstring(lineNumber) +
122-
L", ColumnNumber:" + std::to_wstring(columnNumber);
123-
MessageBox(
124-
nullptr, exceptionInfo.c_str(),
125-
L"ExecuteScript Result", MB_OK);
91+
MessageBox(nullptr, stringData.get(), L"ExecuteScript Result",
92+
MB_OK);
12693
}
12794
}
95+
// Here is the case of execution exception.
96+
// We will use MessageBox to print exception-related information
97+
else
98+
{
99+
wil::com_ptr<ICoreWebView2ExecuteScriptException> exception;
100+
101+
result->get_Exception(&exception);
102+
103+
// The ExceptionName property could be the empty string if script throws a non-Error object,
104+
// such as `throw 1`.
105+
wil::unique_cotaskmem_string exceptionName;
106+
exception->get_Name(&exceptionName);
107+
108+
// The ExceptionMessage property could be the empty string if script throws a non-Error object,
109+
// such as `throw 1`.
110+
wil::unique_cotaskmem_string exceptionMessage;
111+
exception->get_Message(&exceptionMessage)
112+
113+
// Get the location of the exception, note that the coordinates
114+
// here are 0 as the starting position.
115+
uint32_t lineNumber = 0;
116+
uint32_t columnNumber = 0;
117+
exception->get_LineNumber(&lineNumber);
118+
exception->get_ColumnNumber(&columnNumber);
119+
120+
auto exceptionInfo =
121+
L"The script execution failed." +
122+
L"\nName: " + exceptionName.get() +
123+
L"\nMessage: " + exceptionMessage.get() +
124+
L"\nLineNumber: " + std::to_wstring(lineNumber) +
125+
L", ColumnNumber:" + std::to_wstring(columnNumber);
126+
MessageBox(
127+
nullptr, exceptionInfo.c_str(),
128+
L"ExecuteScript Result", MB_OK);
129+
}
130+
128131
return S_OK;
129132
})
130133
.Get());
@@ -133,33 +136,34 @@ void MatchRegWithScript(wil::com_ptr<ICoreWebView2> webView
133136
```
134137
## .NET and WinRT
135138
```c#
136-
class ExecuteScriptWithResultDemo {
139+
class ExecuteScriptWithResultDemo
140+
{
137141
int idx = 0;
138142
139-
private String GenerateScriptCode(String str, String reg, String item) {
140-
String ret = "let str_" + idx + " = \"" + str + "\"; let n_" + idx + "= str_" + idx
141-
+ ".replace(" + reg + ", \"" + item + "\"); n_" + idx + ";";
143+
private String GenerateScriptCode(String str, String reg, String item)
144+
{
145+
String ret = $"let str_{idx} = \"{str}\"; let n_{idx} = str_{idx}.replace({reg}, \"{item}\"); n_{idx};";
142146
++idx;
143147
return ret;
144148
}
145149
146150
147151
// This is a demo that uses regular expressions in
148-
// javascript to complete string replacement, it will handle
152+
// JavaScript to complete string replacement, it will handle
149153
// the case of successful execution and execution exception
150-
public void MatchRegWithScript(String str, String reg, String item) {
151-
var environment = webView2Control.CoreWebView2.Environment;
154+
public void MatchRegWithScript(String str, String reg, String item)
155+
{
152156
String script = GenerateScriptCode(str, reg, item);
153157
CoreWebView2ExecuteScriptResult result = await ExecuteScriptWithResultAsync(script);
154158
155-
bool isSuccess = result.IsSuccess;
159+
bool isSuccess = result.Succeeded;
156160
// Here is the successful execution.
157161
if (isSuccess) {
158162
// Try to get the string result, it will throw an exception
159163
// if the result type isn't string type.
160164
try {
161165
String stringResult = result.TryGetResultAsString();
162-
Debug.WriteLine($"replaced string: {result.stringResult}");
166+
Debug.WriteLine($"replaced string: {stringResult}");
163167
}
164168
catch (ArgumentException) {
165169
Debug.WriteLine($"Non-string message received");
@@ -171,7 +175,7 @@ class ExecuteScriptWithResultDemo {
171175
var exception = result.Exception;
172176
String exceptionInfo = "The script execution failed." +
173177
"\nName:" + exception.Name +
174-
"\nMesssge: " + exception.Message +
178+
"\nMessage: " + exception.Message +
175179
"\nLineNumber:" + exception.LineNumber +
176180
", ColumnNumber:" + exception.ColumnNumber;
177181
Debug.WriteLine($"{exceptionInfo}");
@@ -184,7 +188,7 @@ class ExecuteScriptWithResultDemo {
184188
## Win32 C++
185189
```c++
186190
/// This interface represents a JavaScript exception.
187-
/// If the CoreWebView2.ExecuteScriptWithResult result has IsSuccessful as false,
191+
/// If the CoreWebView2.ExecuteScriptWithResult result has Succeeded as false,
188192
/// you can use the result's Exception property to get the script exception.
189193
[uuid(82F22B72-1B22-403E-A0B9-A8816C9C8E45), object, pointer_default(unique)]
190194
interface ICoreWebView2ExecuteScriptException : IUnknown {
@@ -214,7 +218,7 @@ interface ICoreWebView2ExecuteScriptException : IUnknown {
214218
/// This will return all details of the exception as a JSON string.
215219
/// In the case that script has thrown a non-Error object such as `throw "abc";`
216220
/// or any other non-Error object, you can get object specific properties.
217-
[propget] HRESULT ExceptionAsJSON([out, retval] LPWSTR* value);
221+
[propget] HRESULT ToJson([out, retval] LPWSTR* value);
218222
}
219223

220224
/// This is the result for ExecuteScriptWithResult.
@@ -226,18 +230,30 @@ interface ICoreWebView2ExecuteScriptResult : IUnknown {
226230
/// or via the TryGetResultAsString method.
227231
/// If it is false then the script execution had an unhandled exception which you
228232
/// can get via the Exception property.
229-
[propget] HRESULT IsSuccess([out, retval] BOOL* value);
233+
[propget] HRESULT Succeeded([out, retval] BOOL* value);
230234

231-
/// If IsSuccess is true, then this property is the JSON representation of the result of the script execution
232-
/// and otherwise returns E_INVALIDARG.
235+
/// A function that has no explicit return value returns undefined. If the
236+
/// script that was run throws an unhandled exception, then the result is
237+
/// also "null". This method is applied asynchronously. If the method is
238+
/// run before `ContentLoading`, the script will not be executed
239+
/// and the string "null" will be returned.
240+
241+
/// The return value description is as follows
242+
/// 1. S_OK: Execution succeeds.
243+
/// 2. E_POINTER: When the `jsonResult` is nullptr.
233244
[propget] HRESULT ResultAsJson([out, retval] LPWSTR* jsonResult);
234245

235-
/// If IsSuccess is true and the result of script execution is a string, this method provides the value of the string result
236-
/// and otherwise returns E_INVALIDARG.
246+
/// If Succeeded is true and the result of script execution is a string, this method provides the value of the string result
247+
/// The return value description is as follows
248+
/// 1. S_OK: Execution succeeds.
249+
/// 2. E_ILLEGAL_METHOD_CALL: When the script result is not a string type.
250+
/// 3. E_POINTER: When the `stringResult` is nullptr.
237251
HRESULT TryGetResultAsString([out, retval] LPWSTR* stringResult);
238252

239-
/// If IsSuccess is false, you can use this property to get the unhandled exception thrown by script execution
240-
/// and otherwise returns E_INVALIDARG.
253+
/// If Succeeded is false, you can use this property to get the unhandled exception thrown by script execution
254+
/// Note that due to the compatibility of the WinRT/.NET interface,
255+
/// S_OK will be returned even if the acquisition fails.
256+
/// We can determine whether the acquisition is successful by judging whether the `exception` is nullptr.
241257
[propget] HRESULT Exception(
242258
[out, retval] ICoreWebView2ExecuteScriptException** exception);
243259
}
@@ -256,7 +272,7 @@ interface ICoreWebView2ExecuteScriptWithResultCompletedHandler : IUnknown {
256272
[uuid(67E0B57B-1AC7-4395-9793-5E4EF9C4B7D9), object, pointer_default(unique)]
257273
interface ICoreWebView2_10 : ICoreWebView2_9 {
258274

259-
/// Run JavaScript code from the javaScript parameter in the current
275+
/// Run JavaScript code from the JavaScript parameter in the current
260276
/// top-level document rendered in the WebView.
261277
/// The result of the execution is returned asynchronously in the CoreWebView2ExecuteScriptResult object
262278
/// which has methods and properties to obtain the successful result of script execution as well as any
@@ -290,7 +306,7 @@ namespace Microsoft.Web.WebView2.Core
290306

291307
runtimeclass CoreWebView2ExecuteScriptResult
292308
{
293-
Boolean IsSuccess { get; };
309+
Boolean Succeeded { get; };
294310

295311
String ResultAsJson { get; };
296312

@@ -309,7 +325,7 @@ namespace Microsoft.Web.WebView2.Core
309325

310326
String Message { get; };
311327

312-
String ExceptionAsJSON { get; };
328+
String ToJson { get; };
313329
}
314330
}
315331
```

0 commit comments

Comments
 (0)