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

问题描述 投票:0回答:1

我正在使用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]"作为返回值。
javascript extendscript ecmascript-3
1个回答
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'来避免linter错误)包含它。这会添加一个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 Runtime版本(v9)中对此进行了测试。

© www.soinside.com 2019 - 2024. All rights reserved.