Skip to content

Commit 8108c34

Browse files
authored
[HybridWebView] Fix some issues with the typescript (#29873)
1 parent 767fcfd commit 8108c34

File tree

2 files changed

+154
-146
lines changed

2 files changed

+154
-146
lines changed

src/Core/src/Handlers/HybridWebView/HybridWebView.js

Lines changed: 75 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@
1818
window.dispatchEvent(event);
1919
}
2020
// Determine the mechanism to receive messages from the host application.
21-
if (window.chrome?.webview?.addEventListener) {
21+
if (window.chrome && window.chrome.webview && window.chrome.webview.addEventListener) {
2222
// Windows WebView2
2323
window.chrome.webview.addEventListener('message', (arg) => {
2424
dispatchHybridWebViewMessage(arg.data);
2525
});
2626
}
27-
else if (window.webkit?.messageHandlers?.webwindowinterop) {
27+
else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.webwindowinterop) {
2828
// iOS and MacCatalyst WKWebView
2929
// @ts-ignore - We are extending the global object here
3030
window.external = {
@@ -40,11 +40,11 @@
4040
});
4141
}
4242
// Determine the function to use to send messages to the host application.
43-
if (window.chrome?.webview) {
43+
if (window.chrome && window.chrome.webview) {
4444
// Windows WebView2
4545
sendMessageFunction = msg => window.chrome.webview.postMessage(msg);
4646
}
47-
else if (window.webkit?.messageHandlers?.webwindowinterop) {
47+
else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.webwindowinterop) {
4848
// iOS and MacCatalyst WKWebView
4949
sendMessageFunction = msg => window.webkit.messageHandlers.webwindowinterop.postMessage(msg);
5050
}
@@ -108,78 +108,82 @@
108108
const json = JSON.stringify(errorObj);
109109
sendMessageToDotNet('__InvokeJavaScriptFailed', taskId + '|' + json);
110110
}
111-
const HybridWebView = {
112-
/*
113-
* Send a raw message to the .NET host application.
114-
* The message is sent directly and not processed or serialized.
115-
*
116-
* @param message The message to send to the .NET host application.
117-
*/
118-
SendRawMessage: function (message) {
119-
sendMessageToDotNet('__RawMessage', message);
120-
},
121-
/*
122-
* Invoke a .NET method on the InvokeJavaScriptTarget instance.
123-
* The method name and parameters are serialized and sent to the .NET host application.
124-
*
125-
* @param methodName The name of the .NET method to invoke.
126-
* @param paramValues The parameters to pass to the .NET method. If the method takes no parameters, this can be omitted.
127-
*
128-
* @returns A promise that resolves with the result of the .NET method invocation.
129-
*/
130-
InvokeDotNet: async function (methodName, paramValues) {
131-
const body = {
132-
MethodName: methodName
133-
};
134-
// if parameters were provided, serialize them first
135-
if (paramValues !== undefined) {
136-
if (!Array.isArray(paramValues)) {
137-
paramValues = [paramValues];
138-
}
139-
for (let i = 0; i < paramValues.length; i++) {
140-
paramValues[i] = JSON.stringify(paramValues[i]);
141-
}
142-
if (paramValues.length > 0) {
143-
body.ParamValues = paramValues;
144-
}
145-
}
146-
const message = JSON.stringify(body);
147-
const requestUrl = `${window.location.origin}/__hwvInvokeDotNet?data=${encodeURIComponent(message)}`;
148-
const rawResponse = await fetch(requestUrl, {
149-
method: 'GET',
150-
headers: {
151-
'Accept': 'application/json'
152-
}
153-
});
154-
const response = await rawResponse.json();
155-
if (!response) {
156-
return null;
111+
/*
112+
* Send a raw message to the .NET host application.
113+
* The message is sent directly and not processed or serialized.
114+
*
115+
* @param message The message to send to the .NET host application.
116+
*/
117+
function sendRawMessage(message) {
118+
sendMessageToDotNet('__RawMessage', message);
119+
}
120+
/*
121+
* Invoke a .NET method on the InvokeJavaScriptTarget instance.
122+
* The method name and parameters are serialized and sent to the .NET host application.
123+
*
124+
* @param methodName The name of the .NET method to invoke.
125+
* @param paramValues The parameters to pass to the .NET method. If the method takes no parameters, this can be omitted.
126+
*
127+
* @returns A promise that resolves with the result of the .NET method invocation.
128+
*/
129+
async function invokeDotNet(methodName, paramValues) {
130+
const body = {
131+
MethodName: methodName
132+
};
133+
// if parameters were provided, serialize them first
134+
if (paramValues !== undefined) {
135+
if (!Array.isArray(paramValues)) {
136+
paramValues = [paramValues];
157137
}
158-
if (response.IsJson) {
159-
return JSON.parse(response.Result);
138+
for (let i = 0; i < paramValues.length; i++) {
139+
paramValues[i] = JSON.stringify(paramValues[i]);
160140
}
161-
return response.Result;
162-
},
163-
/*
164-
* Invoke a JavaScript method from the .NET host application.
165-
* This method is called from the HybridWebViewHandler and is not intended to be used by user applications.
166-
*
167-
* @param taskId The task ID that was provided by the .NET host application.
168-
* @param methodName The JavaScript method to invoke in the global scope.
169-
* @param args The arguments to pass to the JavaScript method.
170-
*
171-
* @returns A promise.
172-
*/
173-
__InvokeJavaScript: async function (taskId, methodName, args) {
174-
try {
175-
const result = await methodName(...args);
176-
invokeJavaScriptCallbackInDotNet(taskId, result);
141+
if (paramValues.length > 0) {
142+
body.ParamValues = paramValues;
177143
}
178-
catch (ex) {
179-
console.error(ex);
180-
invokeJavaScriptFailedInDotNet(taskId, ex);
144+
}
145+
const message = JSON.stringify(body);
146+
const requestUrl = `${window.location.origin}/__hwvInvokeDotNet?data=${encodeURIComponent(message)}`;
147+
const rawResponse = await fetch(requestUrl, {
148+
method: 'GET',
149+
headers: {
150+
'Accept': 'application/json'
181151
}
152+
});
153+
const response = await rawResponse.json();
154+
if (!response) {
155+
return null;
156+
}
157+
if (response.IsJson) {
158+
return JSON.parse(response.Result);
182159
}
160+
return response.Result;
161+
}
162+
/*
163+
* Invoke a JavaScript method from the .NET host application.
164+
* This method is called from the HybridWebViewHandler and is not intended to be used by user applications.
165+
*
166+
* @param taskId The task ID that was provided by the .NET host application.
167+
* @param methodName The JavaScript method to invoke in the global scope.
168+
* @param args The arguments to pass to the JavaScript method.
169+
*
170+
* @returns A promise.
171+
*/
172+
async function invokeJavaScript(taskId, methodName, args) {
173+
try {
174+
const result = await methodName(...args);
175+
invokeJavaScriptCallbackInDotNet(taskId, result);
176+
}
177+
catch (ex) {
178+
console.error(ex);
179+
invokeJavaScriptFailedInDotNet(taskId, ex);
180+
}
181+
}
182+
// Define the public API of the HybridWebView control.
183+
const HybridWebView = {
184+
SendRawMessage: sendRawMessage,
185+
InvokeDotNet: invokeDotNet,
186+
__InvokeJavaScript: invokeJavaScript
183187
};
184188
// Make the following APIs available in global scope for invocation from JS
185189
// @ts-ignore - We are extending the global object here

src/Core/src/Handlers/HybridWebView/HybridWebView.ts

Lines changed: 79 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ interface DotNetInvokeResult {
6868
}
6969

7070
// Determine the mechanism to receive messages from the host application.
71-
if (window.chrome?.webview?.addEventListener) {
71+
if (window.chrome && window.chrome.webview && window.chrome.webview.addEventListener) {
7272
// Windows WebView2
7373
window.chrome.webview.addEventListener('message', (arg: any) => {
7474
dispatchHybridWebViewMessage(arg.data);
7575
});
76-
} else if (window.webkit?.messageHandlers?.webwindowinterop) {
76+
} else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.webwindowinterop) {
7777
// iOS and MacCatalyst WKWebView
7878
// @ts-ignore - We are extending the global object here
7979
window.external = {
@@ -89,10 +89,10 @@ interface DotNetInvokeResult {
8989
}
9090

9191
// Determine the function to use to send messages to the host application.
92-
if (window.chrome?.webview) {
92+
if (window.chrome && window.chrome.webview) {
9393
// Windows WebView2
9494
sendMessageFunction = msg => window.chrome.webview.postMessage(msg);
95-
} else if (window.webkit?.messageHandlers?.webwindowinterop) {
95+
} else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.webwindowinterop) {
9696
// iOS and MacCatalyst WKWebView
9797
sendMessageFunction = msg => window.webkit.messageHandlers.webwindowinterop.postMessage(msg);
9898
} else if (window.hybridWebViewHost) {
@@ -160,89 +160,93 @@ interface DotNetInvokeResult {
160160
sendMessageToDotNet('__InvokeJavaScriptFailed', taskId + '|' + json);
161161
}
162162

163-
const HybridWebView = {
164-
165-
/*
166-
* Send a raw message to the .NET host application.
167-
* The message is sent directly and not processed or serialized.
168-
*
169-
* @param message The message to send to the .NET host application.
170-
*/
171-
SendRawMessage: function (message: string) {
172-
sendMessageToDotNet('__RawMessage', message);
173-
},
174-
175-
/*
176-
* Invoke a .NET method on the InvokeJavaScriptTarget instance.
177-
* The method name and parameters are serialized and sent to the .NET host application.
178-
*
179-
* @param methodName The name of the .NET method to invoke.
180-
* @param paramValues The parameters to pass to the .NET method. If the method takes no parameters, this can be omitted.
181-
*
182-
* @returns A promise that resolves with the result of the .NET method invocation.
183-
*/
184-
InvokeDotNet: async function (methodName: string, paramValues?: any) {
185-
const body: JSInvokeMethodData = {
186-
MethodName: methodName
187-
};
163+
/*
164+
* Send a raw message to the .NET host application.
165+
* The message is sent directly and not processed or serialized.
166+
*
167+
* @param message The message to send to the .NET host application.
168+
*/
169+
function sendRawMessage(message: string) {
170+
sendMessageToDotNet('__RawMessage', message);
171+
}
188172

189-
// if parameters were provided, serialize them first
190-
if (paramValues !== undefined) {
191-
if (!Array.isArray(paramValues)) {
192-
paramValues = [paramValues];
193-
}
173+
/*
174+
* Invoke a .NET method on the InvokeJavaScriptTarget instance.
175+
* The method name and parameters are serialized and sent to the .NET host application.
176+
*
177+
* @param methodName The name of the .NET method to invoke.
178+
* @param paramValues The parameters to pass to the .NET method. If the method takes no parameters, this can be omitted.
179+
*
180+
* @returns A promise that resolves with the result of the .NET method invocation.
181+
*/
182+
async function invokeDotNet(methodName: string, paramValues?: any) {
183+
const body: JSInvokeMethodData = {
184+
MethodName: methodName
185+
};
194186

195-
for (let i = 0; i < paramValues.length; i++) {
196-
paramValues[i] = JSON.stringify(paramValues[i]);
197-
}
187+
// if parameters were provided, serialize them first
188+
if (paramValues !== undefined) {
189+
if (!Array.isArray(paramValues)) {
190+
paramValues = [paramValues];
191+
}
198192

199-
if (paramValues.length > 0) {
200-
body.ParamValues = paramValues;
201-
}
193+
for (let i = 0; i < paramValues.length; i++) {
194+
paramValues[i] = JSON.stringify(paramValues[i]);
202195
}
203196

204-
const message = JSON.stringify(body);
197+
if (paramValues.length > 0) {
198+
body.ParamValues = paramValues;
199+
}
200+
}
205201

206-
const requestUrl = `${window.location.origin}/__hwvInvokeDotNet?data=${encodeURIComponent(message)}`;
202+
const message = JSON.stringify(body);
207203

208-
const rawResponse = await fetch(requestUrl, {
209-
method: 'GET',
210-
headers: {
211-
'Accept': 'application/json'
212-
}
213-
});
214-
const response: DotNetInvokeResult = await rawResponse.json();
204+
const requestUrl = `${window.location.origin}/__hwvInvokeDotNet?data=${encodeURIComponent(message)}`;
215205

216-
if (!response) {
217-
return null;
206+
const rawResponse = await fetch(requestUrl, {
207+
method: 'GET',
208+
headers: {
209+
'Accept': 'application/json'
218210
}
211+
});
212+
const response: DotNetInvokeResult = await rawResponse.json();
219213

220-
if (response.IsJson) {
221-
return JSON.parse(response.Result);
222-
}
214+
if (!response) {
215+
return null;
216+
}
223217

224-
return response.Result;
225-
},
226-
227-
/*
228-
* Invoke a JavaScript method from the .NET host application.
229-
* This method is called from the HybridWebViewHandler and is not intended to be used by user applications.
230-
*
231-
* @param taskId The task ID that was provided by the .NET host application.
232-
* @param methodName The JavaScript method to invoke in the global scope.
233-
* @param args The arguments to pass to the JavaScript method.
234-
*
235-
* @returns A promise.
236-
*/
237-
__InvokeJavaScript: async function (taskId: string, methodName: Function, args: any[]) {
238-
try {
239-
const result = await methodName(...args);
240-
invokeJavaScriptCallbackInDotNet(taskId, result);
241-
} catch (ex) {
242-
console.error(ex);
243-
invokeJavaScriptFailedInDotNet(taskId, ex);
244-
}
218+
if (response.IsJson) {
219+
return JSON.parse(response.Result);
220+
}
221+
222+
return response.Result;
223+
}
224+
225+
/*
226+
* Invoke a JavaScript method from the .NET host application.
227+
* This method is called from the HybridWebViewHandler and is not intended to be used by user applications.
228+
*
229+
* @param taskId The task ID that was provided by the .NET host application.
230+
* @param methodName The JavaScript method to invoke in the global scope.
231+
* @param args The arguments to pass to the JavaScript method.
232+
*
233+
* @returns A promise.
234+
*/
235+
async function invokeJavaScript(taskId: string, methodName: Function, args: any[]) {
236+
try {
237+
const result = await methodName(...args);
238+
invokeJavaScriptCallbackInDotNet(taskId, result);
239+
} catch (ex) {
240+
console.error(ex);
241+
invokeJavaScriptFailedInDotNet(taskId, ex);
245242
}
243+
}
244+
245+
// Define the public API of the HybridWebView control.
246+
const HybridWebView = {
247+
SendRawMessage: sendRawMessage,
248+
InvokeDotNet: invokeDotNet,
249+
__InvokeJavaScript: invokeJavaScript
246250
};
247251

248252
// Make the following APIs available in global scope for invocation from JS

0 commit comments

Comments
 (0)