


	
	
		
			
			
				
	
	
	
		
		
		
	
	
	
	
	
	
	
	
	
	
	
		// Set container
window.scriptsLoaded = false; // reset for async loaded scripts
data = {"cipreview":false,"v2mode":true,"widgetid":"2170","ecardid":"","locale":"en","ecardMode":false,"chrchinContainerID":"ecardwidget_id_2170","ciExtraUrlParams":"locale=en","config":"","sitedomain":"https://app.ecardwidget.com","currentID":"2170"};
if(typeof window.widgetData == 'undefined') {
  window.widgetData = {};
}
window.widgetData[data.chrchinContainerID] = data;
console.log(2)
function loadScripts() {
  // Prevents us from loading everything more than once
  if(window.scriptsLoaded && !data.cipreview) {
    return;
  }

  setupIframeResizer();

  // Add missing wrapper
  $chjq('script[src*=".com/embed"]').each(function(i, el) {
    var $el = $chjq(el);
    // remove last slash
    var urlParts = $el.attr('src').split('?')[0];
    if (urlParts.charAt(urlParts.length - 1) == '/') {
      urlParts = urlParts.substr(0, urlParts.length - 1);
    }
    urlParts = urlParts.split('/');
    var paramID = urlParts[urlParts.length - 1];
    var chrchinContainerID = "ecardwidget_id_" + paramID;
    var data = window.widgetData[chrchinContainerID];
    if(!$chjq('#' + data.chrchinContainerID).length) {
      if($el.parent('head').length) {
        $chjq("body").prepend( "<div id='" + data.chrchinContainerID + "'></div>");
      } else {
        $el.after( "<div id='" + data.chrchinContainerID + "'></div>");
      }
    }
    $chjq('#' + data.chrchinContainerID).attr('style','min-height:4px;background:url('+data.sitedomain+'/assets/app/img/loading.gif); background-repeat: no-repeat; background-position: top center; background-position-y: 10px;');
  });
  $chjq("[id^=ecardwidget_id_]").each(function(i, el) {
    ciMainMethod(window.widgetData[el.getAttribute('id')]);
  });
  window.scriptsLoaded = true;
}

/* OUR CUSTOM APP */
function addCiJquery(callback) {
  console.log('addCiJquery')
  if (typeof window.$chjq == "undefined") {
    if (window.attachEvent && !window.addEventListener) {
      console.log("bad ie");;
      // "bad" IE
      var ascript = document.createElement("script");
      ascript.id = "chrchinResizer";

      ascript.setAttribute(
        "src",
        "https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/3.5.14/ie8.polyfils.min.js"
      );
      document.body.appendChild(ascript);
    }
    var script = document.createElement("script");
    script.id = "chrchinJquery";
    script.setAttribute(
      "src",
      "//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"
    );

    script.addEventListener(
      "load",
      function () {
        var script = document.createElement("script");
        script.onload = function() {
          loadScripts();
        }
        script.id = "chrchinScript";
        script.textContent =
          "window.$chjq=jQuery.noConflict(true);(" +
          loadScripts.toString() +
          ")();";
        document.body.appendChild(script);
      },
      false
    );
    document.body.appendChild(script);
  }
}

