Is a Flex object any different from a JS object?
Posted: Mon Feb 04, 2013 10:24 pm
Hello,
I'm trying to pass an object from Actionscript to Javascript and I'm getting mad!
I follow the well known HostObject trick described by Zak Nelson (see here) to embed a JSX file: basically I've a very simple:
Code: Select all[ Embed (source= "myScript.jsx" , mimeType= "application/octet-stream" )]
private static var myScriptClass:Class;
private static var jsxInterface:HostObject;
public function appComplete():void{
// embed the JSX
jsxInterface = HostObject.getRoot(HostObject.extensions[0]);
jsxInterface.eval( new myScriptClass().toString());
}
// click handler for a button - calls the JS
protected function button1_clickHandler(event:MouseEvent):void {
var param:Object = new Object();
param.radius = 10;
jsxInterface.main(param);
}
As you see, I pass the "param" object to JS.
In the Javascript, the main() function is trivial:
Code: Select allvar main = function (obj) {
var d = objectToDescriptor (obj, "myString");
}
// The following comes from Adobe
///////////////////////////////////////////////////////////////////////////////
// Function: objectToDescriptor
// Usage: create an ActionDescriptor from a JavaScript Object
// Input: JavaScript Object (o)
// object unique string (s)
// Pre process converter (f)
// Return: ActionDescriptor
// NOTE: Only boolean, string, number and UnitValue are supported, use a pre processor
// to convert (f) other types to one of these forms.
// REUSE: This routine is used in other scripts. Please update those if you
// modify. I am not using include or eval statements as I want these
// scripts self contained.
///////////////////////////////////////////////////////////////////////////////
function objectToDescriptor (o, s, f) {
if (undefined != f) {
o = f(o);
}
var d = new ActionDescriptor;
var l = o.reflect.properties.length;
d.putString( app.charIDToTypeID( 'Msge' ), s );
for (var i = 0; i < l; i++ ) {
var k = o.reflect.properties.toString();
if (k == "__proto__" || k == "__count__" || k == "__class__" || k == "reflect")
continue;
var v = o[ k ];
k = app.stringIDToTypeID(k);
switch ( typeof(v) ) {
case "boolean":
d.putBoolean(k, v);
break;
case "string":
d.putString(k, v);
break;
case "number":
d.putDouble(k, v);
break;
default:
{
if ( v instanceof UnitValue ) {
var uc = new Object;
uc["px"] = charIDToTypeID("#Pxl"); // pixelsUnit
uc["%"] = charIDToTypeID("#Prc"); // unitPercent
d.putUnitDouble(k, uc[v.type], v.value);
} else {
throw( new Error("Unsupported type in objectToDescriptor " + typeof(v) ) );
}
}
}
}
return d;
}
Well, I can't make it work, it fires: "Error: undefined is not an object".
The fun part is that if, in JS, I check the obj.radius property, it's there! And the value is correct. Yet, the Object isn't suitable to be put inside a descriptor. Why on earth I can't say.
Zak reports that:
This technique can also be used to pass complex objects between the two different contexts. The magic is in the property hostObjectDelegate, which is found on each Creative Suite ActionScript Wrapper. Consider sending a document object to JavaScript from ActionScript:
jsxInterface.sendDocumentToJSX(app.documents.item(0).hostObjectDelegate );
So I've tried with:
Code: Select allprotected function button1_clickHandler(event:MouseEvent):void {
var param:Object = new Object();
param.radius = 10;
jsxInterface.main(param.hostObjectDelegate); // undefined
}
Or also:
Code: Select allprotected function button1_clickHandler(event:MouseEvent):void {
var param:HostObject = new HostObject();
param.radius = 10;
jsxInterface.main(param.hostObjectDelegate); // undefined
}
And eventually
Code: Select allprotected function button1_clickHandler(event:MouseEvent):void {
var param:HostObject = new HostObject();
param.radius = 10;
jsxInterface.main(param); // Error: Host object flash.external.HostObject is invalid
}
But without any luck.
The object is passed to JS (in the very first version I've written up above in the post), I can read its properties, but as long as the objectToDescriptor() function is involved - errors are fired.
Mind you, a dummy object created within JS works flawlessly, so am I wondering: is a Flex object any different form a JS one?!
Code: Select allvar dummy = {
radius: 10;
}
Any help is really appreciated!
Thanks,
Davide
I'm trying to pass an object from Actionscript to Javascript and I'm getting mad!
I follow the well known HostObject trick described by Zak Nelson (see here) to embed a JSX file: basically I've a very simple:
Code: Select all[ Embed (source= "myScript.jsx" , mimeType= "application/octet-stream" )]
private static var myScriptClass:Class;
private static var jsxInterface:HostObject;
public function appComplete():void{
// embed the JSX
jsxInterface = HostObject.getRoot(HostObject.extensions[0]);
jsxInterface.eval( new myScriptClass().toString());
}
// click handler for a button - calls the JS
protected function button1_clickHandler(event:MouseEvent):void {
var param:Object = new Object();
param.radius = 10;
jsxInterface.main(param);
}
As you see, I pass the "param" object to JS.
In the Javascript, the main() function is trivial:
Code: Select allvar main = function (obj) {
var d = objectToDescriptor (obj, "myString");
}
// The following comes from Adobe
///////////////////////////////////////////////////////////////////////////////
// Function: objectToDescriptor
// Usage: create an ActionDescriptor from a JavaScript Object
// Input: JavaScript Object (o)
// object unique string (s)
// Pre process converter (f)
// Return: ActionDescriptor
// NOTE: Only boolean, string, number and UnitValue are supported, use a pre processor
// to convert (f) other types to one of these forms.
// REUSE: This routine is used in other scripts. Please update those if you
// modify. I am not using include or eval statements as I want these
// scripts self contained.
///////////////////////////////////////////////////////////////////////////////
function objectToDescriptor (o, s, f) {
if (undefined != f) {
o = f(o);
}
var d = new ActionDescriptor;
var l = o.reflect.properties.length;
d.putString( app.charIDToTypeID( 'Msge' ), s );
for (var i = 0; i < l; i++ ) {
var k = o.reflect.properties.toString();
if (k == "__proto__" || k == "__count__" || k == "__class__" || k == "reflect")
continue;
var v = o[ k ];
k = app.stringIDToTypeID(k);
switch ( typeof(v) ) {
case "boolean":
d.putBoolean(k, v);
break;
case "string":
d.putString(k, v);
break;
case "number":
d.putDouble(k, v);
break;
default:
{
if ( v instanceof UnitValue ) {
var uc = new Object;
uc["px"] = charIDToTypeID("#Pxl"); // pixelsUnit
uc["%"] = charIDToTypeID("#Prc"); // unitPercent
d.putUnitDouble(k, uc[v.type], v.value);
} else {
throw( new Error("Unsupported type in objectToDescriptor " + typeof(v) ) );
}
}
}
}
return d;
}
Well, I can't make it work, it fires: "Error: undefined is not an object".
The fun part is that if, in JS, I check the obj.radius property, it's there! And the value is correct. Yet, the Object isn't suitable to be put inside a descriptor. Why on earth I can't say.
Zak reports that:
This technique can also be used to pass complex objects between the two different contexts. The magic is in the property hostObjectDelegate, which is found on each Creative Suite ActionScript Wrapper. Consider sending a document object to JavaScript from ActionScript:
jsxInterface.sendDocumentToJSX(app.documents.item(0).hostObjectDelegate );
So I've tried with:
Code: Select allprotected function button1_clickHandler(event:MouseEvent):void {
var param:Object = new Object();
param.radius = 10;
jsxInterface.main(param.hostObjectDelegate); // undefined
}
Or also:
Code: Select allprotected function button1_clickHandler(event:MouseEvent):void {
var param:HostObject = new HostObject();
param.radius = 10;
jsxInterface.main(param.hostObjectDelegate); // undefined
}
And eventually
Code: Select allprotected function button1_clickHandler(event:MouseEvent):void {
var param:HostObject = new HostObject();
param.radius = 10;
jsxInterface.main(param); // Error: Host object flash.external.HostObject is invalid
}
But without any luck.
The object is passed to JS (in the very first version I've written up above in the post), I can read its properties, but as long as the objectToDescriptor() function is involved - errors are fired.
Mind you, a dummy object created within JS works flawlessly, so am I wondering: is a Flex object any different form a JS one?!
Code: Select allvar dummy = {
radius: 10;
}
Any help is really appreciated!
Thanks,
Davide