4 const chatWebsiteAddress = new URL('{{{chatWebsiteAddressOrigin}}}')
5 if (chatWebsiteAddress.origin !== window.location.origin){
6 throw new Error(`Domain "${window.location.origin}"" can't load snippet for '{{{chatWebsiteAddressOrigin}}}'. Please check your website domain in the current XCALLY Chat Website settings.`)
9 window.alert(`Domain ${window.location.origin} can't load snippet for '{{{chatWebsiteAddressOrigin}}}'. Please check your website domain in the current XCALLY Chat Website settings.`)
13 const remoteURL = new URL('{{{remote}}}')
14 const chatOrigin = remoteURL.origin
15 const chatPath = '/snippet/'
16 const chatStylesPath = chatPath + 'styles/'
17 const chatVersion = '{{{chatVersion}}}'
20 const divColor = '<%=div_color%>'
21 const textColor = '<%=text_color%>'
22 const buttonColor = '<%=button_color%>'
23 const backgroungColor = '<%=background_color%>'
24 let alignment = "<%=alignment%>";
25 let verticalAlignment = "<%=verticalAlignment%>";
27 // iframe URL settings
28 const iframeId = 'motion-chat-iframe'
29 const iframeSrcURL = new URL(chatPath, chatOrigin)
30 const iframeSearchParams = new URLSearchParams('{{{query}}}')
31 iframeSearchParams.append('version', chatVersion)
32 iframeSearchParams.append('location', btoa(window.location.host))
33 iframeSrcURL.search = iframeSearchParams
36 const linkURL = new URL(chatStylesPath + 'mobile.css', chatOrigin)
37 linkURL.search = new URLSearchParams({ version: chatVersion })
38 const linkMobile = document.createElement('link');
39 linkMobile.type = "text/css";
40 linkMobile.rel='stylesheet';
41 linkMobile.href = linkURL.toString()
43 // Iframe localstorage whitelisting
44 const allowedOrigins = [chatOrigin]
46 function remoteLocalStorageEventHandler(event){
47 if (allowedOrigins.includes(event.origin)) {
48 const { action, key, value } = event.data
49 const localStorage = window.localStorage
53 localStorage.setItem(key, JSON.stringify(value))
54 event.source.postMessage(
56 action: 'setItemResult',
63 let item = localStorage.getItem(key)
66 item = JSON.parse(item)
68 console.error('Cannot read data from localstorage', error)
71 event.source.postMessage(
73 action: 'getItemResult',
81 localStorage.removeItem(key)
82 event.source.postMessage(
84 action: 'removeItemResult',
90 typeof action === 'string' && console.debug('Unsupported action', action)
97 let iframe = document.createElement('iframe');
99 iframe['id'] = iframeId;
100 iframe['src'] = iframeSrcURL.toString()
102 let iframe_status = false;
104 document.documentElement.style.setProperty('--xc-ws-div-color', divColor);
105 document.documentElement.style.setProperty('--xc-ws-text-color', textColor);
106 document.documentElement.style.setProperty('--xc-ws-button-color', buttonColor);
107 document.documentElement.style.setProperty('--xc-ws-background-color', backgroungColor);
109 document.head.appendChild(linkMobile);
111 <% if (alignment == 'bottom_right') { -%> // Bottom, right
112 iframe.className = 'motion-chat-iframe-bottom_right';
113 verticalAlignment = 0;
114 document.body.appendChild(iframe);
116 <% } else if (alignment == 'right') { -%> // Right
117 iframe.className = 'motion-chat-iframe-right';
118 iframe.style['top'] = verticalAlignment+'%';
119 let iframe_h = topIframe_calc();
120 topIframe_set(iframe_h);
121 let div_tab = document.createElement('div');
122 div_tab['id'] = 'motion-chat-iframe-tab';
123 div_tab.className = 'motion-chat-div-right';
126 <% } else if (alignment == 'left') { -%> // Left
127 iframe.className = 'motion-chat-iframe-left';
128 iframe.style['top'] = verticalAlignment+'%';
129 let iframe_h = topIframe_calc();
130 topIframe_set(iframe_h);
131 let div_tab = document.createElement('div');
132 div_tab.className = 'motion-chat-div-left';
133 div_tab['id'] ='motion-chat-iframe-tab';
138 <% if (alignment == 'right') { -%> // Right
139 topChat_set(iframe_h, verticalAlignment);
140 document.body.appendChild(div_tab);
141 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>';
142 div_tab.innerHTML = html;
144 div_tab.style.backgroundColor = divColor;
145 document.getElementById("chat_tab_text").style.color = textColor;
146 document.getElementById("chat_tab_arrow").style.color = divColor
147 document.getElementById("chat_tab_arrow").style.backgroundColor = textColor;
148 document.getElementById("motion-chat-iframe-tab").style.display = "flex";
150 function appendLink(){
151 if(iframe_status == false){
152 document.body.appendChild(iframe);
157 function expandChatRight(){
159 div_tab.style.right = '295px';
160 iframe.style.right = '0px';
161 document.getElementById("chat_tab_arrow").innerHTML = "<strong> > </strong>";
162 let iframeEl = document.getElementById('motion-chat-iframe');
163 iframeEl.contentWindow?.postMessage({"evt":"show"}, '*');
166 function collapseChatRight(){
168 div_tab.style.right = '0px';
169 iframe.style.right = '-312px';
170 document.getElementById("chat_tab_arrow").innerHTML = "<strong> < </strong>";
171 let iframeEl = document.getElementById('motion-chat-iframe');
172 iframeEl.contentWindow?.postMessage({"evt":"hide"}, '*');
175 function toggleChatExpandedRight(){
176 if(tab_status % 2 === 0) {
185 document.getElementById("motion-chat-iframe-tab").addEventListener("click", toggleChatExpandedRight);
186 <% } else if (alignment == 'left') { -%>
187 topChat_set(iframe_h, verticalAlignment);
188 document.body.appendChild(div_tab);
189 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>';
190 div_tab.innerHTML=html;
192 div_tab.style.backgroundColor = divColor;
193 document.getElementById("chat_tab_text").style.color = textColor;
194 document.getElementById("chat_tab_arrow").style.color = divColor;
195 document.getElementById("chat_tab_arrow").style.backgroundColor = textColor;
196 document.getElementById("motion-chat-iframe-tab").style.display="flex";
198 function appendLink(){
199 if(iframe_status == false){
200 document.body.appendChild(iframe);
205 function expandChatLeft(){
207 div_tab.style.left = '295px';
208 iframe.style.left = '0px';
209 document.getElementById("chat_tab_arrow").innerHTML = "<strong> < </strong>";
210 let iframeEl = document.getElementById('motion-chat-iframe');
211 iframeEl.contentWindow?.postMessage({"evt":"show"}, '*');
214 function collapseChatLeft(){
216 div_tab.style.left = '0px';
217 iframe.style.left = '-312px';
218 document.getElementById("chat_tab_arrow").innerHTML = "<strong> > </strong>";
219 let iframeEl = document.getElementById('motion-chat-iframe');
220 iframeEl.contentWindow?.postMessage({"evt":"hide"}, '*');
223 function toggleChatExpandedLeft(){
224 if(tab_status % 2 === 0) {
233 document.getElementById("motion-chat-iframe-tab").addEventListener("click", toggleChatExpandedLeft);
237 // START Events management
238 window.addEventListener('message', function(evt) {
239 remoteLocalStorageEventHandler(evt)
240 switch (evt.data.cmd) {
242 <% if (alignment == 'bottom_right') { -%> // Bottom, right
243 iframe.style.top = 'auto';
244 iframe.style.bottom = '0px';
245 <% } else if (alignment == 'right') { -%> // Right
246 iframe.style.right = '0px';
247 div_tab.style.right = '295px';
248 <% } else if (alignment == 'left') { -%> // Left
249 iframe.style.left = '0px';
250 div_tab.style.left = '295px';
254 <% if (alignment == 'bottom_right') { -%> // Bottom, right
255 iframe.style.top = 'calc(100% - 50px)';
256 <% } else if (alignment == 'right') { -%> // Right
257 iframe.style.right = '-312px';
258 div_tab.style['right'] = '0px';
259 <% } else if (alignment == 'left') { -%> // Left
260 iframe.style.left = '-312px';
261 div_tab.style.left = '0px';
264 <% if (alignment == 'right' || alignment == 'left') { -%> // Bottom, right
265 div_tab.style.backgroundColor = divColor;
266 document.getElementById("chat_tab_text").style.color = textColor;
267 document.getElementById("chat_tab_arrow").style.color = divColor;
268 document.getElementById("chat_tab_arrow").style.backgroundColor = textColor;
269 document.getElementById("motion-chat-iframe-tab").style.display = "flex";
272 <% if (alignment == 'right' || alignment == 'left') { -%> // Bottom, right
273 document.getElementById("motion-chat-iframe-tab").style.display = "none";
279 // END Events management
281 // START Proactive action management
282 <% proactiveActions.forEach(function(action, index) { -%>
283 <% if (action.type == 'timeout') { -%>
284 setTimeout(function() {
285 <% if (alignment == 'right') { -%>
288 <% } else if (alignment == 'left') { -%>
292 iframe.style.bottom = '0px';
293 iframe.contentWindow?.postMessage({
297 }, <%- action.timeout %> * 1000);
299 <% if (action.type == 'mouseOver') { -%>
300 let elements<%- index %> = document.querySelectorAll("<%- action.selector %>");
301 for (let i = 0; i < elements<%- index %>.length; i++) {
302 elements<%- index %>[i].onmouseover = function() {
303 <% if (alignment == 'right') { -%>
306 <% } else if (alignment == 'left') { -%>
310 iframe.style.bottom = '0px';
311 iframe.contentWindow?.postMessage({
318 // END Proactive action management
321 if (window.DeviceOrientationEvent) {
322 window.addEventListener('orientationchange', function() {
323 if (alignment == 'right'){
324 document.getElementById("chat_tab_arrow").innerHTML = "<strong> < </strong>";
325 let iframeEl = document.getElementById('motion-chat-iframe');
326 iframeEl.contentWindow?.postMessage({"evt":"hide"}, '*');
328 iframe_h = topIframe_calc();
329 topIframe_set(iframe_h);
330 if(typeof div_tab != "undefined") topChat_set(iframe_h, verticalAlignment);
332 else if (alignment == 'left'){
333 document.getElementById("chat_tab_arrow").innerHTML = "<strong> > </strong>";
334 let iframeEl = document.getElementById('motion-chat-iframe');
335 iframeEl.contentWindow?.postMessage({"evt":"hide"}, '*');
337 iframe_h = topIframe_calc();
338 topIframe_set(iframe_h);
339 if(typeof div_tab != "undefined") topChat_set(iframe_h, verticalAlignment);
343 window.addEventListener("resize", function(event) {
344 let iframe_h = topIframe_calc();
345 topIframe_set(iframe_h);
346 if(typeof div_tab != "undefined") topChat_set(iframe_h, verticalAlignment);
349 function topIframe_calc(){
351 let heightD = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
352 let iframeT = ((heightD/100)*verticalAlignment) + 450;
353 if (heightD < iframeT) {
354 height_iframe = 450 - (iframeT - heightD);
356 else { height_iframe = 450; }
357 return height_iframe;
360 function topIframe_set(height_iframe){
361 if( height_iframe > 340){
362 iframe.style['height'] = height_iframe +'px';
363 if (alignment == "right" || alignment == "left" )
364 { iframe.style['top'] = verticalAlignment + "%"; }
365 else{ iframe.style['bottom'] = "0%"; }
369 iframe.style['height'] = '340px';
370 if (alignment == "right" || alignment == "left" )
371 { iframe.style['top'] = "calc(100% - 340px)"; }
372 else{ iframe.style['bottom'] = "0%"; }
377 function topChat_set(height_iframe, verticalAlignment){
379 if( height_iframe > 340){
380 div_tab.style['top'] = "calc("+ verticalAlignment +"% + " + (height_iframe - 100) + "px)";
383 div_tab.style['top'] = "auto";
384 div_tab.style['bottom'] = "0px";
389 <% if (hideWhenOffline && intervalId != null) { -%> // hide template
390 document.getElementById("motion-chat-iframe-tab").style.display = "none";