AppleScript_ The Definitive Guide - Matt Neuburg [274]
Actually, JavaScript OSA can construct Apple events in two ways. If you like, you can construct raw Apple events by a process quite similar to the earlier REALbasic example. However, JavaScript OSA can also read the dictionary of the target application in real time and incorporate its terminology into the JavaScript language. The target application is, in effect, represented by an object with properties and methods corresponding to AppleScript attributes and commands. Here is code to generate and send our model events:
with (MacOS.appBySignature("R*ch")) {
make(_types.document);
document[1].valueOf( ).text = "Hello, world!";
}
This mode of expression is extraordinarily compact and direct. A with clause and dot notation replace the chain of ofs and tells; true assignment with an equal-sign replaces set. Elements appear as arrays. Certain distinctions that are muddied by AppleScript are clarified; the term document is different as an element and as a class, for instance.
JavaScript OSA can't express every kind of Apple event (in particular, boolean test specifiers are not supported), but this is compensated for by the powerful combination of the cool and elegant object-oriented JavaScript language with the automatic implementation of AppleScript terminology. Most important, JavaScript OSA is an OSA language, meaning that it's usable just about anywhere you would use an AppleScript compiled script file. For instance, many of the scripts I use with script runners such as Entourage's and BBEdit's Script menus are written in JavaScript.
To learn more about JavaScript OSA, download it and look through the "Introducing JavaScript OSA" manual (written by yours truly).
UserTalk
UserTalk is the native scripting language of UserLand Frontier and its inexpensive "little brother," Radio UserLand. Frontier is now also once again available in a free version, which is open source.
UserTalk does not read an application's dictionary in real time, the way JavaScript OSA does. In UserTalk, all terminology (not only as relates to Apple events, but the entire language) is implemented through a hierarchical namespace table called "the database." Every name in the database corresponds to a value; a value can be a string, an integer, a raw four-character code, a script written in the UserTalk language, a subtable, or any of a dozen other types of value. The namespace is navigated through dot notation, starting at the top level, which is called root. Certain nodes in the database are short-circuited, though, so that an unqualified term is sought at these points directly. English-like AppleScript terminology is implemented through the database, like everything else; to drive an application, you need a table to translate from English-like terms to four-letter codes, scripts, and so forth. This is called the glue table for that application. Construction of a glue table must be performed separately before you can start targeting a given application. The process of constructing a glue table is largely automatic (Frontier includes a script that can read an application's dictionary and generate the corresponding table), but too involved to describe here. Let's just assume, therefore, that we have previously constructed a BBEdit glue table. Then the code to generate our model events is as follows:
if !(bbedit.isRunning( ))
launch.application(bbedit.appinfo.path)
with objectmodel, bbedit
make(document)
set(document[1].text,"Hello, world!")
The term bbedit refers to our glue table (located in the system.verbs.apps table, one of the short-circuited areas of the database). The term objectmodel refers to a table in system.macintosh (another short-circuited area) where certain common terms are defined. The with clause means: "Look for these terms starting in objectmodel, and if you don't find one, look for it in bbedit instead." As a result, make and set are found in bbedit, whereas