var icApplicationUrl = "https://secure.logmeinrescue.com/"; var bIsLiveSite = true; // nolint var ICLoader = null; // Default websessionID length var webSessionIdLength = 24; function RescueInstantChatLoader() { var msp = null; var mspcounter = 0; var windtitle = ""; var windblinkingvar = null; // this was the original code for creating the iframe's src url // (instant chat url with everything passed as GET parameters, // but it may exceed 2k, so we have to create a new POST version using a dummy form) var createIframeSrc = function (icApplicationUrl, encodedLocation) { // {{{ var content = icApplicationUrl + "InstantChat/HTMLEngine.aspx?"; content += "origin=" + encodeURIComponent2(window.location.protocol + "//" + window.location.host) + "&"; content += ((getParameter("rescuewebsessionid") != "") ? "rescuewebsessionid=" + encodeURIComponent2(getParameter("rescuewebsessionid")) + "&" : ""); content += ICLoader.ApplicationID ? "appid=" + encodeURIComponent2(ICLoader.ApplicationID) + "&" : ""; content += ((ICLoader.HostedCSS != null) ? "HostedCSS=" + encodeURIComponent2(ICLoader.HostedCSS) + "&" : ""); content += ((ICLoader.HostedLanguagesForChatOnlyMode != null) ? "HostedLanguagesForChatOnlyMode=" + encodeURIComponent2(ICLoader.HostedLanguagesForChatOnlyMode) + "&" : ""); content += ((ICLoader.HostedLanguagesForAppletMode != null) ? "HostedLanguagesForAppletMode=" + encodeURIComponent2(ICLoader.HostedLanguagesForAppletMode) + "&" : ""); content += ((ICLoader.PageTitle != null) ? "PageTitle=" + encodeURIComponent2(ICLoader.PageTitle) + "&" : ""); content += ((ICLoader.EntryID != null) ? "EntryID=" + encodeURIComponent2(ICLoader.EntryID) + "&" : ""); content += ((ICLoader.ChannelName != null) ? "ChannelName=" + encodeURIComponent2(ICLoader.ChannelName) + "&" : ""); content += ((ICLoader.CompanyID != null) ? "CompanyID=" + encodeURIComponent2(ICLoader.CompanyID) + "&" : ""); content += ((ICLoader.PrivateCode != null) ? "PrivateCode=" + encodeURIComponent2(ICLoader.PrivateCode) + "&" : ""); content += ((ICLoader.Name != null) ? "name=" + encodeURIComponent2(ICLoader.Name.replace(/\r/g, "").replace(/\n/g, " ")) + "&" : ""); content += ((ICLoader.Comment1 != null) ? "comment1=" + encodeURIComponent2(ICLoader.Comment1.replace(/\r/g, "").replace(/\n/g, " ")) + "&" : ""); content += ((ICLoader.Comment2 != null) ? "comment2=" + encodeURIComponent2(ICLoader.Comment2.replace(/\r/g, "").replace(/\n/g, " ")) + "&" : ""); content += ((ICLoader.Comment3 != null) ? "comment3=" + encodeURIComponent2(ICLoader.Comment3.replace(/\r/g, "").replace(/\n/g, " ")) + "&" : ""); content += ((ICLoader.Comment4 != null) ? "comment4=" + encodeURIComponent2(ICLoader.Comment4.replace(/\r/g, "").replace(/\n/g, " ")) + "&" : ""); content += ((ICLoader.Comment5 != null) ? "comment5=" + encodeURIComponent2(ICLoader.Comment5.replace(/\r/g, "").replace(/\n/g, " ")) + "&" : ""); content += ((ICLoader.Tracking0 != null) ? "tracking0=" + encodeURIComponent2(ICLoader.Tracking0) + "&" : ""); content += ((ICLoader.Language != null) ? "language=" + encodeURIComponent2(ICLoader.Language) + "&" : ""); content += ((ICLoader.PostMessageTargetOrigin != null) ? "postMessageTargetOrigin=" + encodeURIComponent2(ICLoader.PostMessageTargetOrigin) + "&" : ""); content += ((encodedLocation.toLowerCase().indexOf("rescuedebug=1") != -1) ? "rescuedebug=1" : ""); content += ((encodedLocation.toLowerCase().indexOf("rescuedebug=2") != -1) ? "rescuedebug=2" : ""); content += ((encodedLocation.toLowerCase().indexOf("rescuedebug=3") != -1) ? "rescuedebug=3" : ""); content += "#" + encodedLocation; return content; }; // }}} // create a fake form and fake fields, set it to POST and set // the target to the iframe. This shall replace the scary jugnle seen above var createFakeForm = function (icApplicationUrl, encodedLocation, doPost) { // {{{ var form, addField, formUrl, submitButton, icLoaderWhitelist, target, i, l, val; // remove junk from dom (since this whole code may be // called multiple times via "loadInstantChat") form = document.getElementById("PostProxyForm"); if (form) { form.parentNode.removeChild(form); } // use _blank for debugging without the iframe target = "ic_mainframe"; // fields to iterate through (just to be careful) icLoaderWhitelist = ["HostedCSS", "HostedLanguagesForChatOnlyMode", "HostedLanguagesForAppletMode", "PageTitle", "EntryID", "ChannelName", "CompanyID", "PrivateCode", "Name", "Comment1", "Comment2", "Comment3", "Comment4", "Comment5", "Tracking0", "Language", "PostMessageTargetOrigin"]; // create an input field createField = function (appendTo, name, val) { // {{{ var input = document.createElement("INPUT"); input.setAttribute("name", name); input.setAttribute("value", val); if (appendTo) { appendTo.appendChild(input); } return input; }; // }}} formUrl = icApplicationUrl + "InstantChat/HTMLEngine.aspx#" + encodedLocation; // create helper form form = document.createElement("FORM"); form.setAttribute("id", "PostProxyForm"); form.setAttribute("action", formUrl); form.setAttribute("method", "POST"); form.setAttribute("target", target); // ------------------------------- fields {{{ // origin createField(form, "origin", window.location.protocol + "//" + window.location.host); // rescuewebsessionid (from window.location) if (getParameter("rescuewebsessionid") != "") { createField(form, "rescuewebsessionid", getParameter("rescuewebsessionid")); } // ICLoader whitelsited properties for (i = 0, l = icLoaderWhitelist.length; i < l; i += 1) { val = ICLoader[icLoaderWhitelist[i]]; if (val != null && val != undefined && val !== "") { createField(form, icLoaderWhitelist[i], val); } } // rescuedebug=1, rescuedebug=2, rescuedebug=3 for (i = 1, l = 4; i < l; i += 1) { if (encodedLocation.indexOf("rescuedebug=" + i) > -1) { createField(form, "rescuedebug", i); } } // }}} fields ------------------------------- // input type submit is required submitButton = document.createElement("INPUT"); submitButton.setAttribute("type", "submit"); form.appendChild(submitButton); // comment this section out for debugging (display none will not work!) // do not combine it into one style tag, ie6 won't like that form.style.position = "absolute"; form.style.top = 0; form.style.left = 0; form.style.width = 0; form.style.height = 0; form.style.overflow = "hidden"; document.body.appendChild(form); // we must append, otherwise the submit will not work // force posting immediately if (doPost) { form.submit(); } }; // }}} // Start InstantChat Preloader this.Start = function () { // experimental: send using post var passParametersAsGET = true; // may be overridden via "ICLoader.TransferMethod" //if (typeof this.TransferMethod === "string" && this.TransferMethod.toLowerCase() === "post") { // passParametersAsGET = false; //} // okay, experimental or not, we need this; // please remove legacy GET mode when you're around and nothing broke with the POST one. passParametersAsGET = false; // Reload page with rescuewebsesisonid if (window.location.hash.length == webSessionIdLength + 1) { if ((window.location + "").indexOf("rescuewebsessionid") == -1) { var separator = "?"; if (window.location.search.length != 0) separator = "&"; window.location = removeBookmark(window.location + "") + separator + "rescuewebsessionid=" + window.location.hash.replace("#", ""); return; } else { window.location = (window.location + "").replace("rescuewebsessionid", "rescuewebsession2id"); return; } } ICLoader = this; // Check the obligatory parameters if (checkParameter(ICLoader.ICContainer, "ICContainer", true)) return; if (checkParameter(ICLoader.HostedCSS, "HostedCSS", false)) return; ICLoader.ICContainerDiv = document.getElementById(ICLoader.ICContainer); // Check the obligatory attributes if (ICLoader.ICContainerDiv.style.width == "") { alert('*** ENGINE ERROR ***\n\nMissing "style.width": "' + ICLoader.ICContainer + '"'); return; } if (ICLoader.ICContainerDiv.style.height == "") { alert('*** ENGINE ERROR ***\n\nMissing "style.height": "' + ICLoader.ICContainer + '"'); return; } // Hosted Instant Chat or not // iPod Touch, or any other iPod // iPhone // iPad // Palm Pre or Palm device with webOS // Android if (!(IsHostedInstance() || (!IsHostedInstance() && !AmIiPodTouch() && !AmIiPhone() && !AmIiPad() && !AmIPalmPre() && !AmIAndroid() && !AmIBB10()))) { // Generate an empty viewport var meta = document.createElement("meta"); meta.name = "viewport"; meta.id = "viewport"; // Disallow zooming + set default viewstate (for iPhone + iPod Touch) meta.content = "width=334; height=434; user-scalable=0;"; // Set default container size (for iPhone + iPod Touch) ICLoader.ICContainerDiv.style.width = "334px"; ICLoader.ICContainerDiv.style.height = "434px"; // iPhone 5 if (AmIiPhone5()) { ICLoader.ICContainerDiv.style.width = "334px"; // 70% of 640 ICLoader.ICContainerDiv.style.height = "462px"; // (70% of 1136) - safari header height // Disallow zooming meta.content = "initial-scale=0.96; user-scalable=0;"; } // iPad if (AmIiPad()) { ICLoader.ICContainerDiv.style.width = "538px"; // 70% of 768 ICLoader.ICContainerDiv.style.height = "663px"; // (70% of 1024) - safari header height // Disallow zooming meta.content = "width=device-with, user-scalable=no"; } // Palm Pre or Palm device with webOS if (AmIPalmPre()) { ICLoader.ICContainerDiv.style.width = "334px"; ICLoader.ICContainerDiv.style.height = "480px"; // Allow zooming meta.content = "width=334; height=480; user-scalable=yes;"; } // Android if (AmIAndroid()) { ICLoader.ICContainerDiv.style.width = "334px"; // Default ic size ICLoader.ICContainerDiv.style.height = "700px"; // Allow zooming meta.content = "width=334; height=700; user-scalable=yes;"; } // BB10 if (AmIBB10()) { ICLoader.ICContainerDiv.style.width = "334px"; // Default ic size ICLoader.ICContainerDiv.style.height = "700px"; // Allow zooming meta.content = "initial-scale=1; user-scalable=0;"; } // Apply viewstate document.getElementsByTagName("head").item(0).appendChild(meta); } if (ICLoader.PrivateCode != null) if (ICLoader.PrivateCode.length > 6) ICLoader.PrivateCode = ICLoader.PrivateCode.substring(0, 6); // Encode hasmark var encodedLocation = window.location + ""; encodedLocation = encodedLocation.replace("#", "-h-a-s-m1-a2-r5-k7-"); // Generate content (create innerHTML chunk) var content = ""; // Start to communicate with Client Engine msp = setInterval(GetMessagesFromClientEngine, 1000); // Add content ICLoader.ICContainerDiv.innerHTML = content; ICLoader.ICMainFrame = document.getElementById("ic_mainframe"); // this was the original functionality (we do it with replace, the less we have // an empty iframe fooling around in IE6 the better) if (passParametersAsGET) { ICLoader.ICMainFrame.setAttribute("src", createIframeSrc(icApplicationUrl, encodedLocation)); } else { createFakeForm(icApplicationUrl, encodedLocation, true); } //If postMessage is supported then send a message about the onbeforeunload event to the iframe. //This part is needed by Chrome and Safari (Webkit based browsers). See http://code.google.com/p/chromium/issues/detail?id=97206 for details. //Safari Mobile does not support onunload event, so we have to use onpagehide event instead. if (ICLoader.ICMainFrame.contentWindow.postMessage !== undefined) { if (IsiOSDevice()) { window.addEventListener("pagehide", function (e) { ICLoader.ICMainFrame.contentWindow.postMessage("unload", icApplicationUrl); }); } else if (navigator.userAgent.indexOf("WebKit/") !== -1) { window.onunload = function () { ICLoader.ICMainFrame.contentWindow.postMessage("unload", icApplicationUrl); }; } } }; // Set the position of main div this.centralizeGUI = function() { if (ICLoader != null) { // Hosted Instant Chat or not // iPod Touch, or any other iPod // iPhone // iPad // Palm Pre or Palm device with webOS // Android if (IsHostedInstance() || (!IsHostedInstance() && !AmIiPodTouch() && !AmIiPhone() && !AmIiPad() && !AmIPalmPre() && !AmIAndroid())) { if (!document.body.offsetWidth || document.body.offsetWidth == 0) { if ((parseInt(window.innerWidth) + 20) > parseInt(getLiveProperty(ICLoader.ICContainerDiv, "width"))) ICLoader.ICMainFrame.style.width = parseInt(window.innerWidth) + 20 + "px"; } else { if ((parseInt(document.body.offsetWidth) + 20) > parseInt(getLiveProperty(ICLoader.ICContainerDiv, "width"))) { if (navigator.userAgent.indexOf("MSIE 8") != -1 || navigator.userAgent.indexOf("MSIE 9") != -1) ICLoader.ICMainFrame.style.width = parseInt(document.body.offsetWidth) + 16 + "px"; else ICLoader.ICMainFrame.style.width = parseInt(document.body.offsetWidth) + 20 + "px"; } } if (document.documentElement.clientHeight) { if (parseInt(document.documentElement.clientHeight) > parseInt(getLiveProperty(ICLoader.ICContainerDiv, "height"))) ICLoader.ICMainFrame.style.height = parseInt(document.documentElement.clientHeight) + "px"; } } } } this.Unload = function() { //If postMessage is supported then send a message about the onbeforeunload event to the iframe. //This part is needed by Chrome and Safari (Webkit based browsers). See http://code.google.com/p/chromium/issues/detail?id=97206 for details. //Safari Mobile does not support onunload event, so we have to use onpagehide event instead. if (ICLoader.ICMainFrame.contentWindow.postMessage !== undefined) { if (IsiOSDevice() || navigator.userAgent.indexOf("WebKit/") !== -1) { ICLoader.ICMainFrame.contentWindow.postMessage("unload", icApplicationUrl); } else { var blankSrc = icApplicationUrl + "blank.html"; ICLoader.ICMainFrame.src = blankSrc; } } ICLoader.ICContainerDiv.style.display = "none"; setTimeout(function () { ICLoader.ICContainerDiv.removeChild(ICLoader.ICMainFrame); }, 2000); }; // Check the obligatory parameters function checkParameter(obj, name, type) { var returnValue = false; if (obj == null || !obj) { alert('*** ENGINE ERROR ***\n\nMissing object parameter: "' + name + '"'); returnValue = true; } else if (type && !document.getElementById(obj)) { alert('*** ENGINE ERROR ***\n\nMissing HTML element: "' + obj + '"'); returnValue = true; } return returnValue; } // Return QueryString parameter function getParameter(name) { name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); var regexS = "[\\?&]" + name + "=([^&#]*)"; var regex = new RegExp(regexS); var results = regex.exec(window.location.href); if (results == null) return ""; else return results[1]; } // Get actual property of style attribute function getLiveProperty(oObject, sProperty) { // 0px is the default value var sPropertyValue = "0px"; if (oObject.currentStyle) sPropertyValue = oObject.currentStyle[sProperty]; else if(window.getComputedStyle) { var oStyle = window.getComputedStyle(oObject, null); if (oStyle != null) sPropertyValue = oStyle.getPropertyValue(sProperty); } // E.g.: the return value is auto, then returns 0px, only for IE sessions if ((parseInt(sPropertyValue) + "").indexOf("NaN") != -1) sPropertyValue = "0px"; return sPropertyValue; } // Communicate with Client Engine function GetMessagesFromClientEngine() { mspcounter += 1; var tmpstr = window.location + ""; if (tmpstr.indexOf("#") != -1) { clearInterval(msp); if (ICLoader.HostedErrorHandler != null) { if ((tmpstr.substring(tmpstr.indexOf("#") + 1).indexOf("-del") == -1) && (tmpstr.substring(tmpstr.indexOf("#") + 1).length != webSessionIdLength)) { ICLoader.HostedErrorHandler(tmpstr.substring(tmpstr.indexOf("#") + 1)); if (tmpstr.substring(tmpstr.indexOf("#") + 1).length != webSessionIdLength) window.location = tmpstr + "-del"; } } } if (mspcounter > 60) clearInterval(msp); } function encodeURIComponent2(inputstr) { var str = encodeURIComponent(inputstr); str = decodeText3(str, "%25", "%"); str = decodeText3(str, "'", "%27"); return str; } // Remove bookmark function removeBookmark(url) { if (url.indexOf("#") != -1) return url.substring(0, url.indexOf("#")); else return url; } function decodeText3(text, first, second) { var stext = text; while (stext.indexOf(first) != -1) { stext = stext.replace(first, second); } return stext; } this.startBlinking = function(msgText) { if (windblinkingvar == null) windblinkingvar = setInterval(function() { document.title = ((document.title == msgText) ? windtitle : msgText); }, 300); } this.endBlinking = function() { if (windblinkingvar != null) { clearInterval(windblinkingvar); document.title = windtitle; windblinkingvar = null; } } this.setWindowTitle = function(docTitle) { document.title = docTitle; windtitle = docTitle; } // Hosted Instant Chat or not function IsHostedInstance() { // Under internal servers // Under Live servers, e.g.: LIVE, BETA, Enterprise, etc. return !IsUnderLiveServers(window.location + ""); } // Under Live servers, e.g.: LIVE, BETA, Enterprise, etc. function IsUnderLiveServers(sUrl) { if (sUrl.toLowerCase().indexOf("logmeinrescue") != -1) return true; else return false; } // Get user agent string function GetUserAgent() { if (navigator.userAgent) return navigator.userAgent; else return ""; } function IsiOSDevice() { var devices = ["iphone", "ipad", "ipod"]; for (var device in devices) { if (GetUserAgent().toLowerCase().indexOf(devices[device]) !== -1) { return true; } } return false; } // iPod Touch, or any other iPod function AmIiPodTouch() { // Get user agent string if (GetUserAgent().toLowerCase().indexOf("(ipod") != -1) return true; else return false; } // iPhone function AmIiPhone() { // Get user agent string if (GetUserAgent().toLowerCase().indexOf("(iphone") != -1) return true; else return false; } // iPhone 5 function AmIiPhone5() { // Get user agent string if ((GetUserAgent().toLowerCase().indexOf("iphone os 6_0") != -1) && (window.screen.height == 568)) return true; else return false; } // iPad function AmIiPad() { // Get user agent string if (GetUserAgent().toLowerCase().indexOf("(ipad") != -1) return true; else return false; } // Android function AmIAndroid() { // Get user agent string if (GetUserAgent().toLowerCase().indexOf("android") != -1) return true; else return false; } // Android function AmIBB10() { // Get user agent string if (GetUserAgent().toLowerCase().indexOf("bb10") != -1) return true; else return false; } // Palm Pre or Palm device with webOS function AmIPalmPre() { // Get user agent string if (GetUserAgent().toLowerCase().indexOf("webos") != -1 || GetUserAgent().toLowerCase().indexOf("hpwos") != -1) return true; else return false; } }