Hello guys, this may be a silly question but I am not sure how to use the suspend History with my functions. for example many of my code structured this way:
document.getElementById("btn").addEventListener("click", async function () {
await ExecuteAsModal(() => doStaff());
});
async function doStaff() {
// function 1
// function 2
// batchPlay
//batchPlay
}
In the documentation it says we can use this code: I don’t know where should I add it. any help clarifying this and any example would be much appreciated.
async function historyStateSample(executionContext) {
let hostControl = executionContext.hostControl;
// Get an ID for a target document
let documentID = await getTargetDocument();
// Suspend history state on the target document
// This will coalesce all changes into a single history state called
// 'Custom Command'
let suspensionID = await hostControl.suspendHistory({
"documentID": documentID,
"name": "Custom Command"
});
// modify the document
// . . .
// resume the history state
await hostControl.resumeHistory(suspensionID);
}
btw I am in api 2, manifest 5
1 Like
Sorry for my OCD, but I think you meant doStuff()
That said, docs are full of bugs and the page is very inconsistent - in some places it’s executionContext
and in others it’s executionControl
. So basically your target function receives that as a first argument
Your code could be something like:
document.getElementById("btn").addEventListener("click", async function () {
await ExecuteAsModal(doStuff);
});
async function doStuff(executionContext) {
let hostControl = executionContext.hostControl;
let documentID = await getTargetDocument();
let suspensionID = await hostControl.suspendHistory({
"documentID": documentID,
"name": "Custom Command"
});
// function 1
// function 2
// batchPlay
//batchPlay
await hostControl.resumeHistory(suspensionID);
}
1 Like
The documentation make me more confused to be honest. Yeah its should be doStuff()
I made this simple batchPlay to create new layer and convert to smart object to test it, but when I press the button nothing happens.
document.getElementById("btn").addEventListener("click", async function () {
await ExecuteAsModal(doStuff());
});
async function doStuff(executionContext) {
let hostControl = executionContext.hostControl;
let documentID = await getTargetDocument();
let suspensionID = await hostControl.suspendHistory({
documentID: documentID,
name: "New Layer",
});
// new SO
await batchPlay(
[
{
_obj: "make",
_target: [{ _ref: "layer" }],
using: { _obj: "layer", name: "New Layer" },
},
{ _obj: "mergeVisible", duplicate: true },
{ _obj: "newPlacedLayer" },
],
{}
);
await hostControl.resumeHistory(suspensionID);
}
Too many parentheses. Should be:
await ExecuteAsModal(doStuff)
Note just doStuff
instead of doStuff()
Also - do you have a function getTargetDocument()
? This is from the example in the docs. You should get your document yourself. Maybe app.activeDocument?.id
would do if you want it for active document
1 Like
Thank you @Karmalakas it works now
here is the whole code for others who need it:
document.getElementById("btn").addEventListener("click", async function () {
await ExecuteAsModal(doStuff);
});
async function doStuff(executionContext) {
let hostControl = executionContext.hostControl;
// let documentID = await getTargetDocument();
let suspensionID = await hostControl.suspendHistory({
documentID: app.activeDocument?.id,
name: "New Layer",
});
// new SO
await batchPlay(
[
{
_obj: "make",
_target: [{ _ref: "layer" }],
using: { _obj: "layer", name: "New Layer" },
},
{ _obj: "mergeVisible", duplicate: true },
{ _obj: "newPlacedLayer" },
],
{}
);
await hostControl.resumeHistory(suspensionID);
}
1 Like
I’m not sure if the code works on API2. Following is verified working code on API 2 with UXP Developer tool console for someone needs.
async function doStuff(executionContext) {
let result = null; // batchPlay()
await require('photoshop').core.executeAsModal(async function() { // await executeAsModal (API 2)
result = await require('photoshop').action.batchPlay([ // await batchPlay
{
_obj: "make",
_target: [
{
_ref: "layer"
}
],
using: {
_obj: "layer",
name: "New Layer"
}
},
{
_obj: "mergeVisible",
duplicate: true
},
{
_obj: "newPlacedLayer"
}
], {synchronousExecution: false}) // false = async
});
return result;
}
async function doStuffWithSuspendHistory(executionContext) {
let result = null; // batchPlay()
let hostControl = executionContext.hostControl;
let suspensionID = await hostControl.suspendHistory({
documentID: require('photoshop').app.activeDocument.id,
name: "New Layer (test)", // History name
});
result = await doStuff();
await hostControl.resumeHistory(suspensionID);
}
// await require('photoshop').core.executeAsModal(doStuff); // without suspend history
await require('photoshop').core.executeAsModal(doStuffWithSuspendHistory);
1 Like
Does anyone know if this works with API2. I am trying to add a button to the above code but haven’t had luck running it:
document.getElementById("test").addEventListener("click", doStuff);
async function doStuff(executionContext) {
let result = null; // batchPlay()
await require('photoshop').core.executeAsModal(async function() { // await executeAsModal (API 2)
result = await require('photoshop').action.batchPlay([ // await batchPlay
{
_obj: "make",
_target: [
{
_ref: "layer"
}
],
using: {
_obj: "layer",
name: "New Layer"
}
},
{
_obj: "mergeVisible",
duplicate: true
},
{
_obj: "newPlacedLayer"
}
], {synchronousExecution: false}) // false = async
});
return result;
}
async function doStuffWithSuspendHistory(executionContext) {
let result = null; // batchPlay()
let hostControl = executionContext.hostControl;
let suspensionID = await hostControl.suspendHistory({
documentID: require('photoshop').app.activeDocument.id,
name: "New Layer (test)", // History name
});
result = await doStuff();
await hostControl.resumeHistory(suspensionID);
}
// await require('photoshop').core.executeAsModal(doStuff); // without suspend history
await require('photoshop').core.executeAsModal(doStuffWithSuspendHistory);
with a simple html:
<!DOCTYPE html>
<html>
<head>
<script src="main.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<sp-button id="test">test me</sp-button>
<footer>
</footer>
</body>
</html>