﻿// ###############################################################################################
// LmkCrossBrowserJsUtils
//
// ONLY ADD CONTENT HERE IF TESTED AT LEAST ON: IE6, IE7, Safari XP, FF2, FF3
// MENTION IF NOT TESTED YET ON: Safari Mac, Opera
//
// ###############################################################################################

// ###############################################################################################
//                                      GENERAL / DOM
// ###############################################################################################
// **************************************************
// function lmk_GetElementId
// Summary : same as getElementById but working on all browsers
// Tested on: IE6, IE7, FF2, FF3, Safari XP (still missing Safari Mac and Opera)
// Author: Olivier Berthelier
// **************************************************
// References : http://www.javascripttoolbox.com/lib/objectposition/examples.php
function lmk_GetElementById(s) {
    if (document.getElementById && document.getElementById(s) != null) {
        return document.getElementById(s);
    }
    else if (document.all && document.all[s] != null) {
        return document.all[s];
    }
    else if (document.anchors && document.anchors.length && document.anchors.length > 0 && document.anchors[0].x) {
        for (var i = 0; i < document.anchors.length; i++) {
            if (document.anchors[i].name == s) {
                return document.anchors[i]
            }
        }
    }
}
// **************************************************
// function lmk_GetChildElementsByAttribute
// Summary : Returns an array of elements under oElm matching:
//          -sTagName: 'div', 'span', etc.
//          -sAttributeName : 'name', 'style', 'class'
//          -sAttributeValuePattern : '.*background-color:(red|black);' (case insensitive regexp)
// Usage : var arr = lmk_GetChildElementsByAttribute(document, 'div', 'style', '.*background-color:(red|black);') 
// Tested on: IE6(Xenocode), IE7, FF3, Safari 3.2.1(Xenocode)
// Author: Olivier Berthelier
// **************************************************
function lmk_GetChildElementsByAttribute(oElm, sTagName, sAttributeName, sAttributeValuePattern) {
    var aElements = (sTagName == "*" && oElm.all) ? oElm.all : oElm.getElementsByTagName(sTagName);
    var aReturnElements = new Array();
    var oAttributeValue = (typeof sAttributeValuePattern != "undefined") ? new RegExp("(^|\\s)" + sAttributeValuePattern + "(\\s|$)", "i") : null;
    var oCurrent;
    var oAttribute;
    for (var i = 0; i < aElements.length; i++) {
        oCurrent = aElements[i];
        oAttribute = oCurrent.getAttribute && oCurrent.getAttribute(sAttributeName);
        if (typeof oAttribute == "string" && oAttribute.length > 0) {
            if (typeof sAttributeValuePattern == "undefined" || (oAttributeValue && oAttributeValue.test(oAttribute))) {
                aReturnElements.push(oCurrent);
            }
        }
    }
    return aReturnElements;
}
// **************************************************
// function lmk_GetElementsByAttribute
// Summary : Same as lmk_GetChildElementsByAttribute with oElm = document
// Tested on: IE6(Xenocode), IE7, FF3, Safari 3.2.1(Xenocode)
// Author: Olivier Berthelier
// **************************************************
function lmk_GetElementsByAttribute(sTagName, sAttributeName, sAttributeValuePattern) {
    return lmk_GetChildElementsByAttribute(document, sTagName, sAttributeName, sAttributeValuePattern);
}
// **************************************************
// function lmk_GetChildElementByAttribute
// Summary : Same as lmk_GetChildElementsByAttribute but directly returns the first element matched
// Tested on: IE6(Xenocode), IE7, FF3, Safari 3.2.1(Xenocode)
// Author: Olivier Berthelier
// **************************************************
function lmk_GetChildElementByAttribute(oElm, sTagName, sAttributeName, sAttributeValuePattern) {
    var aResult = lmk_GetChildElementsByAttribute(oElm, sTagName, sAttributeName, sAttributeValuePattern);
    if (aResult[0])
        return aResult[0];
    else
        return null;
}
// **************************************************
// function lmk_GetElementByAttribute
// Summary : Same as lmk_GetChildElementByAttribute with oElm = document
// Tested on: IE6(Xenocode), IE7, FF3, Safari 3.2.1(Xenocode)
// Author: Olivier Berthelier
// **************************************************
function lmk_GetElementByAttribute(sTagName, sAttributeName, sAttributeValuePattern) {
    return lmk_GetChildElementByAttribute(document, sTagName, sAttributeName, sAttributeValuePattern);
}
// **************************************************
// function lmk_Replace(oElm, sRegExPattern, sReplacePattern)
// Summary : provides regexp replacement in given node innerHTML 
// Tested on: IE6(Xenocode), IE7, FF3, Safari 3.2.1(Xenocode)
// Author: Olivier Berthelier
// **************************************************
function lmk_Replace(oElm, sRegExPattern, sReplacePattern) {
    oElm.innerHTML = oElm.innerHTML.replace(sRegExPattern, sReplacePattern);
}
// ###############################################################################################
//                                      POSITIONNING
// ###############################################################################################

