@capgo/inappbrowser 7.0.0 → 7.1.6
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/CapgoInappbrowser.podspec +1 -1
- package/README.md +448 -54
- package/android/build.gradle +15 -13
- package/android/src/main/AndroidManifest.xml +2 -1
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/InAppBrowserPlugin.java +530 -35
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/Options.java +251 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewCallbacks.java +4 -0
- package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +904 -20
- package/android/src/main/res/drawable/ic_refresh.xml +9 -0
- package/android/src/main/res/layout/tool_bar.xml +25 -3
- package/android/src/main/res/values/strings.xml +2 -0
- package/dist/docs.json +1365 -67
- package/dist/esm/definitions.d.ts +218 -9
- package/dist/esm/definitions.js.map +1 -1
- package/dist/esm/web.d.ts +10 -2
- package/dist/esm/web.js +26 -2
- package/dist/esm/web.js.map +1 -1
- package/dist/plugin.cjs.js +26 -2
- package/dist/plugin.cjs.js.map +1 -1
- package/dist/plugin.js +26 -2
- package/dist/plugin.js.map +1 -1
- package/ios/Plugin/InAppBrowserPlugin.m +5 -1
- package/ios/Plugin/InAppBrowserPlugin.swift +247 -12
- package/ios/Plugin/WKWebViewController.swift +303 -55
- package/package.json +26 -27
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
import Foundation
|
|
2
2
|
import Capacitor
|
|
3
|
+
import WebKit
|
|
4
|
+
|
|
5
|
+
extension UIColor {
|
|
6
|
+
|
|
7
|
+
convenience init(hexString: String) {
|
|
8
|
+
let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
|
|
9
|
+
var int = UInt64()
|
|
10
|
+
Scanner(string: hex).scanHexInt64(&int)
|
|
11
|
+
let components = (
|
|
12
|
+
R: CGFloat((int >> 16) & 0xff) / 255,
|
|
13
|
+
G: CGFloat((int >> 08) & 0xff) / 255,
|
|
14
|
+
B: CGFloat((int >> 00) & 0xff) / 255
|
|
15
|
+
)
|
|
16
|
+
self.init(red: components.R, green: components.G, blue: components.B, alpha: 1)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
}
|
|
3
20
|
|
|
4
21
|
/**
|
|
5
22
|
* Please read the Capacitor iOS Plugin Development Guide
|
|
@@ -26,14 +43,83 @@ public class InAppBrowserPlugin: CAPPlugin {
|
|
|
26
43
|
#endif
|
|
27
44
|
}
|
|
28
45
|
|
|
29
|
-
func presentView() {
|
|
30
|
-
self.bridge?.viewController?.present(self.navigationWebViewController!, animated:
|
|
46
|
+
func presentView(isAnimated: Bool = true) {
|
|
47
|
+
self.bridge?.viewController?.present(self.navigationWebViewController!, animated: isAnimated, completion: {
|
|
31
48
|
self.currentPluginCall?.resolve()
|
|
32
49
|
})
|
|
33
50
|
}
|
|
34
51
|
|
|
35
|
-
func
|
|
36
|
-
|
|
52
|
+
@objc func clearAllCookies(_ call: CAPPluginCall) {
|
|
53
|
+
DispatchQueue.main.async {
|
|
54
|
+
let dataStore = WKWebsiteDataStore.default()
|
|
55
|
+
let dataTypes = Set([WKWebsiteDataTypeCookies])
|
|
56
|
+
|
|
57
|
+
dataStore.removeData(ofTypes: dataTypes,
|
|
58
|
+
modifiedSince: Date(timeIntervalSince1970: 0)) {
|
|
59
|
+
call.resolve()
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@objc func clearCache(_ call: CAPPluginCall) {
|
|
65
|
+
DispatchQueue.main.async {
|
|
66
|
+
let dataStore = WKWebsiteDataStore.default()
|
|
67
|
+
let dataTypes = Set([WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeMemoryCache])
|
|
68
|
+
|
|
69
|
+
dataStore.removeData(ofTypes: dataTypes,
|
|
70
|
+
modifiedSince: Date(timeIntervalSince1970: 0)) {
|
|
71
|
+
call.resolve()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
@objc func clearCookies(_ call: CAPPluginCall) {
|
|
77
|
+
guard let url = call.getString("url"),
|
|
78
|
+
let host = URL(string: url)?.host else {
|
|
79
|
+
call.reject("Invalid URL")
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
DispatchQueue.main.async {
|
|
84
|
+
WKWebsiteDataStore.default().httpCookieStore.getAllCookies { cookies in
|
|
85
|
+
for cookie in cookies {
|
|
86
|
+
|
|
87
|
+
if cookie.domain == host || cookie.domain.hasSuffix(".\(host)") || host.hasSuffix(cookie.domain) {
|
|
88
|
+
let semaphore = DispatchSemaphore(value: 1)
|
|
89
|
+
WKWebsiteDataStore.default().httpCookieStore.delete(cookie) {
|
|
90
|
+
semaphore.signal()
|
|
91
|
+
}
|
|
92
|
+
semaphore.wait()
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
call.resolve()
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@objc func getCookies(_ call: CAPPluginCall) {
|
|
102
|
+
let urlString = call.getString("url") ?? ""
|
|
103
|
+
let includeHttpOnly = call.getBool("includeHttpOnly") ?? true
|
|
104
|
+
|
|
105
|
+
guard let url = URL(string: urlString), let host = url.host else {
|
|
106
|
+
call.reject("Invalid URL")
|
|
107
|
+
return
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
DispatchQueue.main.async {
|
|
111
|
+
WKWebsiteDataStore.default().httpCookieStore.getAllCookies { cookies in
|
|
112
|
+
var cookieDict = [String: String]()
|
|
113
|
+
for cookie in cookies {
|
|
114
|
+
|
|
115
|
+
if (includeHttpOnly || !cookie.isHTTPOnly) && (cookie.domain == host || cookie.domain.hasSuffix(".\(host)") || host.hasSuffix(cookie.domain)) {
|
|
116
|
+
cookieDict[cookie.name] = cookie.value
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
call.resolve(cookieDict)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
37
123
|
}
|
|
38
124
|
|
|
39
125
|
@objc func openWebView(_ call: CAPPluginCall) {
|
|
@@ -52,7 +138,48 @@ public class InAppBrowserPlugin: CAPPlugin {
|
|
|
52
138
|
return
|
|
53
139
|
}
|
|
54
140
|
|
|
141
|
+
var buttonNearDoneIcon: UIImage?
|
|
142
|
+
if let buttonNearDoneSettings = call.getObject("buttonNearDone") {
|
|
143
|
+
guard let iosSettingsRaw = buttonNearDoneSettings["ios"] else {
|
|
144
|
+
call.reject("IOS settings not found")
|
|
145
|
+
return
|
|
146
|
+
}
|
|
147
|
+
if !(iosSettingsRaw is JSObject) {
|
|
148
|
+
call.reject("IOS settings are not an object")
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
let iosSettings = iosSettingsRaw as! JSObject
|
|
152
|
+
|
|
153
|
+
guard let iconType = iosSettings["iconType"] as? String else {
|
|
154
|
+
call.reject("buttonNearDone.iconType is empty")
|
|
155
|
+
return
|
|
156
|
+
}
|
|
157
|
+
if iconType != "sf-symbol" && iconType != "asset" {
|
|
158
|
+
call.reject("IconType is neither 'sf-symbol' nor 'asset'")
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
guard let icon = iosSettings["icon"] as? String else {
|
|
162
|
+
call.reject("buttonNearDone.icon is empty")
|
|
163
|
+
return
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if iconType == "sf-symbol" {
|
|
167
|
+
buttonNearDoneIcon = UIImage(systemName: icon)
|
|
168
|
+
} else {
|
|
169
|
+
// UIImage(resource: ImageResource(name: "public/monkey.svg", bundle: Bundle.main))
|
|
170
|
+
buttonNearDoneIcon = UIImage(named: icon, in: Bundle.main, with: nil)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
55
174
|
let headers = call.getObject("headers", [:]).mapValues { String(describing: $0 as Any) }
|
|
175
|
+
let closeModal = call.getBool("closeModal", false)
|
|
176
|
+
let closeModalTitle = call.getString("closeModalTitle", "Close")
|
|
177
|
+
let closeModalDescription = call.getString("closeModalDescription", "Are you sure you want to close this window?")
|
|
178
|
+
let closeModalOk = call.getString("closeModalOk", "OK")
|
|
179
|
+
let closeModalCancel = call.getString("closeModalCancel", "Cancel")
|
|
180
|
+
let isInspectable = call.getBool("isInspectable", false)
|
|
181
|
+
let preventDeeplink = call.getBool("preventDeeplink", false)
|
|
182
|
+
let isAnimated = call.getBool("isAnimated", true)
|
|
56
183
|
|
|
57
184
|
var disclaimerContent = call.getObject("shareDisclaimer")
|
|
58
185
|
let toolbarType = call.getString("toolbarType", "")
|
|
@@ -60,39 +187,69 @@ public class InAppBrowserPlugin: CAPPlugin {
|
|
|
60
187
|
if toolbarType != "activity" {
|
|
61
188
|
disclaimerContent = nil
|
|
62
189
|
}
|
|
190
|
+
let ignoreUntrustedSSLError = call.getBool("ignoreUntrustedSSLError", false)
|
|
63
191
|
|
|
64
192
|
self.isPresentAfterPageLoad = call.getBool("isPresentAfterPageLoad", false)
|
|
193
|
+
let showReloadButton = call.getBool("showReloadButton", false)
|
|
194
|
+
|
|
195
|
+
let credentials = self.readCredentials(call)
|
|
65
196
|
|
|
66
197
|
DispatchQueue.main.async {
|
|
67
198
|
let url = URL(string: urlString)
|
|
68
199
|
|
|
69
200
|
if self.isPresentAfterPageLoad {
|
|
70
|
-
self.webViewController = WKWebViewController.init(url: url!, headers: headers)
|
|
201
|
+
self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable, credentials: credentials, preventDeeplink: preventDeeplink)
|
|
71
202
|
} else {
|
|
72
203
|
self.webViewController = WKWebViewController.init()
|
|
73
204
|
self.webViewController?.setHeaders(headers: headers)
|
|
205
|
+
self.webViewController?.setCredentials(credentials: credentials)
|
|
206
|
+
self.webViewController?.setPreventDeeplink(preventDeeplink: preventDeeplink)
|
|
74
207
|
}
|
|
75
208
|
|
|
76
209
|
self.webViewController?.source = .remote(url!)
|
|
77
|
-
self.webViewController?.
|
|
210
|
+
self.webViewController?.leftNavigationBarItemTypes = self.getToolbarItems(toolbarType: toolbarType) + [.reload]
|
|
211
|
+
self.webViewController?.leftNavigationBarItemTypes = self.getToolbarItems(toolbarType: toolbarType)
|
|
78
212
|
self.webViewController?.toolbarItemTypes = []
|
|
79
213
|
self.webViewController?.doneBarButtonItemPosition = .right
|
|
214
|
+
|
|
215
|
+
self.webViewController?.buttonNearDoneIcon = buttonNearDoneIcon
|
|
216
|
+
|
|
217
|
+
if call.getBool("showArrow", false) {
|
|
218
|
+
self.webViewController?.stopBarButtonItemImage = UIImage(named: "Forward@3x", in: Bundle(for: InAppBrowserPlugin.self), compatibleWith: nil)
|
|
219
|
+
}
|
|
220
|
+
|
|
80
221
|
self.webViewController?.capBrowserPlugin = self
|
|
81
222
|
self.webViewController?.title = call.getString("title", "New Window")
|
|
82
223
|
self.webViewController?.shareSubject = call.getString("shareSubject")
|
|
83
224
|
self.webViewController?.shareDisclaimer = disclaimerContent
|
|
225
|
+
self.webViewController?.preShowScript = call.getString("preShowScript")
|
|
226
|
+
self.webViewController?.websiteTitleInNavigationBar = call.getBool("visibleTitle", true)
|
|
227
|
+
if closeModal {
|
|
228
|
+
self.webViewController?.closeModal = true
|
|
229
|
+
self.webViewController?.closeModalTitle = closeModalTitle
|
|
230
|
+
self.webViewController?.closeModalDescription = closeModalDescription
|
|
231
|
+
self.webViewController?.closeModalOk = closeModalOk
|
|
232
|
+
self.webViewController?.closeModalCancel = closeModalCancel
|
|
233
|
+
}
|
|
234
|
+
self.webViewController?.ignoreUntrustedSSLError = ignoreUntrustedSSLError
|
|
84
235
|
self.navigationWebViewController = UINavigationController.init(rootViewController: self.webViewController!)
|
|
85
236
|
self.navigationWebViewController?.navigationBar.isTranslucent = false
|
|
86
237
|
self.navigationWebViewController?.toolbar.isTranslucent = false
|
|
87
238
|
self.navigationWebViewController?.navigationBar.backgroundColor = backgroundColor
|
|
88
239
|
self.navigationWebViewController?.toolbar.backgroundColor = backgroundColor
|
|
240
|
+
self.navigationWebViewController?.toolbar.tintColor = backgroundColor == UIColor.black ? UIColor.white : UIColor.black
|
|
89
241
|
self.navigationWebViewController?.modalPresentationStyle = .fullScreen
|
|
90
242
|
if toolbarType == "blank" {
|
|
91
243
|
self.navigationWebViewController?.navigationBar.isHidden = true
|
|
92
244
|
}
|
|
245
|
+
if showReloadButton {
|
|
246
|
+
let toolbarItems = self.getToolbarItems(toolbarType: toolbarType)
|
|
247
|
+
self.webViewController?.leftNavigationBarItemTypes = toolbarItems + [.reload]
|
|
248
|
+
}
|
|
93
249
|
if !self.isPresentAfterPageLoad {
|
|
94
|
-
self.presentView()
|
|
250
|
+
self.presentView(isAnimated: isAnimated)
|
|
95
251
|
}
|
|
252
|
+
call.resolve()
|
|
96
253
|
}
|
|
97
254
|
}
|
|
98
255
|
|
|
@@ -107,20 +264,76 @@ public class InAppBrowserPlugin: CAPPlugin {
|
|
|
107
264
|
return result
|
|
108
265
|
}
|
|
109
266
|
|
|
267
|
+
@objc func reload(_ call: CAPPluginCall) {
|
|
268
|
+
self.webViewController?.reload()
|
|
269
|
+
call.resolve()
|
|
270
|
+
}
|
|
271
|
+
|
|
110
272
|
@objc func setUrl(_ call: CAPPluginCall) {
|
|
111
|
-
guard let
|
|
273
|
+
guard let urlString = call.getString("url") else {
|
|
112
274
|
call.reject("Cannot get new url to set")
|
|
113
275
|
return
|
|
114
276
|
}
|
|
115
|
-
|
|
277
|
+
|
|
278
|
+
guard let url = URL(string: urlString) else {
|
|
279
|
+
call.reject("Invalid URL")
|
|
280
|
+
return
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
self.webViewController?.load(remote: url)
|
|
284
|
+
call.resolve()
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
@objc func executeScript(_ call: CAPPluginCall) {
|
|
288
|
+
guard let script = call.getString("code") else {
|
|
289
|
+
call.reject("Cannot get script to execute")
|
|
290
|
+
return
|
|
291
|
+
}
|
|
292
|
+
DispatchQueue.main.async {
|
|
293
|
+
self.webViewController?.executeScript(script: script)
|
|
294
|
+
call.resolve()
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
@objc func postMessage(_ call: CAPPluginCall) {
|
|
299
|
+
let eventData = call.getObject("detail", [:])
|
|
300
|
+
// Check if eventData is empty
|
|
301
|
+
if eventData.isEmpty {
|
|
302
|
+
call.reject("Event data must not be empty")
|
|
303
|
+
return
|
|
304
|
+
}
|
|
305
|
+
print("Event data: \(eventData)")
|
|
306
|
+
|
|
307
|
+
DispatchQueue.main.async {
|
|
308
|
+
self.webViewController?.postMessageToJS(message: eventData)
|
|
309
|
+
}
|
|
116
310
|
call.resolve()
|
|
117
311
|
}
|
|
118
312
|
|
|
313
|
+
func isHexColorCode(_ input: String) -> Bool {
|
|
314
|
+
let hexColorRegex = "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$"
|
|
315
|
+
|
|
316
|
+
do {
|
|
317
|
+
let regex = try NSRegularExpression(pattern: hexColorRegex)
|
|
318
|
+
let range = NSRange(location: 0, length: input.utf16.count)
|
|
319
|
+
if let _ = regex.firstMatch(in: input, options: [], range: range) {
|
|
320
|
+
return true
|
|
321
|
+
}
|
|
322
|
+
} catch {
|
|
323
|
+
print("Error creating regular expression: \(error)")
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return false
|
|
327
|
+
}
|
|
328
|
+
|
|
119
329
|
@objc func open(_ call: CAPPluginCall) {
|
|
120
330
|
if !self.isSetupDone {
|
|
121
331
|
self.setup()
|
|
122
332
|
}
|
|
123
333
|
|
|
334
|
+
let isInspectable = call.getBool("isInspectable", false)
|
|
335
|
+
let preventDeeplink = call.getBool("preventDeeplink", false)
|
|
336
|
+
|
|
124
337
|
self.currentPluginCall = call
|
|
125
338
|
|
|
126
339
|
guard let urlString = call.getString("url") else {
|
|
@@ -137,18 +350,22 @@ public class InAppBrowserPlugin: CAPPlugin {
|
|
|
137
350
|
|
|
138
351
|
self.isPresentAfterPageLoad = call.getBool("isPresentAfterPageLoad", false)
|
|
139
352
|
|
|
353
|
+
let credentials = self.readCredentials(call)
|
|
354
|
+
|
|
140
355
|
DispatchQueue.main.async {
|
|
141
356
|
let url = URL(string: urlString)
|
|
142
357
|
|
|
143
358
|
if self.isPresentAfterPageLoad {
|
|
144
|
-
self.webViewController = WKWebViewController.init(url: url!, headers: headers)
|
|
359
|
+
self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable, credentials: credentials, preventDeeplink: preventDeeplink)
|
|
145
360
|
} else {
|
|
146
361
|
self.webViewController = WKWebViewController.init()
|
|
147
362
|
self.webViewController?.setHeaders(headers: headers)
|
|
363
|
+
self.webViewController?.setCredentials(credentials: credentials)
|
|
364
|
+
self.webViewController?.setPreventDeeplink(preventDeeplink: preventDeeplink)
|
|
148
365
|
}
|
|
149
366
|
|
|
150
367
|
self.webViewController?.source = .remote(url!)
|
|
151
|
-
self.webViewController?.
|
|
368
|
+
self.webViewController?.leftNavigationBarItemTypes = [.reload]
|
|
152
369
|
self.webViewController?.toolbarItemTypes = [.back, .forward, .activity]
|
|
153
370
|
self.webViewController?.capBrowserPlugin = self
|
|
154
371
|
self.webViewController?.hasDynamicTitle = true
|
|
@@ -156,17 +373,26 @@ public class InAppBrowserPlugin: CAPPlugin {
|
|
|
156
373
|
self.navigationWebViewController?.navigationBar.isTranslucent = false
|
|
157
374
|
self.navigationWebViewController?.toolbar.isTranslucent = false
|
|
158
375
|
self.navigationWebViewController?.navigationBar.backgroundColor = .white
|
|
159
|
-
|
|
376
|
+
let inputString: String = call.getString("toolbarColor", "#ffffff")
|
|
377
|
+
var color: UIColor = UIColor(hexString: "#ffffff")
|
|
378
|
+
if self.isHexColorCode(inputString) {
|
|
379
|
+
color = UIColor(hexString: inputString)
|
|
380
|
+
} else {
|
|
381
|
+
print("\(inputString) is not a valid hex color code.")
|
|
382
|
+
}
|
|
383
|
+
self.navigationWebViewController?.toolbar.backgroundColor = color
|
|
160
384
|
self.navigationWebViewController?.modalPresentationStyle = .fullScreen
|
|
161
385
|
if !self.isPresentAfterPageLoad {
|
|
162
386
|
self.presentView()
|
|
163
387
|
}
|
|
388
|
+
call.resolve()
|
|
164
389
|
}
|
|
165
390
|
}
|
|
166
391
|
|
|
167
392
|
@objc func close(_ call: CAPPluginCall) {
|
|
168
393
|
DispatchQueue.main.async {
|
|
169
394
|
self.navigationWebViewController?.dismiss(animated: true, completion: nil)
|
|
395
|
+
self.notifyListeners("closeEvent", data: ["url": self.webViewController?.url?.absoluteString ?? ""])
|
|
170
396
|
call.resolve()
|
|
171
397
|
}
|
|
172
398
|
}
|
|
@@ -200,4 +426,13 @@ public class InAppBrowserPlugin: CAPPlugin {
|
|
|
200
426
|
@objc func appWillResignActive(_ notification: NSNotification) {
|
|
201
427
|
self.showPrivacyScreen()
|
|
202
428
|
}
|
|
429
|
+
|
|
430
|
+
private func readCredentials(_ call: CAPPluginCall) -> WKWebViewCredentials? {
|
|
431
|
+
var credentials: WKWebViewCredentials?
|
|
432
|
+
let credentialsDict = call.getObject("credentials", [:]).mapValues { String(describing: $0 as Any) }
|
|
433
|
+
if !credentialsDict.isEmpty, let username = credentialsDict["username"], let password = credentialsDict["password"] {
|
|
434
|
+
credentials = WKWebViewCredentials(username: username, password: password)
|
|
435
|
+
}
|
|
436
|
+
return credentials
|
|
437
|
+
}
|
|
203
438
|
}
|