Skip to content

Commit

Permalink
Better event listener management to fix multiple events listners on m…
Browse files Browse the repository at this point in the history
…essages events attached to the window object, occured when we close and reopen the form.
  • Loading branch information
devdesjardins committed Apr 9, 2021
1 parent 6e1df4a commit 99d39ec
Showing 1 changed file with 119 additions and 98 deletions.
217 changes: 119 additions & 98 deletions lib/rxp-hpp.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,25 @@ var RealexHpp = (function () {
var redirectUrl;

var internal = {

evtMsg: [],
addEvtMsgListener: function(evtMsgFct) {
this.evtMsg.push({ fct: evtMsgFct, opt: false });
if (window.addEventListener) {
window.addEventListener("message", evtMsgFct, false);
} else {
window.attachEvent('message', evtMsgFct);
}
},
removeOldEvtMsgListener: function () {
if (this.evtMsg.length > 0) {
var evt = this.evtMsg.pop();
if (window.addEventListener) {
window.removeEventListener("message", evt.fct, evt.opt);
} else {
window.detachEvent('message', evt.fct);
}
}
},
base64:{
encode:function(input) {
var keyStr = "ABCDEFGHIJKLMNOP" +
Expand Down Expand Up @@ -416,95 +434,93 @@ var RealexHpp = (function () {
return internal.getHostnameFromUrl(origin) === internal.getHostnameFromUrl(hppUrl);
},

receiveMessage: function (lightboxInstance, merchantUrl, isEmbedded) {
return function (event) {
//Check the origin of the response comes from HPP
if (!internal.isMessageFromHpp(event.origin, hppUrl)) {
return;
}
// check for iframe resize values
var evtdata;
if (event.data && (evtdata=internal.decodeAnswer(event.data)).iframe) {
if (!isMobileNewTab()) {
var iframeWidth = evtdata.iframe.width;
var iframeHeight = evtdata.iframe.height;

var iFrame;
var resized = false;

if (isEmbedded) {
iFrame = lightboxInstance.getIframe();
} else {
iFrame = document.getElementById("rxp-frame-" + randomId);
}
if(lightboxInstance.events && lightboxInstance.events.onResize) {
lightboxInstance.events.onResize(evtdata.iframe);
}
receiveMessage: function (e) {
//Check the origin of the response comes from HPP
if (!internal.isMessageFromHpp(e.event.origin, hppUrl)) {
return;
}
// check for iframe resize values
var evtdata;
if (e.event.data && (evtdata=internal.decodeAnswer(e.event.data)).iframe) {
if (!isMobileNewTab()) {
var iframeWidth = evtdata.iframe.width;
var iframeHeight = evtdata.iframe.height;

var iFrame;
var resized = false;

if (e.embedded) {
iFrame = e.instance.getIframe();
} else {
iFrame = document.getElementById("rxp-frame-" + randomId);
}
if (e.instance.events && e.instance.events.onResize) {
e.instance.events.onResize(evtdata.iframe);
}

if (iframeWidth === "390px" && iframeHeight === "440px") {
iFrame.setAttribute("width", iframeWidth);
iFrame.setAttribute("height", iframeHeight);
resized = true;
}
if (iframeWidth === "390px" && iframeHeight === "440px") {
iFrame.setAttribute("width", iframeWidth);
iFrame.setAttribute("height", iframeHeight);
resized = true;
}

iFrame.style.backgroundColor="#ffffff";

if (isMobileIFrame) {
iFrame.style.marginLeft = "0px";
iFrame.style.WebkitOverflowScrolling = "touch";
iFrame.style.overflowX = "scroll";
iFrame.style.overflowY = "scroll";

if (!isEmbedded) {
var overlay = document.getElementById("rxp-overlay-" + randomId);
overlay.style.overflowX = "scroll";
overlay.style.overflowY = "scroll";
}
} else if (!isEmbedded && resized) {
iFrame.style.marginLeft = (parseInt(iframeWidth.replace("px", ""), 10) / 2 * -1) + "px";
}
iFrame.style.backgroundColor="#ffffff";

if (!isEmbedded && resized) {
// wrap the below in a setTimeout to prevent a timing issue on a
// cache-miss load
setTimeout(function () {
var closeButton = document.getElementById("rxp-frame-close-" + randomId);
closeButton.style.marginLeft = ((parseInt(iframeWidth.replace("px", ""), 10) / 2) -7) + "px";
}, 200);
if (isMobileIFrame) {
iFrame.style.marginLeft = "0px";
iFrame.style.WebkitOverflowScrolling = "touch";
iFrame.style.overflowX = "scroll";
iFrame.style.overflowY = "scroll";

if (!e.embedded) {
var overlay = document.getElementById("rxp-overlay-" + randomId);
overlay.style.overflowX = "scroll";
overlay.style.overflowY = "scroll";
}
} else if (!e.embedded && resized) {
iFrame.style.marginLeft = (parseInt(iframeWidth.replace("px", ""), 10) / 2 * -1) + "px";
}
} else {
var _close=function(){
if (isMobileNewTab() && tabWindow) {
//Close the new window
tabWindow.close();
} else {
//Close the lightbox
lightboxInstance.close();
}
var overlay=document.getElementById("rxp-overlay-" + randomId);
if(overlay) {
overlay.remove();
}

};
var response = event.data;
//allow the script to intercept the answer, instead of redirecting to another page. (which is really a 90s thing)
if(typeof merchantUrl==='function'){
var answer=internal.decodeAnswer(response);
merchantUrl(answer,_close);
return;
if (!e.embedded && resized) {
// wrap the below in a setTimeout to prevent a timing issue on a
// cache-miss load
setTimeout(function () {
var closeButton = document.getElementById("rxp-frame-close-" + randomId);
closeButton.style.marginLeft = ((parseInt(iframeWidth.replace("px", ""), 10) / 2) -7) + "px";
}, 200);
}
_close();
//Create a form and submit the hpp response to the merchant's response url
var form = document.createElement("form");
form.setAttribute("method", "POST");
form.setAttribute("action", merchantUrl);
form.appendChild(internal.createFormHiddenInput("hppResponse", response));
document.body.appendChild(form);
form.submit();
}
};
} else {
var _close=function(){
if (isMobileNewTab() && tabWindow) {
//Close the new window
tabWindow.close();
} else {
//Close the lightbox
e.instance.close();
}
var overlay=document.getElementById("rxp-overlay-" + randomId);
if(overlay) {
overlay.remove();
}

};
var response = e.event.data;
//allow the script to intercept the answer, instead of redirecting to another page. (which is really a 90s thing)
if(typeof e.url==='function'){
var answer=internal.decodeAnswer(response);
e.url(answer,_close);
return;
}
_close();
//Create a form and submit the hpp response to the merchant's response url
var form = document.createElement("form");
form.setAttribute("method", "POST");
form.setAttribute("action", e.url);
form.appendChild(internal.createFormHiddenInput("hppResponse", response));
document.body.appendChild(form);
form.submit();
}
}
};

Expand Down Expand Up @@ -576,12 +592,13 @@ var RealexHpp = (function () {
} else {
document.getElementById(idOfLightboxButton).attachEvent('onclick', lightboxInstance.lightbox);
}

if (window.addEventListener) {
window.addEventListener("message", internal.receiveMessage(lightboxInstance, merchantUrl), false);
} else {
window.attachEvent('message', internal.receiveMessage(lightboxInstance, merchantUrl));
}
//avoid multiple message event listener binded to the window object.
internal.removeOldEvtMsgListener();
var evtMsgFct = function (event) {
return internal.receiveMessage({ event: event, instance: lightboxInstance, url: merchantUrl, embedded: false });
};
internal.evtMsg.push({ fct: evtMsgFct, opt: false });
internal.addEvtMsgListener(evtMsgFct);
}
};
})();
Expand Down Expand Up @@ -654,11 +671,13 @@ var RealexHpp = (function () {
document.getElementById(idOfEmbeddedButton).attachEvent('onclick', embeddedInstance.embedded);
}

if (window.addEventListener) {
window.addEventListener("message", internal.receiveMessage(embeddedInstance, merchantUrl, true), false);
} else {
window.attachEvent('message', internal.receiveMessage(embeddedInstance, merchantUrl, true));
}
//avoid multiple message event listener binded to the window object.
internal.removeOldEvtMsgListener();
var evtMsgFct = function (event) {
return internal.receiveMessage({ event: event, instance: embeddedInstance, url: merchantUrl, embedded: true });
};
internal.evtMsg.push({ fct: evtMsgFct, opt: false });
internal.addEvtMsgListener(evtMsgFct);
}
};
})();
Expand Down Expand Up @@ -718,11 +737,13 @@ var RealexHpp = (function () {
document.getElementById(idOfButton).attachEvent('onclick', redirectInstance.redirect);
}

if (window.addEventListener) {
window.addEventListener("message", internal.receiveMessage(redirectInstance, merchantUrl), false);
} else {
window.attachEvent('message', internal.receiveMessage(redirectInstance, merchantUrl));
}
//avoid multiple message event listener binded to the window object.
internal.removeOldEvtMsgListener();
var evtMsgFct = function (event) {
return internal.receiveMessage({ event: event, instance: redirectInstance, url: merchantUrl, embedded: false });
};
internal.evtMsg.push({ fct: evtMsgFct, opt: false });
internal.addEvtMsgListener(evtMsgFct);
}
};
}());
Expand Down

0 comments on commit 99d39ec

Please sign in to comment.