7 Replies Latest reply on Dec 28, 2016 8:13 AM by Kukurykus

    addEventListener callback execute JSX only the first time

    Alberto.B Level 1

      Hello!

      I'm on Photoshop 2017 and as the subject suggests while testing some listeners I found this strange behavior: the addEventListener does get triggered, the callback get called but the evalScript invoking the JSX runs only the first time.

       

      This is how I'm doing it:

       

      ext.JS

      function doSomething(){
       document.getElementById("placeholder").innerHTML += "+";
       csInterface.evalScript("JSXdoSomething",
          function(result){
              document.getElementById("docName").innerHTML += result + ", ";
          });
      }
      
      var csInterface = new CSInterface();
      csInterface.addEventListener("documentAfterActivate",doSomething);
      

       

      in the JSX I have:

      JSXdoSomething = pleaseDo()
      function pleaseDo(){
          return app.activeDocument.name;
      }  
      

       

      now, when switching between documents, this line get executed every time:

      document.getElementById("placeholder").innerHTML += "+";  
      

       

      but the evalScript works only the first time (if you already have a document opened and you open the extension documentAfterActivate gets fired).

       

      E.g.:

      we have 2 documents open: Doc1 and Doc2, the output I'm getting while switching between the two:

      "placeholder" = ++++++...

      "docName" = Doc1, Doc1, Doc1, Doc1...

       

      so the event get fired, the callback update the "placeholder" with `+` but the JSX function doesn't get executed.

       

      I've also tried to call the evalScript in this way:

      a) csInterface.evalScript("pleaseDo" ...

      or

      b) csInterface.evalScript("pleaseDo()" ...

       

      for a) I get the same behavior as described above and for b) I get "EvalScript Error."

       

      I tried to change the JSX in this way:

      $._doSomething = (function(){
         return app.activeDocument.name;
      }());  
      

       

      and call it like this:

      csInterface.evalScript("$._doSomething" ...

       

      I get the same behavior as before: the evalScript get executed only the first time and for the subsequent times the value stored in the return is always the name of the first Document.

      I've also tried to put an alert in the JSX function and sure enough I don't get the pop-up every time I change the document but only the first time.

       

      Have you played with the events? Can you point me in the right direction?

        • 1. Re: addEventListener callback execute JSX only the first time
          JJMack Most Valuable Participant

          I believe scripted events are only triggered from Photoshop UI events. They are not triggered from within automated events they can not be used in a recursive manner.

          • 2. Re: addEventListener callback execute JSX only the first time
            Alberto.B Level 1

            The switching between documents is done interactively while using Photoshop.

            Thinking about your reply it could be that something prevents the evalScript to run exactly because in this way you could switch layer (programmatically this time) and end up in a deadlock?

            • 3. Re: addEventListener callback execute JSX only the first time
              Chuck Uebele Adobe Community Professional & MVP

              Your script will only work one time, because your eventlistener is tied to your JS script becoming activated. The JS is only activated once, so once that happens, it fires your listener, then that's it. If you want to process other documents within PS, then you either need to add a loop or a variable to keep track of which doc is next to process when you click some button or control in your extension panel.

              • 4. Re: addEventListener callback execute JSX only the first time
                Alberto.B Level 1

                I'm sorry I don't think I'm getting what you are saying in the first part of the comment:

                Your script will only work one time, because your eventlistener is tied to your JS script becoming activated. The JS is only activated once, so once that happens, it fires your listener, then that's it.

                The JS, in particular the listener function `doSomething()` is called more than once: every time a document is activated the event is fired. In fact the `placeholder` html element is updated every time the user switches to another document; every time the interactive switch occurs a `+` is added in the innerHTML.

                If I add an alert() inside `doSomething()` it pops up every time I interactively switch to another document.

                evalScript seems not to be able to execute the JSX function more than once, it just returns the value that it collected at the first run.

                 

                In regards to the second part of your reply I need the ability to catch when the user switch to another document; the switch is done through the Photoshop interface not via script/action hence the use of the eventListener.

                • 5. Re: addEventListener callback execute JSX only the first time
                  Kukurykus Adobe Community Professional

                  From my experience I know that when you do something like this:

                   

                  SOMENAME = function someName() {return (...)}

                   

                  then later using SOMENAME() in a code, it will call function put to SOMENAME, so each time the result will be equivalent to that first time function was called. If I'm right that means every next time you can't get the result because result of that first specific situation was already achieved.

                   

                  I'm not expert, and I didn't study particulary all you wrote and your code, but if it's the case then you had to call not SOMENAME() but someName() again.

                   

                   

                  ...this is some theory, I have no idea how it's going to fit to problem you ecountered...

                  • 6. Re: addEventListener callback execute JSX only the first time
                    Alberto.B Level 1

                    Hello Kukurykus,

                    that's what I thought too.

                    So I refactored the code and called someName() instead of SOMENAME but the result sadly didn't change.

                     

                    edit: just for clairty --> if I put an alert() inside the JSX function if comes up only the first time, it seems like evalScript doesn't execute the function; but the event is fired and the callback attached to the event promptly get executed.

                    • 7. Re: addEventListener callback execute JSX only the first time
                      Kukurykus Adobe Community Professional

                      Try this:

                       

                      Put execution of your function to try...catch statement. It has to try something what will be sequent of that you say happens only once, but it won't add any other visible action you wouldn't like if an condition will be true (so during first try). When that sequent action will fail because presciding event won't give expected result, then your script will catch execution of .bat file (with some miminal time of delay, that your current script can stop). Then the .bat file run your script from beggining. This way it let you for clear start, each next time an event doesn't fire. I know it's workaround, but meantime you find what is wrong (I heard those csInterface are specific and buggy some way) you can use this method. If you don't know how to create .bat file with appropiate instructions I hope JJMack can help you as I saw he sometimes uses external files. If not then https://www.autohotkey.com/ will be best way to do it easily.