[JS] Menu Added via Scripting Moves

Adobe Community Professional ,
Dec 16, 2011 Dec 16, 2011

Copy link to clipboard

Copied

I've been able to sucessfully add items to the InDesign menu thanks in part to Marijan Tompa's (tomaxxi) blog post http://indisnip.wordpress.com/2010/08/08/create-customized-menu/

My test code (below) creates a new menu, and sucessfully adds two menu items plus a submenu. The submenu is causing me problems. When you first launch InDesign it's created in the proper place (in the middle of the menu). But when you relaunch InDesign, the submenu moves to the top of the menu and never goes back to it's proper position farther down in the menu where it was the first time InDesign was launched.

I've searched high and low in this forum, the web and InDesign's documentation and can't figure out how to keep it from moving (I want the menu to be farther down the menu, not at the top). I hope one of you kind souls will help me to control the position of the submenu (and have it stay there across launches).

Thanks in advance!

Dan

Here's the code I'm working with. This is saved as testMenu.jsx in the Scripts > startup scripts folder.

P.S. I'm testing this in CS5.5 currently, but ideally this solution should work in CS3 and later.

#targetengine "myTestMenu"

var myFolder = Folder(app.activeScript.path);

myFolder = myFolder.parent + '/Scripts Panel/';

var menuItem1Handler = function( /*onInvoke*/ ){

  app.doScript(File(myFolder + 'MyTest1.jsx'));

};

var menuItem2Handler = function( /*onInvoke*/ ){

  app.doScript(File(myFolder + 'MyTest2.jsx'));

};

menuInstaller()

function menuInstaller() {

  var menuItem1T = "My Menu Item 1",

       menuItem2T = "My Menu Item 2",

       menuT = "MyTestMenu",

             subT = "Sub Menu",

       subs = app.menus.item("$ID/Main").submenus, sma, mnu;

  var refItem = app.menus.item("$ID/Main").submenus.item("$ID/&Layout");

  subMenu1 = app.scriptMenuActions.item(menuItem1T);

  if( subMenu1 == null ) {

          subMenu2 = app.scriptMenuActions.add(menuItem1T);

  }

  subMenu2 = app.scriptMenuActions.item(menuItem2T);

  if( subMenu2 == null ) {

          subMenu2 = app.scriptMenuActions.add(menuItem2T);

  }

  subMenu2.eventListeners.add("onInvoke", menuItem2Handler);

  mnu = subs.item(menuT);

  if( mnu == null ) {

            mnu = subs.add(menuT, LocationOptions.after, refItem);

  }

  mnu.menuItems.add(subMenu1);

  mnu.menuSeparators.add();

  subsSubs = app.menus.item( '$ID/Main' ).submenus.item( menuT ).submenus;

  mnuSubMenu = subsSubs.item( subT );

  if( mnuSubMenu == null ) {

          mnuSubMenu = subsSubs.add( subT);

  }

  mnu.menuItems.add(subMenu2);

};


— Adobe Certified Expert & Instructor at Noble Desktop | Web Developer, Designer, InDesign Scriptor
TOPICS
Scripting

Views

17.4K

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
community guidelines

correct answers 1 Correct answer

Adobe Community Professional , Dec 17, 2011 Dec 17, 2011
Thank you all so much for your replies, and thank you Harbs for making it finally work! Just to make sure this can serve as a resource for others in the future, below is a final (working) menu based on Harb's code. I also added 2 submenu items just to be complete.Thanks again everyone. I'm so glad you could help get this working!Dan#targetengine "HarbsTestMenu"menuInstaller(); function menuInstaller() {    // SET THE FILES THAT ARE TRIGGERED BY MENU ITEMS    menuItem1Handler = function( /*onInvo...

Likes

Translate

Translate
Engaged ,
Dec 14, 2017 Dec 14, 2017

Copy link to clipboard

Copied

LATEST

Great.

-Sumit

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
community guidelines
Guide ,
Dec 17, 2011 Dec 17, 2011

Copy link to clipboard

Copied

Hi Dan,

There would be much to say about your code (variable scope, etc.) but the two most important, I think, are:

— Custom menus and submenus are application-persistent while script menu actions are (usually) session-persistent

In the specific case where an action directly relies on a script file, you don't need to deal w/ session-persistence and you can directly address the script file (no need of app.doScript() stuff and so on).

Here is a possible approach (provided that the featured script files are located in the parent folder of the Startup scripts folder):

