// 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 < 2) { // Disable the Copy Code link if in Chrome if(navigator.userAgent.toLowerCase().indexOf("chrome") != -1) document.getElementById(allTabSetIds[i] + "_copyCode").style.display = "none"; } else 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]; } // Add a language tab set ID function AddLanguageTabSet(tabSetId) { allTabSetIds.push(tabSetId); } // 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"; // Show copy code button if not in Chrome if(navigator.userAgent.toLowerCase().indexOf("chrome") == -1) document.getElementById(tabSetId + "_copyCode").style.display = "inline"; else document.getElementById(tabSetId + "_copyCode").style.display = "none"; } // Copy the code from the active tab of the given tab set to the clipboard function CopyToClipboard(tabSetId) { var tabTemp, contentId; var i = 1; 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: // 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"); } };