Extending PS Objects

Discussion of Photoshop Scripting, Photoshop Actions and Photoshop Automation in General

Moderators: Tom, Kukurykus

russ_c

Extending PS Objects

Post by russ_c »

Hey,

I'm a bit new to Javascript and the PS API, so I think part of my challenge is not having my brain full wrapped around Javascript inheritance and Classes, but what I'd like to do is extend Document and other PS objects with my own methods.

I know I can extend intrinsic objects through prototype like this:

Code: Select allif (typeof String.prototype.endsWith != 'function') {
  String.prototype.endsWith = function (str){
    return this.slice(-str.length) == str;
  };
}

The problem is that I don't understand how Application, Object, and Document Objects relate to figure out how to extend them. I would like to extend all instances of Document by doing something like this:

Code: Select allif (typeof Application.Document.revert != 'function')
{
    Application.Document.revert = function ()
    {
        executeAction( charIDToTypeID( "Rvrt" ), undefined, DialogModes.NO );
    }
}

var doc = app.activeDocument;
doc.revert();


I've noticed that alert(Application.prototype) produces [object Object] , but alert(Document) or alert(Document.prototype) produces a script error because Document is undefined. Any help on understanding how to extend and change PS intrinsic objects would be great!

Professional AI Audio Generation within Adobe Premiere Pro - Download Free Plugin here

Mike Hale

Extending PS Objects

Post by Mike Hale »

I am not sure why but the Photoshop Classes don't seem to be loaded until there are needed. So you have to do something like this to extend the Document class.
Code: Select allapp.activeDocument;// make any kind of reference that loads the Document class
Document.prototype.revert = function (){// extend the class
        executeAction( charIDToTypeID( "Rvrt" ), undefined, DialogModes.NO );
}
app.activeDocument.revert();// use the new method with any instance of the class
russ_c

Extending PS Objects

Post by russ_c »

Wow, how interesting. This explains why my recent discovery that the following...works:

Code: Select allif (typeof app.activeDocument.constructor.prototype.revert != 'function')
{
    app.activeDocument.constructor.prototype.revert = function ()
    {
        app.activeDocument = this
        executeAction( charIDToTypeID( "Rvrt" ), undefined, DialogModes.NO );
    }
}

Unfortunately, this puts a bit of a kink in my plans because using app.activeDocument is not safe in the instance that there are no open documents! I was hoping to put this extension and others in there own .jsxinc file and then #include them at the top of every script to have access to my expanding methods.

Wait...maybe, I haven't tested this yet, but just putting app.activeDocument in a try catch might get the Document object to load?

Russ
xbytor

Extending PS Objects

Post by xbytor »

I've put in requests for something like $.loadClass("Document") before but to no avail.

I'm not sure if anybody else has figured out a way to do this.
russ_c

Extending PS Objects

Post by russ_c »

russ_c wrote:Wait...maybe, I haven't tested this yet, but just putting app.activeDocument in a try catch might get the Document object to load?


Ugh, No...this does not seem to work without an open document:

Code: Select alltry
{
    //Force PS to load Document() Object
    app.activeDocument;
}
catch(e)
{
    //ignore
}

if (typeof Document.prototype.revert != 'function')
{
     Document.prototype.revert = function ()
    {
        app.activeDocument = this
        executeAction( charIDToTypeID( "Rvrt" ), undefined, DialogModes.NO );
    }
}

But this does work, but it seems really nasty:

Code: Select all//Force PS to load Document() Object
try
{
    app.activeDocument;
}
catch(e)
{
    var doc = app.documents.add(1,1);
    doc.close (SaveOptions.DONOTSAVECHANGES);
}

if (typeof Document.prototype.revert != 'function')
{
     Document.prototype.revert = function ()
    {
        app.activeDocument = this
        executeAction( charIDToTypeID( "Rvrt" ), undefined, DialogModes.NO );
    }
}
russ_c

Extending PS Objects

Post by russ_c »

xbytor wrote:I've put in requests for something like $.loadClass("Document") before but to no avail.

I'm not sure if anybody else has figured out a way to do this.

Great idea...point me where to request this and I'll add a voice.
Mike Hale

Extending PS Objects

Post by Mike Hale »

You could follow Adobe's example and only extend the Document class if the script needs it( and the class has been referenced ).

Instead of using the #include preprocessor statement use $.evalFile(). For example;
Code: Select allvar doc = app.activeDocument;
$.evalFile('String:full path to script');// load the Document class extensions including the revert method
doc.revert();