JXA_JavaScript_for_Applications
Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| JXA_JavaScript_for_Applications [2016/01/06 00:46] – [The ObjC interface] ComplexPoint | JXA_JavaScript_for_Applications [2016/01/07 02:17] (current) – deleted in favor of JavaScript for Automation peternlewis | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Using JavaScript for Automation (JXA) with Keyboard Maestro ====== | ||
| - | =====Executing JavaScript from KM – which action ?===== | ||
| - | |||
| - | 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 (' | ||
| - | 2. (in OS X Yosemite onwards) run it in Apple' | ||
| - | |||
| - | [[https:// | ||
| - | |||
| - | 1. With access to the functions and constants of an Automation object, and | ||
| - | 2. with additional access to a lot of low-level Apple system functions through the ObjC object. | ||
| - | |||
| - | The first script to try in JXA consists of just one word: | ||
| - | |||
| - | `this` | ||
| - | |||
| - | 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 ' | ||
| - | |||
| - | {{: | ||
| - | |||
| - | Later on, you may find it interesting to scan this output list for useful functions, but for the moment, it's enough to simply notice that the JXA JavaScript environment is very different from the set of web page (window and document) references that you find in the Browser JavaScript environments of Chrome and Safari. | ||
| - | |||
| - | {{: | ||
| - | |||
| - | Keyboard Maestro' | ||
| - | |||
| - | =====The basics – AppleScript and JavaScript for Automation side by side===== | ||
| - | |||
| - | ====Evaluating simple expressions==== | ||
| - | |||
| - | 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: | ||
| - | |||
| - | - 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. | ||
| - | |||
| - | 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). | ||
| - | |||
| - | ^ AppleScript | ||
| - | | < | ||
| - | {{: | ||
| - | |||
| - | ==Differences to notice: sqrt 5 vs Math.sqrt(5)== | ||
| - | |||
| - | JavaScript' | ||
| - | |||
| - | In the common JavaScript patterns: | ||
| - | |||
| - | - **ObjectName**.*functionName*('' | ||
| - | - **ObjectName**.*propertyName* | ||
| - | |||
| - | |||
| - | The dot corresponds to Applescript' | ||
| - | |||
| - | ^ AppleScript | ||
| - | | < | ||
| - | |||
| - | ====Attaching reusable names to computations and their results: | ||
| - | |||
| - | If we often need to calculate the [[https:// | ||
| - | |||
| - | ===Named computations – handlers and functions=== | ||
| - | |||
| - | ^ AppleScript | ||
| - | | < | ||
| - | return ((sqrt 5) + 1) / 2 | ||
| - | end goldenRatio | ||
| - | |||
| - | class of goldenRatio | ||
| - | return (Math.sqrt(5) + 1) / 2; | ||
| - | } | ||
| - | |||
| - | typeof goldenRatio | ||
| - | {{:: | ||
| - | |||
| - | In both languages, we can call/ | ||
| - | |||
| - | ^ AppleScript | ||
| - | | < | ||
| - | return ((sqrt 5) + 1) / 2 | ||
| - | end goldenRatio | ||
| - | |||
| - | goldenRatio() | ||
| - | return (Math.sqrt(5) + 1) / 2; | ||
| - | } | ||
| - | |||
| - | goldenRatio()</ | ||
| - | {{:: | ||
| - | |||
| - | ==Differences to notice: 1. Separating expressions – AppleScript newline vs JavaScript semicolon== | ||
| - | |||
| - | JavaScript is more flexible with white space than AppleScript – a JS expression can be broken up over several lines, if that makes its structure clearer, while a new line is interpreted as the **end** of an AppleScript expression. | ||
| - | |||
| - | In JavaScript, a semicolon means 'end of expression' | ||
| - | |||
| - | ==Differences to notice: 2. Returning a value from a handler / function== | ||
| - | |||
| - | In AppleScript, | ||
| - | |||
| - | 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 '' | ||
| - | |||
| - | ===Parameters / arguments for named computations=== | ||
| - | |||
| - | 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 ' | ||
| - | |||
| - | ^ AppleScript | ||
| - | | < | ||
| - | |||
| - | return (((sqrt 5) + 1) / 2) * n | ||
| - | | ||
| - | end goldenRatio | ||
| - | |||
| - | |||
| - | -- For a square of side 8 | ||
| - | goldenRatio(8) | ||
| - | |||
| - | -- --> 12.944271909999</ | ||
| - | // n is optional here – defaults to 1 | ||
| - | n = n || 1; | ||
| - | | ||
| - | return ((Math.sqrt(5) + 1) / 2) * n; | ||
| - | } | ||
| - | |||
| - | // For a square of side 8 | ||
| - | goldenRatio(8); | ||
| - | |||
| - | // --> 12.94427190999916</ | ||
| - | |||
| - | ==Differences to notice: 1. Comments== | ||
| - | |||
| - | Both languages allow us to include explanatory comments. AS prefixes comments with two dashes, JS with two forward slashes. | ||
| - | |||
| - | ==Differences to notice: 2. Arguments can be optional in JavaScript== | ||
| - | |||
| - | JavaScript is relaxed about whether we supply an argument or not. If we don't, the name '' | ||
| - | |||
| - | ===Named results of computations – ' | ||
| - | |||
| - | 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. | ||
| - | |||
| - | ^ AppleScript | ||
| - | | < | ||
| - | set phi to (((sqrt 5) + 1) / 2) | ||
| - | set phi18 to phi * 18 | ||
| - | set phi7 to phi * 7 | ||
| - | | ||
| - | return phi18 + phi7 | ||
| - | end run | ||
| - | |||
| - | --> 40.450849718747</ | ||
| - | var phi = (Math.sqrt(5) + 1) / 2, | ||
| - | phi18 = phi * 18, | ||
| - | phi7 = phi * 7; | ||
| - | |||
| - | return phi18 + phi7; | ||
| - | } | ||
| - | |||
| - | // --> 40.45084971874737</ | ||
| - | |||
| - | |||
| - | ==Things to notice – 1. We gave the name ' | ||
| - | |||
| - | In osascript (AppleScript or JXA), **run** is a special name. A handler or function with that name is called automatically – you don't have to append parentheses to call it, like we did with the **goldenRatio** computation. | ||
| - | |||
| - | In fact, when we don't assign any names to computations (don't create any AS handlers or JS functions), osascript automatically wraps our our script in a computation which it names **run**, and immediately calls it. | ||
| - | |||
| - | ==Things to notice - 2. We are attach names here to some results of computations== | ||
| - | |||
| - | The following names are all given to the result of a computation, | ||
| - | |||
| - | - phi | ||
| - | - phi18 | ||
| - | - phi7 | ||
| - | |||
| - | ==Differences to notice: AS and JS use different patterns for naming results== | ||
| - | |||
| - | Where AS uses the pattern: | ||
| - | |||
| - | JS uses one or more [[https:// | ||
| - | |||
| - | In JS we can either: | ||
| - | |||
| - | - group several variable declarations together (separated by commas, finishing with a semicolon – example above), | ||
| - | - use a separate variable declaration statement for each variable, or | ||
| - | - make our lives more complex by using the names without a var declaration | ||
| - | |||
| - | ^ Good and simple JXA – temporary local names ^ Messy and complex JXA – persistent global names ^ | ||
| - | |< | ||
| - | phi18 = phi * 18, | ||
| - | phi7 = phi * 7; | ||
| - | // or | ||
| - | var phi = (Math.sqrt(5) + 1) / 2; | ||
| - | var phi18 = phi * 18; | ||
| - | var phi7 = phi * 7;</ | ||
| - | phi18 = phi * 18; | ||
| - | phi7 = phi * 7;</ | ||
| - | | ||
| - | |||
| - | JavaScript gives us a lot of freedom, [[http:// | ||
| - | at the start of a function. When we do this, JavaScript checks that all of our variables are declared (and therefore ' | ||
| - | |||
| - | {{:: | ||
| - | ====Structuring collections – indexing by number, and by name=== | ||
| - | |||
| - | to follow ... | ||
| - | |||
| - | ====Structuring computations – branching, repetition, and nested composition==== | ||
| - | |||
| - | to follow ... | ||
| - | |||
| - | ====JSON for persistence – saving things between macro runs, and reading them straight back in==== | ||
| - | |||
| - | to follow ... | ||
| - | |||
| - | =====The Automation interface===== | ||
| - | |||
| - | ===Using the Standard Additions library==== | ||
| - | |||
| - | to follow ... | ||
| - | |||
| - | ===Interacting with scriptable applications=== | ||
| - | |||
| - | =====Using the Safari JSContexts Debugger (El Capitan onwards)===== | ||
| - | |||
| - | to follow ... | ||
| - | |||
| - | =====The ObjC interface===== | ||
| - | |||
| - | to follow ... | ||
| - | |||
| - | ===Basic file functions=== | ||
| - | |||
| - | to follow ... | ||
| - | |||
| - | ===Clipboard functions=== | ||
| - | |||
| - | to follow ... | ||
| - | |||
| - | ===Reading the documentation for simple ObjC functions=== | ||
| - | |||
| - | to follow ... | ||
JXA_JavaScript_for_Applications.1452041184.txt.gz · Last modified: by ComplexPoint
