@@ -29,13 +29,15 @@ protocol BrowserInterface {
2929 func getCurrentURL( ) -> String ?
3030
3131 /// Checks if the current active tab/window is in private browsing mode.
32- /// - Returns: true if private browsing is detected, false otherwise
33- func isInPrivateBrowsingMode( ) -> Bool
32+ /// - Returns: true if private browsing is detected, false if regular browsing is detected, nil if detection failed
33+ func isInPrivateBrowsingMode( ) -> Bool ?
3434}
3535
3636/// Base implementation providing common AppleScript execution functionality.
3737/// Browser-specific classes can inherit from this to get shared AppleScript execution logic.
3838class BaseBrowser : BrowserInterface {
39+ private static let appleScriptTimeoutSeconds = 3
40+
3941 let bundleId : String
4042 let displayName : String
4143
@@ -60,6 +62,8 @@ class BaseBrowser: BrowserInterface {
6062 // Handle permission-related errors
6163 if scriptResult. errorCode == - 1743 || scriptResult. errorCode == - 1744 {
6264 PermissionManager . shared. handleBrowserPermissionResult ( success: false )
65+ } else if scriptResult. errorCode == - 1712 {
66+ logger. debug ( " Browser ( \( self . displayName) ) AppleScript timed out " )
6367 } else if scriptResult. errorCode == - 1719 {
6468 // Invalid index - transient race condition when tabs/windows change during polling.
6569 // Silently ignore; the next polling cycle will succeed.
@@ -85,7 +89,7 @@ class BaseBrowser: BrowserInterface {
8589 }
8690
8791 /// Default implementation - subclasses should override
88- func isInPrivateBrowsingMode( ) -> Bool {
92+ func isInPrivateBrowsingMode( ) -> Bool ? {
8993 fatalError ( " Subclasses must implement isInPrivateBrowsingMode() " )
9094 }
9195
@@ -95,7 +99,12 @@ class BaseBrowser: BrowserInterface {
9599 /// - Returns: AppleScriptResult containing the result, error code, and error details
96100 internal func executeAppleScript( _ script: String ) -> AppleScriptResult {
97101 var error : NSDictionary ?
98- let appleScript = NSAppleScript ( source: script)
102+ let wrappedScript = """
103+ with timeout of \( Self . appleScriptTimeoutSeconds) seconds
104+ \( script)
105+ end timeout
106+ """
107+ let appleScript = NSAppleScript ( source: wrappedScript)
99108 let result = appleScript? . executeAndReturnError ( & error)
100109
101110 let errorCode = error ? [ " NSAppleScriptErrorNumber " ] as? Int
0 commit comments