After removing the line
descriptor.putObject( s2t( "replaceLayer" ), s2t( "placeEvent" ), descriptor );
everything worked perfectly!
That is strange, I get the same results with or without that line... However, you are correct that it doesn't appear to be required. I trimmed away a lot of unnecessary code that was recorded by the ScriptingListener plugin but missed that one.
I also have an additional question that I hope you could help with. Is there a way to determine if a layer is of the type 'frame'? I'm looking to further refine my script and this piece of information would be incredibly helpful.
By @Adi1231234
Yes, I can help you there.
I know that you are new to scripting, so let me try to explain... In the legacy ExtendScript used by Photoshop before the new UXP scripting, there were two types of code:
* ExtendScript Document Object Model code (DOM)
* ExtendScript Action Manager code (AM)
DOM code is high-level, more "user friendly" and legible than AM code, which is low-level, more like "machine language". Unfortunately, DOM code doesn't cover many areas of Photoshop, so we have to use AM code. AM code can sometimes provide performance benefits over DOM code, it doesn't matter that the code is more verbose than DOM.
The previous code that I provided to place an image is AM code, which has been greatly simplified from the source and placed into a JavaScript Function.
Now that I have given you some background context, it's time to answer your question regarding checking/testing that the active layer is a Frame.
In the standard DOM code, Adobe shares the same entry for Layer Groups, Artboards and Frames. This is the
"LayerSet" typename. As long as there is no chance that you may have a Layer Group selected, you can just use standard DOM code to ensure that the active layer isn't another layer kind:
if (app.activeDocument.activeLayer.typename == "LayerSet") {
placeInSelectedFrame(File.openDialog("Select the file to place into the Frame:"), false);
} else {
alert("The layer '" + app.activeDocument.activeLayer.name + "' isn't a Frame layer...");
}
function placeInSelectedFrame(theFile, linked) {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
descriptor.putPath(s2t("null"), theFile); // File path
descriptor.putBoolean(s2t("linked"), linked); // Linked/embedded boolean
descriptor.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSAverage")); // Place and fit
executeAction(s2t("placeEvent"), descriptor, DialogModes.NO);
}
However, if you need the script to be able to differentiate between a Frame and not a Layer Group, then you need more complex AM code:
if (isFrame()) {
placeInSelectedFrame(File.openDialog("Select the file to place into the Frame:"), false);
} else {
alert("The layer '" + app.activeDocument.activeLayer.name + "' isn't a Frame layer...");
}
function placeInSelectedFrame(theFile, linked) {
function s2t(s) {
return app.stringIDToTypeID(s);
}
var descriptor = new ActionDescriptor();
descriptor.putPath(s2t("null"), theFile); // File path
descriptor.putBoolean(s2t("linked"), linked); // Linked/embedded boolean
descriptor.putEnumerated(s2t("freeTransformCenterState"), s2t("quadCenterState"), s2t("QCSAverage")); // Place and fit
executeAction(s2t("placeEvent"), descriptor, DialogModes.NO);
}
function isFrame() {
// modified from a script by greless with hints from jazz-y!
try {
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID('layer'), stringIDToTypeID('ordinal'), stringIDToTypeID('targetEnum'));
var options = executeActionGet(r);
return options.hasKey(stringIDToTypeID('framedGroup')); // test for the required key, returns true or false
} catch (e) {}
}
https://community.adobe.com/t5/photoshop-ecosystem-discussions/custom-script-for-renaming-artboards-with-multiple-elements/m-p/13498536