@jimrising/easymerchantsdk-react-native 2.4.7 → 2.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/android/.settings/org.eclipse.buildship.core.prefs +2 -2
- package/android/build.gradle +3 -4
- package/android/config.properties +5 -0
- package/android/config.properties.example +5 -0
- package/ios/ApiManager/APIRequest.swift +0 -3
- package/ios/ApiManager/APIService.swift +0 -2
- package/ios/Classes/EasyMerchantSdk.h +0 -1
- package/ios/Classes/EasyMerchantSdk.m +54 -5
- package/ios/Classes/EasyMerchantSdk.swift +1 -15
- package/ios/Classes/EasyPayViewController.swift +1 -1
- package/ios/EnvironmentConfig.swift +0 -1
- package/ios/Example/SceneDelegate.swift +23 -1
- package/ios/Example/ViewController.swift +0 -8
- package/ios/Extensions/UIFont.swift +0 -1
- package/ios/Extensions/UIViewController+Extension.swift +0 -1
- package/ios/Helper/GrailPayHelper.swift +146 -58
- package/ios/Helper/GrailPayWebViewController.swift +416 -0
- package/ios/Helper/JavaScriptBridge.swift +312 -0
- package/ios/Helper/WebViewConfig.swift +159 -0
- package/ios/Models/Request.swift +48 -204
- package/ios/easymerchantsdk.podspec +2 -2
- package/package.json +1 -1
- package/ios/easymerchantsdk.storyboard +0 -9089
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
//
|
|
2
|
+
// JavaScriptBridge.swift
|
|
3
|
+
// EasyPay
|
|
4
|
+
//
|
|
5
|
+
// JavaScript bridge handler for GrailPay WebView communication
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import WebKit
|
|
10
|
+
|
|
11
|
+
public class JavaScriptBridge: NSObject, WKScriptMessageHandler {
|
|
12
|
+
weak var webViewController: GrailPayWebViewController?
|
|
13
|
+
|
|
14
|
+
public init(webViewController: GrailPayWebViewController) {
|
|
15
|
+
self.webViewController = webViewController
|
|
16
|
+
super.init()
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
|
20
|
+
if let bodyString = message.body as? String {
|
|
21
|
+
if let data = bodyString.data(using: .utf8),
|
|
22
|
+
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
23
|
+
let type = json["type"] as? String {
|
|
24
|
+
handleMessage(type: type, data: json)
|
|
25
|
+
} else {
|
|
26
|
+
handleMessage(type: "message", data: ["message": bodyString])
|
|
27
|
+
}
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
guard let body = message.body as? [String: Any] else { return }
|
|
32
|
+
|
|
33
|
+
if let rawMessage = body["rawMessage"] as? String {
|
|
34
|
+
if let data = rawMessage.data(using: .utf8),
|
|
35
|
+
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
|
|
36
|
+
let type = json["type"] as? String {
|
|
37
|
+
handleMessage(type: type, data: json)
|
|
38
|
+
} else {
|
|
39
|
+
handleMessage(type: "message", data: ["message": rawMessage])
|
|
40
|
+
}
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if let type = body["type"] as? String {
|
|
45
|
+
handleMessage(type: type, data: body)
|
|
46
|
+
} else if let eventType = body["eventType"] as? String {
|
|
47
|
+
handleMessage(type: eventType, data: body)
|
|
48
|
+
} else if body["result"] != nil {
|
|
49
|
+
handleMessage(type: "onComplete", data: body)
|
|
50
|
+
} else if body["message"] != nil {
|
|
51
|
+
handleMessage(type: "showMessage", data: body)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private func handleMessage(type: String, data: [String: Any]) {
|
|
56
|
+
switch type {
|
|
57
|
+
case "postMessage", "showMessage":
|
|
58
|
+
if let message = data["message"] as? String {
|
|
59
|
+
showMessage(message)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
case "onComplete":
|
|
63
|
+
if let resultJson = data["result"] as? String {
|
|
64
|
+
handleCompletion(resultJson)
|
|
65
|
+
} else if let resultDict = data["result"] as? [String: Any] {
|
|
66
|
+
handleCompletionDict(resultDict)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
case "closeWebView":
|
|
70
|
+
webViewController?.closePopupFromBridge()
|
|
71
|
+
webViewController?.closeWebView()
|
|
72
|
+
|
|
73
|
+
case "opener_postMessage", "popup_postMessage":
|
|
74
|
+
handlePopupMessage(data)
|
|
75
|
+
|
|
76
|
+
case "closePopup":
|
|
77
|
+
DispatchQueue.main.async {
|
|
78
|
+
self.webViewController?.closePopupFromBridge()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
case "consoleLog":
|
|
82
|
+
break
|
|
83
|
+
|
|
84
|
+
case "defaultAccountSelected", "linkedDefaultAccount":
|
|
85
|
+
DispatchQueue.main.async {
|
|
86
|
+
var resultData: NSDictionary = [:]
|
|
87
|
+
if let accountData = data["data"] {
|
|
88
|
+
if let accountArray = accountData as? [[String: Any]] {
|
|
89
|
+
resultData = ["data": accountArray]
|
|
90
|
+
} else if let accountDict = accountData as? [String: Any] {
|
|
91
|
+
resultData = ["data": [accountDict]]
|
|
92
|
+
} else {
|
|
93
|
+
resultData = ["data": [accountData]]
|
|
94
|
+
}
|
|
95
|
+
} else {
|
|
96
|
+
resultData = ["data": [data]]
|
|
97
|
+
}
|
|
98
|
+
let result = SDKResult(type: .success, data: resultData)
|
|
99
|
+
self.webViewController?.handleCompletion(result: result)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
case "accountLinked", "linkSuccess", "success", "complete", "done":
|
|
103
|
+
DispatchQueue.main.async {
|
|
104
|
+
var resultData: NSDictionary = [:]
|
|
105
|
+
if let accountData = data["data"] {
|
|
106
|
+
if let accountArray = accountData as? [[String: Any]] {
|
|
107
|
+
resultData = ["data": accountArray]
|
|
108
|
+
} else if let accountDict = accountData as? [String: Any] {
|
|
109
|
+
resultData = ["data": [accountDict]]
|
|
110
|
+
} else {
|
|
111
|
+
resultData = ["data": [accountData]]
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
resultData = ["data": [data]]
|
|
115
|
+
}
|
|
116
|
+
let result = SDKResult(type: .success, data: resultData)
|
|
117
|
+
self.webViewController?.handleCompletion(result: result)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
case "error", "linkError", "failure":
|
|
121
|
+
DispatchQueue.main.async {
|
|
122
|
+
self.webViewController?.closePopupFromBridge()
|
|
123
|
+
if let errorMessage = data["message"] as? String ?? data["error"] as? String {
|
|
124
|
+
self.webViewController?.showAlert(title: "Error", message: errorMessage)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
case "cancelled", "closed", "dismissed":
|
|
129
|
+
DispatchQueue.main.async {
|
|
130
|
+
let cancelledData: NSDictionary = ["status": false, "message": "User cancelled"]
|
|
131
|
+
let result = SDKResult(type: .cancelled, data: cancelledData)
|
|
132
|
+
self.webViewController?.handleCompletion(result: result)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
default:
|
|
136
|
+
break
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
private func handlePopupMessage(_ data: [String: Any]) {
|
|
141
|
+
guard let message = data["message"] else { return }
|
|
142
|
+
|
|
143
|
+
var oauthData: [String: String] = [:]
|
|
144
|
+
|
|
145
|
+
if let messageDict = message as? [String: Any] {
|
|
146
|
+
if let status = messageDict["status"] as? String { oauthData["status"] = status }
|
|
147
|
+
if let state = messageDict["state"] as? String { oauthData["state"] = state }
|
|
148
|
+
if let url = messageDict["url"] as? String { oauthData["url"] = url }
|
|
149
|
+
if let redirectUrl = messageDict["redirectUrl"] as? String { oauthData["url"] = redirectUrl }
|
|
150
|
+
if let publicToken = messageDict["public_token"] as? String { oauthData["public_token"] = publicToken }
|
|
151
|
+
if let type = messageDict["type"] as? String { oauthData["type"] = type }
|
|
152
|
+
|
|
153
|
+
if let eventData = messageDict["eventData"] as? [String: Any],
|
|
154
|
+
let redirectURL = eventData["redirectURL"] as? String {
|
|
155
|
+
oauthData["url"] = redirectURL
|
|
156
|
+
oauthData["redirectURL"] = redirectURL
|
|
157
|
+
|
|
158
|
+
if let urlComponents = URLComponents(string: redirectURL) {
|
|
159
|
+
urlComponents.queryItems?.forEach { item in
|
|
160
|
+
if let value = item.value {
|
|
161
|
+
oauthData[item.name] = value
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if messageDict["moneykit"] != nil {
|
|
168
|
+
oauthData["moneykit"] = "true"
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
DispatchQueue.main.async {
|
|
173
|
+
self.webViewController?.forwardOAuthDataToMainWebView(oauthData)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
func showMessage(_ message: String) {
|
|
178
|
+
DispatchQueue.main.async {
|
|
179
|
+
self.webViewController?.showAlert(title: "GrailPay", message: message)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
private func handleCompletion(_ resultJson: String) {
|
|
184
|
+
DispatchQueue.main.async {
|
|
185
|
+
if let data = resultJson.data(using: .utf8),
|
|
186
|
+
let json = try? JSONSerialization.jsonObject(with: data) as? [String: Any] {
|
|
187
|
+
self.handleCompletionDict(json)
|
|
188
|
+
} else {
|
|
189
|
+
self.webViewController?.closePopupFromBridge()
|
|
190
|
+
self.webViewController?.closeWebView()
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private func handleCompletionDict(_ resultDict: [String: Any]) {
|
|
196
|
+
DispatchQueue.main.async {
|
|
197
|
+
var resultData: NSDictionary = [:]
|
|
198
|
+
|
|
199
|
+
if let data = resultDict["data"] {
|
|
200
|
+
if let dataArray = data as? [[String: Any]] {
|
|
201
|
+
resultData = ["data": dataArray]
|
|
202
|
+
} else if let dataDict = data as? [String: Any] {
|
|
203
|
+
resultData = ["data": [dataDict]]
|
|
204
|
+
} else {
|
|
205
|
+
resultData = ["data": data]
|
|
206
|
+
}
|
|
207
|
+
} else {
|
|
208
|
+
resultData = resultDict as NSDictionary
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
let result = SDKResult(type: .success, data: resultData)
|
|
212
|
+
self.webViewController?.handleCompletion(result: result)
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// MARK: - OAuth Callback Bridge
|
|
218
|
+
public class OAuthCallbackBridge: NSObject, WKScriptMessageHandler {
|
|
219
|
+
let oauthData: [String: String]
|
|
220
|
+
|
|
221
|
+
init(oauthData: [String: String]) {
|
|
222
|
+
self.oauthData = oauthData
|
|
223
|
+
super.init()
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
func getOAuthDataJSON() -> String {
|
|
230
|
+
guard let jsonData = try? JSONSerialization.data(withJSONObject: oauthData, options: []),
|
|
231
|
+
let jsonString = String(data: jsonData, encoding: .utf8) else {
|
|
232
|
+
return "{}"
|
|
233
|
+
}
|
|
234
|
+
return jsonString
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// MARK: - WKWebView Extensions
|
|
239
|
+
extension WKWebView {
|
|
240
|
+
public func injectJavaScript(_ script: String, completion: ((Any?, Error?) -> Void)? = nil) {
|
|
241
|
+
evaluateJavaScript(script) { result, error in
|
|
242
|
+
completion?(result, error)
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
public func injectMessageListener() {
|
|
247
|
+
let script = """
|
|
248
|
+
(function() {
|
|
249
|
+
window.addEventListener('message', function(event) {
|
|
250
|
+
try {
|
|
251
|
+
var data = event.data;
|
|
252
|
+
if (!data || typeof data !== 'object') return;
|
|
253
|
+
|
|
254
|
+
if (data.__bridgeProxy === true && data.message) {
|
|
255
|
+
if (window.webkit?.messageHandlers?.androidBridge) {
|
|
256
|
+
window.webkit.messageHandlers.androidBridge.postMessage(data.message);
|
|
257
|
+
}
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const grailpayEvent = new CustomEvent('grailpay-oauth-complete', { detail: data });
|
|
262
|
+
window.dispatchEvent(grailpayEvent);
|
|
263
|
+
} catch (error) {}
|
|
264
|
+
}, false);
|
|
265
|
+
})();
|
|
266
|
+
"""
|
|
267
|
+
injectJavaScript(script)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
public func injectOAuthData(_ oauthData: [String: String]) {
|
|
271
|
+
guard let jsonData = try? JSONSerialization.data(withJSONObject: oauthData, options: []),
|
|
272
|
+
let jsonString = String(data: jsonData, encoding: .utf8) else { return }
|
|
273
|
+
|
|
274
|
+
let script = """
|
|
275
|
+
(function() {
|
|
276
|
+
var oauthData = \(jsonString);
|
|
277
|
+
window.oauthCallbackData = oauthData;
|
|
278
|
+
var redirectURL = oauthData.url || oauthData.redirectURL || window.location.href;
|
|
279
|
+
|
|
280
|
+
window.postMessage({ type: 'link.resume', moneykit: 1, eventData: { redirectURL: redirectURL } }, '*');
|
|
281
|
+
window.postMessage({ type: 'oauth_complete', source: 'popup', url: redirectURL, status: oauthData.status, state: oauthData.state }, '*');
|
|
282
|
+
window.postMessage({ type: 'mk-oauth-callback', redirectUrl: redirectURL, status: oauthData.status, state: oauthData.state }, '*');
|
|
283
|
+
window.postMessage({ success: true, url: redirectURL, status: oauthData.status, state: oauthData.state }, '*');
|
|
284
|
+
|
|
285
|
+
document.querySelectorAll('iframe').forEach(function(iframe) {
|
|
286
|
+
try {
|
|
287
|
+
if (iframe.contentWindow) {
|
|
288
|
+
iframe.contentWindow.postMessage({ type: 'link.resume', moneykit: 1, eventData: { redirectURL: redirectURL } }, '*');
|
|
289
|
+
iframe.contentWindow.postMessage({ type: 'oauth_complete', source: 'popup', url: redirectURL, status: oauthData.status, state: oauthData.state }, '*');
|
|
290
|
+
iframe.contentWindow.postMessage({ type: 'mk-oauth-callback', redirectUrl: redirectURL, status: oauthData.status, state: oauthData.state }, '*');
|
|
291
|
+
iframe.contentWindow.postMessage({ success: true, url: redirectURL, status: oauthData.status, state: oauthData.state }, '*');
|
|
292
|
+
}
|
|
293
|
+
} catch (e) {}
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
window.dispatchEvent(new CustomEvent('grailpay-oauth-complete', {
|
|
297
|
+
detail: { type: 'oauth_complete', source: 'popup', url: redirectURL, status: oauthData.status, state: oauthData.state },
|
|
298
|
+
bubbles: true
|
|
299
|
+
}));
|
|
300
|
+
|
|
301
|
+
if (typeof window.receiveDeepLinkData !== 'function') {
|
|
302
|
+
window.receiveDeepLinkData = function(data) {
|
|
303
|
+
window.oauthCallbackData = data;
|
|
304
|
+
window.dispatchEvent(new CustomEvent('grailpay-oauth-complete', { detail: data }));
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
window.receiveDeepLinkData(oauthData);
|
|
308
|
+
})();
|
|
309
|
+
"""
|
|
310
|
+
injectJavaScript(script)
|
|
311
|
+
}
|
|
312
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
//
|
|
2
|
+
// WebViewConfig.swift
|
|
3
|
+
// EasyPay
|
|
4
|
+
//
|
|
5
|
+
// WebView configuration utilities for GrailPay
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
import Foundation
|
|
9
|
+
import WebKit
|
|
10
|
+
|
|
11
|
+
public class WebViewConfig {
|
|
12
|
+
public static func createMainWebView(bridge: JavaScriptBridge) -> WKWebView {
|
|
13
|
+
let config = WKWebViewConfiguration()
|
|
14
|
+
config.preferences.javaScriptEnabled = true
|
|
15
|
+
config.preferences.javaScriptCanOpenWindowsAutomatically = true
|
|
16
|
+
config.websiteDataStore = .default()
|
|
17
|
+
|
|
18
|
+
let contentController = WKUserContentController()
|
|
19
|
+
contentController.add(bridge, name: "androidBridge")
|
|
20
|
+
contentController.add(bridge, name: "grailpay")
|
|
21
|
+
contentController.add(bridge, name: "nativeBridge")
|
|
22
|
+
contentController.add(bridge, name: "iosHandler")
|
|
23
|
+
|
|
24
|
+
let bridgeShimScript = WKUserScript(
|
|
25
|
+
source: WebViewConfig.getBridgeShimScript(),
|
|
26
|
+
injectionTime: .atDocumentStart,
|
|
27
|
+
forMainFrameOnly: false
|
|
28
|
+
)
|
|
29
|
+
contentController.addUserScript(bridgeShimScript)
|
|
30
|
+
|
|
31
|
+
config.userContentController = contentController
|
|
32
|
+
config.allowsInlineMediaPlayback = true
|
|
33
|
+
config.mediaTypesRequiringUserActionForPlayback = []
|
|
34
|
+
|
|
35
|
+
let webView = WKWebView(frame: .zero, configuration: config)
|
|
36
|
+
webView.allowsBackForwardNavigationGestures = true
|
|
37
|
+
webView.allowsLinkPreview = true
|
|
38
|
+
webView.customUserAgent = "Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36"
|
|
39
|
+
|
|
40
|
+
return webView
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public static func createPopupWebView(with configuration: WKWebViewConfiguration) -> WKWebView {
|
|
44
|
+
let webView = WKWebView(frame: .zero, configuration: configuration)
|
|
45
|
+
webView.allowsBackForwardNavigationGestures = true
|
|
46
|
+
webView.customUserAgent = "Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36"
|
|
47
|
+
return webView
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public static func createCallbackWebView(oauthBridge: OAuthCallbackBridge) -> WKWebView {
|
|
51
|
+
let config = WKWebViewConfiguration()
|
|
52
|
+
config.preferences.javaScriptEnabled = true
|
|
53
|
+
|
|
54
|
+
let contentController = WKUserContentController()
|
|
55
|
+
contentController.add(oauthBridge, name: "oauthBridge")
|
|
56
|
+
config.userContentController = contentController
|
|
57
|
+
|
|
58
|
+
let webView = WKWebView(frame: .zero, configuration: config)
|
|
59
|
+
webView.customUserAgent = "Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36"
|
|
60
|
+
return webView
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public static func enableCookies() {
|
|
64
|
+
HTTPCookieStorage.shared.cookieAcceptPolicy = .always
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public static func getBridgeShimScript() -> String {
|
|
68
|
+
"""
|
|
69
|
+
(function() {
|
|
70
|
+
var isMainFrame = (window === window.top);
|
|
71
|
+
|
|
72
|
+
if (!window.AndroidBridge) {
|
|
73
|
+
window.AndroidBridge = {
|
|
74
|
+
postMessage: function(message) {
|
|
75
|
+
try {
|
|
76
|
+
var parsed = typeof message === 'string' ? JSON.parse(message) : message;
|
|
77
|
+
if (window.webkit?.messageHandlers?.androidBridge) {
|
|
78
|
+
window.webkit.messageHandlers.androidBridge.postMessage(parsed);
|
|
79
|
+
} else if (window !== window.top) {
|
|
80
|
+
window.parent.postMessage({ __bridgeProxy: true, message: parsed }, '*');
|
|
81
|
+
}
|
|
82
|
+
} catch (e) {
|
|
83
|
+
if (window.webkit?.messageHandlers?.androidBridge) {
|
|
84
|
+
window.webkit.messageHandlers.androidBridge.postMessage({ rawMessage: message });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
showMessage: function(message) {
|
|
89
|
+
if (window.webkit?.messageHandlers?.androidBridge) {
|
|
90
|
+
window.webkit.messageHandlers.androidBridge.postMessage({ type: 'showMessage', message: message });
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
onComplete: function(result) {
|
|
94
|
+
try {
|
|
95
|
+
var parsed = typeof result === 'string' ? JSON.parse(result) : result;
|
|
96
|
+
if (window.webkit?.messageHandlers?.androidBridge) {
|
|
97
|
+
window.webkit.messageHandlers.androidBridge.postMessage({ type: 'onComplete', result: JSON.stringify(parsed) });
|
|
98
|
+
}
|
|
99
|
+
} catch (e) {
|
|
100
|
+
if (window.webkit?.messageHandlers?.androidBridge) {
|
|
101
|
+
window.webkit.messageHandlers.androidBridge.postMessage({ type: 'onComplete', result: result });
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
closeWebView: function() {
|
|
106
|
+
if (window.webkit?.messageHandlers?.androidBridge) {
|
|
107
|
+
window.webkit.messageHandlers.androidBridge.postMessage({ type: 'closeWebView' });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (isMainFrame) {
|
|
114
|
+
window.addEventListener('message', function(event) {
|
|
115
|
+
try {
|
|
116
|
+
var data = event.data;
|
|
117
|
+
if (data && data.__bridgeProxy === true && data.message) {
|
|
118
|
+
if (window.webkit?.messageHandlers?.androidBridge) {
|
|
119
|
+
window.webkit.messageHandlers.androidBridge.postMessage(data.message);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} catch (e) {}
|
|
123
|
+
}, false);
|
|
124
|
+
} else {
|
|
125
|
+
if (!window.webkit) window.webkit = {};
|
|
126
|
+
if (!window.webkit.messageHandlers) window.webkit.messageHandlers = {};
|
|
127
|
+
if (!window.webkit.messageHandlers.androidBridge) {
|
|
128
|
+
window.webkit.messageHandlers.androidBridge = {
|
|
129
|
+
postMessage: function(message) {
|
|
130
|
+
window.parent.postMessage({ __bridgeProxy: true, message: message }, '*');
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
if (!window.AndroidBridge) {
|
|
135
|
+
window.AndroidBridge = {
|
|
136
|
+
postMessage: function(message) {
|
|
137
|
+
try {
|
|
138
|
+
var parsed = typeof message === 'string' ? JSON.parse(message) : message;
|
|
139
|
+
window.parent.postMessage({ __bridgeProxy: true, message: parsed }, '*');
|
|
140
|
+
} catch (e) {
|
|
141
|
+
window.parent.postMessage({ __bridgeProxy: true, message: { rawMessage: message } }, '*');
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
showMessage: function(msg) {
|
|
145
|
+
window.parent.postMessage({ __bridgeProxy: true, message: { type: 'showMessage', message: msg } }, '*');
|
|
146
|
+
},
|
|
147
|
+
onComplete: function(result) {
|
|
148
|
+
window.parent.postMessage({ __bridgeProxy: true, message: { type: 'onComplete', result: result } }, '*');
|
|
149
|
+
},
|
|
150
|
+
closeWebView: function() {
|
|
151
|
+
window.parent.postMessage({ __bridgeProxy: true, message: { type: 'closeWebView' } }, '*');
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
})();
|
|
157
|
+
"""
|
|
158
|
+
}
|
|
159
|
+
}
|