@calvingoh-hexa/capacitor-inappbrowser 6.9.36

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.
Files changed (55) hide show
  1. package/CapgoInappbrowser.podspec +17 -0
  2. package/LICENSE +21 -0
  3. package/README.md +690 -0
  4. package/android/build.gradle +64 -0
  5. package/android/src/main/AndroidManifest.xml +12 -0
  6. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/InAppBrowserPlugin.java +741 -0
  7. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/Options.java +340 -0
  8. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewCallbacks.java +15 -0
  9. package/android/src/main/java/ee/forgr/capacitor_inappbrowser/WebViewDialog.java +1177 -0
  10. package/android/src/main/res/.gitkeep +0 -0
  11. package/android/src/main/res/drawable/arrow_back_disabled.xml +9 -0
  12. package/android/src/main/res/drawable/arrow_back_enabled.xml +9 -0
  13. package/android/src/main/res/drawable/arrow_forward_disabled.xml +9 -0
  14. package/android/src/main/res/drawable/arrow_forward_enabled.xml +9 -0
  15. package/android/src/main/res/drawable/ic_clear_24px.xml +9 -0
  16. package/android/src/main/res/drawable/ic_refresh.xml +9 -0
  17. package/android/src/main/res/layout/activity_browser.xml +22 -0
  18. package/android/src/main/res/layout/bridge_layout_main.xml +15 -0
  19. package/android/src/main/res/layout/content_browser.xml +16 -0
  20. package/android/src/main/res/layout/tool_bar.xml +72 -0
  21. package/android/src/main/res/values/browser_theme.xml +3 -0
  22. package/android/src/main/res/values/colors.xml +5 -0
  23. package/android/src/main/res/values/dimens.xml +3 -0
  24. package/android/src/main/res/values/strings.xml +11 -0
  25. package/android/src/main/res/values/styles.xml +4 -0
  26. package/dist/docs.json +1865 -0
  27. package/dist/esm/definitions.d.ts +361 -0
  28. package/dist/esm/definitions.js +13 -0
  29. package/dist/esm/definitions.js.map +1 -0
  30. package/dist/esm/index.d.ts +4 -0
  31. package/dist/esm/index.js +7 -0
  32. package/dist/esm/index.js.map +1 -0
  33. package/dist/esm/web.d.ts +19 -0
  34. package/dist/esm/web.js +48 -0
  35. package/dist/esm/web.js.map +1 -0
  36. package/dist/plugin.cjs.js +75 -0
  37. package/dist/plugin.cjs.js.map +1 -0
  38. package/dist/plugin.js +78 -0
  39. package/dist/plugin.js.map +1 -0
  40. package/ios/Plugin/Assets.xcassets/Back.imageset/Back.png +0 -0
  41. package/ios/Plugin/Assets.xcassets/Back.imageset/Back@2x.png +0 -0
  42. package/ios/Plugin/Assets.xcassets/Back.imageset/Back@3x.png +0 -0
  43. package/ios/Plugin/Assets.xcassets/Back.imageset/Contents.json +26 -0
  44. package/ios/Plugin/Assets.xcassets/Contents.json +6 -0
  45. package/ios/Plugin/Assets.xcassets/Forward.imageset/Contents.json +26 -0
  46. package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward.png +0 -0
  47. package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward@2x.png +0 -0
  48. package/ios/Plugin/Assets.xcassets/Forward.imageset/Forward@3x.png +0 -0
  49. package/ios/Plugin/Enums.swift +65 -0
  50. package/ios/Plugin/InAppBrowserPlugin.h +10 -0
  51. package/ios/Plugin/InAppBrowserPlugin.m +21 -0
  52. package/ios/Plugin/InAppBrowserPlugin.swift +434 -0
  53. package/ios/Plugin/Info.plist +24 -0
  54. package/ios/Plugin/WKWebViewController.swift +1021 -0
  55. package/package.json +83 -0
