Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@

# Prettier 3.0.3
acc35fbec38d72968b735826c6807793a2054aed

# Xcode swift indent replace spaces to tabs
962c4d81879e85362a5f878889d3aa869f4e6961
130 changes: 65 additions & 65 deletions xcode/App-Mac/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,69 +2,69 @@ import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
private var window: NSWindow!
private var windowForego = false
private var windowLoaded = false
@IBOutlet weak var enbaleNativeLogger: NSMenuItem!
func application(_ application: NSApplication, open urls: [URL]) {
// if open panel is already open, stop processing the URL scheme
if NSApplication.shared.keyWindow?.accessibilityIdentifier() == "open-panel" { return }
for url in urls {
if url.host == "changesavelocation" {
// avoid opening the panel repeatedly and playing unnecessary warning sounds
if NSApplication.shared.keyWindow?.identifier?.rawValue == "changeSaveLocation" { continue }
if windowLoaded {
let viewController = window.contentViewController as? ViewController
viewController?.changeSaveLocation(nil)
} else {
windowForego = true
schemeChangeSaveLocation()
}
}
}
}
func applicationDidFinishLaunching(_ aNotification: Notification) {
// Initialize menu items
enbaleNativeLogger.state = Preferences.enableLogger ? .on : .off
if windowForego { return }
let storyboard = NSStoryboard(name: "View", bundle: Bundle.main)
let windowController = storyboard.instantiateInitialController() as! NSWindowController
// let viewController = windowController.contentViewController as! ViewController
window = windowController.window
window.setIsVisible(true)
windowLoaded = true
}
func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
return true
}
func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
@IBAction func enableLogger(_ sender: NSMenuItem) {
if sender.state == .on {
Preferences.enableLogger = false
sender.state = .off
} else {
Preferences.enableLogger = true
sender.state = .on
}
}
@IBAction func applicationHelp(_ sender: NSMenuItem) {
if let url = URL(string: "https://github.com/quoid/userscripts") {
NSWorkspace.shared.open(url)
}
}

private var window: NSWindow!
private var windowForego = false
private var windowLoaded = false

@IBOutlet weak var enbaleNativeLogger: NSMenuItem!

func application(_ application: NSApplication, open urls: [URL]) {
// if open panel is already open, stop processing the URL scheme
if NSApplication.shared.keyWindow?.accessibilityIdentifier() == "open-panel" { return }
for url in urls {
if url.host == "changesavelocation" {
// avoid opening the panel repeatedly and playing unnecessary warning sounds
if NSApplication.shared.keyWindow?.identifier?.rawValue == "changeSaveLocation" { continue }
if windowLoaded {
let viewController = window.contentViewController as? ViewController
viewController?.changeSaveLocation(nil)
} else {
windowForego = true
schemeChangeSaveLocation()
}
}
}
}

func applicationDidFinishLaunching(_ aNotification: Notification) {
// Initialize menu items
enbaleNativeLogger.state = Preferences.enableLogger ? .on : .off
if windowForego { return }
let storyboard = NSStoryboard(name: "View", bundle: Bundle.main)
let windowController = storyboard.instantiateInitialController() as! NSWindowController
// let viewController = windowController.contentViewController as! ViewController
window = windowController.window
window.setIsVisible(true)
windowLoaded = true
}

func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
return true
}

func applicationWillTerminate(_ aNotification: Notification) {
// Insert code here to tear down your application
}

func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}

@IBAction func enableLogger(_ sender: NSMenuItem) {
if sender.state == .on {
Preferences.enableLogger = false
sender.state = .off
} else {
Preferences.enableLogger = true
sender.state = .on
}
}

