At last week’s Adobe MAX, I got talking to an extremely talented InDesign developer with a complaint; in ExtendScript InDesign exposes array collections of objects in response to certain calls, but the CS SDK doesn’t allow for navigating these.
It’s an interesting point, and one with a little back story. What InDesign actually does is always return an object (e.g., a TextFrame); that object’s properties may then be for a single item, or a number of them (in which case every property you access on that object is actually an array). To the scripting DOM, though, both register as the same type (a TextFrame), and there is no way to know ahead of time what InDesign will return for these.
This is great for a language with weak typing, like ExtendScript, but poses challenges for how to represent that in a strongly typed environment, like ActionScript.
Fortunately, there’s a workaround that allows you to make use of these without having to call out to ExtendScript code; the host object delegate.
This is the core representation of the scripting element that the application returns, and so we can call any API on it that we choose. We lose the type-ahead in ExtensionBuilder, of course, and there’s the potential for runtime errors inherent in any untyped code, but it gives you a mechanism to use InDesign’s more advanced scripting DOM behaviour.
As an example, if you create a document with two text frames, assign the script label ‘test’ to both, and then use the code:
var myText:TextFrame = app.activeDocument.textFrames.item("test");
This will generate a runtime error, because the call to ‘id’ will actually return an Array of Numbers, rather than the expected single Number.
To use the host obect instead, you’d simply change the code to:
var myText:HostObject = app.activeDocument.textFrames.item("test").hostObjectDelegate;
You’ll now get both ids printed. Many properties and functions will work without this, but for times when that fails the HostObject provides an invaluable means of working around that.
Note: you may also want to set the script preferences version to work around an unrelated issue in InDesign with these functions not working in the 7.0 and 7.5 scripting versions. You can do that by inserting ‘app.scriptPreferences.version = “6.0″;’ ahead of the call (and a revert to 7.0/7.5 afterwards).