11// Designed with ❤️ and 🤖 by Ctrl.
2- // Made specifically for your Mac. Try Weave Touch for the iPad!
2+ // Made specifically for your Mac. Try Weave Touch for your iPhone and iPad!
33
44import SwiftUI
55import WebKit
@@ -19,17 +19,33 @@ extension NSColor {
1919 }
2020}
2121
22- // Sets up BrowserView and does basic customizations
22+ // Initializes BrowserView's variables for basic setup
2323struct BrowserView : View {
2424 @State private var webView = WKWebView ( )
2525 @State private var URLString = " "
2626 @State private var pageTitle = " Weave "
2727 @State private var faviconImage : NSImage ?
28- @State private var userAgent = " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.3.1 Safari/605.1.15 "
29-
28+ @State private var userAgent : String = {
29+ // All this stuff is to automatically fetch 3 key values to automatically build a user agent, the WebKit version, Safari version (based on current OS), and a default user agent given by WKWebView.
30+ let defaultUserAgent = WKWebView ( ) . value ( forKey: " userAgent " )
31+ let sysVersion = ProcessInfo . processInfo. operatingSystemVersion
32+ var safariVersion = " \( sysVersion. majorVersion + 3 ) . \( sysVersion. minorVersion) . \( sysVersion. patchVersion) "
33+ var webKitVersion = " "
34+ if let userAgentString = defaultUserAgent as? String {
35+ if let startIndex = userAgentString. range ( of: " AppleWebKit/ " ) ? . upperBound {
36+ let versionSubstring = userAgentString [ startIndex... ]
37+ if let endIndex = versionSubstring. firstIndex ( of: " " ) ?? versionSubstring. firstIndex ( of: " / " ) {
38+ webKitVersion = String ( versionSubstring [ ..< endIndex] )
39+ }
40+ }
41+ }
42+ return " \( defaultUserAgent ?? " Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/621.4.20 (KHTML, like Gecko) Weave/FallbackUserAgent " ) Version/ \( safariVersion) Safari/ \( webKitVersion) "
43+ } ( )
44+
3045 var body : some View {
3146 WebView ( webView: webView, pageTitle: $pageTitle, URLString: $URLString, faviconImage: $faviconImage, userAgent: $userAgent)
3247 . onAppear {
48+ print ( userAgent)
3349 // CSS Style Injection
3450 var sysAccent = NSColor . systemAccentColor. hexString
3551 let styleSheet = """
@@ -74,13 +90,14 @@ struct BrowserView: View {
7490
7591 // Toolbar with keyboard shortcuts and tooltips
7692 . toolbar ( id: " toolbar " ) {
93+
7794 // Back button (cmd + ←)
7895 ToolbarItem ( id: " back " , placement: . navigation) {
7996 Button ( action: goBack) {
8097 Label ( " Back " , systemImage: " chevron.left " )
8198 }
8299 . help ( " Go back " )
83- . keyboardShortcut ( KeyEquivalent . leftArrow, modifiers: [ . command] )
100+ . keyboardShortcut ( . leftArrow, modifiers: [ . command] )
84101 . disabled ( !webView. canGoBack)
85102 }
86103
@@ -90,7 +107,7 @@ struct BrowserView: View {
90107 Label ( " Forward " , systemImage: " chevron.right " )
91108 }
92109 . help ( " Go forward " )
93- . keyboardShortcut ( KeyEquivalent . rightArrow, modifiers: [ . command] )
110+ . keyboardShortcut ( . rightArrow, modifiers: [ . command] )
94111 . disabled ( !webView. canGoForward)
95112 }
96113
@@ -140,7 +157,7 @@ struct BrowserView: View {
140157 Spacer ( )
141158 }
142159
143- // Download button (cmd + shift + d )
160+ // Download button (cmd + s )
144161 ToolbarItem ( id: " download " , placement: . primaryAction, showsByDefault: false ) {
145162 Button ( action: downloadPage) {
146163 Label ( " Download Page " , systemImage: " square.and.arrow.down " )
@@ -174,12 +191,14 @@ struct BrowserView: View {
174191 }
175192
176193 // Sets up functions for webpage commands
194+ // Copies URL to clipboard
177195 private func copyURL( ) {
178196 let pasteboard = NSPasteboard . general
179197 pasteboard. declareTypes ( [ . string] , owner: nil )
180198 pasteboard. setString ( URLString, forType: . string)
181199 }
182200
201+ // Goes back a page and then refreshes (to load new title and favicon data)
183202 private func goBack( ) {
184203 if webView. canGoBack {
185204 webView. goBack ( )
@@ -190,6 +209,7 @@ struct BrowserView: View {
190209 }
191210 }
192211
212+ // Goes forward a page and then refreshes (to load new title and favicon data)
193213 private func goForward( ) {
194214 if webView. canGoForward {
195215 webView. goForward ( )
@@ -200,10 +220,12 @@ struct BrowserView: View {
200220 }
201221 }
202222
223+ // Simply reloads webView
203224 private func refresh( ) {
204225 webView. reload ( )
205226 }
206227
228+ // Shares URL with macOS default Share Sheet
207229 private func shareURL( _ URLString: String ) {
208230 guard let url = URL ( string: URLString) else {
209231 print ( " Invalid URL " )
@@ -216,20 +238,28 @@ struct BrowserView: View {
216238 sharingServicePicker. show ( relativeTo: webView. bounds, of: webView, preferredEdge: . minY)
217239 }
218240
241+ // Checks if URL is valid, if it is, it loads, if it isn't, it does not
219242 private func loadURL( ) {
220243 let trimmedURLString = URLString . trimmingCharacters ( in: . whitespacesAndNewlines)
221- if trimmedURLString. contains ( " . " ) {
222- // Contains a dot, likely a URL
223- if let url = URL ( string: addHttpIfNeeded ( trimmedURLString) ) {
224- let request = URLRequest ( url: url)
225- webView. load ( request)
244+ // Finds final dot in string
245+ if let lastDotIndex = trimmedURLString. lastIndex ( of: " . " ) {
246+ let afterLastDotIndex = trimmedURLString. index ( after: lastDotIndex)
247+ // Check if there are characters following the last period
248+ if afterLastDotIndex < trimmedURLString. endIndex {
249+ // Characters following the last period, so assume it's a domain
250+ if let url = URL ( string: addHTTPIfNeeded ( trimmedURLString) ) {
251+ let request = URLRequest ( url: url)
252+ webView. load ( request)
253+ return
254+ }
226255 }
227- } else {
228- // No dot, treat as search query
229- search ( )
230256 }
257+ // No more than 1 character following final period, likely a search query
258+ search ( )
231259 }
232260
261+
262+ // Function to search with Google
233263 private func search( ) {
234264 guard let searchQuery = URLString . addingPercentEncoding ( withAllowedCharacters: . urlQueryAllowed) else { return }
235265 if let searchURL = URL ( string: " https://google.com/search?q= \( searchQuery) " ) {
@@ -238,14 +268,16 @@ struct BrowserView: View {
238268 }
239269 }
240270
241- private func addHttpIfNeeded( _ URLString: String ) -> String {
271+ // Adds https:// to URLs that don't have it
272+ private func addHTTPIfNeeded( _ URLString: String ) -> String {
242273 if URLString . hasPrefix ( " http:// " ) || URLString . hasPrefix ( " https:// " ) {
243274 return URLString
244275 } else {
245276 return " https:// \( URLString) "
246277 }
247278 }
248279
280+ // Downloads HTML file of page source to ~/Downloads folder
249281 private func downloadPage( ) {
250282 webView. evaluateJavaScript ( " document.URL " ) { ( result, error) in
251283 if let urlString = result as? String , let url = URL ( string: urlString) {
0 commit comments