// **************************************************
// Object lmk_Position
// Summary : Get and Set the position of a dom element
// Tested on: IE6, IE7, FF2, FF3, Safari XP (still missing Safari Mac and Opera)
// Author: Olivier Berthelier
// **************************************************
// References : http://www.javascripttoolbox.com/lib/objectposition/examples.php
// Example :
//  var pos = lmk_Position.get('myElementId');
//  lmk_Position.set('myOtherElementIdToPosition', pos);
var lmk_Position = (function() {
    var pos = {};
    pos.$VERSION = 1.0;
    // Set the position of an object
    // =============================
    pos.set = function(o, left, top) {
        if (typeof (o) == "string") {
            o = lmk_GetElementById(o);
        }
        if (o == null || !o.style) {
            return false;
        }
        // If the second parameter is an object, it is assumed to be the result of getPosition()
        if (typeof (left) == "object") {
            var pos = left;
            left = pos.left;
            top = pos.top;
        }
        o.style.left = left + "px";
        o.style.top = top + "px";
        return true;
    };
    // Retrieve the position and size of an object
    // ===========================================
    pos.get = function(o) {
        var fixBrowserQuirks = true;
        // If a string is passed in instead of an object ref, resolve it
        if (typeof (o) == "string") {
            o = lmk_GetElementById(o);
        }
        if (o == null) {
            return null;
        }
        var left = 0;
        var top = 0;
        var width = 0;
        var height = 0;
        var parentNode = null;
        var offsetParent = null;
        offsetParent = o.offsetParent;
        var originalObject = o;
        var el = o; // "el" will be nodes as we walk up, "o" will be saved for offsetParent references
        while (el.parentNode != null) {
            el = el.parentNode;
            if (el.offsetParent == null) {
            }
            else {
                var considerScroll = true;
                /*
                In Opera, if parentNode of the first object is scrollable, then offsetLeft/offsetTop already 
                take its scroll position into account. If elements further up the chain are scrollable, their 
                scroll offsets still need to be added in. And for some reason, TR nodes have a scrolltop value
                which must be ignored.
                */
                if (fixBrowserQuirks && window.opera) {
                    if (el == originalObject.parentNode || el.nodeName == "TR") {
                        considerScroll = false;
                    }
                }
                if (considerScroll) {
                    if (el.scrollTop && el.scrollTop > 0) {
                        top -= el.scrollTop;
                    }
                    if (el.scrollLeft && el.scrollLeft > 0) {
                        left -= el.scrollLeft;
                    }
                }
            }
            // If this node is also the offsetParent, add on the offsets and reset to the new offsetParent
            if (el == offsetParent) {
                left += o.offsetLeft;
                if (el.clientLeft && el.nodeName != "TABLE") {
                    left += el.clientLeft;
                }
                top += o.offsetTop;
                if (el.clientTop && el.nodeName != "TABLE") {
                    top += el.clientTop;
                }
                o = el;
                if (o.offsetParent == null) {
                    if (o.offsetLeft) {
                        left += o.offsetLeft;
                    }
                    if (o.offsetTop) {
                        top += o.offsetTop;
                    }
                }
                offsetParent = o.offsetParent;
            }
        }
        if (originalObject.offsetWidth) {
            width = originalObject.offsetWidth;
        }
        if (originalObject.offsetHeight) {
            height = originalObject.offsetHeight;
        }
        return { 'left': left, 'top': top, 'width': width, 'height': height
        };
    };
    // Retrieve the position of an object's center point
    // =================================================
    pos.getCenter = function(o) {
        var c = this.get(o);
        if (c == null) { return null; }
        c.left = c.left + (c.width / 2);
        c.top = c.top + (c.height / 2);
        return c;
    };
    return pos;
})();
// **************************************************
// function lmk_CenterElement(oElmId)
// Summary : position an element at the center of the window (absolute) 
// Tested on: IE6(Xenocode), IE7, FF3, Safari 3.2.1(Xenocode)
// Author: Antoine Asfar
// **************************************************
function lmk_CenterElement(oElm) {
    // If a string is passed in instead of an object ref, resolve it
    if (typeof (oElm) == "string") {
        oElm = lmk_GetElementById(oElm);
    }
    if (oElm == null) {
        return null;
    }
    oElm.style.position = 'absolute';
    oElm.style.top = '50%';
    oElm.style.left = '50%';
    oElm.style.marginTop = '-' + (oElm.clientHeight / 2) + 'px';
    oElm.style.marginLeft = '-' + (oElm.clientWidth / 2) + 'px';
}
// ###############################################################################################
//                                      FLASH
// ###############################################################################################
// **************************************************
// Function lmk_FixFlashWmode
// Summary : Browse dom to change wmode to opaque
// Tested on: IE6, IE7, FF3
// Author: Olivier Berthelier
// **************************************************
function lmk_FixFlashWmode() {
    
    // Process embed nodes first (order is important for IE)
    var arrTag = document.getElementsByTagName("embed");
    for (var i = 0; i < arrTag.length; i++) {
        var tag = arrTag[i];
        var span = document.createElement('span'); // does not work with div container...
        tag.parentNode.replaceChild(span, tag);
        span.appendChild(tag);
        var strHTML = span.innerHTML;
        if (strHTML.search(/<embed[^>]*(?:(?:transparent)|(?:opaque))/ig) == -1) { // wmode is either not set or different than transparent/opaque
            if (strHTML.search(/<embed[^>]*wmode\s*=/ig) != -1) { // wmode set to 'window' or empty
                strHTML = strHTML.replace(/(<embed[^>]*wmode\s*=\s*)[^\s>]*/ig, "$1'opaque'");
            }
            else {
                strHTML = strHTML.replace(/(<embed)/ig, "$1 wmode='opaque'"); // wmode missing
            }
            span.innerHTML = strHTML;
        }
    }
    
    // Process object nodes
    arrTag = document.getElementsByTagName("object");
    for (var i = 0; i < arrTag.length; i++) {
        var tag = arrTag[i];
        var span = document.createElement('span');
        tag.parentNode.replaceChild(span, tag);
        span.appendChild(tag);
        var strHTML = span.innerHTML;
        if (strHTML.search(/<param[^>]*(?:transparent)|(?:opaque)/ig) == -1) { // wmode is either not set or different than transparent/opaque
            if (strHTML.search(/<param[^>]*name\s*=[^=]*wmode/ig) != -1) { // wmode set to 'window' or empty
                strHTML = strHTML.replace(/(<param[^>]*name\s*=[^=]*wmode[^=]*=\s*)[^\s>]*/ig, "$1'opaque'");
            }
            else {
                strHTML = strHTML.replace(/(<\/object[^>]*)/ig, "<param value=\"opaque\" name=\"wmode\">$1"); // += "<param value=\"opaque\" name=\"wmode\">";
            }
            span.innerHTML = strHTML;
        }
    }
}
// ###############################################################################################
//                                      AJAX FUNCTIONS
// ###############################################################################################
// **************************************************
// Function lmk_AjaxGetXmlHttpObject
// Summary : Return a new XmlHttpObject
// Tested on: IE6 (virtual machine XP), IE7, FF3, Safari 3.2.1 (Xenocode), Chrome
// Author: Olivier Berthelier
// **************************************************
function lmk_AjaxGetXmlHttpObject() {
    var xmlHttp = null;
    try {
        // Firefox, Opera 8.0+, Safari
        xmlHttp = new XMLHttpRequest();
    }
    catch (e) {
        // Internet Explorer
        try {
            xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
        }
        catch (e) {
            xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
    }
    return xmlHttp;
}
// **************************************************
// Function lmk_AjaxSendContentAsynchronously
// Summary : Send "content" (set to null if method = get) to "url" via "method" (get or post). Response will be
//           processed asynchronously by a "processFunction = function(responseTest){...}"
// Tested on: IE6 (virtual machine XP), IE7, FF3, Safari 3.2.1 (Xenocode), Chrome
// Author: Olivier Berthelier
// **************************************************
function lmk_AjaxSendContentAsynchronously(content, url, method, processFunction) {
    var xmlHttp = lmk_AjaxGetXmlHttpObject();
    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
            return processFunction(xmlHttp.responseText);
        }
        return null;
    }
    xmlHttp.open(method, url, true);
    xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlHttp.setRequestHeader("Connection", "close");
    xmlHttp.send(content);
    alert(xmlHttp.status);
}
// **************************************************
// Function lmk_AjaxSendContentSynchronously
// Summary : Send "content" to "url" via "method" (get or post).
//           returns responseText 
// Tested on: IE6 (virtual machine XP), IE7, FF3, Safari 3.2.1 (Xenocode), Chrome
// Author: Olivier Berthelier
// **************************************************
function lmk_AjaxSendContentSynchronously(content, url, method) {
    var xmlHttp = lmk_AjaxGetXmlHttpObject();
    xmlHttp.open(method, url, false);
    xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xmlHttp.setRequestHeader("Connection", "close");
    xmlHttp.send(content);
    return xmlHttp.responseText;
}
// **************************************************
// Function lmk_AjaxSetFlag
// Summary : Use Ajax to update user navigationContext 
// Tested on: IE6 (virtual machine XP), IE7, FF3, Safari 3.2.1 (Xenocode), Chrome
// Author: Olivier Berthelier
// **************************************************
var LMK_AJAX_HANDLER_URL = "/LmkAjax";

