2

I am looking to speed up my workflow by parsing a resource string to auto create my variable paths. Not only can it get confusing to look at large scale UI's, it's even worse getting the paths written out to access each element. ExtendScript ha s a lot of "quirks" we'll call it. So for sake of simplicity the sample below is cut way down.

var res = "group{,\
itemsToRenameGrp: Group{,\
    itemsToRenameDD: DropDownList{},\
    help: Button{},\
},\
listTabPnl: Panel{,\
    listOfItemsTab: Panel{,\
        listOfItemsPnl: Panel{,\
            listOfItemsLB: ListBox{},\
        },\
        confirmChanges: Button{},\
    },\
    badItemsTab: Panel{,\
        errorLogET: EditText{},\
    },\
},\
}";

I need to create paths like this for variable assignment:

itemsToRenameGrp.itemsToRenameDD
itemsToRenameGrp.help

listTabPnl.listOfItemsTab.listOfItemsPnl
listTabPnl.listOfItemsTab.listOfItemsPnl.listOfItemsLB
listTabPnl.listOfItemsTab.confirmChanges

listTabPnl.badItemsTab
listTabPnl.badItemsTab.errorLogET

I know there has to be a way via RegExp to parse the tab spaces, or "},\" section endings to make this work, I just can't figure out the solution myself. Any help is appreciated. Thanks.

Jongware
  • 21,058
  • 8
  • 43
  • 86
  • Please do not add "Solved" and the solution to your question. It invalidates the entire point of Stack Overflow as an *question and answer* resource. If your own solution is sufficiently different from the current answer(s), you can always add one yourself. – Jongware Dec 19 '14 at 09:33
  • Appologies, was trying to save people the headache of spending time on my issue in which I had resolved. – David Torno Dec 19 '14 at 18:54
  • Please *do* add your own answer! Just don't edit it into the question. – Jongware Dec 22 '14 at 23:29

4 Answers4

0

Those backslashes should not be needed, there is a special multi-line mode when you start a string with three double-quotes.

Rather than parsing the source I'd leave that to ExtendScript and iterate the resulting UI objects.

Dirk
  • 636
  • 3
  • 6
  • The reason behind the parsing was to help in auto creation of additional text to be used within the script. Trying to save me some typing. The problem with iterating the UI objects in ExtendScript, I was unable to access the actual resource name assigned to each element. It only allows access to the created elements' "text", "title", or "name" assigned depending on the element. – David Torno Dec 19 '14 at 18:59
0

I agree that it is rather cumbersome to look at complex resource strings and then have to write "paths" to the UI elements that you want to work with. I'm not sure RegEx is the way, and I have not looked too far into it, but the solution I've come up with is to create a function that returns a "flattened pathway" to the elements so that I can refer to them with ease. If the resource string changes, then all I have to do is modify the "flattened pathway" function to account for those changes--this way I don't need to change anything elsewhere in the code.

For example, given the code you posted, I would make a function that might look something like this:

function getGUI(ui){

  var gui = {};

  gui.lRename  = ui.itemsToRenameGrp.itemsToRenameDD;
  gui.bHelp    = ui.itemsToRenameGrp.help;
  gui.lItems   = ui.listTabPn1.listOfItemsTab.listOfItemsPn1.listOfItemsLB;
  gui.bConfirm = ui.listTabPn1.listOfItemsTab.confirmChanges;
  gui.eLog     = ui.listTabPn1.badItemsTab.errorLogET;

  return gui;
}

Then when you finish "building" your UI with a Window object, call that function like so:

var _mainGUI = getGUI({variable that holds your Window object});

Now, when you want to access the elements, just call them like:

_mainGUI.lRename
_mainGUI.bConfirm
_mainGUI.lItems

...and so on. So this way if you ever make a change to the resource string, you'll just have to modify the getGUI function and your application code can remain the same. Hopefully this helps, and my apologies for the initial, incomplete, answer post--I accidentally hit the submit button too early.

ariestav
  • 2,433
  • 3
  • 23
  • 47
0

Another possibility is parse not the the string but the finished window, like so:

