### Install Browserino using Homebrew Source: https://github.com/alexstrnik/browserino/blob/main/Readme.md This snippet demonstrates how to install Browserino using the Homebrew package manager on macOS. It involves tapping the custom repository and then installing the package. The `--no-quarantine` flag is used to bypass security checks for downloaded applications. ```bash brew tap AlexStrNik/Browserino brew install browserino --no-quarantine ``` -------------------------------- ### Discover Browsers and Open URLs (SwiftUI) Source: https://context7.com/alexstrnik/browserino/llms.txt This snippet demonstrates how to discover installed browsers from configured directories and open URLs in specified applications, including support for incognito/private mode. It relies on the `BrowserUtil` class and `AppKit`. ```swift import AppKit // Discover all installed browsers from configured directories // Preserves the order of previously known browsers let existingBrowsers: [URL] = [] // Previously saved browser list let browsers = BrowserUtil.loadBrowsers(oldBrowsers: existingBrowsers) // Returns: [file:///Applications/Safari.app, file:///Applications/Google Chrome.app, ...] // Open a URL in a specific browser let urls = [URL(string: "https://example.com")!] let safariPath = URL(fileURLWithPath: "/Applications/Safari.app") // Normal mode BrowserUtil.openURL(urls, app: safariPath, isIncognito: false) // Incognito/Private mode (requires privateArgs configuration) // Chrome uses "--incognito", Firefox uses "-private-window" BrowserUtil.openURL(urls, app: safariPath, isIncognito: true) ``` -------------------------------- ### Define Browser Search Directories in Swift Source: https://context7.com/alexstrnik/browserino/llms.txt The `Directory` struct and associated code define file system paths where Browserino searches for browser applications. It includes default locations like `/Applications` and allows for custom paths, persisting these choices using `@AppStorage`. The filtered browsers are determined by checking if their paths start with any of the valid directory paths. ```swift import Foundation // Default browser search location let defaultDirectory = Directory(directoryPath: "/Applications") // Add custom locations for portable or development browsers let customDirectories = [ Directory(directoryPath: "/Applications"), Directory(directoryPath: "/Users/username/Applications"), Directory(directoryPath: "/opt/homebrew/Caskroom") ] // Directories are persisted via @AppStorage @AppStorage("directories") var directories: [Directory] = [] // Browser discovery filters by these directories let urlsForApplications = NSWorkspace.shared.urlsForApplications(toOpen: URL(string: "https:")!) let validDirectories = directories.map { $0.directoryPath } let filteredBrowsers = urlsForApplications.filter { validDirectories.contains { browser in browser.path.hasPrefix($0) } } ``` -------------------------------- ### Keyboard Shortcuts Management in Swift Source: https://context7.com/alexstrnik/browserino/llms.txt Demonstrates how to manage keyboard shortcuts for browsers using @AppStorage. It shows assigning single-key shortcuts to specific browser bundle identifiers and outlines the behavior of various shortcut combinations in the prompt view. ```swift import SwiftUI // Shortcuts are stored as bundle identifier -> key mapping @AppStorage("shortcuts") var shortcuts: [String: String] = [:] // Assign "C" to Chrome, "S" to Safari, "F" to Firefox shortcuts["com.google.Chrome"] = "C" shortcuts["com.apple.Safari"] = "S" shortcuts["org.mozilla.firefox"] = "F" // In the prompt view, shortcuts trigger browser selection: // - Press "C" -> Opens in Chrome // - Press "Shift+C" -> Opens in Chrome (with modifier) // - Press "Shift+Return" -> Opens in selected browser in incognito mode // - Press "Escape" -> Closes prompt without action // - Press "Return" -> Opens in currently highlighted browser // Copy URL shortcuts: // - Command+Option+C (default) or Command+C (alternative) // Copies the URL to clipboard, optionally closes prompt ``` -------------------------------- ### Domain-Specific App Assignment (SwiftUI) Source: https://context7.com/alexstrnik/browserino/llms.txt This snippet shows how to use the `App` struct to assign specific applications to handle URLs from particular domains. It supports subdomain matching and an optional `schemeOverride`. A catch-all app can be configured by leaving the host empty. ```swift import Foundation // Assign Slack app to handle all slack.com URLs let slackApp = App( host: "slack.com", // Matches slack.com and *.slack.com schemeOverride: "slack", // Optional: change URL scheme to "slack://" app: URL(fileURLWithPath: "/Applications/Slack.app") ) // Empty host matches ALL URLs (catch-all app) let catchAllApp = App( host: "", // Matches any URL schemeOverride: "", app: URL(fileURLWithPath: "/Applications/Safari.app") ) // URL host matching logic extension URL { func matchesHost(_ configuredHost: String) -> Bool { if configuredHost.isEmpty { return true } guard let urlHost = self.host()?.lowercased() else { return false } let appHost = configuredHost.lowercased() // Matches exact domain or any subdomain return urlHost == appHost || urlHost.hasSuffix("." + appHost) } } // Example matches for host "slack.com": // - https://slack.com/ -> matches // - https://app.slack.com/ -> matches // - https://api.slack.com/docs -> matches // - https://notslack.com/ -> no match ``` -------------------------------- ### Automatic URL Routing with Regex Rules (SwiftUI) Source: https://context7.com/alexstrnik/browserino/llms.txt This code defines a `Rule` struct for automatically routing URLs based on regular expressions, preventing the selection prompt. Rules are evaluated sequentially, and the first match determines the application. Rules are persisted using `@AppStorage`. ```swift import Foundation // Define a rule to open all GitHub URLs in a specific browser let rule = Rule( regex: "github\.com", app: URL(fileURLWithPath: "/Applications/Firefox.app") ) // Rule matching is case-insensitive // The regex "github\.com" matches: // - https://github.com/user/repo // - https://www.github.com/issues // - http://gist.github.com // Rules are stored in UserDefaults via @AppStorage @AppStorage("rules") var rules: [Rule] = [] rules.append(rule) // When a URL is opened, rules are checked: let urlString = "https://github.com/AlexStrNik/Browserino" for rule in rules { let regex = try? Regex(rule.regex).ignoresCase() if let regex, urlString.firstMatch(of: regex) != nil { BrowserUtil.openURL([URL(string: urlString)!], app: rule.app, isIncognito: false) break } } ``` -------------------------------- ### Settings Import/Export in Swift Source: https://context7.com/alexstrnik/browserino/llms.txt Provides functions to export current user defaults as a filtered dictionary and import settings from a JSON file. It handles filtering out system-specific keys during export and updates user defaults during import. ```swift import Foundation // Export settings to JSON func exportSettings() -> [String: Any] { let defaults = UserDefaults.standard let dictionary = defaults.dictionaryRepresentation() // Filter out system keys let filteredSettings = dictionary.filter { key, _ in !key.contains("NS") && !key.contains("com.apple.") && !key.contains("Apple") && !key.starts(with: "_") } return filteredSettings } // Import settings from JSON func importSettings(from url: URL) { let data = try! Data(contentsOf: url) let settings = try! JSONSerialization.jsonObject(with: data) as! [String: Any] let defaults = UserDefaults.standard for (key, value) in settings { defaults.set(value, forKey: key) } } // Settings JSON structure example: /* { "browsers": [...], // Array of browser URLs "hiddenBrowsers": [...], // Hidden browser URLs "apps": [...], // Domain-app assignments "rules": [...], // Regex routing rules "shortcuts": {...}, // Browser keyboard shortcuts "directories": [...], // Browser search paths "privateArgs": {...}, // Incognito arguments per browser "showInMenuBar": true, "copy_closeAfterCopy": false, "apps_atTop": true } */ ``` -------------------------------- ### Create Floating Browser Selector Panel in Swift Source: https://context7.com/alexstrnik/browserino/llms.txt The `BrowserinoWindow` class is responsible for creating a floating panel that appears when a link is clicked. This panel is positioned near the mouse cursor and automatically hides when it loses focus. The window is configured as a non-activating panel with a transparent titlebar, set to appear above all other windows and on all spaces. ```swift import AppKit // Create the selector window let selectorWindow = BrowserinoWindow() // Window properties: // - Size: 250x200 (minimum, resizable) // - Style: Non-activating panel with transparent titlebar // - Level: Above all other windows (shielding level) // - Behavior: Appears on all spaces, hides on deactivation // Position window near mouse cursor let screen = NSScreen.screens.first!.visibleFrame let mouseLocation = NSEvent.mouseLocation selectorWindow.setFrameOrigin(NSPoint( x: clamp( min: screen.minX + 20, max: screen.maxX - selectorWindow.frame.width - 20, value: mouseLocation.x - selectorWindow.frame.width / 2 ), y: clamp( min: screen.minY + 20, max: screen.maxY - selectorWindow.frame.height - 20, value: mouseLocation.y - (selectorWindow.frame.height - 30) ) )) // Show window and activate NSApplication.shared.activate(ignoringOtherApps: true) selectorWindow.makeKeyAndOrderFront(nil) ``` -------------------------------- ### Handle Custom URL Scheme in Swift Source: https://context7.com/alexstrnik/browserino/llms.txt Browserino registers a custom URL scheme, `browserino://open`, for programmatic URL opening. URLs can be passed base64-encoded within this scheme to prevent parsing issues with special characters. The `AppDelegate` handles decoding these URLs, extracting the original URL for further processing. ```swift import Foundation // Custom scheme format: browserino://open?url= // Encoding a URL for the custom scheme let originalUrl = "https://example.com/path?query=value" let base64Url = Data(originalUrl.utf8).base64EncodedString() let browserinoUrl = "browserino://open?url=\(base64Url)" // Result: browserino://open?url=aHR0cHM6Ly9leGFtcGxlLmNvbS9wYXRoP3F1ZXJ5PXZhbHVl // Decoding in AppDelegate func application(_ application: NSApplication, open urls: [URL]) { let url = urls.first! if url.scheme == "browserino" && url.host == "open" { if let components = URLComponents(url: url, resolvingAgainstBaseURL: false), let queryItems = components.queryItems, let encodedUrl = queryItems.first(where: { $0.name == "url" })?.value, let decodedData = Data(base64Encoded: encodedUrl), let decodedUrlString = String(data: decodedData, encoding: .utf8), let decodedUrl = URL(string: decodedUrlString) { // Process decodedUrl through browser selector } } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.