Skip to content

Commit 5270574

Browse files
Rename scrolling class and update event handling
1 parent 8865bc4 commit 5270574

File tree

1 file changed

+95
-31
lines changed

1 file changed

+95
-31
lines changed

godwin/assets/js/init.js

Lines changed: 95 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
const TOP_CONTAINER_NAME = "agentforce-messaging";
1212
const LWR_IFRAME_NAME = "agentforce-messaging-frame";
1313
const LWR_IFRAME_TITLE = "Chat Window";
14-
const PREVENT_SCROLLING_CLASS = "agentforceMessagingPreventScrolling";
14+
const PREVENT_SCROLLING_CLASS = "embeddedMessagingPreventScrolling";
1515

1616
/**
1717
* Attributes required to construct SCRT 2.0 Service URL.
@@ -45,11 +45,6 @@
4545
resolveAppReadyPromise = resolve;
4646
});
4747

48-
const hostEvents = {
49-
ON_EMBEDDED_MESSAGING_WINDOW_MINIMIZED_EVENT_NAME: "onEmbeddedMessagingWindowMinimized",
50-
ON_EMBEDDED_MESSAGING_WINDOW_MAXIMIZED_EVENT_NAME: "onEmbeddedMessagingWindowMaximized"
51-
};
52-
5348
// =========================
5449
// Utils
5550
// =========================
@@ -219,14 +214,8 @@
219214
function handleMinimize() {
220215
const frame = getIframe();
221216

222-
if (document.body.classList.contains(PREVENT_SCROLLING_CLASS)) {
223-
// [Mobile] Remove class that prevents background clicking and scrolling.
224-
// Restore document body's scroll position only for mobile devices
225-
document.body.classList.remove(PREVENT_SCROLLING_CLASS);
226-
if (agentforce_messaging.documentScrollPosition) {
227-
window.scrollTo(0, agentforce_messaging.documentScrollPosition);
228-
}
229-
}
217+
// [Mobile] Remove class that prevents background clicking and scrolling.
218+
document.body.classList.remove(PREVENT_SCROLLING_CLASS);
230219

231220
if (frame) {
232221
// Update width and height if options are provided
@@ -239,24 +228,16 @@
239228
}
240229
}
241230

242-
frame.classList.remove("initial");
243231
frame.classList.add("minimized");
244232
frame.classList.remove("maximized");
245-
246-
dispatchEventToHost(hostEvents.ON_EMBEDDED_MESSAGING_WINDOW_MINIMIZED_EVENT_NAME);
247233
}
248234
}
249235

250236
function handleMaximize() {
251237
const frame = getIframe();
252238

253-
if(!isDesktop() && !document.body.classList.contains(PREVENT_SCROLLING_CLASS)) {
254-
if (document.scrollingElement) {
255-
agentforce_messaging.documentScrollPosition = document.scrollingElement.scrollTop;
256-
} else {
257-
const docElementRect = document.documentElement.getBoundingClientRect();
258-
agentforce_messaging.documentScrollPosition = Math.abs(docElementRect.top);
259-
}
239+
if(!isDesktop()) {
240+
// [Mobile] Add class that prevents background clicking and scrolling.
260241
document.body.classList.add(PREVENT_SCROLLING_CLASS);
261242
}
262243

@@ -271,11 +252,8 @@
271252
}
272253
}
273254

274-
frame.classList.remove("initial");
275255
frame.classList.add("maximized");
276256
frame.classList.remove("minimized");
277-
278-
dispatchEventToHost(hostEvents.ON_EMBEDDED_MESSAGING_WINDOW_MAXIMIZED_EVENT_NAME);
279257
}
280258
}
281259

@@ -464,7 +442,7 @@
464442
shouldProcessApiCall();
465443

466444
const iframe = getIframe();
467-
if (iframe && !iframe.classList.contains("maximized")) {
445+
if (iframe && iframe.classList.contains("minimized")) {
468446
// Unhide iframe in case hideChatButton was previously called.
469447
toggleChatFabVisibility(false);
470448
return callRpcClient("launchChat")
@@ -572,6 +550,32 @@
572550
});
573551
};
574552

553+
/**
554+
* Handle the onEmbeddedMessagingButtonCreated event.
555+
* Sets CSS variables for minimized iframe dimensions and unhides the iframe.
556+
* @param {CustomEvent} event - Button created event containing button dimensions
557+
*/
558+
function handleButtonCreatedEvent(event) {
559+
const buttonWidth = event?.detail?.buttonDimensions?.width;
560+
const buttonHeight = event?.detail?.buttonDimensions?.height;
561+
562+
if (buttonWidth) {
563+
document.documentElement.style.setProperty('--minimized-iframe-width', buttonWidth);
564+
}
565+
if (buttonHeight) {
566+
document.documentElement.style.setProperty('--minimized-iframe-height', buttonHeight);
567+
}
568+
569+
unhideIframe();
570+
}
571+
572+
/**
573+
* Adds event listeners on host window.
574+
*/
575+
function addEventHandlers() {
576+
window.addEventListener('onEmbeddedMessagingButtonCreated', handleButtonCreatedEvent);
577+
}
578+
575579
/**
576580
* Load the bootstrap.css file for this static file.
577581
*/
@@ -671,7 +675,6 @@
671675
// Iframe app ready event handler
672676
rpcManager.registerHandler("ESW_APP_READY_EVENT", async () => {
673677
await appReadyPromise;
674-
unhideIframe();
675678
const configuration = prepareConfigObject();
676679
return { configuration };
677680
});
@@ -793,12 +796,62 @@
793796
* @param {object} additionalSettings - A key-value mapping.
794797
*/
795798
function mergeObjects(targetObj, sourceObj) {
799+
/**
800+
* Helper function to create a map from array items based on key properties
801+
* @param {Array} array - The array to create a map from
802+
* @param {Function} keyExtractor - Function to extract key from array item
803+
* @returns {Map} Map of key to index
804+
*/
805+
function createArrayMap(array, keyExtractor) {
806+
const map = new Map();
807+
array.forEach((item, index) => {
808+
if (typeof item === 'object' && item !== null) {
809+
const key = keyExtractor(item);
810+
if (key !== null) {
811+
map.set(key, index);
812+
}
813+
}
814+
});
815+
return map;
816+
}
817+
818+
/**
819+
* Helper function to merge arrays with custom key matching
820+
* @param {Array} targetArray - Target array to merge into
821+
* @param {Array} sourceArray - Source array to merge from
822+
* @param {Function} keyExtractor - Function to extract key from array item
823+
*/
824+
function mergeArraysWithKeyMatching(targetArray, sourceArray, keyExtractor) {
825+
const targetMap = createArrayMap(targetArray, keyExtractor);
826+
827+
sourceArray.forEach((sourceItem) => {
828+
if (typeof sourceItem === 'object' && sourceItem !== null) {
829+
const key = keyExtractor(sourceItem);
830+
if (key !== null && !targetMap.has(key)) {
831+
targetArray.push(sourceItem);
832+
}
833+
}
834+
});
835+
}
836+
796837
Object.keys(sourceObj).forEach((key) => {
797838
if (Array.isArray(sourceObj[key])) {
798839
// Handle array merging
799840
if (Array.isArray(targetObj[key])) {
800-
// If both are arrays, append items in source array to target array
801-
targetObj[key].push(...sourceObj[key]);
841+
if (key === 'branding') {
842+
// For branding, merge arrays based on 'n' property
843+
mergeArraysWithKeyMatching(targetObj[key], sourceObj[key], (item) =>
844+
Object.hasOwn(item, 'n') ? item.n : null
845+
);
846+
} else if (key === 'customLabels') {
847+
// For custom labels, merge arrays based on 'sectionName' and 'labelName' properties
848+
mergeArraysWithKeyMatching(targetObj[key], sourceObj[key], (item) =>
849+
(Object.hasOwn(item, 'sectionName') && Object.hasOwn(item, 'labelName'))
850+
? item.sectionName + item.labelName
851+
: null
852+
);
853+
}
854+
// For other array types, keep target array as is (no merging)
802855
} else if (targetObj[key] === undefined) {
803856
// If array exists in source but not target, just use it
804857
targetObj[key] = sourceObj[key];
@@ -812,6 +865,7 @@
812865
}
813866
});
814867
}
868+
815869
AgentforceMessaging.prototype.createIframe = function createIframe() {
816870
return new Promise((resolve, reject) => {
817871
try {
@@ -872,6 +926,9 @@
872926
agentforce_messaging.settings.snippetConfig = snippetConfig;
873927
mergeObjects(agentforce_messaging.settings, snippetConfig);
874928

929+
// Add event listeners.
930+
addEventHandlers();
931+
875932
// Load CSS file.
876933
const cssPromise = loadCSS()
877934
.then(() => {
@@ -924,6 +981,13 @@
924981
}
925982
};
926983

984+
/**
985+
* Remove event listeners on host window.
986+
*/
987+
AgentforceMessaging.prototype.removeEventHandlers = function removeEventHandlers() {
988+
window.removeEventListener('onEmbeddedMessagingButtonCreated', handleButtonCreatedEvent);
989+
};
990+
927991
// Function to create a proxy that forwards to a target object
928992
function createProxy(targetObject, objectName, functionMap = {}) {
929993
return new Proxy({}, {

0 commit comments

Comments
 (0)