Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
7

[ExtendScript] How to use "afterNew" event

Community Expert ,
Dec 04, 2023 Dec 04, 2023

Hi all, I'm trying to run some ExtendScript code when the user creates a new document but I'm not getting it to work. I've probably made a basic mistake, which someone can point out, but otherwise, could anyone test my script on their system?

 

I expect it to name the first Layer "TEST" but for me it throws an error (which the script handles and displays in an alert).

 

I'm using Indesign 19.0.1 and MacOS 14.1.2.

 

Here is my test case, whch I run from the Startup Scripts folder:

 

 

//@targetengine "test"

if (app.eventListeners.item("afterNew").isValid)
    app.eventListeners.item("afterNew").remove();

app.eventListeners.add("afterNew", myHandler);

function myHandler(ev) {

    var messages = [
        'ev.parent.constructor.name = ' + ev.parent.constructor.name,
        'app.layoutWindows.length = ' + app.layoutWindows.length,
        'app.modalState = ' + app.modalState,
    ];

    try {
        // do something to the DOM
        ev.parent.layers[0].name = 'TEST';
        messages.unshift('Success');
    }
    catch (error) {
        messages.unshift('Failed:');
        messages.push('error: ' + error.message + ' (line: ' + error.line + ')');
    }
    finally {
        alert(messages.join('\n'));
    }

};

 

 

This is what I see every time I create a new document:

Screenshot 2023-12-05 at 18.45.50.png

Thanks in advance.

- Mark

 

Edit 2023-12-05: added an alert even if the test was successful, added screenshot.

TOPICS
Scripting
3.1K
Translate
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 2 Correct answers

Enthusiast , Dec 06, 2023 Dec 06, 2023

Tried with InDesign 19.0.1 and macOS 12.6.7.

 

It always succeeds when in the legacy new document  dialog. New format new document dialog causes errors. Even when it succeeds, the modalState is true, and it seems to be executed before it finishes creating the document.

 

alert.png

Translate
Guide , Dec 06, 2023 Dec 06, 2023

Hi Mark,

 

Since afterNew is triggered whenever a document is created, it can occur in various circumstances including when a modal dialog is active, due e.g. to the Preview checkbox of the New document dialog. (Maybe this also occurs under other conditions…)

 

The script below helps clarify this.

 

//----------------------------------
// TEST AFTER_NEW
// [REM] This script does not require a persistent engine,
// run it once to install the event handler.
//----------------------------------

(functio
...
Translate
Guide ,
Dec 08, 2023 Dec 08, 2023

Hi guys,

 

An Idle task approach would probably look like this [I cannot see a solution without tagging a label or so]

 

//----------------------------------
// DOC CREATION EVENT HANDLER
// [REM] This script does not require a persistent engine,
// run it once to install the event handler. (Can also be
// used as startup script.)
//----------------------------------

(function(/*any*/ev,  doc,ff,t)
{
   const UID = 'myDocCreationIdleEventHandler';

   if( !(ev||0).isValid )
   {
      // Install the event listener (if not yet ready.)
      // ---
      (ff=File($.fileName)).exists
      && !((t=app.idleTasks).itemByName(UID)).isValid
      && (t=t.add({ name:UID, sleep:500 }).eventListeners)
      && ((t.add('onIdle',ff)).name=UID);
   }
   else
   {
   	  // Checkpoint and additional conditions.
   	  // ---
      'onIdle'==ev.eventType
      && !app.modalState
      && (doc=app.properties.activeDocument)
      && !doc.properties.saved
      && !doc.extractLabel(UID)
      // DOM-Process.
      // ---
      &&
      (
         doc.insertLabel(UID,'1'),
         doc.layers[0].name='TEST'
         // etc
      );
   }

})($.global.evt);

 

Best,

Marc

Translate
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
Community Expert ,
Dec 09, 2023 Dec 09, 2023

Thanks Marc, that really helpful too. - Mark

Translate
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
Valorous Hero ,
Dec 09, 2023 Dec 09, 2023

Here are my couple of cents:

I think Marc’s code (the first one) doesn’t work as intended. modalState is true in both cases: with the default and legacy New Document dialog box. So, in my opinion, it makes no sense to check if it’s true/false. The problem occurs with the default dialog when the user clicks the ‘Create’ button or turns on the ‘Preview’ checkbox: the error — Cannot handle the request because a modal dialog or alert is active. — is generated. It happens while the script attempts to rename the layer.

I suggest the following modifications: check if the specific error occurs and give a warning offering the user to turn the legacy dialog on.

//----------------------------------
// TEST AFTER_NEW
// [REM] This script does not require a persistent engine,
// run it once to install the event handler.
//----------------------------------

(function(/*any*/ev,  doc,msg,ff,t)
{
   $.level = 2;
   $.bp();
   if( !(ev||0).isValid )
   {
      // Install the event listener (if not yet installed!)
      // ---
      const UID = 'myAfterNewHandler';
      (ff=File($.fileName)).exists
      && !((t=app.eventListeners).itemByName(UID)).isValid
      && ((t.add('afterNew',ff)).name=UID);
      return;
   }

   // Checkpoint.
   // ---
   if( 'afterNew' != ev.eventType ) return; // Make sure this is the right event.
   doc = ev.target||0;
   if( 'Document' != doc.constructor.name ) return; // Make sure you're targeting a Doc.

   // Process.
   // ---
      try
      {
         doc.layers[0].name = 'TEST';
         msg = "Worked fine."
      }
      catch(e)
      {
		if (e.number == 30486)
		{
		    msg = "An error occured:\r" + e.message + " [ line: " + e.line + " ]\r"
		    + "You are probably creating a new document using the default dialog box. "
		    + "Try to turn on the 'Use Legacy \"New Document\" Dialog' check box and try again.  :-)";
		}
      }

   alert( msg );

})($.global.evt);

P.S. The Idle task approach works well for me. Thanks for posting it, Marc!

— Kasyan

Translate
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 08, 2023 Dec 08, 2023

Out of curiosity - what exactly do you want / need to do AFTER a new document has been created? 

 

There is always more than one way to skin the cat... 

 

Translate
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
Community Expert ,
Dec 09, 2023 Dec 09, 2023

Robert, the goal was to perform a DOM operation (specifically. one that isn't allowed when a modal window is present) on new documents.

Translate
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 09, 2023 Dec 09, 2023

What kind? Does it have to be executed immediately? 

 

Translate
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
Community Expert ,
Dec 09, 2023 Dec 09, 2023

The exact DOM operation isn't important, but yes immediately—using an IdleTask is a poorer second-option to using the afterNew event for this reason, but is still workable.

Translate
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 09, 2023 Dec 09, 2023

Maybe it is... 

 

Depends on what and why you want to do - maybe you can react to a different event? 

 

There was a thread about checking for cell overrides - the solution was to check for the availability of the menu item... 

 

Unless you are creating a virus - why user can't execute your script manually?

 

How about Startup Scripts folder? 

Maybe you could add special menu item?

Or even replace the default "new document" menu item? 

 

Translate
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
Community Expert ,
Dec 10, 2023 Dec 10, 2023

What kind? Does it have to be executed immediately? 

In Mark's example he wants to automatically rename a new document's default Layer 1 to TEST. You can get the sample script's after new event to fail in some cases by toggling the new document dialog's Preview button on when it is off.

Translate
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 10, 2023 Dec 10, 2023
LATEST

Yes, I've read all the responses - but missed the last line before the example - he is already using Startup Script folder. 

 

Translate
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