function lmk_AjaxSetFlag(flagName, contextKey) {
    return lmk_AjaxSendContentSynchronously("action=setflag&flag=" + flagName + "&contextKey=" + contextKey, LMK_AJAX_HANDLER_URL, "post");
}
// **************************************************
// Function lmk_AjaxRemoveFlag
// Summary : Use Ajax to update user navigationContext 
// Tested on: IE6 (virtual machine XP), IE7, FF3, Safari 3.2.1 (Xenocode), Chrome
// Author: Olivier Berthelier
// **************************************************
function lmk_AjaxRemoveFlag(flagName, contextKey) {
    return lmk_AjaxSendContentSynchronously("action=removeflag&flag=" + flagName + "&contextKey=" + contextKey, LMK_AJAX_HANDLER_URL, "post");
}
// **************************************************
// Function lmk_AjaxSetLmkPaymentSelected
// Summary : Use Ajax to flag LmkPaymentSelected
// Tested on: IE6 (virtual machine XP), IE7, FF3, Safari 3.2.1 (Xenocode), Chrome
// Author: Olivier Berthelier
// **************************************************
function lmk_AjaxSetLmkPaymentSelected() {
    lmk_AjaxSetFlag("IsLmkPaymentSelected", "ShopNameID");
}

// **************************************************
// Function lmk_AjaxRemoveLmkPaymentSelected
// Summary : Use Ajax to update user navigationContext 
// Tested on: IE6 (virtual machine XP), IE7, FF3, Safari 3.2.1 (Xenocode), Chrome
// Author: Olivier Berthelier
// **************************************************
function lmk_AjaxRemoveLmkPaymentSelected() {
    lmk_AjaxRemoveFlag("IsLmkPaymentSelected", "ShopNameID");
}

