I would like the JXA equivalent of this AppleScript snippet:
tell application "Finder"
# Get path
set currentTarget to target of window 1
set posixPath to (POSIX path of (currentTarget as alias))
# Show dialog
display dialog posixPath buttons {"OK"}
end tell
The closest I got was using the url
property to initialize a Foundation NSURL object and access its fileSystemRepresentation property like so:
// Get path
var finder = Application('Finder')
var currentTarget = finder.finderWindows[0].target()
var fileURLString = currentTarget.url()
// I'd like to get rid of this step
var fileURL = $.NSURL.alloc.initWithString(fileURLString)
var posixPath = fileURL.fileSystemRepresentation
// Show dialog
finder.includeStandardAdditions = true
finder.displayAlert('', {buttons: ['Ok'], message: posixPath})
But this seems unnecessarily complex. Is there a nicer way to get to the POSIX path without using Foundation API or manual string wrangling?
If I naively try this:
finder.finderWindows[0].target().posixPath()
I get this error:
app.startupDisk.folders.byName("Users").folders.byName("kymer").folders.byName("Desktop").posixPath()
--> Error -1728: Can't get object.
This SO answer seems relevant, but I can't seem to adapt it to fit my needs:
App = Application.currentApplication()
App.includeStandardAdditions = true
SystemEvents = Application('System Events')
var pathToMe = App.pathTo(this)
var containerPOSIXPath = SystemEvents.files[pathToMe.toString()].container().posixPath()
Any help would be greatly appreciated!
The fact that such a simple piece of AppleScript code has no straightforward JXA translation is a testament to the sorry state of JXA and macOS automation based on OSA scripting in general:
foo's excellent answer contains helpful background information.
Another pointer is that the last time release notes were published was for OS X 10.11 (El Capitan) (as of this writing, we're on the verge of macOS 10.13 (High Sierra's) release).
This third-party July 2017 blog post announces more broadly that "that question was finally answered at WWDC last month: Apple has abandoned its automation technologies, leaving them to wither and die."
As your own example suggests, among the two dying automation scripting languages AppleScript - despite all its warts - is the more mature, reliable choice.
To solve your problem in JXA, it looks like you've come up with the best approach yourself. Let me package it as a helper function that perhaps easies the pain somewhat - to be clear: such a helper function should NOT be necessary:
// Helper function: Given a Finder window, returns its folder's POSIX path.
// Note: No need for an ObjC.import() statement, because NSURL is
// a Foundation class, and all Foundation classes are implicitly
// available.
function posixPath(finderWin) {
return $.NSURL.alloc.initWithString(finderWin.target.url()).fileSystemRepresentation
}
// Get POSIX path of Finder's frontmost window:
posixPath(Application('Finder').finderWindows[0])
In theory you'd write something like:
finder.finderWindows[0].target({as:"alias"})
but this doesn't work and there's nothing in the documentation to indicate it's supported. But this is SOP for JXA which, like Apple's earlier Scripting Bridge, suffers numerous design flaws and omissions, which never have (and likely never will be) fixed.[1]
FWIW, here's how you do it in Node.js, using NodeAutomation:
$ node
> Object.assign(this,require('nodeautomation'));undefined
> const fn = app('Finder')
> var file = fn.FinderWindows[0].target({asType:k.alias}) // returns File object
> file.toString() // converts File object to POSIX path string
'/Users/jsmith/dev/nodeautomation'
(Be aware that NodeAutomation is a very low-priority project for me, given that Mac Automation looks to be pretty much on its last legs at Apple. Caveat emptor, etc. For non-trivial scripting I strongly recommend sticking to AppleScript as it's the only officially supported solution that actually works right.)
[1] For instance, another JXA limitation is that most apps' move
and duplicate
commands are seriously crippled cos the JXA authors forgot to implement insertion reference forms. (BTW, I reported all these problems before JXA was even released, and appscript had all this stuff solved a decade ago, so they've no excuse for not getting it right either.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With