@IBAction func applicationHelp(_ sender: NSMenuItem) {
if let url = URL(string: "https://github.com/quoid/userscripts") {
NSWorkspace.shared.open(url)
}
}

}
102 changes: 51 additions & 51 deletions xcode/App-Mac/Functions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,67 @@ import SafariServices
private let logger = USLogger(#fileID)

func getSaveLocationURL() -> URL {
return Preferences.scriptsDirectoryUrl
return Preferences.scriptsDirectoryUrl
}

func setSaveLocationURL(url: URL) -> Bool {
guard FileManager.default.isWritableFile(atPath: url.path) else {
let alert = NSAlert()
alert.messageText = "Can not write to path. Choose a different path."
alert.runModal()
return false
}
Preferences.scriptsDirectoryUrl = url
return Preferences.scriptsDirectoryUrl == url
guard FileManager.default.isWritableFile(atPath: url.path) else {
let alert = NSAlert()
alert.messageText = "Can not write to path. Choose a different path."
alert.runModal()
return false
}
Preferences.scriptsDirectoryUrl = url
return Preferences.scriptsDirectoryUrl == url
}

func sendExtensionMessage(name: String, userInfo: [String : Any]? = nil, completion: ((Error?) -> Void)? = nil) {
SFSafariApplication.dispatchMessage(
withName: name,
toExtensionWithIdentifier: extIdentifier,
userInfo: userInfo
) { error in // always be called
if error != nil {
debugPrint("Message attempted. Error info: \(String.init(describing: error))")
}
if let userHandle = completion { userHandle(error) }
}
SFSafariApplication.dispatchMessage(
withName: name,
toExtensionWithIdentifier: extIdentifier,
userInfo: userInfo
) { error in // always be called
if error != nil {
debugPrint("Message attempted. Error info: \(String.init(describing: error))")
}
if let userHandle = completion { userHandle(error) }
}
}

func changeSaveLocationPanel(directoryURL: URL? = nil) -> NSOpenPanel {
let panel = NSOpenPanel()
panel.allowsMultipleSelection = false
panel.canChooseDirectories = true
panel.canCreateDirectories = true
panel.canChooseFiles = false
if directoryURL != nil {
panel.directoryURL = directoryURL
}
panel.title = "Change Save Location - Userscripts"
panel.identifier = NSUserInterfaceItemIdentifier("changeSaveLocation")
return panel
let panel = NSOpenPanel()
panel.allowsMultipleSelection = false
panel.canChooseDirectories = true
panel.canCreateDirectories = true
panel.canChooseFiles = false
if directoryURL != nil {
panel.directoryURL = directoryURL
}
panel.title = "Change Save Location - Userscripts"
panel.identifier = NSUserInterfaceItemIdentifier("changeSaveLocation")
return panel
}

func schemeChangeSaveLocation() {
let saveLocationURL = getSaveLocationURL()
let panel = changeSaveLocationPanel(directoryURL: saveLocationURL)
// shows the path selection panel
let response = panel.runModal()
// check if clicked open button and there is a valid result
guard response == .OK, let url: URL = panel.urls.first else { return }
// revoke implicitly starts security-scoped access
defer { url.stopAccessingSecurityScopedResource() }
// check if path has indeed changed
if url.absoluteString == saveLocationURL.absoluteString { return }
// try set new save location path to bookmark
guard setSaveLocationURL(url: url) else { return }
// use semaphore to ensure the async func executed before app exits
let semaphore = DispatchSemaphore(value: 0)
// notify browser extension of relevant updates
sendExtensionMessage(
name: "SAVE_LOCATION_CHANGED",
userInfo: ["saveLocation": url.absoluteString.removingPercentEncoding ?? url.absoluteString],
completion: { _ in semaphore.signal() }
)
semaphore.wait()
let saveLocationURL = getSaveLocationURL()
let panel = changeSaveLocationPanel(directoryURL: saveLocationURL)
// shows the path selection panel
let response = panel.runModal()
// check if clicked open button and there is a valid result
guard response == .OK, let url: URL = panel.urls.first else { return }
// revoke implicitly starts security-scoped access
defer { url.stopAccessingSecurityScopedResource() }
// check if path has indeed changed
if url.absoluteString == saveLocationURL.absoluteString { return }
// try set new save location path to bookmark
guard setSaveLocationURL(url: url) else { return }
// use semaphore to ensure the async func executed before app exits
let semaphore = DispatchSemaphore(value: 0)
// notify browser extension of relevant updates
sendExtensionMessage(
name: "SAVE_LOCATION_CHANGED",
userInfo: ["saveLocation": url.absoluteString.removingPercentEncoding ?? url.absoluteString],
completion: { _ in semaphore.signal() }
)
semaphore.wait()
}
Loading