Copy link to clipboard
Copied
I`ve developed a Photoshop extension and I try to get callback from jsx
for example
JS
function init() {
var csInterface = new CSInterface();
themeManager.init();
$("#btn_test").click(function () {
csInterface.evalScript('getstatus()',function(f){
alert(f); //value is 1,2,3 looks array object but Data Type is String
});
});
}
JSX
function getstatus(){
var f =[1,2,3];
return f;
}
getstatus return array object but it became String object when evalScript get callback
It`s very inconvenience
if someone give me good idea I would be glad
Shuji
Hi,You
you need to include json2.js in the JSX, for ExtendScript doesn't know about JSON natively.
Then in the JS:
$('#arr').on('click', function(){
csInterface.evalScript('getArray()', function(res){
console.log(JSON.parse(res));
})
})
and in the JSX:
function getArray() {
return JSON.stringify([1,2,3]);
}
You may want to have a look at my HTML Panel Tips series to get a headstart with similar matters.
Hope this helps!
Cheers,
Davide
Copy link to clipboard
Copied
Hi,You
you need to include json2.js in the JSX, for ExtendScript doesn't know about JSON natively.
Then in the JS:
$('#arr').on('click', function(){
csInterface.evalScript('getArray()', function(res){
console.log(JSON.parse(res));
})
})
and in the JSX:
function getArray() {
return JSON.stringify([1,2,3]);
}
You may want to have a look at my HTML Panel Tips series to get a headstart with similar matters.
Hope this helps!
Cheers,
Davide
Copy link to clipboard
Copied
Hi Davide,
It should be noted that Crockford's json2.js is not fully ExtendScript compliant. (More precisely, ExtendScript is not fully ECMA compliant, as you already know.)
In particular, json2 uses a few ternary operations in the form
cond1 ? "cond1 OK" : cond2 ? "cond2 OK" : "cond2 KO"
assuming right-associativity of the ternary op, which is the case in ECMA-262 but not in ExtendScript 😕
Studying json2 some months ago I found other tricky issues, which leads me to implement IdExtenso's JSON module:
IdExtenso/$$.JSON.jsxlib at master · indiscripts/IdExtenso · GitHub
Best,
Marc
Copy link to clipboard
Copied
Thank you Marc!
Isn't your JSON implementation plug-and-play replacement of json2.js, correct?
Copy link to clipboard
Copied
Hi Davide,
Indeed my JSON module requires the framework (IdExtenso), which by definition involves InDesign.
Maybe I should provide adapters for other ExtendScript hosts, but ID remains my main scope (so far.)
However, 99% of the code is purely ExtendScript-based, so it wouldn't be too difficult to extract an universal JSON.jsx from it…
@+
Marc
Copy link to clipboard
Copied
I finally did it:
extendscript/JSON at master · indiscripts/extendscript · GitHub
Hope that helps,
Marc
Copy link to clipboard
Copied
Well done Marc!
Brilliant and incredibly useful code.
I just want to point out (not to you!) the obj.toSource() method.
Given Marc's test object
var obj = {
myNumber: 12345678,
myBool: true,
myString: "Hello\tWorld\u00a0: This is fine!",
myRegex: /[a-z\d]+/,
myArray: [ ['this', 'is'], [1], ['array', 'of', 'arrays'] ],
myObject: {a:1,b:2,c:3},
myUnit: UnitValue(5,'mm'),
myXML: <root><aaa xxx='yyy'>hello</aaa></root>,
myDate: new Date,
myFile: File("c:/test.txt"),
myNativeObj: $.global,
};
His code will produce
{
"myNumber" : 12345678,
"myBool" : true,
"myString" : "Hello\tWorld\xA0: This is fine!",
"myRegex" : RegExp("[a-z\\d]+",""),
"myArray" : [
[ "this", "is" ],
[ 1 ],
[ "array", "of", "arrays" ]
],
"myObject" : {
"a" : 1,
"b" : 2,
"c" : 3
},
"myUnit" : UnitValue("5mm"),
"myXML" : <root>
<aaa xxx="yyy">hello</aaa>
</root>,
"myDate" : (new Date(1508054575699)),
"myFile" : File("/c/test.txt"),
"myNativeObj" : $.global
}
This is so to speak a "perfect"* result. If one only needs to parse more simple objects / arrays then obj.toSource() could well do. See how obj.toSource() passes and fails Marc's test object
({
myNumber: 12345678,
myBool: true,
myString: "Hello World : This is fine!",
myRegex: (new RegExp(/[a-z\d]+/)),
myArray: [
["this", "is"],
[1],
["array", "of", "arrays"]
],
myObject: { a: 1, b: 2, c: 3 },
myUnit: ({}),
myXML: ({}),
myDate: (new Date(1508054393407)),
myFile: new File("/c/test.txt"),
myNativeObj: ({})
})
If the passes are good enough and the fails are irrelevant to you then it's going to be the simplest method of passing.
*Marc's result is "perfect" for the JSX engine for which it was written but the results are going to have to be treated with great care on the JS end of the extension.
In particular the xml and native objects like the UnitValue and $.global are going to cause a parsing error if just blindly parsed.
Ten A​ It is true that Photoshop will automatically parse the callback as a string as will as far as I know all the apps with the noted exception of InDesign. If the result is not explicitly made a string on the JSX engine then the JS engine just receives a blank callback.
One other note, one from CEP6.1 parse the object directly from the JSX engine to JS engine as an object that does not need parsing if using the PlugPlug and CSXSEvent(); methods and then on the JS side you receive it as using addEventListener This method is a bit less convenient than the standard callback method but save the need for the JSON.parse on the other end.
Copy link to clipboard
Copied
Hi Davide,
thank you for reply me
I tried to it
It was success , I got value as an Array object
this is very useful
Shuji
Copy link to clipboard
Copied
ExtendScript function always return String, we need to parse it as David say.
Copy link to clipboard
Copied
I didn't know that ExtendScript always return String
I tried to it without Json2 many time