forked from quoid/userscripts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathViewController.swift
More file actions
125 lines (116 loc) · 4.89 KB
/
Copy pathViewController.swift
File metadata and controls
125 lines (116 loc) · 4.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import WebKit
private let logger = USLogger(#fileID)
class ViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandlerWithReply, UIDocumentPickerDelegate {
@IBOutlet var webView: WKWebView!
// https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview
override func loadView() {
// https://developer.apple.com/documentation/webkit/wkwebviewconfiguration
let configuration = WKWebViewConfiguration()
// https://developer.apple.com/documentation/webkit/wkwebviewconfiguration/2875766-seturlschemehandler
configuration.setURLSchemeHandler(USchemeHandler(), forURLScheme: AppWebViewUrlScheme)
// https://developer.apple.com/documentation/webkit/wkusercontentcontroller
configuration.userContentController.addScriptMessageHandler(self, contentWorld: .page, name: "controller")
// https://developer.apple.com/documentation/webkit/wkwebview
self.webView = WKWebView(frame: .zero, configuration: configuration)
// https://developer.apple.com/documentation/webkit/wknavigationdelegate
self.webView.navigationDelegate = self
#if DEBUG
// https://webkit.org/blog/13936/enabling-the-inspection-of-web-content-in-apps/
if #available(macOS 13.3, iOS 16.4, tvOS 16.4, *) {
// https://developer.apple.com/documentation/webkit/wkwebview/4111163-inspectable/
self.webView.isInspectable = true
}
logger?.debug("\(#function, privacy: .public) - DEBUG mode: isInspectable = true")
#endif
view = webView
// self.webView.scrollView.isScrollEnabled = false
self.webView.isOpaque = false
let backgroundColor = UIColor.init(red: (47/255.0), green: (51/255.0), blue: (55/255.0), alpha: 1.0)
view.setValue(backgroundColor, forKey: "backgroundColor")
self.webView.backgroundColor = backgroundColor
}
// https://developer.apple.com/documentation/uikit/uiviewcontroller/1621495-viewdidload
override func viewDidLoad() {
super.viewDidLoad()
webView.load(URLRequest(url: URL(string: "\(AppWebViewUrlScheme):///")!))
}
// https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455629-webview
// DOMContentLoaded
// func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
// webView.evaluateJavaScript("")
// }
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
if navigationAction.navigationType == .linkActivated {
guard let url = navigationAction.request.url else {
decisionHandler(.allow)
return
}
// allow registration scheme
if url.scheme == AppWebViewUrlScheme {
decisionHandler(.allow)
return
}
// allow specified url prefixes
// let allowPrefixes = [
// "https://github.com/quoid/userscripts"
// ]
// for prefix in allowPrefixes {
// if url.absoluteString.lowercased().hasPrefix(prefix) {
// decisionHandler(.allow)
// return
// }
// }
// open from external app like safari
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
decisionHandler(.cancel)
return
}
decisionHandler(.allow)
}
decisionHandler(.allow)
}
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) async -> (
Any?,
String?
) {
guard let name = message.body as? String else {
logger?.error("\(#function, privacy: .public) - Userscripts iOS received a message without a name")
return (nil, "bad message body")
}
switch name {
case "INIT":
let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "0.0.0"
let buildNumber = Bundle.main.infoDictionary?["CFBundleVersion"] as? String ?? "0"
return ([
"build": buildNumber,
"version": appVersion,
"directory": getCurrentScriptsDirectoryString(),
], nil)
case "CHANGE_DIRECTORY":
// https://developer.apple.com/documentation/uikit/view_controllers/providing_access_to_directories
logger?.info("\(#function, privacy: .public) - Userscripts iOS has requested to set the readLocation")
let documentPicker = UIDocumentPickerViewController(forOpeningContentTypes: [.folder])
documentPicker.delegate = self
documentPicker.directoryURL = getDocumentsDirectory()
present(documentPicker, animated: true, completion: nil)
break
case "OPEN_DIRECTORY":
guard var components = URLComponents(url: Preferences.scriptsDirectoryUrl, resolvingAgainstBaseURL: true) else {
return (nil, "ScriptsDirectoryUrl malformed")
}
components.scheme = "shareddocuments"
if let url = components.url, UIApplication.shared.canOpenURL(url) {
await UIApplication.shared.open(url)
}
break
default:
return (nil, "Unexpected message body")
}
return (nil, nil)
}
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL) {
Preferences.scriptsDirectoryUrl = url
webView.evaluateJavaScript("webapp.updateDirectory('\(getCurrentScriptsDirectoryString())')")
}
}