Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save bumaociyuan/a37c78cd5503f371b391 to your computer and use it in GitHub Desktop.
Save bumaociyuan/a37c78cd5503f371b391 to your computer and use it in GitHub Desktop.
Yosemite JXA Javascript Function for clicking application sub-menu items
// Click an OS X app sub-menu item
// 2nd argument is an array of arbitrary length (exact menu item labels, giving full path)
// e.g. menuItemClick("InqScribe", ['View', 'Aspect Ratio', 'Use Media Ratio'])
// Note that the menu path (spelling & sequence) must be exactly as in the app
// See menuItemTestClick() below for a slower version which reports any errors
// For OS X 10.10 Yosemite JXA JavaScript for Automation
function menuItemClick(strAppName, lstMenuPath) {
var oApp = Application(strAppName),
lngChain = lstMenuPath.length,
blnResult = false;
if (lngChain > 1) {
var appSE = Application("System Events"),
lstApps = appSE.processes.where({
name: strAppName
}),
procApp = lstApps.length ? lstApps[0] : null;
if (procApp) {
oApp.activate();
var strMenu = lstMenuPath[0],
fnMenu = procApp.menuBars[0].menus.byName(strMenu),
lngLast = lngChain - 1;
for (var i = 1; i < lngLast; i++) {
strMenu = lstMenuPath[i];
fnMenu = fnMenu.menuItems[strMenu].menus[strMenu];
}
fnMenu.menuItems[
lstMenuPath[lngLast]
].click();
blnResult = true;
}
}
return blnResult;
}
// TESTING VERSION: REPORTS ANY ERRORS IN DETAIL OF MENU PATHS
// Click an OS X app sub-menu item
// 2nd argument is an array of arbitrary length (exact menu item labels, giving full path)
//menuItemClick("InqScribe", ['View', 'Aspect Ratio', 'Use Media Ratio'])
function menuItemTestClick(strAppName, lstMenuPath) {
var oApp = Application(strAppName),
lngChain = lstMenuPath.length,
blnResult = false
var blnDebug = false; // edit to 'true' if you want warnings of errors in the path
// (NOTE this kind of checking slows the script, so edit to blnDebug=false for regular use)
if (lngChain > 1) {
var appSE = Application("System Events"),
lstApps = appSE.processes.where({
name: strAppName
}),
procApp = lstApps.length ? lstApps[0] : null;
if (procApp) {
var strMenu = lstMenuPath[0],
strPath = strMenu,
fnMenu = procApp.menuBars[0].menus.byName(strMenu),
lngLast = lngChain - 1,
mnuItem;
if (blnDebug) {
try {
fnMenu.class()
} catch (e) {
throw "Menu Name " + '"' + strMenu + '"' + " not found in " + strAppName
}
}
for (var i = 1; i < lngLast; i++) {
strMenu = lstMenuPath[i];
strPath = strPath + ' > ' + strMenu;
fnMenu = fnMenu.menuItems[strMenu].menus[strMenu];
if (blnDebug) {
try {
fnMenu.class()
} catch (e) {
throw "Menu item " + '"' + strPath + '"' + " not found in " + strAppName
}
}
}
strMenu = lstMenuPath[lngLast];
strPath = strPath + ' > ' + strMenu;
mnuItem = fnMenu.menuItems[strMenu];
if (blnDebug) {
try {
mnuItem.class()
} catch (e) {
throw "Menu item " + '"' + strPath + '"' + " not found in " + strAppName
}
}
oApp.activate()
mnuItem.click();
blnResult = true;
}
}
return blnResult;
}
@RobTrew
Copy link

RobTrew commented Jan 28, 2017

FWIW I've updated the original gist at: https://gist.github.com/RobTrew/575111796d0e3bf9bf3a

@davidRsully
Copy link

How can I pass a menu item with an ellipse in the name?
Ex: Safari - File - Export as PDF...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment