Installing and using the ScriptingListener plug-in

Not all operations are scriptable using Photoshop's built-in methods. There are a couple of ways to get around this. One is calling a Photoshop Action from your script. If you plan to share scripts with other users, this method requires that other users install the script and any Actions the script calls in order to run the desired operations.

The second is using the ScriptingListener plug-in to capture JavaScript created by Photoshop to build Actions and incorporate this code directly into your script.

Installing the ScriptingListener plug-in:

Quit Photoshop

Locate the ScriptingListener plug-in inside Photoshop's application folder:

Drag the ScriptingListener plug-in into the folder 'Adobe Photoshop Only' in Photoshop's Plug-Ins folder:

Launch Photoshop

Using the ScriptingListener plug-in:

As you work in Photoshop, the ScriptingListener plug-in records JavaScript for any operation which is Actionable to a log file named ScriptingListenerJS.log, which by default is saved to the desktop.

To determine if an operation is Actionable, launch the ScriptingListenerJS.log file and keep the Console visible as you are working. You will see the log update if the operation you just performed is Actionable. Painting, for example, is not an Actionable operation. You can click 'Clear'' at any point to clear the entries in the log.

As you will notice, the Javascript which is recorded by the ScriptingListener plug-in isn't easily read or clearly labeled. Try to get in the habit of recording one step at a time and commenting each operation so you know what it does.

For Example, here is some Javascript for generating a slice:

// =======================================================
var id14 = charIDToTypeID( "Mk  " );
  var desc5 = new ActionDescriptor();
  var id15 = charIDToTypeID( "null" );
	var ref2 = new ActionReference();
	var id16 = stringIDToTypeID( "slice" );
	ref2.putClass( id16 );
  desc5.putReference( id15, ref2 );
  var id17 = charIDToTypeID( "Usng" );
	var desc6 = new ActionDescriptor();
	var id18 = charIDToTypeID( "Type" );
	var id19 = stringIDToTypeID( "sliceType" );
	var id20 = stringIDToTypeID( "user" );
	desc6.putEnumerated( id18, id19, id20 );
	var id21 = charIDToTypeID( "At  " );
	  var desc7 = new ActionDescriptor();
	  var id22 = charIDToTypeID( "Top " );
	  var id23 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id22, id23, 92.000000 );
	  var id24 = charIDToTypeID( "Left" );
	  var id25 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id24, id25, 62.000000 );
	  var id26 = charIDToTypeID( "Btom" );
	  var id27 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id26, id27, 184.000000 );
	  var id28 = charIDToTypeID( "Rght" );
	  var id29 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id28, id29, 231.000000 );
	var id30 = charIDToTypeID( "Rctn" );
	desc6.putObject( id21, id30, desc7 );
  var id31 = stringIDToTypeID( "slice" );
  desc5.putObject( id17, id31, desc6 );
executeAction( id14, desc5, DialogModes.NO );

Here is the code with some comments:

// Create a Slice

/*This javacript creates a user slice, 169px wide by 92px high, at the corrodinates x:62, y:92, with a slice type of 'Image'.*/

var id14 = charIDToTypeID( "Mk  " );
  var desc5 = new ActionDescriptor();
  var id15 = charIDToTypeID( "null" );
		var ref2 = new ActionReference();
		var id16 = stringIDToTypeID( "slice" );
		ref2.putClass( id16 );
  desc5.putReference( id15, ref2 );
  var id17 = charIDToTypeID( "Usng" );
	var desc6 = new ActionDescriptor();
	var id18 = charIDToTypeID( "Type" );
	var id19 = stringIDToTypeID( "sliceType" );
	var id20 = stringIDToTypeID( "user" );
	desc6.putEnumerated( id18, id19, id20 );
	var id21 = charIDToTypeID( "At  " );
	  var desc7 = new ActionDescriptor();
	  var id22 = charIDToTypeID( "Top " );
	  var id23 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id22, id23, 92.000000 );
	  var id24 = charIDToTypeID( "Left" );
	  var id25 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id24, id25, 62.000000 );
	  var id26 = charIDToTypeID( "Btom" );
	  var id27 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id26, id27, 184.000000 );
	  var id28 = charIDToTypeID( "Rght" );
	  var id29 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id28, id29, 231.000000 );
	var id30 = charIDToTypeID( "Rctn" );
	desc6.putObject( id21, id30, desc7 );
  var id31 = stringIDToTypeID( "slice" );
  desc5.putObject( id17, id31, desc6 );
executeAction( id14, desc5, DialogModes.NO );

You can also turn the Javascipt that the ScriptingListener plug-in generates into your own functions:

function makeSlice() {
var id14 = charIDToTypeID( "Mk  " );
  var desc5 = new ActionDescriptor();
  var id15 = charIDToTypeID( "null" );
	var ref2 = new ActionReference();
	var id16 = stringIDToTypeID( "slice" );
	ref2.putClass( id16 );
  desc5.putReference( id15, ref2 );
  var id17 = charIDToTypeID( "Usng" );
	var desc6 = new ActionDescriptor();
	var id18 = charIDToTypeID( "Type" );
	var id19 = stringIDToTypeID( "sliceType" );
	var id20 = stringIDToTypeID( "user" );
	desc6.putEnumerated( id18, id19, id20 );
	var id21 = charIDToTypeID( "At  " );
	  var desc7 = new ActionDescriptor();
	  var id22 = charIDToTypeID( "Top " );
	  var id23 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id22, id23, 92.000000 );
	  var id24 = charIDToTypeID( "Left" );
	  var id25 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id24, id25, 62.000000 );
	  var id26 = charIDToTypeID( "Btom" );
	  var id27 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id26, id27, 184.000000 );
	  var id28 = charIDToTypeID( "Rght" );
	  var id29 = charIDToTypeID( "#Rlt" );
	  desc7.putUnitDouble( id28, id29, 231.000000 );
	  var id30 = charIDToTypeID( "Rctn" );
	desc6.putObject( id21, id30, desc7 );
  var id31 = stringIDToTypeID( "slice" );
  desc5.putObject( id17, id31, desc6 );
executeAction( id14, desc5, DialogModes.NO );
}

Then you can simply call the function every time you want to use it:

makeSlice();

Another neat trick is to move all of your own functions created using the ScriptingListener or from scratch into an external .js file. Then you can use an 'include' to reference the .js file with all your functions, keeping the script your working on neat and tidy.

Here's how you 'Include' a .js file.