Confused about suspend history usage

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

Sorry for my OCD, but I think you meant doStuff() :sweat_smile:

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() :smile:
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 :smile:
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);
}