User Tools

Site Tools


JavaScript_for_Automation

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
JavaScript_for_Automation [2016/02/20 20:33]
ComplexPoint [Attaching reusable names to computations and their results:]
JavaScript_for_Automation [2016/05/09 03:28]
alain JMTX template + add forum links & internal links
Line 1: Line 1:
 ====== Using JavaScript for Automation (JXA) with Keyboard Maestro ====== ====== Using JavaScript for Automation (JXA) with Keyboard Maestro ======
  
-=====Executing ​JavaScript ​from KM – which action ​?=====+===== Which Execute ​JavaScript ​Should You Use? =====
  
 JavaScript, once a language which ran only in web browsers, can now be used in a variety of environments. From Keyboard Maestro you can: JavaScript, once a language which ran only in web browsers, can now be used in a variety of environments. From Keyboard Maestro you can:
  
 1. Run it in Chrome or Safari web pages ('​browser JavaScript'​),​ or 1. Run it in Chrome or Safari web pages ('​browser JavaScript'​),​ or
-2. (in OS X Yosemite onwards) run it in Apple'​s osascript environment,​ for automating applications. ('​JavaScript for Automation',​ or JXA, sometimes JSA in Apple'​s documentation).+2. Run it in Apple'​s osascript environment,​ for automating applications. ('​JavaScript for Automation',​ or JXA, sometimes JSA in Apple'​s documentation), or 
 +3. Run it in Custom HTML Prompt windows.
  
 [[https://​developer.apple.com/​library/​mac/​releasenotes/​InterapplicationCommunication/​RN-JavaScriptForAutomation/​Articles/​Introduction.html|JavaScript for Automation]] (JXA) is a more flexible alternative to AppleScript,​ with a richer set of default libraries for some basics like regexes and URL handling. Its equivalent of AppleScript '​records'​ is more forgiving and much easier to use. JXA is the same fast JavaScript Core language that Safari uses, but it is running in an osascript context: [[https://​developer.apple.com/​library/​mac/​releasenotes/​InterapplicationCommunication/​RN-JavaScriptForAutomation/​Articles/​Introduction.html|JavaScript for Automation]] (JXA) is a more flexible alternative to AppleScript,​ with a richer set of default libraries for some basics like regexes and URL handling. Its equivalent of AppleScript '​records'​ is more forgiving and much easier to use. JXA is the same fast JavaScript Core language that Safari uses, but it is running in an osascript context:
Line 19: Line 20:
 the result will be a listing of all the pre-defined names in JXA's osascript environment. the result will be a listing of all the pre-defined names in JXA's osascript environment.
  
-We can either run this directly from from one of KM's '​Execute a JavaScript for Automation'​ actions, or use an osascript command in an Execute Shell Script action.+We can either run this directly from from one of Keyboard Maestro's '​Execute a JavaScript for Automation'​ actions, or use an osascript command in an Execute Shell Script action.
  
 {{:​undefined:​jxaactionthis.png?​400|}}{{:​undefined:​jxashellactionthis.png?​400|}} {{:​undefined:​jxaactionthis.png?​400|}}{{:​undefined:​jxashellactionthis.png?​400|}}
Line 27: Line 28:
 {{:​chromwinkeys.png?​400|}}{{:​undefined:​jssafariactiondocument.png?​400|}} {{:​chromwinkeys.png?​400|}}{{:​undefined:​jssafariactiondocument.png?​400|}}
  
-Keyboard Maestro''Execute a JavaScript in Safari' ​and 'Execute a JavaScript in Google Chrome' ​actions are for interacting with web pages, whereas JXA is for automating OS X and OS X Applications.+Keyboard Maestro[[action:Execute a JavaScript in Safari|Execute a JavaScript in Safari]] ​and [[action:Execute a JavaScript in Google Chrome|Execute a JavaScript in Google Chrome]] ​actions are for interacting with web pages, the [[action:​Execute a JavaScript in Custom Prompt|Execute a JavaScript in Custom Prompt]] action is for interacting with Custom HTML Prompts, whereas JXA is for automating OS X and OS X Applications ​via the [[action:​Execute a JavaScript For Automation|Execute a JavaScript For Automation]] action.
  
 =====The basics – AppleScript and JavaScript for Automation side by side===== =====The basics – AppleScript and JavaScript for Automation side by side=====
Line 35: Line 36:
 The simplest scripts evaluate an expression and return its value. ​ The simplest scripts evaluate an expression and return its value. ​
  
-**NB** ​KM Maestro can only make use of values returned as (or converted to) a string – a KM variable is always a string of some kind. This means that:+**NB** ​Keyboard ​Maestro can only make use of values returned as (or converted to) a string – a Keyboard Maestro ​variable is always a string of some kind. This means that:
  
 - If the result of an evaluation is not a string (or something simple like a number, that can automatically be converted to a string), the action may puzzle you by appearing to produce no result. - If the result of an evaluation is not a string (or something simple like a number, that can automatically be converted to a string), the action may puzzle you by appearing to produce no result.
 - It's a good idea to test your action code first in (El Capitan or Yosemite) Script Editor, which shows all results, whatever their type, including error messages. - It's a good idea to test your action code first in (El Capitan or Yosemite) Script Editor, which shows all results, whatever their type, including error messages.
  
-The following all return the same number to KM (in string format, and at a slightly higher level of precision – more decimal points – from JavaScript).+The following all return the same number to Keyboard Maestro ​(in string format, and at a slightly higher level of precision – more decimal points – from JavaScript).
  
 ^ AppleScript ​   ^ JXA  ^ ^ AppleScript ​   ^ JXA  ^
Line 61: Line 62:
 | <code applescript>​count of documents of application "​TextEdit" ​   </​code>​ | <code javascript>​Application("​TextEdit"​).documents.length ​   </​code>​ | | <code applescript>​count of documents of application "​TextEdit" ​   </​code>​ | <code javascript>​Application("​TextEdit"​).documents.length ​   </​code>​ |
  
-====Attaching reusable ​names to computations ​and their results:====+====Assigning ​names to functions ​and procedures:====
  
 If we often need to calculate the [[https://​en.wikipedia.org/​wiki/​Golden_ratio|Golden Ratio]], we can attach a name to its computation,​ and reuse it by that name. Nameable computations are called '​handlers'​ in AppleScript,​ and '​functions'​ in JavaScript. If we often need to calculate the [[https://​en.wikipedia.org/​wiki/​Golden_ratio|Golden Ratio]], we can attach a name to its computation,​ and reuse it by that name. Nameable computations are called '​handlers'​ in AppleScript,​ and '​functions'​ in JavaScript.
  
-===Named ​computations – handlers and functions===+===Named ​AS 'handlers' ​and JS functions===
  
 ^ AppleScript ​   ^ JXA  ^ ^ AppleScript ​   ^ JXA  ^
Line 105: Line 106:
 In JavaScript, however, a function only returns what you ask it to. If you don't use the **return** keyword, the function evaluates to the special value ''​undefined'',​ and your Keyboard Maestro action will just get an empty string. Always include a **return** line. In JavaScript, however, a function only returns what you ask it to. If you don't use the **return** keyword, the function evaluates to the special value ''​undefined'',​ and your Keyboard Maestro action will just get an empty string. Always include a **return** line.
  
-===Parameters / arguments for named computations===+===Parameters / arguments for name functions===
  
 If you are building a well-proportioned temple or table, you will probably want to multiply the Golden Ratio by something else, so a named computation with a variable '​parameter'​ or '​argument'​ might make sense. If you are building a well-proportioned temple or table, you will probably want to multiply the Golden Ratio by something else, so a named computation with a variable '​parameter'​ or '​argument'​ might make sense.
Line 140: Line 141:
 JavaScript is relaxed about whether we supply an argument or not. If we don't, the name ''​n''​ will have the special value ''​undefined'',​ which takes on the value ''​false''​ in a logical expression. Above we are using the [[https://​developer.mozilla.org/​en-US/​docs/​Web/​JavaScript/​Reference/​Operators/​Logical_Operators|JavaScript logical operator OR ( || )]] to attach the name n to the value 1 if no argument has been supplied. JavaScript is relaxed about whether we supply an argument or not. If we don't, the name ''​n''​ will have the special value ''​undefined'',​ which takes on the value ''​false''​ in a logical expression. Above we are using the [[https://​developer.mozilla.org/​en-US/​docs/​Web/​JavaScript/​Reference/​Operators/​Logical_Operators|JavaScript logical operator OR ( || )]] to attach the name n to the value 1 if no argument has been supplied.
  
-===Named results ​of computations ​– '​variables'​ which hold values===+===Named results – '​variables'​ which hold values===
  
 In addition to reusable names for particular computations and their arguments, we can also give names to the results of computations. Once a result is stored in a named variable, we can reuse it without having to recalculate it. In addition to reusable names for particular computations and their arguments, we can also give names to the results of computations. Once a result is stored in a named variable, we can reuse it without having to recalculate it.
Line 208: Line 209:
 ====Indexing by number: AS lists ⇄ JS arrays=== ====Indexing by number: AS lists ⇄ JS arrays===
  
-==Length== 
 ^ Length of AppleScript '​list'​ ^ JavaScript '​array'​ length ​ ^ ^ Length of AppleScript '​list'​ ^ JavaScript '​array'​ length ​ ^
 |<code applescript>​length of ¬ |<code applescript>​length of ¬
Line 215: Line 215:
  
 // 3</​code>​| ​ // 3</​code>​| ​
- 
-==Arbitrary nesting of lists within lists== 
 ^ Nested AppleScript list  ^ Nested JS array  ^ ^ Nested AppleScript list  ^ Nested JS array  ^
 |<code applescript>​length of ¬ |<code applescript>​length of ¬
Line 223: Line 221:
 .length .length
 // 2  (JS ignores white space and new lines)</​code>​| ​ // 2  (JS ignores white space and new lines)</​code>​| ​
- 
-==Extracting parts of lists== 
 ^ AppleScript lists are 1-based ​ ^ JavaScript arrays are 0-based ​ ^ ^ AppleScript lists are 1-based ​ ^ JavaScript arrays are 0-based ​ ^
 |<code applescript>​items 1 thru 3 of ¬ |<code applescript>​items 1 thru 3 of ¬
Line 237: Line 233:
 .slice(-3) .slice(-3)
 // ["​beta",​ "​gamma",​ "​delta"​]</​code>​| ​ // ["​beta",​ "​gamma",​ "​delta"​]</​code>​| ​
- +^ AppleScript ​concatenation ​ ^ JavaScript ​concatenation ​^
-==Concatenating lists== +
- +
-^ AppleScript ​ ^ JavaScript ​ ^+
 |<code applescript>​{"​alpha",​ "​beta"​} & {"​gamma",​ "​delta"​} |<code applescript>​{"​alpha",​ "​beta"​} & {"​gamma",​ "​delta"​}
  
Line 246: Line 239:
 .concat(["​gamma",​ "​delta"​]) .concat(["​gamma",​ "​delta"​])
 // ["​alpha",​ "​beta",​ "​gamma",​ "​delta"​]</​code>​| ​ // ["​alpha",​ "​beta",​ "​gamma",​ "​delta"​]</​code>​| ​
- +^ AppleScript ​join() (user-defined) ​ ^ JavaScript ​join() (built in) ^
-==Joining list parts up with connecting strings== +
- +
-^ AppleScript ​ ^ JavaScript ​ ^+
 |<code applescript>​join("​ -> ", {"​Sun",​ "​Mon",​ "​Tue"​}) |<code applescript>​join("​ -> ", {"​Sun",​ "​Mon",​ "​Tue"​})
  
Line 264: Line 254:
  
 // "Sun -> Mon -> Tue // "Sun -> Mon -> Tue
- 
- 
- 
- 
  
  
Line 274: Line 260:
 //  of JavaScript arrays //  of JavaScript arrays
 </​code>​| ​ </​code>​| ​
 +
 ====Indexing by name – AS records and JS objects==== ====Indexing by name – AS records and JS objects====
  
 to follow ... to follow ...
-====Structuring ​computations ​– branching, ​repetition, and nested composition====+ 
 +====Structuring ​scripts ​– branching, ​nestingmapping, filtering ​and reducing====
  
 to follow ... to follow ...
Line 284: Line 272:
  
 to follow ... to follow ...
 +
 +=====Accessing Keyboard Maestro Variables=====
 +
 +You can access Keyboard Maestro variables (7.1+) from JXA scripts using the Keyboard Maestro Engine application.
 +
 +<code javascript>​
 +var kme = Application("​Keyboard Maestro Engine"​);​
 +kme.getvariable('​Var'​);​
 +kme.setvariable('​Var',​ { to: "Hello World!"​ });
 +</​code>​
 +
 +JXA can get a list of all variables as described on the [forum](https://​forum.keyboardmaestro.com/​t/​using-km-variables-in-yosemite-javascript-for-applications-jxa/​889) and those methods also provide more convoluted ways to access variables for versions prior to 7.1.
  
 =====The Automation interface===== =====The Automation interface=====
Line 314: Line 314:
  
 to follow ... to follow ...
 +
 +===== See Also =====
 +
 +----
 +
 +=== Actions ===
 +
 +* [[action:​Execute a JavaScript For Automation|Execute a JavaScript For Automation]]
 +* [[action:​Execute a JavaScript in Custom Prompt|Execute a JavaScript in Custom Prompt]]
 +* [[action:​Execute a JavaScript in Google Chrome|Execute a JavaScript in Google Chrome]]
 +* [[action:​Execute a JavaScript in Safari|Execute a JavaScript in Safari]]
 +* [[:​Actions|See all Actions]]
 +
 +----
 +
 +==== Forum ====
 +
 +- [[https://​forum.keyboardmaestro.com/​t/​using-km-variables-in-yosemite-javascript-for-applications-jxa/​889|Using KM variables in Yosemite Javascript for Applications (JXA)]]
 +- [[https://​forum.keyboardmaestro.com/​t/​how-to-change-safari-web-inspector-font/​3655|How to Change Safari Web Inspector Font]]
 +
 +- [[https://​www.google.fr/​search?​q=site:​forum.keyboardmaestro.com+JavaScript+for+Automation+JXA|Keyboard Maestro Forum topics about JavaScript for Automation]]
JavaScript_for_Automation.txt · Last modified: 2019/01/12 12:43 by JMichaelTX