How to check if there is a selection in the active document with UXP?

I am porting a cep extension to UXP. It used app.activeDocument.selection.bounds in a try-catch block to check whether there was actually a selection present.

The documentation mentions a selection class (https://www.adobe.io/photoshop/uxp/ps_reference/classes/selection/), but I have not found any way to access it. (require("photoshop").app.activedocument.selection evaluates to undefined)

What would be the proper way to perform this kind of check in Photoshop UXP?

This is how I am doing it in my plugin. If you don’t need the selection coordinates var then you can replace the try line with try{await getSelectionBounds();}

var selectionExists=true;    
try{var selectionBounds=await getSelectionBounds();}
catch(e){selectionExists=false;}

async function getSelectionBounds(){

const idDoc=await app.activeDocument._id;

const result = await require("photoshop").action.batchPlay(
[
   {
  "_obj": "get",
  "_target": [
     {
        "_property": "selection"
     },
     {
        "_ref": "document",
        "_id": idDoc
     }
  ],
  "_options": {
     "dialogOptions": "dontDisplay"
  }
   }
],{
   "synchronousExecution": false,
   "modalBehavior": "fail"
});


const left = result[0].selection.left._value;
const top = result[0].selection.top._value; 
const right = result[0].selection.right._value; 
const bottom = result[0].selection.bottom._value;  

return [left,top,right,bottom];    

}

const idDoc=await app.activeDocument._id;

Note that you possibly won’t need to await the ID, just use:

const idDoc = app.activeDocument._id

Oh, one more thing regarding "_target" section of your code above:
idDoc is used for targeting the current opened document using its ID, that’s OK.

 {
    "_ref": "document",
    "_id": idDoc
 }

That’s (by default) how Alchemist generates a code from the opened document, using "_id"

However, sometimes you just need to target the current opened document, and you can avoid getting its ID by just targeting the current opened document like so:

{
    "_ref": "document",
    "_enum": "ordinal",
    "_value": "targetEnum"
}

Cheers!

1 Like

Thanks a bunch! I had no idea you could use “_obj”: “get” to simply get various properties in Photoshop.

Additionally, Thank you for this extra info as well!

I have seen some things I thought didn’t need await cause timing issues on some computers but not on other computers. Because of that, I have been adding await when in doubt just in case it needs it. It doesn’t seem to hurt it.

I didn’t know about the method you suggested or the current doc ID. I’ll try that.

Generally you only need await on asynchronous code, for example promises or async functions (that essentially return promises). When it comes to batchplay, there are two possible return values:
Descriptor and Promise<Descriptor>. Normally, it will return a promise, but if you add { synchronousExecution: true } as the batchPlay options, it will already wait for that internally and return a Descriptor.

In regards to the Photoshop API it’s always clearly stated in the docs when a function is async, for example:
image