实现了CheckBox连动效果的treeview

<!----------------------------------------------------------------------
//   Copyright (c) 2000-2003 Microsoft Corporation.  All Rights Reserved.
//
---------------------------------------------------------------------->

< public:component tagname = treeview literalcontent = true >
    
< public:attach event = oncontentready onevent = " oncontentready() "   />
    
< public:attach event = ondocumentready onevent = " ondocumentready() "   />
    
< public:attach event = " onscroll "  onevent = " onScroll() "   />
    
< public:event name = " onexpand "  id = " _tvevtExpand "   />
    
< public:event name = " oncollapse "  id = " _tvevtCollapse "   />
    
< public:event name = " onselectedindexchange "  id = " _tvevtSelect "   />
    
< public:event name = " oncheck "  id = " _tvevtCheck "   />
    
< public:event name = " onfirequeuedevents "  id = " _tvevtFireQueuedEvents "   />
    
< public:event name = " onnodebound "  id = " _tvevtNodeBound "   />
    
< public:event name = " onnodetypesbound "  id = " _tvevtNodeTypesBound "   />
    
< public:event name = " onhover "  id = " _tvevtHover "   />
    
< public:event name = " onunhover "  id = " _tvevtUnhover "   />
    
< public:property name = " clickedNodeIndex "  GET = " getClickedNodeIndex "   />
    
< public:property name = " defaultStyle "  id = " _tvpropDefaultStyle "  GET = " getDefaultStyle "  PUT = " setDefaultStyle "   />
    
< public:property name = " hoverStyle "  id = " _tvpropHoverStyle "  GET = " getHoverStyle "  PUT = " setHoverStyle "   />
    
< public:property name = " selectedStyle "  id = " _tvpropSelectedStyle "  GET = " getSelectedStyle "  PUT = " setSelectedStyle "   />
    
< public:property name = " childType "  id = " _tvpropChildType "  GET = " getChildType "  PUT = " setChildType "   />
    
< public:property name = " imageUrl "  id = " _tvpropImageUrl "  GET = " getImageUrl "  PUT = " setImageUrl "   />
    
< public:property name = " expandedImageUrl "  id = " _tvpropExpandedImageUrl "  GET = " getExpandedImageUrl "  PUT = " setExpandedImageUrl "   />
    
< public:property name = " selectedImageUrl "  id = " _tvpropSelectedImageUrl "  GET = " getSelectedImageUrl "  PUT = " setSelectedImageUrl "   />
    
< public:property name = " target "  id = " _tvpropTarget "  GET = " getTarget "  PUT = " setTarget "   />
    
< public:property name = " treeNodeSrc "  id = " _tvpropTreeNodeSrc "  GET = " getTreeNodeSrc "  PUT = " setTreeNodeSrc "   />
    
< public:property name = " treeNodeXsltSrc "  id = " _tvpropTreeNodeXsltSrc "  GET = " getTreeNodeXsltSrc "  PUT = " setTreeNodeXsltSrc "   />
    
< public:property name = " selectExpands "  id = " _tvpropSelectExpands "  GET = " getSelectExpands "  PUT = " setSelectExpands "   />
    
< public:property name = " expandLevel "  id = " _tvpropExpandLevel "  GET = " getExpandLevel "  PUT = " setExpandLevel "   />
    
< public:property name = " autoSelect "  id = " _tvpropAutoSelect "  GET = " getAutoSelect "  PUT = " setAutoSelect "   />
    
< public:property name = " treeNodeTypeSrc "  id = " _tvpropTreeNodeTypeSrc "  GET = " getTreeNodeTypeSrc "  PUT = " setTreeNodeTypeSrc "   />
    
< public:property name = " showLines "  id = " _tvpropShowLines "  GET = " getShowLines "  PUT = " setShowLines "   />
    
< public:property name = " showPlus "  id = " _tvpropShowPlus "  GET = " getShowPlus "  PUT = " setShowPlus "   />
    
< public:property name = " showToolTip "  id = " _tvpropShowToolTip "  GET = " getShowToolTip "  PUT = " setShowToolTip "   />
    
< public:property name = " indent "  id = " _tvpropIndent "  GET = " getIndent "  PUT = " setIndent "   />
    
< public:property name = " selectedNodeIndex "  id = " _tvpropSelectedNodeIndex "  GET = " getSelectedNodeIndex "  PUT = " setSelectedNodeIndex "   />
    
< public:property name = " systemImagesPath "  id = " _tvpropSystemImagesPath "  GET = " getSystemImagesPath "  PUT = " setSystemImagesPath "   />
    
< public:method name = " queueEvent "   />
    
< public:method name = " getTreeNode "   />
    
< public:method name = " addAt "   />
    
< public:method name = " createTreeNode "   />
    
< public:method name = " getTreeNodeType "   />
    
< public:method name = " createTreeNodeType "   />
    
< public:method name = " addTreeNodeType "   />
    
< public:method name = " add "   />
    
< public:method name = " databind "   />
    
< public:method name = " databindTypes "   />
    
< public:method name = " getChildren "   />
    
</ public:component >

< script language = javascript >

var  contentNode;
var  treeviewNode;
var  g_typesNode;
var  g_styles;
var  g_event;
var  g_timer  =   - 1 ;
var  g_nodeClicked  =   null ;
var  g_strQueuedEvents  =   "" ;
var  g_bInteractive  =   false ;
var  g_numStop  =   0 ;
var  g_selectedNodeBeforeDelay  =   "" ;
var  g_bFocus  =   false ;
var  g_bCreated  =   false ;
var  g_typeIsland  =   null ;
var  g_bNodesReady  =   false ;
var  g_bTypesReady  =   false ;
var  g_bMouseDown  =   false ;
var  g_pendingBinds  =   new  Array( 0 );
var  g_pendingSyncBinds  =   new  Array( 0 );
var  g_bindTimer  =   - 1 ;
var  g_bLock  =   false ;
var  g_bInTypesBoundEvent  =   false ;
var  L_strMSXMLError_Text  =   " Error creating MSXML object.  Please make sure the MSXML library is installed on your computer. " ;
var  L_strRetrievingNodes_Text  =   " Retrieving nodes... " ;
var  L_strXMLError_Text  =   " Error loading XML file %s " ;
var  L_strInvalidXML_Text  =   " Invalid XML in %s " ;
var  L_strXSLTError_Text  =   "  or unsupported XSLT in %s " ;
var  L_fontSize_Text  =   " 10pt " ;
var  L_fontName_Text  =   " Times " ;
var  L_strToolTip_Text  =   " Use +/- to expand/collapse " ;

//  properties
var  prop_defaultStyle  =   null ;
var  prop_hoverStyle  =   null ;
var  prop_selectedStyle  =   null ;
var  prop_childType  =   null ;
var  prop_imageUrl  =   null ;
var  prop_expandedImageUrl  =   null ;
var  prop_selectedImageUrl  =   null ;
var  prop_target  =   null ;
var  prop_treeNodeSrc  =   null ;
var  prop_treeNodeXsltSrc  =   null ;
var  prop_selectExpands  =   null ;
var  prop_expandLevel  =   - 1 ;
var  prop_autoSelect  =   false ;
var  prop_treeNodeTypeSrc  =   null ;
var  prop_showLines  =   true ;
var  prop_showPlus  =   true ;
var  prop_showToolTip  =   true ;
var  prop_indent  =   19 ;
var  prop_selectedNodeIndex  =   null ;
var  prop_systemImagesPath  =   null ;

//
//
 QueueEvent()
//
//
 Queue an event for later posting to the server, when the
//
 _tvevtFireQueuedEvents event fires.
//
function  queueEvent(strEvent, strParams)
{
    
if  (g_strQueuedEvents.length  >   0 )
        g_strQueuedEvents 
+=   " ; " ;
    g_strQueuedEvents 
+=  (strEvent  +   " , "   +  strParams);
    setHiddenHelperValue();
}

function  getQueuedEvents()
{
    
return  g_strQueuedEvents;
}

