3 const chatWebsiteAddressOrigin = '{{{chatWebsiteAddressOrigin}}}'
4 if(chatWebsiteAddressOrigin !== window.location.origin){
5 alert(`The current location does not match ${chatWebsiteAddressOrigin}. Please check your website domain in the current XCALLY Chat Website settings.`)
10 const remoteURL = new URL('{{{remote}}}')
11 const chatOrigin = remoteURL.origin
12 const chatPath = '/snippet/'
13 const chatStylesPath = chatPath + 'styles/'
14 const chatVersion = '{{{chatVersion}}}'
17 const divColor = '<%=div_color%>'
18 const textColor = '<%=text_color%>'
19 const buttonColor = '<%=button_color%>'
20 const backgroungColor = '<%=background_color%>'
21 let alignment = "<%=alignment%>";
22 let verticalAlignment = "<%=verticalAlignment%>";
24 // iframe URL settings
25 const iframeId = 'motion-chat-iframe'
26 const iframeSrcURL = new URL(chatPath, chatOrigin)
27 const iframeSearchParams = new URLSearchParams('{{{query}}}')
28 iframeSearchParams.append('version', chatVersion)
29 iframeSearchParams.append('location', btoa(window.location.host))
30 iframeSrcURL.search = iframeSearchParams
33 const linkURL = new URL(chatStylesPath + 'mobile.css', chatOrigin)
34 linkURL.search = new URLSearchParams({ version: chatVersion })
35 const linkMobile = document.createElement('link');
36 linkMobile.type = "text/css";
37 linkMobile.rel='stylesheet';
38 linkMobile.href = linkURL.toString()
40 // Iframe localstorage whitelisting
41 const allowedOrigins = [chatOrigin]
43 function remoteLocalStorageEventHandler(event){
44 if (allowedOrigins.includes(event.origin)) {
45 const { action, key, value } = event.data
46 const localStorage = window.localStorage
50 localStorage.setItem(key, JSON.stringify(value))
51 event.source.postMessage(
53 action: 'setItemResult',
60 let item = localStorage.getItem(key)
63 item = JSON.parse(item)
65 console.error('Cannot read data from localstorage', error)
68 event.source.postMessage(
70 action: 'getItemResult',
78 localStorage.removeItem(key)
79 event.source.postMessage(
81 action: 'removeItemResult',
87 typeof action === 'string' && console.debug('Unsupported action', action)
94 let iframe = document.createElement('iframe');
96 iframe['id'] = iframeId;
97 iframe['src'] = iframeSrcURL.toString()
99 let iframe_status = false;
101 document.documentElement.style.setProperty('--xc-ws-div-color', divColor);
102 document.documentElement.style.setProperty('--xc-ws-text-color', textColor);
103 document.documentElement.style.setProperty('--xc-ws-button-color', buttonColor);
104 document.documentElement.style.setProperty('--xc-ws-background-color', backgroungColor);
106 document.head.appendChild(linkMobile);
108 <% if (alignment == 'bottom_right') { -%> // Bottom, right
109 iframe.className = 'motion-chat-iframe-bottom_right';
110 verticalAlignment = 0;
111 document.body.appendChild(iframe);
113 <% } else if (alignment == 'right') { -%> // Right
114 iframe.className = 'motion-chat-iframe-right';
115 iframe.style['top'] = verticalAlignment+'%';
116 let iframe_h = topIframe_calc();
117 topIframe_set(iframe_h);
118 let div_tab = document.createElement('div');
119 div_tab['id'] = 'motion-chat-iframe-tab';
120 div_tab.className = 'motion-chat-div-right';
123 <% } else if (alignment == 'left') { -%> // Left
124 iframe.className = 'motion-chat-iframe-left';
125 iframe.style['top'] = verticalAlignment+'%';
126 let iframe_h = topIframe_calc();
127 topIframe_set(iframe_h);
128 let div_tab = document.createElement('div');
129 div_tab.className = 'motion-chat-div-left';
130 div_tab['id'] ='motion-chat-iframe-tab';
135 <% if (alignment == 'right') { -%> // Right
136 topChat_set(iframe_h, verticalAlignment);
137 document.body.appendChild(div_tab);
138 let html = '<div id="chat_tab_arrow"> <strong><</strong> </div> <span id="chat_tab_text" style="writing-mode: tb-rl; transform: rotate(-180deg);" flex><strong><%=labelText%></strong></span>';
139 div_tab.innerHTML = html;
141 div_tab.style.backgroundColor = divColor;
142 document.getElementById("chat_tab_text").style.color = textColor;
143 document.getElementById("chat_tab_arrow").style.color = divColor
144 document.getElementById("chat_tab_arrow").style.backgroundColor = textColor;
145 document.getElementById("motion-chat-iframe-tab").style.display = "flex";
147 function appendLink(){
148 if(iframe_status == false){
149 document.body.appendChild(iframe);
154 function expandChatRight(){
156 div_tab.style.right = '295px';
157 iframe.style.right = '0px';
158 document.getElementById("chat_tab_arrow").innerHTML = "<strong> > </strong>";
159 let iframeEl = document.getElementById('motion-chat-iframe');
160 iframeEl.contentWindow?.postMessage({"evt":"show"}, '*');
163 function collapseChatRight(){
165 div_tab.style.right = '0px';
166 iframe.style.right = '-312px';
167 document.getElementById("chat_tab_arrow").innerHTML = "<strong> < </strong>";
168 let iframeEl = document.getElementById('motion-chat-iframe');
169 iframeEl.contentWindow?.postMessage({"evt":"hide"}, '*');
172 function toggleChatExpandedRight(){
173 if(tab_status % 2 === 0) {
182 document.getElementById("motion-chat-iframe-tab").addEventListener("click", toggleChatExpandedRight);
183 <% } else if (alignment == 'left') { -%>
184 topChat_set(iframe_h, verticalAlignment);
185 document.body.appendChild(div_tab);
186 let html='<div id="chat_tab_arrow"> <strong>></strong> </div><span id="chat_tab_text" style="writing-mode: tb-rl; transform: rotate(-180deg);" flex><strong><%=labelText%></strong></span>';
187 div_tab.innerHTML=html;
189 div_tab.style.backgroundColor = divColor;
190 document.getElementById("chat_tab_text").style.color = textColor;
191 document.getElementById("chat_tab_arrow").style.color = divColor;
192 document.getElementById("chat_tab_arrow").style.backgroundColor = textColor;
193 document.getElementById("motion-chat-iframe-tab").style.display="flex";
195 function appendLink(){
196 if(iframe_status == false){
197 document.body.appendChild(iframe);
202 function expandChatLeft(){
204 div_tab.style.left = '295px';
205 iframe.style.left = '0px';
206 document.getElementById("chat_tab_arrow").innerHTML = "<strong> < </strong>";
207 let iframeEl = document.getElementById('motion-chat-iframe');
208 iframeEl.contentWindow?.postMessage({"evt":"show"}, '*');
211 function collapseChatLeft(){
213 div_tab.style.left = '0px';
214 iframe.style.left = '-312px';
215 document.getElementById("chat_tab_arrow").innerHTML = "<strong> > </strong>";
216 let iframeEl = document.getElementById('motion-chat-iframe');
217 iframeEl.contentWindow?.postMessage({"evt":"hide"}, '*');
220 function toggleChatExpandedLeft(){
221 if(tab_status % 2 === 0) {
230 document.getElementById("motion-chat-iframe-tab").addEventListener("click", toggleChatExpandedLeft);
234 // START Events management
235 window.addEventListener('message', function(evt) {
236 remoteLocalStorageEventHandler(evt)
237 switch (evt.data.cmd) {
239 <% if (alignment == 'bottom_right') { -%> // Bottom, right
240 iframe.style.top = 'auto';
241 iframe.style.bottom = '0px';
242 <% } else if (alignment == 'right') { -%> // Right
243 iframe.style.right = '0px';
244 div_tab.style.right = '295px';
245 <% } else if (alignment == 'left') { -%> // Left
246 iframe.style.left = '0px';
247 div_tab.style.left = '295px';
251 <% if (alignment == 'bottom_right') { -%> // Bottom, right
252 iframe.style.top = 'calc(100% - 50px)';
253 <% } else if (alignment == 'right') { -%> // Right
254 iframe.style.right = '-312px';
255 div_tab.style['right'] = '0px';
256 <% } else if (alignment == 'left') { -%> // Left
257 iframe.style.left = '-312px';
258 div_tab.style.left = '0px';
261 <% if (alignment == 'right' || alignment == 'left') { -%> // Bottom, right
262 div_tab.style.backgroundColor = divColor;
263 document.getElementById("chat_tab_text").style.color = textColor;
264 document.getElementById("chat_tab_arrow").style.color = divColor;
265 document.getElementById("chat_tab_arrow").style.backgroundColor = textColor;
266 document.getElementById("motion-chat-iframe-tab").style.display = "flex";
269 <% if (alignment == 'right' || alignment == 'left') { -%> // Bottom, right
270 document.getElementById("motion-chat-iframe-tab").style.display = "none";
276 // END Events management
278 // START Proactive action management
279 <% proactiveActions.forEach(function(action, index) { -%>
280 <% if (action.type == 'timeout') { -%>
281 setTimeout(function() {
282 <% if (alignment == 'right') { -%>
285 <% } else if (alignment == 'left') { -%>
289 iframe.style.bottom = '0px';
290 iframe.contentWindow?.postMessage({
294 }, <%- action.timeout %> * 1000);
296 <% if (action.type == 'mouseOver') { -%>
297 let elements<%- index %> = document.querySelectorAll("<%- action.selector %>");
298 for (let i = 0; i < elements<%- index %>.length; i++) {
299 elements<%- index %>[i].onmouseover = function() {
300 <% if (alignment == 'right') { -%>
303 <% } else if (alignment == 'left') { -%>
307 iframe.style.bottom = '0px';
308 iframe.contentWindow?.postMessage({
315 // END Proactive action management
318 if (window.DeviceOrientationEvent) {
319 window.addEventListener('orientationchange', function() {
320 if (alignment == 'right'){
321 document.getElementById("chat_tab_arrow").innerHTML = "<strong> < </strong>";
322 let iframeEl = document.getElementById('motion-chat-iframe');
323 iframeEl.contentWindow?.postMessage({"evt":"hide"}, '*');
325 iframe_h = topIframe_calc();
326 topIframe_set(iframe_h);
327 if(typeof div_tab != "undefined") topChat_set(iframe_h, verticalAlignment);
329 else if (alignment == 'left'){
330 document.getElementById("chat_tab_arrow").innerHTML = "<strong> > </strong>";
331 let iframeEl = document.getElementById('motion-chat-iframe');
332 iframeEl.contentWindow?.postMessage({"evt":"hide"}, '*');
334 iframe_h = topIframe_calc();
335 topIframe_set(iframe_h);
336 if(typeof div_tab != "undefined") topChat_set(iframe_h, verticalAlignment);
340 window.addEventListener("resize", function(event) {
341 let iframe_h = topIframe_calc();
342 topIframe_set(iframe_h);
343 if(typeof div_tab != "undefined") topChat_set(iframe_h, verticalAlignment);
346 function topIframe_calc(){
348 let heightD = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
349 let iframeT = ((heightD/100)*verticalAlignment) + 450;
350 if (heightD < iframeT) {
351 height_iframe = 450 - (iframeT - heightD);
353 else { height_iframe = 450; }
354 return height_iframe;
357 function topIframe_set(height_iframe){
358 if( height_iframe > 340){
359 iframe.style['height'] = height_iframe +'px';
360 if (alignment == "right" || alignment == "left" )
361 { iframe.style['top'] = verticalAlignment + "%"; }
362 else{ iframe.style['bottom'] = "0%"; }
366 iframe.style['height'] = '340px';
367 if (alignment == "right" || alignment == "left" )
368 { iframe.style['top'] = "calc(100% - 340px)"; }
369 else{ iframe.style['bottom'] = "0%"; }
374 function topChat_set(height_iframe, verticalAlignment){
376 if( height_iframe > 340){
377 div_tab.style['top'] = "calc("+ verticalAlignment +"% + " + (height_iframe - 100) + "px)";
380 div_tab.style['top'] = "auto";
381 div_tab.style['bottom'] = "0px";
386 <% if (hideWhenOffline && intervalId != null) { -%> // hide template
387 document.getElementById("motion-chat-iframe-tab").style.display = "none";