@Stephen Marsh wrote:
I am not happy that I have to select the (variable length) back layer within the active layer set in order to set its name as a variable. As the child layers length is variable (2 or 20 child layers in the set), I can't get the last/back layer via an explicit absolute [index number]. Is there any AM code for this, or a way to do this via DOM, to get the relative name without actually selecting the layer?
not very elegant, but you can do it like this:
[].slice.call(activeDocument.activeLayer.layers).reverse()[0]
When I need to know the location of layers relative to groups, I usually use my getLayersCollection() AM function. It returns a DOM-like object with the document structure and the properties I specified. Further, this object can be easily and quickly parsed using a recursive function. Since indexing in the AM code is the opposite of DOM indexing, the first nested layer in each object will be the bottom one:
/**Get the full structure of document layers (including nested groups)
* as an array of objects. Parameters that you need to specify yourself
* (in the example, the script gets the name, id, type, visibility, three types of layer borders)
*/
#target photoshop
var o = getLayersCollection()
function getLayersCollection() {
var doc = new AM('document'),
lr = new AM('layer'),
indexFrom = doc.getProperty('hasBackgroundLayer') ? 0 : 1,
indexTo = doc.getProperty('numberOfLayers');
return layersCollection(indexFrom, indexTo)
function layersCollection(from, to, parentItem, group) {
parentItem = parentItem ? parentItem : [];
for (var i = from; i <= to; i++) {
var layerSection = lr.getProperty('layerSection', i, true).value;
if (layerSection == 'layerSectionEnd') {
i = layersCollection(i + 1, to, [], parentItem)
continue;
}
var properties = {};
{ /** get AM proprties here */
properties.name = lr.getProperty('name', i, true)
properties.artboard = lr.hasProperty('artboardEnabled', i, true) ? lr.getProperty('artboardEnabled', i, true) : false;
}
if (layerSection == 'layerSectionStart') {
for (o in properties) { parentItem[o] = properties[o] }
group.push(parentItem);
return i;
} else {
parentItem.push(properties)
}
}
return parentItem
}
}
function AM(target, order) {
var s2t = stringIDToTypeID,
t2s = typeIDToStringID;
target = target ? s2t(target) : null;
this.getProperty = function (property, id, idxMode) {
property = s2t(property);
(r = new ActionReference()).putProperty(s2t('property'), property);
id != undefined ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id)) :
r.putEnumerated(target, s2t('ordinal'), order ? s2t(order) : s2t('targetEnum'));
return getDescValue(executeActionGet(r), property)
}
this.hasProperty = function (property, id, idxMode) {
property = s2t(property);
(r = new ActionReference()).putProperty(s2t('property'), property);
id ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id))
: r.putEnumerated(target, s2t('ordinal'), order ? s2t(order) : s2t('targetEnum'));
return executeActionGet(r).hasKey(property)
}
this.descToObject = function (d) {
var o = {}
for (var i = 0; i < d.count; i++) {
var k = d.getKey(i)
o[t2s(k)] = getDescValue(d, k)
}
return o
}
function getDescValue(d, p) {
switch (d.getType(p)) {
case DescValueType.OBJECTTYPE: return { type: t2s(d.getObjectType(p)), value: d.getObjectValue(p) };
case DescValueType.LISTTYPE: return d.getList(p);
case DescValueType.REFERENCETYPE: return d.getReference(p);
case DescValueType.BOOLEANTYPE: return d.getBoolean(p);
case DescValueType.STRINGTYPE: return d.getString(p);
case DescValueType.INTEGERTYPE: return d.getInteger(p);
case DescValueType.LARGEINTEGERTYPE: return d.getLargeInteger(p);
case DescValueType.DOUBLETYPE: return d.getDouble(p);
case DescValueType.ALIASTYPE: return d.getPath(p);
case DescValueType.CLASSTYPE: return d.getClass(p);
case DescValueType.UNITDOUBLE: return (d.getUnitDoubleValue(p));
case DescValueType.ENUMERATEDTYPE: return { type: t2s(d.getEnumerationType(p)), value: t2s(d.getEnumerationValue(p)) };
default: break;
};
}
}
... View more