turbo-native-initializer 0.0.14 → 0.0.16
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.
- checksums.yaml +4 -4
- data/lib/turbo_native_initializer/templates/android_stack/base/app/src/main/assets/json/configuration.json +2 -2
- data/lib/turbo_native_initializer/templates/android_tabs/base/app/src/main/assets/json/configuration.json +2 -2
- data/lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Configuration/path-configuration.json +3 -3
- data/lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Controllers/TurboNavigationController.swift +22 -6
- data/lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Controllers/TurboWebViewController.swift +8 -0
- data/lib/turbo_native_initializer/templates/ios_stack/TurboNativeProject/Delegates/SceneDelegate.swift.tt +9 -39
- data/lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Configuration/path-configuration.json +3 -3
- data/lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Controllers/TurboNavigationController.swift +22 -6
- data/lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Controllers/TurboWebViewController.swift +8 -0
- data/lib/turbo_native_initializer/templates/ios_tabs/TurboNativeProject/Delegates/SceneDelegate.swift.tt +14 -48
- data/lib/turbo_native_initializer/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6841be700aef23b3f08578ca5600a2b04f749b0759b78524b9eeee25b401761
|
4
|
+
data.tar.gz: 150fcb0fdb292a111db55d614684162201e46fef74df2dd0d5e3bb07d1e631eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 94495c27a497d66a322a394b5d0892d38ffd4b6db121dff707598864283efe3afd48ed50ab4f31ff08e60f64171ec2e7c2803131939e4aea202a1499e9d3bf31
|
7
|
+
data.tar.gz: dc44d0613e6e02f30de088a3f329297c8fd38e310e56c921a55d913c199862f6d44dfe468ff206bd0381dfedde8daf1def0acb41eef353b1dd93643421850b01
|
@@ -2,11 +2,11 @@
|
|
2
2
|
"settings": {},
|
3
3
|
"rules": [
|
4
4
|
{ "patterns": [".*"], "properties": { "uri": "turbo://fragment/web", "pull_to_refresh_enabled": true } },
|
5
|
-
{ "patterns": ["/refresh_historical_location"], "properties": { "presentation": "refresh" } },
|
6
5
|
{ "patterns": ["/recede_historical_location"], "properties": { "presentation": "pop" } },
|
7
6
|
{ "patterns": ["/resume_historical_location"], "properties": { "presentation": "none" } },
|
8
|
-
{ "patterns": ["
|
7
|
+
{ "patterns": ["/refresh_historical_location"], "properties": { "presentation": "refresh" } },
|
9
8
|
{ "patterns": ["/new$", "/edit$", "/signin$", "/strada-form$"], "properties": { "context": "modal", "uri": "turbo://fragment/web/modal", "pull_to_refresh_enabled": false } },
|
9
|
+
{ "patterns": ["^/$"], "properties": { "uri": "turbo://fragment/web/home", "presentation": "replace_all" } },
|
10
10
|
{ "patterns": ["/numbers$"], "properties": { "uri": "turbo://fragment/numbers", "title": "Numbers" } }
|
11
11
|
]
|
12
12
|
}
|
@@ -2,11 +2,11 @@
|
|
2
2
|
"settings": {},
|
3
3
|
"rules": [
|
4
4
|
{ "patterns": [".*"], "properties": { "uri": "turbo://fragment/web", "pull_to_refresh_enabled": true } },
|
5
|
-
{ "patterns": ["/refresh_historical_location"], "properties": { "presentation": "refresh" } },
|
6
5
|
{ "patterns": ["/recede_historical_location"], "properties": { "presentation": "pop" } },
|
7
6
|
{ "patterns": ["/resume_historical_location"], "properties": { "presentation": "none" } },
|
8
|
-
{ "patterns": ["
|
7
|
+
{ "patterns": ["/refresh_historical_location"], "properties": { "presentation": "refresh" } },
|
9
8
|
{ "patterns": ["/new$", "/edit$", "/signin$", "/strada-form$"], "properties": { "context": "modal", "uri": "turbo://fragment/web/modal", "pull_to_refresh_enabled": false } },
|
9
|
+
{ "patterns": ["^/$"], "properties": { "uri": "turbo://fragment/web/home", "presentation": "replace_all" } },
|
10
10
|
{ "patterns": ["/numbers$"], "properties": { "uri": "turbo://fragment/numbers", "title": "Numbers" } }
|
11
11
|
]
|
12
12
|
}
|
@@ -1,11 +1,11 @@
|
|
1
1
|
{
|
2
2
|
"settings": {},
|
3
3
|
"rules": [
|
4
|
-
{ "patterns": ["/
|
5
|
-
{ "patterns": ["/recede_historical_location"], "properties": { "presentation": "pop", "visitable": false } },
|
4
|
+
{ "patterns": ["/recede_historical_location"], "properties": { "presentation": "back", "visitable": false } },
|
6
5
|
{ "patterns": ["/resume_historical_location"], "properties": { "presentation": "none", "visitable": false } },
|
6
|
+
{ "patterns": ["/refresh_historical_location"], "properties": { "presentation": "refresh", "visitable": false } },
|
7
|
+
{ "patterns": ["/new$", "/edit$", "/signin$", "/strada-form$"], "properties": { "presentation": "modal", "pull-to-refresh-enabled": false } },
|
7
8
|
{ "patterns": ["^/$"], "properties": { "presentation": "replace-all" } },
|
8
|
-
{ "patterns": ["/new$", "/edit$", "/signin$", "/strada-form$"], "properties": { "presentation": "modal" } },
|
9
9
|
{ "patterns": ["/numbers$"], "properties": { "view-controller": "numbers" } }
|
10
10
|
]
|
11
11
|
}
|
@@ -22,9 +22,14 @@ class TurboNavigationController : UINavigationController {
|
|
22
22
|
}
|
23
23
|
|
24
24
|
// - Create view controller appropriate for url/properties
|
25
|
-
// - Navigate to that with the correct presentation
|
26
25
|
let viewController = makeViewController(for: url, properties: properties)
|
27
|
-
|
26
|
+
|
27
|
+
// - Navigate to that with the correct presentation
|
28
|
+
if session.topmostVisitable?.visitableURL == url {
|
29
|
+
navigate(to: viewController, action: .replace, properties: properties)
|
30
|
+
} else {
|
31
|
+
navigate(to: viewController, action: options.action, properties: properties)
|
32
|
+
}
|
28
33
|
|
29
34
|
// Initiate the visit with Turbo
|
30
35
|
if isVisitable(properties) {
|
@@ -43,8 +48,8 @@ extension TurboNavigationController {
|
|
43
48
|
return properties["presentation"] as? String == "modal"
|
44
49
|
}
|
45
50
|
|
46
|
-
private func
|
47
|
-
return properties["presentation"] as? String == "
|
51
|
+
private func isBack(_ properties: PathProperties) -> Bool {
|
52
|
+
return properties["presentation"] as? String == "back"
|
48
53
|
}
|
49
54
|
|
50
55
|
private func isRefresh(_ properties: PathProperties) -> Bool {
|
@@ -71,6 +76,14 @@ extension TurboNavigationController {
|
|
71
76
|
return properties["visitable"] as? Bool ?? true
|
72
77
|
}
|
73
78
|
|
79
|
+
private func isPullToRefreshEnabled(_ properties: PathProperties) -> Bool {
|
80
|
+
return properties["pull-to-refresh-enabled"] as? Bool ?? true
|
81
|
+
}
|
82
|
+
|
83
|
+
private func title(from properties: PathProperties) -> String? {
|
84
|
+
return properties["title"] as? String
|
85
|
+
}
|
86
|
+
|
74
87
|
private func noticeMessage(from url: URL) -> String? {
|
75
88
|
URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.first(where: { $0.name == "notice" })?.value
|
76
89
|
}
|
@@ -90,13 +103,16 @@ extension TurboNavigationController {
|
|
90
103
|
}
|
91
104
|
}
|
92
105
|
|
93
|
-
|
106
|
+
let viewController = TurboWebViewController(url: url)
|
107
|
+
viewController.pullToRefreshEnabled = isPullToRefreshEnabled(properties)
|
108
|
+
viewController.title = title(from: properties)
|
109
|
+
return viewController
|
94
110
|
}
|
95
111
|
|
96
112
|
private func navigate(to viewController: UIViewController, action: VisitAction, properties: PathProperties = [:]) {
|
97
113
|
if isModal(properties) {
|
98
114
|
present(UINavigationController(rootViewController: viewController), animated: true)
|
99
|
-
} else if
|
115
|
+
} else if isBack(properties) {
|
100
116
|
popViewController(animated: true)
|
101
117
|
} else if isRefresh(properties) {
|
102
118
|
session.reload()
|
@@ -5,6 +5,8 @@ import WebKit
|
|
5
5
|
|
6
6
|
final class TurboWebViewController: VisitableViewController, ErrorPresenter, BridgeDestination {
|
7
7
|
|
8
|
+
var pullToRefreshEnabled = true
|
9
|
+
|
8
10
|
private lazy var bridgeDelegate: BridgeDelegate = {
|
9
11
|
BridgeDelegate(location: visitableURL.absoluteString, destination: self, componentTypes: BridgeComponent.allTypes)
|
10
12
|
}()
|
@@ -20,6 +22,8 @@ final class TurboWebViewController: VisitableViewController, ErrorPresenter, Bri
|
|
20
22
|
|
21
23
|
navigationItem.backButtonTitle = "Back"
|
22
24
|
|
25
|
+
visitableView.allowsPullToRefresh = pullToRefreshEnabled
|
26
|
+
|
23
27
|
if presentingViewController != nil {
|
24
28
|
navigationItem.leftBarButtonItem = dismissModalButton
|
25
29
|
}
|
@@ -49,6 +53,10 @@ final class TurboWebViewController: VisitableViewController, ErrorPresenter, Bri
|
|
49
53
|
|
50
54
|
// MARK: Visitable
|
51
55
|
|
56
|
+
override func visitableDidRender() {
|
57
|
+
title = title ?? visitableView.webView?.title
|
58
|
+
}
|
59
|
+
|
52
60
|
override func visitableDidActivateWebView(_ webView: WKWebView) {
|
53
61
|
bridgeDelegate.webViewDidBecomeActive(webView)
|
54
62
|
}
|
@@ -14,9 +14,7 @@ final class SceneDelegate: UIResponder {
|
|
14
14
|
// MARK: - Setup
|
15
15
|
|
16
16
|
private func configureRootViewController() {
|
17
|
-
|
18
|
-
|
19
|
-
navigationController = window.rootViewController as? TurboNavigationController
|
17
|
+
navigationController = window!.rootViewController as? TurboNavigationController
|
20
18
|
navigationController.session = session
|
21
19
|
navigationController.modalSession = modalSession
|
22
20
|
}
|
@@ -68,6 +66,14 @@ extension SceneDelegate: SessionDelegate {
|
|
68
66
|
navigationController.route(url: proposal.url, options: proposal.options, properties: proposal.properties)
|
69
67
|
}
|
70
68
|
|
69
|
+
func session(_ session: Session, openExternalURL url: URL) {
|
70
|
+
if url.host == rootURL.host, !url.pathExtension.isEmpty {
|
71
|
+
navigationController.present(SFSafariViewController(url: url), animated: true)
|
72
|
+
} else {
|
73
|
+
UIApplication.shared.open(url)
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
71
77
|
func session(_ session: Session, didFailRequestForVisitable visitable: Visitable, error: Error) {
|
72
78
|
if let turboError = error as? TurboError, case let .http(statusCode) = turboError, statusCode == 401 {
|
73
79
|
promptForAuthentication()
|
@@ -78,58 +84,22 @@ extension SceneDelegate: SessionDelegate {
|
|
78
84
|
}
|
79
85
|
}
|
80
86
|
|
81
|
-
// When a form submission completes in the modal session, we need to
|
82
|
-
// manually clear the snapshot cache in the default session, since we
|
83
|
-
// don't want potentially stale cached snapshots to be used
|
84
87
|
func sessionDidFinishFormSubmission(_ session: Session) {
|
85
88
|
if (session == modalSession) {
|
86
89
|
self.session.clearSnapshotCache()
|
87
90
|
}
|
88
91
|
}
|
89
92
|
|
90
|
-
func sessionDidLoadWebView(_ session: Session) {
|
91
|
-
session.webView.navigationDelegate = self
|
92
|
-
}
|
93
|
-
|
94
93
|
func sessionWebViewProcessDidTerminate(_ session: Session) {
|
95
94
|
session.reload()
|
96
95
|
}
|
97
96
|
}
|
98
97
|
|
99
|
-
extension SceneDelegate: WKNavigationDelegate {
|
100
|
-
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
101
|
-
if navigationAction.navigationType == .linkActivated {
|
102
|
-
// Any link that's not on the same domain as the Turbo root url will go through here
|
103
|
-
// Other links on the domain, but that have an extension that is non-html will also go here
|
104
|
-
// You can decide how to handle those, by default if you're not the navigationDelegate
|
105
|
-
// the Session will open them in the default browser
|
106
|
-
|
107
|
-
let url = navigationAction.request.url!
|
108
|
-
|
109
|
-
// For this demo, we'll load files from our domain in a SafariViewController so you
|
110
|
-
// don't need to leave the app. You might expand this in your app
|
111
|
-
// to open all audio/video/images in a native media viewer
|
112
|
-
if url.host == rootURL.host, !url.pathExtension.isEmpty {
|
113
|
-
let safariViewController = SFSafariViewController(url: url)
|
114
|
-
navigationController.present(safariViewController, animated: true)
|
115
|
-
} else {
|
116
|
-
UIApplication.shared.open(url)
|
117
|
-
}
|
118
|
-
|
119
|
-
decisionHandler(.cancel)
|
120
|
-
} else {
|
121
|
-
decisionHandler(.allow)
|
122
|
-
}
|
123
|
-
}
|
124
|
-
}
|
125
|
-
|
126
98
|
extension SceneDelegate: WKUIDelegate {
|
127
99
|
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
|
128
100
|
let confirm = UIAlertController(title: nil, message: message, preferredStyle: .alert)
|
129
101
|
confirm.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in completionHandler(false) })
|
130
102
|
confirm.addAction(UIAlertAction(title: "OK", style: .default) { _ in completionHandler(true) })
|
131
|
-
|
132
|
-
// JavaScript alerts in Turbo Native
|
133
103
|
navigationController.present(confirm, animated: true)
|
134
104
|
}
|
135
105
|
}
|
@@ -1,11 +1,11 @@
|
|
1
1
|
{
|
2
2
|
"settings": {},
|
3
3
|
"rules": [
|
4
|
-
{ "patterns": ["/
|
5
|
-
{ "patterns": ["/recede_historical_location"], "properties": { "presentation": "pop", "visitable": false } },
|
4
|
+
{ "patterns": ["/recede_historical_location"], "properties": { "presentation": "back", "visitable": false } },
|
6
5
|
{ "patterns": ["/resume_historical_location"], "properties": { "presentation": "none", "visitable": false } },
|
6
|
+
{ "patterns": ["/refresh_historical_location"], "properties": { "presentation": "refresh", "visitable": false } },
|
7
|
+
{ "patterns": ["/new$", "/edit$", "/signin$", "/strada-form$"], "properties": { "presentation": "modal", "pull-to-refresh-enabled": false } },
|
7
8
|
{ "patterns": ["^/$"], "properties": { "presentation": "replace-all" } },
|
8
|
-
{ "patterns": ["/new$", "/edit$", "/signin$", "/strada-form$"], "properties": { "presentation": "modal" } },
|
9
9
|
{ "patterns": ["/numbers$"], "properties": { "view-controller": "numbers" } }
|
10
10
|
]
|
11
11
|
}
|
@@ -22,9 +22,14 @@ class TurboNavigationController : UINavigationController {
|
|
22
22
|
}
|
23
23
|
|
24
24
|
// - Create view controller appropriate for url/properties
|
25
|
-
// - Navigate to that with the correct presentation
|
26
25
|
let viewController = makeViewController(for: url, properties: properties)
|
27
|
-
|
26
|
+
|
27
|
+
// - Navigate to that with the correct presentation
|
28
|
+
if session.topmostVisitable?.visitableURL == url {
|
29
|
+
navigate(to: viewController, action: .replace, properties: properties)
|
30
|
+
} else {
|
31
|
+
navigate(to: viewController, action: options.action, properties: properties)
|
32
|
+
}
|
28
33
|
|
29
34
|
// Initiate the visit with Turbo
|
30
35
|
if isVisitable(properties) {
|
@@ -43,8 +48,8 @@ extension TurboNavigationController {
|
|
43
48
|
return properties["presentation"] as? String == "modal"
|
44
49
|
}
|
45
50
|
|
46
|
-
private func
|
47
|
-
return properties["presentation"] as? String == "
|
51
|
+
private func isBack(_ properties: PathProperties) -> Bool {
|
52
|
+
return properties["presentation"] as? String == "back"
|
48
53
|
}
|
49
54
|
|
50
55
|
private func isRefresh(_ properties: PathProperties) -> Bool {
|
@@ -71,6 +76,14 @@ extension TurboNavigationController {
|
|
71
76
|
return properties["visitable"] as? Bool ?? true
|
72
77
|
}
|
73
78
|
|
79
|
+
private func isPullToRefreshEnabled(_ properties: PathProperties) -> Bool {
|
80
|
+
return properties["pull-to-refresh-enabled"] as? Bool ?? true
|
81
|
+
}
|
82
|
+
|
83
|
+
private func title(from properties: PathProperties) -> String? {
|
84
|
+
return properties["title"] as? String
|
85
|
+
}
|
86
|
+
|
74
87
|
private func noticeMessage(from url: URL) -> String? {
|
75
88
|
URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems?.first(where: { $0.name == "notice" })?.value
|
76
89
|
}
|
@@ -90,13 +103,16 @@ extension TurboNavigationController {
|
|
90
103
|
}
|
91
104
|
}
|
92
105
|
|
93
|
-
|
106
|
+
let viewController = TurboWebViewController(url: url)
|
107
|
+
viewController.pullToRefreshEnabled = isPullToRefreshEnabled(properties)
|
108
|
+
viewController.title = title(from: properties)
|
109
|
+
return viewController
|
94
110
|
}
|
95
111
|
|
96
112
|
private func navigate(to viewController: UIViewController, action: VisitAction, properties: PathProperties = [:]) {
|
97
113
|
if isModal(properties) {
|
98
114
|
present(UINavigationController(rootViewController: viewController), animated: true)
|
99
|
-
} else if
|
115
|
+
} else if isBack(properties) {
|
100
116
|
popViewController(animated: true)
|
101
117
|
} else if isRefresh(properties) {
|
102
118
|
session.reload()
|
@@ -5,6 +5,8 @@ import WebKit
|
|
5
5
|
|
6
6
|
final class TurboWebViewController: VisitableViewController, ErrorPresenter, BridgeDestination {
|
7
7
|
|
8
|
+
var pullToRefreshEnabled = true
|
9
|
+
|
8
10
|
private lazy var bridgeDelegate: BridgeDelegate = {
|
9
11
|
BridgeDelegate(location: visitableURL.absoluteString, destination: self, componentTypes: BridgeComponent.allTypes)
|
10
12
|
}()
|
@@ -20,6 +22,8 @@ final class TurboWebViewController: VisitableViewController, ErrorPresenter, Bri
|
|
20
22
|
|
21
23
|
navigationItem.backButtonTitle = "Back"
|
22
24
|
|
25
|
+
visitableView.allowsPullToRefresh = pullToRefreshEnabled
|
26
|
+
|
23
27
|
if presentingViewController != nil {
|
24
28
|
navigationItem.leftBarButtonItem = dismissModalButton
|
25
29
|
}
|
@@ -49,6 +53,10 @@ final class TurboWebViewController: VisitableViewController, ErrorPresenter, Bri
|
|
49
53
|
|
50
54
|
// MARK: Visitable
|
51
55
|
|
56
|
+
override func visitableDidRender() {
|
57
|
+
title = title ?? visitableView.webView?.title
|
58
|
+
}
|
59
|
+
|
52
60
|
override func visitableDidActivateWebView(_ webView: WKWebView) {
|
53
61
|
bridgeDelegate.webViewDidBecomeActive(webView)
|
54
62
|
}
|
@@ -14,14 +14,8 @@ final class SceneDelegate: UIResponder {
|
|
14
14
|
private let rootURL2 = <%= name %>.homeURL2
|
15
15
|
|
16
16
|
private var tabBarController: UITabBarController!
|
17
|
-
|
18
|
-
private
|
19
|
-
tabBarController.viewControllers![0] as! TurboNavigationController
|
20
|
-
}()
|
21
|
-
|
22
|
-
private lazy var navigationController2 = {
|
23
|
-
tabBarController.viewControllers![1] as! TurboNavigationController
|
24
|
-
}()
|
17
|
+
private var navigationController1: TurboNavigationController!
|
18
|
+
private var navigationController2: TurboNavigationController!
|
25
19
|
|
26
20
|
private func navigationController() -> TurboNavigationController {
|
27
21
|
tabBarController.selectedViewController as! TurboNavigationController
|
@@ -30,13 +24,13 @@ final class SceneDelegate: UIResponder {
|
|
30
24
|
// MARK: - Setup
|
31
25
|
|
32
26
|
private func configureRootViewController() {
|
33
|
-
|
34
|
-
|
35
|
-
tabBarController = window.rootViewController as? UITabBarController
|
27
|
+
tabBarController = window!.rootViewController as? UITabBarController
|
36
28
|
|
29
|
+
navigationController1 = tabBarController.viewControllers![0] as? TurboNavigationController
|
37
30
|
navigationController1.session = session1
|
38
31
|
navigationController1.modalSession = modalSession
|
39
32
|
|
33
|
+
navigationController2 = tabBarController.viewControllers![1] as? TurboNavigationController
|
40
34
|
navigationController2.session = session2
|
41
35
|
navigationController2.modalSession = modalSession
|
42
36
|
}
|
@@ -88,6 +82,14 @@ extension SceneDelegate: SessionDelegate {
|
|
88
82
|
navigationController().route(url: proposal.url, options: proposal.options, properties: proposal.properties)
|
89
83
|
}
|
90
84
|
|
85
|
+
func session(_ session: Session, openExternalURL url: URL) {
|
86
|
+
if url.host == baseURL.host, !url.pathExtension.isEmpty {
|
87
|
+
navigationController().present(SFSafariViewController(url: url), animated: true)
|
88
|
+
} else {
|
89
|
+
UIApplication.shared.open(url)
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
91
93
|
func session(_ session: Session, didFailRequestForVisitable visitable: Visitable, error: Error) {
|
92
94
|
if let errorPresenter = visitable as? ErrorPresenter {
|
93
95
|
errorPresenter.presentError(error) { session.reload() }
|
@@ -96,58 +98,22 @@ extension SceneDelegate: SessionDelegate {
|
|
96
98
|
}
|
97
99
|
}
|
98
100
|
|
99
|
-
// When a form submission completes in the modal session, we need to
|
100
|
-
// manually clear the snapshot cache in the default session, since we
|
101
|
-
// don't want potentially stale cached snapshots to be used
|
102
101
|
func sessionDidFinishFormSubmission(_ session: Session) {
|
103
102
|
if (session == modalSession) {
|
104
103
|
self.session().clearSnapshotCache()
|
105
104
|
}
|
106
105
|
}
|
107
106
|
|
108
|
-
func sessionDidLoadWebView(_ session: Session) {
|
109
|
-
session.webView.navigationDelegate = self
|
110
|
-
}
|
111
|
-
|
112
107
|
func sessionWebViewProcessDidTerminate(_ session: Session) {
|
113
108
|
session.reload()
|
114
109
|
}
|
115
110
|
}
|
116
111
|
|
117
|
-
extension SceneDelegate: WKNavigationDelegate {
|
118
|
-
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
119
|
-
if navigationAction.navigationType == .linkActivated {
|
120
|
-
// Any link that's not on the same domain as the Turbo root url will go through here
|
121
|
-
// Other links on the domain, but that have an extension that is non-html will also go here
|
122
|
-
// You can decide how to handle those, by default if you're not the navigationDelegate
|
123
|
-
// the Session will open them in the default browser
|
124
|
-
|
125
|
-
let url = navigationAction.request.url!
|
126
|
-
|
127
|
-
// For this demo, we'll load files from our domain in a SafariViewController so you
|
128
|
-
// don't need to leave the app. You might expand this in your app
|
129
|
-
// to open all audio/video/images in a native media viewer
|
130
|
-
if url.host == baseURL.host, !url.pathExtension.isEmpty {
|
131
|
-
let safariViewController = SFSafariViewController(url: url)
|
132
|
-
navigationController().present(safariViewController, animated: true)
|
133
|
-
} else {
|
134
|
-
UIApplication.shared.open(url)
|
135
|
-
}
|
136
|
-
|
137
|
-
decisionHandler(.cancel)
|
138
|
-
} else {
|
139
|
-
decisionHandler(.allow)
|
140
|
-
}
|
141
|
-
}
|
142
|
-
}
|
143
|
-
|
144
112
|
extension SceneDelegate: WKUIDelegate {
|
145
113
|
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
|
146
114
|
let confirm = UIAlertController(title: nil, message: message, preferredStyle: .alert)
|
147
115
|
confirm.addAction(UIAlertAction(title: "Cancel", style: .cancel) { _ in completionHandler(false) })
|
148
|
-
confirm.addAction(UIAlertAction(title: "OK", style: .default) { _ in completionHandler(true) })
|
149
|
-
|
150
|
-
// JavaScript alerts in Turbo Native
|
116
|
+
confirm.addAction(UIAlertAction(title: "OK", style: .default) { _ in completionHandler(true) })
|
151
117
|
navigationController().present(confirm, animated: true)
|
152
118
|
}
|
153
119
|
}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: turbo-native-initializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nixon
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|