3bbfa2b26eb812d63f9eabe313e1f8475d35bebe
[mkjsf-moved-to-github.git] / src / META-INF / resources / pz2utils / listeners.js
1 var renderTargetsReqVar;\r
2 var renderOnRecordTargetsReqVar;\r
3 \r
4 // Renders UI elements listed in 'renderWhileActiveclients', optionally doing\r
5 // another update round-trip to Pazpar2 when done.\r
6 function renderTargets(doRefresh) {\r
7   // console.log('rendering ' + renderWhileActiveclients);\r
8   var sourcecomp = document.getElementById("pz2watch:activeclientsField");\r
9   jsf.ajax.request(sourcecomp, null, {\r
10     render : renderWhileActiveclients\r
11   });\r
12   if (doRefresh) {\r
13     // console.log('Will do another ajax request after a timeout in order to\r
14     // render: pz2watch:activeclientsField');\r
15     renderTargetsReqVar = setTimeout(function() {\r
16       // console.log('Making request for pz2watch:activeclientsField');\r
17       jsf.ajax.request(sourcecomp, null, {\r
18         render : "pz2watch:activeclientsField"\r
19       });\r
20     }, 500);\r
21   } else {\r
22     // console.log("No further updates from server requested");\r
23   }\r
24 }\r
25 \r
26 // Renders UI elements listed in 'renderWhileActiveclientsRecord', optionally\r
27 // doing\r
28 // another record request when done.\r
29 function renderOnRecordTargets(doRefresh) {\r
30   // console.log('rendering ' + renderWhileActiveclientsRecord);\r
31   var sourcecomp = document.getElementById("pz2watch:activeclientsFieldRecord");\r
32   jsf.ajax.request(sourcecomp, null, {\r
33     render : renderWhileActiveclientsRecord\r
34   });\r
35   if (doRefresh) {\r
36     // console.log('Will do another ajax request after a timeout in order to\r
37     // render: pz2watch:activeclientsFieldRecord');\r
38     renderOnRecordTargetsReqVar = setTimeout(function() {\r
39       // console.log('Making request for pz2watch:activeclientsFieldRecord');\r
40       jsf.ajax.request(sourcecomp, null, {\r
41         render : "pz2watch:activeclientsFieldRecord"\r
42       });\r
43     }, 1000);\r
44   } else {\r
45     // console.log("No further updates from server requested");\r
46   }\r
47 }\r
48 \r
49 // Listens for browser initiated changes to 'window.location.hash' and sends \r
50 // the hash key changes to the back-end, to have the back-end pull up a previous \r
51 // Pazpar2 state.\r
52 // \r
53 // See also: The field in pz2watch.xhtml, the StateListener function below,\r
54 // the method Pz2Bean.handleQueryStateChanges(), and the classes \r
55 // Pazpar2State and StateManager for a complete picture of browser history \r
56 // handling.\r
57 function windowlocationhashListener() {\r
58   if (trackHistory) {\r
59     \r
60     var stateKey = document.getElementById("pz2watch:windowlocationhash");\r
61     // console.log("browser hash update response detected.");\r
62     // console.log("pz2watch:windowlocationhash: [" + stateKey.value + "]");\r
63     // console.log("window.location.hash: [" + window.location.hash + "]");\r
64     if (window.location.hash != stateKey.value) {  \r
65       if (window.location.hash) {\r
66         //console.log("updating pz2watch:windowlocationhash with new window.location.hash [" + window.location.hash + "]");\r
67         stateKey.value = window.location.hash;\r
68         //console.log("firing pz2watch:windowlocationhash onChange");\r
69         stateKey.onchange();\r
70       } else if (stateKey.value) {\r
71         //console.log("updating window.location.hash with pz2watch:windowlocationhash  [" + stateKey.value + "]");\r
72         window.location.hash = stateKey.value;\r
73         //console.log("firing pz2watch:windowlocationhash onChange");\r
74         stateKey.onchange();\r
75       } \r
76     } else {\r
77       //console.log("State hash already has the value of the new browser hash - not updating state hash");\r
78     }\r
79   }\r
80 }\r
81 \r
82 // Listens for ViewExpiredException message. Reloads the current page, stripped\r
83 // of\r
84 // it's jsessionid and hash content\r
85 function viewExpirationListener(data) {\r
86   if (data.status === "success" && data.responseXML) {\r
87     var errorElements = data.responseXML.getElementsByTagName("error-name");\r
88     if (errorElements.length > 0) {\r
89       var errorname = errorElements.item(0).textContent\r
90           || errorElements.item(0).text;\r
91       if (errorname === "class javax.faces.application.ViewExpiredException") {\r
92         var newloc = window.location.protocol + "//" + window.location.host\r
93             + window.location.pathname.replace(/;jsessionid.*/, '');\r
94         alert('Sorry, this session has expired. A new one will be loaded.');\r
95         window.location.replace(newloc);\r
96       }\r
97     }\r
98   }\r
99 \r
100 }\r
101 \r
102 function errorListener(data) {\r
103   // alert(data.toSource());\r
104   if (data.source.name === "pz2watch:activeclientsField") {\r
105     alert("This occurred when polling: ["\r
106         + data.description\r
107         + "]. The page could be in an inconsistent state after this. We apologize for the inconvenience.");\r
108   } else {\r
109     var pattern = /viewId.*could not be restored./;\r
110     if (pattern.test(data.description)) {\r
111       // ignore - caught by view expiration listener\r
112     } else {\r
113       alert("An error ["\r
114           + data.errorName + ": " +data.description\r
115           + "] was triggered by ["\r
116           + data.source.name\r
117           + "]. The page could be in an inconsistent state after this. We apologize for the inconvenience.");\r
118     }\r
119   }\r
120 }\r
121 \r
122 // Composite listener, invoking all field update listeners\r
123 function fieldUpdateListener(data) {\r
124   if (data.status === "success") {\r
125     var updates = data.responseXML.getElementsByTagName("update");\r
126     for ( var i = 0, max = updates.length; i < max; i++) {\r
127       var lsnri = fieldListeners.getListener(updates[i].getAttribute("id"));\r
128       if (lsnri) {\r
129         lsnri.invoke(updates[i]);\r
130       }\r
131     }\r
132   }\r
133 }\r
134 \r
135 var Pz2listeners = function() {\r
136   var lsnrs = {};\r
137   this.addListener = function(key, lsnr) {\r
138     lsnrs[key] = lsnr;\r
139   };\r
140   this.getListener = function(key) {\r
141     return lsnrs[key];\r
142   };\r
143 };\r
144 \r
145 var fieldListeners = new Pz2listeners();\r
146 \r
147 // Listens for back-end initiated changes to the state key and updates\r
148 // window.location.hash with changes, to record them in browsing history\r
149 var StateListener = function() {\r
150   this.invoke = function(field) {\r
151     var stateKeyDoc = StringtoXML(field.textContent || field.text);\r
152     var stateKeyValue = stateKeyDoc.childNodes[0].getAttribute("value");\r
153     // console.log('Received state key update from the back-end: ' + stateKeyValue);\r
154     if (stateKeyValue !== window.location.hash) {\r
155       window.location.hash = stateKeyValue;\r
156       // console.log("Browsers hash (window.location.hash) updated with [" + stateKeyValue + "]");\r
157     } else {\r
158       // console.log("Browsers hash (window.location.hash) already has the value [" + stateKeyValue + "]");\r
159     }\r
160   };\r
161 };\r
162 \r
163 // Listens for updates to general 'activeclients' field, then invokes\r
164 // renderTargets\r
165 var ActiveclientsListener = function() {\r
166   this.invoke = function(field) {\r
167     var updateDoc = StringtoXML(field.textContent || field.text);\r
168     var activeClientsValue = (updateDoc.childNodes[0].textContent || updateDoc.childNodes[0].text);\r
169     // console.log('Activeclients response detected: ' + activeClientsValue);\r
170     clearTimeout(renderTargetsReqVar);\r
171     if (activeClientsValue > '0') {\r
172       renderTargets(true);\r
173     } else {\r
174       renderTargets(false);\r
175     }\r
176   };\r
177 };\r
178 \r
179 // Listens for updates to record 'activeclients' field, then invokes\r
180 // renderOnRecordTargets\r
181 var ActiveclientsRecordListener = function() {\r
182   this.invoke = function(field) {\r
183     var updateDoc = StringtoXML(field.textContent || field.text);\r
184     var activeClientsRecordValue = (updateDoc.childNodes[0].textContent || updateDoc.childNodes[0].text);\r
185     // console.log('Activeclients response for record detected: ' + activeClientsRecordValue);\r
186     clearTimeout(renderOnRecordTargetsReqVar);\r
187     if (activeClientsRecordValue > '0') {\r
188       renderOnRecordTargets(true);\r
189     } else {\r
190       // console.log('Active clients is 0, final rendering');\r
191       renderOnRecordTargets(false);\r
192     }\r
193   };\r
194 };\r
195 \r
196 // Inserts field update listeners, state listeners, view expired listener\r
197 // into Ajax response handling\r
198 jsf.ajax.addOnEvent(fieldUpdateListener);\r
199 jsf.ajax.addOnEvent(viewExpirationListener);\r
200 jsf.ajax.addOnError(errorListener);\r
201 \r
202 function StringtoXML(text) {\r
203   var doc;\r
204   if (window.ActiveXObject) {\r
205     doc = new ActiveXObject('Microsoft.XMLDOM');\r
206     doc.async = false;\r
207     doc.loadXML(text);\r
208   } else {\r
209     var parser = new DOMParser();\r
210     doc = parser.parseFromString(text, 'text/xml');\r
211   }\r
212   return doc;\r
213 }\r
214 \r
215 // Sets up field update listeners\r
216 var setUpListeners = function() {\r
217   // console.log("Starts tracking activeclientsField, for 'show' and 'record'");\r
218   fieldListeners.addListener("pz2watch:activeclientsField",\r
219       new ActiveclientsListener());\r
220   fieldListeners.addListener("pz2watch:activeclientsFieldRecord",\r
221       new ActiveclientsRecordListener());\r
222   if (trackHistory) {\r
223     // console.log("Starts tracking windowlocationhash field");\r
224     fieldListeners.addListener("pz2watch:windowlocationhash",\r
225         new StateListener());\r
226     // console.log("Setting listener for browser onhashchange");\r
227     window.onload = window.onhashchange = windowlocationhashListener;\r
228   }\r
229 };