Recursive layer.getByName()
As built-in javascript function for Photoshop .getByName() search only at document top level, I wrote a recursive version for my personal use.
Maybe others could find it useful. It returns a javascript object containing a reference to the found layer.
It was successfully tested with Photoshop CS 6 on Mac but I'm far to be a JSX master, so this function certainly be improved.
function getLayerByName(layerName, kind, depth) {
/*
Gets the first layer in the document with the provided name by exploring all document's groups and sub-groups.
Params:
- layerName (string, case sensitive): required
- kind (string): 'NORMAL', or 'TEXT', or empty (default value)
- depth (integer): maximum groups depth to search in. 1 means document's level. 0 means no depth limit (default value)
Returns a Javascript object with the following properties:
- layer: found layer reference, or null if not found
- name: found layer's name, or empty
- kind: found layer's kind, or empty
- group: boolean, true if found layer is a group
- ingroup: boolean, true if found layer is part of a group
- locked: boolean
- visible: boolean
- path: path to found layer, or empty
*/
// --------------------- parameters
depth = (isInteger(depth))? Math.abs(depth) : 0;
kind = normalizeKind(kind) || '';
if (typeof layerName == 'undefined' || layerName == '') return getLayersProps('', '', 'empty layer name');
// --------------------- level 1 : document
var found = false;
try{
var theLayer = app.activeDocument.artLayers.getByName(layerName); // found
if (kind != '') {
if (theLayer.kind == ('LayerKind.' + kind)) {
found = true;
return getLayersProps(theLayer, 'document/', '');
}
}else{
found = true;
return getLayersProps(theLayer, 'document/', '');
}
}catch (err){
}
// --------------------- recursive process (layers and groups)
if (!found) return searchRecursiveLayer(layerName, app.activeDocument, depth, kind, 2, '');
}
function searchRecursiveLayer(layerName, searchObject, depth, kind, searchLevel, path) {
var actualPath = path + searchObject.name + '/';
// alert("searchRecursiveLayer()\n\nsearch for=" + layerName + "\ndepth=" + depth + "\nkind=" + kind + "\nsearchLevel=" + searchLevel + "\nPath=" + actualPath + "\n\nsearchObject=\n" + showDebugObject(searchObject) + "\n\nlayers.length=" + searchObject.layers.length);///// for debugging
if ((depth > 0) && (searchLevel > depth)) return getLayersProps('', actualPath, 'unable to find layer at depth ' + depth);
for (var i = 0 ; i < searchObject.layers.length ; i++) { // loop through single layers or groups
var thisLayer = searchObject.layers;
if (thisLayer.typename == 'LayerSet') {
try{
var theLayer = thisLayer.artLayers.getByName(layerName); // found
if (kind != '') {
if (theLayer.kind == ('LayerKind.' + kind)) return getLayersProps(theLayer, actualPath + thisLayer.name + '/', '');
}else{
return getLayersProps(theLayer, actualPath + thisLayer.name + '/', '');
}
}catch (err){
return searchRecursiveLayer(layerName, thisLayer, depth, kind, searchLevel + 1, actualPath);
}
}else{
if (thisLayer.name == layerName) return getLayersProps(thisLayer, actualPath, ''); // found
}
}
return getLayersProps('', actualPath, 'unable to find layer' + ((kind != '')? (' of kind ' + kind) : '') + ' at depth ' + depth);
}
function getLayersProps(layerRef, path, errStr) {
errStr = errStr || '';
path = path || '';
var resultObject = {'layer': null, 'name': '', 'kind': '', 'group': false, 'ingroup': false, 'locked': false, 'visible': true, 'path': '', 'error': errStr};
if (layerRef == '') return resultObject;
resultObject.layer = layerRef;
resultObject.name = layerRef.name;
resultObject.kind = layerRef.kind;
resultObject.group = (layerRef.typename == 'LayerSet'); // otherwise 'ArtLayer'
resultObject.ingroup = (layerRef.parent.typename != 'Document');
resultObject.locked = layerRef.allLocked;
resultObject.visible = layerRef.visible;
resultObject.path = path;
resultObject.error = errStr;
return resultObject;
}
function isInteger(value) {
if (isNaN(parseInt(value,10)) || (parseInt(value,10) != value - 0)) return false;
return true;
}
function normalizeKind(kind) {
return (kind.replace(/^\s+|\s+$/g,'')).toUpperCase();
}
function normalizeKind(kind) {
return (kind.replace(/^\s+|\s+$/g,'')).toUpperCase();
}
funct
Example:
if (app.documents.length > 0) {
var layerToSearch = prompt('Name of layer to search for:', 'Test');
var depth = prompt('Maximum depth to search in (0 for no depth limit):', 0);
var kind = prompt('Layer kind to search (NORMAL | TEXT | empty):', '');
var searchResult = getLayerByName(layerToSearch, kind, depth);
alert("getLayerByName()\nName param='" + layerToSearch + "'\nKind param='" + kind + "'\nDepth param=" + depth + "\n\n" + showResultObject(searchResult));
}
function showResultObject(resultObject) { // for demo purpose
var strResult = '';
for (var prop in resultObject) {
strResult += '[' + prop + '] = ' + ((Object.prototype.toString.call(resultObject[prop]) === '[object String]')? ("'" + resultObject[prop] + "'") : resultObject[prop]) + "\n";
}
return strResult;
}
function showDebugObject(object) { // for debug purpose
return object + "\nname=" + ob
