Photoshop DOM Parser (debugging)
Posted: Fri Nov 25, 2011 3:19 am
This code recursively parses the ActionDescriptor, ActionList, ActionReference types and outputs it to a TextArea in a somewhat pretty format.
Useful for debugging if you want to peek at the entire DOM or just a small part..
For instance, to peek at the DOM (note: will output a lot of info) ...
Code: Select allvar ar4:ActionReference = new ActionReference();
ar4.putEnumerated(phClassApplication, phTypeOrdinal, phEnumTarget );
var desc4:ActionDescriptor = Photoshop.app.executeActionGet(phEventGet, ar4);
// first arg is your textArea name (debug in this case)
// second arg should be zero, third argument, is the indent spacing between children
recursiveParseDesc(debug, 0, 2, desc4);
The code:
Code: Select allprotected function repeatString(string:String, numTimes:uint):String {
if(numTimes == 0) return "";
if(numTimes & 1) return string + repeatString(string, numTimes - 1);
var tmp:String = repeatString(string, numTimes/2);
return tmp + tmp;
}
protected function convertToName(typeID:Number):String {
var str:String = Photoshop.app.typeIDToCharID(typeID);
if (str.length == 0) {
str = Photoshop.app.typeIDToStringID(typeID);
if (str.length != 0) {
str = "\"" + str + "\"";
} else {
return (new String(typeID));
}
} else {
str = "\'" + str + "\'";
}
if (str.length == 0) {
return (new String(typeID));
}
return str;
}
protected function parseReference(txt:TextArea, indent:Number, indentIncrement:Number, refer:ActionReference):void {
var x:ActionReference = new ActionReference();
switch (refer.getForm()) {
case ReferenceFormType.CLASSTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass());
break;
case ReferenceFormType.ENUMERATED:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + convertToName(refer.getEnumeratedType()) + " : " + convertToName(refer.getEnumeratedValue());
break;
case ReferenceFormType.IDENTIFIER:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + convertToName(refer.getIdentifier());
break;
case ReferenceFormType.INDEX:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + refer.getIndex();
break;
case ReferenceFormType.NAME:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + "\"" + refer.getName() + "\"";
break;
case ReferenceFormType.OFFSET:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + refer.getOffset();
break;
case ReferenceFormType.PROPERTY:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + convertToName(refer.getProperty());
break;
default:
break;
}
}
protected function recursiveParseList(txt:TextArea, indent:Number, indentIncrement:Number, list:ActionList):void {
for (var i:Number = 0; i < list.count; i++) {
switch (list.getType(i)) {
case DescValueType.ALIASTYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getPath(i);
break;
case DescValueType.BOOLEANTYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getBoolean(i);
break;
case DescValueType.CLASSTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(list.getClass(i));
break;
case DescValueType.DOUBLETYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getDouble(i);
break;
case DescValueType.ENUMERATEDTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(list.getEnumerationType(i)) + " : " + convertToName(list.getEnumerationValue(i));
break;
case DescValueType.INTEGERTYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getInteger(i);
break;
case DescValueType.LISTTYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getList(i);
recursiveParseList(txt, indent+indentIncrement, indentIncrement, list.getList(i));
break;
case DescValueType.OBJECTTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(list.getObjectType(i)) + " : " + list.getObjectValue(i);
recursiveParseDesc(txt, indent+indentIncrement, indentIncrement, list.getObjectValue(i));
break;
case DescValueType.RAWTYPE:
txt.text += "\n" + repeatString(" ", indent) + "\"" + list.getData(i) + "\"";
break;
case DescValueType.REFERENCETYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getReference(i);
parseReference(txt, indent+indentIncrement, indentIncrement, list.getReference(i));
break;
case DescValueType.STRINGTYPE:
txt.text += "\n" + repeatString(" ", indent) + "\"" + list.getString(i) + "\"";
break;
case DescValueType.UNITDOUBLE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(list.getUnitDoubleType(i)) + " : " + list.getUnitDoubleValue(i);
break;
default:
break;
}
}
}
protected function recursiveParseDesc(txt:TextArea, indent:Number, indentIncrement:Number, desc:ActionDescriptor):void {
for (var i:Number = 0; i < desc.count; i++) {
var id:String = convertToName(desc.getKey(i));
txt.text += "\n" + repeatString(" ", indent) + id + " : " + desc.getType(desc.getKey(i));
indent = indent+indentIncrement;
switch (desc.getType(desc.getKey(i))) {
case DescValueType.BOOLEANTYPE:
txt.text += "\n" + repeatString(" ", indent) + desc.getBoolean(desc.getKey(i));
break;
case DescValueType.CLASSTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(desc.getClass(desc.getKey(i)));
break;
case DescValueType.DOUBLETYPE:
txt.text += "\n" + repeatString(" ", indent) + desc.getDouble(desc.getKey(i));
break;
case DescValueType.ENUMERATEDTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(desc.getEnumerationType(desc.getKey(i))) + " : " + convertToName(desc.getEnumerationValue(desc.getKey(i)));
break;
case DescValueType.INTEGERTYPE:
txt.text += "\n" + repeatString(" ", indent) + desc.getInteger(desc.getKey(i));
break;
case DescValueType.LISTTYPE:
txt.text += "\n" + repeatString(" ", indent) + desc.getList(desc.getKey(i));
recursiveParseList(txt, indent+indentIncrement, indentIncrement, desc.getList(desc.getKey(i)));
break;
case DescValueType.OBJECTTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(desc.getObjectType(desc.getKey(i))) + " : " + desc.getObjectValue(desc.getKey(i));
recursiveParseDesc(txt, indent+indentIncrement, indentIncrement, desc.getObjectValue(desc.getKey(i)));
break;
case DescValueType.RAWTYPE:
txt.text += "\n" + repeatString(" ", indent) + "\"" + desc.getData(desc.getKey(i)) + "\"";
break;
case DescValueType.REFERENCETYPE:
txt.text += "\n" + repeatString(" ", indent) + desc.getReference(desc.getKey(i));
parseReference(txt, indent+indentIncrement, indentIncrement, desc.getReference(desc.getKey(i)));
break;
case DescValueType.STRINGTYPE:
txt.text += "\n" + repeatString(" ", indent) + "\"" + desc.getString(desc.getKey(i)) + "\"";
break;
case DescValueType.UNITDOUBLE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(desc.getUnitDoubleType(desc.getKey(i))) + " : " + desc.getUnitDoubleValue(desc.getKey(i));
break;
default:
break;
}
indent = indent-indentIncrement;
}
}
Example output for just the section of the key 'CrnT' (current tool options) (when bucketTool was active):
Code: Select all'CrnT' : DescValueType.OBJECTTYPE
'CrnT' : [ActionDescriptor]
'Md ' : DescValueType.ENUMERATEDTYPE
'BlnM' : 'Nrml'
'Opct' : DescValueType.INTEGERTYPE
100
'BckT' : DescValueType.INTEGERTYPE
12
'BckA' : DescValueType.BOOLEANTYPE
true
'BckS' : DescValueType.BOOLEANTYPE
true
'Cntg' : DescValueType.BOOLEANTYPE
true
'BckF' : DescValueType.BOOLEANTYPE
false
'Ptrn' : DescValueType.OBJECTTYPE
'Ptrn' : [ActionDescriptor]
'Nm ' : DescValueType.STRINGTYPE
"$$$/Presets/Patterns/Patterns_pat/Bubbles=Bubbles"
'Idnt' : DescValueType.STRINGTYPE
"b7334da0-122f-11d4-8bb5-e27e45023b5f"
EDIT: Forgot to include desiredClass key in ActionReference parser. Fixed.
Useful for debugging if you want to peek at the entire DOM or just a small part..
For instance, to peek at the DOM (note: will output a lot of info) ...
Code: Select allvar ar4:ActionReference = new ActionReference();
ar4.putEnumerated(phClassApplication, phTypeOrdinal, phEnumTarget );
var desc4:ActionDescriptor = Photoshop.app.executeActionGet(phEventGet, ar4);
// first arg is your textArea name (debug in this case)
// second arg should be zero, third argument, is the indent spacing between children
recursiveParseDesc(debug, 0, 2, desc4);
The code:
Code: Select allprotected function repeatString(string:String, numTimes:uint):String {
if(numTimes == 0) return "";
if(numTimes & 1) return string + repeatString(string, numTimes - 1);
var tmp:String = repeatString(string, numTimes/2);
return tmp + tmp;
}
protected function convertToName(typeID:Number):String {
var str:String = Photoshop.app.typeIDToCharID(typeID);
if (str.length == 0) {
str = Photoshop.app.typeIDToStringID(typeID);
if (str.length != 0) {
str = "\"" + str + "\"";
} else {
return (new String(typeID));
}
} else {
str = "\'" + str + "\'";
}
if (str.length == 0) {
return (new String(typeID));
}
return str;
}
protected function parseReference(txt:TextArea, indent:Number, indentIncrement:Number, refer:ActionReference):void {
var x:ActionReference = new ActionReference();
switch (refer.getForm()) {
case ReferenceFormType.CLASSTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass());
break;
case ReferenceFormType.ENUMERATED:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + convertToName(refer.getEnumeratedType()) + " : " + convertToName(refer.getEnumeratedValue());
break;
case ReferenceFormType.IDENTIFIER:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + convertToName(refer.getIdentifier());
break;
case ReferenceFormType.INDEX:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + refer.getIndex();
break;
case ReferenceFormType.NAME:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + "\"" + refer.getName() + "\"";
break;
case ReferenceFormType.OFFSET:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + refer.getOffset();
break;
case ReferenceFormType.PROPERTY:
txt.text += "\n" + repeatString(" ", indent) + convertToName(refer.getDesiredClass()) + " :: " + convertToName(refer.getProperty());
break;
default:
break;
}
}
protected function recursiveParseList(txt:TextArea, indent:Number, indentIncrement:Number, list:ActionList):void {
for (var i:Number = 0; i < list.count; i++) {
switch (list.getType(i)) {
case DescValueType.ALIASTYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getPath(i);
break;
case DescValueType.BOOLEANTYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getBoolean(i);
break;
case DescValueType.CLASSTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(list.getClass(i));
break;
case DescValueType.DOUBLETYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getDouble(i);
break;
case DescValueType.ENUMERATEDTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(list.getEnumerationType(i)) + " : " + convertToName(list.getEnumerationValue(i));
break;
case DescValueType.INTEGERTYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getInteger(i);
break;
case DescValueType.LISTTYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getList(i);
recursiveParseList(txt, indent+indentIncrement, indentIncrement, list.getList(i));
break;
case DescValueType.OBJECTTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(list.getObjectType(i)) + " : " + list.getObjectValue(i);
recursiveParseDesc(txt, indent+indentIncrement, indentIncrement, list.getObjectValue(i));
break;
case DescValueType.RAWTYPE:
txt.text += "\n" + repeatString(" ", indent) + "\"" + list.getData(i) + "\"";
break;
case DescValueType.REFERENCETYPE:
txt.text += "\n" + repeatString(" ", indent) + list.getReference(i);
parseReference(txt, indent+indentIncrement, indentIncrement, list.getReference(i));
break;
case DescValueType.STRINGTYPE:
txt.text += "\n" + repeatString(" ", indent) + "\"" + list.getString(i) + "\"";
break;
case DescValueType.UNITDOUBLE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(list.getUnitDoubleType(i)) + " : " + list.getUnitDoubleValue(i);
break;
default:
break;
}
}
}
protected function recursiveParseDesc(txt:TextArea, indent:Number, indentIncrement:Number, desc:ActionDescriptor):void {
for (var i:Number = 0; i < desc.count; i++) {
var id:String = convertToName(desc.getKey(i));
txt.text += "\n" + repeatString(" ", indent) + id + " : " + desc.getType(desc.getKey(i));
indent = indent+indentIncrement;
switch (desc.getType(desc.getKey(i))) {
case DescValueType.BOOLEANTYPE:
txt.text += "\n" + repeatString(" ", indent) + desc.getBoolean(desc.getKey(i));
break;
case DescValueType.CLASSTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(desc.getClass(desc.getKey(i)));
break;
case DescValueType.DOUBLETYPE:
txt.text += "\n" + repeatString(" ", indent) + desc.getDouble(desc.getKey(i));
break;
case DescValueType.ENUMERATEDTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(desc.getEnumerationType(desc.getKey(i))) + " : " + convertToName(desc.getEnumerationValue(desc.getKey(i)));
break;
case DescValueType.INTEGERTYPE:
txt.text += "\n" + repeatString(" ", indent) + desc.getInteger(desc.getKey(i));
break;
case DescValueType.LISTTYPE:
txt.text += "\n" + repeatString(" ", indent) + desc.getList(desc.getKey(i));
recursiveParseList(txt, indent+indentIncrement, indentIncrement, desc.getList(desc.getKey(i)));
break;
case DescValueType.OBJECTTYPE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(desc.getObjectType(desc.getKey(i))) + " : " + desc.getObjectValue(desc.getKey(i));
recursiveParseDesc(txt, indent+indentIncrement, indentIncrement, desc.getObjectValue(desc.getKey(i)));
break;
case DescValueType.RAWTYPE:
txt.text += "\n" + repeatString(" ", indent) + "\"" + desc.getData(desc.getKey(i)) + "\"";
break;
case DescValueType.REFERENCETYPE:
txt.text += "\n" + repeatString(" ", indent) + desc.getReference(desc.getKey(i));
parseReference(txt, indent+indentIncrement, indentIncrement, desc.getReference(desc.getKey(i)));
break;
case DescValueType.STRINGTYPE:
txt.text += "\n" + repeatString(" ", indent) + "\"" + desc.getString(desc.getKey(i)) + "\"";
break;
case DescValueType.UNITDOUBLE:
txt.text += "\n" + repeatString(" ", indent) + convertToName(desc.getUnitDoubleType(desc.getKey(i))) + " : " + desc.getUnitDoubleValue(desc.getKey(i));
break;
default:
break;
}
indent = indent-indentIncrement;
}
}
Example output for just the section of the key 'CrnT' (current tool options) (when bucketTool was active):
Code: Select all'CrnT' : DescValueType.OBJECTTYPE
'CrnT' : [ActionDescriptor]
'Md ' : DescValueType.ENUMERATEDTYPE
'BlnM' : 'Nrml'
'Opct' : DescValueType.INTEGERTYPE
100
'BckT' : DescValueType.INTEGERTYPE
12
'BckA' : DescValueType.BOOLEANTYPE
true
'BckS' : DescValueType.BOOLEANTYPE
true
'Cntg' : DescValueType.BOOLEANTYPE
true
'BckF' : DescValueType.BOOLEANTYPE
false
'Ptrn' : DescValueType.OBJECTTYPE
'Ptrn' : [ActionDescriptor]
'Nm ' : DescValueType.STRINGTYPE
"$$$/Presets/Patterns/Patterns_pat/Bubbles=Bubbles"
'Idnt' : DescValueType.STRINGTYPE
"b7334da0-122f-11d4-8bb5-e27e45023b5f"
EDIT: Forgot to include desiredClass key in ActionReference parser. Fixed.