Copy link to clipboard
Copied
Hello gang!
I just wanted to share with you my small utility tool for Photoshop called Clean SL that cleans ScriptingListenerJS.log file to make it more readable.
Recently watched Davide_Barranca's Adobe Photoshop HTML Panels Development course and realised how painful it is to work with Action Manager's code and how unreadable it is right off the box. I know there are quite a few other tools that cleans log file, however it doesn't hurt to have an option to choose.
Interested? Grab it here: rendertom / Clean SL / source / — Bitbucket
Script performs multiple actions such as cleaning-up variable names and hoisting them to the top, wraps code block into function, converts charID to string ID for better readability and such. Resulting code is clean and maintains better readability.
From this:
var idHStr = charIDToTypeID( "HStr" );
var desc21 = new ActionDescriptor();
var idpresetKind = stringIDToTypeID( "presetKind" );
var idpresetKindType = stringIDToTypeID( "presetKindType" );
var idpresetKindCustom = stringIDToTypeID( "presetKindCustom" );
desc21.putEnumerated( idpresetKind, idpresetKindType, idpresetKindCustom );
var idClrz = charIDToTypeID( "Clrz" );
desc21.putBoolean( idClrz, false );
var idAdjs = charIDToTypeID( "Adjs" );
var list1 = new ActionList();
var desc22 = new ActionDescriptor();
var idH = charIDToTypeID( "H " );
desc22.putInteger( idH, 39 );
var idStrt = charIDToTypeID( "Strt" );
desc22.putInteger( idStrt, 23 );
var idLght = charIDToTypeID( "Lght" );
desc22.putInteger( idLght, -27 );
var idHsttwo = charIDToTypeID( "Hst2" );
list1.putObject( idHsttwo, desc22 );
desc21.putList( idAdjs, list1 );
executeAction( idHStr, desc21, DialogModes.NO );
to this:
hueSaturation();
function hueSaturation() {
var s2t = function (s) {
return app.stringIDToTypeID(s);
};
var descriptor = new ActionDescriptor();
var list = new ActionList();
var descriptor2 = new ActionDescriptor();
descriptor.putEnumerated( s2t( "presetKind" ), s2t( "presetKindType" ), s2t( "presetKindCustom" ));
descriptor.putBoolean( s2t( "colorize" ), false );
descriptor2.putInteger( s2t( "hue" ), 39 );
descriptor2.putInteger( s2t( "saturation" ), 23 );
descriptor2.putInteger( s2t( "lightness" ), -27 );
list.putObject( s2t( "hueSatAdjustmentV2" ), descriptor2 );
descriptor.putList( s2t( "adjustment" ), list );
executeAction( s2t( "hueSaturation" ), descriptor, DialogModes.NO );
}
Clone or download repository and place Clean SJ.jsx script to Photoshop’s Scripts folder:
Adobe Photoshop CC 20XX -> Presets -> Scripts -> Clean JS.jsx
Restart Photoshop to access Clean JS script from File -> Scripts
------------------------------------------------
Since I am rather new to Photoshop Scripting, I might have missed something of my code brakes. So if you find any bugs or issues, please do not hesitate to let me know so I could fix it.
So, happy cleaning everybody!
Copy link to clipboard
Copied
SuperMerlin schrieb
Panic over, I was trying ctrl/c ctrl/v after selecting the text, this does not work for me, but right click and select copy does work. How strange is that!
Hmmh?
click (selecting the text) and then strg+c strg+v (eg in editor) works for me under Windows as well.
Copy link to clipboard
Copied
How ScriptUI works depends on the version in use. For example a single click in the clean code pain will select all in the panel in the scriptUI version iset in CC 2017. The same click in older ScriptUI versions will only highlights the clean code frame. While you can select test within it its a bear to select and scroll to select wall the cleaned code its not actually useable. In CC 2017 if to start selecting in the window you have the same problem. But you can switch to the source window and then switch to the clean window to select all.
ScriptUI was implemented using flash in older version of Photoshop where newer versions of ScriptUI was recorded html. There were many issues with the new version most have been fixed and the are still inconsistent behaviors between versions. The may be differences between platforms also Paul left this forum because Adobe never fixed bugs he reported. Adobe only chooses to fix some reported bugs. There are bugs in Photoshop the have been reported that remain in Photoshop release after release. There are some incompatibilities between versions of Photoshop.
Copy link to clipboard
Copied
SuperMerlin wrote
Just found a bug in the increment function, it is putting a space between the function name and the increment number. A quick fix.
newVariableVersion = coreName.replace(/^\s+|\s$/g,'') + versionNumber;
I tried that quick fix it did not work. It only seemed to remove a single space. I do not know jacascript and regular expressions are above my pay grade. All I could do us take my hammer and chisel and hack at his code. My scupture is not a work of art but the monster works for me. So I cam now un check Convert charID to stringID and the cleaned up code works where if fails if I check Convert charID to stringID. However the has also clear up the problem I was having with the thir mat failing in the return statement at the top if the step.
This is my ugly hack please clean it up.
function increment(string, storedArray) {
var coreName, newVariableVersion, versionNumber;
coreName = string.replace(/\d+$/, "");
coreName = coreName.replace(/^\s+|\s$/g,'');
coreName = coreName.replace(/^\s+|\s$/g,'');
coreName = coreName.replace(/^\s+|\s$/g,'');
newVariableVersion = coreName;
versionNumber = 2;
while (contains(storedArray, newVariableVersion)) {
newVariableVersion = coreName + versionNumber;
versionNumber++;
}
storedArray.push(newVariableVersion);
return newVariableVersion;
}
Copy link to clipboard
Copied
WAW that's great of you! Thank you so much !!!
Copy link to clipboard
Copied
Heya!
Came across this but it does not seem to be working for Photoshop 2020? Will this be updated you think? I get a lot of errors even with simple things unless I remove the codes.
Copy link to clipboard
Copied
The make that fails is a make text layer so any make text will fail. So disabled convert charID to stringID option will fix the problem for me anyway. Action manager code recorded by scriptlisten is nasty to look at. Russ and Davide know scripting I just hack at it.
Copy link to clipboard
Copied
Much love to everyone contributing, especially JJMack for testing it. Love you guys!
Clean SL v1.3 is online: Please remove old Clean SL Settings.txt file before using this update.
Enjoy!
Copy link to clipboard
Copied
Great rounds of updates, thank you, Tomas!
Copy link to clipboard
Copied
What have I done wrong? Is there a dependency on this JSON2.JS file? Latest CC17…
Is this the one?
Copy link to clipboard
Copied
Yeap, download entire repository and link to json2.js file will be valid.
I had to used this library for reading/parsing UI data.
Copy link to clipboard
Copied
I have both files in the presets/scripts folder and the error persists. What am I doing wrong?
Do I need to remove the comments from line 52? Remove the comments and change to the absolute install path?
?
Copy link to clipboard
Copied
Then just update the path on line 52 to link to json2.js file
//@include "custom/path/to/json2.js"
Copy link to clipboard
Copied
I have updated the code:
//@include "/Applications/Adobe Photoshop CS6/Presets/Scripts/json2.js"
Should I be using CC17 instead? I usually have ScriptListener in a lesser used “sandpit” version, in this case CS6.
Now returns a new error:
EDIT: Same error in CC17. I have tried moving the JSON2 file into different folders, both inside and outside of the logged in User’s folder with the same results (obviously updating the path each time).
Copy link to clipboard
Copied
Steven, can you please try this build? Dropbox - Clean SL v1.3.jsxbin
It has JSON2 built-in, so you don't need to change anything. Please let me know if that works
Copy link to clipboard
Copied
Works fine! Thanks, I am interested to test, so thank you!
Copy link to clipboard
Copied
Geat update Thomas all seem to work Thank You for my option. To get an extra lone log all you need to do is add a test layer. Text is a beast that is why I added a text layer. It showed up the the problem you have now fixed. I wish Adobe would fix a few more of their bugs. So I may could use CC 2017 instead of being gun shy duck and use CC 2014.
Copy link to clipboard
Copied
Davide_Barranca JJMack SuperMerlin xbytor2
I think I found a bug in my code, but I need your advice.
Some of CharIDs return empty StringID - can this happen?
For instance, I have this script that returns ~90% empty StringIDs. Could you check this for me? Or am I loosing my mind? If such things happen, I will fix it, but before I do that, I need your input, couse you guys have more exp with AM then I do.
(function () {
var charIDs = ["SWOp", "OpSa", "DIDr", "In ", "Fmt ", "IRFm", "JPEG", "Intr", "Qlty", "QChS", "QCUI", "QChT", "QChV", "Optm", "Pass", "blur", "Mtt ", "EICC", "MttR", "MttG", "MttB", "SHTM", "SImg", "SWsl", "STsl", "SLAl", "SWch", "STch", "CHsR", "SWmd", "STmd", "MDCC", "ohXH", "ohIC", "ohAA", "ohQA", "ohCA", "ohIZ", "ohTC", "SToc", "OC03", "ohAC", "SToc", "OC03", "ohIn", "ohLE", "STle", "LE03", "ohEn", "STen", "EN00", "olCS", "olEC", "STst", "ST00", "olWH", "STwh", "WH01", "olSV", "STsp", "SP04", "olSH", "STsp", "SP04", "ncTp", "STnc", "NC00", "SCnc", "ncTp", "STnc", "NC19", "SCnc", "ncTp", "STnc", "NC28", "SCnc", "ncTp", "STnc", "NC24", "SCnc", "ncTp", "STnc", "NC24", "SCnc", "ncTp", "STnc", "NC24", "SCnc", "olNC", "obIA", "obIP", "obCS", "STcs", "CS01", "ncTp", "STnc", "NC01", "SCnc", "ncTp", "STnc", "NC20", "SCnc", "ncTp", "STnc", "NC02", "SCnc", "ncTp", "STnc", "NC19", "SCnc", "ncTp", "STnc", "NC06", "SCnc", "ncTp", "STnc", "NC24", "SCnc", "ncTp", "STnc", "NC24", "SCnc", "ncTp", "STnc", "NC24", "SCnc", "ncTp", "STnc", "NC22", "SCnc", "ovNC", "ovCM", "ovCW", "ovCU", "ovSF", "ovCB", "ovSN", "Usng", "Expr"];
var stringID;
for (var i = 0, il = charIDs.length; i < il; i++) {
stringID = charIDtoStringID(charIDs);
$.writeln("charID: \"" + charIDs + "\",\tStringID: \"" + stringID + "\"");
}
function charIDtoStringID(charID) {
try {
return typeIDToStringID(charIDToTypeID(charID));
} catch (e) {
alert("Unable to convert \"" + charID + "\" to StringID\n" + e.toString() + "\nLine: " + e.line.toString() + "\n" + charID);
return charID;
}
}
})();
Copy link to clipboard
Copied
Tomas,
I knew that some charID has no correspondence to any stringID, but I run into them quite rarely. I cannot say the reason why, though. Didn't Adobe engineer bother to add them? Some internal stuff only that isn't supposed to be used by third party devs?
Copy link to clipboard
Copied
I think this function was from X
function IDTz(id){
try {
var res = typeIDToStringID( id );
if(res == '' ){
var res = typeIDToCharID( id );
}
}catch(e){}
return res;
}
Copy link to clipboard
Copied
Yeap, got it. Thanks for clearing this for me. Will fix Clean SL to catch and ignore empty StringsIDs.
Thanks guys.
Copy link to clipboard
Copied
Fixed few bugs in Clean SL v1.3.1:
Copy link to clipboard
Copied
Thomas
I want to thank you again for this tool ant the work you have put into it. You know I only hack at scripting. I use windows and control the Scriptlistener log via Windows commands. Which I wrapped into a widows Batch command file. I'm sure you could do something like that on a Mac. If the JSX Launcher works on a Mac and works it does on windows With CC 2014 through CC 2017 you could also have a persistent Palette window in Photoshop to control the log file. If you start the palette before opening any document the Palette will be associated with the JSX Launcher and stick around. As lone as Photoshop and SAX Launcher extension is active. I wrote an Palette script today for windows. You could most likely to use it with Mac OSX and CC 2014 - CC 2017. With the right OSX command. Or even modify it to work on both Windows and Mac machine by testing the users platform. You could distribute is along with Clean SL as a companion palette.
]
Jive messes with formatting Its not much code you should be able to still read it. Or use the link
// JJMack 2017 Control Scriptistener Log in Photoshop
var palette = new Window( "palette" ,"Scriptlistener Log File");
palette.orientation = "row";
palette.btna = palette.add( "button", undefined,'Lock' );
palette.btnb = palette.add( "button", undefined,'UnLock' );
palette.btnc = palette.add( "button", undefined,'Edit' );
palette.btnd = palette.add( "button", undefined,'Clear' );
palette.btnx = palette.add( "button", undefined, "Exit Palette");
customEventManager = {
events: {},
addListener: function( evt, handler, context ) {
if ( !this.events[ evt ] ) {
this.events[ evt ] = [];
}
this.events[ evt ].push( { "handler": handler, "context": context } );
},
trigger: function( evt ) {
if ( this.events[ evt ] ) {
for ( var i = 0; i < this.events[ evt ].length; i++ ) {
this.events[ evt ][ i ].handler.call( this.events[ evt ][ i ].context, evt );
}
}
}
}
palette.btna.onClick = function() {palette.evt.trigger( "Lock" );}
palette.btnb.onClick = function() {palette.evt.trigger( "UnLock" );}
palette.btnc.onClick = function() {palette.evt.trigger( "Edit" );}
palette.btnd.onClick = function() {palette.evt.trigger( "Clear" );}
palette.btnx.onClick = function() {palette.close();};
aHandler = function( evt) {
app.system('Attrib +R "%USERPROFILE%\\Desktop\\ScriptingListenerJS.log"');
}
bHandler = function( evt) {
app.system('Attrib -R "%USERPROFILE%\\Desktop\\ScriptingListenerJS.log"');
}
cHandler = function( evt) {
app.system('Start notepad "%USERPROFILE%\\Desktop\\ScriptingListenerJS.log"');
}
dHandler = function( evt) {
app.system('Echo. > "%USERPROFILE%\\Desktop\\ScriptingListenerJS.log"');
}
palette.evt = customEventManager;
palette.evt.addListener( "Lock", aHandler );
palette.evt.addListener( "UnLock", bHandler );
palette.evt.addListener( "Edit", cHandler );
palette.evt.addListener( "Clear", dHandler );
palette.onShow = function(){
var ww = palette.bounds.width;
var hh = palette.bounds.height;
PaletteDisplay = 0; // Photoshop's First Display
//PaletteDisplay = $.screens.length-1; // Photoshop's Last Display
PaletteTop = $.screens[PaletteDisplay].top + 990; // Relative to Top of display
PaletteLeft] = $.screens[PaletteDisplay].right - ww - 41 ; // Relative to Right of side not Left side of display
palette.bounds.x = PaletteLeft;
palette.bounds.y = PaletteTop;
palette.bounds.width = ww;
palette.bounds.height = hh;
}
//alert($.screens);
palette.show();
Copy link to clipboard
Copied
Gang, what about yet another option in Clean SL to extract method parameters?
It would really work great with small AM codes, like opening documents, changing Hue/Sat, transform, maybe something else, as those use few parameters. However it would actually blow up with textlayers, as there would be >80 params.
But still, trying to explore the possibility.
Before:
transform();
function transform() { ... }
After:
transform(0, 0, 45);
function transform(horizontal, vertical, angle) { ... }
Some examples:
open2(new File( "/Users/rendertom/Desktop/Image.png" ));
function open2(null4) {
var descriptor = new ActionDescriptor();
descriptor.putPath( charIDToTypeID( "null" ), null4 );
descriptor.putInteger( stringIDToTypeID( "documentID" ), 210 );
executeAction( stringIDToTypeID( "open" ), descriptor, DialogModes.NO );
}
hueSaturation(false, 20, 33, 52);
function hueSaturation(colorize, hue, Strt, lightness) {
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var list = new ActionList();
descriptor.putEnumerated( stringIDToTypeID( "presetKind" ), stringIDToTypeID( "presetKindType" ), stringIDToTypeID( "presetKindCustom" ));
descriptor.putBoolean( stringIDToTypeID( "colorize" ), colorize );
descriptor2.putInteger( stringIDToTypeID( "hue" ), hue );
descriptor2.putInteger( charIDToTypeID( "Strt" ), Strt );
descriptor2.putInteger( stringIDToTypeID( "lightness" ), lightness );
list.putObject( stringIDToTypeID( "hueSatAdjustmentV2" ), descriptor2 );
descriptor.putList( stringIDToTypeID( "adjustment" ), list );
executeAction( stringIDToTypeID( "hueSaturation" ), descriptor, DialogModes.NO );
}
transform(-24, 7.5, 54.658385, 55);
function transform(horizontal, vertical, width, height) {
var descriptor = new ActionDescriptor();
var descriptor2 = new ActionDescriptor();
var reference = new ActionReference();
reference.putEnumerated( stringIDToTypeID( "layer" ), stringIDToTypeID( "ordinal" ), stringIDToTypeID( "targetEnum" ));
descriptor.putReference( charIDToTypeID( "null" ), reference );
descriptor.putEnumerated( stringIDToTypeID( "freeTransformCenterState" ), stringIDToTypeID( "quadCenterState" ), stringIDToTypeID( "QCSAverage" ));
descriptor2.putUnitDouble( stringIDToTypeID( "horizontal" ), stringIDToTypeID( "pixelsUnit" ), horizontal );
descriptor2.putUnitDouble( stringIDToTypeID( "vertical" ), stringIDToTypeID( "pixelsUnit" ), vertical );
descriptor.putObject( stringIDToTypeID( "offset" ), stringIDToTypeID( "offset" ), descriptor2 );
descriptor.putUnitDouble( stringIDToTypeID( "width" ), stringIDToTypeID( "percentUnit" ), width );
descriptor.putUnitDouble( stringIDToTypeID( "height" ), stringIDToTypeID( "percentUnit" ), height );
descriptor.putEnumerated( charIDToTypeID( "Intr" ), stringIDToTypeID( "interpolationType" ), stringIDToTypeID( "bicubic" ));
executeAction( stringIDToTypeID( "transform" ), descriptor, DialogModes.NO );
}
Copy link to clipboard
Copied
I think most use Action manager Code to make functions that have parameters. Your tool make it easier to add the parameters for one can actually read your cleaned code. Adding an option to do that would be good. We could use it either way. Text is a beast. I feel I never be able to script text well.
Copy link to clipboard
Copied
Started implementing Extract Parameters function. It's in dev branch. In case someone wants to test it - find it here:
rendertom / Clean SL / source / — Bitbucket
Cheers.