home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Documentation / DirectX9 / directplay.chm / code / dhtmlobj.js < prev    next >
Encoding:
Text File  |  2004-09-27  |  17.9 KB  |  649 lines

  1.  
  2. var g_oMemberSettings = new Object();
  3.  
  4. // _iState
  5. // 0 - initializing
  6. // 1 - binding
  7.  
  8. //var g_fMembersDSC = false; // indicates the data set is complete (DSO)
  9. //var g_fMembersRSC = false; // indicates the table is complete (TABLE)
  10.  
  11. var g_fMemberTableReady = false;
  12.  
  13. //var g_sCurMemberView = "attributes"; // cache the default view in global since we need to filter asynchronously
  14.  
  15. var g_FilterMap = new Array();
  16.  
  17. //'(ref_friendly = * \/ *) | invoke_kind = 0'; // old attribute filter
  18. g_FilterMap["attributes"] = "invoke_kind=0 | ((invoke_kind=2 | invoke_kind=6) & ref_persistent <> null)"; // look for text pattern; requires a space followed by slash followed by space to match
  19. g_FilterMap["all"] = 'ref_dynamic <> null'; // show all dynamic member
  20. g_FilterMap["properties"] = '((invoke_kind=2 | invoke_kind=4 | invoke_kind=6) & ref_dynamic <> null)';
  21. g_FilterMap["methods"] = 'invoke_kind=1';
  22. g_FilterMap["events"] = 'invoke_kind=8';
  23. g_FilterMap["collections"] = 'invoke_kind=32';
  24. g_FilterMap["behaviors"] = 'invoke_kind=128';
  25. g_FilterMap["filters"] = 'invoke_kind=256';
  26.  
  27. var g_aMemberImg2Str = new Array();
  28. g_aMemberImg2Str["method"] = "Method";
  29. g_aMemberImg2Str["prop_ro"] = "Read-Only Property";
  30. g_aMemberImg2Str["prop_rw"] = "Read/Write Property";
  31. g_aMemberImg2Str["prop_wo"] = "Write-Only Property";
  32. g_aMemberImg2Str["event"] = "Event";
  33. g_aMemberImg2Str["collection"] = "Collection";
  34. g_aMemberImg2Str["object"] = "Object";
  35. g_aMemberImg2Str["attribute"] = "Attribute";
  36. g_aMemberImg2Str["behavior"] = "Behavior";
  37. g_aMemberImg2Str["filter"] = "Filter";
  38.  
  39. g_oRegImgTitle = new RegExp("(method|prop_ro|prop_rw|prop_wo|event|collection|object|attribute|behavior|filter)\.gif");
  40. g_oRegProp = new RegExp("(prop_..|attribute)");
  41.  
  42. var g_aMemberViewByNum = new Array();
  43. g_aMemberViewByNum["all"] = 0;
  44. g_aMemberViewByNum["attributes"] = 1;
  45. g_aMemberViewByNum["properties"] = 2;
  46. g_aMemberViewByNum["methods"] = 3;
  47. g_aMemberViewByNum["events"] = 4;
  48. g_aMemberViewByNum["collections"] = 5;
  49. g_aMemberViewByNum["behaviors"] = 6;
  50. g_aMemberViewByNum["filters"] = 7;
  51.  
  52. /*
  53. Insert object-page-specific data-bound tables into the page. IE4/Windows only  
  54.  
  55. vCtx - hash containing context information for the current binding. Valid keys include:
  56.             defView - default filter (acceptable values: all, methods, properties, events, attributes (default), or collections)
  57.             dataPath - location of the data set to which the DSOs are to bind
  58.      - for legacy reasons, this parameter may also specify a string representing the default view
  59.         specifying default filter for members table.
  60.  
  61. sCSSLink - optional string specifying name of field to surround with hyperlink
  62.            acceptable values: cssattr (default), prop
  63. */
  64. function AddObjTables(vCtx, sCSSLink)
  65. {    
  66.     if (!oBD.getsNavBar) // so that down-level links show up in Mac and Unix
  67.     {
  68.         if (typeof(divMembers) == 'object')
  69.         {
  70.             divMembers.children(0).className = "clsExpanded";
  71.         }
  72.         if (typeof(divCSS) == 'object')
  73.         {
  74.             divCSS.children(0).className = "clsExpanded";
  75.         }
  76.         return false;
  77.     }
  78.  
  79.     var vDefView = "";
  80.     var sDataPath = "../data/"; // using relative path allows this code to be used by ANY reference
  81.  
  82.     // dig data out of the context object
  83.     if (typeof(vCtx) == 'object' && vCtx != null)
  84.     {
  85.         if (typeof(vCtx.defView) == 'string')
  86.         {
  87.             vDefView = vCtx.defView;
  88.         }
  89.  
  90.         if (typeof(vCtx.dataPath) == 'string')
  91.         {
  92.             sDataPath = vCtx.dataPath;
  93.         }
  94.     }
  95.     else if (typeof(vCtx) == 'string')
  96.     {
  97.         vDefView = vCtx;
  98.     }
  99.         
  100.     var oReg = new RegExp("[\\\\]", "g");
  101.     var sPath = location.pathname.replace(oReg, "/"); // Normalize the path on or off-line
  102.     aPath = sPath.split("/");
  103.     var sObjName = aPath[aPath.length-1].split(".")[0];
  104.  
  105.     if (typeof(divMembers) == 'object')
  106.     {
  107.         var oPersistence = EnsurePersistence();
  108.         var sPM = oPersistence.getPersistedMembers();
  109.         if (sPM)
  110.         {
  111.             vDefView = sPM;
  112.         }
  113.  
  114.         // coerce to a sensible default if nothing passed
  115.         if (!vDefView)
  116.         {
  117.             // if nothing explicit is passed, and it's a collection, show all; otherwise show attribs only 
  118.             vDefView = (IsCollection(document)) ? "all" : "attributes";
  119.         }
  120.  
  121.         g_oMemberSettings._sDefView = vDefView;
  122.         
  123.         // 8/6/1999: set the charset explicitly
  124.  
  125.         // filter on attribs first so that we can build the HTML syntax
  126.         sMembers = '<OBJECT classid="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83" ' +
  127.             'ID=tdcMembers ondatasetcomplete="handle_members_dsc()" HEIGHT=0 WIDTH=0>' +
  128.             '<PARAM NAME="DataURL" VALUE="' + sDataPath + sObjName + '_members.csv">' +
  129.             '<PARAM NAME="UseHeader" VALUE="True">' +
  130.             '<PARAM NAME="TextQualifier" VALUE="|">' +
  131.             '<PARAM NAME="charset" VALUE="windows-1252">' +
  132.             '<PARAM NAME="CaseSensitive" VALUE="False">' +
  133.             '<PARAM NAME="Sort" VALUE="' + GetFriendlyCol('attributes') + '">' +
  134.             '<PARAM NAME="Filter" VALUE="' + g_FilterMap['attributes'] + '">' +
  135.             '</OBJECT>';
  136.  
  137.         g_oMemberSettings._iState = 0;
  138.  
  139.         document.body.insertAdjacentHTML('afterBegin', sMembers);
  140.  
  141.         // bug/feature optimizes out dbinding when no elements on the page bind to the data source
  142.         // so trigger the binding
  143.         var oRS = tdcMembers.recordset;
  144.  
  145.     }
  146.  
  147.     if (typeof(divCSS) == 'object') // CSS is optional if object doesn't support it.
  148.     {
  149.         AddCSSTable(divCSS, sDataPath + sObjName + '_css.csv', sCSSLink);
  150.     }
  151.     
  152.     return true;    
  153. }
  154.  
  155. // Once the syntax is built, 
  156. // refilter the data
  157. // inject the member table
  158. function AddMemberTable()
  159. {
  160.  
  161.     if (AddMemberTable._bAdded)
  162.     {
  163.         // only add the table once!
  164.         return;
  165.     }
  166.  
  167.     AddMemberTable._bAdded = true;
  168.  
  169.     var cImgCol = GetImgCol(g_oMemberSettings._sDefView);
  170.     var cNameCol = GetFriendlyCol(g_oMemberSettings._sDefView);
  171.  
  172.     divMembers.innerHTML = "<TABLE CLASS='clsStd' STYLE='table-layout:fixed' ID=tblMembers onreadystatechange='handle_members_rsc()'>" +
  173.         "<COL ID=colMembersSel WIDTH='20%'><COL WIDTH='40px'><COL WIDTH='*'>" +
  174.         "<THEAD><TR VALIGN=TOP BGCOLOR=#DDDDDD><TH>" + 
  175.         BuildViewCombo() +
  176.         "</TH><TH> </TH><TH>Description</TH></TR></THEAD>" +
  177.         "<TBODY><TR><TD NOWRAP><A DATAFLD=ref_link>" +
  178.  
  179.         "<SPAN ID=ref_friendly onmouseover='handle_member_hover()' DATAFLD=" + cNameCol + "></SPAN></A></TD>" +
  180.  
  181.         "<TD ALIGN='center'><IMG ID=ref_icon DATAFLD=" + cImgCol + "></TD>" +
  182.         "<TD><SPAN DATAFLD=ref_desc DATAFORMATAS=html></SPAN></TD></TR></TABLE>" +
  183.         "<DIV ID='divProposed' STYLE='display:none'>* denotes an extension to the W3C DOM.</DIV>";
  184.         
  185.         if(cboInvokeKind.offsetWidth > colMembersSel.offsetWidth){
  186.             colMembersSel.width = cboInvokeKind.offsetWidth;
  187.         }
  188.  
  189.     cboInvokeKind.selectedIndex = MapViewToOption(g_oMemberSettings._sDefView);
  190.  
  191.     //FilterMembers(cboInvokeKind, tdcMembers, "#tdcMembers");
  192.  
  193.     return true;
  194. }
  195.  
  196. // deal with clipping of member cells
  197. function handle_member_hover()
  198. {
  199.     var oSpan = window.event.srcElement;
  200.     var oTD = oSpan.parentElement.parentElement;
  201.     if (IsClipped(oTD) && oSpan.title == "")
  202.         oSpan.title = oSpan.innerText;
  203. }
  204.  
  205. function IsClipped(o)
  206. {
  207.     return (o.scrollWidth > o.offsetWidth ? true : false);
  208. }
  209.  
  210. // Add the data bound CSS table to the document
  211. function AddCSSTable(oContainer, sPathToData, sLinkFld)
  212. {
  213.     // wrap the CSS attribute name in a link unless prop is explicitly specified
  214.     // sort by the field surrounded by the link    
  215.     if (!sLinkFld || sLinkFld != "cssattr")
  216.     {
  217.         sLinkFld = "prop";
  218.     }
  219.  
  220.     var sCSS = '<OBJECT WIDTH=0 HEIGHT=0 id=tdcCSS CLASSID="clsid:333C7BC4-460F-11D0-BC04-0080C7055A83" ondatasetcomplete="handle_css_dsc()">' +
  221.         '<PARAM NAME="DataURL" VALUE="' + sPathToData + '">' +
  222.         '<PARAM NAME="UseHeader" VALUE="True">' +
  223.         '<PARAM NAME="charset" VALUE="windows-1252">' +
  224.         '<PARAM NAME="TextQualifier" VALUE="|">' +
  225.         '<PARAM NAME="Sort" VALUE="' + sLinkFld + '">' +
  226.         '</OBJECT>'
  227.  
  228.     document.body.insertAdjacentHTML('afterBegin', sCSS);
  229.  
  230.     oContainer.innerHTML = "<TABLE CLASS='clsStd' STYLE='table-layout:fixed' DATASRC=#tdcCSS onreadystatechange='FixCSSTable()'>" +
  231.         "<COL WIDTH='20%'><COL WIDTH='15%'><COL WIDTH='*'>" +
  232.         "<THEAD><TR VALIGN=TOP BGCOLOR=#DDDDDD><TH>Style property</TH><TH>Style attribute</TH><TH>Description</TH></TR>" +
  233.         "<TBODY><TR>" +
  234.         GenBoundCell('prop', null, null, (sLinkFld == "prop" ? "<A DATAFLD=propurl>" : null), (sLinkFld == "prop" ? "</A>" : null)) +
  235.         GenBoundCell('cssattr', null, null, (sLinkFld == "cssattr" ? "<A DATAFLD=propurl>" : null), (sLinkFld == "cssattr" ? "</A>" : null)) +
  236.         GenBoundCell('css_desc', null, 'html') +
  237.         "</TR>" +
  238.         "</TABLE>";
  239.  
  240.     return true;
  241. }
  242.  
  243. // fires when the ondatasetcomplete event fires on the CSS DSO
  244. // Only if this happens should the related styles block be displayed
  245. function handle_css_dsc()
  246. {
  247.     SetExpandableCaption(pStyles, "Show Styles", true);
  248. }
  249.  
  250. // Return true if the document represents a collection
  251. function IsCollection(oDoc)
  252. {
  253.     var oReg = new RegExp("Collection");
  254.     return (oDoc.title.match(oReg) ? true : false);
  255. }
  256.  
  257.  
  258. /*
  259. Return a string representing a data bound table cell
  260. cField - name of the field in the data set
  261. cElem - name of element to bind
  262. cFormat - format of data
  263. cPre - prefix wrapper 
  264. cPost - suffix wrapper
  265. */
  266. function GenBoundCell(cField, cElem, cFormat, cPre, cPost)
  267. {
  268.     if (!cElem)
  269.     {
  270.         cElem = 'SPAN';
  271.     }
  272.  
  273.     if (!cFormat)
  274.     {
  275.         cFormat="text"
  276.     }
  277.  
  278.     if (!cPre)
  279.     {
  280.         cPre = '';
  281.     }
  282.  
  283.     if (!cPost)
  284.     {
  285.         cPost = '';
  286.     }
  287.  
  288.     return '<TD>' + cPre + '<' + cElem + ' DATAFLD=' + cField + ' DATAFORMATAS=' + cFormat + '>' + '</' + cElem + '>' + cPost + '</TD>';
  289. }
  290.  
  291. // Filter the members displayed supplied by a TDC
  292. // oSelect - reference to a select
  293. // oTDC - reference to a TDC
  294. function FilterMembers(oSelect, oTDC, sDataSrc)
  295. {
  296.     var sView = g_oMemberSettings._sDefView = oSelect.options(oSelect.selectedIndex).value;
  297.  
  298.     g_fMemberTableReady = false;
  299.  
  300.     var sNameCol = GetFriendlyCol(sView)
  301.     if (RebindMTCols(tblMembers, sNameCol, GetImgCol(sView), sDataSrc))
  302.     {
  303.         oTDC.object.Sort = sNameCol;
  304.     }
  305.         
  306.     //oSelect.parentElement.title = 
  307.     oTDC.object.Filter = GetFilterExpr(sView);
  308.  
  309.     var oPersistence = EnsurePersistence();
  310.     oPersistence.persistMembers(sView);
  311.     oTDC.Reset();
  312.  
  313.     return true;
  314. }
  315.  
  316. // Rebind the name/img column of the member table to the appropriate field in the data set (but only if necessary)
  317. function RebindMTCols(oTable, sNewFCol, sNewImgCol, sDataSrc)
  318. {    
  319.     // Don't bother rebinding to the same column
  320.     if (!sDataSrc && g_oMemberSettings._sFC == sNewFCol)
  321.     {
  322.         return false;
  323.     }
  324.  
  325.     if (!sDataSrc)
  326.     {
  327.         sDataSrc = oTable.dataSrc;
  328.     }
  329.     
  330.     oTable.dataSrc = '';
  331.     ref_friendly.dataFld = sNewFCol;
  332.     ref_icon.dataFld = sNewImgCol;
  333.     oTable.dataSrc = sDataSrc;
  334.  
  335.     g_oMemberSettings._sFC = sNewFCol;
  336.     
  337.     return true;
  338. }
  339.  
  340. // Fired when a member image loads. Allows us to set the tooltip
  341. // oImg - reference to an image object
  342. // no need to specify a full vroot here.
  343.  
  344. function handle_members_dsc()
  345. {
  346.     if (g_oMemberSettings._iState == 0)
  347.     {
  348.         g_oMemberSettings._iState = 1;
  349.  
  350.         if (typeof(blkHTML) != 'undefined' && !blkHTML.getAttribute("_GENERATED"))
  351.         {
  352.             BuildHTMLSyntax(tdcMembers.recordset.Clone(1), blkHTML);
  353.         }
  354.  
  355.         AddMemberTable();
  356.  
  357.         // TDC BUG: Can't modify the TDC state (filter/sort) during dsc event, so use a timeout instead
  358.         window.setTimeout("SyncMemberView()", 0);
  359.     }
  360.     else if (g_oMemberSettings._iState == 1)
  361.     {
  362.         
  363.         ModifyMemberRows();
  364.     }    
  365.  
  366. }
  367.  
  368. function SyncMemberView()
  369. {
  370.  
  371.     var sView = g_oMemberSettings._sDefView;
  372.     var sNewFilter = GetFilterExpr(sView);
  373.     if (tdcMembers.object.Filter != sNewFilter)
  374.     {
  375.         tdcMembers.object.Filter = sNewFilter;
  376.         tdcMembers.object.Sort = GetFriendlyCol(sView);
  377.         tdcMembers.Reset();
  378.     }
  379.     else
  380.     {
  381.         ModifyMemberRows();
  382.     }
  383.  
  384.     tblMembers.dataSrc = "#tdcMembers";
  385. }
  386.  
  387. function BuildHTMLSyntax(oRS, oDest)
  388. {
  389.     if (!oDest)
  390.     {
  391.         // The XSL Transform determined that the object wasn't worthy of HTML syntax 
  392.         // since it didn't output the container
  393.         return;
  394.     }
  395.  
  396.     oDest.setAttribute("_GENERATED", "1"); // prevent reentry; we only have to build syntax once
  397.  
  398.  
  399.     if (oRS.BOF && oRS.EOF)
  400.     {
  401.         // no attributes; hide the syntax block. #104158
  402.         document.all[oDest.sourceIndex-1].style.display = "none";
  403.         return;
  404.     }
  405.  
  406.     
  407.     var sPN = oDest.getAttribute("PN");
  408.     var sSyntax = "<PRE CLASS='clsSyntax'><<B>" + sPN + "</B>";
  409.     oRS.MoveFirst();
  410.     while (!oRS.EOF)
  411.     {
  412.         //invoke_kind=2 | invoke_kind=4 | invoke_kind=6) & ref_dynamic <> null
  413.         var sAttr = oRS.Fields("ref_persistent").value;
  414.         if (sAttr != "null")
  415.         {
  416.             sSyntax += "<DIV STYLE='margin-left:20px'><B>" + sAttr + "</B>=<I>" + sAttr.toLowerCase() + "</I></DIV>";
  417.         }
  418.         oRS.MoveNext();
  419.     }
  420.  
  421.     sSyntax += "<DIV>></DIV>";
  422.  
  423.     if (!oDest.getAttribute("CLOSING_OPTIONAL"))
  424.     {
  425.         sSyntax += "<B></" + sPN + "></B>"
  426.     }
  427.     
  428.     oDest.innerHTML = sSyntax + "</PRE>";
  429. }
  430.  
  431. function AddProposedAdorner(oTbl, oRow, oRS)
  432. {
  433.     //BUGBUG: Remove this test when all data files are synchronized to include 'proposed' column
  434.     if (oRS.fields.count != 9) return false;
  435.  
  436.     oRS.AbsolutePosition = oRow.recordNumber;
  437.     if (oRS.fields("proposed").value == 1)
  438.     {
  439.         oRow.cells(0).innerHTML += "*";
  440.         return 1;
  441.     }
  442.     return 0;
  443. }
  444.  
  445. function ModifyMemberRows()
  446. {
  447.     if (!g_fMemberTableReady)
  448.     {
  449.         window.setTimeout("ModifyMemberRows()", 1000);
  450.         return;
  451.     }
  452.  
  453.     var iProposed = 0;
  454.     for (var i = 1; i < tblMembers.rows.length; i++)
  455.     {
  456.         ModifyMemberRow(tblMembers.rows[i].cells(1).children(0), tdcMembers);
  457.         iProposed += AddProposedAdorner(tblMembers, tblMembers.rows[i], tdcMembers.recordset);
  458.     }
  459.     divProposed.style.display = (iProposed ? "inline" : "none");
  460. }
  461.  
  462. function handle_members_rsc()
  463. {
  464.  
  465.     // see if the table is complete
  466.     if (window.event.srcElement.readyState == 'complete')
  467.     {        
  468.         g_fMemberTableReady = true;
  469.     }
  470. }
  471.  
  472. function ModifyMemberRow(oImg, oTDC)
  473. {
  474.     var sImgPath = oImg.href.toLowerCase();
  475.  
  476.     var aMatch = sImgPath.match(g_oRegImgTitle);
  477.  
  478.     oImg.title = (null != aMatch ? g_aMemberImg2Str[aMatch[1]] : "Member");
  479.  
  480.     if (g_oRegProp.test((null != aMatch ? aMatch[1] : sImgPath)))
  481.     {
  482.         var oRow = tblMembers.rows[oImg.recordNumber];
  483.         if (oRow)
  484.         {
  485.             ModPropAttr(oRow.children(0).all(1), oTDC);
  486.         }
  487.     }
  488.  
  489.     return true;
  490. }
  491.  
  492. // Builds a string and sets the tooltip for the cell
  493. // When All is selected, the property rather than the attribute is displayed
  494. // When Attrib is selected, the attrib is displayed and the tooltip is arranged appropriately
  495. // When property is selected, the property is displayed ...
  496. // oPropCell - the cell to be tipped
  497. function ModPropAttr(oPropCell, oTDC)
  498. {
  499.     // added robustness and stack var to handle quirk on some machines
  500.     if (typeof(oTDC) != 'object')
  501.     {
  502.         return false;
  503.     }
  504.  
  505.     var oRS = oTDC.recordset;
  506.     if (!oRS)
  507.     {
  508.         return false;
  509.     }
  510.  
  511.     oRS.AbsolutePosition = oPropCell.recordNumber;
  512.     
  513.     var iFilter = cboInvokeKind.options(cboInvokeKind.selectedIndex).value;
  514.  
  515.     var sPropValue = null, sAttrValue = null;
  516.     
  517.     with (oRS.fields)
  518.     {
  519.         sPropValue = item('ref_dynamic').value;
  520.         sAttrValue = item('ref_persistent').value;
  521.         if (sPropValue == 'null' || sAttrValue == 'null')
  522.         {
  523.             return false;
  524.         }
  525.     }
  526.  
  527.     var sProp = sPropValue + ' property';
  528.     var sAttr = sAttrValue + ' attribute';
  529.     var sTip = 'The ' + (iFilter==0 ? sAttr : sProp) + ' corresponds to the ' + (iFilter==0 ? sProp : sAttr) + '.';
  530.     oPropCell.className = "clsPropattr";
  531.     oPropCell.title = sTip;
  532.  
  533.     return true;
  534. }
  535.  
  536. // Map an invoke_kind to a filter expression for use by the TDC
  537. function GetFilterExpr(sValue)
  538. {
  539.     sValue = sValue.toLowerCase();
  540.     return (typeof(g_FilterMap[sValue]) == "string" ? g_FilterMap[sValue] : "");
  541. }
  542.  
  543. function GetFriendlyCol(sValue)
  544. {
  545.     return (sValue.toLowerCase() == "attributes") ? "ref_persistent" : "ref_dynamic";
  546. }
  547.  
  548. function GetImgCol(sValue)
  549. {
  550.     return (sValue == "attributes") ? "pers_icon" : "dyn_icon";
  551. }
  552.     
  553. // map the specified view to an index into a SELECT defined below
  554. function MapViewToOption(vView)
  555. {
  556.     return (typeof(g_aMemberViewByNum[vView]) == 'number' ? g_aMemberViewByNum[vView] : 0);
  557. }
  558.  
  559. // return a string representing the SELECT to be injected into the data bound table
  560. function BuildViewCombo()
  561. {
  562.         return "<SELECT ID='cboInvokeKind' onchange='FilterMembers(this, tdcMembers)'>" +
  563.         "<OPTION VALUE='all'>All" +
  564.         "<OPTION VALUE='attributes'>Attributes" +
  565.         "<OPTION VALUE='properties'>Properties" +
  566.         "<OPTION VALUE='methods'>Methods" +
  567.         "<OPTION VALUE='events'>Events" +
  568.         "<OPTION VALUE='collections'>Collections" +
  569.         "<OPTION VALUE='behaviors'>Behaviors" + 
  570.         "<OPTION VALUE='filters'>Filters" + 
  571.         "</SELECT>";
  572. }
  573.  
  574. // BUGBUG: code assumes that run-time column is 0 and that this is the linked column
  575. function fixNA()
  576. {
  577.     var tblStyles = divCSS.children(0);
  578.     var iLen = tblStyles.rows.length;
  579.     for (var i = 1; i< iLen; i++)
  580.     {
  581.         var oRow = tblStyles.rows(i);
  582.         var oProp = oRow.children(0);
  583.         var sText = oProp.innerText;
  584.         if (sText == "N/A")
  585.         {
  586.             var sHREF = oProp.children(0).href;
  587.             var oAttr = oRow.children(1);
  588.             var sAttrText = oRow.children(1).innerText;
  589.             oAttr.innerHTML = "<A HREF='" + sHREF + "'>" + sAttrText + "</A>";
  590.             oProp.innerHTML = sText;
  591.         }
  592.         else
  593.         {
  594.             break;
  595.         }
  596.     }
  597.  
  598.     return true;
  599. }
  600.  
  601. // behavior attribute is only proposed, so append some text to that effect
  602. function addProposed()
  603. {
  604.     var tbl=divCSS.children(0);
  605.     for (i=0;i<tbl.rows.length;i++)
  606.     {
  607.         if (tbl.rows(i).cells(1).innerText=="behavior")
  608.         {
  609.             tbl.rows(i).cells(1).insertAdjacentText("beforeEnd"," (proposed)");
  610.             break;
  611.         }
  612.     }        
  613.  
  614.     return true;
  615. }
  616.  
  617. // patch the style table
  618. function FixCSSTable()
  619. {
  620.     var tbl=event.srcElement;
  621.     if (tbl.readyState=="complete")
  622.     {
  623.         window.setTimeout("addProposed()", 0);
  624.         window.setTimeout("fixNA()", 0);
  625.     }
  626.  
  627.     return true;
  628. }
  629.  
  630. /*
  631. function Trace(s)
  632. {
  633.     if (typeof(divTrace) != 'object')
  634.     {
  635.         document.body.insertAdjacentHTML('beforeEnd', '<DIV ID="divTrace" STYLE="background-color:lime;overflow:scroll;height:300px;width:400px"></DIV><BUTTON onclick="Trace_Clear()">Clear</BUTTON>');
  636.     }
  637.  
  638.     divTrace.innerHTML += s + "<BR>";
  639. }
  640.  
  641. function Trace_Clear()
  642. {
  643.     if (typeof(divTrace) == 'object')
  644.     {
  645.         divTrace.innerHTML = "";
  646.     }
  647. }
  648. */
  649.