Skip to content

Commit

Permalink
Merge pull request #546 from Countly/async-multi-fix
Browse files Browse the repository at this point in the history
Multi instance fix
  • Loading branch information
turtledreams authored Jan 10, 2025
2 parents fd3716e + f65e1b1 commit 809fcfe
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 98 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 24.11.4

- Mitigated an issue where `content` and `feedback` interface methods would not have worked if async methods were used when multi instancing the SDK.

## 24.11.3

- Added support for content resizing (Experimental!)
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/bridged_utils.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function initMain(name, version) {
}

const SDK_NAME = "javascript_native_web";
const SDK_VERSION = "24.11.3";
const SDK_VERSION = "24.11.4";

// tests
describe("Bridged SDK Utilities Tests", () => {
Expand Down
4 changes: 4 additions & 0 deletions cypress/fixtures/multi_instance.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@
Countly.q.push(["YOUR_APP_KEY3", "collect_from_forms"]);
Countly.q.push(["YOUR_APP_KEY3", "collect_from_facebook"]);
Countly.q.push(["YOUR_APP_KEY3", "opt_in"]);
Countly.q.push(["YOUR_APP_KEY3", "feedback.showNPS"]);
Countly.q.push(["YOUR_APP_KEY3", "content.enterContentZone"]);

//initialize fourth instance for another app asynchronously
Countly.q.push(["init", {
Expand Down Expand Up @@ -158,6 +160,8 @@
Countly.q.push(["YOUR_APP_KEY4", "collect_from_forms"]);
Countly.q.push(["YOUR_APP_KEY4", "collect_from_facebook"]);
Countly.q.push(["YOUR_APP_KEY4", "opt_in"]);
Countly.q.push(["YOUR_APP_KEY4", "feedback.showNPS"]);
Countly.q.push(["YOUR_APP_KEY4", "content.enterContentZone"]);
</script>
</head>
</html>
105 changes: 69 additions & 36 deletions lib/countly.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@
statusCode: "cly_hc_status_code",
errorMessage: "cly_hc_error_message"
});
var SDK_VERSION = "24.11.3";
var SDK_VERSION = "24.11.4";
var SDK_NAME = "javascript_native_web";

// Using this on document.referrer would return an array with 17 elements in it. The 12th element (array[11]) would be the path we are looking for. Others would be things like password and such (use https://regex101.com/ to check more)
Expand Down Expand Up @@ -4386,8 +4386,22 @@
if (e) {
return;
}
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "sendContentRequest, received content: [" + resp + "]");
_classPrivateFieldGet2(_displayContent, _this).call(_this, resp);
if (!resp) {
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.VERBOSE, "sendContentRequest, no content to display");
return;
}
try {
var response = JSON.parse(resp);
} catch (error) {
// verbose log
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.VERBOSE, "sendContentRequest, No content to display or an error while parsing content: " + error);
return;
}
if (!response.html || !response.geo) {
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.VERBOSE, "sendContentRequest, no html content or orientation to display");
return;
}
_classPrivateFieldGet2(_displayContent, _this).call(_this, response);
clearInterval(_classPrivateFieldGet2(_contentZoneTimer, _this)); // prevent multiple content requests while one is on
window.addEventListener('message', function (event) {
_classPrivateFieldGet2(_interpretContentMessage, _this).call(_this, event);
Expand All @@ -4399,6 +4413,9 @@
var width = window.innerWidth;
var height = window.innerHeight;
var iframe = document.getElementById(_classPrivateFieldGet2(_contentIframeID, _this));
if (!iframe) {
return;
}
iframe.contentWindow.postMessage({
type: 'resize',
width: width,
Expand All @@ -4408,72 +4425,75 @@
});
}, true);
});
_classPrivateFieldInitSpec(this, _displayContent, function (content) {
if (!content) {
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "displayContent, no content to display");
return;
_classPrivateFieldInitSpec(this, _displayContent, function (response) {
try {
var iframe = document.createElement("iframe");
iframe.id = _classPrivateFieldGet2(_contentIframeID, _this);
iframe.src = response.html;
iframe.style.position = "absolute";
var dimensionToUse = response.geo.p;
var resInfo = _classPrivateFieldGet2(_getResolution, _this).call(_this, true);
if (resInfo.width >= resInfo.height) {
dimensionToUse = response.geo.l;
}
;
iframe.style.left = dimensionToUse.x + "px";
iframe.style.top = dimensionToUse.y + "px";
iframe.style.width = dimensionToUse.w + "px";
iframe.style.height = dimensionToUse.h + "px";
iframe.style.border = "none";
iframe.style.zIndex = "999999";
document.body.appendChild(iframe);
} catch (error) {
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.ERROR, "displayContent, Error while creating iframe for the content: " + error);
}
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "displayContent, displaying content");
var response = JSON.parse(content);
var iframe = document.createElement("iframe");
iframe.id = _classPrivateFieldGet2(_contentIframeID, _this);
iframe.src = response.html;
iframe.style.position = "absolute";
var dimensionToUse = response.geo.p;
var resInfo = _classPrivateFieldGet2(_getResolution, _this).call(_this, true);
if (resInfo.width >= resInfo.height) {
dimensionToUse = response.geo.l;
}
iframe.style.left = dimensionToUse.x + "px";
iframe.style.top = dimensionToUse.y + "px";
iframe.style.width = dimensionToUse.w + "px";
iframe.style.height = dimensionToUse.h + "px";
iframe.style.border = "none";
iframe.style.zIndex = "999999";
document.body.appendChild(iframe);
});
_classPrivateFieldInitSpec(this, _interpretContentMessage, function (messageEvent) {
if (messageEvent.origin !== _this.url) {
// this.#log(logLevelEnums.ERROR, "sendContentRequest, Received message from invalid origin");
// this.#log(logLevelEnums.ERROR, "interpretContentMessage, Received message from invalid origin");
// silent ignore
return;
}
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "sendContentRequest, Received message from: [" + messageEvent.origin + "] with data: [" + JSON.stringify(messageEvent.data) + "]");
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "interpretContentMessage, Received message from: [" + messageEvent.origin + "] with data: [" + JSON.stringify(messageEvent.data) + "]");
var _messageEvent$data = messageEvent.data,
close = _messageEvent$data.close,
link = _messageEvent$data.link,
event = _messageEvent$data.event,
resize_me = _messageEvent$data.resize_me;
if (event) {
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "sendContentRequest, Received event");
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "interpretContentMessage, Received event");
if (close === 1) {
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "sendContentRequest, Closing content frame for event");
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "interpretContentMessage, Closing content frame for event");
_classPrivateFieldGet2(_closeContentFrame, _this).call(_this);
}
if (!Array.isArray(event)) {
if (_typeof(event) === "object") {
_readOnlyError("event");
} else {
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.ERROR, "sendContentRequest, Invalid event type: [" + _typeof(event) + "]");
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.ERROR, "interpretContentMessage, Invalid event type: [" + _typeof(event) + "]");
return;
}
}
// event is expected to be an array of events
for (var i = 0; i < event.length; i++) {
_classPrivateFieldGet2(_add_cly_events, _this).call(_this, event[i]);
_classPrivateFieldGet2(_add_cly_events, _this).call(_this, event[i]); // let this method handle the event
}
}
if (link) {
if (close === 1) {
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "sendContentRequest, Closing content frame for link");
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "interpretContentMessage, Closing content frame for link");
_classPrivateFieldGet2(_closeContentFrame, _this).call(_this);
}
window.open(link, "_blank");
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "sendContentRequest, Opened link in new tab: [".concat(link, "]"));
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "interpretContentMessage, Opened link in new tab: [".concat(link, "]"));
}
if (resize_me) {
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "sendContentRequest, Resizing iframe");
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "interpretContentMessage, Resizing iframe");
var resInfo = _classPrivateFieldGet2(_getResolution, _this).call(_this, true);
if (!resize_me.l || !resize_me.p || !resize_me.l.x || !resize_me.l.y || !resize_me.l.w || !resize_me.l.h || !resize_me.p.x || !resize_me.p.y || !resize_me.p.w || !resize_me.p.h) {
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.ERROR, "interpretContentMessage, Invalid resize object");
return;
}
var dimensionToUse = resize_me.p;
if (resInfo.width >= resInfo.height) {
dimensionToUse = resize_me.l;
Expand All @@ -4489,10 +4509,11 @@
}
});
_classPrivateFieldInitSpec(this, _closeContentFrame, function () {
// we might want to remove event listeners here too but with the current implementation, it seems unnecessary
var iframe = document.getElementById(_classPrivateFieldGet2(_contentIframeID, _this));
if (iframe) {
iframe.remove();
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "sendContentRequest, removed iframe");
_classPrivateFieldGet2(_log, _this).call(_this, logLevelEnums.DEBUG, "interpretContentMessage, removed iframe");
if (_classPrivateFieldGet2(_inContentZone, _this)) {
// if user did not exit content zone, re-enter
_classPrivateFieldGet2(_enterContentZoneInternal, _this).call(_this, true);
Expand Down Expand Up @@ -4846,11 +4867,23 @@
}
if (typeof inst[req[arg]] === "function") {
inst[req[arg]].apply(inst, req.slice(arg + 1));
} else if (req[arg].indexOf("userData.") === 0) {
}
// Add interfaces you add to here for async queue to work
else if (req[arg].indexOf("userData.") === 0) {
var userdata = req[arg].replace("userData.", "");
if (typeof inst.userData[userdata] === "function") {
inst.userData[userdata].apply(inst, req.slice(arg + 1));
}
} else if (req[arg].indexOf("content.") === 0) {
var contentMethod = req[arg].replace("content.", "");
if (typeof inst.content[contentMethod] === "function") {
inst.content[contentMethod].apply(inst, req.slice(arg + 1));
}
} else if (req[arg].indexOf("feedback.") === 0) {
var feedbackMethod = req[arg].replace("feedback.", "");
if (typeof inst.feedback[feedbackMethod] === "function") {
inst.feedback[feedbackMethod].apply(inst, req.slice(arg + 1));
}
} else if (typeof Countly[req[arg]] === "function") {
Countly[req[arg]].apply(Countly, req.slice(arg + 1));
}
Expand Down
Loading

0 comments on commit 809fcfe

Please sign in to comment.