console.log(4)
// the guts of this userscript
function ciMainMethod(myData) {

  console.log('ciMainMethod')
  console.log(5)
  ciRandId = "x" + myData.chrchinContainerID;
  iOScheck = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
  iOScheck = false;
  ciUrlParams = "";

  if (myData.config) {
    ciUrlParams +=
      "&prevconfig=" +
      encodeURIComponent(JSON.stringify(myData.config)) +
      "&" +
      myData.ciExtraUrlParams;
  }
  if (myData.ecardid) ciUrlParams += "&ecardid=" + myData.ecardid;

  ciIframeHTML =
    '<iframe id="' +
    ciRandId +
    '_chrchin_iframe_widget" frameborder="0" src="' +
    myData.sitedomain +
    "/widgetly/" +
    myData.widgetid +
    "?" +
    ciUrlParams +
    '" width="100%" scrolling="no"></iframe>';
  console.log(ciIframeHTML);
  myData.ci_settings = {
    showWidget: true,
    buttonElement: "",
  };

  var $chjq = window.$chjq;
  if (myData.cipreview) {
    var div = document.createElement("div");
    div.id = "churchiniframeholster";
    div.innerHTML = ciIframeHTML;
    $chjq("#embedPrev").prepend(div);
    //$chjq('#embedPrev div:not(:last)').remove();
  }
  var backdropHTML =
    '<div id="' +
    ciRandId +
    '_chrchin_wrap" style="display: none;">' +
    '<div id="' +
    ciRandId +
    '_chrchin_container">' +
    '<img alt="Loading..." border="0" height="80" id="' +
    ciRandId +
    '_chrchin_unit_loading" src="' +
    myData.sitedomain +
    '/assets/img/ajax-loader.gif">' +
    '<div id="' +
    ciRandId +
    '_chrchin_unit"><iframe id="' +
    ciRandId +
    '_chrchin_iframe_modal" frameborder="0" scrolling="no" src="' +
    myData.sitedomain +
    "/assets/app/sendmodal.cfm?" +
    //window.location.search.replace("?", "") +
    "&locale=" +
    myData.locale +
    "&css=" +
    window.css +
    '"></iframe>' +
    '<div id="' +
    ciRandId +
    '_chrchin_close_btn" align="right">' +
    '<a href="javascript:void(0)" style="display:block;"><img alt="" border="0" src="' +
    myData.sitedomain +
    '/assets/app/img/btn_close.png"></a>' +
    "</div>" +
    "</div>" +
    "</div>" +
    "</div>";

  $chjq("body").append(backdropHTML);

  // Responsive Classes (mobile-class / desktop-class)
  var mq = window.matchMedia("(min-width: 820px)");
  responsiveClasses(mq.matches);
  mq.addListener(function (changed) {
    responsiveClasses(changed.matches);
  });

  function responsiveClasses(mediaMatched) {
    if (mediaMatched) {
      // Desktop
      $chjq("#" + ciRandId + "_chrchin_container").attr(
        "style",
        "position: fixed; top: 0px; left: 0px; bottom: 0px; right: 0px; background-color: rgba(48, 48, 48, 0.8); overflow-x: hidden; overflow-y: auto; z-index: 99999999999999;"
      );
      $chjq("#" + ciRandId + "_chrchin_unit_loading").attr(
        "style",
        "position: absolute; left: 50%; top: 80px; margin-left: -40px; z-index:1;"
      );
      $chjq("#" + ciRandId + "_chrchin_unit").attr(
        "style",
        "display: block; position: relative; left: 50%; margin-left: -400px; max-width: 800px; min-width: 320px; width: 100%; text-align: left; top: 20px; visibility: visible; z-index: 999998; overflow: hidden;"
      );
      $chjq("#" + ciRandId + "_chrchin_iframe_modal").attr(
        "style",
        "position: relative; z-index: 2; border: 0px; height: 632px; left: 0px; top: 0px; width: 100%; overflow: hidden;"
      );
      $chjq("#" + ciRandId + "_chrchin_close_btn").attr(
        "style",
        "display: block; position: absolute; right:0; padding-right:5px; padding-left:40px; text-align: right; top: 0px; z-index: 999999; cursor:pointer;"
      );
    } else {
      // Mobile
      if (iOScheck) {
        $chjq("#" + ciRandId + "_chrchin_container").attr(
          "style",
          "position: static; top: 0px; left: 0px; bottom: 0px; right: 0px; background-color: rgba(48, 48, 48, 0.8); z-index: 99999999999999;"
        );
      } else {
        $chjq("#" + ciRandId + "_chrchin_container").attr(
          "style",
          "position: fixed; top: 0px; left: 0px; bottom: 0px; right: 0px; background-color: rgba(48, 48, 48, 0.8); overflow-x: hidden; overflow-y: auto; z-index: 99999999999999;"
        );
      }

      $chjq("#" + ciRandId + "_chrchin_unit_loading").attr(
        "style",
        "position: absolute; left: 50%; top: 80px; margin-left: -40px; z-index:1;"
      );
      $chjq("#" + ciRandId + "_chrchin_unit").attr(
        "style",
        "display: block; position: relative; left: 50%; margin-left: -160px; max-width: 320px; min-width: 320px; width: 100%; text-align: left; top: 20px; visibility: visible; z-index: 999998; overflow: hidden;"
      );
      $chjq("#" + ciRandId + "_chrchin_iframe_modal").attr(
        "style",
        "position: relative; z-index: 2; border: 0px; height: 600px; left: 0px; top: 0px; width: 100%; overflow: hidden;"
      );
      $chjq("#" + ciRandId + "_chrchin_close_btn").attr(
        "style",
        "display: block; position: absolute; right:0; padding-right:5px; padding-left:40px; text-align: right; top: 0px; z-index: 999999; cursor:pointer;"
      );
    }
  }

  if (!myData.cipreview) {
    window
      .$chjq("#" + myData.chrchinContainerID)
      .append(ciIframeHTML);
  }
  function loadModal(loadData) {
    // When an Ecard is clicked ...
    $chjq("iframe#" + ciRandId + "_chrchin_iframe_modal")
      .get(0)
      .iFrameResizer.sendMessage(loadData.message);
    $chjq("iframe#" + ciRandId + "_chrchin_iframe_modal")
      .get(0)
      .iFrameResizer.resize();
    // Show the modal
    $chjq("#" + ciRandId + "_chrchin_wrap").css("display", "block");

    if (iOScheck) {
      $chjq("html, body").animate(
        {
          scrollTop: $chjq("#" + ciRandId + "_chrchin_wrap").offset()
            .top,
        },
        1000
      );
    }
  }

  $chjq(myData.ci_settings.buttonElement).click(function () {
    loadModal({
      description: "",
      ecardid: 6448,
      image: "/assets/uploads/ci/2004/00217CB7-1B85-4C56-A65650BCF4201D5D.jpeg",
      paywall: false,
      title: "",
      whitelabel: false,
      widgetid: "2004",
      disableSocialWidgetTabs: myData.disableSocialWidgetTabs,
    });
  });
  $chjq("#" + ciRandId + "_chrchin_iframe_widget").on(
    "load",
    function () {
      $chjq("[id^=ecardwidget_id_]").each(function(i, el) {
        // Init Widget Iframe Resizer/Callbacks
        chrchiFrameResize(
          {
            log: false,
            heightCalculationMethod: "lowestElement",
            checkOrigin: false,
            resizedCallback: function (messageData) { },
            messageCallback: function (data) {
              loadModal(data);
            },
            closedCallback: function (id) { },
          },
          "#x" + el.getAttribute('id') + "_chrchin_iframe_widget"
        );
      });

      var style = $chjq('#' + myData.chrchinContainerID).attr('style');
      $chjq('#churchiniframeholster,#' + myData.chrchinContainerID).attr('style',style + '; background: none !important;');

    }
  );

  $chjq("#" + ciRandId + "_chrchin_iframe_modal").on(
    "load",
    function () {
      // Init Modal Iframe Resizer/Callbacksss
      chrchiFrameResize(
        {
          log: false,
          heightCalculationMethod: "lowestElement",
          checkOrigin: false,
          resizedCallback: function (messageData) { },
          messageCallback: function (data) { },
          closedCallback: function (id) { },
        },
        "#" + ciRandId + "_chrchin_iframe_modal"
      );
    }
  );

  $chjq(document).on(
    "click",
    "#" + ciRandId + "_chrchin_close_btn",
    function () {
      var iframe = $chjq("iframe#" + ciRandId + "_chrchin_iframe_modal");
      $chjq("#" + ciRandId + "_chrchin_wrap").css("display", "none");
      iframe
        .get(0)
        .iFrameResizer.sendMessage({
          ecardid: 0,
          widgetid: "",
          image: "",
          title: "",
          description: "",
        });
    }
  );
}

