text: ﻿// The IDs of all code snippet sets on the same page are stored so that we can keep them in synch when a tab is
  // selected.
  var allTabSetIds = new Array();
  
  // The IDs of language-specific text (LST) spans are used as dictionary keys so that we can get access to the
  // spans and update them when the user changes to a different language tab.  The values of the dictionary
  // objects are pipe separated language-specific attributes (lang1=value|lang2=value|lang3=value).  The language
  // ID can be specific (cs, vb, cpp, etc.) or may be a neutral entry (nu) which specifies text common to multiple
  // languages.  If a language is not present and there is no neutral entry, the span is hidden for all languages
  // to which it does not apply.
  var allLSTSetIds = new Object();
  
  // Help 1 persistence support.  This code must appear inline.
  var isHelp1;
  
  var curLoc = document.location + ".";
  
  if(curLoc.indexOf("mk:@MSITStore") == 0)
  {
      isHelp1 = true;
      curLoc = "ms-its:" + curLoc.substring(14, curLoc.length - 1);
      document.location.replace(curLoc);
  }
  else
      if(curLoc.indexOf("ms-its:") == 0)
          isHelp1 = true;
      else
          isHelp1 = false;
  
  // The OnLoad method
  function OnLoad(defaultLanguage)
  {
      var defLang;
  
      if(typeof(defaultLanguage) == "undefined" || defaultLanguage == null || defaultLanguage == "")
          defLang = "vb";
      else
          defLang = defaultLanguage;
  
      // This is a hack to fix the URLs for the background images on certain styles.  Help Viewer 1.0 doesn't
      // mind if you put the relative URL in the styles for fix up later in script.  However, Help Viewer 2.0 will
      // abort all processing and won't run any startup script if it sees an invalid URL in the style.  As such, we
      // put a dummy attribute in the style to specify the image filename and use this code to get the URL from the
      // Favorites icon and then substitute the background image icons in the URL and set it in each affected style.
      // This works in either version of the help viewer.
      var iconPath = undefined;
  
      try
      {
          var linkEnum = document.getElementsByTagName("link");
  
          for(var idx = 0; idx < linkEnum.length; idx++)
          {
              var link = linkEnum[idx];
  
              if(link.rel.toLowerCase() == "shortcut icon")
                  iconPath = link.href.toString();
          }
      }
      catch(e) { }
      finally { }
  
      if(iconPath)
      {
          try
          {
              var styleSheetEnum = document.styleSheets;
  
              for(var idx = 0; idx < styleSheetEnum.length; idx++)
              {
                  var styleSheet = styleSheetEnum[idx];
  
                  // Ignore sheets at ms-help URLs
                  if(styleSheet.href != null && styleSheet.href.substr(0, 8) == "ms-help:")
                      continue;
  
                  // Ignore errors (Help Viewer 2).  styleSheet.rules is inaccessible due to security restrictions
                  // for all style sheets not defined within the page.
                  try
                  {
                      // Get sheet rules
                      var rules = styleSheet.rules;
  
                      if(rules == null)
                          rules = styleSheet.cssRules;
  
                      if(rules != null)
                          if(rules.length != 0)
                              for(var ruleNdx = 0; ruleNdx != rules.length; ruleNdx++)
                              {
                                  var rule = rules.item(ruleNdx);
  
                                  var selectorText = rule.selectorText.toLowerCase();
  
                                  // The selector text may show up grouped or individually for these
                                  if(selectorText == ".oh_codesnippetcontainertableftactive, .oh_codesnippetcontainertableft, .oh_codesnippetcontainertableftdisabled" ||
                                    selectorText == ".oh_codesnippetcontainertableftactive" ||
                                    selectorText == ".oh_codesnippetcontainertableft" ||
                                    selectorText == ".oh_codesnippetcontainertableftdisabled")
                                  {
                                      rule.style.backgroundImage = "url(" + iconPath.replace("favicon.ico", "tabLeftBG.gif") + ")";
                                  }
  
                                  if(selectorText == ".oh_codesnippetcontainertabrightactive, .oh_codesnippetcontainertabright, .oh_codesnippetcontainertabrightdisabled" ||
                                    selectorText == ".oh_codesnippetcontainertabrightactive" ||
                                    selectorText == ".oh_codesnippetcontainertabright" ||
                                    selectorText == ".oh_codesnippetcontainertabrightdisabled")
                                  {
                                      rule.style.backgroundImage = "url(" + iconPath.replace("favicon.ico", "tabRightBG.gif") + ")";
                                  }
  
                                  if(selectorText == ".oh_footer")
                                  {
                                      rule.style.backgroundImage = "url(" + iconPath.replace("favicon.ico", "footer_slice.gif") + ")";
                                  }
                              }
                  }
                  catch(e) { }
                  finally { }
              }
          }
          catch(e) { }
          finally { }
      }
  
      // In MS Help Viewer, the transform the topic is ran through can move the footer.  Move it back where it
      // belongs if necessary.
      try
      {
          var footer = document.getElementById("OH_footer")
  
          if(footer)
          {
              var footerParent = document.body;
  
              if(footer.parentElement != footerParent)
              {
                  footer.parentElement.removeChild(footer);
                  footerParent.appendChild(footer);
              }
          }
      }
      catch(e) { }
      finally { }
  
      var language = GetLanguageCookie("CodeSnippetContainerLanguage", defLang);
  
      // If LST exists on the page, set the LST to show the user selected programming language
      UpdateLST(language);
  
      // If code snippet groups exist, set the current language for them
      if(allTabSetIds.length > 0)
      {
          var i = 0;
  
          while(i < allTabSetIds.length)
          {
              var tabCount = 1;
  
              // The tab count may vary so find the last one in this set
              while(document.getElementById(allTabSetIds[i] + "_tab" + tabCount) != null)
                  tabCount++;
  
              tabCount--;
  
              // If not grouped, skip it
              if(tabCount > 1)
                  SetCurrentLanguage(allTabSetIds[i], language, tabCount);
  
              i++;
          }
      }
  }
  
  // This function executes in the OnLoad event and ChangeTab action on code snippets.  The function parameter
  // is the user chosen programming language.  This function iterates through the "allLSTSetIds" dictionary object
  // to update the node value of the LST span tag per the user's chosen programming language.
  function UpdateLST(language)
  {
      for(var lstMember in allLSTSetIds)
      {
          var devLangSpan = document.getElementById(lstMember);
  
          if(devLangSpan != null)
          {
              // There may be a carriage return before the LST span in the content so the replace function below
              // is used to trim the whitespace at the end of the previous node of the current LST node.
              if(devLangSpan.previousSibling != null && devLangSpan.previousSibling.nodeValue != null)
                  devLangSpan.previousSibling.nodeValue = devLangSpan.previousSibling.nodeValue.replace(/\s+$/, "");
  
              var langs = allLSTSetIds[lstMember].split("|");
              var k = 0;
              var keyValue;
  
              while(k < langs.length)
              {
                  keyValue = langs[k].split("=");
  
                  if(keyValue[0] == language)
                  {
                      devLangSpan.innerHTML = keyValue[1];
  
                      // Help 1 and MS Help Viewer workaround.  Add a space if the following text element starts
                      // with a space to prevent things running together.
                      if (devLangSpan.parentNode != null && devLangSpan.parentNode.nextSibling != null) {
                          if (devLangSpan.parentNode.nextSibling.nodeValue != null &&
                            !devLangSpan.parentNode.nextSibling.nodeValue.substring(0, 1).match(/[.,);:!/?]/)) {
                              devLangSpan.innerHTML = keyValue[1] + " ";
                          }
                      }
                      break;
                  }
  
                  k++;
              }
  
              // If not found, default to the neutral language.  If there is no neutral language entry, clear the
              // content to hide it.
              if(k >= langs.length)
              {
                  if(language != "nu")
                  {
                      k = 0;
  
                      while(k < langs.length)
                      {
                          keyValue = langs[k].split("=");
  
                          if(keyValue[0] == "nu")
                          {
                              devLangSpan.innerHTML = keyValue[1];
  
                              // Help 1 and MS Help Viewer workaround.  Add a space if the following text element
                              // starts with a space to prevent things running together.
                              if (devLangSpan.parentNode != null && devLangSpan.parentNode.nextSibling != null) {
                                  if (devLangSpan.parentNode.nextSibling.nodeValue != null &&
                                    !devLangSpan.parentNode.nextSibling.nodeValue.substring(0, 1).match(/[.,);:!/?]/)) {
                                      devLangSpan.innerHTML = keyValue[1] + " ";
                                  }
                              }
                              break;
                          }
  
                          k++;
                      }
                  }
  
                  if(k >= langs.length)
                      devLangSpan.innerHTML = "";
              }
          }
      }
  }
  
  // Get the selected language cookie
  function GetLanguageCookie(cookieName, defaultValue)
  {
      if(isHelp1)
      {
          try
          {
              var globals = Help1Globals;
  
              var value = globals.Load(cookieName);
  
              if(value == null)
                  value = defaultValue;
  
              return value;
          }
          catch(e)
          {
              return defaultValue;
          }
      }
  
      var cookie = document.cookie.split("; ");
  
      for(var i = 0; i < cookie.length; i++)
      {
          var crumb = cookie[i].split("=");
  
          if(cookieName == crumb[0])
              return unescape(crumb[1])
      }
  
      return defaultValue;
  }
  
  // Set the selected language cookie
  function SetLanguageCookie(name, value)
  {
      if(isHelp1)
      {
          try
          {
              var globals = Help1Globals;
  
              globals.Save(name, value);
          }
          catch(e)
          {
          }
  
          return;
      }
  
      var today = new Date();
  
      today.setTime(today.getTime());
  
      // Set the expiration time to be 60 days from now (in milliseconds)
      var expires_date = new Date(today.getTime() + (60 * 1000 * 60 * 60 * 24));
  
      document.cookie = name + "=" + escape(value) + ";expires=" + expires_date.toGMTString() + ";path=/";
  }
  
  // Add a language-specific text ID
  function AddLanguageSpecificTextSet(lstId)
  {
      var keyValue = lstId.split("?")
  
      allLSTSetIds[keyValue[0]] = keyValue[1];
  }
  
  var clipboardHandler;
  
  // Add a language tab set ID
  function AddLanguageTabSet(tabSetId)
  {
      allTabSetIds.push(tabSetId);
  
      // Create the clipboard handler on first use
      if(clipboardHandler == null && typeof (Clipboard) == "function")
      {
          clipboardHandler = new Clipboard('.OH_copyCodeSnippet',
          {
              text: function (trigger)
              {
                  // Get the code to copy to the clipboard from the active tab of the given tab set
                  var i = 1, tabSetId = trigger.id;
                  var pos = tabSetId.indexOf('_');
  
                  if(pos == -1)
                      return "";
  
                  tabSetId = tabSetId.substring(0, pos);
  
                  do
                  {
                      contentId = tabSetId + "_code_Div" + i;
                      tabTemp = document.getElementById(contentId);
  
                      if(tabTemp != null && tabTemp.style.display != "none")
                          break;
  
                      i++;
  
                  } while(tabTemp != null);
  
                  if(tabTemp == null)
                      return "";
  
                  return document.getElementById(contentId).innerText;
              }
          });
      }
  }
  
  // Switch the active tab for all of other code snippets
  function ChangeTab(tabSetId, language, snippetIdx, snippetCount)
  {
      SetLanguageCookie("CodeSnippetContainerLanguage", language);
  
      SetActiveTab(tabSetId, snippetIdx, snippetCount);
  
      // If LST exists on the page, set the LST to show the user selected programming language
      UpdateLST(language);
  
      var i = 0;
  
      while(i < allTabSetIds.length)
      {
          // We just care about other snippets
          if(allTabSetIds[i] != tabSetId)
          {
              // Other tab sets may not have the same number of tabs
              var tabCount = 1;
  
              while(document.getElementById(allTabSetIds[i] + "_tab" + tabCount) != null)
                  tabCount++;
  
              tabCount--;
  
              // If not grouped, skip it
              if(tabCount > 1)
                  SetCurrentLanguage(allTabSetIds[i], language, tabCount);
          }
  
          i++;
      }
  }
  
  // Sets the current language in the specified tab set
  function SetCurrentLanguage(tabSetId, language, tabCount)
  {
      var tabIndex = 1;
  
      while(tabIndex <= tabCount)
      {
          var tabTemp = document.getElementById(tabSetId + "_tab" + tabIndex);
  
          if(tabTemp != null && tabTemp.innerHTML.indexOf("'" + language + "'") != -1)
              break;
  
          tabIndex++;
      }
  
      if(tabIndex > tabCount)
      {
          // Select the first non-disabled tab
          tabIndex = 1;
  
          if(document.getElementById(tabSetId + "_tab1").className.indexOf("OH_CodeSnippetContainerTabDisabled") != -1)
          {
              tabIndex++;
  
              while(tabIndex <= tabCount)
              {
                  var tab = document.getElementById(tabSetId + "_tab" + tabIndex);
  
                  if(tab.className.indexOf("OH_CodeSnippetContainerTabDisabled") == -1)
                  {
                      tab.className = "OH_CodeSnippetContainerTabActiveNotFirst";
                      document.getElementById(tabSetId + "_code_Div" + j).style.display = "block";
                      break;
                  }
  
                  tabIndex++;
              }
  
              // Disable left most image if first tab is disabled
              document.getElementById(tabSetId + "_tabimgleft").className = "OH_CodeSnippetContainerTabLeftDisabled";
          }
      }
  
      SetActiveTab(tabSetId, tabIndex, tabCount);
  
      // Disable right most image if last tab is disabled
      if(document.getElementById(tabSetId + "_tab" + tabCount).className.indexOf("OH_CodeSnippetContainerTabDisabled") != -1)
          document.getElementById(tabSetId + "_tabimgright").className = "OH_CodeSnippetContainerTabRightDisabled";
  }
  
  // Set the active tab within a tab set
  function SetActiveTab(tabSetId, tabIndex, tabCount)
  {
      var i = 1;
  
      while(i <= tabCount)
      {
          var tabTemp = document.getElementById(tabSetId + "_tab" + i);
  
          if(tabTemp.className == "OH_CodeSnippetContainerTabActive")
              tabTemp.className = "OH_CodeSnippetContainerTabFirst";
          else
              if(tabTemp.className == "OH_CodeSnippetContainerTabActiveNotFirst")
                  tabTemp.className = "OH_CodeSnippetContainerTab";
              else
                  if(tabTemp.className.indexOf("OH_CodeSnippetContainerTabDisabled") != -1)
                  {
                      tabTemp.firstChild.style.color = "#a8a8a8";
                      tabTemp.firstChild.style.fontWeight = "normal";
                  }
  
          var codeTemp = document.getElementById(tabSetId + "_code_Div" + i);
  
          if(codeTemp.style.display != "none")
              codeTemp.style.display = "none";
  
          i++;
      }
  
      if(document.getElementById(tabSetId + "_tab" + tabIndex).className.indexOf("OH_CodeSnippetContainerTabDisabled") == -1)
      {
          if(tabIndex == 1)
              document.getElementById(tabSetId + "_tab" + tabIndex).className = "OH_CodeSnippetContainerTabActive";
          else
              document.getElementById(tabSetId + "_tab" + tabIndex).className = "OH_CodeSnippetContainerTabActiveNotFirst";
      }
      else
      {
          document.getElementById(tabSetId + "_tab" + tabIndex).firstChild.style.color = "black";
          document.getElementById(tabSetId + "_tab" + tabIndex).firstChild.style.fontWeight = "bold";
      }
  
      document.getElementById(tabSetId + "_code_Div" + tabIndex).style.display = "block";
  
      // Change the CSS of the first/last image div according the currently selected tab
      if(tabIndex == 1 && document.getElementById(tabSetId + "_tab" + tabIndex).className.indexOf("OH_CodeSnippetContainerTabDisabled") == -1)
          document.getElementById(tabSetId + "_tabimgleft").className = "OH_CodeSnippetContainerTabLeftActive";
      else
          if(document.getElementById(tabSetId + "_tabimgleft").className != "OH_CodeSnippetContainerTabLeftDisabled")
              document.getElementById(tabSetId + "_tabimgleft").className = "OH_CodeSnippetContainerTabLeft";
  
      if(tabIndex == tabCount && document.getElementById(tabSetId + "_tab" + tabIndex).className.indexOf("OH_CodeSnippetContainerTabDisabled") == -1)
          document.getElementById(tabSetId + "_tabimgright").className = "OH_CodeSnippetContainerTabRightActive";
      else
          if(document.getElementById(tabSetId + "_tabimgright").className != "OH_CodeSnippetContainerTabRightDisabled")
              document.getElementById(tabSetId + "_tabimgright").className = "OH_CodeSnippetContainerTabRight";
  }
  
  // Copy the code from the active tab of the given tab set to the clipboard
  function CopyToClipboard(tabSetId)
  {
      var tabTemp, contentId;
      var i = 1;
  
      if(typeof (Clipboard) == "function")
          return;
  
      do
      {
          contentId = tabSetId + "_code_Div" + i;
          tabTemp = document.getElementById(contentId);
  
          if(tabTemp != null && tabTemp.style.display != "none")
              break;
  
          i++;
  
      } while(tabTemp != null);
  
      if(tabTemp == null)
          return;
  
      if(window.clipboardData)
      {
          try
          {
              window.clipboardData.setData("Text", document.getElementById(contentId).innerText);
          }
          catch(e)
          {
              alert("Permission denied. Enable copying to the clipboard.");
          }
      }
      else if(window.netscape)
      {
          try
          {
              netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  
              var clip = Components.classes["@mozilla.org/widget/clipboard;1"].createInstance(
                  Components.interfaces.nsIClipboard);
  
              if(!clip)
                  return;
  
              var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(
                  Components.interfaces.nsITransferable);
  
              if(!trans)
                  return;
  
              trans.addDataFlavor("text/unicode");
  
              var str = new Object();
              var len = new Object();
              var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(
                  Components.interfaces.nsISupportsString);
  
              var copytext = document.getElementById(contentId).textContent;
  
              str.data = copytext;
              trans.setTransferData("text/unicode", str, copytext.length * 2);
  
              var clipid = Components.interfaces.nsIClipboard;
  
              clip.setData(trans, null, clipid.kGlobalClipboard);
          }
          catch(e)
          {
              alert("Permission denied. Enter \"about:config\" in the address bar and double-click the \"signed.applets.codebase_principal_support\" setting to enable copying to the clipboard.");
          }
      }
  }
  
  // Help 1 persistence object.  This requires a hidden input element on the page with a class of "userDataStyle"
  // defined in the style sheet that implements the user data binary behavior:
  // <input type="hidden" id="userDataCache" class="userDataStyle" />
  var Help1Globals =
  {
      UserDataCache: function()
      {
          var userData = document.getElementById("userDataCache");
  
          return userData;
      },
  
      Load: function(key)
      {
          var userData = this.UserDataCache();
  
          userData.load("userDataSettings");
  
          var value = userData.getAttribute(key);
  
          return value;
      },
  
      Save: function(key, value)
      {
          var userData = this.UserDataCache();
          userData.setAttribute(key, value);
          userData.save("userDataSettings");
      }
  };
  