function  fireQueuedEvents()
{
    
if  (g_strQueuedEvents  !=   "" )
    {
        
if  (getAttribute( " onfirequeuedevents " !=   null )
        {
            
if  (g_timer  !=   - 1 )
            {
                
//  force pending autoSelect to trigger
                window.clearTimeout(g_timer);
                autoSelect();
            }
            
else
            {
                g_bInteractive 
=   false ;
                g_numStop 
=   0 ;
                _tvevtFireQueuedEvents.fire();
            }
        }
    }
}

//
//
 SetAnchorClass()
//
//
 Set the cssText property in addition to the className, since just setting className
//
 doesn't do the trick.  
//
//
 node: Anchor to which we're applying a new class
//
 name: the class to apply
//
       DefaultStyle: Apply DefaultStyle
//
       HoverStyle: Apply DefaultStyle, then HoverStyle
//
       SelectedStyle: Apply DefaultStyle, then SelectedStyle
//

function  SetAnchorClass(node, name)
{
    
var  strStyle  =   "" ;
    
var  lname  =  name.toLowerCase();
    
    
//  Everything is based on DefaultStyle
    strStyle  +=  cascadeStyle(getParentTreeNode(node),  " defaultstyle " );

    
if  (lname  !=   " defaultstyle " )
    {
        
var  str  =  cascadeStyle(getParentTreeNode(node), lname);
        
if  (str  !=   null )
        {
            strStyle 
+=   " ; "   +  str;
        }        
    }
    node.style.cssText 
=  strStyle;
    
if  (lname  ==   " hoverstyle "   &&  g_bFocus  ==   false )
        blurFilter(node);
                
    node.className 
=  lname;
}

//
//
 getParentTreeNode()
//
//
 Walk up the display tree (NOT the TREENODE tree) until we find an element with
//
 a treenode expando.
//
function  getParentTreeNode(node)
{
    
var  el  =  node;
    
while  (el  !=   null   &&  el.getAttribute( " treenode " ==   null )
        el 
=  el.parentElement;
    
return  el.getAttribute( " treenode " );
}

//
//
 HoverNode()
//
//
 Apply hover effect to given text node
//
//
 textnode: textnode (id: _tntext) to apply hover to, or treenode
//
function  HoverNode(textnode)
{
    
var  node;
    
    
if  (textnode.tagName.toLowerCase()  ==   " treenode " )
        node 
=  textnode.subtree.all.item( " _tntext " 0 );
    
else
        node 
=  textnode;

    
var  nodeIndex  =  getNodeIndex(getParentTreeNode(node));

    
if  (node.className  ==   " defaultstyle " )
    {
        SetAnchorClass(node, 
" hoverstyle " );
        HoverNodeIndex 
=  nodeIndex;
    }
    
else   if  (node.className  !=   " hoverstyle " )
        HoverNodeIndex 
=   "" ;
    e 
=  element.document.createEventObject();
    e.treeNodeIndex 
=  nodeIndex;
    _tvevtHover.fire(e);
    setHiddenHelperValue();
}

//
//
 UnhoverNode()
//
//
 Remove hover effect from given text node
//
//
 textnode: textnode (id: _tntext) to remove hover from, or treenode
//
function  UnhoverNode(textnode)
{
    
if  (textnode  !=   null )
    {
        
var  node;
        
if  (textnode.tagName.toLowerCase()  ==   " treenode " )
            node 
=  textnode.subtree.all.item( " _tntext " 0 );
        
else
            node 
=  textnode;
            
        
if  (node.className  ==   " hoverstyle " )
        {
            SetAnchorClass(node, 
" defaultstyle " );
        }
        e 
=  element.document.createEventObject(event);
        
if  (HoverNodeIndex  ==   "" )
            e.treeNodeIndex 
=  getNodeIndex(getParentTreeNode(node))
        
else
            e.treeNodeIndex 
=  HoverNodeIndex;
        _tvevtUnhover.fire(e);
        HoverNodeIndex 
=   "" ;
        setHiddenHelperValue();
    }
}
    
//  mOver()
//
//
 onmouseover handler for the anchor of a treenode
//
function  mOver()
{
    
if  (g_bInteractive  ==   true )
    {
        
var  oItem  =   this .all.item( " _tntext " 0 );
        
if  (HoverNodeIndex.length  >   0 )
            UnhoverNode(getNodeFromIndex(HoverNodeIndex));
        HoverNode(oItem);
    }
}

//
//
 mOut()
//
//
 onmouseout handler for the anchor of a treenode
//
function  mOut()
{
    
if  (g_bInteractive  ==   true )
    {
        
var  node  =   this .parentElement.treenode;
        
var  nodeIndex  =  getNodeIndex(node)
        
if  (nodeIndex  ==  HoverNodeIndex)
        {
            UnhoverNode(node);
            window.status 
=  window.defaultStatus;
        }
        
else   if  (nodeIndex  ==  selectedNodeIndex)
        {
            e 
=  element.document.createEventObject(event);
            e.treeNodeIndex 
=  nodeIndex;
            _tvevtUnhover.fire(e);
        }        
    }
}

//
//
 onkeydown
//
function  onkeydown()
{
    
if  ( ! g_bInteractive)
        
return ;
    
    
if  (event.altKey  ==   true )
        
return ;
            
    
var  oldNode;
    
var  hoverNode  =   null ;
    
if  (HoverNodeIndex.length  >   0 )
    {
        oldNode 
=  getNodeFromIndex(HoverNodeIndex);
        hoverNode 
=  oldNode;
    }
    
else
        oldNode 
=  getNodeFromIndex(selectedNodeIndex);
    
switch  (event.keyCode)
    {
        
case   187 :    //  keyboard +/=
             if  (event.shiftKey  !=   true )
                
break ;
            
//  else fall through
         case   107 :    //  keypad +
             if  (oldNode.getAttribute( " expanded " !=   true )
            {
                doNodePlusMinusClick(oldNode);
                fireQueuedEvents();
            }
            event.returnValue 
=   false ;    
            
break ;
        
case   189 :    //  keyboard -/_
             if  (event.shiftKey  ==   true )
                
break ;
            
//  else fall through
         case   109 :    //  keypad -
             if  (oldNode.getAttribute( " expanded " ==   true )
            {
                doNodePlusMinusClick(oldNode);
                fireQueuedEvents();
            }
            event.returnValue 
=   false ;
            
break ;   
        
case   39 :     //  right arrow
            event.returnValue  =   false ;
            
if  (oldNode.children.tags( " treenode " ).length  ==   0 )
            {
                
var  exp  =  getNodeAttribute(oldNode,  " expandable " );
                
if  (exp  ==   null   &&  oldNode.getAttribute( " TreeNodeSrc " !=   null )
                    exp 
=   " checkOnce " ;
                
if  (oldNode.getAttribute( " expanded " ==   true   ||   ! (exp  ==   " always "   ||  (exp  ==   " checkOnce "   &&  oldNode.getAttribute( " checkedExpandable " !=   true )))
                    
break ;
            }
            
if  (oldNode.getAttribute( " expanded " !=   true )
            {
                doNodePlusMinusClick(oldNode);
                updateStatus(oldNode);
                fireQueuedEvents();
                
break ;
            }
            
//  fall through
         case   40 :     //  down arrow
             var  node  =  getNextVisibleNode(oldNode);
            
if  (node  !=   null )
            {
                
if  (element.getAttribute( " autoselect " ==   true )
                {
                    selectNode(node, 
true );
                    updateStatus(node);
                    UnhoverNode(hoverNode);
                }
                
else
                {                    
                    UnhoverNode(oldNode);
                    HoverNode(node);
                    changeFocus(node, oldNode);                    
                    updateStatus(node);
                }
                scrollTree(node);
            }
            event.returnValue 
=   false ;
            
break ;
        
case   37 :     //  left arrow
             if  (oldNode.getAttribute( " expanded " ==   true )
            {
                doNodePlusMinusClick(oldNode);
                fireQueuedEvents();
            }
            
else
            {
                
//  jump the hover up to the parent node
                 var  node  =  oldNode.parentElement;
                
while  (node.tagName.substr( 0 , 4 ).toLowerCase()  !=   " tree " )
                    node 
=  node.parentElement;
                
if  (node.tagName.toLowerCase()  ==   " treenode " )
                {
                    
if  (element.getAttribute( " autoselect " ==   true )
                    {
                        selectNode(node, 
true );
                        updateStatus(node);
                        UnhoverNode(hoverNode);
                    }
                    
else
                    {
                        UnhoverNode(oldNode);
                        HoverNode(node);
                        changeFocus(node, oldNode);
                        updateStatus(node);
                    }
                    scrollTree(node);
                }
            }
            event.returnValue 
=   false ;
            
break ;
        
case   38 :     //  up arrow
             var  node  =  getPreviousVisibleNode(oldNode);
            
if  (node  !=   null )
            {
                
if  (element.getAttribute( " autoselect " ==   true )
                {
                    selectNode(node, 
true );
                    updateStatus(node);
                    UnhoverNode(hoverNode);
                }
                
else
                {
                    UnhoverNode(oldNode);
                    HoverNode(node);
                    changeFocus(node, oldNode);
                    updateStatus(node);
                }
                scrollTree(node);
            }
            event.returnValue 
=   false ;
            
break ;
        
case   32 :     //  spacebar
             var  cb  =  oldNode.subtree.all.item( " _cb " 0 );
            
if  (cb  !=   null )
            {
                cb.setAttribute(
" checked " ! cb.getAttribute( " checked " ),  0 );
                doCheckboxClick(oldNode);
                fireQueuedEvents();
            }
            event.returnValue 
=   false ;
            
break ;
        
case   13 :     //  enter key
            doNodeClick(oldNode)
            
if  ( ! navigateNode(oldNode))
            {
                
if  (element.getAttribute( " selectExpands " ==   true )
                    doNodePlusMinusClick(oldNode);
                fireQueuedEvents();
            }
            event.returnValue 
=   false ;
            
break ;
    }
}

//
//
 changeFocus()
//
function  changeFocus(node, oldNode)
{
    
var  accessnode  =  node.subtree.all.item( " _tnaccess " 0 );
    accessnode.tabindex 
=   1 ;
    accessnode.focus();
    accessnode 
=  oldNode.subtree.all.item( " _tnaccess " 0 );
    accessnode.tabindex 
=   - 1 ;
}

//
//
 updateStatus()
//
function  updateStatus(node)
{
    
var  href  =  node.getAttribute( " navigateurl " );
    
if  (href  !=   null )
        window.status 
=  href;
    
else
        window.status 
=  window.defaultStatus;
}

//
//
 onstop
//
function  onstop()
{
    g_numStop
++ ;
    
if  (g_numStop  >=   2 )
    {
        g_bInteractive 
=   true ;
    }

    
for  ( var  i  =   0 ; i  <  g_pendingBinds.length; i ++ )
    {
        
if  (g_pendingBinds[i]  !=   null   &&  g_pendingBinds[i].el  !=   null )
            g_pendingBinds[i].el._bound 
=   null ;
    }
}

//
//
 onfocus
//
function  onfocus()
{
    
if  ( ! g_bFocus)
    {
        dofocus();
    }
}

//
//
 dofocus
//
function  dofocus()
{
    
var  node  =   null ;
    g_bFocus 
=   true ;   //  sometimes we just call dofocus() without going through onfocus()
     try
    {
        node 
=  getNodeFromIndex(selectedNodeIndex);
    }
    
catch  (e)
    {
    }
    
if  (node  !=   null )
    {
        
var  oItem  =  node.subtree.all.item( " _tnaccess " 0 );
        
if  (oItem  !=   null )
        {
            
if  (g_bInteractive)
            {
                focusFilter(oItem);
                oItem.tabIndex 
=   1 ;
                
if  ( ! g_bMouseDown)  //  don't scroll the window when selecting a new node
                {
                    
try
                    {
                        
var  prevScrollTop  =  element.scrollTop;
                        
var  prevScrollLeft  =  element.scrollLeft;

                        oItem.focus();

                        element.scrollTop 
=  prevScrollTop;
                        element.scrollLeft 
=  prevScrollLeft;
                    }
                    
catch  (e)
                    {
                    }
                }
            }
        }
    }

    node 
=   null ;
    
try
    {
        node 
=  getNodeFromIndex(HoverNodeIndex);
    }
    
catch  (e)
    {
    }

    
if  (node  !=   null   &&  g_bInteractive)
    {
        
var  oItem  =  node.subtree.all.item( " _tnaccess " 0 );
        
if  (oItem  !=   null )
            focusFilter(oItem);
    }
}

//
//
 focusFilter
//
function  focusFilter(oItem)
{
    
if  (oItem.id  ==   " _tnaccess " )
        oItem 
=  oItem.all.item( " _tntext " 0 ); 
    
if  (oItem.filters.length  >   0 )
    {
        
var  oFilter  =  oItem.filters.item( " DXImageTransform.Microsoft.Alpha " );
        
if  (oFilter)
        {
            oFilter.opacity 
*=   2 ;
        }
    }
}

//
//
 onblur
//
function  onblur()
{
    
var  node  =   null ;
    g_bFocus 
=   false ;
    
try
    {
        node 
=  getNodeFromIndex(selectedNodeIndex);
    }
    
catch  (e)
    {
    }

    
if  (node  !=   null )
    {
        
var  oItem  =  node.subtree.all.item( " _tnaccess " 0 );
        
if  (oItem  !=   null )
        {
            blurFilter(oItem);
            oItem.tabIndex 
=   - 1 ;
        }
    }

    node 
=   null ;
    
try
    {
        node 
=  getNodeFromIndex(HoverNodeIndex);
    }
    
catch  (e)
    {
    }
    
if  (node  !=   null )
    {
        
var  oItem  =  node.subtree.all.item( " _tnaccess " 0 );
        
if  (oItem  !=   null )
        {
            blurFilter(oItem);
            oItem.tabIndex 
=   - 1 ;
        }
    }    
    setHiddenHelperValue();
}

//
//
 blurFilter
//
//
 decreases alpha filter opacity on given node by 50%, adding one if needed
//
function  blurFilter(oItem)
{
    
if  (oItem.id  ==   " _tnaccess " )
        oItem 
=  oItem.all.item( " _tntext " 0 ); 
    
if  (oItem.filters.length  >   0 )
    {
        
var  oFilter  =  oItem.filters.item( " DXImageTransform.Microsoft.Alpha " );
        
if  (oFilter)
        {
            oFilter.opacity 
/=   2 ;
            
return ;
        }
    }
    oItem.style.filter 
+=   " progid:DXImageTransform.Microsoft.Alpha(opacity=50,style=0) " ;
}

//
//
 oncontentready
//
//
 oncontentready handler for the TREEVIEW element.  Initializes the tree.
//
function  oncontentready()
{
    
if  (element.document.parentWindow.name.indexOf( " __hifSmartNav " ==   0 )
        
return //  don't run script in SmartNav's IFrame
 
    g_styles 
=   new  Object();
    
var  strFont  =   " font:  "   +  L_fontSize_Text  +   "   "   +  L_fontName_Text  +   " " ;
    g_styles[
" parent " =  strFont  +   " text-decoration: none; color: black; overflow:hidden; " ;
    g_styles[
" child " =  strFont  +   " overflow:hidden; " ;
    g_styles[
" defaultstyle " =  strFont  +   " display:inline-block; color: black; text-decoration:none; cursor: hand; overflow:hidden; " ;
    g_styles[
" hoverstyle " =   " color: highlighttext; background-color:highlight; filter:progid:DXImageTransform.Microsoft.Alpha(opacity=50,style=0); " ;
    g_styles[
" selectedstyle " =   " color: highlighttext; background-color:highlight; " ;
    g_styles[
" icon " =   " cursor:hand; " ;
    
    
if  (element.style.overflowX  ==   "" );
        element.style.overflowX 
=   " auto " ;
    
    
//
     //  Set treeview attributes to boolean
     //
    verifyBooleanAttribute(element,  " showPlus " );
    
if  (element.getAttribute( " showPlus " ==   false   &&  element.getAttribute( " selectExpands " ==   null )
        element.setAttribute(
" selectExpands " true 0 );
    verifyBooleanAttribute(element, 
" selectExpands " );
    verifyBooleanAttribute(element, 
" autoSelect " );
    verifyBooleanAttribute(element, 
" showLines " );
    verifyBooleanAttribute(element, 
" showToolTip " );
    
    
var  systemImagesPath  =  element.getAttribute( " SystemImagesPath " );
    
if  (systemImagesPath  ==   null )
        element.setAttribute(
" SystemImagesPath " " treeimages/ " 0 );
    
else   if  (systemImagesPath.charAt(systemImagesPath.length  -   1 !=   ' / ' )
        element.setAttribute(
" SystemImagesPath " , systemImagesPath  +   ' / ' 0 );
    
if  (isRtl())
    {
        element.setAttribute(
" SystemImagesPath " , element.getAttribute( " SystemImagesPath " +   " rtl/ " 0 );
    }
    
    
//  Create div for parsing content
    contentNode  =  element.document.createElement( " treeview " );
    contentNode.innerHTML 
=  element.innerHTML;
    
    element.tabIndex
= 0 ;
    element.attachEvent(
" onkeydown " , onkeydown);
    element.attachEvent(
" onfocus " , onfocus);
    element.attachEvent(
" onblur " , onblur);
    f_AddStopEvent();
    element.hideFocus 
=   true ;

    
if  (element.getAttribute( " selectedNodeIndex " ==   null )
        prop_selectedNodeIndex 
=   "" ;

    
if  (element.getAttribute( " HoverNodeIndex " ==   null )
        element.setAttribute(
" HoverNodeIndex " "" 0 );
           
    
//  Create nodeTypes collection on the element
     if  (element.getAttribute( " TreeNodeTypeSrc " ==   null )
    {
        element.nodeTypes 
=  contentNode.children.tags( " TREENODETYPE " );
        verifyTypeValues();
        g_bTypesReady 
=   true ;
    }
    
else
        databindTypes();

    
if  (treeNodeSrc  !=   null )
    {
        
if  (element.nodeTypes  !=   null )
        {
            contentNode.innerHTML 
=  getNodeTypeHtml();
            element.nodeTypes 
=  contentNode.children.tags( " TREENODETYPE " );
        }
        
else
            contentNode.innerHTML 
=   "" ;
        databindNode(element);
    }
    
else
    {
        g_bNodesReady 
=   true ;
        tryToBuildTreeFromRoot();
    }
}

//
//
 ondocumentready()
//
function  ondocumentready()
{
    
if  (element.document.parentWindow.name.indexOf( " __hifSmartNav " ==   0 )
        
return //  don't run script in SmartNav's IFrame

    f_CleanupEvents();

    g_strQueuedEvents 
=   "" ;

    
if  (HoverNodeIndex.length  >   0 )
        HoverNode(getNodeFromIndex(HoverNodeIndex));

    g_bInteractive 
=   true ;

    
if  (element.getAttribute( " Focused " !=   null )
        dofocus();
    
else
        onblur();

    
var  newScrollTop  =  element.getAttribute( " __scrollTop " );
    
var  newScrollLeft  =  element.getAttribute( " __scrollLeft " );
    
if  (newScrollTop  !=   null )
        element.scrollTop 
=  newScrollTop;
    
if  (newScrollLeft  !=   null )
        element.scrollLeft 
=  newScrollLeft;

    
var  parent  =  element.offsetParent;
    
if  (parent  !=   null )
    {
        
var  newParentTop  =  element.getAttribute( " __parentTop " );
        
var  newParentLeft  =  element.getAttribute( " __parentLeft " );
        
if  (newParentTop  !=   null )
            parent.scrollTop 
=  newParentTop;
        
if  (newParentLeft  !=   null )
            parent.scrollLeft 
=  newParentLeft;
    }
    
    
//  verify selectedNodeIndex
     if  (getNodeFromIndex(selectedNodeIndex)  ==   null )
    {
        
if  (getNodeFromIndex( " 0 " !=   null )
            selectedNodeIndex 
=   " 0 " ;
        
else
            selectedNodeIndex 
=   "" ;
    }    
}

//
//
 changeIcon(node, imageUrl)
//
//
 Change the icon to the given Url.  If the Url isn't found, don't change anything.  The exception
//
 is if we try to set the icon to an unspecified ExpandedImageUrl, we instead show the ImageUrl.
//

function  changeIcon(node, imageUrl)
{
    
var  icon1;
    
var  imageUrlLC  =  imageUrl.toLowerCase();
    
var  textnode  =  node.subtree.all( " _tntext " 0 );
    
var  accessnode  =  node.subtree.all( " _tnaccess " 0 );
    
var  spacer  =  accessnode.previousSibling;
    
if  (spacer  !=   null )
    {   
        icon1 
=  spacer.previousSibling;
        
if  (icon1  !=   null   &&  icon1.id  !=   " _nodeicon " )   
            icon1 
=   null
    }
    
else
        icon1 
=   null ;
    
var  newSrc  =  getNodeAttribute(node, imageUrlLC);
    
    
if  (newSrc  !=   null   &&  icon1  ==   null )
    {
        
//  node's ImageUrl attribute was not defined, so there is no icon.  Make one.
        icon1  =  node.document.createElement( " <IMG align='absmiddle' border='0' class='icon' id='_nodeicon' > " );
        icon1.src 
=  newSrc;
        accessnode.parentElement.insertBefore(icon1, accessnode);
        
//  don't forget the spacer
        spacer  =  node.document.createElement( " <SPAN> " );
        spacer.style.width 
=   5 ;
        accessnode.parentElement.insertBefore(spacer, accessnode);        
    }
    
else   if  (newSrc  !=   null )
    {
        icon1.src 
=  newSrc;
        icon1.style.display 
=   " inline " ;
    }
    
else   if  (imageUrlLC  ==   " imageurl " )
    {
        
if  (icon1  !=   null )
        {
            
//  If the node's ImageUrl isn't defined, we don't want to leave a selected or expanded icon showing.  Hide it.
            icon1.style.display  =   " none " ;
        }
    }
    
else   if  (imageUrlLC  ==   " selectedimageurl "   &&  node.getAttribute( " expanded " ==   true )
        changeIcon(node, 
" expandedimageurl " );
    
else  
        changeIcon(node, 
" imageurl " );
    
if  (icon1  !=   null )
    {
        icon1.style.cursor 
=  textnode.style.cursor;
        spacer.style.cursor 
=  textnode.style.cursor;
    }
}   

//
//
 selectNode(node)
//
//
 Make node the selected node, unselecting the previously selected node.
//
//
 node: node to select
//
 delay: TRUE to delay event firing (used on keyboard nav with autoselect=true)
//
function  selectNode(node, delay)
{
    
var  nodeIndex;
    
var  selectedNode  =   null ;
    
var  strImage;
    
var  oItem;
    
var  oOldItem  =   null ;

    
if  (node  &&  node.subtree  ==   null )
        node 
=  getNodeFromIndex( " 0 " );  //  can't select a node that hasn't been built; select root instead      
        
    nodeIndex 
=  getNodeIndex(node);
    
if  (selectedNodeIndex  !=  nodeIndex)
    {
        
if  (selectedNodeIndex  !=   ""   &&  selectedNodeIndex  !=   null )
        {
            
//  unselect previous item
            selectedNode  =  getNodeFromIndex(selectedNodeIndex);
            
if  (selectedNode  !=   null   &&  selectedNode.subtree  !=   null )
            {
                oOldItem 
=  selectedNode.subtree.all.item( " _tntext " 0 );
                SetAnchorClass(oOldItem, 
" defaultstyle " );
                oOldItem.parentElement.tabIndex 
=   - 1 ;
                
//  restore old icon
                 if  (selectedNode.getAttribute( " expanded " ==   true )
                    strImage 
=   " ExpandedImageUrl " ;
                
else
                    strImage 
=   " ImageUrl " ;
                changeIcon(selectedNode, strImage);
            }
        }

        
if  (node)
        {
            oItem 
=  node.subtree.all.item( " _tntext " 0 );
            applySelection(node, oItem);
        }
                
        
if  (selectedNodeIndex.length  >   0 )
        {
            
//  Fire event
            g_event  =  createEventObject();
            g_event.newTreeNodeIndex 
=  nodeIndex;
            g_event.oldTreeNodeIndex 
=  selectedNodeIndex;
            prop_selectedNodeIndex 
=  nodeIndex;
            
if  (delay  !=   true )
                _tvevtSelect.fire(g_event);
            
else
            {
                
if  (g_timer  !=   - 1 )
                    window.clearTimeout(g_timer);
                g_timer 
=  window.setTimeout(autoSelect,  500 " JScript " );
                
if  (g_selectedNodeBeforeDelay  ==   "" )
                    g_selectedNodeBeforeDelay 
=  g_event.oldTreeNodeIndex;
            }
        }
        
else
            prop_selectedNodeIndex 
=  nodeIndex;

        
//  Because we use a timeout to set focus, between a nodeclick and changing the selected node
         //  a user's event, which could have an alert, can occur.  An alert blurs the tree, which
         //  leaves the old selected node with a 50% filter.  So if we're blurred when we unselect the
         //  old node, call focusFilter to it to correct the problem.  
         if  ( ! g_bFocus  &&  g_bInteractive)
        {
            
if  (oOldItem  !=   null )
                focusFilter(oOldItem);
        }     
    }
    setHiddenHelperValue();  
//  here instead of inside the main IF to preserve focus change
}

function  autoSelect()
{
    g_timer 
=   - 1 ;
    
if  (selectedNodeIndex  !=  g_selectedNodeBeforeDelay)
    {
        navigateNode(getNodeFromIndex(g_event.newTreeNodeIndex));
        _tvevtSelect.fire(g_event);
        fireQueuedEvents();
    }
    g_selectedNodeBeforeDelay 
=   "" ;
}

//
//
 applySelection()
//
function  applySelection(node, oItem)
{
    SetAnchorClass(oItem, 
" SelectedStyle " );
    
    
//  set new icon
    changeIcon(node,  " SelectedImageUrl " );

    scrollTree(node);
    
    
if  (selectedNodeIndex.length  >   0 )
    {
        
if  (g_bFocus)
            changeFocus(node, getNodeFromIndex(selectedNodeIndex));
    }
    
    
//   We need to blur node if we re-selected it while blurred (which can happen when using client OM)
     if  ( ! g_bFocus  &&  g_bInteractive)
    {
        blurFilter(oItem);
    }
}

//
//
 reselectNode()
//
function  reselectNode(el)
{
    
if  (selectedNodeIndex  ==  getNodeIndex(el))
        applySelection(el, el.subtree.all.item(
" _tntext " 0 ));
}

//
//
 tryToBuildTreeFromRoot()
//
function  tryToBuildTreeFromRoot()
{
    
if  (g_bNodesReady  ==   true   &&  g_bTypesReady  ==   true )
    {
        
var  bRebuilding  =  g_bCreated;
        
        buildTreeFromRoot();

        
if  (selectedNodeIndex.length  ==   0 )
        {
            prop_selectedNodeIndex 
=   " 0 " ;
        }
        
var  node  =  getNodeFromIndex(selectedNodeIndex);
        prop_selectedNodeIndex 
=   "" ;
        selectNode(node);
    }
}

//
//
 buildTreeFromRoot()
//
function  buildTreeFromRoot()
{
    
//  Create TREEVIEW surrogate div, to encapsulate all other DIVs.
    treeviewNode  =  element.document.createElement( " HTML " );
    
var  bodyNode  =  element.document.createElement( " BODY " );
    bodyNode.dir 
=  element.getAttribute( " dir " );
    bodyNode.style.direction 
=  element.currentStyle.direction;        
    
    
var  head  =  element.document.createElement( " HEAD " );
    
var  base  =  element.document.createElement( " BASE " );
    
var  path  =   null ;
    
if  (window.location.pathname  !=   null )
    {
        
var  lastslash  =  window.location.pathname.lastIndexOf( " / " );
        
if  (lastslash  !=   - 1 )
            path 
=  window.location.pathname.substr( 0 , lastslash  +   1 );
        
else
            path 
=  window.location.pathname;
    }
    
var  protocol  =  window.location.protocol.toLowerCase();
    base.href 
=  window.location.protocol  +  (protocol  !=   " mailto: "   &&  protocol  !=   " news: "   ?   " // "  :  "" +  window.location.host  +  path;
    head.appendChild(base);
    treeviewNode.appendChild(head);
    
    
var  kids  =  contentNode.children.tags( " treenode " );
    
if  (kids[ 0 !=  undefined)
    {
        
for  ( var  i  =   0 ; i  <  kids.length; i ++ )
        {
            kids[i].sibIndex 
=  i;
            
var  subtree  =  buildTree(kids[i],  0 );
            bodyNode.appendChild(subtree);
        }
    }
    treeviewNode.appendChild(bodyNode);
    
    
//  Create viewlink.
    treeviewNode.style.display  =   " block " ;
    treeviewNode.subtree 
=  bodyNode;
    defaults.viewLink 
=  treeviewNode.document;
    setHiddenHelperValue();

    g_bCreated 
=   true ;
}       

//
//
 buildTree()
//
//
 Recursively traverses the
//
 parsed TREEVIEW tree and creates the document tree of nested
//
 DIVs for the viewlink.
//
//
 root: Root node of the subtree to build
//
 level: level of the tree
//
//
 returns: created subtree
//
function  buildTree(root, level)
{  
    
var  display  =   true ;
    
if  (root.subtree  !=   null   &&  root.subtree.style.display  ==   " none " )
        display 
=   false ;
        
    root.detachEvent(
" onclick " , DefaultNodeOnClick);
    root.attachEvent(
" onclick " , DefaultNodeOnClick);
    
    
//  clear all cached values for this node
    root.inheritedType  =  undefined;
    root.nodetypeIndex 
=  undefined;

    
//  process expandLevel
     var  exp  =  makeBoolean(root.getAttribute( " expanded " ));
    
if  (exp  ==   null )
    {
        
if  (level  <  element.getAttribute( " ExpandLevel " ))
        {
            root.setAttribute(
" expanded " true 0 );
            exp 
=   true ;
        }
        
else
            exp 
=   false ;
    }
    
    
//
     //  convert string values to boolean
     //
     if  ( ! verifyBooleanAttribute(root,  " expanded " ))
        root.setAttribute(
" expanded " false 0 );
    
if  ( ! verifyBooleanAttribute(root,  " checked " ))
        root.setAttribute(
" checked " false );
    verifyBooleanAttribute(root, 
" checkBox " );
    verifyBooleanAttribute(root, 
" checkedExpandable " );
             
    
if  (root.getAttribute( " type " !=   null )
        root.setAttribute(
" type " , root.getAttribute( " type " ).toLowerCase(),  0 );
    
if  (root.getAttribute( " childType " !=   null )
        root.setAttribute(
" childType " , root.getAttribute( " childType " ).toLowerCase(),  0 );
        
    
//  Create this node first
     var  collChildren  =  root.children.tags( " treenode " );
    
var  iChildren  =  collChildren.length;
    
var  expandable  =  getNodeAttribute(root,  " expandable " );
    
if  (expandable  ==   null   &&  root.getAttribute( " TreeNodeSrc " !=   null )
        expandable 
=   " checkOnce " ;
    
if  (root.getAttribute( " _bound " !=   " binding " )
    {
        
var  subtree  =  generateItem(root, iChildren  >   0   ||  (expandable  ==   " always "   ||  (expandable  ==   " checkOnce "   &&  root.getAttribute( " checkedExpandable " !=   true ))  ?   " parent "  :  " child " );
        
if  (display  ==   false )
            subtree.style.display 
=   " none " ;
            
        
if  (exp  ==   true   &&  root.getAttribute( " TreeNodeSrc " !=   null   &&  root.getAttribute( " _bound " !=   " complete " )
        {
            
//  Databind.  When databinding is finished, this subtree will be built automatically
            root.setAttribute( " expanded " true 0 );
            saveSubtree(root, subtree);
            databindNode(root);
        }
        
else
        {
            
//  Create children
             if  (root.getAttribute( " expanded " ==   true )
            {
                
for  ( var  i  =   0 ; i  <  iChildren; i ++ )
                {
                    collChildren[i].sibIndex 
=  i;
                    
var  sub2  =  buildTree(collChildren[i], level  +   1 );
                    
if  (sub2  !=  undefined)
                        subtree.appendChild(sub2);
                }
            }
            
else
            {
                
for  ( var  i  =   0 ; i  <  iChildren; i ++ )
                {
                    
if  (collChildren[i].getAttribute( " subtree " !=   null )
                        collChildren[i].subtree 
=   null ;
                }
            }
            saveSubtree(root, subtree);
        }
    }
    
    
return  root.subtree;
}

//
//
 saveSubtree(el, subtree)
//
function  saveSubtree(el, subtree)
{
    
if  (el.getAttribute( " subtree " ==   null )
        el.subtree 
=  subtree;
    
else  {
        el.subtree.replaceNode(subtree);
        el.subtree 
=  subtree;
    }
}
     
//
//
 calcJunction(el)
//
//
 Determine if this node is at an L, T, or top root (R) junction.
//
function  calcJunction(el)
{
    
var  elParent  =  el.parentElement;
    
var  collChildren  =  elParent.children.tags( " treenode " );
    
    
if  (elParent.tagName  ==   " treeview "    &&  collChildren[ 0 ==  el)
    {
        
if  (collChildren.length  >   1 )
            
return  ( ' F ' );
        
else
            
return  ( ' R ' );
    }
    
else
    {
        
if  (collChildren[collChildren.length  -   1 ==  el)
        {
            
return  ( ' L ' );
        }
        
else
        {
            
return  ( ' T ' );
        }
    }
}

//
//
 generateItem(el, nodeclass)
//
//
 Creates the DOM object tree for a TREEVIEW item.
//
//
 el: TREENODE element for which the tree is generated
//
 nodeclass: "parent" or "child" (leaf)
//
function  generateItem(el, nodeClass)
{
    
var  image;
    
var  plusminusNode;
    
var  elAnchor;
    
    
var  expImgUrl  =  getNodeAttribute(el,  " ExpandedImageUrl " );
    
var  imgUrl  =  getNodeAttribute(el,  " ImageUrl " );
    
var  node  =  el.document.createElement( " DIV " );
    
var  cJunction;
    
var  junctionNode;
    
var  str;
    
    node.className 
=  nodeClass;
    node.treenode 
=  el;
    node.noWrap 
=   true
    node.style.display 
=   " block " ;
    
    
if  (nodeClass  ==   " child "   &&  el.getAttribute( " expanded " ==   true )
        el.setAttribute(
" expanded " false 0 );
        
    
//  Determine L, T, or root junction
    cJunction  =  calcJunction(el);
    junctionNode 
=  generateJunctionNode(el, cJunction, nodeClass);          
    node.appendChild(junctionNode);
    
    addLinesAndWhitespace(node, el, junctionNode);  
    
    
//  Add checkbox
     if  (getNodeAttribute(el,  " checkBox " ==   true )
    {
        
var  cb  =  createCheckBox(el);
        node.appendChild(cb);
    }
             
    
//  Add anchor tag
    elAnchor  =  el.document.createElement( " <A> " );
    elAnchor.onclick 
=  nodePlusMinusClick;
    junctionNode.applyElement(elAnchor, 
" outside " );
        
    
//  Add second anchor for image/text
    elAnchor  =  el.document.createElement( " <A tabindex=-1> " );
    str 
=  getNodeAttribute(el,  " NavigateUrl " );
    
if  (str  !=   null   &&  str  !=   "" )
    {
        elAnchor.href 
=  str;
    }
    str 
=  getNodeAttribute(el,  " Target " );
    
if  (str  !=   null )
        elAnchor.target 
=  str;
        
    
//  For accessibility, generate another anchor to enclose the text node
     var  accessAnchor  =  elAnchor.cloneNode();
    accessAnchor.id 
=   " _tnaccess " ;
    
    elAnchor.onclick 
=  nodeClick;
    elAnchor.oncontextmenu 
=  contextmenu;
    elAnchor.onmousedown 
=  mousedown;
    elAnchor.onmouseup 
=  mouseup;
    node.insertBefore(elAnchor);
        
    imageSrc 
=  (nodeClass  ==   " parent "   &&  el.getAttribute( " expanded " ==   true   &&  expImgUrl  !=   null   ?  expImgUrl : imgUrl);

    
var  spacer  =   null ;
    
if  (imageSrc  !=   null   &&  imageSrc  !=  undefined)
    {
        image 
=  el.document.createElement( " <IMG align='absmiddle' border='0' class='icon' id='_nodeicon'> " );
        image.src 
=  imageSrc;
        image.style.cssText 
=  g_styles[ " icon " ];
        elAnchor.appendChild(image);
        spacer 
=  el.document.createElement( " <SPAN> " );
        spacer.style.width 
=   5 ;
        elAnchor.appendChild(spacer);
    }
    
    
var  textNode  =  generateTextNode(el);
    
if  (spacer  !=   null )
    {
        spacer.style.cursor 
=  textNode.style.cursor;
        image.style.cursor 
=  textNode.style.cursor;
    }
    
    
if  (nodeClass  ==   " parent "   &&  element.getAttribute( " showToolTip " !=   false )
        accessAnchor.title 
=  textNode.innerText  +   "  :  "   +  L_strToolTip_Text;
    
    accessAnchor.appendChild(textNode);
    elAnchor.appendChild(accessAnchor);
    
    elAnchor.onmouseenter 
=  mOver;
    elAnchor.onmouseleave 
=  mOut;
        
    
return  node;
}

//
//
 createCheckBox
//
function  createCheckBox(el)
{
    
var  form  =  el.document.createElement( " <FORM style='display:inline' name='_fcb'> " );
    
var  bChecked  =  el.getAttribute( " checked " );
    
var  cb  =  el.document.createElement( " <INPUT style='display:inline' tabindex=-1 type=checkbox name='_cb' "   +  (bChecked  ?   "  checked  "  :  "   " +   " /> " );
    cb.onclick 
=  checkboxClick;
    form.appendChild(cb);
    
    
return  form;
}

//
//
 generateJunctionNode()
//
function  generateJunctionNode(el, cJunction, nodeClass)
{
    
var  imageSrc;
    
var  junctionNode;
    
var  systemImagesPath  =  element.getAttribute( " systemImagesPath " );
    
    
if  (element.getAttribute( " showLines " !=   false )
    {
        imageSrc 
=  systemImagesPath;
        
switch  (cJunction)
        {
            
case   ' L ' :
                imageSrc 
+=   " L " ;
                
break ;
            
case   ' T ' :
                imageSrc 
+=   " T " ;
                
break ;
            
case   ' R ' :
                imageSrc 
+=   " R " ;
                
break ;
            
case   ' F ' :
                imageSrc 
+=   " F " ;
                
break ;
            
default :
                
return   null ;
                
break ;
        }
        
if  (nodeClass  ==   " parent "   &&  element.getAttribute( " showPlus " !=   false  )
        {
            
if  (el.getAttribute( " expanded " ==   true )
                imageSrc 
+=   " minus.gif " ;
            
else
                imageSrc 
+= " plus.gif " ;
        }
        
else
            imageSrc 
+=   " .gif " ;
    }
    
else
    {
        
if  (nodeClass  ==   " parent "   &&  element.getAttribute( " showPlus " !=   false )
        {
            
if  (el.getAttribute( " expanded " ==   true )
                imageSrc 
=  systemImagesPath  +   " minus.gif " ;
            
else
                imageSrc 
=  systemImagesPath  +   " plus.gif " ;
        }
        
else
        {
            imageSrc 
=  systemImagesPath  +   " white.gif " ;
        }
    }
    
if  (element.getAttribute( " showLines " ==   false   &&  element.getAttribute( " showPlus " ==   false )
        junctionNode 
=  element.document.createElement( " <SPAN name='junction'> " );
    
else
    {
        junctionNode 
=  element.document.createElement( " <IMG align='absmiddle' border='0' class='icon' name='junction'> " );
        junctionNode.src 
=  imageSrc;
    }    
    
return  junctionNode;
}

//
//
 addLinesAndWhitespace()
//
function  addLinesAndWhitespace(node, el, junctionNode)
{
    
//
     //  Walk up tree to draw lines/whitespace
     //
     var  elWalk  =  el.parentElement;
    
var  elInsertBefore  =  junctionNode;
    
var  systemImagesPath  =  element.getAttribute( " systemImagesPath " );

    
if  (element.getAttribute( " showLines " !=   false )
    {
        
while  (elWalk  &&  elWalk.tagName.toLowerCase()  ==   " treenode " )
        {
            
var  nextSib  =  elWalk.nextSibling;
            
while  (nextSib  !=   null   &&  nextSib.nodeType  ==   3 )
                nextSib 
=  nextSib.nextSibling;
                
            
var  imageSrc;
            
var  image;
            
            
if  (nextSib  !=   null   &&  nextSib.tagName.toLowerCase()  ==   " treenode " )
                imageSrc 
=  systemImagesPath  +   " I.gif " ;
            
else
                imageSrc 
=  systemImagesPath  +   " white.gif " ;
            image 
=  el.document.createElement( " <IMG align='absmiddle' border='0'> " );
            image.src 
=  imageSrc;
            elInsertBefore 
=  node.insertBefore(image, elInsertBefore);
            elWalk 
=  elWalk.parentElement;
        }
    }    
    
else
    {
        
var  strIndex  =  getNodeIndex(el);
        
if  (strIndex.indexOf( " . " !=   - 1 )
        {
            
if  (element.getAttribute( " Indent " !=   null )
            {
                
if  (isRtl())
                    node.style.marginRight 
=  element.getAttribute( " Indent " );
                
else                            
                    node.style.marginLeft 
=  element.getAttribute( " Indent " );
            }
        }
    }
}

//
//
 generateTextNode()
//
//
 el: treenode for which to generate text node
//
function  generateTextNode(el)
{
    
var  textNode  =  el.document.createElement( " <SPAN id=_tntext tabIndex=-1 style='display:inline; height=100%'> " );
    
    
if  (el.getAttribute( " Text " !=   null )
    {
        textNode.innerHTML 
=  el.getAttribute( " Text " );
    }
    
else
    {
        
//  Remove any TREENODEs from the inner content, keeping everything else.
         var  iChild  =   0 ;
        
while  (iChild  <  el.childNodes.length)
        {
            
if  (el.childNodes[iChild].nodeType  ==   3   ||  el.childNodes[iChild].tagName.toLowerCase()  !=   " treenode " )
            {
                
//  just copy the content
                 var  oClone  =  el.childNodes[iChild].cloneNode( true );
                textNode.appendChild(oClone);
            }
            iChild
++ ;
        }
    }
    textNode.className 
=   " defaultstyle " ;
    
var  defStyle  =  cascadeStyle(el,  " defaultstyle " );
    textNode.style.cssText 
=  defStyle;

    
return  textNode;
}

//
//
 updateTree(el)
//
//
 Show or hide the children of element el based on el's Expanded
//
 attribute.
//
  
function  updateTree(el)
{
    
if  (el.getAttribute( " expanded " ==   true )
    {
        
//  If we previously expanded this
         //  node, just show its children without rebuilding them.
         var  i  =   0 ;
        
var  coll  =  el.children.tags( " treenode " );
        
var  bRebuild  =   true ;
        
if  (el.getAttribute( " _buildChildren " !=   true   &&  (coll.length  >   0   &&  coll( 0 ).getAttribute( " subtree " !=   null ))
        {   
            bRebuild 
=   false
            
for  ( var  i  =   0 ; i  <  coll.length; i ++ )
            {
                
if  (coll(i).subtree  ==   null )
                {
                    
//  a node has been added since we last expanded.  Rebuild everything.
                    bRebuild  =   true ;
                    
break ;
                }
                coll(i).subtree.style.display 
=   " block " ;
            }
        }
        
if  (bRebuild)
        {
            
//  build and show children
            el.removeAttribute( " _buildChildren " );
            buildTree(el, getNodeLevel(el));
            reselectNode(el);
            
if  (HoverNodeIndex  ==  getNodeIndex(el))
                HoverNode(el);
        }
    }
    
    
else
    {
        
//  hide children
         var  collChildren  =  el.children.tags( " treenode " );
        
for  ( var  i  =   0 ; i  <  collChildren.length; i ++ )
        {
            collChildren(i).subtree.style.display 
=   " none " ;
        }
               
        
//  If the selected or hovered node was one of the collapsed node's descendants,
         //  the collapsed node must become selected/hovered instead
         var  index  =  getNodeIndex(el);
        
if  (selectedNodeIndex.length  >  index.length  &&  selectedNodeIndex.substr( 0 ,index.length)  ==  index)
        {
            selectNode(el);
        }
        
else   if  (selectedNodeIndex  ==  index)
            changeIcon(el, 
" SelectedImageUrl " );
            
        
if  (HoverNodeIndex.length  >=  index.length  &&  HoverNodeIndex.substr( 0 , index.length)  ==  index)
        {
            
if  (selectedNodeIndex  !=  index)
            {
                
if  (HoverNodeIndex  !=  index)
                {
                    UnhoverNode(getNodeFromIndex(HoverNodeIndex));
                    HoverNode(el);
                }
            }
            
else
                UnhoverNode(getNodeFromIndex(HoverNodeIndex));
        }
    }
    setHiddenHelperValue();
}        
    
//
//
 cascadeStyle(el, att)
//
//
 Cascade style from built-in to the tree to the type to the node.
//
function  cascadeStyle(el, att)
{
    
//  built-in
     var  str  =  g_styles[att];

    
//  tree
     var  strStyle  =  element.getAttribute(att);
    
if  (strStyle  !=   null )
        str 
=  str  +   " ; "   +  strStyle;
    
    
//  type
    strStyle  =  getNodeTypeAttribute(el, att);
    
if  (strStyle  !=   null )
        str 
=  str  +   " ; "   +  strStyle;
    
    
//  node
    strStyle  =  el.getAttribute(att);
    
if  (strStyle  !=   null )
        str 
=  str  +   " ; "   +  strStyle;
    
    
return  str;
}

//
//
 getNodeTypeAttribute    
//
//
 Returns the given attribute from the given element's node type.
//
function  getNodeTypeAttribute(el, att)
{
    
var  _nodetype  =  getNodeTypeObject(el);
    
if  (_nodetype  !=   null )
        
return  _nodetype.getAttribute(att);
    
return   null ;
}

//
//
 getNodeAttribute
//
//
 Returns the given attribute from the node, the node's type, or the treeview
//
function  getNodeAttribute(el, att)
{
    
var  strReturn;
    
    
//  try the node
    strReturn  =  el.getAttribute(att);
    
if  (strReturn  !=   null )
        
return  strReturn;
        
    
//  try the node's type
    strReturn  =  getNodeTypeAttribute(el, att);
    
if  (strReturn  !=   null )
        
return  strReturn;
        
    
//  try the tree
     return  element.getAttribute(att);
}

//
//
 navigateNode()
//
//
 If the given node has a NavigateUrl, navigate to it.  Return TRUE if we're navigating our own page; FALSE otherwise.
//
function  navigateNode(el)
{
    
var  url  =  getNodeAttribute(el,  " NavigateUrl " );
    
if  (url  !=   null   &&  url  !=   "" )
    {
        
var  target  =  getNodeAttribute(el,  " Target " );
        
if  (target  ==   null   ||  target  ==   " _self " )
        {
            window.open(url, 
" _self " );
            
return   true ;
        }
        
else
            window.open(url, target);
    }
    
return   false ;
}

//
//
 checkboxClick()
//
//
 event handler for mouse click on an item's checkbox
//
function  checkboxClick()
{
    
if  (g_bInteractive  ==   false )
        
return ;

    
var  el  =   this .parentElement.parentElement.treenode;
    event.cancelBubble 
=   true ;
    
    doCheckboxClick(el);
    fireQueuedEvents();
}

//
//
 doCheckboxClick()
//
  function  doCheckboxClick(el){
            
var  checked  =  private_getAttribute(el, " checked " )
            el.checked 
=   ! checked;
            
var  evt  =  createEventObject();
            evt.treeNodeIndex 
=  getNodeIndex(el);
            g_nodeClicked 
=  el;
            _tvevtCheck.fire(evt);
            setNodeState(el,el.checked);
//  maybe need el only,but I think it's safly
        }
        
function   setNodeState(el,state){
            _setChildNode(el,state);
            _setParentNode(el,state);
        }
         
function   _setChildNode(el,state){
            
var  childNodes  =  el.children;
            
if (childNodes.length  >   0 ){ //  if has childs 
                 for ( var  i  =   0  ;i <= childNodes.length - 1 ;i ++ ){
                    private_setAttribute(childNodes[i],
" Checked " ,state);
                    _saveCheckState(childNodes[i]);
                    _setChildNode(childNodes[i],state);
                }
            }
        }
        
function   _setParentNode(el,state){
            
var  parentNode  =  el.parentElement;
            
if (parentNode){
                
if ( ! _checkSiblingdNode(el)){
                    private_setAttribute(parentNode,
" Checked " ,state);
                    _saveCheckState(parentNode);
                    _setParentNode(parentNode,state);
                }
            }
        }
        
function  _checkSiblingdNode(el){
            
var  parentNode  =  el.parentElement; //  you can use getParentTreeNode function in this htc,but I like this usage.
             for ( var  i  =   0 ;i <= parentNode.children.length - 1 ;i ++ ){
                
if (el  !=  parentNode.children[i]){
                    
if (private_getAttribute(parentNode.children[i], " Checked " )){
                        
return   true ;
                    }
                }
            }
            
return   false ;
        }
            
            
function  _saveCheckState(el){
            
if (getNodeIndex(el))
                queueEvent(
' oncheck ' , getNodeIndex(el));
        }
//
//
 nodeClick()
//
//
 event handler for mouse click on an item in the tree
//
function  nodeClick()
{
    
if  (g_bInteractive  ==   false )
        
return ;

    
var  el  =   this .parentElement.treenode;
    
if  (doNodeClick(el)  ==   true )
    {
        
if  (element.getAttribute( " selectExpands " ==   true )
            doNodePlusMinusClick(el);
        fireQueuedEvents();
    }
}

//
//
 contextmenu()
//
//
 event handler for right-clicking a tree node
//
function  contextmenu()
{
    event.cancelBubble 
=   true ;
    e 
=  element.document.createEventObject(event);
    e.treeNodeIndex 
=  getNodeIndex( this .parentElement.treenode);
    event.returnValue 
=  element.fireEvent( " oncontextmenu " , e);
}

//
//
 mousedown()
//
function  mousedown()
{
    
if  (event.button  &   1 )
    {
        g_bMouseDown 
=   true ;
    }
}

//
//
 mouseup()
//
function  mouseup()
{
    g_bMouseDown 
=   false ;
}

//
//
 nodePlusMinusClick()
//
//
 event handler for mouse click on the plus/minus icon of a treenode
//
function  nodePlusMinusClick()
{
    
if  (g_bInteractive  ==   false )
        
return ;

    
var  el  =   this .parentElement.treenode;
    
if  (doNodePlusMinusClick(el)  ==   true )
        fireQueuedEvents();
}

//
//
 doNodeClick()
//
//
 Does the work associated with a node click.  Separated out from nodeClick() so that
//
 we can call it directly without having to identify the anchor element of a node.
//
//
 returns: true to continue processing
//
          false to stop (because we're navigating our own page)
//
function  doNodeClick(el)
{
    
if  (g_bInteractive  ==   false )
        
return ;
        
    g_nodeClicked 
=  el;

    
//  The element, which is in a content node outside of the document, is outside the event hierarchy.
     //  Fire the event ourselves, rather than relying on bubbling.
    event.cancelBubble  =   true ;
    el.fireEvent(
" onclick " );         //  Execute our onclick handler
    element.fireEvent( " onclick " , event);   //  Execute the tree's onclick handler

    
if  (getNodeAttribute(el,  " NavigateUrl " !=   null )
    {
        
var  target  =  getNodeAttribute(el,  " Target " );
        
if  (target  ==   null   ||  target.toLowerCase()  ==   " _self " )
            
return   false ;
    }

    selectNode(el);
    
return   true ;
}

//
//
 doNodePlusMinusClick()
//
//
 Does the work associated with a node click.  Separated out from nodePlusMinusClick() so that
//
 we can call it directly without having to identify the anchor element of a node.
//
//
 return: true if something interesting happened (expanded, collapsed), false otherwise
//
function  doNodePlusMinusClick(el)
{
    
if  (g_bInteractive  ==   false )
        
return   false ;
        
    
//  The element, which is in a content node outside of the document, is outside the event hierarchy.
     //  Fire the event ourselves, rather than relying on bubbling.
    event.cancelBubble  =   true ;

    g_nodeClicked 
=  el;

    
if  (el.getAttribute( " expanded " ==   false   &&  el.getAttribute( " _bound " ==   null   &&  el.getAttribute( " TreeNodeSrc " !=   null )
    {
        el._isExpanding 
=   true ;
        private_databind(el);
        
return   true ;
    }
    
else
        
return  finishNodePlusMinusClick(el);
}

function  finishNodePlusMinusClick(el)
{        
    
//  See if we're a leaf (no children) or a branch (children)
     var  exp  =  getNodeAttribute(el,  " expandable " );
    
if  (exp  ==   null   &&  el.getAttribute( " TreeNodeSrc " !=   null )
        exp 
=   " checkOnce " ;

    
if  (el.children.tags( " treenode " ).length  >   0   ||  exp  ==   " always "   ||  (exp  ==   " checkOnce "   &&  el.getAttribute( " checkedExpandable " !=   true ))
    {
        
//
         //  We're a branch.  Update ourselves.
         //
         var  expanded  =   ! el.getAttribute( " expanded " );
        el.setAttribute(
" expanded " , expanded,  0 );
        
        
if  (exp  ==   " checkOnce " )
            el.checkedExpandable 
=   true ;
            
        
var  evt  =  createEventObject();
        evt.treeNodeIndex 
=  getNodeIndex(el);

        
var  eventToFire  =  changeJunctionImage(el);
        
        
//  update our children
        updateTree(el);
        doVisualRefresh();
        
        
//  show status node if we're posting back for databinding
         if  (expanded  ==   true   &&  el.children.tags( " treenode " ).length  ==   0   &&  element.getAttribute( " onfirequeuedevents " !=   null )
            addStatusNode(el, L_strRetrievingNodes_Text);
        
        eventToFire.fire(evt);

        
return   true ;
    }
    
return   false ;
}

//
//
 changeJunctionImage()
//
//
 Changes the +/- junction image to match current Expanded state.
//
//
 el: treenode element containing junction image to change
//
function  changeJunctionImage(el)
{
    
//  find the icons we need to change
     var  icon1  =  el.subtree.all( " junction " , 0 );
    
    
if  (el.getAttribute( " expanded " ==   true )
    {
        
//  Expanding the node
         if  (icon1  !=   null )
            icon1.src 
=  icon1.src.replace( / plus / " minus " );
        
if  (selectedNodeIndex  !=  getNodeIndex(el)  ||  getNodeAttribute(el,  " selectedimageurl " ==   null )
            changeIcon(el, 
" ExpandedImageUrl " );
        
return  _tvevtExpand;
    }
    
else
    {
        
//  Collapsing the node
         if  (icon1  !=   null )
            icon1.src 
=  icon1.src.replace( / minus / " plus " );
        
if  (selectedNodeIndex  !=  getNodeIndex(el))
            changeIcon(el, 
" ImageUrl " );
        
return  _tvevtCollapse;
    }
}

//
//
 DefaultNodeOnClick()
//
//
 A default onclick handler for treenode elements to cancel the event bubble.
//
 This is needed for the server control, otherwise the event will bubble up the
//
 tree until it hits a node with an onclick handler.  In the case of a server
//
 control, odds are good that the onclick handler will cause a server postback,
//
 thereby preventing the tree from getting its onclick.  So we need to cancel
//
 the bubble, allowing the onclick event we fire on the tree to get through.
//
function  DefaultNodeOnClick()
{
    event.cancelBubble 
=   true ;
}

function  getClickedNodeIndex()
{
    
if  (g_nodeClicked  !=   null )
        
return  getNodeIndex(g_nodeClicked);
    
else
        
return   null ;
}

function  getNodeLevel(node)
{
    
var  level  =   0 ;
    
while  (node.parentElement.tagName.toLowerCase()  ==   " treenode " )
    {
        node 
=  node.parentElement;
        level
++ ;
    }
    
return  level;
}
    
//
//
 getNodeIndex()
//
//
 Walks up the tree, generating an index string of the form a.b.c[...].z (ex: 1.0.5.12) where
//
 each number represents a 0-based index into a set of children.  Each set of these values
//
 creates a unique index to a node.  In the following tree:
//
         A
//
       / | 
//
      B  C  D
//
     /    / 
//
    E   F G   H
//
 node F is 0.0.1, node G is 0.2.0, and H is 0.2.1.
//
function  getNodeIndex(node)
{
    
var  strIndex  =   "" ;
    
if  (node  !=   null )
    {
        
if  (node.getAttribute( " sibIndex " ==   null )
        {
            
if  (node.parentElement  ==   null )
            {
                
//  There is no parent, this node is in the ether
                 return   null ;
            }

            
//  generate a sibling index
             var  col  =  node.parentElement.children.tags( " treenode " );
            
var  i  =   0 ;
            
while  (col[i]  !=  node)
                i
++ ;
            node.sibIndex 
=  i;
        }
        strIndex 
=  node.sibIndex.toString();
        
while  (node.parentElement  &&  node.parentElement.tagName.toLowerCase()  ==   " treenode " )
        {
            node 
=  node.parentElement;
            
if  (node.getAttribute( " sibIndex " ==   null )
                
return   null ;
            strIndex 
=  node.sibIndex  +   " . "   +  strIndex;
        }
    }
    
return  strIndex;
}

//
//
 getNodeFromIndex()
//
//
 The flipside of getNodeIndex, this function returns a node given a dot-delimited index
//
function  getNodeFromIndex(strIndex)
{
    
if  (strIndex  !=   null   &&  strIndex  !=  undefined  &&  strIndex.length  !=   0 )
    {
        
//  convert index string into array of strings
         var  a  =  strIndex.split( " . " );
        
var  i  =   0 ;
        
var  node  =  contentNode;
        
while  (i  <  a.length)
        {
            
var  coll  =  node.children.tags( " treenode " );
            
if  (coll  ==   null   ||  coll.length  <  (a[i]  -   0 +   1 )
            {
                
return   null ;
            }                
            node 
=  coll.item(a[i ++ -   0 );
        }
        
return  node;
    }
    
else
    {
        
return   null ;
    }
}
 

//
//
 getNextVisibleNode()
//
function  getNextVisibleNode(node)
{
    
var  next  =  node;
    
if  (node.getAttribute( " expanded " ==   true )
    {
        
//  get first child treenode
        next  =  node.children[ 0 ];
        
while  (next  !=   null   &&  next  !=  undefined  &&  next.nodeName.toLowerCase()  !=   " treenode " )
            next 
=  next.nextSibling;
        
if  (next)
            
return  next;
    }
    
    
//  get first sibling treenode
    next  =  node.nextSibling;
    
while  (next  !=   null   &&  next  !=  undefined  &&  next.nodeName.toLowerCase()  !=   " treenode " )
        next 
=  next.nextSibling;
    
if  (next  !=   null
        
return  next;
     
    
//  get first sibling of first ancestor that has one     
    next  =  node.parentElement;
    
while  ((next.nextSibling  ==   null   ||  next.nextSibling  ==  undefined)  &&  next.nodeName.toLowerCase()  ==   " treenode " )
    {
        next 
=  next.parentElement;
    }
    
if  (next.nextSibling  !=   null   &&  next.nextSibling  !=  undefined  &&  next.nextSibling.nodeName.toLowerCase()  ==   " treenode " )
        
return  next.nextSibling;
    
else
        
return   null ;
}
        
//
//
 getPreviousVisibleNode()
//
function  getPreviousVisibleNode(node)
{
    
var  prev  =  node;
    
    
//  check for a previous sibling
    prev  =  node.previousSibling;
    
while  (prev  !=   null   &&  prev  !=  undefined  &&  prev.nodeName.toLowerCase()  !=   " treenode " )
        prev 
=  prev.previousSibling;
    
if  (prev)
    {
        
//  Found a previous sibling.  If that sibling is expanded, we need to drop down to its last child
         if  (prev.getAttribute( " expanded " ==   true )
        {
            
//  get last child
             var  lastChild  =  prev;
            
while  (lastChild  !=  node  &&  lastChild  !=   null )
            {
                prev 
=  lastChild;
                lastChild 
=  getNextVisibleNode(prev);
            }
        }
        
return  prev;
    }
    
    
//  get parent
     if  (node.parentElement.nodeName.toLowerCase()  ==   " treenode " )
        
return  node.parentElement;
    
else
        
return   null ;
}        

//
//
 setHiddenHelperValue()
//
function  setHiddenHelperValue()
{
    
var  id  =  element.HelperID;
    
if  (id  ==   null )
        
return ;

    
var  helper  =  window.document.all(id);
    
if  (helper  ==   null )
        
return ;

    
var  parentTop  =   - 1 ;
    
var  parentLeft  =   - 1 ;
    
var  parent  =  element.offsetParent;
    
if  (parent  !=   null )
    {
        parentTop 
=  parent.scrollTop;
        parentLeft 
=  parent.scrollLeft;
    }

    helper.value 
=  (g_bFocus  ?   " 1 "  :  " 0 " +   " | "   +  HoverNodeIndex  +   " | "   +  element.scrollTop  +   " | "   +  element.scrollLeft  +   " | "   +  parentTop  +   " | "   +  parentLeft  +   " | "   +  g_strQueuedEvents;
}

//
//
 scrollTree()
//
function  scrollTree(tnode)
{
    
var  node  =  tnode.subtree.all.item( " _tntext " 0 );

    
var  top  =  node.offsetTop  -  element.scrollTop;
    
if  (top  <   0 )
    {
        element.scrollTop 
+=  top;
    }
    
else
    {
        
var  bottom  =  top  +  node.offsetHeight;
        
var  elemHeight  =  element.clientHeight;
        
if  (bottom  >  elemHeight)
        {
            element.scrollTop 
+=  bottom  -  elemHeight;
        }
    }

    
var  rc  =  node.getBoundingClientRect();
    
var  elRc  =  element.getBoundingClientRect();

    
//  scroll window if we're focused  
     if  (g_bFocus)
    {
        
if  (elRc.top  +  rc.top  <  element.document.body.clientTop) 
            node.scrollIntoView(
true );
        
else   if  (elRc.top  +  rc.bottom  >  element.document.body.clientHeight)
            node.scrollIntoView(
false );
    }

}

//
//
 getInheritedType()
//
//
 Returns the node's inheritedType, if defined, or finds it and returns it if undefined.
//
 A node's inheritedType is the first of:
//
      * parent's childType
//
      * parent's type's childType
//
      * parent's inheritedType's childType
//
      * parent's inheritedType
//
function  getInheritedType(el)
{
    
if  (el.inheritedType  ===  undefined  ||  g_bInTypesBoundEvent)
    {
        
var  parentNode  =  el.parentElement;
/*
        while (parentNode.tagName.toLowerCase() != "treenode" && parentNode.tagName.toLowerCase() != "treeview")
            parentNode = parentNode.parentElement;
*/         
        
//  parent's childType
        el.inheritedType  =  parentNode.getAttribute( " childType " );
        
var  tagname  =  parentNode.tagName.toLowerCase();
        
        
if  (el.inheritedType  ==   null   &&  tagname  !=   " treeview " )
        {
            
//  parent's type's or inheritedType's childType
             var  _parenttype  =  getNodeTypeObject(parentNode);
            
if  (_parenttype  !=   null )
            {
                el.inheritedType 
=  _parenttype.getAttribute( " childType " );
            }
                       
            
//  parent's inheritedType
             if  (el.inheritedType  ==   null   &&  tagname  ==   " treenode " )
            {
                el.inheritedType 
=  getInheritedType(parentNode);
            }
        }

        
//  grab from the treeview
         if  (el.inheritedType  ==   null )
            el.inheritedType 
=  element.getAttribute( " childType " );
    }
    
return  el.inheritedType;
}
 
//
//
 getNodeTypeObject()
//
//
 Returns the node type object for the given node, if defined.  If undefined, searches
//
 for and stores the node type object, then returns it.  Returns null if no type is defined
//
 for this node.
//
//
 This function assumes that a node's type or inheritedType attribute holds the name of its type
//
function  getNodeTypeObject(el)
{
    
if  (el.nodetypeIndex  ==  undefined  ||  g_bInTypesBoundEvent)
    {
        
var  theType  =  el.getAttribute( " type " );
        
if  (theType  ==   null )
            theType 
=  getInheritedType(el);
        
if  (theType  ==   null )
            
return   null ;
        
        theType 
=  theType.toLowerCase();
        
var  i  =   0 ;
        
var  len  =  element.nodeTypes.length;
        
while  (i  <  len)
        {
            
if  (element.nodeTypes[i].getAttribute( " type " ==  theType)
            {
                el.nodetypeIndex 
=  i;
                
break ;
            }
            i
++ ;
        }
    }
    
return  element.nodeTypes[el.nodetypeIndex];
}

//
//
 replaceJunctionNode()
//
//
 Replace the junction node of the given node by generating a new one
//
 
//
 node: treenode on which to perform replacement
//
function  replaceJunctionNode(node)
{
    
if  (node.subtree  ==   null )
        
return ;
    
var  oldNode  =  node.subtree.all( " junction " 0 );
    
if  (oldNode  ==   null )
        
return ;
        
    
var  cJunction  =  calcJunction(node);
    
var  exp  =  node.getAttribute( " Expandable " );
    
if  (exp  ==   null   &&  node.getAttribute( " TreeNodeSrc " !=   null )
        exp 
=   " checkOnce " ;
    
var  bChildNodes  =  node.children.tags( " treenode " ).length  >   0 ;
    
var  junctionNode  =  generateJunctionNode(node, cJunction, bChildNodes  ||  (exp  ==   " always "   ||  (exp  ==   " checkOnce "   &&  node.getAttribute( " checkedExpandable " !=   true ))  ?   " parent "  :  " child " );          
    
var  accessNode  =  node.subtree.all( " _tnaccess " 0 );
    
if  ( ! bChildNodes)
        accessNode.title 
=   ""
    
else
    {
        
var  textNode  =  node.subtree.all( " _tntext " 0 );
        accessNode.title 
=  textNode.innerText  +   "  :  "   +  L_strToolTip_Text;
    }
    oldNode.replaceNode(junctionNode);
}

//
//
 addStatusNode()
//
function  addStatusNode(el, str)
{
    
if  (el.subtree  !=   null   &&  el.subtree.all.item( " _fetch " 0 !=   null )
        
return ;
        
    
//  Show "fetching" message
     var  fetchNode  =   el.document.createElement( " <DIV id=_fetch> " );
    
var  imageNode  =  el.document.createElement( " <IMG align='absmiddle' border='0'> " );
    imageNode.src 
=  element.getAttribute( " systemimagespath " +   " white.gif " ;
    fetchNode.appendChild(imageNode);    
    
var  junctionNode  =  generateJunctionNode( null ' L ' " child " );
    fetchNode.appendChild(junctionNode);
    addLinesAndWhitespace(fetchNode, el 
==  element  ?  contentNode : el, junctionNode);  
    
var  textNode  =  el.document.createElement( " <SPAN id=_tntext tabIndex=-1 style='display:inline; height=100%'> " );
    textNode.innerText 
=  str;
    textNode.className 
=   " defaultstyle " ;
    
var  defStyle;
    
if  (el  ==  element)
        defStyle 
=  g_styles[ " defaultstyle " +   " ; "   +  element.getAttribute( " defaultstyle " );
    
else
        defStyle 
=  cascadeStyle(el,  " defaultstyle " );
    textNode.style.cssText 
=  defStyle;
    fetchNode.appendChild(textNode);
    
if  (el  ==  element)
    {
        
if  ( ! g_bCreated)
        {
            
//  Create viewlink.
            fetchNode.style.display  =   " block " ;
            defaults.viewLink 
=  fetchNode.document;
        }
        
else
        {
            treeviewNode.appendChild(fetchNode);
        }
    }
    
else
    {
        
if  (el.subtree  !=   null )
            el.subtree.appendChild(fetchNode);
    }
    doVisualRefresh();
}

//
//
 databindNode()
//
//
 Databind to the given node's TreeNodeSrc & TreeNodeXsltSrc.  This creates
//
 the node's children based on this binding, but does not affect the node
//
 itself.
//
//
 el: node for which we're databinding
//
function  databindNode(el)
{
    
var  src  =  el.getAttribute( " TreeNodeSrc " );
    
if  (src  ==   null )
        
return ;

    addStatusNode(el, L_strRetrievingNodes_Text);
    el._bound 
=   " binding " ;  

    
var  XsltSrc  =  el.getAttribute( " TreeNodeXsltSrc " );
    
var  databindInfo  =   new  Object();
    databindInfo.el 
=  el;
    databindInfo.transform 
=   null ;
    databindInfo.island 
=   null ;
    databindInfo.src 
=  src;
    
    
if  (el  ==  contentNode)
        g_bNodesReady 
=   false ;

    
if  (XsltSrc  !=   null )
    {
        databindInfo.transform 
=  element.document.all(XsltSrc);
        
if  (databindInfo.transform  ==   null )
        {
            
//  create our own data island for the transform

            
try
            {
                databindInfo.transform 
=   new  ActiveXObject( " Msxml2.DOMDocument " );
            }
            
catch  (e)
            {
                databindError(databindInfo, L_strMSXMLError_Text);
                
return ;
            }
            databindInfo.transform.async 
=   false ;
            
if  ( ! databindInfo.transform.loadXML(XsltSrc))
                databindInfo.transform.load(XsltSrc);
        }
        
else
            databindInfo.transform 
=  databindInfo.transform.XMLDocument;
    }
    
    databindInfo.island 
=  element.document.all(src);

    
if  (databindInfo.island  ==   null )
    {
        
//  create our own data island
         try
        {
            databindInfo.island 
=   new  ActiveXObject( " Msxml2.DOMDocument " );
        }
        
catch  (e)
        {
            databindError(databindInfo, L_strMSXMLError_Text);
            
return ;
        }
        databindInfo.island.async 
=   false ;
        g_pendingSyncBinds 
=  g_pendingSyncBinds.concat(databindInfo);
        
if  (g_bindTimer  ==   - 1 )
            g_bindTimer 
=  window.setTimeout(syncBind,  10 " JScript " );
    }
    
else
        finishDatabindingNode(databindInfo, 
true );
}

function  syncBind()
{
    
//  loop through pending synchronous databinds
     while  (g_pendingSyncBinds.length  >   0 )
    {
        
var  databindInfo  =  g_pendingSyncBinds[ 0 ];
        
//  remove from array
        g_pendingSyncBinds.splice( 0 1 );
        
if  ( ! databindInfo.island.loadXML(databindInfo.src))
        {
            databindInfo.island.async 
=   true ;
            
//  add to our array of pending databinds
            g_pendingBinds  =  g_pendingBinds.concat(databindInfo);
            databindInfo.island.onreadystatechange 
=  finishDatabindingNodeHandler;
            databindInfo.island.load(databindInfo.src);
        }
        
else
            finishDatabindingNode(databindInfo, 
true );
    }
    g_bindTimer 
=   - 1 ;
}
    
function  finishDatabindingNodeHandler()
{
    
//  loop through pending databinds, resolving those which are complete
     for  ( var  i  =   0 ; i  <  g_pendingBinds.length; i ++ )
    {
        
if  (g_pendingBinds[i].island.readyState  ==   1 )
            g_pendingBinds[i].b 
=   true ;
        
if  (g_pendingBinds[i].island.readyState  ==   4   &&  g_pendingBinds[i].b  ==   true )
        {
            
var  bindInfo  =  g_pendingBinds[i];
            g_pendingBinds.splice(i, 
1 );
            finishDatabindingNode(bindInfo, 
false );
            i
-- ;
        }
    }
}

function  finishDatabindingNode(databindInfo, bReady)
{
    
if  (bReady  !=   true   &&  databindInfo.island  ==   null )
        
return ;

    
if  (databindInfo.island.xml  ==   ""   ||  (databindInfo.transform  !=   null   &&  databindInfo.transform.xml  ==   "" ))
    {
        
var  regexp  =   /% s / ;
        
var  str  =   " <B> "   +  L_strXMLError_Text  +   " </B> " ;
        str 
=  str.replace(regexp, databindInfo.el.getAttribute( ' TreeNodeSrc ' ));
        databindError(databindInfo, str);
        
return ;
    }
   
    
//  Databind to this data island
     if  (databindInfo.transform  !=   null )
    {
        
var  html  =  databindInfo.island.transformNode(databindInfo.transform);
        
try
        {
            databindInfo.island 
=    new  ActiveXObject( " Msxml2.DOMDocument " );
        }
        
catch  (e)
        {
            databindError(databindInfo, L_strMSXMLError_Text);
            
return ;
        }
        databindInfo.island.loadXML(html);
    }

    
//  Make sure the root is a TREENODES tag
     var  container  =  databindInfo.island.selectSingleNode( " TREENODES " );
    
if  (container  ==   null )
    {
        
var  strXslt  =  databindInfo.el.getAttribute( " TreeNodeXsltSrc " );
        
var  strError  =   " <B> "   +  L_strInvalidXML_Text;
        
var  regexp  =   /% s / ;
        strError 
=  strError.replace(regexp, databindInfo.el.getAttribute( ' TreeNodeSrc ' ));
        
if  (strXslt  !=   null )
        {
            strError 
+=  L_strXSLTError_Text  +   " </B> " ;
            strError 
=  strError.replace(regexp, databindInfo.el.getAttribute( ' TreeNodeXsltSrc ' )); 
        }
        
else
            strError 
+=   " </B> " ;
        databindError(databindInfo, strError);
        
return ;
    }
    
    
var  child  =  container.firstChild;
    
var  html  =   "" ;
    
while  (child  !=   null )
    {
        
if  (child.nodeName.toLowerCase()  ==   " treenode " )
            html 
+=  child.xml;
        child 
=  child.nextSibling;
    }
    databindInfo.el._bound 
=   " complete " ;
    
    
//  All nodes must have namespace inserted
    html  =  html.replace( / ( < /? )(treenode) / gi,  " $1 "   +  element.scopeName  +   " :$2 " );
    
    
if  (databindInfo.el  ==  element)
    {
        contentNode.innerHTML 
=  html;
        g_bNodesReady 
=   true ;
        tryToBuildTreeFromRoot(); 
    }
    
else
    {
        databindInfo.el.innerHTML 
+=  html;
        
if  (databindInfo.el.subtree  !=   null )
        {
            buildTree(databindInfo.el, getNodeLevel(databindInfo.el));
            
if  (databindInfo.el._isExpanding  ==   true )
            {
                databindInfo.el.removeAttribute(
" _isExpanding " );
                finishNodePlusMinusClick(databindInfo.el);
            }
            
else
            {
                reselectNode(databindInfo.el);
            }
        }
    }

    doVisualRefresh();
    
    
var  evt  =  element.document.createEventObject();
    
if  (databindInfo.el  ==  element)
        evt.treeNodeIndex 
=   null ;
    
else
        evt.treeNodeIndex 
=  getNodeIndex(databindInfo.el);
    evt.reason 
=   0 ;
    _tvevtNodeBound.fire(evt);
}

//
//
 databindError()
//
//
 Report an error during databinding
//
function  databindError(databindInfo, strError)
{
    
var  fetch;
    
var  event  =  createEventObject();
    
if  (databindInfo.el  ==  element)
        event.treeNodeIndex 
=   null ;
    
else
        event.treeNodeIndex 
=  getNodeIndex(databindInfo.el);
    event.reason 
=   2 ;
    _tvevtNodeBound.fire(event);
    
    
if  (databindInfo.el  ==  element)
        fetch 
=  defaults.viewLink.all.item( " _fetch " 0 );
    
else
        fetch 
=  databindInfo.el.subtree.all.item( " _fetch " 0 );
    
if  (fetch  !=   null )
    {
        
var  tntext  =  fetch.all.item( " _tntext " 0 );
        tntext.innerHTML 
=  strError;
    }
}

//
//
 databindTypes()
//
//
 Bind the tree for TreeNodeTypes
//
function  databindTypes()
{
    
var  src  =  element.getAttribute( " TreeNodeTypeSrc " );

    
if  (src  ==   null )
        
return ;
 
    g_bTypesReady 
=   false ;
    
    g_typeIsland 
=  element.document.all(src);
    
if  (g_typeIsland  ==   null )
    {
        
//  create our own data island
         try
        {
            g_typeIsland 
=   new  ActiveXObject( " Msxml2.DOMDocument " );
        }
        
catch  (e)
        {
            databindError(databindInfo, L_strMSXMLError_Text);
            
return ;
        }
        g_typeIsland.async 
=   false ;
        
if  ( ! g_typeIsland.loadXML(src))
        {
            g_typeIsland.async 
=   true ;
            g_typeIsland.onreadystatechange 
=  finishDatabindingTypes;
            g_typeIsland.load(src);
        }
        
else
            finishDatabindingTypes();
    }
}

function  finishDatabindingTypes()
{
    
if  (g_typeIsland.readyState  !=   4 )
        
return ;

    
if  (g_typeIsland.xml  ==   "" )
    {
        databindTypesError();
        
return ;
    }
            
    
//  Make sure the root is a TREENODETYPES tag
     var  container  =  g_typeIsland.selectSingleNode( " TREENODETYPES " );
    
if  (container  ==   null )
    {
        databindTypesError();
        
return ;
    }
    
    
var  child  =  container.firstChild;
    
var  html  =   "" ;
    
while  (child  !=   null )
    {
        
if  (child.nodeName.toLowerCase()  ==   " treenodetype " )
            html 
+=  child.xml;
        child 
=  child.nextSibling;
    }

    
//  All nodetypes must have namespace inserted
    html  =  html.replace( / ( < /? )(treenodetype) / gi,  " $1 "   +  element.scopeName  +   " :$2 " );
    
    g_typesNode 
=  element.document.createElement( " DIV " );
    g_typesNode.innerHTML 
=  html;

    element.nodeTypes 
=  g_typesNode.children.tags( " TREENODETYPE " );
    verifyTypeValues();
    g_bTypesReady 
=   true ;
    
var  evt  =  element.document.createEventObject();
    evt.reason 
=   0 ;
    g_bInTypesBoundEvent 
=   true ;
    _tvevtNodeTypesBound.fire(evt);
    g_bInTypesBoundEvent 
=   false ;
    tryToBuildTreeFromRoot();
}

//
//
 databindTypesError()
//
function  databindTypesError()
{
    
var  event  =  createEventObject();
    event.reason 
=   2 ;
    g_bInTypesBoundEvent 
=   true ;
    _tvevtNodeTypesBound.fire(event);
    g_bInTypesBoundEvent 
=   false ;
    g_typesNode 
=  element.document.createElement( " DIV " );
    element.nodeTypes 
=  g_typesNode.children.tags( " TREENODETYPE " );
    g_bTypesReady
= true ;
}

//
//
 verifyExpandableValue()
//
//
 Verifies that the value is one of the acceptable Expandable values
//
//
 value: value to verify
//
function  verifyExpandableValue(value)
{
    
var  lval  =  value.toLowerCase();
    
switch  (lval)
    {
        
case   " auto " :
        
case   " checkonce " :
        
case   " always " :
            
return   true ;
        
default :
            
return   false ;
            
break ;
    }
}

//
//
 verifyBooleanAttribute()
//
//
 Verifies that the attribute's value is boolean, or a text equivalent.  If the latter,
//
 the attribute is converted to the corresponding boolean.  If the value is not a boolean
//
 equivalent or null, the attribute is set to false.
//
//
 node: node on which to verify attribute
//
 att: attribute to verify
//
//
 returns: true if the value was a boolean or equivalent
//
          false otherwise
//
function  verifyBooleanAttribute(node, att)
{
    
var  value  =  node.getAttribute(att);
    
if  (value  ==   null )
        
return   false ;

    
var  boolval  =  makeBoolean(value);
       
    
if  (value  ==  boolval)
        
return   true ;

    node.setAttribute(att, boolval 
==   null   ?   false  : boolval,  0 );
    
return  (boolval  !=   null );
}

function  makeBoolean(value)
{
    
if  (value  ==   true   ||  value  ==   false )
        
return  value;
    
    
if  (value  ==   null )
        
return   null ;
        
    
var  lval  =  value.toLowerCase();
    
switch  (lval)
    {
        
case   " true " :
            
return   true ;
        
case   " false " :
            
return   false ;
        
default :
            
return   null ;
    }
}

//
//
 verifyTypeValues()
//
//
 converts the value of each TreeNodeType's Type attribute to lower case, and
//
 string booleans to true booleans
//
function  verifyTypeValues()
{
    
var  len  =  element.nodeTypes.length;
    
for  ( var  i  =   0 ; i  <  len; i ++ )
    {
        
var  str  =  element.nodeTypes[i].getAttribute( " type " );
        
if  (str  !=   null )
            element.nodeTypes[i].setAttribute(
" type " , str.toLowerCase(),  0 );
        verifyBooleanAttribute(element.nodeTypes[i], 
" expanded " );
        verifyBooleanAttribute(element.nodeTypes[i], 
" checkBox " );
    }
}

//
//
 getNodeTypeHtml()
//
//
 Get the HTML source for the nodeTypes collection
//
function  getNodeTypeHtml()
{
    
var  html  =   "" ;
    
for  ( var  i  =   0 ; i  <  element.nodeTypes.length; i ++ )
    {
        html 
+=  element.nodeTypes[i].outerHTML;
    }
    
return  html;
}

// ---------------------------------------------------
//
//
 Public OM
//
//
---------------------------------------------------

//
//
 TreeView properties
//

function  getDefaultStyle()
{
    
return  prop_defaultStyle;
}

function  setDefaultStyle(value)
{
    
if  (prop_defaultStyle  ==  value)
        
return ;
        
    
if  ( typeof  value  ==   " string " )
    {
        prop_defaultStyle 
=  value;

        
if  (g_bCreated)
        {
            modifyNodesByType(contentNode, 
null " defaultstyle " )
            _tvpropDefaultStyle.fireChange();
        }
    }
}

function  getHoverStyle()
{
    
return  prop_hoverStyle;
}

function  setHoverStyle(value)
{
    
if  (prop_hoverStyle  ==  value)
        
return ;
        
    
if  ( typeof  value  ==   " string " )
    {
        prop_hoverStyle 
=  value;

        
if  (g_bCreated)
        {
            modifyNodesByType(contentNode, 
null " hoverstyle " )
            _tvpropHoverStyle.fireChange();
        }
    }
}

function  getSelectedStyle()
{
    
return  prop_selectedStyle;
}

function  setSelectedStyle(value)
{
    
if  (prop_selectedStyle  ==  value)
        
return ;
        
    
if  ( typeof  value  ==   " string " )
    {
        prop_selectedStyle 
=  value;

        
if  (g_bCreated)
        {
            modifyNodesByType(contentNode, 
null " selectedstyle " )
            _tvpropSelectedStyle.fireChange();
        }
    }
}

function  getChildType()
{
    
return  prop_childType;
}

function  setChildType(value)
{
    
if  (prop_childType  !=  value)
    {
        prop_childType 
=  value;
        
if  (g_bCreated)
        {
            
var  col  =  contentNode.children.tags( " treenode " );
            
for  ( var  i  =   0 ; i  <  col.length; i ++ )
                buildTree(col[i], 
0 );  
            
            _tvpropChildType.fireChange();
        }
    }
}    
        
function  getImageUrl()
{
    
return  prop_imageUrl;
}

function  setImageUrl(value)
{
    
if  (prop_imageUrl  !=  value)
    {
        prop_imageUrl 
=  value;
        
if  (g_bCreated)
        {
            modifyNodesInheritingFromRoot(contentNode, 
" imageurl " , value);
            _tvpropImageUrl.fireChange();
        }
    }
}
   
function  getSelectedImageUrl()
{
    
return  prop_selectedImageUrl;
}

function  setSelectedImageUrl(value)
{
    
if  (prop_selectedImageUrl  !=  value)
    {
        prop_selectedImageUrl 
=  value;
        
if  (g_bCreated)
        {
            modifyNodesInheritingFromRoot(contentNode, 
" selectedimageurl " , value);
            _tvpropSelectedImageUrl.fireChange();
        }
    }
}
   
function  getExpandedImageUrl()
{
    
return  prop_expandedImageUrl;
}

function  setExpandedImageUrl(value)
{
    
if  (prop_expandedImageUrl  !=  value)
    {
        prop_expandedImageUrl 
=  value;
        
if  (g_bCreated)
        {
            modifyNodesInheritingFromRoot(contentNode, 
" expandedimageurl " , value);
            _tvpropExpandedImageUrl.fireChange();
        }
    }
}
   
function  getTarget()
{
    
return  prop_target;
}

function  setTarget(value)
{
    
if  (prop_target  !=  value)
    {
        prop_target 
=  value;
        
if  (g_bCreated)
        {
            modifyNodesInheritingFromRoot(contentNode, 
" target " , value);
            _tvpropTarget.fireChange();
        }
    }
}

function  getTreeNodeSrc()
{
    
return  prop_treeNodeSrc;
}

function  setTreeNodeSrc(value)
{
    
if  (prop_treeNodeSrc  !=  value)
    {
        prop_treeNodeSrc 
=  value;
        _tvpropTreeNodeSrc.fireChange();
    }
}

function  getTreeNodeXsltSrc()
{
    
return  prop_treeNodeXsltSrc;
}

function  setTreeNodeXsltSrc(value)
{
    
if  (prop_treeNodeXsltSrc  !=  value)
    {
        prop_treeNodeXsltSrc 
=  value;
        _tvpropTreeNodeXsltSrc.fireChange();
    }
}

function  getSelectExpands()
{
    
return  prop_selectExpands;
}

function  setSelectExpands(value)
{
    
var  boolval  =  makeBoolean(value)
    
if  (boolval  !=   null   &&  boolval  !=  prop_selectExpands)
    {
        prop_selectExpands 
=  value;
        
if  (g_bCreated)
            _tvpropSelectExpands.fireChange();
    }
}

function  getExpandLevel()
{
    
return  prop_expandLevel;
}

function  setExpandLevel(value)
{
    
if  (prop_expandLevel  !=  value)
    {
        prop_expandLevel 
=  value  -   0 ;
        
if  (g_bCreated)
        {
            expandNodes(contentNode, value);
            _tvpropExpandLevel.fireChange();
        }
    }
}

function  getAutoSelect()
{
    
return  prop_autoSelect;
}

function  setAutoSelect(value)
{
    
var  boolval  =  makeBoolean(value)
    
if  (boolval  !=   null   &&  boolval  !=  prop_autoSelect)
    {
        prop_autoSelect 
=  value;
        
if  (g_bCreated)
            _tvpropAutoSelect.fireChange();
    }
}

function  getTreeNodeTypeSrc()
{
    
return  prop_treeNodeTypeSrc;
}

function  setTreeNodeTypeSrc(value)
{
    
if  (prop_treeNodeTypeSrc  !=  value)
    {
        prop_treeNodeTypeSrc 
=  value;
        
if  (g_bCreated)
        {
            _tvpropTreeNodeTypeSrc.fireChange();
        }
    }
}

function  getShowLines()
{
    
return  prop_showLines;
}

function  setShowLines(value)
{
    
var  boolval  =  makeBoolean(value);
    
if  (prop_showLines  !=  boolval  &&  boolval  !=   null )
    {
        prop_showLines 
=  boolval;
        
if  (g_bCreated)
        {
            buildTreeFromRoot();
            _tvpropShowLines.fireChange();
        }
    }
}

function  getShowPlus()
{
    
return  prop_showPlus;
}

function  setShowPlus(value)
{
    
var  boolval  =  makeBoolean(value);
    
if  (prop_showPlus  !=  boolval  &&  boolval  !=   null )
    {
        prop_showPlus 
=  boolval;
        
if  (g_bCreated)
        {
            modifyNodesByType(contentNode, 
null " _showplus " );
            _tvpropShowPlus.fireChange();
        }
    }
}

function  getShowToolTip()
{
    
return  prop_showToolTip;
}

function  setShowToolTip(value)
{
    
var  boolval  =  makeBoolean(value);
    
if  (prop_showToolTip  !=  boolval  &&  boolval  !=   null )
    {
        prop_showToolTip 
=  boolval;
        
if  (g_bCreated)
        {
            _tvpropShowToolTip.fireChange();
        }
    }
}

function  getIndent()
{
    
return  prop_indent;
}

function  setIndent(value)
{
    
if  (prop_indent  !=  value)
    {
        
if  ( typeof  value  ==   " string " )
        {
            
var  i  =  parseInt(value);
            
if  (i  ==  NaN)
                
return ;
            
else
                prop_indent 
=  i;       
        }
        
else   if  ( typeof  value  ==   " number " )
            prop_indent 
=  value;
        
else
            
return ;
        
if  (g_bCreated)
        {
            
if  (getShowLines()  !=   true )
                modifyNodesByType(contentNode, 
null " _indent " );
            _tvpropShowLines.fireChange();
        }
    }
}

function  getSelectedNodeIndex()
{
    
return  prop_selectedNodeIndex;
}

function  setSelectedNodeIndex(value)
{
    
if  (prop_selectedNodeIndex  !=  value  &&   typeof  value  ==   " string " )
    {
        
//  validate format of string
         if  (value.length  ==   0 )
            
return ;
        
        
if  (value.search( / [ ^ 0 - 9 .] / !=   - 1 )     //  a character other than a digit or .
             return ;

        
if  (value[ 0 ==   ' . ' )      //  mustn't begin with a .
             return ;

        
if  (value.indexOf( " .. " !=   - 1 )    //  mustn't have two consecutive periods
             return ;
            
        
if  (g_bCreated)
        {
            
//  does a node exist at this index?
             var  node  =  getNodeFromIndex(value);
            
if  (node  !=   null   &&  node.subtree  !=   null )
            {
                selectNode(node);
                _tvpropSelectedNodeIndex.fireChange();
            }
            
else
            {
                
//  Set index to 0, if possible
                 if  (value  !=   " 0 " )
                    selectedNodeIndex 
=   " 0 " ;
                
else
                    prop_selectedNodeIndex 
=   "" ;
            }
        }
        
else
            prop_selectedNodeIndex 
=  value;
    }
}

function  getSystemImagesPath()
{
    
return  prop_systemImagesPath;
}

function  setSystemImagesPath(value)
{
    
if  (prop_systemImagesPath  !=  value  &&   typeof  value  ==   " string " )
    {
        prop_systemImagesPath 
=  value;
        
if  (g_bCreated)
        {
            buildTreeFromRoot();
            _tvpropSystemImagesPath.fireChange();
        }
    }
}

//
//
 expandNodes()
//
//
 Recursively expand all nodes from root down through the given
//
 number of levels
//
//
 root: starting node
//
 level: number of levels to expand
//
function  expandNodes(root, level)
{
    
if  (root  !=  contentNode)
    {
        
var  exp  =  root.getAttribute( " expanded " );
        
if  (exp  !=   true )
        {
            doNodePlusMinusClick(root);
        }
    }
    
if  (level  >   0 )
    {
        
var  col  =  root.children.tags( " treenode " );
        
for  ( var  i  =   0 ; i  <  col.length; i ++ )
        {
            expandNodes(col[i], level 
-   1 );
        }
    }
}

//
//
 databind()
//
//
 Force the tree to rebind
//
function  databind()
{
    
if  (g_typesNode  ==   null )
        g_typesNode 
=  element.document.createElement( " DIV " );

    g_typesNode.innerHTML 
=  getNodeTypeHtml();                        
    element.nodeTypes 
=  g_typesNode.children.tags( " TREENODETYPE " );
    treeviewNode.subtree.removeNode(
true );
    contentNode.innerText 
=   "" ;
    databindNode(element);
}

//
//
 getTreeNodeType()
//
//
 Retrieves a public object representing the treenodetype at the requested index or
//
  with the requested name
//
//
 key: string name or integer index of type to get
//
function  getTreeNodeType(key)
{
    
var  tnt  =   null ;
    
var  len  =  element.nodeTypes.length;
    
    
if  ( typeof  key  ==   " number " )
    {
        
if  (key  >=   0   &&  key  <  len)
            tnt 
=  element.nodeTypes[key];
    }
    
else
    {
        
for  ( var  i  =   0 ; i  <  len; i ++ )
        {
            
var  temp  =  element.nodeTypes[i];
            
if  (temp.getAttribute( " Type " ==  key)
            {
                tnt 
=  temp;
                
break ;
            }
        }
    }
    
    
if  (tnt  !=   null )
        
return  private_getTreeNodeType(tnt);
    
else
        
return   null ;
}

//
//
 createTreeNodeType()
//
//
 Create a new treenodetype in the ether
//
function  createTreeNodeType()
{
    
var  realtnt  =  element.document.createElement( " treenodetype " );
    
return  private_getTreeNodeType(realtnt);
}

//
//
 private_getTreeNodeType()
//
//
 Returns a public object representing the given treenodetype
//
//
 tnt: treenodetype for which to generate a public object
//
function  private_getTreeNodeType(tnt)
{
    
var  obj  =   new  Object();
    
    obj.addTo 
=   function (tree)
    {
        
if  (tree.nodeTypes  ==   null   ||  tree.nodeTypes.length  ==   0 )
        {
            g_typesNode 
=  element.document.createElement( " DIV " );
            g_typesNode.appendChild(tnt); 
            tree.nodeTypes 
=  g_typesNode.children.tags( " TREENODETYPE " );
        }
        
else
        {
            g_typesNode.appendChild(tnt);
            tree.nodeTypes 
=  g_typesNode.children.tags( " TREENODETYPE " );
        }            
        modifyNodesByType(contentNode, tnt.getAttribute(
" type " ),  " type " );
    }
    obj.remove 
=   function (bRedraw) { private_removeTreeNodeType(tnt, bRedraw); };
    obj.getAttribute 
=   function (name) {  return  private_getNodeTypeAttribute(tnt, name); };
    obj.setAttribute 
=   function (name, value) { private_setNodeTypeAttribute(tnt, name, value); };
    
    
return  obj;
}

//
//
 addTreeNodeType()
//
//
 Add the given treenodetype to the end of the tree's nodetypes collection
//
//
 tnt: treenodetype to add
//
function  addTreeNodeType(tnt)
{
    tnt.addTo(element);
}

//
//
 private_removeTreeNodeType()
//
//
 Remove the treenodetype from the tree.  Note that redrawing nodes of this type
//
 requires a full tree traversal, which can be very slow.
//
//
 tnt: type to remove
//
 bRedraw: Redraw nodes of this type?
//
function  private_removeTreeNodeType(tnt, bRedraw)
{
    
var  name  =  tnt.getAttribute( " Type " );
    
    tnt.removeNode(
false );
    
    
if  (bRedraw  !=   false )
    {
        
//  Because indices may have shifted, we'll need to rebuild the tree.
        modifyNodesByType(contentNode,  null " type " );
    }
    
else
    {
        
//  uncache the nodetypeIndex of all nodes
        modifyNodesByType(contentNode,  null " _nodetypeIndex " );
    }
}

//
//
 modifyNodesByType()
//
//
 Rebuild all nodes of the given type
//
//
 node: current node
//
 type: name of type; if null, rebuild all nodes
//
 att: attribute of node being modified (in lower case)
//
function  modifyNodesByType(node, type, att)
{
    
if  (node  !=  contentNode)
    {
        
if  (node.subtree  ==   null //  if the node hasn't been built yet, don't go any further
             return ;
        
        
if  (type  ==   null   ||  getNodeAttribute(node,  " Type " ==  type)
        {
            modifyNode(node, att, 
null , type);
            
if  (att  ==   " type "   ||  att  ==   " childtype " )
                
return //  these atts already handle the node's children
        }
    }
    
var  col  =  node.children.tags( " treenode " );
    
for  ( var  i  =   0 ; i  <  col.length; i ++ )
    {
        modifyNodesByType(col[i], type, att);
    }
}

//
//
 modifyNodesInheritingFromRoot()
//
//
 Searches the tree from the given node downward for all nodes which
//
 inherited the given attribute from the root, rebuilding the appropriate
//
 aspect of such nodes.  This function is called when an inheritable attribute
//
 is changed on the TreeView itself.
//
//
 root: starting node of search
//
 att: attribute to check
//
 value: new value of attribute
//
function  modifyNodesInheritingFromRoot(root, att, value)
{
    
if  (root  !=  contentNode)
    {
        
if  (root.subtree  ==   null )
            
return ;
            
        
if  (inheritsFromRoot(root, att))
        {
            modifyNode(root, att, value, 
null );
            
if  (att  ==   " type "   ||  att  ==   " childtype " )
                
return //  these atts already handle the node's children
        }
    }
    
var  col  =  root.children.tags( " treenode " );
    
for  ( var  i  =   0 ; i  <  col.length; i ++ )
    {
        modifyNodesInheritingFromRoot(col[i], att, value);
    }
}

//
//
 inheritsFromRoot()
//
//
 Determines if the given node inherits its att value from the TreeView
//
//
 node: node to check
//
 att: att to check
//
function  inheritsFromRoot(node, att)
{
    
//  try the node
     if  (node.getAttribute(att)  !=   null )
        
return   false ;
        
    
//  try the node's type
     if  (getNodeTypeAttribute(node, att)  !=   null )
        
return   false ;
        
    
return   true ;
}          

//
//
 private_getNodeTypeAttribute()
//
//
 Gets the given attribute from the given node
//
//
 tnt: treenodetype from which to retrieve attribute
//
 name: name of attribute to retrieve
//
function  private_getNodeTypeAttribute(tnt, name)
{
    
return  tnt.getAttribute(name.toLowerCase());
}

//
//
 private_setNodeTypeAttribute()
//
//
 Sets the given attribute on the given node
//
//
 tnt: treenodetype on which to set attribute
//
 name: name of attribute to set
//
 value: value of attribute to set
//
function  private_setNodeTypeAttribute(tnt, name, value)
{
    
var  lname  =  name.toLowerCase();
    
if  (lname  ==   " outerhtml " )
        
return ;
        
    
var  old  =  tnt.getAttribute(name, value);
    
    tnt.setAttribute(name, value, 
0 );
    
if  (tnt.parentElement  ==   null )
        
return ;
        
    
//  Update display tree if display-related change was made
     switch  (lname)
    {
        
case   " text " :            
        
case   " innertext " :
            
break ;
        
        
case   " expandable " :
            
if  (verifyExpandableValue(value)  ==   true )
                modifyNodesByType(contentNode, tnt.getAttribute(
" type " ), lname);
            
else
                tnt.setAttribute(name, old, 
0 );
            
break ;

        
default :
            modifyNodesByType(contentNode, tnt.getAttribute(
" type " ), lname);
            
break ;
    }

            
//
//
 createTreeNode()
//
//
 Creates a new treenode in the ether
//
function  createTreeNode()
{
    
var  realNode  =  element.document.createElement( " treenode " );
    
return  private_getTreeNode(realNode);
}

//
//
 getTreeNode()
//
//
 Retrieves a public object representing the node at the requested index
//
//
 index: dot-separated index string of node to retrieve
//
function  getTreeNode(index)
{
    
var  node  =  getNodeFromIndex(index);
    
if  (node  ==   null )
        
return   null ;
    
    
return  private_getTreeNode(node);
}

//
//
 private_getTreeNode()
//
//
 Retrieves a public object representing the given node
//
//
 node: treenode to munge into public object
//
function  private_getTreeNode(node)
{
    
var  obj  =   new  Object();
    
    obj.addAt 
=   function (index, newnode)
    {
        
if  (newnode._real  !=   null )
            private_addAt(node, index, newnode._real);
        
else
        {
            
var  temp  =  private_getTreeNode(node);
            temp._real 
=  node;
            newnode.addTo(index, temp);
        }
    };
    obj.addTo 
=   function (index, parent)
    {
        
if  (parent._real  !=   null )
            private_addAt(parent._real, index, node);
        
else
        {
            
var  temp  =  private_getTreeNode(node);
            temp._real 
=  node;
            parent.addAt(index, temp);
        }
    };
    obj.add 
=   function (newnode) { obj.addAt(node.children.tags( " treenode " ).length, newnode); }; 
    obj.remove 
=   function () { private_remove(node); };
    obj.databind 
=   function () { private_databind(node); };
    obj.getAttribute 
=   function (name) {  return  private_getAttribute(node, name); };
    obj.setAttribute 
=   function (name, value) { private_setAttribute(node, name, value); };
    obj._real 
=   null ;
    obj.findAttribute 
=   function (name) {  return  getNodeAttribute(node, name); };
    obj.getNodeIndex 
=   function ()
    {
        
var  index  =  getNodeIndex(node);
        
if  (index  ==   "" )
            
return   null ;
        
return  index;
    };
    obj.getParent 
=   function ()
    {
        
if  (node.parentElement  ==   null   ||  node.parentElement.tagName.toLowerCase()  !=   " treenode " )
            
return   null ;
        
else
            
return  private_getTreeNode(node.parentElement);
    }; 
    obj.getChildren 
=   function () {  return  private_getChildren(node); };
    
    
return  obj;
}

//
//
 addAt()
//
//
 Add a root node at the given index.  TreeView method.
//
//
 index: integer index at which to add the node
//
 node: node to add
//
function  addAt(index, node)
{
    node.addTo(index, private_getTreeNode(contentNode));
}

//
//
 add()
//
//
 Add a root node to the end of the tree.  TreeView method.
//
//
 node: node to add
//
function  add(node)
{
    node.addTo(contentNode.children.tags(
" treenode " ).length, private_getTreeNode(contentNode));
}

//
//
 private_addAt()
//
//
 Implements addition of a node to the tree
//
//
 parent: node to add a child to
//
 index: integer index at which to add a child node
//
 child: node to add
//
function  private_addAt(parent, index, child)
{
    
if  (child.parentElement  !=   null )
        
return ;
        
    
var  col  =  parent.children.tags( " treenode " );
    
var  iCount  =  col.length;
    
    
if  (index  <   0   ||  index  >  iCount)
        
return ;
  
    
var  selectedNode  =  getNodeFromIndex(selectedNodeIndex);
    
    
//
     //  add node to tree
     //
     if  (index  ==  iCount)
        parent.appendChild(child);
    
else
    {
        col[index].insertAdjacentElement(
" beforeBegin " , child);
    }

    
//
     //  adjust sibling indices
     //
    child.sibIndex  =  index;
    
for  ( var  i  =  index; i  <=  iCount; i ++ )
        col[i].sibIndex 
=  i;

    
//
     //  adjust selected index if necessary
     //
     if  (selectedNode  !=   null   &&  index  <  selectedNode.sibIndex)
        prop_selectedNodeIndex 
=  getNodeIndex(selectedNode);
        
    
//
     //  update display tree if the node is now part of a treeview and its parent or previous sibling is expanded
     //
     var  p  =  parent;
    
while  (p  !=   null   &&  p.tagName.toLowerCase()  ==   " treenode " )
        p 
=  p.parentElement;
    
if  (p  !=   null   &&  p.tagName.toLowerCase()  !=   " treeview " )
        
return ;
    
if  (parent.getAttribute( " expanded " ==   true   ||  parent  ==  contentNode)
    {
        
//  build added node's display tree
         var  disptree  =  buildTree(child, getNodeLevel(child));
        
if  (index  ==  iCount)
        {
            
if  (parent.subtree  ==   null )
            {
                
if  (parent  ==  contentNode)
                    tryToBuildTreeFromRoot();
                
else
                    parent.subtree 
=  disptree;
            }
            
else
            {
                
if  (parent  ==  contentNode)
                    treeviewNode.subtree.appendChild(disptree);
                
else
                    parent.subtree.appendChild(disptree);
            }
        }
        
else
            col[index 
+   1 ].subtree.insertAdjacentElement( " beforeBegin " , disptree);
            
        
if  (element.getAttribute( " showlines " !=   false   &&  index  >   0   &&  col[index  -   1 ].getAttribute( " expanded " ==   true )
        {
            
//  rebuild previous sibling's display tree, to show correct lines.
            buildTree(col[index  -   1 ], getNodeLevel(col[index  -   1 ]));
            
//  if that tree contains the selected node, redisplay the selection
             if  (selectedNodeIndex.indexOf(getNodeIndex(col[index  -   1 ]))  ==   0 )
                reselectNode(getNodeFromIndex(selectedNodeIndex));
        }
    }
    
    
//
     //  Update the junctions of the nodes immediately above and below this node, if needed
     //
     if  (iCount  ==   0 )                                 //  parent's first child
    {
        
if  (parent  !=  contentNode)
            replaceJunctionNode(parent);
    }
    
else   if  (index  ==  iCount)                        //  new last sibling
        replaceJunctionNode(col[index  -   1 ]);
    
else   if  (index  ==   0 )
        replaceJunctionNode(col[
1 ]);                 //  new first sibling
    
    
if  (selectedNode  !=   null )
        prop_selectedNodeIndex 
=  getNodeIndex(selectedNode);
    
else
        selectNode(child);
}

//
//
 private_remove()
//
//
 Remove the given node from the tree
//
//
 node: node to remove
//
function  private_remove(node)
{
    
if  (node.parentElement  ==   null )
        
return   null ;
    
    
var  parent  =  node.parentElement;
    
var  col  =  parent.children.tags( " treenode " );
    
var  iCount  =  col.length;
    
var  sibindex  =  node.sibIndex;
    
var  selectedNode  =  getNodeFromIndex(selectedNodeIndex);
    
var  nodeIndex  =  getNodeIndex(node);
    
    node.subtree.removeNode(
true );
    node.subtree 
=   null ;
    node.removeNode(
true );
    node.removeAttribute(
" sibIndex " );
    
if  (node.getAttribute( " expanded " ==   false )
        node._buildChildren 
=   true //  set expando so we'll rebuild the node's children if the node is added again and then expanded
     
    
//
     //  adjust junctions and whitespace/lines
     //         
     if  (iCount  ==   1 )
        replaceJunctionNode(parent);
    
else   if  (sibindex  !=   0   &&  sibindex  ==  iCount  -   1 )
        buildTree(col[sibindex 
-   1 ], getNodeLevel(col[sibindex  -   1 ]));  //  rebuild previous sibling and its subtree
     else   if  (sibindex  ==   0   &&  parent.tagName.toLowerCase()  !=   " treenode " )
        replaceJunctionNode(col[
0 ]);  //  new first root
    
    
//
     //  adjust sibling indices
     //
     for  ( var  i  =  sibindex; i  <  col.length; i ++ )
        col[i].sibIndex 
=  i;       

    
//
     //  adjust selectedNodeIndex
     //
     if  (node  ==  selectedNode  ||
     (selectedNodeIndex.length 
>  nodeIndex.length  &&  selectedNodeIndex.substr( 0 , nodeIndex.length  +   1 ==  nodeIndex  +   " . " ))
    {
        
//  deleted the selected node or an ancestor of the selected node.
         var  temp  =  prop_selectedNodeIndex;
        prop_selectedNodeIndex 
=   "" ;
        
if  (iCount  -   1   >  sibindex)
            selectNode(col[sibindex]);          
//  the node now at the same index as the deleted node
         else   if  (iCount  >   1   &&  sibindex  >   0 )
            selectNode(col[sibindex 
-   1 ]);       //  the first sibling prior to the deleted node
         else   if  (nodeIndex  !=   " 0 " )
            selectNode(parent);                 
//  the parent of the deleted node
         else
        {
            prop_selectedNodeIndex 
=  temp;
            selectNode(
null );
        }
    }
    
else
    {
        
//  adjust the selected node index to reflect new tree structure
        prop_selectedNodeIndex  =   "" ;
        selectNode(selectedNode);
    }
    
return  node;
}

//
//
 private_databind()
//
//
 node: node to bind
//
function  private_databind(node)
{
    
//  If the selection is within the subtree under the node being databound,
     //  then select the node.
     var  dataNodeIndex  =  getNodeIndex(node);
    
if  ((dataNodeIndex  !=  selectedNodeIndex)  &&  (selectedNodeIndex.indexOf(dataNodeIndex)  ==   0 ))
        selectNode(node);
    
    
//  delete all treenode content
    col  =  node.children.tags( " treenode " );
    
for  ( var  i  =  col.length  -   1 ; i  >=   0 ; i -- )
    {
        
if  (col[i].subtree  !=   null )
            col[i].subtree.removeNode(
true );
        col[i].removeNode(
true );
    }
    node._bound 
=   null ;
    databindNode(node);
}

//
//
 private_getAttribute()
//
//
 Gets the given attribute from the given node
//
//
 node: node from which to retrieve attribute
//
 name: name of attribute to retrieve
//
function  private_getAttribute(node, name)
{
    
var  lcName  =  name.toLowerCase();
    
var  ret  =  node.getAttribute(lcName);
    
if  (ret  ==   null   &&  lcName  ==   " text " )
    {
        
var  textnode  =  node.subtree.all.item( " _tntext " 0 );
        ret 
=  textnode.innerText;
    }
    
return  ret;
}

//
//
 private_setAttribute()
//
//
 Sets the given attribute on the given node
//
//
 node: node on which to set attribute
//
 name: name of attribute to set
//
 value: value of attribute to set
//
function  private_setAttribute(node, name, value)
{
    
var  lname  =  name.toLowerCase();
    
if  (lname  ==   " outerhtml " )
        
return ;
        
    
var  old  =  node.getAttribute(name, value);
    
    node.setAttribute(name, value, 
0 );
    
if  (node.parentElement  ==   null )
        
return ;
        
    
if  (node.subtree  ==   null )
        
return ;

    modifyNode(node, lname, value, old);        
}

//
//
 getChildren()
//
//
 public entry point for private_getChildren()
//
function  getChildren()
{
    
return  private_getChildren(contentNode);
}

//
//
 private_getChildren()
//
//
 Returns an array of public treenode objects representing the top-level children of the given root
//
//
 root: DOM object parent from which to get children
//
function  private_getChildren(root)
{
    
var  col  =  root.children.tags( " treenode " );
    
var  objArray  =   new  Array(col.length);
    
for  ( var  iNode  =   0 ; iNode  <  col.length; iNode ++ )
    {
        objArray[iNode] 
=  private_getTreeNode(col[iNode]);
    }
    
return  objArray;
}

//
//
 modifyNode()
//
//
 Rebuild display node as required by change to given attribute
//
//
 node: node to modify
//
 lname: name of changed attribute, in lower case
//
 value: new value of attribute
//
 old: old value of attribute
//
function  modifyNode(node, lname, value, old)
{
    
//  Update display tree if display-related change was made
     switch  (lname)
    {
        
case   " defaultstyle " :
        
case   " hoverstyle " :
        
case   " selectedstyle " :
        
case   " style " :
            
var  oItem  =  node.subtree.all.item( " _tntext " 0 );
            
var  stylename  =  oItem.className;
            
if  (stylename  ==   "" )
                stylename 
=   " defaultstyle " ;
            SetAnchorClass(oItem, stylename); 
//  reapply current style
             if  ( ! g_bFocus  &&  (stylename  ==   " selectedstyle " ))
            {
                blurFilter(oItem);
            }
            
break ;
            
        
case   " text " :
        
case   " innertext " :
        
case   " innerhtml " :
            
var  tntext  =  node.subtree.all.item( " _tntext " 0 );          
            
var  newText  =  generateTextNode(node);
            tntext.replaceNode(newText);
            
var  accessAnchor  =  node.subtree.all.item( " _tnaccess " 0 );
            
if  (accessAnchor.getAttribute( " title " !=   "" )
                accessAnchor.title 
=  newText.innerText  +   "  :  "   +  L_strToolTip_Text;
            
            reselectNode(node);                
            
break ;

        
case   " imageurl " :
            
if  (selectedNodeIndex  ==  getNodeIndex(node))
            {
                
if  (getNodeAttribute(node,  " selectedImageUrl " ==   null )
                    changeIcon(node, lname);
            }
            
else   if  (node.getAttribute( " Expanded " ==   true )
                changeIcon(node, 
" expandedimageurl " );   //  let changeIcon function figure things out
             else
                changeIcon(node, lname);
            
break ;
        
case   " selectedimageurl " :          
            
if  (selectedNodeIndex  ==  getNodeIndex(node))
                changeIcon(node, lname);
            
break ;
        
case   " expandedimageurl " :
            
if  (node.getAttribute( " Expanded " ==   true   &&  (selectedNodeIndex  !=  getNodeIndex(node)  ||  getNodeAttribute(node,  " selectedImageUrl " ==   null ))
                changeIcon(node, lname);
            
break ;
            
        
case   " type " :
            
//  the new type could contain a new childType, so rebuild the whole subtree
            buildTree(node, getNodeLevel(node));
            
var  temp  =  getNodeFromIndex(selectedNodeIndex);
            prop_selectedNodeIndex 
=   "" ;
            selectNode(temp);
            
break ;
            
        
case   " childtype " :
            
var  col  =  node.children.tags( " treenode " );
            
for  (i  =   0 ; i  <  col.length; i ++ )
            {
                buildTree(col[i], getNodeLevel(col[i]));
                
var  temp  =  getNodeFromIndex(selectedNodeIndex);
                prop_selectedNodeIndex 
=   "" ;
                selectNode(temp);
            }
            
break ;
            
        
case   " target " :
            
var  accessnode  =  node.subtree.all( " _tnaccess " 0 );
            accessnode.target 
=  getNodeAttribute(node, lname);
            accessnode.parentElement.target 
=  accessnode.target;
            
break ;
        
case   " navigateurl " :
            
var  accessnode  =  node.subtree.all( " _tnaccess " 0 );
            
var  url  =  getNodeAttribute(node, lname);
            
if  (url  ==   ""   ||  url  ==   null )
            {
                accessnode.removeAttribute(
" href " );
                accessnode.parentElement.removeAttribute(
" href " );
                
if  (url  ==   "" )
                    node.removeAttribute(
" navigateUrl " );
            }
            
else
            {
                accessnode.href 
=  getNodeAttribute(node, lname);
                accessnode.parentElement.href 
=  accessnode.href;
            }
            
break ;
            
        
case   " expandable " :
            
if  (verifyExpandableValue(value)  ==   true )
                replaceJunctionNode(node);
            
else
                node.setAttribute(lname, old, 
0 );
            
break ;
            
        
case   " expanded " :
            
if  (verifyBooleanAttribute(node, lname)  ==   false )
                node.setAttribute(lname, old, 
0 );
            
else   if  (node.getAttribute(lname)  !=  old)
            {
                node.setAttribute(
" expanded " ! node.getAttribute( " expanded " ),  0 );
                doNodePlusMinusClick(node);
            }
            
break ;
            
        
case   " checked " :
            
if  (verifyBooleanAttribute(node, lname)  ==   false )
                node.setAttribute(lname, old, 
0 );
            
else   if  (getNodeAttribute(node,  " checkBox " ==   true   &&  node.getAttribute(lname)  !=  old)
            {
                
var  cb  =  node.subtree.all.item( " _cb " 0 );
                cb.setAttribute(
" checked " , node.getAttribute(lname),  0 );
            }
            
break ;                
                
        
case   " checkbox " :
            
if  (verifyBooleanAttribute(node, lname)  ==   false   &&  node.getAttribute(lname)  !=   null )
                node.setAttribute(lname, old, 
0 );
            
else   if  (getNodeAttribute(node,  " checkbox " ==   true )
            {
                
if  (old  !=   true )
                {
                    
var  jn  =  node.subtree.all( " junction " 0 );
                    
if  (jn)
                    {
                        
var  cb  =  createCheckBox(node);
                        jn.parentElement.insertAdjacentElement(
" afterEnd " , cb);
                    }
                }
            }
            
else
            {
                
var  cb  =  node.subtree.all( " _fcb " 0 );
                
if  (cb)
                    cb.removeNode(
true );
            }
            
break ;
        
        
case   " treenodesrc " :
        
case   " treenodexsltsrc " :
            
if  (value  !=   null )
            {
                node.setAttribute(
" checkedExpandable " false 0 );
                node._bound 
=   null ;
            }
            
break ;
        
        
case   " _showplus " :    //  not a real attribute-- back door for TreeView
            replaceJunctionNode(node);
            
break ;                      
            
        
case   " _indent " :      //  not a real attribute-- back door for TreeView
             var  strIndex  =  getNodeIndex(node);
            
if  (strIndex.indexOf( " . " !=   - 1 )
            {
                
if  (isRtl())
                    node.subtree.style.marginRight 
=  prop_indent;
                
else
                    node.subtree.style.marginLeft 
=  prop_indent;
            }
            
break ;
            
        
case   " _nodetypeIndex " //  not a real attribute-- back door for TreeView
            node.nodetypeIndex  =  undefined;
            node.inheritedType 
=  undefined;
            
break ;
            
    }
}
            
//
//
 Cleans up the OnStop events left over from previous postbacks
//
function  f_CleanupEvents()
{
    
var  eventArray  =  window.__treeviewAttachedEvents;

    
if  ((eventArray  !=   null &&  (eventArray[ 0 ]))
    {
        
var  newArray  =   new  Array( false );

        
//  First array element is the dirty bit
         for  ( var  i  =   1 ; i  <  eventArray.length; i ++ )
        {
            
if  (element.document.all[eventArray[i][ 0 ]]  ==   null )
            {
                element.document.detachEvent(
" onstop " , eventArray[i][ 1 ]);
            }
            
else
            {
                newArray 
=  newArray.concat( new  Array(eventArray[i]));
            }
        }

        window.__treeviewAttachedEvents 
=  newArray;
    }
}

//
//
 Adds an OnStop event
//
function  f_AddStopEvent()
{
    
var  eventArray  =  window.__treeviewAttachedEvents;
    
if  (eventArray  ==   null )
    {
        eventArray 
=   new  Array( false );
    }

    element.document.attachEvent(
" onstop " , onstop);
    eventArray[
0 =   true ;
    entry 
=   new  Array(element.uniqueID, onstop);
    window.__treeviewAttachedEvents 
=  eventArray.concat( new  Array(entry));
}

//
//
 Responds to onscroll
//
function  onScroll()
{
    setHiddenHelperValue();
}

//
//
 isRtl()
//
//
 true if we're rendering right to left; false otherwise
//
function  isRtl()
{
    
if  (element.currentStyle.direction.toLowerCase()  ==   " rtl "   ||  element.dir.toLowerCase()  ==   " rtl " )
        
return   true ;
    
else
        
return   false ;
}

//
//
 Visually refreshes the TreeView (workaround for IE 5.5 refresh bug)
//
function  doVisualRefresh()
{
    
var  display  =  element.style.display;
    element.style.display 
=   " none " ;
    element.style.display 
=  display;
}

</ script >
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值