Scripting Dictionary

Scripting Dictionary

As mentioned in the Introduction, the only reliable source of information regarding an application’s objects, methods, and classes is the scripting dictionary. You can view it by dragging and dropping the application onto the Script Editor icon or window. Alternatively, select „Open Dictionary“ from script editor’s „File“ menu.

Script Editor then opens a new window showing the scripting dictionary for the selected app. Make sure to set the language selector in the top toolbar to „JavaScript”.

Scripting dictionary for Apple’s Numbers app

The top pane of the dictionary display shows the name of the application or the application suite in the list to the very left („Numbers Suite“). Clicking on it gives you a list of „commands“ (prefixed with a C in a blue circle) and „classes“ (prefixed with a C in a violet square) in the center column.

Selecting a suite from the scripting dictionary

Classes are objects#

Although Apple uses a „C“ for „class“, what you really get in any JXA script are objects. So, Application in the screenshot above is actually an Object Specifier, kind of the application’s top-level object. Clicking on this entry in the central column will display the object’s direct properties and „Elements“. The latter are usually arrays of other objects, „Templates“ in the case of the Numbers application.

Properties and elements inherited from other suites or frameworks are listed in the bottom pane of the Script Editor window. For the Numbers application, those are the properties frontmost, version, and name as well as the elements windows and documents. These exist for all Application objects.

All this tells you that you can get an array of templates for the Numbers app with Application("Numbers").templates() and of the documents currently open in the app with Application("Numbers").documents(). The same goes for properties like name: Application("Numbers").name() will unsurprisingly return “Numbers”.

Calling methods#

Things get a bit more tricky with commands. Some of them, for example make do not work at all (see Working with Objects to learn about creating objects in JXA). In general, many commands from the „Standards Suite“ are so underdocumented (see move, delete etc.) that they’re probably useless.

Commands from the Standard Suite in Script Editor

The most important commands, though work ok: open to open files in an app, close to close documents, and save to write them back to disk. The description of the commands uses AppleScript terminology:

open  method : Open a document.
  open file or list of file : The file(s) to be opened.
    → Document or list of Document : The opened document(s).

That means: open expects a file name or an array of file names – do not pass a file or an alias to a file here! The method returns a Document or an array of Documents, those being Object Specifiers of the Document class.

// Open a bunch of Numbers documents
const documents = Application("Numbers").open([
  "File1.numbers", "File2.numbers", "File3.numbers"]);

If a method expects more than one parameter, things get a bit more complicated.

save method : Save a document.
  save specifier : The document(s) or window(s) to save.
    [in: file] : The file in which to save the document.
    [as: “Numbers”] : The file format to use.

This descriptions means: save expects one mandatory, unnamed parameter, namely the document or window to save. You can pass two optional named parameters to specify a file name and a format for this file. All parameters in square brackets are optional. In JavaScript, you’d write something like this:

// Save a document
const app = Application("Numbers");
app.save(app.documents[0], {in: "targetFile.csv"})

The optional parameters are always passed in an object whose keys are the parameter names. Here, as is useless, since you can’t pass anything else than “Numbers” as its value. In many cases, mandatory parameters are passed first to the method, but in some cases they need instead be stuffed as named parameters into an object.

offset method : Find one piece of text inside another
  offset
    of: text : the source text to find the position of
    in: text : the target text to search in
      → integer : the position of the source text in the target, or 0 if not found

The offset method from Standard Additions expects two mandatory parameters, so you’d use something like

const app = Application.currentApplication();
app.includeStandardAdditions = true;
const index = app.offset({ "of" :"fox", 
  "in" : "The quick brown fox jumps over the lazy dog"});

(This is just meant to illustrate how to interpret the scripting dictionary. In a real application, you’d use JavaScript’s String methods for this task.)