3 Replies Latest reply on Dec 3, 2016 3:32 AM by Klaus Göbel

    When is a script closed (time of unregistering)?

    K.Daube Level 1

      Dear friends and experts!
      To avoid one (or more) of the special effects reported in this forum Klaus Göbel proposes to unregister the script when it is closed. But: when is the script closed?

      I did not get a formal education in interactive programming, hence I have no real clue about the process: what is calling what. My programming experience is in procedural languages starting with Fortran in the 1960ies.

      Please point me to a document describing all this - the Scripting Guide does not tell. And of course JavaScript books don't either.
      The only sample script using Notify is FM_Suppress_Alerts.jsx and this is absolutely simplistic.
      My understanding is this:

      • Starting the script registers it - 'purchases' a watch dog (IMHO not the same as registering an FDK client).
      • After starting the script it establishes the menu and configures the watchdog called Notification.
      • Within FM there is a nother watchdog barking at (the cat) Command when a menu item is selected.
      • Command calls the appropriate routine and then sleeps again (return tells the watch dog: have done!)
      • Notify is waked up on special events and calls appropriate routines (return tells the watch dog: have done!)
      • After a user has performed a menu selection and the the requested functions have been performed: where are we in the script? At the end of Command? At the end of main (that's really unreasonable).

      The main structure of my script is this:

      // --- Windows ID must be set outside the dialogue function to be available for Notify functions
      var wPalC  = new Window("palette","FM-calc : Handle #calc Markers",    undefined); 
      //... also wPalS and wPalDS
        main ();
      
      function main () {
        SetUpGlobals ();                                // all global variables and constants
        SetupFMcalc ();                                 // get inital data -- debug to be set explicitly
        SetupNotifications ();                          // notification trigger 'Change document' etc.
        // --- During development switch between the two following statements:
        SetUpMenus(); // uncomment for real work
        //DebugMenu (); // comment for real work - debugging does not work with menus
      }
      #include funGlobals.jsx
      //... more includes
      function SetUpMenus () {
         //...
      }
      function Command (cmd) {
         //...
      }
      function SetupNotifications () {
         //...
      }
      function RemoveMyNotification() { 
         //...
      }
      function Notify (note, object, sparam, iparam) { 
         //...
      }
      //--- now follow the functions directly called from Command
      function OpenHelpFile () 
      function DoFMcalcInSelection()
      function DoFMcalcInDoc ()  
      function DoFMcalcInBook ()  
      function HandleCalcMarkers() 
      function HandleSeriesMarkers() 
      function HandleDocSettings() 
      //...And all the others which I want to have in this module
      

      In the past I had the call of RemoveMyNotification in the call-back functions for the Cancel/Exit buttons in the panels. But now I guess that the best place would be at the end of the Command function: After anything has been done.
      But: SetUpNotifications is within the main function and will not be executed anymore after the script has been started the first time.

      I need a better insight, sigh!

        • 1. Re: When is a script closed (time of unregistering)?
          Wiedenmaier Level 3

          Hi Klaus,

           

          I don't know if I understand your question correctly, but I'll give it a try.

           

          FM loads a script, when it is registered or when it is in a startup Folder (user dir, inst dir). This script is never unloaded. It is always there, as well as its global variables. Only a function finishes, when its job is done.

           

          Your main function is called when the script is loaded by FM, or better by the ExtendScript plugin (fminit\FrameMakerScriptingSupport.dll). So your notifications are registered when FM is started, and they stay registered as long they are unregistered (Notification(YOURNOTIFACATIONOFINTEREST, false)).

           

          So if you don't want to be notified again, you have to call that function somewhere in your code, perhabs when any function ends. Lets say you have a checked menu (true/false), which enables or disables an Event handler, so put the code in there.

           

          I don't understand, why it makes sense to deactivate a notification after a command is executed. But if you Need this in your Special use case, call this at the end of the command event handler (Command(cmd)). Then FM get back the Control and this function is finished.

           

          Of if you don't Need it any more, after an Event is called the first time, unhook it at the end of the notify eventhandler (Notify (note, object, sparam, iparam)).

           

          Markus

          • 2. Re: When is a script closed (time of unregistering)?
            Wiedenmaier Level 3

            Hi Klaus,

             

            one recommendation. Write one script for each use case you want to solve:

             

            • one which handles your command
            • one for each notification you are interested in

             

            If you want to make a reuse of some functions, put these in some separate jsx-files and include them, where they are needed.

            In this case your notification (watch dog) script is very simple.

             

            #include "something.jsx"

             

            Notification(YOURNOTIFACATIONOFINTEREST, true)

            function Notify (note, object, sparam, iparam)

            {

                switch(note)

                {

                      case YOURNOTIFACATIONOFINTEREST;

                          DoSomething() ;

                          break;

                }

            }

             

            Put this script to your startup folder and the commands also. This is easier to maintain, then registering anything in one single script.

            • 3. Re: When is a script closed (time of unregistering)?
              Klaus Göbel Level 3

              Hi Klaus,

               

              here some scripts:

               

              EventTest1

              alert ("Start TEST1","TEST1");
              TestString = "First";
               w1 = new Window("palette","My First Test",undefined);
               CloseButton = w1.add ("button",undefined,"close",{name:"cancel"})
               w1.show();
               CloseButton.onClick = function(){w1.close()};
              
              Notification(Constants.FA_Note_PostMouseCommand,true);
              
              w1.onClose=GoodBye;
                  
              
              function Notify(note, object)
              {
                  switch (note)
                      {
                      case Constants.FA_Note_PostMouseCommand:
                          {
                          alert("TEST1: " + TestString,"TEST1");
                          break;
                          }
                      }
              }
              
              function GoodBye()
              {
                  alert("BYE1","TEST1");
                      Notification(Constants.FA_Note_PostMouseCommand,false);
                  };
              

               

              EventTest2

              alert ("Start TEST2","TEST2 ");
              TestString = "Second";
               w2 = new Window("palette","My Second Test",undefined);
               CloseButton = w2.add ("button",undefined,"close",{name:"cancel"})
               w2.show();
               CloseButton.onClick = function(){w2.close()};
              
              Notification(Constants.FA_Note_PostMouseCommand,true);
              
              w2.onClose=function(){alert("BYE2","TEST2")};
              
              function Notify(note, object)
              {
                  switch (note)
                      {
                      case Constants.FA_Note_PostMouseCommand:
                          {
                          alert("TEST2: "  + TestString,"TEST2: ");
                          break;
                          }
                      }
              }
              
              

               

              EventTest3

              alert ("Start TEST3","TEST3");
              TestString = "Third";
              
               w3 = new Window("palette","My Third Test",undefined);
               CloseButton = w3.add ("button",undefined,"close",{name:"cancel"})
               w3.show();
               CloseButton.onClick = function(){w3.close()};
              
                Notification(Constants.FA_Note_PostMouseCommand,true);
              
              w3.onClose=function(){alert("BYE3","TEST3")};
              
              function Notify(note, object)
              {
                  switch (note)
                      {
                      case Constants.FA_Note_PostMouseCommand:
                          {
                           
                          alert("TEST3: "  + TestString,"TEST3");
                          break;
                          }
                      }
              }
              
              

               

               

              Testsequence:

               

              - Open any document.

              - Start EventTest3 first, then EventTest2 and then EventTest1

               

              DON'T CLOSE THEM YET, only click OK.

               

              You can see these scripts in your scriptlibrary (radiobutton registered) ordered like this:

              EventTest3

              EventTest2

              EventTest1

               

              Because the dialogues are overlapping, move them.

              DON'T CLOSE THEM YET

               

              Click into the document at any place:

              Now you can see the alerts :

              - TEST3: First

              - TEST2: First

              - TEST1: First

               

              Now close all dialogs

               

              Click into the document at any place:

              Now you can see the alerts :

              - TEST3: First

              - TEST2: First

               

              "TEST1: First" is missing, because it is unregistered

               

              Have a look at the value of the variable "TestString" (First)

               

              Now restart FrameMaker and open any document.

               

              You can see  in your scriptlibrary (radiobutton registered) registered scripts ordered like this:

              EventTest2

              EventTest3

               

              And when clicking into the document you'll get the order:

              TEST2: Third

              TEST3: Third

              because it now is in alphabetical order.

               

              If you NOW change EventTest2:

              alert("TEST2: "  + TestString,"TEST2: ");
              

              to

              alert("New TEST2: "  + TestString,"TEST2: ");
              

               

              you can see, that this is displayed.

              Means: if you have a real script where lots of things happen and you change the script (while it is still registered) this function is called and can cause what cou call "special effects"

               

               

              and of course: after the test you have to remove the registered scripts manually

              That demonstrates the danger within registering / not unregistering scripts and and also the usage of global variables.

               

              I hope, that helps to understand these things a little better.

              I also hope this does NOT lead to additional confusion.