From 2b766e40565ee746b9502b73c76195f2f704fe82 Mon Sep 17 00:00:00 2001 From: Matthew Leibowitz Date: Thu, 5 Jun 2025 20:47:47 +0200 Subject: [PATCH] [HybridWebView] Fix some issues with the typescript --- .../Handlers/HybridWebView/HybridWebView.js | 146 +++++++++-------- .../Handlers/HybridWebView/HybridWebView.ts | 154 +++++++++--------- 2 files changed, 154 insertions(+), 146 deletions(-) diff --git a/src/Core/src/Handlers/HybridWebView/HybridWebView.js b/src/Core/src/Handlers/HybridWebView/HybridWebView.js index 6cbce2c552db..e76a75b65ba3 100644 --- a/src/Core/src/Handlers/HybridWebView/HybridWebView.js +++ b/src/Core/src/Handlers/HybridWebView/HybridWebView.js @@ -18,13 +18,13 @@ window.dispatchEvent(event); } // Determine the mechanism to receive messages from the host application. - if (window.chrome?.webview?.addEventListener) { + if (window.chrome && window.chrome.webview && window.chrome.webview.addEventListener) { // Windows WebView2 window.chrome.webview.addEventListener('message', (arg) => { dispatchHybridWebViewMessage(arg.data); }); } - else if (window.webkit?.messageHandlers?.webwindowinterop) { + else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.webwindowinterop) { // iOS and MacCatalyst WKWebView // @ts-ignore - We are extending the global object here window.external = { @@ -40,11 +40,11 @@ }); } // Determine the function to use to send messages to the host application. - if (window.chrome?.webview) { + if (window.chrome && window.chrome.webview) { // Windows WebView2 sendMessageFunction = msg => window.chrome.webview.postMessage(msg); } - else if (window.webkit?.messageHandlers?.webwindowinterop) { + else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.webwindowinterop) { // iOS and MacCatalyst WKWebView sendMessageFunction = msg => window.webkit.messageHandlers.webwindowinterop.postMessage(msg); } @@ -108,78 +108,82 @@ const json = JSON.stringify(errorObj); sendMessageToDotNet('__InvokeJavaScriptFailed', taskId + '|' + json); } - const HybridWebView = { - /* - * Send a raw message to the .NET host application. - * The message is sent directly and not processed or serialized. - * - * @param message The message to send to the .NET host application. - */ - SendRawMessage: function (message) { - sendMessageToDotNet('__RawMessage', message); - }, - /* - * Invoke a .NET method on the InvokeJavaScriptTarget instance. - * The method name and parameters are serialized and sent to the .NET host application. - * - * @param methodName The name of the .NET method to invoke. - * @param paramValues The parameters to pass to the .NET method. If the method takes no parameters, this can be omitted. - * - * @returns A promise that resolves with the result of the .NET method invocation. - */ - InvokeDotNet: async function (methodName, paramValues) { - const body = { - MethodName: methodName - }; - // if parameters were provided, serialize them first - if (paramValues !== undefined) { - if (!Array.isArray(paramValues)) { - paramValues = [paramValues]; - } - for (let i = 0; i < paramValues.length; i++) { - paramValues[i] = JSON.stringify(paramValues[i]); - } - if (paramValues.length > 0) { - body.ParamValues = paramValues; - } - } - const message = JSON.stringify(body); - const requestUrl = `${window.location.origin}/__hwvInvokeDotNet?data=${encodeURIComponent(message)}`; - const rawResponse = await fetch(requestUrl, { - method: 'GET', - headers: { - 'Accept': 'application/json' - } - }); - const response = await rawResponse.json(); - if (!response) { - return null; + /* + * Send a raw message to the .NET host application. + * The message is sent directly and not processed or serialized. + * + * @param message The message to send to the .NET host application. + */ + function sendRawMessage(message) { + sendMessageToDotNet('__RawMessage', message); + } + /* + * Invoke a .NET method on the InvokeJavaScriptTarget instance. + * The method name and parameters are serialized and sent to the .NET host application. + * + * @param methodName The name of the .NET method to invoke. + * @param paramValues The parameters to pass to the .NET method. If the method takes no parameters, this can be omitted. + * + * @returns A promise that resolves with the result of the .NET method invocation. + */ + async function invokeDotNet(methodName, paramValues) { + const body = { + MethodName: methodName + }; + // if parameters were provided, serialize them first + if (paramValues !== undefined) { + if (!Array.isArray(paramValues)) { + paramValues = [paramValues]; } - if (response.IsJson) { - return JSON.parse(response.Result); + for (let i = 0; i < paramValues.length; i++) { + paramValues[i] = JSON.stringify(paramValues[i]); } - return response.Result; - }, - /* - * Invoke a JavaScript method from the .NET host application. - * This method is called from the HybridWebViewHandler and is not intended to be used by user applications. - * - * @param taskId The task ID that was provided by the .NET host application. - * @param methodName The JavaScript method to invoke in the global scope. - * @param args The arguments to pass to the JavaScript method. - * - * @returns A promise. - */ - __InvokeJavaScript: async function (taskId, methodName, args) { - try { - const result = await methodName(...args); - invokeJavaScriptCallbackInDotNet(taskId, result); + if (paramValues.length > 0) { + body.ParamValues = paramValues; } - catch (ex) { - console.error(ex); - invokeJavaScriptFailedInDotNet(taskId, ex); + } + const message = JSON.stringify(body); + const requestUrl = `${window.location.origin}/__hwvInvokeDotNet?data=${encodeURIComponent(message)}`; + const rawResponse = await fetch(requestUrl, { + method: 'GET', + headers: { + 'Accept': 'application/json' } + }); + const response = await rawResponse.json(); + if (!response) { + return null; + } + if (response.IsJson) { + return JSON.parse(response.Result); } + return response.Result; + } + /* + * Invoke a JavaScript method from the .NET host application. + * This method is called from the HybridWebViewHandler and is not intended to be used by user applications. + * + * @param taskId The task ID that was provided by the .NET host application. + * @param methodName The JavaScript method to invoke in the global scope. + * @param args The arguments to pass to the JavaScript method. + * + * @returns A promise. + */ + async function invokeJavaScript(taskId, methodName, args) { + try { + const result = await methodName(...args); + invokeJavaScriptCallbackInDotNet(taskId, result); + } + catch (ex) { + console.error(ex); + invokeJavaScriptFailedInDotNet(taskId, ex); + } + } + // Define the public API of the HybridWebView control. + const HybridWebView = { + SendRawMessage: sendRawMessage, + InvokeDotNet: invokeDotNet, + __InvokeJavaScript: invokeJavaScript }; // Make the following APIs available in global scope for invocation from JS // @ts-ignore - We are extending the global object here diff --git a/src/Core/src/Handlers/HybridWebView/HybridWebView.ts b/src/Core/src/Handlers/HybridWebView/HybridWebView.ts index f1b77bd72439..f09b3c991831 100644 --- a/src/Core/src/Handlers/HybridWebView/HybridWebView.ts +++ b/src/Core/src/Handlers/HybridWebView/HybridWebView.ts @@ -68,12 +68,12 @@ interface DotNetInvokeResult { } // Determine the mechanism to receive messages from the host application. - if (window.chrome?.webview?.addEventListener) { + if (window.chrome && window.chrome.webview && window.chrome.webview.addEventListener) { // Windows WebView2 window.chrome.webview.addEventListener('message', (arg: any) => { dispatchHybridWebViewMessage(arg.data); }); - } else if (window.webkit?.messageHandlers?.webwindowinterop) { + } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.webwindowinterop) { // iOS and MacCatalyst WKWebView // @ts-ignore - We are extending the global object here window.external = { @@ -89,10 +89,10 @@ interface DotNetInvokeResult { } // Determine the function to use to send messages to the host application. - if (window.chrome?.webview) { + if (window.chrome && window.chrome.webview) { // Windows WebView2 sendMessageFunction = msg => window.chrome.webview.postMessage(msg); - } else if (window.webkit?.messageHandlers?.webwindowinterop) { + } else if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.webwindowinterop) { // iOS and MacCatalyst WKWebView sendMessageFunction = msg => window.webkit.messageHandlers.webwindowinterop.postMessage(msg); } else if (window.hybridWebViewHost) { @@ -160,89 +160,93 @@ interface DotNetInvokeResult { sendMessageToDotNet('__InvokeJavaScriptFailed', taskId + '|' + json); } - const HybridWebView = { - - /* - * Send a raw message to the .NET host application. - * The message is sent directly and not processed or serialized. - * - * @param message The message to send to the .NET host application. - */ - SendRawMessage: function (message: string) { - sendMessageToDotNet('__RawMessage', message); - }, - - /* - * Invoke a .NET method on the InvokeJavaScriptTarget instance. - * The method name and parameters are serialized and sent to the .NET host application. - * - * @param methodName The name of the .NET method to invoke. - * @param paramValues The parameters to pass to the .NET method. If the method takes no parameters, this can be omitted. - * - * @returns A promise that resolves with the result of the .NET method invocation. - */ - InvokeDotNet: async function (methodName: string, paramValues?: any) { - const body: JSInvokeMethodData = { - MethodName: methodName - }; + /* + * Send a raw message to the .NET host application. + * The message is sent directly and not processed or serialized. + * + * @param message The message to send to the .NET host application. + */ + function sendRawMessage(message: string) { + sendMessageToDotNet('__RawMessage', message); + } - // if parameters were provided, serialize them first - if (paramValues !== undefined) { - if (!Array.isArray(paramValues)) { - paramValues = [paramValues]; - } + /* + * Invoke a .NET method on the InvokeJavaScriptTarget instance. + * The method name and parameters are serialized and sent to the .NET host application. + * + * @param methodName The name of the .NET method to invoke. + * @param paramValues The parameters to pass to the .NET method. If the method takes no parameters, this can be omitted. + * + * @returns A promise that resolves with the result of the .NET method invocation. + */ + async function invokeDotNet(methodName: string, paramValues?: any) { + const body: JSInvokeMethodData = { + MethodName: methodName + }; - for (let i = 0; i < paramValues.length; i++) { - paramValues[i] = JSON.stringify(paramValues[i]); - } + // if parameters were provided, serialize them first + if (paramValues !== undefined) { + if (!Array.isArray(paramValues)) { + paramValues = [paramValues]; + } - if (paramValues.length > 0) { - body.ParamValues = paramValues; - } + for (let i = 0; i < paramValues.length; i++) { + paramValues[i] = JSON.stringify(paramValues[i]); } - const message = JSON.stringify(body); + if (paramValues.length > 0) { + body.ParamValues = paramValues; + } + } - const requestUrl = `${window.location.origin}/__hwvInvokeDotNet?data=${encodeURIComponent(message)}`; + const message = JSON.stringify(body); - const rawResponse = await fetch(requestUrl, { - method: 'GET', - headers: { - 'Accept': 'application/json' - } - }); - const response: DotNetInvokeResult = await rawResponse.json(); + const requestUrl = `${window.location.origin}/__hwvInvokeDotNet?data=${encodeURIComponent(message)}`; - if (!response) { - return null; + const rawResponse = await fetch(requestUrl, { + method: 'GET', + headers: { + 'Accept': 'application/json' } + }); + const response: DotNetInvokeResult = await rawResponse.json(); - if (response.IsJson) { - return JSON.parse(response.Result); - } + if (!response) { + return null; + } - return response.Result; - }, - - /* - * Invoke a JavaScript method from the .NET host application. - * This method is called from the HybridWebViewHandler and is not intended to be used by user applications. - * - * @param taskId The task ID that was provided by the .NET host application. - * @param methodName The JavaScript method to invoke in the global scope. - * @param args The arguments to pass to the JavaScript method. - * - * @returns A promise. - */ - __InvokeJavaScript: async function (taskId: string, methodName: Function, args: any[]) { - try { - const result = await methodName(...args); - invokeJavaScriptCallbackInDotNet(taskId, result); - } catch (ex) { - console.error(ex); - invokeJavaScriptFailedInDotNet(taskId, ex); - } + if (response.IsJson) { + return JSON.parse(response.Result); + } + + return response.Result; + } + + /* + * Invoke a JavaScript method from the .NET host application. + * This method is called from the HybridWebViewHandler and is not intended to be used by user applications. + * + * @param taskId The task ID that was provided by the .NET host application. + * @param methodName The JavaScript method to invoke in the global scope. + * @param args The arguments to pass to the JavaScript method. + * + * @returns A promise. + */ + async function invokeJavaScript(taskId: string, methodName: Function, args: any[]) { + try { + const result = await methodName(...args); + invokeJavaScriptCallbackInDotNet(taskId, result); + } catch (ex) { + console.error(ex); + invokeJavaScriptFailedInDotNet(taskId, ex); } + } + + // Define the public API of the HybridWebView control. + const HybridWebView = { + SendRawMessage: sendRawMessage, + InvokeDotNet: invokeDotNet, + __InvokeJavaScript: invokeJavaScript }; // Make the following APIs available in global scope for invocation from JS