6 Replies Latest reply on Jan 4, 2010 3:27 PM by Laubender

    How do I avoid scripting inaccuracies caused by delays in redrawing?

    Frame25Matt

      Hello, all! I've run into an interesting quirk. When I resize a text frame, and then try to work with its contents, my script chokes because there seems to be a delay between the resizing operation and the script being "aware" of the change. I have a text frame with text and table contents that fit within its boundaries. Then I resize the text frame to make it a bit shorter, and check to see whether or not the contents are now overset. When I run this check, even if the shorter frame has now created an overset situation, it returns false--the script still thinks the content is inside the text frame--but only for a few seconds. I've set a breakpoint to check this, and when I test for overset text it returns false the first couple of times I check, but then finally "kicks in" as true after a few seconds. Clearly InDesign is reflowing the text, which takes a bit of time to register before the script can correctly read it.

       

      Do I have to just create a setTimeout to force a delay manually? Is there some way to hold the next line of the script until the last page-manipulation operation is confirmed complete? If I go with an arbitrary setTimeout it's inelegant, and worse, it's still conceivable that on a slow computer the delahy wouldn't be long enough to generate accurate results every single time. Is there anything I'm missing? Thank you!

        • 1. Re: How do I avoid scripting inaccuracies caused by delays in redrawing?
          Harbs. Level 6

          What version of InDesign?

           

          If it's CS2 or earlier, you might need recompose() to get it all in 

          sync.

           

          Harbs

          http://www.in-tools.com

          Innovations in Automation

          • 2. Re: How do I avoid scripting inaccuracies caused by delays in redrawing?
            Harbs. Level 6

            Actually, in a normal situation, you shouldn't have this problem in any version. There must be more to the story. What exactly is your situation?

             

            Harbs

            • 3. Re: How do I avoid scripting inaccuracies caused by delays in redrawing?
              sstanleyau Level 4

              FWIW, I recall having to use it fairly regularly in CS2. Just can't remember the specifics...

              • 4. Re: How do I avoid scripting inaccuracies caused by delays in redrawing?
                Frame25Matt Level 1

                I'm in CS4. I have a document with several pages--let's say four for the sake of illustration. Each page is landscape lettersized and has a text frame that takes up a good chunk of the page; the text frames are linked so each one continues the flow from the previous page. The content happens to be lengthy tables (but I suppose could also just be text, or text and tables).

                 

                Now, the final page of my document needs to have room for a graphic at the bottom, so I need to take the LAST text frame and move up its bottom edge. So I go into the last cell of the last table (my tables are in an array called assetTables) and grab the ID of the text frame which contains it. I read its geometric bounds, then alter them.

                 

                function adjustFinalPage(textFrameArray) {

                    var finalID = assetTables[assetTables.length-1].rows.lastItem().cells.lastItem().insertionPoints.firstI tem().parentTextFrames[0].id;
                    var tempBounds = myDocument.textFrames.itemByID(finalID).geometricBounds;
                    tempBounds.splice(2,1,4.6); // Adjust the bottom edge of the last page upwards
                    myDocument.textFrames.itemByID(finalID).geometricBounds = tempBounds;
                    if (addOverflowPages(textFrameArray)) { alert('Added a new page'); } else { alert('Added nothing'); }

                    }

                 

                At the end of the function I call my "addOverflowPages" function to add a fifth page if this adjustment caused my last table to overflow the text frame on page four. This is not the full function, but contains the relevant parts of it (much of which I wrote with earlier help from Harbs--thanks Harbs!):


                function addOverflowPages(textFrameArray) {
                    var didSomething = false;
                    var i =
                textFrameArray.length-1;
                    var finalCell = whichFrameArray[0].parentStory.tables.lastItem().cells.lastItem();
                    var breakpoint = 'break';
                    while (finalCell.parent.parent.insertionPoints.lastItem().parentTextFrames.length==0) {
                        // SNIPPED OUT: Code to add new page, draw text frame, and link to previous page's text frame
                        didSomething = true;
                        }
                    return didSomething;
                    }

                 

                Now here's the problem. If this code is run straight out of the gate, then the while loop is never entered--even when the table overflows its text frame! BUT when I put a breakpoint at the var breakpoint = 'break'; line and type in the Javascript Console:

                 

                finalCell.parent.parent.insertionPoints.lastItem().parentTextFrames.length

                 

                I get 1 rather than 0. (0 is the value you get when the final cell of the final table is outside the bounds of a text frame.) But if I continue to paste that line in a few more times, it SWITCHES and goes from 1 back to the correct value of 0. So the only sensible conclusion I can reach is that there is some kind of delay going on while InDesign reflows the table.

                 

                Note:

                 

                I have, just to jump ahead, tried adding in the line:

                 

                myDocument.recompose();

                 

                just before calling the addOverflowPages function, and this so far DOES seem to eliminate the glitch. But before I consider that an actual cure, I want to be sure that it does in fact permanently solve the problem (rather than just, say, introduce an additional delay which HAPPENS to solve the problem in most cases). For example, does recompose prevent the following lines from executing until after the recomposition completes? Because otherwise, I might find the same problem recurring if the script is run on a slow or busy computer--the recomposition process might take a few extra milliseconds to complete, causing my overset check to fail again. Can't have that!

                • 5. Re: How do I avoid scripting inaccuracies caused by delays in redrawing?
                  Harbs. Level 6

                  It could be a problem because it's tables. I've never seen this with straight text. This problem used to happen a lot with inline/anchored frames prior to CS3.

                   

                  You do not need to call recompose() on the whole document. calling recompose() on the parentStory of the textFrame should be enough.

                   

                  Harbs

                  • 6. Re: How do I avoid scripting inaccuracies caused by delays in redrawing?
                    Laubender Adobe Community Professional & MVP

                    Harbs,

                    just an observation: today I had a problem that I could solve with "recompose()". It's a CS4 script, that takes out an text asset from a library, places it to a page, then simply stores it back to the same library. Nothing complex, just a single text frame, just placing and storing: and "puff", the assets preview is lost or never composed:

                     

                    //JavaScript
                    var d=app.activeDocument;

                    //All assets in the library are single text frames

                    var libraryName = app.libraries.item("MyLibrary.indl");

                    for(n=0;n<libraryName.assets.length;n++){
                        var assetName=libraryName.assets.item(n).name;
                        var assetDescription=libraryName.assets.item(n).description;
                        var assetLabel=libraryName.assets.item(n).label;
                        var assetAssetType=libraryName.assets.item(n).assetType;
                        
                        libraryName.assets.item(n).placeAsset(d);
                        
                        //Do something exciting with the placed asset...
                        
                        libraryName.assets[n].remove();
                        
                        libraryName.store(d.textFrames.item(0));
                        
                        libraryName.assets[0].name=assetName;
                        libraryName.assets[0].description=assetDescription;
                        libraryName.assets[0].label=assetLabel;
                        libraryName.assets[0].assetType=assetAssetType;
                        
                        d.textFrames.item(0).remove();
                        
                        };

                     

                     

                    Adding:
                    d.textFrames.item(0).recompose();

                    to the (now) blank line 17 does the trick.

                     

                    Uwe

                     

                    Edit: tried the same in InDesign CS3: worked without recompose().