javascriptadobe-illustrator

Determine whether the Text Frame itself is selected or if the text within the Text Frame is selected or if no Text Frame or text portion is selected


Some Background

We work with product label design in Adobe Illustrator CC 2022. The purpose of this script is to convert our metric value to Imperial value depending on the user selection: ML to FL OZ or G to OZ. The math/conversion part works fine.

What I need guidance with

I need to determine whether the user has:

  1. Selected the Text Frame itself.
  2. Whether the user has their cursor active inside the Text Frame or has selected a portion of text.
  3. Whether none of the two above is the case.

The included code snippet does work for numbers 1 & 2 above but number 3 on the list I can't seem to get right. It seems to totally ignore the nested "Catch". I am not very familiar with Try/Catch blocks and have tried if/then statements with no luck.

Is there any way to get the script to not ignore the nested catch alternatively, is there another workaround perhaps?

The code snippet in question (I have included comments for ease of reference):

if (app.documents.length > 0)
{
    var $docRef = app.activeDocument;
    var $rslt = "I am the replacement value";
    try
    {
        //check if the selected object is a "Text Frame"
        
        if($docRef.selection[0].typename == "TextFrame")
        {
            $docRef.selection[0].contents = $rslt;
        }
    }
    catch(e1)
    {
        alert("e1 :"+e1.message); // "e1: undefined is not an object"
        
        //DO THE FOLLOWING: Ignore the error and try the nested check
        
        try
        {
            //check if the parent object of selected is a "Story"... thus editable text within a Text Frame
            
            if($docRef.selection.parent.typename == "Story")
            {
                $docRef.selection.contents = $rslt;
            }
        }
        catch(e2)
        {
            alert("e2 :"+e2.message);  // "e2: undefined is not an object"
            
            //DO THE FOLLOWING: Assume that no ediatble text is selected, create a Text Frame and populate it with $rslt value

            alert("Creating new Text Frame");
            
            //MY PROBLEM: It ignores this Catch step completely...
        }
    }
}

Solution

  • Probably it can be something like this:

    var sel = app.selection;
    if (sel.typename == undefined) sel = sel[0];
    try { sel.contents = "I am the replacement value" } catch(e) {}
    

    Or:

    var sel = app.activeDocument.selection;
    
    if (sel.length > 0) {
        if (sel.typename == undefined) sel = sel[0];
    
        if (sel.typename == 'TextFrame' || sel.typename == 'TextRange') {
            sel.contents = 'I am the replacement value';
        } else {
            alert('Creating a new text frame')
        }
    
    } else alert('Nothing is selected');