javascript/selenium-core/scripts/ui-element.js
function UIMap()
{
    // the singleton pattern, split into two parts so that "new" can still
    // be used, in addition to "getInstance()"
    UIMap.self = this;
    
    // need to attach variables directly to the Editor object in order for them
    // to be in scope for Editor methods
    if (is_IDE()) {
        Editor.uiMap = this;
        Editor.UI_PREFIX = UI_GLOBAL.UI_PREFIX;
    }
    
    this.pagesets = new Object();
    
    
    
    /**
     * pageset[pagesetName]
     *   regexp
     *   elements[elementName]
     *     UIElement
     */
    this.addPageset = function(pagesetShorthand)
    {
        try {
            var pageset = new Pageset(pagesetShorthand);
        }
        catch (e) {
            safe_alert("Could not create pageset from shorthand:\n"
                + print_r(pagesetShorthand) + "\n" + e.message);
            return false;
        }
        
        if (this.pagesets[pageset.name]) {
            safe_alert('Could not add pageset "' + pageset.name
                + '": a pageset with that name already exists!');
            return false;
        }
        
        this.pagesets[pageset.name] = pageset;
        return true;
    };
    
    
    
    /**
     * @param pagesetName
     * @param uiElementShorthand  a representation of a UIElement object in
     *                            shorthand JSON.
     */
    this.addElement = function(pagesetName, uiElementShorthand)
    {
        try {
            var uiElement = new UIElement(uiElementShorthand);
        }
        catch (e) {
            safe_alert("Could not create UI element from shorthand:\n"
                + print_r(uiElementShorthand) + "\n" + e.message);
            return false;
        }
        
        // run the element's unit tests only for the IDE, and only when the
        // IDE is starting. Make a rough guess as to the latter condition.
        if (is_IDE() && !editor.selDebugger && !uiElement.test()) {
            safe_alert('Could not add UI element "' + uiElement.name
                + '": failed testcases!');
            return false;
        }
        
        try {
            this.pagesets[pagesetName].uiElements[uiElement.name] = uiElement;
        }
        catch (e) {
            safe_alert("Could not add UI element '" + uiElement.name
                + "' to pageset '" + pagesetName + "':\n" + e.message);
            return false;
        }
        
        return true;
    };
    
    
    
    /**
     * Returns the pageset for a given UI specifier string.
     *
     * @param uiSpecifierString
     * @return  a pageset object
     */
    this.getPageset = function(uiSpecifierString)
    {
        try {
            var uiSpecifier = new UISpecifier(uiSpecifierString);
            return this.pagesets[uiSpecifier.pagesetName];
        }
        catch (e) {
            return null;
        }
    }
    
    
    
    /**
     * Returns the UIElement that a UISpecifierString or pageset and element
     * pair refer to.
     *
     * @param pagesetNameOrUISpecifierString
     * @return  a UIElement, or null if none is found associated with
     *          uiSpecifierString
     */
    this.getUIElement = function(pagesetNameOrUISpecifierString, uiElementName)
    {
        var pagesetName = pagesetNameOrUISpecifierString;
        if (arguments.length == 1) {
            var uiSpecifierString = pagesetNameOrUISpecifierString;
            try {
                var uiSpecifier = new UISpecifier(uiSpecifierString);
                pagesetName = uiSpecifier.pagesetName;
                var uiElementName = uiSpecifier.elementName;
            }
            catch (e) {
                return null;
            }
        }
        try {
            return this.pagesets[pagesetName].uiElements[uiElementName];
        }
        catch (e) {
            return null;
        }
    };
    
    
    
    /**
     * Returns a list of pagesets that "contains" the provided page,
     * represented as a document object. Containership is defined by the
     * Pageset object's contain() method.
     *
     * @param inDocument  the page to get pagesets for
     * @return            a list of pagesets
     */
    this.getPagesetsForPage = function(inDocument)
    {
        var pagesets = [];
        for (var pagesetName in this.pagesets) {
            var pageset = this.pagesets[pagesetName];
            if (pageset.contains(inDocument)) {
                pagesets.push(pageset);
            }
        }
        return pagesets;
    };
    
    
    
    /**
     * Returns a list of all pagesets.
     *
     * @return  a list of pagesets
     */
    this.getPagesets = function()
    {
        var pagesets = [];
        for (var pagesetName in this.pagesets) {
            pagesets.push(this.pagesets[pagesetName]);
        }
        return pagesets;
    };
    
    
    
    /**
     * Returns a list of elements on a page that a given UI specifier string,
     * maps to. If no elements are mapped to, returns an empty list..
     *
     * @param   uiSpecifierString  a String that specifies a UI element with
     *                             attendant argument values
     * @param   inDocument         the document object the specified UI element
     *                             appears in
     * @return                     a potentially-empty list of elements
     *                             specified by uiSpecifierString
     */
    this.getPageElements = function(uiSpecifierString, inDocument)
    {
        var locator = this.getLocator(uiSpecifierString);
        var results = locator ? eval_locator(locator, inDocument) : [];
        return results;
    };
    
    
    
    /**
     * Returns the locator string that a given UI specifier string maps to, or
     * null if it cannot be mapped.
     *
     * @param uiSpecifierString
     */
    this.getLocator = function(uiSpecifierString)
    {
        try {
            var uiSpecifier = new UISpecifier(uiSpecifierString);
        }
        catch (e) {
            safe_alert('Could not create UISpecifier for string "'
                + uiSpecifierString + '": ' + e.message);
            return null;
        }
        
        var uiElement = this.getUIElement(uiSpecifier.pagesetName,
            uiSpecifier.elementName);
        try {
            return uiElement.getLocator(uiSpecifier.args);
        }
        catch (e) {
            return null;
        }
    }
    
    
    
    /**
     * Finds and returns a UI specifier string given an element and the page
     * that it appears on.
     *
     * @param pageElement  the document element to map to a UI specifier
     * @param inDocument   the document the element appears in
     * @return             a UI specifier string, or false if one cannot be
     *                     constructed
     */
    this.getUISpecifierString = function(pageElement, inDocument)
    {
        var is_fuzzy_match =
            BrowserBot.prototype.locateElementByUIElement.is_fuzzy_match;
        var pagesets = this.getPagesetsForPage(inDocument);
        
        for (var i = 0; i < pagesets.length; ++i) {
            var pageset = pagesets[i];
            var uiElements = pageset.getUIElements();
            
            for (var j = 0; j < uiElements.length; ++j) {
                var uiElement = uiElements[j];
                
                // first test against the generic locator, if there is one.
                // This should net some performance benefit when recording on
                // more complicated pages.
                if (uiElement.getGenericLocator) {
                    var passedTest = false;
                    var results =
                        eval_locator(uiElement.getGenericLocator(), inDocument);
                    for (var i = 0; i < results.length; ++i) {
                        if (results[i] == pageElement) {
                            passedTest = true;
                            break;
                        }
                    }
                    if (!passedTest) {
                        continue;
                    }
                }
                
                var defaultLocators;
                if (uiElement.isDefaultLocatorConstructionDeferred) {
                    defaultLocators = uiElement.getDefaultLocators(inDocument);
                }
                else {
                    defaultLocators = uiElement.defaultLocators;
                }
                
                //safe_alert(print_r(uiElement.defaultLocators));
                for (var locator in defaultLocators) {
                    var locatedElements = eval_locator(locator, inDocument);
                    if (locatedElements.length) {
                        var locatedElement = locatedElements[0];
                    }
                    else {
                        continue;
                    }
                    
                    // use a heuristic to determine whether the element
                    // specified is the "same" as the element we're matching
                    if (is_fuzzy_match) {
                        if (is_fuzzy_match(locatedElement, pageElement)) {
                            return UI_GLOBAL.UI_PREFIX + '=' +
                                new UISpecifier(pageset.name, uiElement.name,
                                    defaultLocators[locator]);
                        }
                    }
                    else {
                        if (locatedElement == pageElement) {
                            return UI_GLOBAL.UI_PREFIX + '=' +
                                new UISpecifier(pageset.name, uiElement.name,
                                    defaultLocators[locator]);
                        }
                    }
                    
                    // ok, matching the element failed. See if an offset
                    // locator can complete the match.
                    if (uiElement.getOffsetLocator) {
                        for (var k = 0; k < locatedElements.length; ++k) {
                            var offsetLocator = uiElement
                                .getOffsetLocator(locatedElements[k], pageElement);
                            if (offsetLocator) {
                                return UI_GLOBAL.UI_PREFIX + '=' +
                                    new UISpecifier(pageset.name,
                                        uiElement.name,
                                        defaultLocators[locator])
                                    + '->' + offsetLocator;
                            }
                        }
                    }
                }
            }
        }
        return false;
    };
    
    
    
    /**
     * Returns a sorted list of UI specifier string stubs representing possible
     * UI elements for all pagesets, paired the their descriptions. Stubs
     * contain all required arguments, but leave argument values blank.
     *
     * @return  a list of UI specifier string stubs
     */
    this.getUISpecifierStringStubs = function() {
        var stubs = [];
        var pagesets = this.getPagesets();
        for (var i = 0; i < pagesets.length; ++i) {
            stubs = stubs.concat(pagesets[i].getUISpecifierStringStubs());
        }
        stubs.sort(function(a, b) {
            if (a[0] < b[0]) {
                return -1;
            }
            return a[0] == b[0] ? 0 : 1;
        });
        return stubs;
    }
}
function UIMap()
{
    // the singleton pattern, split into two parts so that "new" can still
    // be used, in addition to "getInstance()"
    UIMap.self = this;
    
    // need to attach variables directly to the Editor object in order for them
    // to be in scope for Editor methods
    if (is_IDE()) {
        Editor.uiMap = this;
        Editor.UI_PREFIX = UI_GLOBAL.UI_PREFIX;
    }
    
    this.pagesets = new Object();
    
    
    
    /**
     * pageset[pagesetName]
     *   regexp
     *   elements[elementName]
     *     UIElement
     */
    this.addPageset = function(pagesetShorthand)
    {
        try {
            var pageset = new Pageset(pagesetShorthand);
        }
        catch (e) {
            safe_alert("Could not create pageset from shorthand:\n"
                + print_r(pagesetShorthand) + "\n" + e.message);
            return false;
        }
        
        if (this.pagesets[pageset.name]) {
            safe_alert('Could not add pageset "' + pageset.name
                + '": a pageset with that name already exists!');
            return false;
        }
        
        this.pagesets[pageset.name] = pageset;
        return true;
    };
    
    
    
    /**
     * @param pagesetName
     * @param uiElementShorthand  a representation of a UIElement object in
     *                            shorthand JSON.
     */
    this.addElement = function(pagesetName, uiElementShorthand)
    {
        try {
            var uiElement = new UIElement(uiElementShorthand);
        }
        catch (e) {
            safe_alert("Could not create UI element from shorthand:\n"
                + print_r(uiElementShorthand) + "\n" + e.message);
            return false;
        }
        
        // run the element's unit tests only for the IDE, and only when the
        // IDE is starting. Make a rough guess as to the latter condition.
        if (is_IDE() && !editor.selDebugger && !uiElement.test()) {
            safe_alert('Could not add UI element "' + uiElement.name
                + '": failed testcases!');
            return false;
        }
        
        try {
            this.pagesets[pagesetName].uiElements[uiElement.name] = uiElement;
        }
        catch (e) {
            safe_alert("Could not add UI element '" + uiElement.name
                + "' to pageset '" + pagesetName + "':\n" + e.message);
            return false;
        }
        
        return true;
    };
    
    
    
    /**
     * Returns the pageset for a given UI specifier string.
     *
     * @param uiSpecifierString
     * @return  a pageset object
     */
    this.getPageset = function(uiSpecifierString)
    {
        try {
            var uiSpecifier = new UISpecifier(uiSpecifierString);
            return this.pagesets[uiSpecifier.pagesetName];
        }
        catch (e) {
            return null;
        }
    }
    
    
    
    /**
     * Returns the UIElement that a UISpecifierString or pageset and element
     * pair refer to.
     *
     * @param pagesetNameOrUISpecifierString
     * @return  a UIElement, or null if none is found associated with
     *          uiSpecifierString
     */
    this.getUIElement = function(pagesetNameOrUISpecifierString, uiElementName)
    {
        var pagesetName = pagesetNameOrUISpecifierString;
        if (arguments.length == 1) {
            var uiSpecifierString = pagesetNameOrUISpecifierString;
            try {
                var uiSpecifier = new UISpecifier(uiSpecifierString);
                pagesetName = uiSpecifier.pagesetName;
                var uiElementName = uiSpecifier.elementName;
            }
            catch (e) {
                return null;
            }
        }
        try {
            return this.pagesets[pagesetName].uiElements[uiElementName];
        }
        catch (e) {
            return null;
        }
    };
    
    
    
    /**
     * Returns a list of pagesets that "contains" the provided page,
     * represented as a document object. Containership is defined by the
     * Pageset object's contain() method.
     *
     * @param inDocument  the page to get pagesets for
     * @return            a list of pagesets
     */
    this.getPagesetsForPage = function(inDocument)
    {
        var pagesets = [];
        for (var pagesetName in this.pagesets) {
            var pageset = this.pagesets[pagesetName];
            if (pageset.contains(inDocument)) {
                pagesets.push(pageset);
            }
        }
        return pagesets;
    };
    
    
    
    /**
     * Returns a list of all pagesets.
     *
     * @return  a list of pagesets
     */
    this.getPagesets = function()
    {
        var pagesets = [];
        for (var pagesetName in this.pagesets) {
            pagesets.push(this.pagesets[pagesetName]);
        }
        return pagesets;
    };
    
    
    
    /**
     * Returns a list of elements on a page that a given UI specifier string,
     * maps to. If no elements are mapped to, returns an empty list..
     *
     * @param   uiSpecifierString  a String that specifies a UI element with
     *                             attendant argument values
     * @param   inDocument         the document object the specified UI element
     *                             appears in
     * @return                     a potentially-empty list of elements
     *                             specified by uiSpecifierString
     */
    this.getPageElements = function(uiSpecifierString, inDocument)
    {
        var locator = this.getLocator(uiSpecifierString);
        var results = locator ? eval_locator(locator, inDocument) : [];
        return results;
    };
    
    
    
    /**
     * Returns the locator string that a given UI specifier string maps to, or
     * null if it cannot be mapped.
     *
     * @param uiSpecifierString
     */
    this.getLocator = function(uiSpecifierString)
    {
        try {
            var uiSpecifier = new UISpecifier(uiSpecifierString);
        }
        catch (e) {
            safe_alert('Could not create UISpecifier for string "'
                + uiSpecifierString + '": ' + e.message);
            return null;
        }
        
        var uiElement = this.getUIElement(uiSpecifier.pagesetName,
            uiSpecifier.elementName);
        try {
            return uiElement.getLocator(uiSpecifier.args);
        }
        catch (e) {
            return null;
        }
    }
    
    
    
    /**
     * Finds and returns a UI specifier string given an element and the page
     * that it appears on.
     *
     * @param pageElement  the document element to map to a UI specifier
     * @param inDocument   the document the element appears in
     * @return             a UI specifier string, or false if one cannot be
     *                     constructed
     */
    this.getUISpecifierString = function(pageElement, inDocument)
    {
        var is_fuzzy_match =
            BrowserBot.prototype.locateElementByUIElement.is_fuzzy_match;
        var pagesets = this.getPagesetsForPage(inDocument);
        
        for (var i = 0; i < pagesets.length; ++i) {
            var pageset = pagesets[i];
            var uiElements = pageset.getUIElements();
            
            for (var j = 0; j < uiElements.length; ++j) {
                var uiElement = uiElements[j];
                
                // first test against the generic locator, if there is one.
                // This should net some performance benefit when recording on
                // more complicated pages.
                if (uiElement.getGenericLocator) {
                    var passedTest = false;
                    var results =
                        eval_locator(uiElement.getGenericLocator(), inDocument);
                    for (var i = 0; i < results.length; ++i) {
                        if (results[i] == pageElement) {
                            passedTest = true;
                            break;
                        }
                    }
                    if (!passedTest) {
                        continue;
                    }
                }
                
                var defaultLocators;
                if (uiElement.isDefaultLocatorConstructionDeferred) {
                    defaultLocators = uiElement.getDefaultLocators(inDocument);
                }
                else {
                    defaultLocators = uiElement.defaultLocators;
                }
                
                //safe_alert(print_r(uiElement.defaultLocators));
                for (var locator in defaultLocators) {
                    var locatedElements = eval_locator(locator, inDocument);
                    if (locatedElements.length) {
                        var locatedElement = locatedElements[0];
                    }
                    else {
                        continue;
                    }
                    
                    // use a heuristic to determine whether the element
                    // specified is the "same" as the element we're matching
                    if (is_fuzzy_match) {
                        if (is_fuzzy_match(locatedElement, pageElement)) {
                            return UI_GLOBAL.UI_PREFIX + '=' +
                                new UISpecifier(pageset.name, uiElement.name,
                                    defaultLocators[locator]);
                        }
                    }
                    else {
                        if (locatedElement == pageElement) {
                            return UI_GLOBAL.UI_PREFIX + '=' +
                                new UISpecifier(pageset.name, uiElement.name,
                                    defaultLocators[locator]);
                        }
                    }
                    
                    // ok, matching the element failed. See if an offset
                    // locator can complete the match.
                    if (uiElement.getOffsetLocator) {
                        for (var k = 0; k < locatedElements.length; ++k) {
                            var offsetLocator = uiElement
                                .getOffsetLocator(locatedElements[k], pageElement);
                            if (offsetLocator) {
                                return UI_GLOBAL.UI_PREFIX + '=' +
                                    new UISpecifier(pageset.name,
                                        uiElement.name,
                                        defaultLocators[locator])
                                    + '->' + offsetLocator;
                            }
                        }
                    }
                }
            }
        }
        return false;
    };
    
    
    
    /**
     * Returns a sorted list of UI specifier string stubs representing possible
     * UI elements for all pagesets, paired the their descriptions. Stubs
     * contain all required arguments, but leave argument values blank.
     *
     * @return  a list of UI specifier string stubs
     */
    this.getUISpecifierStringStubs = function() {
        var stubs = [];
        var pagesets = this.getPagesets();
        for (var i = 0; i < pagesets.length; ++i) {
            stubs = stubs.concat(pagesets[i].getUISpecifierStringStubs());
        }
        stubs.sort(function(a, b) {
            if (a[0] < b[0]) {
                return -1;
            }
            return a[0] == b[0] ? 0 : 1;
        });
        return stubs;
    }
}
function UIMap ( ) { // the singleton pattern, split into two parts so that "new" can still // be used, in addition to "getInstance()" UIMap . self = this ; // need to attach variables directly to the Editor object in order for them // to be in scope for Editor methods if ( is_IDE ( ) ) { Editor . uiMap = this ; Editor . UI_PREFIX = UI_GLOBAL . UI_PREFIX ; } this . pagesets = new Object ( ) ; /**
     * pageset[pagesetName]
     *   regexp
     *   elements[elementName]
     *     UIElement
     */ this . addPageset = function ( pagesetShorthand ) { try { var pageset = new Pageset ( pagesetShorthand ) ; } catch ( e ) { safe_alert ( "Could not create pageset from shorthand:\n" + print_r ( pagesetShorthand ) + "\n" + e . message ) ; return false ; } if ( this . pagesets [ pageset . name ] ) { safe_alert ( 'Could not add pageset "' + pageset . name + '": a pageset with that name already exists!' ) ; return false ; } this . pagesets [ pageset . name ] = pageset ; return true ; } ; /**
     * @param pagesetName
     * @param uiElementShorthand  a representation of a UIElement object in
     *                            shorthand JSON.
     */ this . addElement = function ( pagesetName , uiElementShorthand ) { try { var uiElement = new UIElement ( uiElementShorthand ) ; } catch ( e ) { safe_alert ( "Could not create UI element from shorthand:\n" + print_r ( uiElementShorthand ) + "\n" + e . message ) ; return false ; } // run the element's unit tests only for the IDE, and only when the // IDE is starting. Make a rough guess as to the latter condition. if ( is_IDE ( ) && ! editor . selDebugger && ! uiElement . test ( ) ) { safe_alert ( 'Could not add UI element "' + uiElement . name + '": failed testcases!' ) ; return false ; } try { this . pagesets [ pagesetName ] . uiElements [ uiElement . name ] = uiElement ; } catch ( e ) { safe_alert ( "Could not add UI element '" + uiElement . name + "' to pageset '" + pagesetName + "':\n" + e . message ) ; return false ; } return true ; } ; /**
     * Returns the pageset for a given UI specifier string.
     *
     * @param uiSpecifierString
     * @return  a pageset object
     */ this . getPageset = function ( uiSpecifierString ) { try { var uiSpecifier = new UISpecifier ( uiSpecifierString ) ; return this . pagesets [ uiSpecifier . pagesetName ] ; } catch ( e ) { return null ; } } /**
     * Returns the UIElement that a UISpecifierString or pageset and element
     * pair refer to.
     *
     * @param pagesetNameOrUISpecifierString
     * @return  a UIElement, or null if none is found associated with
     *          uiSpecifierString
     */ this . getUIElement = function ( pagesetNameOrUISpecifierString , uiElementName ) { var pagesetName = pagesetNameOrUISpecifierString ; if ( arguments . length == 1 ) { var uiSpecifierString = pagesetNameOrUISpecifierString ; try { var uiSpecifier = new UISpecifier ( uiSpecifierString ) ; pagesetName = uiSpecifier . pagesetName ; var uiElementName = uiSpecifier . elementName ; } catch ( e ) { return null ; } } try { return this . pagesets [ pagesetName ] . uiElements [ uiElementName ] ; } catch ( e ) { return null ; } } ; /**
     * Returns a list of pagesets that "contains" the provided page,
     * represented as a document object. Containership is defined by the
     * Pageset object's contain() method.
     *
     * @param inDocument  the page to get pagesets for
     * @return            a list of pagesets
     */ this . getPagesetsForPage = function ( inDocument ) { var pagesets = [ ] ; for ( var pagesetName in this . pagesets ) { var pageset = this . pagesets [ pagesetName ] ; if ( pageset . contains ( inDocument ) ) { pagesets . push ( pageset ) ; } } return pagesets ; } ; /**
     * Returns a list of all pagesets.
     *
     * @return  a list of pagesets
     */ this . getPagesets = function ( ) { var pagesets = [ ] ; for ( var pagesetName in this . pagesets ) { pagesets . push ( this . pagesets [ pagesetName ] ) ; } return pagesets ; } ; /**
     * Returns a list of elements on a page that a given UI specifier string,
     * maps to. If no elements are mapped to, returns an empty list..
     *
     * @param   uiSpecifierString  a String that specifies a UI element with
     *                             attendant argument values
     * @param   inDocument         the document object the specified UI element
     *                             appears in
     * @return                     a potentially-empty list of elements
     *                             specified by uiSpecifierString
     */ this . getPageElements = function ( uiSpecifierString , inDocument ) { var locator = this . getLocator ( uiSpecifierString ) ; var results = locator ? eval_locator ( locator , inDocument ) : [ ] ; return results ; } ; /**
     * Returns the locator string that a given UI specifier string maps to, or
     * null if it cannot be mapped.
     *
     * @param uiSpecifierString
     */ this . getLocator = function ( uiSpecifierString ) { try { var uiSpecifier = new UISpecifier ( uiSpecifierString ) ; } catch ( e ) { safe_alert ( 'Could not create UISpecifier for string "' + uiSpecifierString + '": ' + e . message ) ; return null ; } var uiElement = this . getUIElement ( uiSpecifier . pagesetName , uiSpecifier . elementName ) ; try { return uiElement . getLocator ( uiSpecifier . args ) ; } catch ( e ) { return null ; } } /**
     * Finds and returns a UI specifier string given an element and the page
     * that it appears on.
     *
     * @param pageElement  the document element to map to a UI specifier
     * @param inDocument   the document the element appears in
     * @return             a UI specifier string, or false if one cannot be
     *                     constructed
     */ this . getUISpecifierString = function ( pageElement , inDocument ) { var is_fuzzy_match = BrowserBot . prototype . locateElementByUIElement . is_fuzzy_match ; var pagesets = this . getPagesetsForPage ( inDocument ) ; for ( var i = 0 ; i < pagesets . length ; ++ i ) { var pageset = pagesets [ i ] ; var uiElements = pageset . getUIElements ( ) ; for ( var j = 0 ; j < uiElements . length ; ++ j ) { var uiElement = uiElements [ j ] ; // first test against the generic locator, if there is one. // This should net some performance benefit when recording on // more complicated pages. if ( uiElement . getGenericLocator ) { var passedTest = false ; var results = eval_locator ( uiElement . getGenericLocator ( ) , inDocument ) ; for ( var i = 0 ; i < results . length ; ++ i ) { if ( results [ i ] == pageElement ) { passedTest = true ; break ; } } if ( ! passedTest ) { continue ; } } var defaultLocators ; if ( uiElement . isDefaultLocatorConstructionDeferred ) { defaultLocators = uiElement . getDefaultLocators ( inDocument ) ; } else { defaultLocators = uiElement . defaultLocators ; } //safe_alert(print_r(uiElement.defaultLocators)); for ( var locator in defaultLocators ) { var locatedElements = eval_locator ( locator , inDocument ) ; if ( locatedElements . length ) { var locatedElement = locatedElements [ 0 ] ; } else { continue ; } // use a heuristic to determine whether the element // specified is the "same" as the element we're matching if ( is_fuzzy_match ) { if ( is_fuzzy_match ( locatedElement , pageElement ) ) { return UI_GLOBAL . UI_PREFIX + '=' + new UISpecifier ( pageset . name , uiElement . name , defaultLocators [ locator ] ) ; } } else { if ( locatedElement == pageElement ) { return UI_GLOBAL . UI_PREFIX + '=' + new UISpecifier ( pageset . name , uiElement . name , defaultLocators [ locator ] ) ; } } // ok, matching the element failed. See if an offset // locator can complete the match. if ( uiElement . getOffsetLocator ) { for ( var k = 0 ; k < locatedElements . length ; ++ k ) { var offsetLocator = uiElement . getOffsetLocator ( locatedElements [ k ] , pageElement ) ; if ( offsetLocator ) { return UI_GLOBAL . UI_PREFIX + '=' + new UISpecifier ( pageset . name , uiElement . name , defaultLocators [ locator ] ) + '->' + offsetLocator ; } } } } } } return false ; } ; /**
     * Returns a sorted list of UI specifier string stubs representing possible
     * UI elements for all pagesets, paired the their descriptions. Stubs
     * contain all required arguments, but leave argument values blank.
     *
     * @return  a list of UI specifier string stubs
     */ this . getUISpecifierStringStubs = function ( ) { var stubs = [ ] ; var pagesets = this . getPagesets ( ) ; for ( var i = 0 ; i < pagesets . length ; ++ i ) { stubs = stubs . concat ( pagesets [ i ] . getUISpecifierStringStubs ( ) ) ; } stubs . sort ( function ( a , b ) { if ( a [ 0 ] < b [ 0 ] ) { return - 1 ; } return a [ 0 ] == b [ 0 ] ? 0 : 1 ; } ) ; return stubs ; } }
Construct the UI map object, and return it. Once the object is instantiated,
it binds to a global variable and will not leave scope.

@return  new UIMap object
Construct the UI map object and return it . Once the object is instantiated it binds to a global variable and will not leave scope .