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

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

Guide ,
Sep 04, 2025 Sep 04, 2025
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?????
TOPICS
How to , Scripting
1.4K
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 3 Correct answers

Community Expert , Sep 04, 2025 Sep 04, 2025

@dublove yes definitely. That is the way I would code it. I had a quick search and I have already written a function (for you, back in 2022!). Here is an example usage:

/**
 * @author m1b
 */
function main() {

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

    alert('sel = ' + sel + ' (length: ' + sel.length + ')');

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Test');

/**
 * Returns any text frames found in given `items`
...
Translate
Community Expert , Sep 05, 2025 Sep 05, 2025

@dublove I wrote this function for getting the table. Not sure how good it is.

- Mark

 

function main() {

    var doc = app.activeDocument;
    var table = getTable(doc.selection);

    alert(table);

};
app.doScript(main, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, 'Test');

/**
 * Attempts to return a Table, given an object.
 * @author m1b
 * @version 2023-02-06
 * @param {InsertionPoint|Text|Cells|Table|TextFrame} obj - an object related to a Cell.
 * @returns {Cell}
 */
f
...
Translate
Community Expert , Oct 17, 2025 Oct 17, 2025

@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);

}
Translate
Guide ,
Oct 17, 2025 Oct 17, 2025

Thanks

 

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
Guide ,
Oct 17, 2025 Oct 17, 2025

The sel[i] values in these three scenarios appear to be different.
I still can't distinguish between them:
Nested Frame (with overflow),
Nested Frame (without overflow),
Normal Frame

 

I only want the outermost frame, ignoring the contained ones.

 

I might not be able to avoid it, the cost is too high, just alert or keep it simple;
Like this:

if (
‘Character’ === sel[j].parent.constructor.name
&& 0 === sel[j].parent.parentTextFrames.length
) {
alert(“Warning: Frames nested within frames. Please expand and delete”);
exit();
}

002.png

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 ,
Oct 17, 2025 Oct 17, 2025

Because the actual text was longer than this

 

Hi @dublove , Unless it has already been suggested, seems like you need a while statement that would end when the overflow is false. (You might have to add code to stop if the frame exceeds the page bounds)

 

//adds 5mm to the right and bottom of the selected text frame until overflows is false  
var s = app.activeDocument.selection[0];
var b;
if (s.overflows) {
    //expand until overflows is false
	while (s.overflows) {
        b = s.geometricBounds
        s.geometricBounds = [b[0],b[1], b[2] + 5, b[3] + 5]
    }
} 

 

 

Screen Shot 1.png

 

Overflows is false

 

Screen Shot.png

 

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
Guide ,
Oct 17, 2025 Oct 17, 2025

Hi,rob day.

The reason isn't that the text is too long, but that the text box is nested within another box.
So the value of sel.length is 2, but I only need the outer one.
If the text box is not split into columns, retrieve the width of the entire text box. If it is split into columns, retrieve the width of one column.

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 ,
Oct 18, 2025 Oct 18, 2025

So the value of sel.length is 2

 

The 3 column text frame is nested, so I get 1 as the length when the text frame is selected:

 

var s = app.activeDocument.selection
alert("Selection length is: " + s.length)

 

Screen Shot 2.png

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
Guide ,
Oct 18, 2025 Oct 18, 2025

The current issue is how to distinguish between these two scenarios:
1. A single text box is selected (which itself contains another text box).
At this point, sel.length == 2.
I only need the outermost box.

2. I also need to differentiate the second scenario:
Two text boxes are selected.
At this point, sel.length == 2.
Both sel[0] and sel[1] are what I need

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 ,
Oct 18, 2025 Oct 18, 2025

1. A single text box is selected (which itself contains another text box).
At this point, sel.length == 2.

 

I get 1.

 

I think you are not understanding how anchored objects work. If you anchor a text frame in a text flow, it is treated as a single character. In this example if I count the selected text frame’s characters I get 2—the A and the text frame:

 

var s = app.activeDocument.selection[0].texts[0].characters
alert("Selection’s text character count length is: " + s.length)

 

 

Screen Shot 4.png

 

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
Guide ,
Oct 20, 2025 Oct 20, 2025

Hi @rob day @Laubender  @m1b 

You haven't understood what I mean.
If there are no nested text boxes, my `sel[j]` should sequentially retrieve each selected text box.

If there are nested text boxes, I only retrieve the outermost text box.

 

That is, I ignore the internal text boxes.
My current goal:
How to ensure sel[j] only selects external, independent objects.

0022.png

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 ,
Oct 20, 2025 Oct 20, 2025

If there are nested text boxes,

 

In your sample the image in the text frame on page 2 it is not nested—it is anchored into the text. The anchor prevents you from changing its geometric bounds. See AnchoredObjectSettings:

 

https://www.indesignjs.de/extendscriptAPI/indesign-latest/#AnchoredObjectSetting.html#d1e387376__d1e...

 

 

If I select the text frame and get the first page item in the text flow, I can get it’s anchoredObjectSettings properties

 

var s = app.activeDocument.selection[0];
//the selected text frame’s text contains an anchored page item
var pf = s.texts[0].pageItems[0]
//the anchored object’s position
alert(pf.anchoredObjectSettings.anchoredPosition)

 

Screen Shot 13.png

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
Guide ,
Oct 20, 2025 Oct 20, 2025

Hi @m1b  Perhaps the best approach is to exclude it directly from

`var sel = getTextFrames(doc.selection);`

.Excluding it later complicates matters.

var sel = getTextFrames(doc.selection);

var newSel = [];
for (var i = 0; i < sel.length; i++) {
    if (
        'Character' === sel[i].parent.constructor.name
    ) {
        newSel.push(sel[i])
        sel = newSel
    }
    else {
        sel[i] = sel[i]
    }
}

 In this approach, although I ultimately obtained the outer frame sel.length-1, the number of elements in sel is greater than 1, making subsequent control difficult.

 

It would be great if we could exclude it from the very beginning with `getTextFrames(doc.selection)`.
There are two versions: one that includes embedded text boxes and one that excludes them.
if

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 ,
Oct 18, 2025 Oct 18, 2025

@rob day said: 

while (s.overflows)

 

Hi Rob,

a very tricky situation could lead to permanent overflow that cannot be resolved.
So the while would run "endless".

 

Kind regards,
Uwe Laubender
( Adobe Community Expert )

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 ,
Oct 18, 2025 Oct 18, 2025

So the while would run "endless".

 

Hi Uwe, I think it depends on where b is defined? So the top code creates the endless loop, but the 2nd example doesn’t?  I did not notice the anchored, 3 column text frame.

 

//adds 5mm to the right and bottom of the selected text frame until overflows is false  
var s = app.activeDocument.selection[0];
if (s.overflows) {
    var b = s.geometricBounds
	while (s.overflows) {
        s.geometricBounds = [b[0],b[1], b[2] + 5, b[3]]
    }
} 

 

var s = app.activeDocument.selection[0];
var b;
if (s.overflows) {
	while (s.overflows) {
        b = s.geometricBounds
        s.geometricBounds = [b[0],b[1], b[2] + 5, b[3]]
    }
} 
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
Guide ,
Oct 20, 2025 Oct 20, 2025

Hi @m1b 

Strange,

&& 0 === sel[i].parent.parentTextFrames.length

This condition has always been invalid.

So

‘Character’ === sel[i].parent.constructor.name
&& 0 === sel[i].parent.parentTextFrames.length

has always been false? Then the continue statement is quite odd.

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
Guide ,
Oct 22, 2025 Oct 22, 2025
LATEST

@m1b 

It is absolutely necessary to add another condition: getTextFrames(items) no longer includes nested text frames.
I have now reverted to the original check:

Sometimes this approach is clearer, though a bit troublesome.

if (
(“InsertionPoint” == item.constructor.name
|| “Text” == item.constructor.name
|| “Word” == item.constructor.name
|| “Paragraph” == item.constructor.name))
{
sel = item.parentTextFrames;
alert(item.constructor.name)
alert(sel.length)
FitToColumn(sel);
}

 

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