Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi instance fix #546

Merged
merged 3 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading