Skip to main content
Inspiring
June 28, 2013
Question

How to access app.activeDocument from a palette button?

  • June 28, 2013
  • 1 reply
  • 4063 views

I'm trying to debug a script that silently fails (I've got a seperate "How best to debug?" question here).

Through brute force trial and error I've established that I can't access app.activeDocument in a function called by a button in a palette, and that any attempt to even look at app.activeDocument within the scope of this function causes the script to fall over and fail silently with no errors - even something that should be safe like if (!app.activeDocument){}.

So, how do I access the active document - and specifically, app.activeDocument.selection - from within the scope of a function called by a button on a palette window?

I've looked in the Javascript tools guide, the Illustrator CS6 scripting guide and Peter Kahrell's ScriptUI docs, and found nothing. I've googled around and found worrying long long threads linking to things referring to "The holy grail of Illustrator scripting", lots of "You can't" comments, something I didn't understand about refreshing the connection to the app, something about #targetengine another which seems to involve writing a seperate javascript file to the hard disk then running it (?!?!) and something else called BridgeTalk which seems to involve actionscript.

Is it really this complicated? This is literally my first Illustrator script, and all I want is a palette (yes, it has to be a palette, not a dialog) that gets information about the current selection when you press a button.

So, simple question, (hopefully) simple answer! How do you access data about the current selection from a palette button?

This topic has been closed for replies.

1 reply

alanomalyAuthor
Inspiring
June 28, 2013

With a lot of trial and error and ploughing through vague, unclear articles and non-existent docs, I figured it out.

  • It seems like palettes don't actually know what app they're in. They just sit there.
  • To get anything from your app, you need to throw javascript at it using the seemingly completely undocumented BridgeTalk, giving BridgeTalk a callback function if you need anything to happen in the palette once it's finished

This actually isn't half as difficult as it looks when you're wading through the mountains of noise on the topic. Basically, anything you want to write like this:

function someFunction() {

   // get data from the application and write it in the palette

   palette.info.text = app.activeDocument.selection.length;

}

palette.button.onclick = someFunction;

...you have to write like this...

function someFunction() {

  // get data from the application

  return app.activeDocument.selection.length;

}

palette.button.onclick = function(){

// make a BridgeTalk object to throw the script

  var bt = new BridgeTalk();

  bt.target = "illustrator";

// a string containing javascript code to execute in Illustrator

  bt.body = someFunction.toString()+'someFunction();';

// a function that recieves whatever the body JS above returns

  bt.onResult = function(result){

      palette.info.text = result;

};

  bt.send();

}

This sort of structure should work for essentially anything - the only tricky case I can think of is if you need Illustrator to read some data that is in your palette - since the code you throw can't access any variables in the rest of your script - in which case you can do something like this:

bt.body = 'var = '+someVariable.toString()+'; '+someFunction.toString()+'someFunction();';

Or if you need to parameters to someFunction:

bt.body = someFunction.toString()+'someFunction('+someVariable.toString()+');';

CarlosCanto
Community Expert
Community Expert
June 28, 2013

correct, you have to use BridgeTalk to make a palette talk with Illustrator, it is all documented in the Tools Guide

look at this two script I posted here

selectLayers

alignText