I'm working with Adobe CEP (it lets developers create windowed extensions for Adobe CC products). The bulk of my code is modern JavaScript (the platform uses Chromium 57, Node.js 7.7.4). However, in order to access the DOM, I need to write some functions in Adobe ExtendScript and execute them from normal JS. The only way is to execute a script using their provided csInterface.evalScript(script, callback)
. script
has to be a string, which in my case is a function call converted to a string. I want to be able to pass an object to and from ExtendScript via evalScript
, but evalScript
only takes and returns a string.
Currently, I am passing each object property as its own argument. This is unwieldy, but it works.
My first though was JSON.stringify()
, but unfortunately ExtendScript is a dialect of ECMAScript 3, which means no JSON.parse()
support.
I can't just concat the object argument into the script function call, because then the string evaluates to foo([object Object])
.
I've seen there are functions like eval()
/uneval()
or Object.toSource()
, but those are not supported by Chromium.
Here's an example, similar to my current method:
functions.js (ES3/ExtendScript)
function drawCircle(x, y, name) {
// pick a layer
var layer = app.activeDocument.layers[0];
var diameter = 10;
var top = y + diameter / 2;
var left = x - diameter / 2;
// draw ellipse in layer
var circle = layer.pathItems.ellipse(top, left, diameter, diameter);
circle.name = name;
circle.filled = true;
return true;
}
app.js (ES6)
const csInterface = new CSInterface(); // provided by Adobe
async function circle() {
const dataObject = {x: 10, y: 10, name: 'Hello world!'};
// the script to call
// evaluates to drawCircle(10,10,'Hello world!');
const script = "drawCircle(" + dataObject.x + "," + dataObject.y + ",'" + dataObject.name + "');";
return new Promise((resolve, reject) => {
csInterface.evalScript(script, (result) => {
resolve(result);
});
});
}
As expected, circle()
calls drawCircle()
just fine, and an ellipse appears in the document I'm working on. However, executing a script/calling a function by concatenation feels very wrong. So in summary,
- I would like some (neater) way of turning
dataObject
into a string and passing it todrawCircle()
viaevalScript()
, - and I would like to return
dataObject
fromdrawCircle()
and receive it back as an object. Currently, returning an object only results in"[object Object]"
as a return value.