// ###############################################################################################
//                                      MISC FUNCTIONS
// ###############################################################################################
// **************************************************
// Function lmk_RewriteLinks
// Summary : Process DOM to rewrite links that might not have been rewritten successfully by JsProcessor
// Tested on: IE6, IE7, IE8, FF3, Chrome
// Author: Olivier Berthelier
// **************************************************
function lmk_RewriteLinks() {
    /* Constants that must have been inserted by proxy
        
    LMK_REGEXP_ANY_SUBDOMAIN = "[a-z0-9_\\.\\-]+";
    LMK_REGEXP_ANY_DOMAIN = "[a-z0-9_\\-]+\\.[a-z]+";
    LMK_TARGET_DOMAIN = "cartelire.com";
    LMK_PROXY_DOMAIN = "limonetikdev1.com";
    LMK_ISSUER_ROOT = "proxy.limonetikdev.com";
    LMK_HANDLER_DOMAIN_KEY = "LmkDomain";
    */

    // Regular Expressions definition

    // http://www.fnac.com/blabla to http://www.limonetik5.com/blabla
    var lmk_RegExp1 = new RegExp("(http://(?:" + LMK_REGEXP_ANY_SUBDOMAIN + "\\.)?)" + LMK_TARGET_DOMAIN + "\\b", "gi");
    var lmk_Replace1 = "$1" + LMK_PROXY_DOMAIN;

    // https://www.fnac.com/blabla or https://www.amazon.com/blabla to https://proxy.limonetik.com/LmkDomain/www.fnac.com/blabla
    var lmk_RegExp2 = new RegExp("https://", "gi");
    var lmk_Replace2 = "https://" + LMK_ISSUER_ROOT + "/" + LMK_HANDLER_DOMAIN_KEY + "/";

    //http://www.amazon.com/blabla to http://proxy.limonetik.com/LmkDomain/www.amazon.com/blabla
    var lmk_RegExp3 = new RegExp("http://(?=(?:" + LMK_REGEXP_ANY_SUBDOMAIN + "\\.)?(?!" + LMK_PROXY_DOMAIN + "|" + LMK_TARGET_DOMAIN + ")" + LMK_REGEXP_ANY_DOMAIN + ")", "gi");
    var lmk_Replace3 = "http://" + LMK_ISSUER_ROOT + "/" + LMK_HANDLER_DOMAIN_KEY + "/";

    // Get all links in DOM
    var links = document.getElementsByTagName("a");

    // Rewrite links
    for (var i = 0; i < links.length; i++) {

        if (links[i].href.match(lmk_RegExp1)) {
            links[i].href = links[i].href.replace(lmk_RegExp1, lmk_Replace1);
        }
        else if (links[i].href.match(lmk_RegExp2)) {
            links[i].href = links[i].href.replace(lmk_RegExp2, lmk_Replace2);
        }
        else if (links[i].href.match(lmk_RegExp3)) {
            links[i].href = links[i].href.replace(lmk_RegExp3, lmk_Replace3);
        }

    }

}

