Automation with JavaScript

KosmicTask Help

Automation with JavaScript

Automation with JavaScript

The Ruby and Python examples above make it clear that the ScriptingBridge framework is critical in allowing us to create a connection to the application that we wish to automate. What is less clear is the importance of the Cocoa bridge.

The Cocoa bridge enables our scripts to communicate with the OS X Cocoa framework and its essential objects and methods. Indeed, it is only because the Cocoa bridge exists that we can get to the scripting bridge object, SBApplication, in the first place.

This connection to the Cocoa bridge and what it entails becomes a bit clearer if we consider JavaScript. KosmicTask includes support for two variants of JavaScript, namely JavaScript itself and JavaScript Cocoa.

The first variant, JavaScript, supports just the range of functionality that we would expect of the language. If we look at the list of available JavaScript templates in the Resource Browser we see that the selection is quite restrictive. We cannot return files as results, we cannot automate other applications and we cannot import other frameworks.

The second variant, JavaScript Cocoa, is a Cocoa bridged version of JavaScript that greatly extends the capabilities of the language. With the bridge in place JavaScript powered tasks can now access all the capabilities of the Cocoa framework including access to the ScriptingBridge. JavaScript Cocoa tasks are implemented using JSCocoa.

So here is a JavaScript Cocoa implementation of our Pages task. As usual it behaves just like all our previous examples of this task.

// load the ScriptingBridge framework
loadFramework("ScriptingBridge")

function kosmicTask(pagesDocFilePath)
{
  // use the ScriptingBridge framework to access the application
  var app = SBApplication.applicationWithBundleIdentifier('com.apple.iWork.pages')

  // rtf file path
  var rtfDocFilePath = pagesDocFilePath + ".rtf"

  // open pages
  var myDoc = app.open(pagesDocFilePath)

  // save document
  myDoc.saveAs_in("SLDocumentTypeRichText", rtfDocFilePath)

  // save document
  myDoc.closeSaving_savingIn(false, null)

  // form our file result path
  // this file will be automatically deleted when the task ends.
  var resultFile = KosmicTaskController.resultFileWithName('result.html')

  // run external task using a Cocoa NSTask object !
  var args = ['-convert', 'html', '-output', resultFile, rtfDocFilePath]
  var task = NSTask.launchedTaskWithLaunchPath_arguments('/usr/bin/textutil', args)
  task.waitUntilExit;

  // form result dictionary 
  return {kosmicFile: resultFile};
}

Note that the Cocoa bridge code has added a function, loadFramework(), that allows us to load in the ScriptingBridge framework that we need to get our automation object reference.

Another standout feature is the use of NSTask, a Cocoa class, to run our external command. Native JavaScript, unlike all our previous examples, provides no way of initiating an external task (mainly to prevent malicious Internet browser scripts from wreaking havoc) . This example demonstrates clearly how a Cocoa bridge can enhance a language's overall functionality and usefulness.

An additional detail is the use of the KosmicTaskController object to retrieve a result file path. This utility object is automatically made available to all JavaScript Cocoa tasks. In fact KosmicTask makes a KosmicTaskController object available for many of the languages that it supports. This provides a simple way for KosmicTask to expose utility and support functions to the task. See the usage documents in the Resource Browser for further details