Built motion from commit 97153652.|2.6.26
[motion2.git] / server / files / chat / iframe.ejs
1 (function() {
2     'use strict';
3     try {
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.`)
7         }
8     } catch (error) {
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.`)
10         return 
11     }
12         // Init all URLs
13         const remoteURL = new URL('{{{remote}}}')
14         const chatOrigin = remoteURL.origin
15         const chatPath = '/snippet/'
16         const chatStylesPath = chatPath + 'styles/'
17         const chatVersion = '{{{chatVersion}}}'
18
19         // Style setttings
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%>";
26
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
34
35         // Style URL settings
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()
42
43         // Iframe localstorage whitelisting
44         const allowedOrigins = [chatOrigin]
45
46         function remoteLocalStorageEventHandler(event){
47             if (allowedOrigins.includes(event.origin)) {
48                 const { action, key, value } = event.data
49                 const localStorage = window.localStorage
50                 switch(action){
51                     case 'setItem':
52                         {
53                             localStorage.setItem(key, JSON.stringify(value))
54                             event.source.postMessage(
55                                 {
56                                 action: 'setItemResult',
57                                 key
58                                 }, event.origin)
59                         }
60                         break
61                     case 'getItem':
62                         {
63                             let item = localStorage.getItem(key)
64                             if(item){
65                                 try {
66                                     item = JSON.parse(item)
67                                 } catch (error) {
68                                     console.error('Cannot read data from localstorage', error)
69                                 }
70                             }
71                             event.source.postMessage(
72                                 {
73                                 action: 'getItemResult',
74                                 key,
75                                 item
76                                 }, event.origin)
77                         }
78                         break
79                     case 'removeItem':
80                         {   
81                             localStorage.removeItem(key)
82                             event.source.postMessage(
83                                 {
84                                 action: 'removeItemResult',
85                                 key
86                                 }, event.origin)
87                         }
88                         break
89                     default:
90                         typeof action === 'string' && console.debug('Unsupported action', action)
91                     break;
92                 }
93             }
94         }
95
96         // DOM Manipulation
97         let iframe = document.createElement('iframe');
98         // Attributes
99         iframe['id'] = iframeId;
100         iframe['src'] = iframeSrcURL.toString()
101
102         let  iframe_status = false;
103
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);
108     
109         document.head.appendChild(linkMobile);
110
111         <% if (alignment == 'bottom_right') { -%> // Bottom, right
112             iframe.className = 'motion-chat-iframe-bottom_right';
113             verticalAlignment = 0;
114             document.body.appendChild(iframe);
115
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';
124             let  tab_status=0;
125
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';
134             let  tab_status=0;
135
136         <% } -%>   
137
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;
143             
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";
149             
150             function appendLink(){
151                 if(iframe_status == false){
152                     document.body.appendChild(iframe);
153                     iframe_status=true;
154                 }      
155             }
156
157             function expandChatRight(){
158                 appendLink()
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"}, '*');
164             }
165
166             function collapseChatRight(){
167                 appendLink()
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"}, '*');
173             }
174
175             function toggleChatExpandedRight(){    
176                 if(tab_status % 2 === 0) {
177                     expandChatRight()
178                 }
179                 else {
180                     collapseChatRight()
181                 }
182                 tab_status++;
183             }
184
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;
191
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";
197
198             function appendLink(){
199                 if(iframe_status == false){
200                     document.body.appendChild(iframe);
201                     iframe_status=true;
202                 }   
203             }
204
205             function expandChatLeft(){
206                 appendLink()
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"}, '*');
212             }
213
214             function collapseChatLeft(){
215                 appendLink()
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"}, '*');
221             }
222
223             function toggleChatExpandedLeft(){
224                 if(tab_status % 2 === 0) {
225                     expandChatLeft()
226                 }   
227                 else {
228                     collapseChatLeft()
229                 }   
230                 tab_status++;
231             }
232
233             document.getElementById("motion-chat-iframe-tab").addEventListener("click", toggleChatExpandedLeft); 
234
235             <% } -%>    
236
237         // START Events management
238         window.addEventListener('message', function(evt) {
239             remoteLocalStorageEventHandler(evt)
240             switch (evt.data.cmd) {
241                 case 'show':
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';
251                     // Left    
252                     <% } -%>                break;
253                 case 'hide':
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';
262                     <% } -%>                break;
263                 case "init": 
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";
270                     <% } -%>                break;
271                 case "offline": 
272                     <% if (alignment == 'right' || alignment == 'left') { -%> // Bottom, right
273                         document.getElementById("motion-chat-iframe-tab").style.display = "none";
274                     <% } -%>                break;
275                 default:
276             }
277
278         }, false);
279         // END Events management
280
281         // START Proactive action management
282         <% proactiveActions.forEach(function(action, index) { -%>
283             <% if (action.type == 'timeout') { -%>        
284             setTimeout(function() {
285                 <% if (alignment == 'right') { -%>
286                 expandChatRight();
287                 tab_status++;
288                 <% } else if (alignment == 'left') { -%> 
289                 expandChatLeft();
290                 tab_status++;
291                 <% } else { -%> 
292                 iframe.style.bottom = '0px';
293                 iframe.contentWindow?.postMessage({
294                     evt: 'show'
295                 }, '*');
296                 <% } -%> 
297             }, <%- action.timeout %> * 1000);
298         <% } -%>
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') { -%>
304                 expandChatRight();
305                 tab_status++;
306                 <% } else if (alignment == 'left') { -%> 
307                 expandChatLeft();
308                 tab_status++;
309                 <% } else { -%> 
310                 iframe.style.bottom = '0px';
311                 iframe.contentWindow?.postMessage({
312                     evt: 'show'
313                 }, '*');
314                 <% } -%> 
315             }
316         }
317         <% } -%>    <% }); -%>
318         // END Proactive action management
319         
320
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"}, '*');
327                 tab_status = 0;
328                 iframe_h = topIframe_calc();
329                 topIframe_set(iframe_h);
330                 if(typeof div_tab != "undefined") topChat_set(iframe_h, verticalAlignment);
331             }
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"}, '*');
336                 tab_status = 0;
337                 iframe_h = topIframe_calc();
338                 topIframe_set(iframe_h);
339                 if(typeof div_tab != "undefined") topChat_set(iframe_h, verticalAlignment);
340             } }, false);
341         }
342
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);
347         });
348
349         function topIframe_calc(){
350         let height_iframe
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);
355         }
356         else { height_iframe = 450; }
357         return height_iframe;
358         }
359
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%"; }
366
367             }
368             else {
369             iframe.style['height'] = '340px';
370             if (alignment == "right" || alignment == "left" )
371             { iframe.style['top'] = "calc(100% - 340px)"; }
372             else{ iframe.style['bottom'] = "0%"; }
373
374             }
375         }
376     
377         function topChat_set(height_iframe, verticalAlignment){
378     
379         if( height_iframe > 340){
380             div_tab.style['top'] = "calc("+ verticalAlignment +"% + " + (height_iframe - 100) + "px)";
381         }
382         else {
383             div_tab.style['top'] = "auto";
384             div_tab.style['bottom'] = "0px";
385         }
386         }
387
388         // hide chat
389         <% if (hideWhenOffline && intervalId != null) { -%> // hide template
390             document.getElementById("motion-chat-iframe-tab").style.display = "none";
391         <% } -%>
392 }());