I just started learning UXP Photoshop development and I’ve run into a snag that I haven’t found anyone else having. I’ve put together a test plugin that simply replaces the text contents of any text layer named “My Text”. When I run the code by clicking on a UI button the batchPlay code doesn’t work unless the alert code line that I was using to troubleshoot is uncommented. This seems like strange behavior. Has anyone experienced this?
Code from main.js:
const app = require("photoshop").app;
const batchPlay = require("photoshop").action.batchPlay;
function change_text () {
require("photoshop").core.executeAsModal(process_layers(app.activeDocument));
}
async function change_text_alchemist_code (layer_id, text) {
// alert(text);
await batchPlay(
[
{
_obj: "set",
_target: [
{
_ref: "layer",
_id: layer_id
}
],
to: {
_obj: "textLayer",
textKey: text
}
}
],
{}
);
}
function process_layers (layers) {
let i,
layer;
for (i = 0; i < layers.layers.length; i += 1) {
layer = layers.layers[i];
if (layer.kind === "group") {
process_layers(layer);
} else {
if (layer.name === "My Text" && layer.kind === "text") {
change_text_alchemist_code(layer.id, "Hello World!");
}
}
}
}
document.getElementById("change_text").addEventListener("click", change_text);
We all experience many strange behaviors in this new async world when we forget to add an await
in front of an async function call. The alert causes enough of a pause that the call goes through. At a glance, I would start by making all the functions async and adding await before each call to them.
As a side note, I would recommend avoiding batchPlay for text. The descriptors are the largest by default. We added support for text in DOM; please take a look.
Sam
1 Like
Hi Sam,
I really appreciate the response!
I had a feeling it was something like that. Unfortunately, that did not fix the issue. I still get the same behavior. It does not update the text without the alert line being uncommented. I will look into the DOM text support but I will need this to work for other batchPlay code that I’m planning on adding.
The revised code still does not work:
const app = require("photoshop").app;
const batchPlay = require("photoshop").action.batchPlay;
async function change_text () {
await require("photoshop").core.executeAsModal(process_layers(app.activeDocument));
}
async function change_text_alchemist_code (layer_id, text) {
// alert(text);
await batchPlay(
[
{
_obj: "set",
_target: [
{
_ref: "layer",
_id: layer_id
}
],
to: {
_obj: "textLayer",
textKey: text
}
}
],
{}
);
}
async function process_layers (layers) {
let i,
layer;
for (i = 0; i < layers.layers.length; i += 1) {
layer = layers.layers[i];
if (layer.kind === "group") {
await process_layers(layer);
} else {
if (layer.name === "My Text" && layer.kind === "text") {
await change_text_alchemist_code(layer.id, "Hello World!");
}
}
}
}
document.getElementById("change_text").addEventListener("click", change_text);
Hi Sam,
The DOM method is not working either.
const app = require("photoshop").app;
async function execute_as_modal () {
await require("photoshop").core.executeAsModal(change_text());
}
async function change_text () {
app.activeDocument.layers[0].textItem.contents = "Hello World!";
}
document.getElementById("change_text").addEventListener("click", execute_as_modal);
Hi Sam,
I found the solution here.
Thanks again for your help.
Ah, yes. executeAsModal
does expect a function as an argument. That is one of hurdles to this new modal paradigm.
This is perhaps an example of where type definitions can help identify issues.