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

[ExtendScript] How to use "afterNew" event

Community Expert ,
Dec 04, 2023 Dec 04, 2023

Copy link to clipboard

Copied

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

Views

1.8K

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 2 Correct answers

Community Expert , 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

Votes

Translate

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
...

Votes

Translate

Translate
Guide ,
Dec 08, 2023 Dec 08, 2023

Copy link to clipboard

Copied

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

Votes

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

Copy link to clipboard

Copied

Thanks Marc, that really helpful too. - Mark

Votes

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

Copy link to clipboard

Copied

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

Votes

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

Copy link to clipboard

Copied

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... 

 

Votes

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

Copy link to clipboard

Copied

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

Votes

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

Copy link to clipboard

Copied

What kind? Does it have to be executed immediately? 

 

Votes

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

Copy link to clipboard

Copied

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.

Votes

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

Copy link to clipboard

Copied

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? 

 

Votes

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

Copy link to clipboard

Copied

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.

Votes

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

Copy link to clipboard

Copied

LATEST

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

 

Votes

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