function loadNamedWidgets(cont, _target){
    // cont : ScruitUI container
    // _target : Object
    var k, K, child, id;
    K=cont.children.length;
    for (k=0; k<K; k++){
        child = cont.children[k];
        if (/^(Window|Panel|Group)$/.test(child.constructor.name)){
            loadNamedWidgets(child, _target);
            }
        else{
            // check that a ownProperty of cont is same as child
            for (id in cont){
                if (cont.hasOwnProperty(id)){
                    if (cont[id] === child) {_target[id] = child; break;};
                    }
                else break;
                };
            };
        };
    return;
    };

TEST : In the test below, *radio1 and radio2 will be written twice, but those from p2 will overwrite those from p1 (name conflict), *titleST (unnamed) added at the end will not appear while valueET (named) will.

var w = new Window("palette{\
            text : 'hi',\
            header : Group{\
                        superBtn : Button{},\
                        extraBtn : Button{},\
                        helpBtn : Button{},\
                        },\
            body: Group{\
                        p1 : Panel{\
                                    _tag : 1,\
                                    radio1 : RadioButton{},\
                                    radio2 : RadioButton{},\
                                    },\
                        p2 : Panel{\
                                    _tag : 2,\
                                    radio1 : RadioButton{},\
                                    radio2 : RadioButton{},\
                                    },\
                        },\
            console : Group{\
                        consoleET : EditText{text: '', properties: {readonly: true}},\
                        },\
            footer : Group{}\
            }");
var titleST = w.footer.add("statictext{text : 'title'}");
var valueET = w.footer.valueET = w.footer.add("edittext{text : '0000'}");
var binds = {};
loadNamedWidgets(w, binds);

$.writeln(binds.toSource());
Xavier Gomez
  • 114
  • 4
0

It's messy, but I finally figured out something that gives me what I wanted.

Solution:

var res = "group{,\
    itemsToRenameGrp: Group{,\
        itemsToRenameDD: DropDownList{},\
        help: Button{},\
    },\
    listTabPnl: Panel{,\
        listOfItemsTab: Panel{,\
            listOfItemsPnl: Panel{,\
                listOfItemsLB: ListBox{},\
            },\
            confirmChanges: Button{},\
        },\
        badItemsTab: Panel{,\
            errorLogET: EditText{},\
        },\
    },\
}";

var lines = res.split("\n");
var numLines = lines.length;
var variablePaths = new Array();
var val, newVal, firstColon, firstBrace, lastBrace, tabLength, oldTabLength, path, splitPath;
path = "";
oldTabLength = 0;
if(numLines > 0){
    for(var r=0; r<numLines; r++){
        val = lines[r];
        firstColon = val.indexOf(":");
        firstBrace = val.indexOf("{");
        lastBrace = val.lastIndexOf("}");
        try{tabLength = val.match(/\t/g).length}catch(err){};   /*  Count tabs  */
        if(firstColon > 0 && firstBrace > 0){   /*  Valid possible element line */
            if(firstColon < firstBrace){    /*  Confirmed element line  */
                newVal = val.substring(0, firstColon);  /*  Strip line down to just name and leading tabs   */
                if(tabLength > oldTabLength){   /*  Checks for line indent (child element)  */
                    path += "." + newVal.replace(new RegExp("\t", "g"), "");
                }else if(tabLength == oldTabLength){    /*  Checks for line indent match (same parent as previous element)  */
                    path = path.substring(0, path.lastIndexOf(".")) + "." + newVal.replace(new RegExp("\t", "g"), "");
                }else  if(tabLength < oldTabLength){    /*  Checks for line indent (new parent to add)  */
                    splitPath = path.split(".");
                    try{    /*  This section adjusts how far back in heirarchy to remove    */
                        if(tabLength > 0){
                            splitPath.length -= ((oldTabLength - tabLength)+1);
                        }else{
                            splitPath.length -= (oldTabLength - tabLength);
                        }
                    }catch(err){};
                    path = splitPath.join(".").toString() + "." + newVal.replace(new RegExp("\t", "g"), "");    /*  Creates new cleaned up string path (tabs removed)   */
                }
                oldTabLength = tabLength;
                if(tabLength >= oldTabLength){
                    variablePaths.push(path);   /*  Populates array */
                }
            }
        }
    }
}else{
    alert("Nothing to process");
}

alert("Element Names:\n" + variablePaths.join("\n"));

– David Torno

Armali
  • 14,228
  • 13
  • 47
  • 141