如何从Javascript(Adobe CEP)将对象传递给Adobe ExtendScript?

时间:2019-04-07 03:21:58

标签: javascript extendscript ecmascript-3

我正在使用Adobe CEP(它使开发人员可以为Adobe CC产品创建窗口式扩展)。我的代码大部分是现代JavaScript(该平台使用Chromium 57,Node.js 7.7.4)。 但是,为了访问DOM,我需要在Adobe ExtendScript中编写一些函数并从普通JS执行它们。唯一的方法是使用脚本提供的csInterface.evalScript(script, callback)执行脚本。 script必须是字符串,就我而言,这是一个转换为字符串的函数调用。 我希望能够通过evalScript 与ExtendScript进行传递,但是evalScript仅接受并返回一个字符串。

当前,我将每个对象属性作为其自变量传递。这很麻烦,但是有效。

虽然我的第一个是JSON.stringify(),但是不幸的是ExtendScript是ECMAScript 3的方言,这意味着不支持JSON.parse()

我不能只将对象参数合并到脚本函数调用中,因为这样字符串的值将为foo([object Object])

我已经看到eval() / uneval()Object.toSource()之类的功能,但Chromium不支持这些功能。

这是一个示例,类似于我当前的方法:

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);
        });
    });
}

正如预期的那样,circle()调用drawCircle()很好,并且在我正在处理的文档中出现一个椭圆。但是,通过串联执行脚本/调用函数感觉很错误。所以总而言之,

  1. 我希望以某种(更巧妙的方式)将dataObject转换为字符串并通过drawCircle()传递给evalScript()
  2. ,我想从dataObject返回drawCircle()并将其作为对象接收。当前,返回对象仅导致"[object Object]"作为返回值。

1 个答案:

答案 0 :(得分:1)

Javascript-> ExtendScript

将对象从Javascript传递到ExtendScript的唯一方法是使用JSON.stringify()将其作为JSON字符串发送。

是的,关于JSON.parse()的支持,您是正确的,但是,您不需要

您仍然可以发送字符串化的对象,并将作为对象到达ExtendScript。

const dataObject = {x: 10, y: 10, name: 'Hello world!'};
const script = "drawCircle(" + JSON.stringify(dataObject) + ")";

然后在ExtendScript中,您可以执行以下操作:

function drawCircle(obj) {
  var layer = app.activeDocument.layers[0];

  var radius = 10;
  var top = obj.y + 5;
  var left = obj.x - 5;

  var circle = layer.pathItems.ellipse(top, left, radius, radius);

  circle.name = obj.name;
  circle.filled = true;

  return true;
}

ExtendScript-> Javascript

您将需要此ExtendScript模块,将其复制到与jsx相同的文件夹中

Link to Indiscripts ExtendScript JSON module

然后将其与jsx顶部的#include 'json.jsx';(或//@include 'json.jsx'以避免棉绒错误)一起包含。这将添加一个提供两个方法的JSON全局函数:JSON.eval()JSON.lave()

我们需要的方法是lave(),它允许您将对象字符串化为Javascript。认为它是JSON.stringify()的更友好版本。

function drawCircle(obj) {
  var layer = app.activeDocument.layers[0];

  var radius = 10;
  var top = obj.y + 5;
  var left = obj.x - 5;

  // draw ellipse in layer
  var circle = layer.pathItems.ellipse(top, left, radius, radius);

  circle.name = obj.name;
  circle.filled = true;

  return JSON.lave(circle);
}

然后在javascript中可以再次解析为对象:

const dataObject = {x: 10, y: 10, name: 'Hello world!'};
const script = "drawCircle(" + JSON.stringify(dataObject) + ")";

csInterface.evalScript(script, (result) => {
  console.log(JSON.parse(result));
});

我在最新的CEP运行时版本(v9)中对此进行了测试。