Hoping to get some clarification as to why this happens.
With apiVersion set to 1 you get a deprecated warning, but you also get a a full list of all layers when calling app.activeDocument.layers. Each layer object has an array of children objects. This structure makes it easy to build a full snapshot of the entire layer structure of a file without having to use BatchPlay.
With API2, only the top-level layers are listed and as far as I can see there is no access to children info.
This seems odd to me that upgrading the API results in less usability. Is there a reason for this?
Jarda
August 19, 2022, 7:18pm
2
Each group should have .layers
property with its childs.
Ah you’re correct. Thanks. I need to use BatchPlay to get layers anyway since recursing these objects is too slow.
Jarda
August 20, 2022, 10:50pm
4
Yes it is… since there is no caching and it asks PS so many times…
Make sure to check multiGet first. https://twitter.com/J_Bereza/status/1555977684479627265
Also, you can always make a new Layer()
instance based on IDs.
@Jarda or anyone:
I tried to use the Twitter thread code linked above to create a list of all layers in the document. Here’s the code I’m using:
const docRef = {
_ref: "document",
_id: this.id,
};
const allLayers = await batchPlay([{
_obj: "multiGet",
_target: docRef,
extendedReference: [
[
"name",
"layerID",
],
{
_obj: "layer",
index: this.backgroundLayer ? 0 : 1,
count: -1,
},
],
},], {"modalBehavior": "execute",})
.then(result => {return result[0].list}, error => {console.log(error)})
console.log(allLayers)
I get an error that says: Error: NAPI API failure: Number expected
and the line referenced as causing the error is:
.then(result => {return result[0].list}, error => {console.log(error)})
I get all kinds of syntax errors when I try to include the line:
public get allLayers():{name: string, layerID: number}[]{
So that’s why I tried coming up with some alternate code, but I’m obviously not getting it right.
Any thoughts?
Jarda
August 28, 2022, 9:23am
6
1 Like
Thanks for that reminder @Jarda .
Working code below. If anyone has any suggestions for simplifying or improving, please post.
const batchPlay = require("photoshop").action.batchPlay;
const hasBackgroundLayer = await batchPlay([
{ _obj: "get", _target: [ { _property: "hasBackgroundLayer" }, { _ref: "document", _enum: "ordinal", _value: "targetEnum" } ], _options: { dialogOptions: "dontDisplay" } }
],{}).then(result => {return result[0].hasBackgroundLayer}, error => {console.log(error)});
const layerProperties = await batchPlay([
{ _obj: "multiGet",
_target: { _ref: [{_ref: "document", _enum: "ordinal"}]},
extendedReference: [["name", "layerID"], {_obj: "layer", index: hasBackgroundLayer ? 0 : 1, count:-1}],
options: {failOnMissingProperty:false, failOnMissingElement: false}
}], {});
console.log(layerProperties[0].list)
Jarda
August 28, 2022, 5:46pm
8
I think it should be ok like this for active document.
const batchPlay = require("photoshop").action.batchPlay;
const hasBackgroundLayer = await batchPlay([
{
_obj: "get",
_target: [
{_property: "hasBackgroundLayer"},
{_ref: "document", _enum: "ordinal", _value: "targetEnum"}
],
}
], {});
const layerProperties = await batchPlay([
{
_obj: "multiGet",
_target: {_ref: "document", _enum: "ordinal"},
extendedReference: [["name", "layerID"], {_obj: "layer", index: hasBackgroundLayer ? 0 : 1, count: -1}]
}], {});
console.log(layerProperties[0].list)
Anyway, I would personally prefer to edit the document prototype or extend the Document class. So you can use this.
keyword as shown in my tweet. https://developer.adobe.com/photoshop/uxp/2022/ps_reference/media/prototype/