// load jQuery and execute the ciMainMethod function
console.log("document.readyState",document.readyState)
if (data.cipreview) {
  $chjq = $;
  loadScripts();
} else if(typeof window.$chjq != 'undefined') {
  loadScripts();
} else if(document.readyState === 'ready' || document.readyState === 'complete' || document.readyState === 'interactive') {
  addCiJquery(loadScripts);
} else {
  document.onreadystatechange = function () {
    console.log("onreadystatechange",document.readyState)
    if (document.readyState == "complete" || document.readyState === 'interactive' ) {
      addCiJquery(loadScripts);
    }
  }
}

/*
 * File: iframeResizer.js
 * Desc: Force iframes to size to content.
 * Requires: iframeResizer.contentWindow.js to be loaded into the target frame.
 * Doc: https://github.com/davidjbradshaw/iframe-resizer
 * Author: David J. Bradshaw - dave@bradshaw.net
 * Contributor: Jure Mav - jure.mav@gmail.com
 * Contributor: Reed Dadoune - reed@dadoune.com
 */

function setupIframeResizer() {

  if (typeof window === "undefined") return; // don't run for server side render

  var count = 0,
    logEnabled = false,
    hiddenCheckEnabled = false,
    msgHeader = "message",
    msgHeaderLen = msgHeader.length,
    msgId = "[iFrameSizer]", //Must match iframe msg ID
    msgIdLen = msgId.length,
    pagePosition = null,
    requestAnimationFrame = window.requestAnimationFrame,
    resetRequiredMethods = {
      max: 1,
      scroll: 1,
      bodyScroll: 1,
      documentElementScroll: 1,
    },
    settings = {},
    timer = null,
    logId = "Host Page",
    defaults = {
      autoResize: true,
      bodyBackground: null,
      bodyMargin: null,
      bodyMarginV1: 8,
      bodyPadding: null,
      checkOrigin: true,
      inPageLinks: false,
      enablePublicMethods: true,
      heightCalculationMethod: "bodyOffset",
      id: "iFrameResizer",
      interval: 32,
      log: false,
      maxHeight: Infinity,
      maxWidth: Infinity,
      minHeight: 0,
      minWidth: 0,
      resizeFrom: "parent",
      scrolling: false,
      sizeHeight: true,
      sizeWidth: false,
      warningTimeout: 5000,
      tolerance: 0,
      widthCalculationMethod: "scroll",
      closedCallback: function () { },
      initCallback: function () { },
      messageCallback: function () {
        warn("MessageCallback function not defined");
      },
      resizedCallback: function () { },
      scrollCallback: function () {
        return true;
      },
    };

  function addEventListener(obj, evt, func) {
    /* istanbul ignore else */ // Not testable in PhantonJS
    if ("addEventListener" in window) {
      obj.addEventListener(evt, func, false);
    } else if ("attachEvent" in window) {
      //IE
      obj.attachEvent("on" + evt, func);
    }
  }

  function removeEventListener(el, evt, func) {
    /* istanbul ignore else */ // Not testable in phantonJS
    if ("removeEventListener" in window) {
      el.removeEventListener(evt, func, false);
    } else if ("detachEvent" in window) {
      //IE
      el.detachEvent("on" + evt, func);
    }
  }

  function setupRequestAnimationFrame() {
    var vendors = ["moz", "webkit", "o", "ms"],
      x;

    // Remove vendor prefixing if prefixed and break early if not
    for (x = 0; x < vendors.length && !requestAnimationFrame; x += 1) {
      requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"];
    }

    if (!requestAnimationFrame) {
      log("setup", "RequestAnimationFrame not supported");
    }
  }

  function getMyID(iframeId) {
    var retStr = "Host page: " + iframeId;

    if (window.top !== window.self) {
      if (window.parentIFrame && window.parentIFrame.getId) {
        retStr = window.parentIFrame.getId() + ": " + iframeId;
      } else {
        retStr = "Nested host page: " + iframeId;
      }
    }

    return retStr;
  }

  function formatLogHeader(iframeId) {
    return msgId + "[" + getMyID(iframeId) + "]";
  }

  function isLogEnabled(iframeId) {
    return settings[iframeId] ? settings[iframeId].log : logEnabled;
  }

  function log(iframeId, msg) {
    output("log", iframeId, msg, isLogEnabled(iframeId));
  }

  function info(iframeId, msg) {
    output("info", iframeId, msg, isLogEnabled(iframeId));
  }

  function warn(iframeId, msg) {
    output("warn", iframeId, msg, true);
  }

  function output(type, iframeId, msg, enabled) {
    if (true === enabled && "object" === typeof window.console) {
      console[type](formatLogHeader(iframeId), msg);
    }
  }

  function iFrameListener(event) {
    function resizeIFrame() {
      function resize() {
        setSize(messageData);
        setPagePosition(iframeId);
        callback("resizedCallback", messageData);
      }

      ensureInRange("Height");
      ensureInRange("Width");

      syncResize(resize, messageData, "init");
    }

    function processMsg() {
      var data = msg.substr(msgIdLen).split(":");

      return {
        iframe: settings[data[0]].iframe,
        id: data[0],
        height: data[1],
        width: data[2],
        type: data[3],
      };
    }

    function ensureInRange(Dimension) {
      var max = Number(settings[iframeId]["max" + Dimension]),
        min = Number(settings[iframeId]["min" + Dimension]),
        dimension = Dimension.toLowerCase(),
        size = Number(messageData[dimension]);

      log(
        iframeId,
        "Checking " + dimension + " is in range " + min + "-" + max
      );

      if (size < min) {
        size = min;
        log(iframeId, "Set " + dimension + " to min value");
      }

      if (size > max) {
        size = max;
        log(iframeId, "Set " + dimension + " to max value");
      }

      messageData[dimension] = "" + size;
    }

    function isMessageFromIFrame() {
      function checkAllowedOrigin() {
        function checkList() {
          var i = 0,
            retCode = false;

          log(
            iframeId,
            "Checking connection is from allowed list of origins: " +
            checkOrigin
          );

          for (; i < checkOrigin.length; i++) {
            if (checkOrigin[i] === origin) {
              retCode = true;
              break;
            }
          }
          return retCode;
        }

        function checkSingle() {
          var remoteHost = settings[iframeId].remoteHost;
          log(iframeId, "Checking connection is from: " + remoteHost);
          return origin === remoteHost;
        }

        return checkOrigin.constructor === Array ? checkList() : checkSingle();
      }

      var origin = event.origin,
        checkOrigin = settings[iframeId].checkOrigin;

      if (checkOrigin && "" + origin !== "null" && !checkAllowedOrigin()) {
        throw new Error(
          "Unexpected message received from: " +
          origin +
          " for " +
          messageData.iframe.id +
          ". Message was: " +
          event.data +
          ". This error can be disabled by setting the checkOrigin: false option or by providing of array of trusted domains."
        );
      }

      return true;
    }

    function isMessageForUs() {
      return (
        msgId === ("" + msg).substr(0, msgIdLen) &&
        msg.substr(msgIdLen).split(":")[0] in settings
      ); //''+Protects against non-string msg
    }

    function isMessageFromMetaParent() {
      //Test if this message is from a parent above us. This is an ugly test, however, updating
      //the message format would break backwards compatibity.
      var retCode = messageData.type in { true: 1, false: 1, undefined: 1 };

      if (retCode) {
        log(iframeId, "Ignoring init message from meta parent page");
      }

      return retCode;
    }

    function getMsgBody(offset) {
      return msg.substr(msg.indexOf(":") + msgHeaderLen + offset);
    }

    function forwardMsgFromIFrame(msgBody) {
      log(
        iframeId,
        "MessageCallback passed: {iframe: " +
        messageData.iframe.id +
        ", message: " +
        msgBody +
        "}"
      );
      callback("messageCallback", {
        iframe: messageData.iframe,
        message: JSON.parse(msgBody),
      });
      log(iframeId, "--");
    }

    function getPageInfo() {
      var bodyPosition = document.body.getBoundingClientRect(),
        iFramePosition = messageData.iframe.getBoundingClientRect();

      return JSON.stringify({
        iframeHeight: iFramePosition.height,
        iframeWidth: iFramePosition.width,
        clientHeight: Math.max(
          document.documentElement.clientHeight,
          window.innerHeight || 0
        ),
        clientWidth: Math.max(
          document.documentElement.clientWidth,
          window.innerWidth || 0
        ),
        offsetTop: parseInt(iFramePosition.top - bodyPosition.top, 10),
        offsetLeft: parseInt(iFramePosition.left - bodyPosition.left, 10),
        scrollTop: window.pageYOffset,
        scrollLeft: window.pageXOffset,
      });
    }

    function sendPageInfoToIframe(iframe, iframeId) {
      function debouncedTrigger() {
        trigger(
          "Send Page Info",
          "pageInfo:" + getPageInfo(),
          iframe,
          iframeId
        );
      }

      debouce(debouncedTrigger, 32);
    }

    function startPageInfoMonitor() {
      function setListener(type, func) {
        function sendPageInfo() {
          if (settings[id]) {
            sendPageInfoToIframe(settings[id].iframe, id);
          } else {
            stop();
          }
        }

        ["scroll", "resize"].forEach(function (evt) {
          log(id, type + evt + " listener for sendPageInfo");
          func(window, evt, sendPageInfo);
        });
      }

      function stop() {
        setListener("Remove ", removeEventListener);
      }

      function start() {
        setListener("Add ", addEventListener);
      }

      var id = iframeId; //Create locally scoped copy of iFrame ID

      start();

      settings[id].stopPageInfo = stop;
    }

    function stopPageInfoMonitor() {
      if (settings[iframeId] && settings[iframeId].stopPageInfo) {
        settings[iframeId].stopPageInfo();
        delete settings[iframeId].stopPageInfo;
      }
    }

    function checkIFrameExists() {
      var retBool = true;

      if (null === messageData.iframe) {
        warn(iframeId, "IFrame (" + messageData.id + ") not found");
        retBool = false;
      }
      return retBool;
    }

    function getElementPosition(target) {
      var iFramePosition = target.getBoundingClientRect();

      getPagePosition(iframeId);

      return {
        x: Math.floor(Number(iFramePosition.left) + Number(pagePosition.x)),
        y: Math.floor(Number(iFramePosition.top) + Number(pagePosition.y)),
      };
    }

    function scrollRequestFromChild(addOffset) {
      /* istanbul ignore next */ //Not testable in Karma
      function reposition() {
        pagePosition = newPosition;
        scrollTo();
        log(iframeId, "--");
      }

      function calcOffset() {
        return {
          x: Number(messageData.width) + offset.x,
          y: Number(messageData.height) + offset.y,
        };
      }

      function scrollParent() {
        if (window.parentIFrame) {
          window.parentIFrame["scrollTo" + (addOffset ? "Offset" : "")](
            newPosition.x,
            newPosition.y
          );
        } else {
          warn(
            iframeId,
            "Unable to scroll to requested position, window.parentIFrame not found"
          );
        }
      }

      var offset = addOffset
        ? getElementPosition(messageData.iframe)
        : { x: 0, y: 0 },
        newPosition = calcOffset();

      log(
        iframeId,
        "Reposition requested from iFrame (offset x:" +
        offset.x +
        " y:" +
        offset.y +
        ")"
      );

      if (window.top !== window.self) {
        scrollParent();
      } else {
        reposition();
      }
    }

    function scrollTo() {
      if (false !== callback("scrollCallback", pagePosition)) {
        setPagePosition(iframeId);
      } else {
        unsetPagePosition();
      }
    }

    function findTarget(location) {
      function jumpToTarget() {
        var jumpPosition = getElementPosition(target);

        log(
          iframeId,
          "Moving to in page link (#" +
          hash +
          ") at x: " +
          jumpPosition.x +
          " y: " +
          jumpPosition.y
        );
        pagePosition = {
          x: jumpPosition.x,
          y: jumpPosition.y,
        };

        scrollTo();
        log(iframeId, "--");
      }

      function jumpToParent() {
        if (window.parentIFrame) {
          window.parentIFrame.moveToAnchor(hash);
        } else {
          log(
            iframeId,
            "In page link #" +
            hash +
            " not found and window.parentIFrame not found"
          );
        }
      }

      var hash = location.split("#")[1] || "",
        hashData = decodeURIComponent(hash),
        target =
          document.getElementById(hashData) ||
          document.getElementsByName(hashData)[0];

      if (target) {
        jumpToTarget();
      } else if (window.top !== window.self) {
        jumpToParent();
      } else {
        log(iframeId, "In page link #" + hash + " not found");
      }
    }

    function callback(funcName, val) {
      return chkCallback(iframeId, funcName, val);
    }

    function actionMsg() {
      if (settings[iframeId].firstRun) firstRun();

      switch (messageData.type) {
        case "close":
          closeIFrame(messageData.iframe);
          break;
        case "message":
          forwardMsgFromIFrame(getMsgBody(6));
          break;
        case "scrollTo":
          scrollRequestFromChild(false);
          break;
        case "scrollToOffset":
          scrollRequestFromChild(true);
          break;
        case "pageInfo":
          sendPageInfoToIframe(settings[iframeId].iframe, iframeId);
          startPageInfoMonitor();
          break;
        case "pageInfoStop":
          stopPageInfoMonitor();
          break;
        case "inPageLink":
          findTarget(getMsgBody(9));
          break;
        case "reset":
          resetIFrame(messageData);
          break;
        case "init":
          resizeIFrame();
          callback("initCallback", messageData.iframe);
          break;
        default:
          resizeIFrame();
      }
    }

    function hasSettings(iframeId) {
      var retBool = true;

      if (!settings[iframeId]) {
        retBool = false;
        warn(
          messageData.type +
          " No settings for " +
          iframeId +
          ". Message was: " +
          msg
        );
      }

      return retBool;
    }

    function iFrameReadyMsgReceived() {
      for (var iframeId in settings) {
        trigger(
          "iFrame requested init",
          createOutgoingMsg(iframeId),
          document.getElementById(iframeId),
          iframeId
        );
      }
    }

    function firstRun() {
      settings[iframeId].firstRun = false;
    }

    var msg = event.data,
      messageData = {},
      iframeId = null;

    if ("[iFrameResizerChild]Ready" === msg) {
      iFrameReadyMsgReceived();
    } else if (isMessageForUs()) {
      messageData = processMsg();
      iframeId = logId = messageData.id;

      clearTimeout(settings[iframeId].msgTimeout);

      if (!isMessageFromMetaParent() && hasSettings(iframeId)) {
        log(iframeId, "Received: " + msg);

        if (checkIFrameExists() && isMessageFromIFrame()) {
          actionMsg();
        }
      }
    } else {
      info(iframeId, "Ignored: " + msg);
    }
  }

  function chkCallback(iframeId, funcName, val) {
    var func = null,
      retVal = null;

    if (settings[iframeId]) {
      func = settings[iframeId][funcName];

      if ("function" === typeof func) {
        retVal = func(val);
      } else {
        throw new TypeError(
          funcName + " on iFrame[" + iframeId + "] is not a function"
        );
      }
    }

    return retVal;
  }

  function closeIFrame(iframe) {
    var iframeId = iframe.id;

    log(iframeId, "Removing iFrame: " + iframeId);
    if (iframe.parentNode) {
      iframe.parentNode.removeChild(iframe);
    }
    chkCallback(iframeId, "closedCallback", iframeId);
    log(iframeId, "--");
    delete settings[iframeId];
  }

  function getPagePosition(iframeId) {
    if (null === pagePosition) {
      pagePosition = {
        x:
          window.pageXOffset !== undefined
            ? window.pageXOffset
            : document.documentElement.scrollLeft,
        y:
          window.pageYOffset !== undefined
            ? window.pageYOffset
            : document.documentElement.scrollTop,
      };
      log(
        iframeId,
        "Get page position: " + pagePosition.x + "," + pagePosition.y
      );
    }
  }

  function setPagePosition(iframeId) {
    // TIM CUSTOM CHANGE
    if (null !== pagePosition) {
      window.scrollTo(pagePosition.x, pagePosition.y);
      log(
        iframeId,
        "Set page position: " + pagePosition.x + "," + pagePosition.y
      );
      unsetPagePosition();
    }
  }

  function unsetPagePosition() {
    pagePosition = null;
  }

  function resetIFrame(messageData) {
    function reset() {
      setSize(messageData);
      trigger("reset", "reset", messageData.iframe, messageData.id);
    }

    log(
      messageData.id,
      "Size reset requested by " +
      ("init" === messageData.type ? "host page" : "iFrame")
    );
    getPagePosition(messageData.id);
    syncResize(reset, messageData, "reset");
  }

  function setSize(messageData) {
    function setDimension(dimension) {
      messageData.iframe.style[dimension] = messageData[dimension] + "px";
      log(
        messageData.id,
        "IFrame (" +
        iframeId +
        ") " +
        dimension +
        " set to " +
        messageData[dimension] +
        "px"
      );
    }

    function chkZero(dimension) {
      //FireFox sets dimension of hidden iFrames to zero.
      //So if we detect that set up an event to check for
      //when iFrame becomes visible.

      /* istanbul ignore next */ //Not testable in PhantomJS
      if (!hiddenCheckEnabled && "0" === messageData[dimension]) {
        hiddenCheckEnabled = true;
        log(iframeId, "Hidden iFrame detected, creating visibility listener");
        fixHiddenIFrames();
      }
    }

    function processDimension(dimension) {
      setDimension(dimension);
      chkZero(dimension);
    }

    var iframeId = messageData.iframe.id;

    if (settings[iframeId]) {
      if (settings[iframeId].sizeHeight) {
        processDimension("height");
      }
      if (settings[iframeId].sizeWidth) {
        processDimension("width");
      }
    }
  }

  function syncResize(func, messageData, doNotSync) {
    /* istanbul ignore if */ //Not testable in PhantomJS
    if (doNotSync !== messageData.type && requestAnimationFrame) {
      log(messageData.id, "Requesting animation frame");
      requestAnimationFrame(func);
    } else {
      func();
    }
  }

  function trigger(calleeMsg, msg, iframe, id, noResponseWarning) {
    function postMessageToIFrame() {
      var target = settings[id].targetOrigin;
      log(
        id,
        "[" +
        calleeMsg +
        "] Sending msg to iframe[" +
        id +
        "] (" +
        msg +
        ") targetOrigin: " +
        target
      );
      iframe.contentWindow.postMessage(msgId + msg, target);
    }

    function iFrameNotFound() {
      warn(id, "[" + calleeMsg + "] IFrame(" + id + ") not found");
    }

    function chkAndSend() {
      if (
        iframe &&
        "contentWindow" in iframe &&
        null !== iframe.contentWindow
      ) {
        //Null test for PhantomJS
        postMessageToIFrame();
      } else {
        iFrameNotFound();
      }
    }

    function warnOnNoResponse() {
      function warning() {
        warn(
          id,
          "No response from iFrame. Check iFrameResizer.contentWindow.js has been loaded in iFrame"
        );
      }

      if (!!noResponseWarning) {
        settings[id].msgTimeout = setTimeout(
          warning,
          settings[id].warningTimeout
        );
      }
    }

    id = id || iframe.id;

    if (settings[id]) {
      chkAndSend();
      warnOnNoResponse();
    }
  }

  function createOutgoingMsg(iframeId) {
    return (
      iframeId +
      ":" +
      settings[iframeId].bodyMarginV1 +
      ":" +
      settings[iframeId].sizeWidth +
      ":" +
      settings[iframeId].log +
      ":" +
      settings[iframeId].interval +
      ":" +
      settings[iframeId].enablePublicMethods +
      ":" +
      settings[iframeId].autoResize +
      ":" +
      settings[iframeId].bodyMargin +
      ":" +
      settings[iframeId].heightCalculationMethod +
      ":" +
      settings[iframeId].bodyBackground +
      ":" +
      settings[iframeId].bodyPadding +
      ":" +
      settings[iframeId].tolerance +
      ":" +
      settings[iframeId].inPageLinks +
      ":" +
      settings[iframeId].resizeFrom +
      ":" +
      settings[iframeId].widthCalculationMethod
    );
  }

  function setupIFrame(iframe, options) {
    function setLimits() {
      function addStyle(style) {
        if (
          Infinity !== settings[iframeId][style] &&
          0 !== settings[iframeId][style]
        ) {
          iframe.style[style] = settings[iframeId][style] + "px";
          log(
            iframeId,
            "Set " + style + " = " + settings[iframeId][style] + "px"
          );
        }
      }

      function chkMinMax(dimension) {
        if (
          settings[iframeId]["min" + dimension] >
          settings[iframeId]["max" + dimension]
        ) {
          throw new Error(
            "Value for min" +
            dimension +
            " can not be greater than max" +
            dimension
          );
        }
      }

      chkMinMax("Height");
      chkMinMax("Width");

      addStyle("maxHeight");
      addStyle("minHeight");
      addStyle("maxWidth");
      addStyle("minWidth");
    }

    function newId() {
      var id = (options && options.id) || defaults.id + count++;
      if (null !== document.getElementById(id)) {
        id = id + count++;
      }
      return id;
    }

    function ensureHasId(iframeId) {
      logId = iframeId;
      if ("" === iframeId) {
        iframe.id = iframeId = newId();
        logEnabled = (options || {}).log;
        logId = iframeId;
        log(
          iframeId,
          "Added missing iframe ID: " + iframeId + " (" + iframe.src + ")"
        );
      }

      return iframeId;
    }

    function setScrolling() {
      log(
        iframeId,
        "IFrame scrolling " +
        (settings[iframeId].scrolling ? "enabled" : "disabled") +
        " for " +
        iframeId
      );
      iframe.style.overflow =
        false === settings[iframeId].scrolling ? "hidden" : "auto";
      switch (settings[iframeId].scrolling) {
        case true:
          iframe.scrolling = "yes";
          break;
        case false:
          iframe.scrolling = "no";
          break;
        default:
          iframe.scrolling = settings[iframeId].scrolling;
      }
    }

    //The V1 iFrame script expects an int, where as in V2 expects a CSS
    //string value such as '1px 3em', so if we have an int for V2, set V1=V2
    //and then convert V2 to a string PX value.
    function setupBodyMarginValues() {
      if (
        "number" === typeof settings[iframeId].bodyMargin ||
        "0" === settings[iframeId].bodyMargin
      ) {
        settings[iframeId].bodyMarginV1 = settings[iframeId].bodyMargin;
        settings[iframeId].bodyMargin =
          "" + settings[iframeId].bodyMargin + "px";
      }
    }

    function checkReset() {
      // Reduce scope of firstRun to function, because IE8's JS execution
      // context stack is borked and this value gets externally
      // changed midway through running this function!!!
      var firstRun = settings[iframeId].firstRun,
        resetRequertMethod =
          settings[iframeId].heightCalculationMethod in resetRequiredMethods;

      if (!firstRun && resetRequertMethod) {
        resetIFrame({ iframe: iframe, height: 0, width: 0, type: "init" });
      }
    }

    function setupIFrameObject() {
      if (Function.prototype.bind) {
        //Ignore unpolyfilled IE8.
        settings[iframeId].iframe.iFrameResizer = {
          close: closeIFrame.bind(null, settings[iframeId].iframe),

          resize: trigger.bind(
            null,
            "Window resize",
            "resize",
            settings[iframeId].iframe
          ),

          moveToAnchor: function (anchor) {
            trigger(
              "Move to anchor",
              "moveToAnchor:" + anchor,
              settings[iframeId].iframe,
              iframeId
            );
          },

          sendMessage: function (message) {
            message = JSON.stringify(message);
            trigger(
              "Send Message",
              "message:" + message,
              settings[iframeId].iframe,
              iframeId
            );
          },
        };
      }
    }

    //We have to call trigger twice, as we can not be sure if all
    //iframes have completed loading when this code runs. The
    //event listener also catches the page changing in the iFrame.
    function init(msg) {
      function iFrameLoaded() {
        trigger("iFrame.onload", msg, iframe, undefined, true);
        checkReset();
      }

      addEventListener(iframe, "load", iFrameLoaded);
      trigger("init", msg, iframe, undefined, true);
    }

    function checkOptions(options) {
      if ("object" !== typeof options) {
        throw new TypeError("Options is not an object");
      }
    }

    function copyOptions(options) {
      for (var option in defaults) {
        if (defaults.hasOwnProperty(option)) {
          settings[iframeId][option] = options.hasOwnProperty(option)
            ? options[option]
            : defaults[option];
        }
      }
    }

    function getTargetOrigin(remoteHost) {
      return "" === remoteHost || "file://" === remoteHost ? "*" : remoteHost;
    }

    function processOptions(options) {
      options = options || {};
      settings[iframeId] = {
        firstRun: true,
        iframe: iframe,
        remoteHost: iframe.src.split("/").slice(0, 3).join("/"),
      };

      checkOptions(options);
      copyOptions(options);

      settings[iframeId].targetOrigin =
        true === settings[iframeId].checkOrigin
          ? getTargetOrigin(settings[iframeId].remoteHost)
          : "*";
    }

    function beenHere() {
      return iframeId in settings && "iFrameResizer" in iframe;
    }

    var iframeId = ensureHasId(iframe.id);

    if (!beenHere()) {
      processOptions(options);
      setScrolling();
      setLimits();
      setupBodyMarginValues();
      init(createOutgoingMsg(iframeId));
      setupIFrameObject();
    } else {
      warn(iframeId, "Ignored iFrame, already setup.");
    }
  }

  function debouce(fn, time) {
    if (null === timer) {
      timer = setTimeout(function () {
        timer = null;
        fn();
      }, time);
    }
  } //Not testable in PhantomJS

  /* istanbul ignore next */ function fixHiddenIFrames() {
    function checkIFrames() {
      function checkIFrame(settingId) {
        function chkDimension(dimension) {
          return "0px" === settings[settingId].iframe.style[dimension];
        }

        function isVisible(el) {
          return null !== el.offsetParent;
        }

        if (
          isVisible(settings[settingId].iframe) &&
          (chkDimension("height") || chkDimension("width"))
        ) {
          trigger(
            "Visibility change",
            "resize",
            settings[settingId].iframe,
            settingId
          );
        }
      }

      for (var settingId in settings) {
        checkIFrame(settingId);
      }
    }

    function mutationObserved(mutations) {
      log(
        "window",
        "Mutation observed: " + mutations[0].target + " " + mutations[0].type
      );
      debouce(checkIFrames, 16);
    }

    function createMutationObserver() {
      var target = document.querySelector("body"),
        config = {
          attributes: true,
          attributeOldValue: false,
          characterData: true,
          characterDataOldValue: false,
          childList: true,
          subtree: true,
        },
        observer = new MutationObserver(mutationObserved);

      observer.observe(target, config);
    }

    var MutationObserver =
      window.MutationObserver || window.WebKitMutationObserver;

    if (MutationObserver) createMutationObserver();
  }

  function resizeIFrames(event) {
    function resize() {
      sendTriggerMsg("Window " + event, "resize");
    }

    log("window", "Trigger event: " + event);
    debouce(resize, 16);
  } //Not testable in PhantomJS

  /* istanbul ignore next */ function tabVisible() {
    function resize() {
      sendTriggerMsg("Tab Visable", "resize");
    }

    if ("hidden" !== document.visibilityState) {
      log("document", "Trigger event: Visiblity change");
      debouce(resize, 16);
    }
  }

  function sendTriggerMsg(eventName, event) {
    function isIFrameResizeEnabled(iframeId) {
      return (
        "parent" === settings[iframeId].resizeFrom &&
        settings[iframeId].autoResize &&
        !settings[iframeId].firstRun
      );
    }

    for (var iframeId in settings) {
      if (isIFrameResizeEnabled(iframeId)) {
        trigger(eventName, event, document.getElementById(iframeId), iframeId);
      }
    }
  }

  function setupEventListeners() {
    addEventListener(window, "message", iFrameListener);

    addEventListener(window, "resize", function () {
      resizeIFrames("resize");
    });

    addEventListener(document, "visibilitychange", tabVisible);
    addEventListener(document, "-webkit-visibilitychange", tabVisible); //Andriod 4.4
    addEventListener(window, "focusin", function () {
      resizeIFrames("focus");
    }); //IE8-9
    addEventListener(window, "focus", function () {
      resizeIFrames("focus");
    });
  }

  function factory() {
    function init(options, element) {
      function chkType() {
        if (!element.tagName) {
          throw new TypeError("Object is not a valid DOM element");
        } else if ("IFRAME" !== element.tagName.toUpperCase()) {
          throw new TypeError(
            "Expected <IFRAME> tag, found <" + element.tagName + ">"
          );
        }
      }

      if (element) {
        chkType();
        setupIFrame(element, options);
        iFrames.push(element);
      }
    }

    function warnDeprecatedOptions(options) {
      if (options && options.enablePublicMethods) {
        warn(
          "enablePublicMethods option has been removed, public methods are now always available in the iFrame"
        );
      }
    }

    var iFrames;

    setupRequestAnimationFrame();
    setupEventListeners();

    return function iFrameResizeF(options, target) {
      iFrames = []; //Only return iFrames past in on this call

      warnDeprecatedOptions(options);

      switch (typeof target) {
        case "undefined":
        case "string":
          Array.prototype.forEach.call(
            document.querySelectorAll(target || "iframe"),
            init.bind(undefined, options)
          );
          break;
        case "object":
          init(options, target);
          break;
        default:
          throw new TypeError("Unexpected data type (" + typeof target + ")");
      }

      return iFrames;
    };
  }

  function createJQueryPublicMethod($) {
    if (!$.fn) {
      info("", "Unable to bind to jQuery, it is not fully loaded.");
    } else if (!$.fn.chrchiFrameResize) {
      $.fn.chrchiFrameResize = function $iFrameResizeF(options) {
        function init(index, element) {
          setupIFrame(element, options);
        }

        return this.filter("iframe").each(init).end();
      };
    }
  }

  if (window.$chjq) {
    createJQueryPublicMethod(window.$chjq);
  }

  // if (typeof define === "function" && define.amd) {
  //   define([], factory);
  // } else if (typeof module === "object" && typeof module.exports === "object") {
  //   //Node for browserfy
  //   module.exports = factory();
  // }
  window.chrchiFrameResize = window.chrchiFrameResize || factory();
}