@@ -0,0 +1,26 @@
1
+ {
2
+ "images" : [
3
+ {
4
+ "idiom" : "universal",
5
+ "filename" : "Back.png",
6
+ "scale" : "1x"
7
+ },
8
+ {
9
+ "idiom" : "universal",
10
+ "filename" : "Back@2x.png",
11
+ "scale" : "2x"
12
+ },
13
+ {
14
+ "idiom" : "universal",
15
+ "filename" : "Back@3x.png",
16
+ "scale" : "3x"
17
+ }
18
+ ],
19
+ "info" : {
20
+ "version" : 1,
21
+ "author" : "xcode"
22
+ },
23
+ "properties" : {
24
+ "template-rendering-intent" : "template"
25
+ }
26
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "info" : {
3
+ "version" : 1,
4
+ "author" : "xcode"
5
+ }
6
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "images" : [
3
+ {
4
+ "idiom" : "universal",
5
+ "filename" : "Forward.png",
6
+ "scale" : "1x"
7
+ },
8
+ {
9
+ "idiom" : "universal",
10
+ "filename" : "Forward@2x.png",
11
+ "scale" : "2x"
12
+ },
13
+ {
14
+ "idiom" : "universal",
15
+ "filename" : "Forward@3x.png",
16
+ "scale" : "3x"
17
+ }
18
+ ],
19
+ "info" : {
20
+ "version" : 1,
21
+ "author" : "xcode"
22
+ },
23
+ "properties" : {
24
+ "template-rendering-intent" : "template"
25
+ }
26
+ }
@@ -0,0 +1,65 @@
1
+ //
2
+ // Enums.swift
3
+ // Sample
4
+ //
5
+ // Created by Meniny on 2018-01-20.
6
+ // Copyright © 2018年 Meniny. All rights reserved.
7
+ //
8
+
9
+ import Foundation
10
+ import UIKit
11
+
12
+ public enum WKWebSource: Equatable {
13
+ case remote(URL)
14
+ case file(URL, access: URL)
15
+ case string(String, base: URL?)
16
+
17
+ public var url: URL? {
18
+ switch self {
19
+ case .remote(let u): return u
20
+ case .file(let u, access: _): return u
21
+ default: return nil
22
+ }
23
+ }
24
+
25
+ public var remoteURL: URL? {
26
+ switch self {
27
+ case .remote(let u): return u
28
+ default: return nil
29
+ }
30
+ }
31
+
32
+ public var absoluteString: String? {
33
+ switch self {
34
+ case .remote(let u): return u.absoluteString
35
+ case .file(let u, access: _): return u.absoluteString
36
+ default: return nil
37
+ }
38
+ }
39
+ }
40
+
41
+ public enum BarButtonItemType {
42
+ case back
43
+ case forward
44
+ case reload
45
+ case stop
46
+ case activity
47
+ case done
48
+ case flexibleSpace
49
+ case custom(icon: UIImage?, title: String?, action: (WKWebViewController) -> Void)
50
+ }
51
+
52
+ public enum NavigationBarPosition: String, Equatable, Codable {
53
+ case none
54
+ case left
55
+ case right
56
+ }
57
+
58
+ @objc public enum NavigationType: Int, Equatable, Codable {
59
+ case linkActivated
60
+ case formSubmitted
61
+ case backForward
62
+ case reload
63
+ case formResubmitted
64
+ case other
65
+ }
@@ -0,0 +1,10 @@
1
+ #import <UIKit/UIKit.h>
2
+
3
+ //! Project version number for Plugin.
4
+ FOUNDATION_EXPORT double PluginVersionNumber;
5
+
6
+ //! Project version string for Plugin.
7
+ FOUNDATION_EXPORT const unsigned char PluginVersionString[];
8
+
9
+ // In this header, you should import all the public headers of your framework using statements like #import <Plugin/PublicHeader.h>
10
+
@@ -0,0 +1,21 @@
1
+ #import <Foundation/Foundation.h>
2
+ #import <Capacitor/Capacitor.h>
3
+
4
+ // Define the plugin using the CAP_PLUGIN Macro, and
5
+ // each method the plugin supports using the CAP_PLUGIN_METHOD macro.
6
+ CAP_PLUGIN(InAppBrowserPlugin, "InAppBrowser",
7
+ CAP_PLUGIN_METHOD(openWebView, CAPPluginReturnPromise);
8
+ CAP_PLUGIN_METHOD(clearCookies, CAPPluginReturnPromise);
9
+ CAP_PLUGIN_METHOD(getCookies, CAPPluginReturnPromise);
10
+ CAP_PLUGIN_METHOD(clearAllCookies, CAPPluginReturnPromise);
11
+ CAP_PLUGIN_METHOD(clearCache, CAPPluginReturnPromise);
12
+ CAP_PLUGIN_METHOD(reload, CAPPluginReturnPromise);
13
+ CAP_PLUGIN_METHOD(open, CAPPluginReturnPromise);
14
+ CAP_PLUGIN_METHOD(setUrl, CAPPluginReturnPromise);
15
+ CAP_PLUGIN_METHOD(show, CAPPluginReturnPromise);
16
+ CAP_PLUGIN_METHOD(close, CAPPluginReturnPromise);
17
+ CAP_PLUGIN_METHOD(hide, CAPPluginReturnPromise);
18
+ CAP_PLUGIN_METHOD(executeScript, CAPPluginReturnPromise);
19
+ CAP_PLUGIN_METHOD(postMessage, CAPPluginReturnPromise);
20
+ CAP_PLUGIN_METHOD(insertCSS, CAPPluginReturnPromise);
21
+ )
@@ -0,0 +1,434 @@
1
+ import Foundation
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
+ }
20
+
21
+ /**
22
+ * Please read the Capacitor iOS Plugin Development Guide
23
+ * here: https://capacitorjs.com/docs/plugins/ios
24
+ */
25
+ @objc(InAppBrowserPlugin)
26
+ public class InAppBrowserPlugin: CAPPlugin {
27
+ var navigationWebViewController: UINavigationController?
28
+ private var privacyScreen: UIImageView?
29
+ private var isSetupDone = false
30
+ var currentPluginCall: CAPPluginCall?
31
+ var isPresentAfterPageLoad = false
32
+ var webViewController: WKWebViewController?
33
+
34
+ private func setup() {
35
+ self.isSetupDone = true
36
+
37
+ #if swift(>=4.2)
38
+ NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive(_:)), name: UIApplication.didBecomeActiveNotification, object: nil)
39
+ NotificationCenter.default.addObserver(self, selector: #selector(appWillResignActive(_:)), name: UIApplication.willResignActiveNotification, object: nil)
40
+ #else
41
+ NotificationCenter.default.addObserver(self, selector: #selector(appDidBecomeActive(_:)), name: .UIApplicationDidBecomeActive, object: nil)
42
+ NotificationCenter.default.addObserver(self, selector: #selector(appWillResignActive(_:)), name: .UIApplicationWillResignActive, object: nil)
43
+ #endif
44
+ }
45
+
46
+ func presentView(isAnimated: Bool = true) {
47
+ self.bridge?.viewController?.present(self.navigationWebViewController!, animated: isAnimated, completion: {
48
+ self.currentPluginCall?.resolve()
49
+ })
50
+ }
51
+
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
+
123
+ }
124
+
125
+ @objc func openWebView(_ call: CAPPluginCall) {
126
+ if !self.isSetupDone {
127
+ self.setup()
128
+ }
129
+ self.currentPluginCall = call
130
+
131
+ guard let urlString = call.getString("url") else {
132
+ call.reject("Must provide a URL to open")
133
+ return
134
+ }
135
+
136
+ if urlString.isEmpty {
137
+ call.reject("URL must not be empty")
138
+ return
139
+ }
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
+
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)
183
+
184
+ var disclaimerContent = call.getObject("shareDisclaimer")
185
+ let toolbarType = call.getString("toolbarType", "")
186
+ let backgroundColor = call.getString("backgroundColor", "black") == "white" ? UIColor.white : UIColor.black
187
+ if toolbarType != "activity" {
188
+ disclaimerContent = nil
189
+ }
190
+ let ignoreUntrustedSSLError = call.getBool("ignoreUntrustedSSLError", false)
191
+
192
+ self.isPresentAfterPageLoad = call.getBool("isPresentAfterPageLoad", false)
193
+ let showReloadButton = call.getBool("showReloadButton", false)
194
+
195
+ let credentials = self.readCredentials(call)
196
+
197
+ DispatchQueue.main.async {
198
+ let url = URL(string: urlString)
199
+
200
+ if self.isPresentAfterPageLoad {
201
+ self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable, credentials: credentials, preventDeeplink: preventDeeplink)
202
+ } else {
203
+ self.webViewController = WKWebViewController.init()
204
+ self.webViewController?.setHeaders(headers: headers)
205
+ self.webViewController?.setCredentials(credentials: credentials)
206
+ self.webViewController?.setPreventDeeplink(preventDeeplink: preventDeeplink)
207
+ }
208
+
209
+ self.webViewController?.source = .remote(url!)
210
+ self.webViewController?.leftNavigationBarItemTypes = self.getToolbarItems(toolbarType: toolbarType) + [.reload]
211
+ self.webViewController?.leftNavigationBarItemTypes = self.getToolbarItems(toolbarType: toolbarType)
212
+ self.webViewController?.toolbarItemTypes = []
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
+
221
+ self.webViewController?.capBrowserPlugin = self
222
+ self.webViewController?.title = call.getString("title", "New Window")
223
+ self.webViewController?.shareSubject = call.getString("shareSubject")
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
235
+ self.navigationWebViewController = UINavigationController.init(rootViewController: self.webViewController!)
236
+ self.navigationWebViewController?.navigationBar.isTranslucent = false
237
+ self.navigationWebViewController?.toolbar.isTranslucent = false
238
+ self.navigationWebViewController?.navigationBar.backgroundColor = backgroundColor
239
+ self.navigationWebViewController?.toolbar.backgroundColor = backgroundColor
240
+ self.navigationWebViewController?.toolbar.tintColor = backgroundColor == UIColor.black ? UIColor.white : UIColor.black
241
+ self.navigationWebViewController?.modalPresentationStyle = .fullScreen
242
+ if toolbarType == "blank" {
243
+ self.navigationWebViewController?.navigationBar.isHidden = true
244
+ }
245
+ if showReloadButton {
246
+ let toolbarItems = self.getToolbarItems(toolbarType: toolbarType)
247
+ self.webViewController?.leftNavigationBarItemTypes = toolbarItems + [.reload]
248
+ }
249
+ if !self.isPresentAfterPageLoad {
250
+ self.presentView(isAnimated: isAnimated)
251
+ }
252
+ call.resolve()
253
+ }
254
+ }
255
+
256
+ func getToolbarItems(toolbarType: String) -> [BarButtonItemType] {
257
+ var result: [BarButtonItemType] = []
258
+ if toolbarType == "activity" {
259
+ result.append(.activity)
260
+ } else if toolbarType == "navigation" {
261
+ result.append(.back)
262
+ result.append(.forward)
263
+ }
264
+ return result
265
+ }
266
+
267
+ @objc func reload(_ call: CAPPluginCall) {
268
+ self.webViewController?.reload()
269
+ call.resolve()
270
+ }
271
+
272
+ @objc func setUrl(_ call: CAPPluginCall) {
273
+ guard let urlString = call.getString("url") else {
274
+ call.reject("Cannot get new url to set")
275
+ return
276
+ }
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
+ self.webViewController?.executeScript(script: script)
293
+ call.resolve()
294
+ }
295
+
296
+ @objc func postMessage(_ call: CAPPluginCall) {
297
+ let eventData = call.getObject("detail", [:])
298
+ // Check if eventData is empty
299
+ if eventData.isEmpty {
300
+ call.reject("Event data must not be empty")
301
+ return
302
+ }
303
+ print("Event data: \(eventData)")
304
+
305
+ self.webViewController?.postMessageToJS(message: eventData)
306
+ call.resolve()
307
+ }
308
+
309
+ func isHexColorCode(_ input: String) -> Bool {
310
+ let hexColorRegex = "^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6})$"
311
+
312
+ do {
313
+ let regex = try NSRegularExpression(pattern: hexColorRegex)
314
+ let range = NSRange(location: 0, length: input.utf16.count)
315
+ if let _ = regex.firstMatch(in: input, options: [], range: range) {
316
+ return true
317
+ }
318
+ } catch {
319
+ print("Error creating regular expression: \(error)")
320
+ }
321
+
322
+ return false
323
+ }
324
+
325
+ @objc func open(_ call: CAPPluginCall) {
326
+ if !self.isSetupDone {
327
+ self.setup()
328
+ }
329
+
330
+ let isInspectable = call.getBool("isInspectable", false)
331
+ let preventDeeplink = call.getBool("preventDeeplink", false)
332
+
333
+ self.currentPluginCall = call
334
+
335
+ guard let urlString = call.getString("url") else {
336
+ call.reject("Must provide a URL to open")
337
+ return
338
+ }
339
+
340
+ if urlString.isEmpty {
341
+ call.reject("URL must not be empty")
342
+ return
343
+ }
344
+
345
+ let headers = call.getObject("headers", [:]).mapValues { String(describing: $0 as Any) }
346
+
347
+ self.isPresentAfterPageLoad = call.getBool("isPresentAfterPageLoad", false)
348
+
349
+ let credentials = self.readCredentials(call)
350
+
351
+ DispatchQueue.main.async {
352
+ let url = URL(string: urlString)
353
+
354
+ if self.isPresentAfterPageLoad {
355
+ self.webViewController = WKWebViewController.init(url: url!, headers: headers, isInspectable: isInspectable, credentials: credentials, preventDeeplink: preventDeeplink)
356
+ } else {
357
+ self.webViewController = WKWebViewController.init()
358
+ self.webViewController?.setHeaders(headers: headers)
359
+ self.webViewController?.setCredentials(credentials: credentials)
360
+ self.webViewController?.setPreventDeeplink(preventDeeplink: preventDeeplink)
361
+ }
362
+
363
+ self.webViewController?.source = .remote(url!)
364
+ self.webViewController?.leftNavigationBarItemTypes = [.reload]
365
+ self.webViewController?.toolbarItemTypes = [.back, .forward, .activity]
366
+ self.webViewController?.capBrowserPlugin = self
367
+ self.webViewController?.hasDynamicTitle = true
368
+ self.navigationWebViewController = UINavigationController.init(rootViewController: self.webViewController!)
369
+ self.navigationWebViewController?.navigationBar.isTranslucent = false
370
+ self.navigationWebViewController?.toolbar.isTranslucent = false
371
+ self.navigationWebViewController?.navigationBar.backgroundColor = .white
372
+ let inputString: String = call.getString("toolbarColor", "#ffffff")
373
+ var color: UIColor = UIColor(hexString: "#ffffff")
374
+ if self.isHexColorCode(inputString) {
375
+ color = UIColor(hexString: inputString)
376
+ } else {
377
+ print("\(inputString) is not a valid hex color code.")
378
+ }
379
+ self.navigationWebViewController?.toolbar.backgroundColor = color
380
+ self.navigationWebViewController?.modalPresentationStyle = .fullScreen
381
+ if !self.isPresentAfterPageLoad {
382
+ self.presentView()
383
+ }
384
+ call.resolve()
385
+ }
386
+ }
387
+
388
+ @objc func close(_ call: CAPPluginCall) {
389
+ DispatchQueue.main.async {
390
+ self.navigationWebViewController?.dismiss(animated: true, completion: nil)
391
+ self.notifyListeners("closeEvent", data: ["url": self.webViewController?.url?.absoluteString ?? ""])
392
+ call.resolve()
393
+ }
394
+ }
395
+
396
+ private func showPrivacyScreen() {
397
+ if privacyScreen == nil {
398
+ self.privacyScreen = UIImageView()
399
+ if let launchImage = UIImage(named: "LaunchImage") {
400
+ privacyScreen!.image = launchImage
401
+ privacyScreen!.frame = UIScreen.main.bounds
402
+ privacyScreen!.contentMode = .scaleAspectFill
403
+ privacyScreen!.isUserInteractionEnabled = false
404
+ } else if let launchImage = UIImage(named: "Splash") {
405
+ privacyScreen!.image = launchImage
406
+ privacyScreen!.frame = UIScreen.main.bounds
407
+ privacyScreen!.contentMode = .scaleAspectFill
408
+ privacyScreen!.isUserInteractionEnabled = false
409
+ }
410
+ }
411
+ self.navigationWebViewController?.view.addSubview(self.privacyScreen!)
412
+ }
413
+
414
+ private func hidePrivacyScreen() {
415
+ self.privacyScreen?.removeFromSuperview()
416
+ }
417
+
418
+ @objc func appDidBecomeActive(_ notification: NSNotification) {
419
+ self.hidePrivacyScreen()
420
+ }
421
+
422
+ @objc func appWillResignActive(_ notification: NSNotification) {
423
+ self.showPrivacyScreen()
424
+ }
425
+
426
+ private func readCredentials(_ call: CAPPluginCall) -> WKWebViewCredentials? {
427
+ var credentials: WKWebViewCredentials?
428
+ let credentialsDict = call.getObject("credentials", [:]).mapValues { String(describing: $0 as Any) }
429
+ if !credentialsDict.isEmpty, let username = credentialsDict["username"], let password = credentialsDict["password"] {
430
+ credentials = WKWebViewCredentials(username: username, password: password)
431
+ }
432
+ return credentials
433
+ }
434
+ }
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
7
+ <key>CFBundleExecutable</key>
8
+ <string>$(EXECUTABLE_NAME)</string>
9
+ <key>CFBundleIdentifier</key>
10
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11
+ <key>CFBundleInfoDictionaryVersion</key>
12
+ <string>6.0</string>
13
+ <key>CFBundleName</key>
14
+ <string>$(PRODUCT_NAME)</string>
15
+ <key>CFBundlePackageType</key>
16
+ <string>FMWK</string>
17
+ <key>CFBundleShortVersionString</key>
18
+ <string>1.0</string>
19
+ <key>CFBundleVersion</key>
20
+ <string>$(CURRENT_PROJECT_VERSION)</string>
21
+ <key>NSPrincipalClass</key>
22
+ <string></string>
23
+ </dict>
24
+ </plist>