Copy link to clipboard
Copied
Good day dear audience!
Sorry for my bad English. I ask for help in writing a script for the extension panel.
There is a script button and a slider:
<button class="tool" id="gb_3b"><div class="inst">Start</div></button>
<b>Middle radius: <span style="font-size: 1.2em" id="gb3rval"></span></b>
<div id="gblur3rad"></div>
Running the script and initializing the slider in JS:
$("#gb_3b").button().click(function(a) {
csInterface.evalScript('$._ext.evalFile("' + extensionRoot + 'work/Smart_Frequency_3_Band_GB.jsxbin")')
});
$(function() {
$('#gblur3rad').slider({
min: 0.1,
max: 20,
step: 0.1,
value: 5,
create: setInputsFromSlider1,
slide: setInputsFromSlider1,
stop: setInputsFromSlider3
});
function setInputsFromSlider1() {
$('#gb3rval').text($('#gblur3rad').slider("value"));
};
function setInputsFromSlider3() {
var radius = $('#gblur3rad').slider("value");
csInterface.evalScript('GBlur3S("'+radius+'")', function() {csInterface.evalScript('GBlur3S2("'+radius+'")');});
};
};
main.jsx which is specified in the manifest:
function GBlur3S(radius) {
var idslct = charIDToTypeID( "slct" );
var desc16 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref5 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
ref5.putName( idLyr, "Base Middle GB" );
desc16.putReference( idnull, ref5 );
var idMkVs = charIDToTypeID( "MkVs" );
desc16.putBoolean( idMkVs, false );
var idLyrI = charIDToTypeID( "LyrI" );
var list3 = new ActionList();
list3.putInteger( 3 );
desc16.putList( idLyrI, list3 );
executeAction( idslct, desc16, DialogModes.NO );
var idsetd = charIDToTypeID( "setd" );
var desc34236 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref236 = new ActionReference();
var idfilterFX = stringIDToTypeID( "filterFX" );
ref236.putIndex( idfilterFX, 1 );
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref236.putEnumerated( idLyr, idOrdn, idTrgt );
desc34236.putReference( idnull, ref236 );
var idfilterFX = stringIDToTypeID( "filterFX" );
var desc34237 = new ActionDescriptor();
var idFltr = charIDToTypeID( "Fltr" );
var desc34238 = new ActionDescriptor();
var idRds = charIDToTypeID( "Rds " );
var idPxl = charIDToTypeID( "#Pxl" );
desc34238.putUnitDouble( idRds, idPxl, radius );
var idGsnB = charIDToTypeID( "GsnB" );
desc34237.putObject( idFltr, idGsnB, desc34238 );
var idfilterFX = stringIDToTypeID( "filterFX" );
desc34236.putObject( idfilterFX, idfilterFX, desc34237 );
executeAction( idsetd, desc34236, DialogModes.NO );
};
function GBlur3S2(radius) {
var idslct = charIDToTypeID( "slct" );
var desc16 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref5 = new ActionReference();
var idLyr = charIDToTypeID( "Lyr " );
ref5.putName( idLyr, "Base Middle GB (H)" );
desc16.putReference( idnull, ref5 );
var idMkVs = charIDToTypeID( "MkVs" );
desc16.putBoolean( idMkVs, false );
var idLyrI = charIDToTypeID( "LyrI" );
var list3 = new ActionList();
list3.putInteger( 3 );
desc16.putList( idLyrI, list3 );
executeAction( idslct, desc16, DialogModes.NO );
var idsetd = charIDToTypeID( "setd" );
var desc34236 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref236 = new ActionReference();
var idfilterFX = stringIDToTypeID( "filterFX" );
ref236.putIndex( idfilterFX, 1 );
var idLyr = charIDToTypeID( "Lyr " );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref236.putEnumerated( idLyr, idOrdn, idTrgt );
desc34236.putReference( idnull, ref236 );
var idfilterFX = stringIDToTypeID( "filterFX" );
var desc34237 = new ActionDescriptor();
var idFltr = charIDToTypeID( "Fltr" );
var desc34238 = new ActionDescriptor();
var idRds = charIDToTypeID( "Rds " );
var idPxl = charIDToTypeID( "#Pxl" );
desc34238.putUnitDouble( idRds, idPxl, radius );
var idGsnB = charIDToTypeID( "GsnB" );
desc34237.putObject( idFltr, idGsnB, desc34238 );
var idfilterFX = stringIDToTypeID( "filterFX" );
desc34236.putObject( idfilterFX, idfilterFX, desc34237 );
executeAction( idsetd, desc34236, DialogModes.NO );
};
After executing the script 2 smart layers with blur are formed. When you move the slider, the blur radius changes simultaneously in both layers.
Until then, everything works. But I would like to make it possible to set the value of the radius slider and this value was transferred to the external JSX.
Here is the part of JSX code where you need to insert a variable from JS:
//
// SmartFrequency3_BandGB.jsx
//
//
// Generated Thu Aug 02 2018 01:02:07 GMT+0300
//
cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };
//
//==================== Smart Frequency 3-Band GB ==============
//
function SmartFrequency3_BandGB() {
function step1(enabled, withDialog) {
if (enabled != undefined && !enabled)
return;
var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
var desc1 = new ActionDescriptor();
var ref1 = new ActionReference();
ref1.putProperty(cTID('Prpr'), cTID('CchP'));
ref1.putEnumerated(cTID('capp'), cTID('Ordn'), cTID('Trgt'));
desc1.putReference(cTID('null'), ref1);
var desc2 = new ActionDescriptor();
desc2.putInteger(cTID('HsSt'), 1);
desc1.putObject(cTID('T '), cTID('CchP'), desc2);
executeAction(sTID('set'), desc1, dialogMode);
};
// code
function step21(enabled, withDialog) {
if (enabled != undefined && !enabled)
return;
var dialogMode = (withDialog ? DialogModes.ALL : DialogModes.NO);
var desc1 = new ActionDescriptor();
desc1.putUnitDouble(cTID('Rds '), cTID('#Pxl'), radius);
executeAction(sTID('gaussianBlur'), desc1, dialogMode);
};
step1();
// code
step21();
};
//=========================================
// SmartFrequency3_BandGB.main
//=========================================
//
SmartFrequency3_BandGB.main = function () {
SmartFrequency3_BandGB();
};
SmartFrequency3_BandGB.main();
// EOF
"SmartFrequency3_BandGB.jsx"
// EOF
How to pass "radius" variable from JS to JSX?
Я тоже тупой. В расширениях вообще не шарю)).
Но мне попалось одно демо-расширение.
Там был такой код на кнопку. в js-файле.
$("#rgb_c").button().click(function(a) { csInterface.evalScript('$._ext.evalFile("'+extensionRoot+'tools/RGB.jsx")')});
Я изменил его на вот такой.
$("#rgb_c").button().click(function(a) { csInterface.evalScript('var xxx= 1; $._ext.evalFile("'+extensionRoot+'tools/RGB.jsx")')});
В файле RGB.jsx воткнул такой код
alert(xxx)
Запустил фотошоп, нажал кнопку, получил правильный алерт
...Copy link to clipboard
Copied
Is that impossible? Or is my English so bad?
Copy link to clipboard
Copied
I do not use and do not understand anything in extensions. But try to use the search.
For example, maybe this will help
Re: How to pass information between JS Extension and JSX host
Copy link to clipboard
Copied
Do I understand it correctly that the .js file is web browser JavaScript?
If so, I don't see why it should not be possible to pass the radius variable to the .jsx (which is Photoshop JavaScript) as an argument when you call the .jsx file.
Copy link to clipboard
Copied
You must have a function in JSX which accepts an argument.
JS:
$("#TEST").click(function(){
var str = "Hello World";
var myString = "runMyScript('" + str + "')";
csInterface.evalScript(myString);
});
JSX:
function runMyScript(message){
alert(message);
};
Copy link to clipboard
Copied
Yes. In the example above, I did just that. And it works. The question was a bit different. How to pass a variable to any other path, not to the JSX path that is written in the manifest file.
I have a lot of JSX in the extension. Here is an example of how they are called from JS:
$("#TEST").button().click(function(a) {
csInterface.evalScript('$._ext.evalFile("' + extensionRoot + 'jsx/test.jsx")')
});
Due to poor knowledge of scripts I can not understand how to pass a variable in such JSX
Copy link to clipboard
Copied
Oh, I see. What if you try this:
Just have your main JSX function that you pass in data into from the JS.
Except, this time, pass in your jsx path to the final jsx script you wish to run as well as the variables you with to send.
In fact, use not the evalFile but use the evalScript.
Then in your JSX that is described in the manifest that is being called, you have one 'distribution' function which reads in the target jsx path via eval and uses other pieces of your data to do things like choose which function to run and the arguments to that function.
Copy link to clipboard
Copied
Thanks. But I know too little scripts to understand how to do it.
Copy link to clipboard
Copied
Let's pretend you have lots of jsx files, among which one is your host script:
jsx/host_script.jsx
jsx/function_1.jsx
jsx/function_2.jsx
jsx/function_3.jsx
Inside each one which is not the host_script.jsx you may have a series of functions like this:
function func_1a( inStr ){
alert(func_1a.name + "(): " + inStr);
}
function func_1b( inStr ){
alert(func_1b.name + "(): " + inStr);
}
You'd need an object to serve as the data-holder as well as the instructions for who will do work on this data:
var instructionObj = {
scriptToRun : "function_1.jsx",
functionToRun : "func_1a",
inStr : "HEY!"
}
And in your main jsx file, the host_script.jsx you may have a controlling function whose job will be to take your CEP-js data and relay it to its proper destination:
function runMyJsx( instructionObj ){ // are these auto-parsed from JSON into objects? I don't remember..
// setting the vars up for clarity
var scriptToRun = instructionObj.scriptToRun; // "function_1.jsx"
var functionToRun = instructionObj.functionToRun; // "func_1a"
var inStr = instructionObj.inStr; // "HEY!"
// if the 'script to run' isn't already included in the host_script.jsx via '#include function_1.jsx' then bring it in.
// here's a way without doing a file.read(): https://forums.adobe.com/thread/2412769
eval("#include " + scriptToRun); // now it theoretically should be available for use- let me know how it goes?
// time to release the hounds!
eval(functionToRun + "(" + inStr.toSource() + ")"); // func_1 : HEY!
}
Of course then you'd call your JS function with an evalScript("runMyJsx('" + JSON.stringify(instructionObj) + "')");
So there you have it, dynamic choice of an individual jsx file, a function from that file and a piece of data that is meant for that function.
I have not tested any of this with actual CEP, would like to see results either way.
Good luck! I hope this ends up working for you!
Copy link to clipboard
Copied
I tried to do exactly as you have written. Created a separate file function_1.jsx. Which contains a single function
function func_1a( inStr ){
alert(func_1a.name + "(): " + inStr);
}
In HTML add a button for this JSX
<button class="test" id="myFunct">TEST</button>
In JS wrote so
$("#myFunct").button().click(function(a) {
var instructionObj = {
scriptToRun : "function_1.jsx",
functionToRun : "func_1a",
inStr : "HEY!"
};
csInterface.evalScript("runMyJsx('" + JSON.stringify(instructionObj) + "')");
});
And in main jsx file main.jsx wrote so
function runMyJsx( instructionObj ){
var scriptToRun = instructionObj.scriptToRun;
var functionToRun = instructionObj.functionToRun;
var inStr = instructionObj.inStr;
eval("#include " + scriptToRun);
eval(functionToRun + "(" + inStr.toSource() + ")");
}
And nothing happens when you press the button TEST
Copy link to clipboard
Copied
Sorry, it does appear that the JSON object passed in is not auto-parsed - maybe it was vice-versa when data goes back to the JS and I did forget.
So, now make sure to have the JSON code inside of your host script.
"object"!=typeof JSON&&(JSON={}),function(){"use strict";function f(t){return 10>t?"0"+t:t}function quote(t){
return escapable.lastIndex=0,escapable.test(t)?'"'+t.replace(escapable,function(t){var e=meta
; return"string"==typeof e?e:"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+t+'"'}
function str(t,e){var n,r,o,f,u,i=gap,p=e
;switch(p&&"object"==typeof p&&"function"==typeof p.toJSON&&(p=p.toJSON(t)), "function"==typeof rep&&(p=rep.call(e,t,p)),typeof p){case"string":return quote(p);case"number":return isFinite(p)?String(p):"null";
case"boolean":case"null":return String(p);case"object":if(!p)return"null";if(gap+=indent,u=[],"[object Array]"===Object.prototype.toString.apply(p)){
for(f=p.length,n=0;f>n;n+=1)u
=str(n,p)||"null";return o=0===u.length?"[]":gap?"[\n"+gap+u.join(",\n"+gap)+"\n"+i+"]":"["+u.join(",")+"]",gap=i,o} if(rep&&"object"==typeof rep)for(f=rep.length,n=0;f>n;n+=1)"string"==typeof rep
&&(r=rep ,o=str(r,p),o&&u.push(quote(r)+(gap?": ":":")+o)); else for(r in p)Object.prototype.hasOwnProperty.call(p,r)&&(o=str(r,p),o&&u.push(quote(r)+(gap?": ":":")+o));return o=0===u.length?"{}":gap?"{\n"+gap+
u.join(",\n"+gap)+"\n"+i+"}":"{"+u.join(",")+"}",gap=i,o}}"function"!=typeof Date.prototype.toJSON&&(Date.prototype.toJSON=function(){
return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+
f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){
return this.valueOf()});var cx,escapable,gap,indent,meta,rep;"function"!=typeof JSON.stringify&&
(escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
meta={"\b":"\\b"," ":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},JSON.stringify=function(t,e,n){var r;
if(gap="",indent="","number"==typeof n)for(r=0;n>r;r+=1)indent+=" ";else"string"==typeof n&&(indent=n);if(rep=e,
e&&"function"!=typeof e&&("object"!=typeof e||"number"!=typeof e.length))throw new Error("JSON.stringify");return str("",{"":t})}),
"function"!=typeof JSON.parse&&(cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
JSON.parse=function(text,reviver){function walk(t,e){var n,r,o=t
;if(o&&"object"==typeof o)for(n in o)Object.prototype.hasOwnProperty.call(o,n)&& (r=walk(o,n),void 0!==r?o
=r:delete o );return reviver.call(t,e,o)}var j;if(text=String(text),cx.lastIndex=0,cx.test(text)&& (text=text.replace(cx,function(t){return"\\u"+("0000"+t.charCodeAt(0).toString(16)).slice(-4)})),
/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@")
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]")
.replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return j=eval("("+text+")"),"function"==typeof reviver?walk({"":j},""):j;
throw new SyntaxError("JSON.parse")})}();
Then make sure to add this line into the runMyJsx function:
function runMyJsx( instructionObj ){
instructionObj = JSON.parse(instructionObj);
...
Copy link to clipboard
Copied
Thank you very much for your help. But I guess I'm too stupid. When I included the presented code in my host script, all other buttons in the panel stopped working.
Copy link to clipboard
Copied
Я тоже тупой. В расширениях вообще не шарю)).
Но мне попалось одно демо-расширение.
Там был такой код на кнопку. в js-файле.
$("#rgb_c").button().click(function(a) { csInterface.evalScript('$._ext.evalFile("'+extensionRoot+'tools/RGB.jsx")')});
Я изменил его на вот такой.
$("#rgb_c").button().click(function(a) { csInterface.evalScript('var xxx= 1; $._ext.evalFile("'+extensionRoot+'tools/RGB.jsx")')});
В файле RGB.jsx воткнул такой код
alert(xxx)
Запустил фотошоп, нажал кнопку, получил правильный алерт ))
Может это как раз то, что надо?
Copy link to clipboard
Copied
This is the standard code to run the script with a button in the extension. I have all the JSX is and start. And what you offered was something I couldn't think of myself. Everything genius is simple! Thank you very much! That's exactly what I needed. Everything worked fine.
Copy link to clipboard
Copied
Wow that's even easier!
Copy link to clipboard
Copied
I must be really stupid. What you offered worked perfectly. But there is one unclear point.
There is such here is code
$(function() {
$('#gblur3rad').slider({
min: 0.1,
max: 20,
step: 0.1,
value: 5,
create: setInputsFromSlider11,
slide: setInputsFromSlider11,
stop: setInputsFromSlider13
})
function setInputsFromSlider11() {
$('#gb3rval').text($('#gblur3rad').slider("value"));
}
function setInputsFromSlider13() {
var radius = $('#gblur3rad').slider("value");
csInterface.evalScript('GBlur3S("'+radius+'")', function() {csInterface.evalScript('GBlur3S2("'+radius+'")');});
}
$("#gb_3b").button().click(function(a) {
var rds = $('#gblur3rad').slider("value");
csInterface.evalScript('var rad = "rds"; $._ext.evalFile("' + extensionRoot + 'work/Smart_Frequency_3_Band_GB.jsx")')
});
});
If I set the rad variable to a numeric value, everything works fine. But how can I instead of a number to substitute the variable there rds? In such look as it is written down at me var rad = "rds", it does not work. Requires a numeric value. Requires a numeric value.
P.S. I'm really stupid ))) var rad = " '+rds+' " and it worked.
Copy link to clipboard
Copied
This thread moved from Photoshop Scripting to Extensions / Add-ons Development.