#targetengine "DanRodneyMenu"

// =====================================

// This script is a 'startup script', it runs each time ID starts

// and shouldn't be rerun during the session. We don't really need

// it to be session-persistent. However we use a #targetengine to

// save a 'done' flag which prevents the script from being rerun.

// =====================================

(function(/*obj|undefined*/HOST)

// -------------------------------------

// Install and/or update the menu/submenu

// and connect the menu actions

{

    // ---

    // HOST can be your framework container, if needed (default: $.global)

    // ---

    HOST || (HOST=$.global);

    // ---

    // Prevent the current (startup) script from being uselessly rerun

    // ---

    if( HOST[$.engineName] )

        {

        alert( "This script is automatically executed at startup. You shouldn't run it manually." );

        return;

        }

        // ---

    HOST[$.engineName] = true;

    // ---

    // Settings and constants

    // ---

    var MENU_NAME = "My Test Menu",

        FEATURES = [

            { caption: "My Menu Item 1", fileName: 'File-One.jsx', subName: "" },

            { caption: "My Menu Item 2", fileName: 'File-Two.jsx', subName: "My Sub Menu" }

            ],

        LO_END = LocationOptions.atEnd,

        INDESIGN_ROOT_MENU = app.menus.item( '$ID/Main' ),

        FEATURE_LOCATION_PATH = (function()

            {

            var f;

            try{ f=app.activeScript; }

            catch(_){ f=File(_.fileName); }

            return f.parent.parent + '/';

            })();

    // ---

    // (Re)set the actions

    // Note: checks also whether script files are available

    // ---

    var    t, f, i = FEATURES.length;

    while( i-- )

        {

        t = FEATURES;

        if( (f=File(FEATURE_LOCATION_PATH + t.fileName)).exists )

            {

            // The script file exists => create the corresponding action

            // and directly attach the event listener to the file

            // (no need to use app.doScript(...) here)

            // ---

            (t.action = app.scriptMenuActions.add( t.caption )).

                addEventListener('onInvoke', f);

            }

        else

            {

            // The script file does not exist => remove that feature

            // ---

            FEATURES.splice(i,1);

            }

        }

    // ---

    // Create/reset the custom menu container *if necessary*

    // Note:  menus/submenus are application-persistent

    // ---

    var    mnu = INDESIGN_ROOT_MENU.submenus.itemByName( MENU_NAME );

    if( !mnu.isValid )

        {

        // Our custom menu hasn't been created yet

        // ---

        if( !FEATURES.length ) return;

        mnu = INDESIGN_ROOT_MENU.submenus.add(

            MENU_NAME,

            LocationOptions.after,

            INDESIGN_ROOT_MENU.submenus.item( '$ID/&Window' )

            );

        }

    else

        {

        // Our custom menu already exists, but we must clear

        // any sub element in order to rebuild a fresh structure

        // ---

        mnu.menuElements.everyItem().remove();

        // If FEATURES is empty, remove the menu itself

        // ---

        if( !FEATURES.length ){ mnu.remove(); return; }

        }

    // ---

    // Now, let's fill mnu with respect to FEATURES' order

    // (Possible submenus are specified in .subName and created on the fly)

    // ---

    var s,

        n = FEATURES.length,

        subs = {},

        sub = null;

    for( i=0 ; i < n ; ++i )

        {

        t = FEATURES;

        // Target the desired submenu

        // ---

        sub = (s=t.subName) ?

            ( subs || (subs=mnu.submenus.add( s, LO_END )) ) :

            mnu;

        // Connect the related action

        // ---

        sub.menuItems.add( t.action );

        }

})();

@+

Marc

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
community guidelines
LEGEND ,
Dec 18, 2011 Dec 18, 2011

Copy link to clipboard

Copied

That's odd. John's post seems to exist, but doesn't show up...

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
community guidelines
LEGEND ,
Dec 18, 2011 Dec 18, 2011

Copy link to clipboard

Copied

That seemed to do it... Weird...

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
community guidelines
LEGEND ,
Dec 18, 2011 Dec 18, 2011

Copy link to clipboard

Copied

That's odd. John's post seems to exist, but doesn't show up...

It's worse than that. Cache corruption.

Viewing from adobe-vm-wa06.sgvm2hosted.jiveland.com

I see my post but not your replies. Dumping cookies and reloading

fixes it, because I get another server.

I'll start a thread in Forum Comments.

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
community guidelines