Skip to main content
dublove
Legend
September 4, 2025
Answered

I'm completely confused by "app.documents[0].selection"and "app.activeDocument.selection[0]"

  • September 4, 2025
  • 4 replies
  • 1771 views
When I select a text box, both of the following are correct:
var sel = app.documents[0].selection;
alert(sel); // [object TextFrame]
alert(sel.length) // 1​


When my cursor is inside the text, I tried the code below and found both are [object TextFrame], but sel.length is invalid..
It should be noted that sel is undefined.

    item = app.activeDocument.selection[0];
    if (item.parent.textFrames[0].constructor.name == "TextFrame") {
        var sel = item.parent.textFrames[0];
    }
    alert(sel);//[object TextFrame]
    alert(sel.length)//undefined?????
Correct answer m1b

@m1b 

Because the actual text was longer than this, I ran the script without expanding the text.
It took me a long time to find this bug.

 

Another text box was hidden inside the text box.
This caused my code to fail due to an error in sel[0].visibleBounds.

Is there a way to get a warning or prompt?

 

My test code:

var doc = app.activeDocument;
sel = getTextFrames(doc.selection);
alert(sel)
alert(sel[0].visibleBounds);
function getTextFrames(items){
....
....
}

 


@dublove once you know what the problem is, you can check for it...

var doc = app.activeDocument;
var sel = getTextFrames(doc.selection);

for (var i = 0; i < sel.length; i++) {

    if (
        'Character' === sel[i].parent.constructor.name
        && 0 === sel[i].parent.parentTextFrames.length
    )
        // ignore overset anchored object
        continue;

    alert('sel[' + i + '] = ' + sel[i].visibleBounds);

}

4 replies

dublove
dubloveAuthor
Legend
March 21, 2026

Hi @m1b.

It’s been a while.

An old problem, a new idea:
Is it possible—regardless of whether I select an image or a textFrame (using positioning)—
for “getTextFrames(items)” to return the outermost textFrame?

 

Community Expert
September 4, 2025

@m1b said: "there's usually no difference between app.activeDocument and app.documents[0]."

 

Hi @dublove ,

the difference between app.documents[0] and app.activeDocument is a subtle one.

It could be that the addressed document with app.documents[0] is a document without a layout window.

Not so with app.activeDocument. That is always one with a layout window.

 

Let's proof that; start InDesign with no document open and add two documents with a different parameter for showingWindow in method add():

// START InDesign WITH NO OPEN DOCUMENT:
// Add two documents:
var doc1 = app.documents.add(); // showingWindow parameter true is default
var doc2 = app.documents.add( false ); // showingWindow parameter set to false

alert( app.documents.length ) ; // returns 2

alert( app.activeDocument == doc1 ); // returns true

 

Regards,
Uwe Laubender
( Adobe Community Expert )

dublove
dubloveAuthor
Legend
September 4, 2025

@Laubender 

Too deep.
Can't grasp it all at once.
How do I make `sel = item.parent.textFrames[0];` into a real, controllable object?

It should be controllable like `sel = app.documents[0].selection;`.

 

I tried using
alert(app.documents[0].selection.parent);
but app.documents[0].selection doesn't seem to support parent.

 

It seems like alert(app.documents[0].selection[0].parent.textFrames[0]);
But sel.app.documents[0].selection[0].parent.textFrames[0];
still cannot be recognized as a real textFrame.
It remains a fake (logical textFrame?)

Participant
September 4, 2025

Really helpful breakdown — I’ve run into similar issues where features behave differently depending on device or context. It reminds me how important it is to double-check workflows across platforms, whether it’s Excel or even how a website displays on mobile vs desktop. Consistency really makes or breaks productivity.

m1b
Community Expert
Community Expert
September 4, 2025

@dublove there's usually no difference between app.activeDocument and app.documents[0].

 

Your problem is simply that sometimes the line

var sel = item.parent.textFrames[0];

doesn't get called, due to the predicate, so it will throw an error.

 

If you want to handle the error gracefully, do it like this:

var item = app.activeDocument.selection[0];

// must define sel outside the if/else
var sel;

if (item.parent.textFrames[0].constructor.name == "TextFrame") {
    sel = item.parent.textFrames[0];
}
else {
    sel = { length: 0 };
}

alert(sel);
alert(sel.length);
dublove
dubloveAuthor
Legend
September 4, 2025

Hi m1b.

As you mentioned, is the value of sel.length 0?
But sel is already an object [object TextFrame].
If that's the case, my sort(a,b) interaction below won't capture the objects and will throw an error.

Actually, I just want to automatically obtain the final TextFrame based on different selections.

 alert(item.constructor.name);
    var sel;
    item = app.activeDocument.selection[0];
    if (item.parent.textFrames[0].constructor.name == "TextFrame") {
        sel = item.parent.textFrames[0];
    }
    else if (
        item.constructor.name == "Image"
        || item.constructor.name == "TextFrame") {
        sel = app.documents[0].selection;
    }
        sel.sort(function (a, b) {
        var aBounds = a.visibleBounds;
        var bBounds = b.visibleBounds;
 
        if (aBounds[1] < bBounds[1]) {
            return -1;
        } else if (aBounds[1] > bBounds[1]) {
            return 1;
        }
        else {
            return bBounds[0] - aBounds[0];
        }
    });