/* Proxify string content */

function lmk_ProxifyString(contentToProxify) {

/* must have been inserted by proxy
    LMK_REGEXP_ANY_SUBDOMAIN = "[a-z0-9_\\.\\-]+";

    LMK_REGEXP_ANY_DOMAIN = "[a-z0-9_\\-]+\\.[a-z]+";

    LMK_TARGET_DOMAIN = "norrisdata.net";

    LMK_PROXY_DOMAIN = "limonetikdev4.com";

    LMK_ISSUER_ROOT = "proxy.limonetikdev.com";

    LMK_HANDLER_DOMAIN_KEY = "LmkDomain";
*/
    // Regular Expressions definition



    // http://www.fnac.com/blabla to http://www.limonetik5.com/blabla

    var lmk_RegExp1 = new RegExp("(http://(?:" + LMK_REGEXP_ANY_SUBDOMAIN + "\\.)?)" + LMK_TARGET_DOMAIN + "\\b", "gi");

    var lmk_Replace1 = "$1" + LMK_PROXY_DOMAIN;



    // https://www.fnac.com/blabla or https://www.amazon.com/blabla to https://proxy.limonetik.com/LmkDomain/www.fnac.com/blabla

    var lmk_RegExp2 = new RegExp("https://", "gi");

    var lmk_Replace2 = "https://" + LMK_ISSUER_ROOT + "/" + LMK_HANDLER_DOMAIN_KEY + "/";



    //http://www.amazon.com/blabla to http://proxy.limonetik.com/LmkDomain/www.amazon.com/blabla

    var lmk_RegExp3 = new RegExp("http://(?=(?:" + LMK_REGEXP_ANY_SUBDOMAIN + "\\.)?(?!" + LMK_PROXY_DOMAIN + "|" + LMK_TARGET_DOMAIN + ")" + LMK_REGEXP_ANY_DOMAIN + ")", "gi");

    var lmk_Replace3 = "http://" + LMK_ISSUER_ROOT + "/" + LMK_HANDLER_DOMAIN_KEY + "/";

    if (contentToProxify.match(lmk_RegExp1)) {
        contentToProxify = contentToProxify.replace(lmk_RegExp1, lmk_Replace1);
    }

    if (contentToProxify.match(lmk_RegExp2)) {
        contentToProxify = contentToProxify.replace(lmk_RegExp2, lmk_Replace2);
    }

    if (contentToProxify.match(lmk_RegExp3)) {
        contentToProxify = contentToProxify.replace(lmk_RegExp3, lmk_Replace3);
    }

    return contentToProxify;
}