home *** CD-ROM | disk | FTP | other *** search
/ PC World 2007 July & August / PCWorld_2007-07-08_cd.bin / system / bootvis / bootvis.msi / _2C89A9B080E04AB5A09DF570A2E53DC0 / html / langref.js < prev    next >
Text File  |  2003-06-23  |  19KB  |  816 lines

  1. //
  2. // Common code
  3. //
  4. var ieVer = 0;
  5. var curLang = null;
  6. var showAll = true;
  7. var cook = null;
  8. var baseUrl = document.scripts[document.scripts.length - 1].src.replace(/[^\/]+.js/, "");
  9.  
  10. if (navigator.appName == "Microsoft Internet Explorer") {
  11.     var ver = navigator.appVersion;
  12.     var v = new Number(ver.substring(0,ver.indexOf(".", 0)));
  13.     if (v >= 4) {
  14.         ieVer = 4;
  15.  
  16.         // Look for a version number buried somewhere in the version string.
  17.         var toks = ver.split(/[^0-9.]/);
  18.         if (toks) {
  19.             for (var i = 0; i < toks.length; i++) {
  20.                 var tok = toks[i];
  21.                 if (tok.indexOf(".", 0) > 0) {
  22.                     if (tok >= 5)
  23.                         ieVer = 5;
  24.                 }
  25.             }
  26.         }
  27.     }
  28. }
  29.  
  30. if (ieVer >= 4) {
  31.     window.onload = bodyOnLoad;
  32. }
  33.  
  34. function bodyOnClick()
  35. {
  36.     if (ieVer >= 4) {
  37.         var elem = window.event.srcElement;
  38.         for (; elem; elem = elem.parentElement) {
  39.             if (elem.id == "reftip")
  40.                 return;
  41.         }
  42.  
  43.         hideTip();
  44.         closeMenu();
  45.         hideSeeAlso();
  46.     }
  47. }
  48.  
  49. function bodyOnLoad()
  50. {
  51.     if (ieVer >= 4) {
  52.         initLangs();
  53.         initReftips();
  54.         initSeeAlso();
  55.         document.body.onclick = bodyOnClick;
  56.     }
  57.  
  58. }
  59.  
  60. //
  61. // Language filtering
  62. //
  63. function initLangs()
  64. {
  65.     var hdr = document.all.hdr;
  66.     if (!hdr)
  67.         return;
  68.  
  69.     var langs = new Array;
  70.     var spans = document.all.tags("SPAN");
  71.     if (spans) {
  72.         var iElem = spans.length;
  73.         for (iElem = 0; iElem < spans.length; iElem++) {
  74.             var elem = spans[iElem];
  75.             if (elem.className == "lang") {
  76.  
  77.                 // Update the array of unique language names.
  78.                 var a = elem.innerText.split(",");
  79.                 for (var iTok = 0; iTok < a.length; iTok++) {
  80.                     var m = a[iTok].match(/([A-Za-z].*[A-Za-z+#])/);
  81.                     if (m) {
  82.                         var iLang = 0;
  83.                         while (iLang < langs.length && langs[iLang] < m[1])
  84.                             iLang++;
  85.                         if (iLang == langs.length || langs[iLang] != m[1]) {
  86.                             var before = langs.slice(0,iLang);
  87.                             var after = langs.slice(iLang);
  88.                             langs = before.concat(m[1]).concat(after);
  89.                         }
  90.                     }
  91.                 }
  92.             }
  93.         }
  94.     }
  95.  
  96.     if (langs.length > 0) {
  97.         var pres = document.all.tags("PRE");
  98.         if (pres) {
  99.             for (var iPre = 0; iPre < pres.length; iPre++)
  100.                 initPreElem(pres[iPre]);
  101.         }
  102.  
  103.         var obj = document.all.obj_cook;
  104.         if (obj && obj.object) {
  105.             cook = obj;
  106.             if (obj.getValue("lang.all") != "1") {
  107.                 var lang = obj.getValue("lang");
  108.                 var c = langs.length;
  109.                 for (var i = 0; i != c; ++i) {
  110.                     if (langs[i] == lang) {
  111.                         curLang = langs[i];
  112.                         showAll = false;
  113.                     }
  114.                 }
  115.             }
  116.         }
  117.  
  118.         var iLim = document.body.all.length;
  119.         var head = null;
  120.         for (var i = 0; i < iLim; i++) {
  121.             var elem = document.body.all[i];
  122.             if (elem.tagName.match(/^(P|PRE|[DOU]L)$/))
  123.                 break;
  124.             if (elem.tagName.match(/^H[1-6]$/)) {
  125.                 head = elem;
  126.                 head.insertAdjacentHTML('BeforeEnd', '<SPAN CLASS=ilang></SPAN>');
  127.             }
  128.         }
  129.  
  130.         var td = hdr.insertCell(0);
  131.         if (td) {
  132.             // Localizable strings.
  133.             var L_Filter_Tip = "Language Filter";        // tooltip for language button
  134.             var L_Language = "Language";                // heading for menu of programming languages
  135.             var L_Show_All = "Show All";                // label for 'show all languages' menu item
  136.  
  137.             // Add the language button to the button bar.
  138.             td.className = "button1";
  139.             td.style.width = "19px";
  140.             td.onclick = langMenu;
  141.             td.innerHTML = '<IMG SRC="' + baseUrl + 'Filter.gif' + '" ALT="' +
  142.                 L_Filter_Tip + '" BORDER=0>';
  143.  
  144.             // Add the menu.
  145.             var div = '<DIV ID="lang_menu" CLASS=langMenu><B>' + L_Language + '</B><UL>';
  146.             for (var i = 0; i < langs.length; i++)
  147.                 div += '<LI><A HREF="" ONCLICK="chooseLang(this)">' + langs[i] + '</A><BR>';
  148.             div += '<LI><A HREF="" ONCLICK="chooseAll()">' + L_Show_All + '</A></UL></DIV>';
  149.             document.body.insertAdjacentHTML('BeforeEnd', div);
  150.         }
  151.  
  152.         if (!showAll)
  153.             filterLang();
  154.     }
  155. }
  156.  
  157. function initPreElem(pre)
  158. {
  159.     var htm0 = pre.outerHTML;
  160.  
  161.     var reLang = /<span\b[^>]*class="?lang"?[^>]*>/i;
  162.     var iFirst = -1;
  163.     var iSecond = -1;
  164.  
  165.     iFirst = htm0.search(reLang);
  166.     if (iFirst >= 0) {
  167.         iPos = iFirst + 17;
  168.         iMatch = htm0.substr(iPos).search(reLang);
  169.         if (iMatch >= 0)
  170.             iSecond = iPos + iMatch;
  171.     }
  172.  
  173.     if (iSecond < 0) {
  174.         var htm1 = trimPreElem(htm0);
  175.         if (htm1 != htm0) {
  176.             pre.insertAdjacentHTML('AfterEnd', htm1);
  177.             pre.outerHTML = "";
  178.         }
  179.     }
  180.     else {
  181.         var rePairs = /<(\w+)\b[^>]*><\/\1>/gi;
  182.  
  183.         var substr1 = htm0.substring(0,iSecond);
  184.         var tags1 = substr1.replace(/>[^<>]+(<|$)/g, ">$1");
  185.         var open1 = tags1.replace(rePairs, "");
  186.         open1 = open1.replace(rePairs, "");
  187.  
  188.         var substr2 = htm0.substring(iSecond);
  189.         var tags2 = substr2.replace(/>[^<>]+</g, "><");
  190.         var open2 = tags2.replace(rePairs, "");
  191.         open2 = open2.replace(rePairs, "");
  192.  
  193.         pre.insertAdjacentHTML('AfterEnd', open1 + substr2);
  194.         pre.insertAdjacentHTML('AfterEnd', trimPreElem(substr1 + open2));
  195.         pre.outerHTML = "";
  196.     }    
  197. }
  198.  
  199. function trimPreElem(htm)
  200. {
  201.     return htm.replace(/[ \r\n]*((<\/[BI]>)*)[ \r\n]*<\/PRE>/g, "$1</PRE>").replace(
  202.         /\w*<\/SPAN>\w*((<[BI]>)*)\w*\r\n/g, "\r\n</SPAN>$1"
  203.         );
  204. }
  205.  
  206. function getBlock(elem)
  207. {
  208.     while (elem && elem.tagName.match(/^([BIUA]|SPAN|CODE|TD)$/))
  209.         elem = elem.parentElement;
  210.     return elem;
  211. }
  212.  
  213. function langMenu()
  214. {
  215.     bodyOnClick();
  216.  
  217.     window.event.returnValue = false;
  218.     window.event.cancelBubble = true;
  219.  
  220.     var div = document.all.lang_menu;
  221.     var lnk = window.event.srcElement;
  222.     if (div && lnk) {
  223.         var x = lnk.offsetLeft + lnk.offsetWidth - div.offsetWidth;
  224.         div.style.pixelLeft = (x < 0) ? 0 : x;
  225.         div.style.pixelTop = lnk.offsetTop + lnk.offsetHeight;
  226.         div.style.visibility = "visible";
  227.     }
  228. }
  229.  
  230. function chooseLang(item)
  231. {
  232.     window.event.returnValue = false;
  233.     window.event.cancelBubble = true;
  234.  
  235.     if (item) {
  236.         closeMenu();
  237.         curLang = item.innerText;
  238.         showAll = false;
  239.     }
  240.  
  241.     if (cook) {
  242.         cook.putValue('lang', curLang);
  243.         cook.putValue('lang.all', '');
  244.     }
  245.  
  246.     filterLang();
  247. }
  248.  
  249. function chooseAll()
  250. {
  251.     window.event.returnValue = false;
  252.     window.event.cancelBubble = true;
  253.  
  254.     closeMenu();
  255.  
  256.     showAll = true;
  257.     if (cook)
  258.         cook.putValue('lang.all', '1');
  259.  
  260.     unfilterLang();
  261. }
  262.  
  263. function closeMenu()
  264. {
  265.     var div = document.all.lang_menu;
  266.     if (div && div.style.visibility != "hidden") {
  267.         var lnk = document.activeElement;
  268.         if (lnk && lnk.tagName == "A")
  269.             lnk.blur();
  270.  
  271.         div.style.visibility = "hidden";
  272.     }
  273. }
  274.  
  275. function getNext(elem)
  276. {
  277.     for (var i = elem.sourceIndex + 1; i < document.all.length; i++) {
  278.         var next = document.all[i];
  279.         if (!elem.contains(next))
  280.             return next;
  281.     }
  282.     return null;
  283. }
  284.  
  285. function filterMatch(text, name)
  286. {
  287.     var a = text.split(",");
  288.     for (var iTok = 0; iTok < a.length; iTok++) {
  289.         var m = a[iTok].match(/([A-Za-z].*[A-Za-z+#])/);
  290.         if (m && m[1] == name)
  291.             return true;
  292.     }
  293.     return false;
  294. }
  295.  
  296. function topicHeading(head)
  297. {
  298.     var iLim = document.body.children.length;
  299.     var idxLim = head.sourceIndex;
  300.  
  301.     for (var i = 0; i < iLim; i++) {
  302.         var elem = document.body.children[i];
  303.         if (elem.sourceIndex < idxLim) {
  304.             if (elem.tagName.match(/^(P|PRE|[DOU]L)$/))
  305.                 return false;
  306.         }
  307.         else
  308.             break;
  309.     }
  310.     return true;
  311. }
  312.  
  313. function filterLang()
  314. {
  315.     var spans = document.all.tags("SPAN");
  316.     for (var i = 0; i < spans.length; i++) {
  317.         var elem = spans[i];
  318.         if (elem.className == "lang") {
  319.             var newVal = filterMatch(elem.innerText, curLang) ? "block" : "none";
  320.             var block = getBlock(elem);
  321.             block.style.display = newVal;
  322.             elem.style.display = "none";
  323.  
  324.             if (block.tagName == "DT") {
  325.                 var next = getNext(block);
  326.                 if (next && next.tagName == "DD")
  327.                     next.style.display = newVal;
  328.             }
  329.             else if (block.tagName == "DIV") {
  330.                 block.className = "filtered2";
  331.             }
  332.             else if (block.tagName.match(/^H[1-6]$/)) {
  333.                 if (topicHeading(block)) {
  334.                     if (newVal != "none") {
  335.                         var tag = null;
  336.                         if (block.children && block.children.length) {
  337.                             tag = block.children[block.children.length - 1];
  338.                             if (tag.className == "ilang") {
  339.                                 tag.innerHTML = (newVal == "block") ?
  340.                                     '  [' + curLang + ']' : "";
  341.                             }
  342.                         }
  343.                     }
  344.                 }
  345.                 else {
  346.                     var next = getNext(block);
  347.                     while (next && !next.tagName.match(/^(H[1-6]|DIV)$/)) {
  348.                         next.style.display = newVal;
  349.                         next = getNext(next);
  350.                     }
  351.                 }
  352.             }
  353.         }
  354.         else if (elem.className == "ilang") {
  355.             elem.innerHTML = '  [' + curLang + ']';
  356.         }
  357.     }
  358.  
  359.     if (ieVer == 4) {
  360.         document.body.style.display = "none";
  361.         document.body.style.display = "block";
  362.     }
  363. }
  364.  
  365. function unfilterLang(name)
  366. {
  367.     var spans = document.all.tags("SPAN");
  368.     for (var i = 0; i < spans.length; i++) {
  369.         var elem = spans[i];
  370.         if (elem.className == "lang") {
  371.             var block = getBlock(elem);
  372.             block.style.display = "block";
  373.             elem.style.display = "inline";
  374.  
  375.             if (block.tagName == "DT") {
  376.                 var next = getNext(block);
  377.                 if (next && next.tagName == "DD")
  378.                     next.style.display = "block";
  379.             }
  380.             else if (block.tagName == "DIV") {
  381.                 block.className = "filtered";
  382.             }
  383.             else if (block.tagName.match(/^H[1-6]$/)) {
  384.                 if (topicHeading(block)) {
  385.                     var tag = null;
  386.                     if (block.children && block.children.length) {
  387.                         tag = block.children[block.children.length - 1];
  388.                         if (tag && tag.className == "ilang")
  389.                             tag.innerHTML = "";
  390.                     }
  391.                 }
  392.                 else {
  393.                     var next = getNext(block);
  394.                     while (next && !next.tagName.match(/^(H[1-6]|DIV)$/)) {
  395.                         next.style.display = "block";
  396.                         next = getNext(next);
  397.                     }
  398.                 }
  399.             }
  400.         }
  401.         else if (elem.className == "ilang") {
  402.             elem.innerHTML = "";
  403.         }
  404.     }
  405. }
  406.  
  407.  
  408. //
  409. // Reftips (parameter popups)
  410. //
  411. function initReftips()
  412. {
  413.     var DLs = document.all.tags("DL");
  414.     var PREs = document.all.tags("PRE");
  415.     if (DLs && PREs) {
  416.         var iDL = 0;
  417.         var iPRE = 0;
  418.         var iSyntax = -1;
  419.         for (var iPRE = 0; iPRE < PREs.length; iPRE++) {
  420.             if (PREs[iPRE].className == "syntax") {
  421.                 while (iDL < DLs.length && DLs[iDL].sourceIndex < PREs[iPRE].sourceIndex)
  422.                     iDL++;            
  423.                 if (iDL < DLs.length) {
  424.                     initSyntax(PREs[iPRE], DLs[iDL]);
  425.                     iSyntax = iPRE;
  426.                 }
  427.                 else
  428.                     break;
  429.             }
  430.         }
  431.  
  432.         if (iSyntax >= 0) {
  433.             var last = PREs[iSyntax];
  434.             last.insertAdjacentHTML(
  435.                 'AfterEnd',
  436.                 '<DIV ID=reftip CLASS=reftip STYLE="position:absolute;visibility:hidden;overflow:visible;"></DIV>'
  437.                 );
  438.         }
  439.     }
  440. }
  441.  
  442. function initSyntax(pre, dl)
  443. {
  444.     var strSyn = pre.outerHTML;
  445.     var ichStart = strSyn.indexOf('>', 0) + 1;
  446.     var terms = dl.children.tags("DT");
  447.     if (terms) {
  448.         for (var iTerm = 0; iTerm < terms.length; iTerm++) {
  449.             var words = terms[iTerm].innerText.replace(/\[.+\]/g, " ").replace(/,/g, " ").split(" ");
  450.             var htm = terms[iTerm].innerHTML;
  451.             for (var iWord = 0; iWord < words.length; iWord++) {
  452.                 var word = words[iWord];
  453.  
  454.                 if (word.length > 0 && htm.indexOf(word, 0) < 0)
  455.                     word = word.replace(/:.+/, "");
  456.  
  457.                 if (word.length > 0) {
  458.                     var ichMatch = findTerm(strSyn, ichStart, word);
  459.                     while (ichMatch > 0) {
  460.                         var strTag = '<A HREF="" ONCLICK="showTip(this)" CLASS="synParam">' + word + '</A>';
  461.  
  462.                         strSyn =
  463.                             strSyn.slice(0, ichMatch) +
  464.                             strTag +
  465.                             strSyn.slice(ichMatch + word.length);
  466.  
  467.                         ichMatch = findTerm(strSyn, ichMatch + strTag.length, word);
  468.                     }
  469.                 }
  470.             }
  471.         }
  472.     }
  473.  
  474.     // Replace the syntax block with our modified version.
  475.     pre.outerHTML = strSyn;
  476. }
  477.  
  478. function findTerm(strSyn, ichPos, strTerm)
  479. {
  480.     var ichMatch = strSyn.indexOf(strTerm, ichPos);
  481.     while (ichMatch >= 0) {
  482.         var prev = (ichMatch == 0) ? '\0' : strSyn.charAt(ichMatch - 1);
  483.         var next = strSyn.charAt(ichMatch + strTerm.length);
  484.         if (!isalnum(prev) && !isalnum(next) && !isInTag(strSyn, ichMatch)) {
  485.             var ichComment = strSyn.indexOf("/*", ichPos);
  486.             while (ichComment >= 0) {
  487.                 if (ichComment > ichMatch) {
  488.                     ichComment = -1;
  489.                     break; 
  490.                 }
  491.                 var ichEnd = strSyn.indexOf("*/", ichComment);
  492.                 if (ichEnd < 0 || ichEnd > ichMatch)
  493.                     break;
  494.                 ichComment = strSyn.indexOf("/*", ichEnd);
  495.             }
  496.             if (ichComment < 0) {
  497.                 ichComment = strSyn.indexOf("//", ichPos);
  498.                 while (ichComment >= 0) {
  499.                     if (ichComment > ichMatch) {
  500.                         ichComment = -1;
  501.                         break; 
  502.                     }
  503.                     var ichEnd = strSyn.indexOf("\n", ichComment);
  504.                     if (ichEnd < 0 || ichEnd > ichMatch)
  505.                         break;
  506.                     ichComment = strSyn.indexOf("//", ichEnd);
  507.                 }
  508.             }
  509.             if (ichComment < 0)
  510.                 break;
  511.         }
  512.         ichMatch = strSyn.indexOf(strTerm, ichMatch + strTerm.length);
  513.     }
  514.     return ichMatch;
  515. }
  516.  
  517. function isInTag(strHtml, ichPos)
  518. {
  519.     return strHtml.lastIndexOf('<', ichPos) >
  520.         strHtml.lastIndexOf('>', ichPos);
  521. }
  522.  
  523. function isalnum(ch)
  524. {
  525.     return ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || (ch == '_'));
  526. }
  527.  
  528. function showTip(link)
  529. {
  530.     bodyOnClick();
  531.  
  532.     var tip = document.all.reftip;
  533.     if (!tip || !link)
  534.         return;
  535.  
  536.     window.event.returnValue = false;
  537.     window.event.cancelBubble = true;
  538.  
  539.     // Hide the tip if necessary and initialize its size.
  540.     tip.style.visibility = "hidden";
  541.     tip.style.pixelWidth = 260;
  542.     tip.style.pixelHeight = 24;
  543.  
  544.     // Find the link target.
  545.     var term = null;
  546.     var def = null;
  547.     var DLs = document.all.tags("DL");
  548.     for (var iDL = 0; iDL < DLs.length; iDL++) {
  549.         if (DLs[iDL].sourceIndex > link.sourceIndex) {
  550.             var dl = DLs[iDL];
  551.             var iMax = dl.children.length - 1;
  552.             for (var iElem = 0; iElem < iMax; iElem++) {
  553.                 var dt = dl.children[iElem];
  554.                 if (dt.tagName == "DT" && dt.style.display != "none") {
  555.                     if (findTerm(dt.innerText, 0, link.innerText) >= 0) {
  556.                         var dd = dl.children[iElem + 1];
  557.                         if (dd.tagName == "DD") {
  558.                             term = dt;
  559.                             def = dd;
  560.                         }
  561.                         break;
  562.                     }
  563.                 }
  564.             }
  565.             break;
  566.         }
  567.     }
  568.  
  569.     if (def) {
  570.         window.linkElement = link;
  571.         window.linkTarget = term;
  572.         tip.innerHTML = '<DL><DT>' + term.innerHTML + '</DT><DD>' + def.innerHTML + '</DD></DL>';
  573.         window.setTimeout("moveTip()", 0);
  574.     }
  575. }
  576.  
  577. function jumpParam()
  578. {
  579.     hideTip();
  580.  
  581.     window.linkTarget.scrollIntoView();
  582.     document.body.scrollLeft = 0;
  583.  
  584.     flash(3);
  585. }
  586.  
  587. function flash(c)
  588. {
  589.     window.linkTarget.style.background = (c & 1) ? "#CCCCCC" : "";
  590.     if (c)
  591.         window.setTimeout("flash(" + (c-1) + ")", 200);
  592. }
  593.  
  594. function moveTip()
  595. {
  596.     var tip = document.all.reftip;
  597.     var link = window.linkElement;
  598.     if (!tip || !link)
  599.         return; //error
  600.  
  601.     var w = tip.offsetWidth;
  602.     var h = tip.offsetHeight;
  603.  
  604.     if (w > tip.style.pixelWidth) {
  605.         tip.style.pixelWidth = w;
  606.         window.setTimeout("moveTip()", 0);
  607.         return;
  608.     }
  609.  
  610.     var maxw = document.body.clientWidth;
  611.     var maxh = document.body.clientHeight;
  612.  
  613.     if (h > maxh) {
  614.         if (w < maxw) {
  615.             w = w * 3 / 2;
  616.             tip.style.pixelWidth = (w < maxw) ? w : maxw;
  617.             window.setTimeout("moveTip()", 0);
  618.             return;
  619.         }
  620.     }
  621.  
  622.     var x,y;
  623.  
  624.     var linkLeft = link.offsetLeft - document.body.scrollLeft;
  625.     var linkRight = linkLeft + link.offsetWidth;
  626.  
  627.     var linkTop = link.offsetTop - document.body.scrollTop;
  628.     var linkBottom = linkTop + link.offsetHeight;
  629.  
  630.     var cxMin = link.offsetWidth - 24;
  631.     if (cxMin < 16)
  632.         cxMin = 16;
  633.  
  634.     if (linkLeft + cxMin + w <= maxw) {
  635.         x = maxw - w;
  636.         if (x > linkRight + 8)
  637.             x = linkRight + 8;
  638.         y = maxh - h;
  639.         if (y > linkTop)
  640.             y = linkTop;
  641.     }
  642.     else if (linkBottom + h <= maxh) {
  643.         x = maxw - w;
  644.         if (x < 0)
  645.             x = 0;
  646.         y = linkBottom;
  647.     }
  648.     else if (w <= linkRight - cxMin) {
  649.         x = linkLeft - w - 8;
  650.         if (x < 0)
  651.             x = 0;
  652.         y = maxh - h;
  653.         if (y > linkTop)
  654.             y = linkTop;
  655.     }
  656.     else if (h <= linkTop) {
  657.         x = maxw - w;
  658.         if (x < 0)
  659.             x = 0;
  660.         y = linkTop - h;
  661.     }
  662.     else if (w >= maxw) {
  663.         x = 0;
  664.         y = linkBottom;
  665.     }
  666.     else {
  667.         w = w * 3 / 2;
  668.         tip.style.pixelWidth = (w < maxw) ? w : maxw;
  669.         window.setTimeout("moveTip()", 0);
  670.         return;
  671.     }
  672.  
  673.     link.style.background = "#FFFF80";
  674.     tip.style.pixelLeft = x + document.body.scrollLeft;
  675.     tip.style.pixelTop = y + document.body.scrollTop;
  676.     tip.style.visibility = "visible";
  677. }
  678.  
  679. function hideTip()
  680. {
  681.     if (window.linkElement) {
  682.         window.linkElement.style.background = "";
  683.         window.linkElement = null;
  684.     }
  685.  
  686.     var tip = document.all.reftip;
  687.     if (tip) {
  688.         tip.style.visibility = "hidden";
  689.         tip.innerHTML = "";
  690.     }
  691. }
  692.  
  693. function beginsWith(s1, s2)
  694. {
  695.     // Does s1 begin with s2?
  696.     return s1.substring(0, s2.length) == s2;
  697. }
  698.  
  699. //
  700. // See Also popups
  701. //
  702. function initSeeAlso()
  703. {
  704.     // Localizable strings.
  705.     var L_See_Also = "See Also";
  706.     var L_Requirements = "Requirements";
  707.     var L_QuickInfo = "QuickInfo";
  708.  
  709.     var hdr = document.all.hdr;
  710.     if (!hdr)
  711.         return;
  712.  
  713.     var divS = new String;
  714.     var divR = new String;
  715.  
  716.     var heads = document.all.tags("H4");
  717.     if (heads) {
  718.         for (var i = 0; i < heads.length; i++) {
  719.             var head = heads[i];
  720.             var txt = head.innerText;
  721.             if (beginsWith(txt, L_See_Also)) {
  722.                 divS += head.outerHTML;
  723.                 var next = getNext(head);
  724.                 while (next && !next.tagName.match(/^(H[1-4]|DIV)$/)) {
  725.                     divS += next.outerHTML;
  726.                     next = getNext(next);
  727.                 }
  728.             }
  729.             else if (beginsWith(txt, L_Requirements) || beginsWith(txt, L_QuickInfo)) {
  730.                 divR += head.outerHTML;
  731.                 var next = getNext(head);
  732.                 while (next && !next.tagName.match(/^(H[1-4]|DIV)$/)) {
  733.                     divR += next.outerHTML;
  734.                     next = getNext(next);
  735.                 }
  736.             }
  737.         }
  738.     }
  739.  
  740.     var pos = getNext(hdr.parentElement);
  741.     if (pos) {
  742.         if (divR != "") {
  743.             divR = '<DIV ID=rpop CLASS=sapop>' + divR + '</DIV>';
  744.             var td = hdr.insertCell(0);
  745.             if (td) {
  746.                 td.className = "button1";
  747.                 td.style.width = "19px";
  748.                 td.onclick = showRequirements;
  749.                 td.innerHTML = '<IMG SRC="' + baseUrl + 'Requirements.gif' + '" ALT="' + L_Requirements + '" BORDER=0>';
  750.                 if (ieVer == 4)
  751.                     document.body.insertAdjacentHTML('AfterBegin', divR);
  752.                 else
  753.                     document.body.insertAdjacentHTML('BeforeEnd', divR);
  754.             }
  755.         }
  756.         if (divS != "") {
  757.             divS = '<DIV ID=sapop CLASS=sapop>' + divS + '</DIV>';
  758.             var td = hdr.insertCell(0);
  759.             if (td) {
  760.                 td.className = "button1";
  761.                 td.style.width = "19px";
  762.                 td.onclick = showSeeAlso;
  763.                 td.innerHTML = '<IMG SRC="' + baseUrl + 'SeeAlso.gif' + '" ALT="' + L_See_Also + '" BORDER=0>';
  764.                 if (ieVer == 4)
  765.                     document.body.insertAdjacentHTML('AfterBegin', divS);
  766.                 else
  767.                     document.body.insertAdjacentHTML('BeforeEnd', divS);
  768.             }
  769.         }
  770.     }
  771. }
  772.  
  773. function showSeeAlso()
  774. {
  775.     bodyOnClick();
  776.  
  777.     window.event.returnValue = false;
  778.     window.event.cancelBubble = true;
  779.  
  780.     var div = document.all.sapop;
  781.     var lnk = window.event.srcElement;
  782.  
  783.     if (div && lnk) {
  784.         div.style.pixelTop = lnk.offsetTop + lnk.offsetHeight;
  785.         div.style.visibility = "visible";
  786.     }
  787. }
  788.  
  789. function showRequirements()
  790. {
  791.     bodyOnClick();
  792.  
  793.     window.event.returnValue = false;
  794.     window.event.cancelBubble = true;
  795.  
  796.     var div = document.all.rpop;
  797.     var lnk = window.event.srcElement;
  798.  
  799.     if (div && lnk) {
  800.         div.style.pixelTop = lnk.offsetTop + lnk.offsetHeight;
  801.         div.style.visibility = "visible";
  802.     }
  803. }
  804.  
  805. function hideSeeAlso()
  806. {
  807.     var div = document.all.sapop;
  808.     if (div)
  809.         div.style.visibility = "hidden";
  810.  
  811.     var div = document.all.rpop;
  812.     if (div)
  813.         div.style.visibility = "hidden";
  814. }
  815.  
  816.