Highlighted

When is a script closed (time of unregistering)?

Advocate ,
Dec 02, 2016

Copy link to clipboard

Copied

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!

TOPICS
Scripting

Views

364

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more

When is a script closed (time of unregistering)?

Advocate ,
Dec 02, 2016

Copy link to clipboard

Copied

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!

TOPICS
Scripting

Views

365

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Dec 02, 2016 0
Engaged ,
Dec 03, 2016

Copy link to clipboard

Copied

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

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 03, 2016 0
Engaged ,
Dec 03, 2016

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 03, 2016 0
Enthusiast ,
Dec 03, 2016

Copy link to clipboard

Copied

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.

Likes

Translate

Translate

Report

Report
Community Guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
Reply
Loading...
Dec 03, 2016 0