Run JavaScript For Automation (JXA) snippets from AppleScript

Many users think that JXA snippets cannot be embedded in applescripts. I wrote 3 examples here to show that this is quite possible.

My examples are simple and don’t give JXA any advantage over AppleseScript. So if someone adds an example illustrating the advantage of JXA, that would be very helpful.

.
Example 1: change application’s front window borders using JXA


-- Change application's front window borders using JXA
setWindowBounds_JXA("Safari") of me

on setWindowBounds_JXA(appName)
	do shell script "osascript -l JavaScript -e \"function run() {
  const systemEvents = Application('System Events');
  const p = systemEvents.processes().find(ap => ap.name() === '" & appName & "');
  console.log(p.name());
  const app = Application(p.name());
  const window = app.windows[0];
  window.bounds = {
    x: 30,
    y: 23,
    width: 1000,
    height: 500,
  };
  app.activate();
}\""
end setWindowBounds_JXA

.

Example 2: Get current date with formatting using JXA


-- Get current date with formatting using JXA
set currentDate to getCurrentDateObject_JXA() of me

on getCurrentDateObject_JXA()
	return date (do shell script "osascript -l JavaScript -e \"function run(input, parameters) { 

   ObjC.import('Cocoa')
   rightNow = $.NSDate.date
   dtFormatter = $.NSDateFormatter.alloc.init
   dtFormatter.dateStyle = $.NSDateFormatterFullStyle
   dtFormatter.timeStyle = $.NSDateFormatterMediumStyle

   formattedDate = dtFormatter.stringFromDate(rightNow)

   return ObjC.unwrap(formattedDate)
}
\"")
end getCurrentDateObject_JXA

.

Example 3: add new sheet to Numbers.app document using JXA


-- Add new sheet to Numbers.app document using JXA
addSheetToNumbersDocument_JXA("\"Test\" sheet") of me

on addSheetToNumbersDocument_JXA(newSheet)
	do shell script "osascript -l JavaScript -e \"function run (){
  const app = Application('Numbers');
  const doc = app.documents[0];
  const sheet = app.Sheet({name: '" & newSheet & "'});
  doc.sheets.push(sheet);
}\""
end addSheetToNumbersDocument_JXA

In the last example the Numbers workbook should be opened before running the script.

1 Like

A better way would be to use run script:

to uppercase(s as text)
	run script (the quoted form of s) & ¬
		".toUpperCase();" in "JavaScript"
end uppercase

uppercase("hello") --> "HELLO"

Thanks @CK,

Your comment is helpful and perfect. I already somewhere met with a script similar to yours, but did not give due attention. In general, now it is clear that my hacking :smiley: with osascript does not give any advantages.

The performance of a regular method with a run script (from @CK) is better than mine.

The next script using run script is 1.4 times faster than one using osascript.


on setWindowBounds_JXA(appName as text)
	run script "function run() {
const systemEvents = Application('System Events');
const p = systemEvents.processes().find(ap => ap.name() === '" & appName & "');
console.log(p.name());
const app = Application(p.name());
const window = app.windows[0];
window.bounds = {
x: 30,
y: 23,
width: 1000,
height: 500,
};
app.activate();
}" in "JavaScript"
end setWindowBounds_JXA

setWindowBounds_JXA("Safari")
2 Likes