comparison core.js @ 608:0256f3748b27 multiple-tests-concatenation

Merge
author Giulio Moro <giuliomoro@yahoo.it>
date Sat, 12 Mar 2016 15:32:30 +0000
parents 328f24798462 640ffb822da1
children 34d8bca65edc
comparison
equal deleted inserted replaced
607:328f24798462 608:0256f3748b27
164 function loadProjectSpecCallback(response) { 164 function loadProjectSpecCallback(response) {
165 // Function called after asynchronous download of XML project specification 165 // Function called after asynchronous download of XML project specification
166 //var decode = $.parseXML(response); 166 //var decode = $.parseXML(response);
167 //projectXML = $(decode); 167 //projectXML = $(decode);
168 168
169 // First perform XML schema validation 169 // Check if XML is new or a resumption
170 var Module = { 170 var parse = new DOMParser();
171 xml: response, 171 var responseDocument = parse.parseFromString(response,'text/xml');
172 schema: schemaXSD, 172 var errorNode = responseDocument.getElementsByTagName('parsererror');
173 arguments:["--noout", "--schema", 'test-schema.xsd','document.xml']
174 };
175
176 var xmllint = validateXML(Module);
177 console.log(xmllint);
178 if(xmllint != 'document.xml validates\n')
179 {
180 document.getElementsByTagName('body')[0].innerHTML = null;
181 var msg = document.createElement("h3");
182 msg.textContent = "FATAL ERROR";
183 var span = document.createElement("h4");
184 span.textContent = "The XML validator returned the following errors when decoding your XML file";
185 document.getElementsByTagName('body')[0].appendChild(msg);
186 document.getElementsByTagName('body')[0].appendChild(span);
187 xmllint = xmllint.split('\n');
188 for (var i in xmllint)
189 {
190 document.getElementsByTagName('body')[0].appendChild(document.createElement('br'));
191 var span = document.createElement("span");
192 span.textContent = xmllint[i];
193 document.getElementsByTagName('body')[0].appendChild(span);
194 }
195 return;
196 }
197
198 var parse = new DOMParser();
199 projectXML = parse.parseFromString(response,'text/xml');
200 var errorNode = projectXML.getElementsByTagName('parsererror');
201 if (errorNode.length >= 1) 173 if (errorNode.length >= 1)
202 { 174 {
203 var msg = document.createElement("h3"); 175 var msg = document.createElement("h3");
204 msg.textContent = "FATAL ERROR"; 176 msg.textContent = "FATAL ERROR";
205 var span = document.createElement("span"); 177 var span = document.createElement("span");
208 document.getElementsByTagName('body')[0].appendChild(msg); 180 document.getElementsByTagName('body')[0].appendChild(msg);
209 document.getElementsByTagName('body')[0].appendChild(span); 181 document.getElementsByTagName('body')[0].appendChild(span);
210 document.getElementsByTagName('body')[0].appendChild(errorNode[0]); 182 document.getElementsByTagName('body')[0].appendChild(errorNode[0]);
211 return; 183 return;
212 } 184 }
213 185 if (responseDocument.children[0].nodeName == "waet") {
214 // Build the specification 186 // document is a specification
215 specification.decode(projectXML); 187
216 storage.initialise(); 188 // Perform XML schema validation
189 var Module = {
190 xml: response,
191 schema: schemaXSD,
192 arguments:["--noout", "--schema", 'test-schema.xsd','document.xml']
193 };
194 projectXML = responseDocument;
195 var xmllint = validateXML(Module);
196 console.log(xmllint);
197 if(xmllint != 'document.xml validates\n')
198 {
199 document.getElementsByTagName('body')[0].innerHTML = null;
200 var msg = document.createElement("h3");
201 msg.textContent = "FATAL ERROR";
202 var span = document.createElement("h4");
203 span.textContent = "The XML validator returned the following errors when decoding your XML file";
204 document.getElementsByTagName('body')[0].appendChild(msg);
205 document.getElementsByTagName('body')[0].appendChild(span);
206 xmllint = xmllint.split('\n');
207 for (var i in xmllint)
208 {
209 document.getElementsByTagName('body')[0].appendChild(document.createElement('br'));
210 var span = document.createElement("span");
211 span.textContent = xmllint[i];
212 document.getElementsByTagName('body')[0].appendChild(span);
213 }
214 return;
215 }
216 // Build the specification
217 specification.decode(projectXML);
218 // Generate the session-key
219 storage.initialise();
220
221 } else if (responseDocument.children[0].nodeName == "waetresult") {
222 // document is a result
223 projectXML = document.implementation.createDocument(null,"waet");
224 projectXML.children[0].appendChild(responseDocument.getElementsByTagName('waet')[0].getElementsByTagName("setup")[0].cloneNode(true));
225 var child = responseDocument.children[0].children[0];
226 while (child != null) {
227 if (child.nodeName == "survey") {
228 // One of the global survey elements
229 if (child.getAttribute("state") == "complete") {
230 // We need to remove this survey from <setup>
231 var location = child.getAttribute("location");
232 var globalSurveys = projectXML.getElementsByTagName("setup")[0].getElementsByTagName("survey")[0];
233 while(globalSurveys != null) {
234 if (location == "pre" || location == "before") {
235 if (globalSurveys.getAttribute("location") == "pre" || globalSurveys.getAttribute("location") == "before") {
236 projectXML.getElementsByTagName("setup")[0].removeChild(globalSurveys);
237 break;
238 }
239 } else {
240 if (globalSurveys.getAttribute("location") == "post" || globalSurveys.getAttribute("location") == "after") {
241 projectXML.getElementsByTagName("setup")[0].removeChild(globalSurveys);
242 break;
243 }
244 }
245 globalSurveys = globalSurveys.nextElementSibling;
246 }
247 } else {
248 // We need to complete this, so it must be regenerated by store
249 var copy = child;
250 child = child.previousElementSibling;
251 responseDocument.children[0].removeChild(copy);
252 }
253 } else if (child.nodeName == "page") {
254 if (child.getAttribute("state") == "empty") {
255 // We need to complete this page
256 projectXML.children[0].appendChild(responseDocument.getElementById(child.getAttribute("ref")).cloneNode(true));
257 var copy = child;
258 child = child.previousElementSibling;
259 responseDocument.children[0].removeChild(copy);
260 }
261 }
262 child = child.nextElementSibling;
263 }
264 // Build the specification
265 specification.decode(projectXML);
266 // Use the original
267 storage.initialise(responseDocument);
268 }
217 /// CHECK FOR SAMPLE RATE COMPATIBILITY 269 /// CHECK FOR SAMPLE RATE COMPATIBILITY
218 if (specification.sampleRate != undefined) { 270 if (specification.sampleRate != undefined) {
219 if (Number(specification.sampleRate) != audioContext.sampleRate) { 271 if (Number(specification.sampleRate) != audioContext.sampleRate) {
220 var errStr = 'Sample rates do not match! Requested '+Number(specification.sampleRate)+', got '+audioContext.sampleRate+'. Please set the sample rate to match before completing this test.'; 272 var errStr = 'Sample rates do not match! Requested '+Number(specification.sampleRate)+', got '+audioContext.sampleRate+'. Please set the sample rate to match before completing this test.';
221 alert(errStr); 273 alert(errStr);
295 } 347 }
296 document.getElementsByTagName("head")[0].appendChild(interfaceJS); 348 document.getElementsByTagName("head")[0].appendChild(interfaceJS);
297 349
298 // Create the audio engine object 350 // Create the audio engine object
299 audioEngineContext = new AudioEngine(specification); 351 audioEngineContext = new AudioEngine(specification);
300
301 $(specification.pages).each(function(index,elem){
302 $(elem.audioElements).each(function(i,audioElem){
303 var URL = elem.hostURL + audioElem.url;
304 var buffer = null;
305 for (var i=0; i<audioEngineContext.buffers.length; i++)
306 {
307 if (URL == audioEngineContext.buffers[i].url)
308 {
309 buffer = audioEngineContext.buffers[i];
310 break;
311 }
312 }
313 if (buffer == null)
314 {
315 buffer = new audioEngineContext.bufferObj();
316 buffer.getMedia(URL);
317 audioEngineContext.buffers.push(buffer);
318 }
319 });
320 });
321 } 352 }
322 353
323 function createProjectSave(destURL) { 354 function createProjectSave(destURL) {
324 // Save the data from interface into XML and send to destURL 355 // Save the data from interface into XML and send to destURL
325 // If destURL is null then download XML in client 356 // If destURL is null then download XML in client
326 // Now time to render file locally 357 // Now time to render file locally
327 var xmlDoc = interfaceXMLSave(); 358 var xmlDoc = interfaceXMLSave();
328 var parent = document.createElement("div"); 359 var parent = document.createElement("div");
329 parent.appendChild(xmlDoc); 360 parent.appendChild(xmlDoc);
330 var file = [parent.innerHTML]; 361 var file = [parent.innerHTML];
331 if (destURL == "null" || destURL == undefined) { 362 if (destURL == "local") {
332 var bb = new Blob(file,{type : 'application/xml'}); 363 var bb = new Blob(file,{type : 'application/xml'});
333 var dnlk = window.URL.createObjectURL(bb); 364 var dnlk = window.URL.createObjectURL(bb);
334 var a = document.createElement("a"); 365 var a = document.createElement("a");
335 a.hidden = ''; 366 a.hidden = '';
336 a.href = dnlk; 367 a.href = dnlk;
339 370
340 popup.showPopup(); 371 popup.showPopup();
341 popup.popupContent.innerHTML = "<span>Please save the file below to give to your test supervisor</span><br>"; 372 popup.popupContent.innerHTML = "<span>Please save the file below to give to your test supervisor</span><br>";
342 popup.popupContent.appendChild(a); 373 popup.popupContent.appendChild(a);
343 } else { 374 } else {
344 var xmlhttp = new XMLHttpRequest; 375 destUrlFull = destURL+"?key="+storage.SessionKey.key;
345 destUrlFull = destURL;
346 var saveFilenamePrefix; 376 var saveFilenamePrefix;
347 // parse the querystring of destUrl, get the "id" (if any) and append it to destUrl 377 // parse the querystring of destUrl, get the "id" (if any) and append it to destUrl
348 var qs = returnUrl.split("?"); 378 var qs = returnUrl.split("?");
349 if(qs.length == 2){ 379 if(qs.length == 2){
350 qs = qs[1]; 380 qs = qs[1];
355 saveFilenamePrefix = pair[1]; 385 saveFilenamePrefix = pair[1];
356 } 386 }
357 } 387 }
358 } 388 }
359 if(typeof(saveFilenamePrefix) !== "undefined"){ 389 if(typeof(saveFilenamePrefix) !== "undefined"){
360 destUrlFull+="?saveFilenamePrefix="+saveFilenamePrefix; 390 destUrlFull+="&saveFilenamePrefix="+saveFilenamePrefix;
361 } 391 }
392 var xmlhttp = new XMLHttpRequest;
362 xmlhttp.open("POST",destUrlFull,true); 393 xmlhttp.open("POST",destUrlFull,true);
363 xmlhttp.setRequestHeader('Content-Type', 'text/xml'); 394 xmlhttp.setRequestHeader('Content-Type', 'text/xml');
364 xmlhttp.onerror = function(){ 395 xmlhttp.onerror = function(){
365 console.log('Error saving file to server! Presenting download locally'); 396 console.log('Error saving file to server! Presenting download locally');
366 createProjectSave(null); 397 createProjectSave("local");
367 }; 398 };
368 xmlhttp.onreadystatechange = function() { 399 xmlhttp.onload = function() {
369 console.log(xmlhttp.status); 400 console.log(xmlhttp);
370 if (xmlhttp.status != 200 && xmlhttp.readyState == 4) { 401 if (this.status >= 300) {
371 createProjectSave(null); 402 console.log("WARNING - Could not update at this time");
372 } else { 403 createProjectSave("local");
373 var parser = new DOMParser(); 404 } else {
374 var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml"); 405 var parser = new DOMParser();
375 if (xmlDoc == null) 406 var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml");
376 { 407 var response = xmlDoc.getElementsByTagName('response')[0];
377 createProjectSave('null'); 408 window.onbeforeunload=null;
378 } 409 if (response.getAttribute("state") == "OK") {
379 var response = xmlDoc.childNodes[0]; 410 var file = response.getElementsByTagName("file")[0];
380 if (response.getAttribute('state') == "OK") 411 if(typeof(returnUrl) !== "undefined"){
381 { 412 window.location = returnUrl;
382 var file = response.getElementsByTagName('file')[0]; 413 }
383 console.log('Save OK: Filename '+file.textContent+','+file.getAttribute('bytes')+'B'); 414 console.log("Save: OK, written "+file.getAttribute("bytes")+"B");
384 popup.showPopup(); 415 popup.popupContent.textContent = "Thank you. Your session has been saved.";
385 popup.popupContent.innerHTML = null; 416 } else {
386 popup.popupContent.textContent = "Thank you!"; 417 var message = response.getElementsByTagName("message");
387 window.onbeforeunload=null; 418 console.log("Save: Error! "+message.textContent);
388 if(typeof(returnUrl) !== "undefined"){ 419 createProjectSave("local");
389 window.location = returnUrl; 420 }
390 } 421 }
391 } else { 422 };
392 var message = response.getElementsByTagName('message')[0];
393 errorSessionDump(message.textContent);
394 }
395 }
396 };
397 xmlhttp.send(file); 423 xmlhttp.send(file);
398 popup.showPopup(); 424 popup.showPopup();
399 popup.popupContent.innerHTML = null; 425 popup.popupContent.innerHTML = null;
400 popup.popupContent.textContent = "Submitting. Please Wait"; 426 popup.popupContent.textContent = "Submitting. Please Wait";
401 popup.hideNextButton(); 427 popup.hideNextButton();
448 } 474 }
449 475
450 function decibelToLinear(gain) 476 function decibelToLinear(gain)
451 { 477 {
452 return Math.pow(10,gain/20.0); 478 return Math.pow(10,gain/20.0);
479 }
480
481 function randomString(length) {
482 return Math.round((Math.pow(36, length + 1) - Math.random() * Math.pow(36, length))).toString(36).slice(1);
453 } 483 }
454 484
455 function interfacePopup() { 485 function interfacePopup() {
456 // Creates an object to manage the popup 486 // Creates an object to manage the popup
457 this.popup = null; 487 this.popup = null;
745 this.hidePopup(); 775 this.hidePopup();
746 for (var node of this.popupOptions) 776 for (var node of this.popupOptions)
747 { 777 {
748 this.store.postResult(node); 778 this.store.postResult(node);
749 } 779 }
780 this.store.complete();
750 advanceState(); 781 advanceState();
751 } 782 }
752 }; 783 };
753 784
754 this.previousClick = function() { 785 this.previousClick = function() {
823 } 854 }
824 for (var i=0; i<specification.pages.length; i++) 855 for (var i=0; i<specification.pages.length; i++)
825 { 856 {
826 if (specification.testPages <= i && specification.testPages != 0) {break;} 857 if (specification.testPages <= i && specification.testPages != 0) {break;}
827 this.stateMap.push(pageHolder[i]); 858 this.stateMap.push(pageHolder[i]);
859 storage.createTestPageStore(pageHolder[i]);
860 for (var element of pageHolder[i].audioElements) {
861 var URL = pageHolder[i].hostURL + element.url;
862 var buffer = null;
863 for (var buffObj of audioEngineContext.buffers) {
864 if (URL == buffObj.url) {
865 buffer = buffObj;
866 break;
867 }
868 }
869 if (buffer == null) {
870 buffer = new audioEngineContext.bufferObj();
871 buffer.getMedia(URL);
872 audioEngineContext.buffers.push(buffer);
873 }
874 }
828 } 875 }
829 876
830 if (specification.preTest != null) {this.preTestSurvey = specification.preTest;} 877 if (specification.preTest != null) {this.preTestSurvey = specification.preTest;}
831 if (specification.postTest != null) {this.postTestSurvey = specification.postTest;} 878 if (specification.postTest != null) {this.postTestSurvey = specification.postTest;}
832 879
841 }; 888 };
842 this.advanceState = function(){ 889 this.advanceState = function(){
843 if (this.stateIndex == null) { 890 if (this.stateIndex == null) {
844 this.initialise(); 891 this.initialise();
845 } 892 }
893 storage.update();
846 if (this.stateIndex == -1) { 894 if (this.stateIndex == -1) {
847 this.stateIndex++; 895 this.stateIndex++;
848 console.log('Starting test...'); 896 console.log('Starting test...');
849 if (this.preTestSurvey != null) 897 if (this.preTestSurvey != null)
850 { 898 {
873 this.currentStateMap = this.stateMap[this.stateIndex]; 921 this.currentStateMap = this.stateMap[this.stateIndex];
874 if (this.currentStateMap.randomiseOrder) 922 if (this.currentStateMap.randomiseOrder)
875 { 923 {
876 this.currentStateMap.audioElements = randomiseOrder(this.currentStateMap.audioElements); 924 this.currentStateMap.audioElements = randomiseOrder(this.currentStateMap.audioElements);
877 } 925 }
878 this.currentStore = storage.createTestPageStore(this.currentStateMap); 926 this.currentStore = storage.testPages[this.stateIndex];
879 if (this.currentStateMap.preTest != null) 927 if (this.currentStateMap.preTest != null)
880 { 928 {
881 this.currentStatePosition = 'pre'; 929 this.currentStatePosition = 'pre';
882 popup.initState(this.currentStateMap.preTest,storage.testPages[this.stateIndex].preTest); 930 popup.initState(this.currentStateMap.preTest,storage.testPages[this.stateIndex].preTest);
883 } else { 931 } else {
934 for (var element of interfaceContext.commentQuestions) 982 for (var element of interfaceContext.commentQuestions)
935 { 983 {
936 element.exportXMLDOM(storePoint); 984 element.exportXMLDOM(storePoint);
937 } 985 }
938 pageXMLSave(storePoint.XMLDOM, this.currentStateMap); 986 pageXMLSave(storePoint.XMLDOM, this.currentStateMap);
987 storePoint.complete();
939 }; 988 };
940 } 989 }
941 990
942 function AudioEngine(specification) { 991 function AudioEngine(specification) {
943 992
1187 this.audioObjects[audioObjectId].url = URL; 1236 this.audioObjects[audioObjectId].url = URL;
1188 // Obtain store node 1237 // Obtain store node
1189 var aeNodes = this.pageStore.XMLDOM.getElementsByTagName('audioelement'); 1238 var aeNodes = this.pageStore.XMLDOM.getElementsByTagName('audioelement');
1190 for (var i=0; i<aeNodes.length; i++) 1239 for (var i=0; i<aeNodes.length; i++)
1191 { 1240 {
1192 if(aeNodes[i].id == element.id) 1241 if(aeNodes[i].getAttribute("ref") == element.id)
1193 { 1242 {
1194 this.audioObjects[audioObjectId].storeDOM = aeNodes[i]; 1243 this.audioObjects[audioObjectId].storeDOM = aeNodes[i];
1195 break; 1244 break;
1196 } 1245 }
1197 } 1246 }
1929 1978
1930 this.OptionNode = function() { 1979 this.OptionNode = function() {
1931 this.type = undefined; 1980 this.type = undefined;
1932 this.schema = specification.schema.getAllElementsByName('surveyentry')[0]; 1981 this.schema = specification.schema.getAllElementsByName('surveyentry')[0];
1933 this.id = undefined; 1982 this.id = undefined;
1983 this.name = undefined;
1934 this.mandatory = undefined; 1984 this.mandatory = undefined;
1935 this.statement = undefined; 1985 this.statement = undefined;
1936 this.boxsize = undefined; 1986 this.boxsize = undefined;
1937 this.options = []; 1987 this.options = [];
1938 this.min = undefined; 1988 this.min = undefined;
1984 var node = doc.createElement('surveyentry'); 2034 var node = doc.createElement('surveyentry');
1985 node.setAttribute('type',this.type); 2035 node.setAttribute('type',this.type);
1986 var statement = doc.createElement('statement'); 2036 var statement = doc.createElement('statement');
1987 statement.textContent = this.statement; 2037 statement.textContent = this.statement;
1988 node.appendChild(statement); 2038 node.appendChild(statement);
1989 switch(this.type) 2039 if (this.type != "statement") {
1990 {
1991 case "statement":
1992 break;
1993 case "question":
1994 node.id = this.id; 2040 node.id = this.id;
2041 if (this.name != undefined) { node.setAttribute("name",this.name);}
1995 if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);} 2042 if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);}
1996 if (this.boxsize != undefined) {node.setAttribute("boxsize",this.boxsize);} 2043 switch(this.type)
1997 break; 2044 {
1998 case "number": 2045 case "question":
1999 node.id = this.id; 2046 if (this.boxsize != undefined) {node.setAttribute("boxsize",this.boxsize);}
2000 if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);} 2047 break;
2001 if (this.min != undefined) {node.setAttribute("min", this.min);} 2048 case "number":
2002 if (this.max != undefined) {node.setAttribute("max", this.max);} 2049 if (this.min != undefined) {node.setAttribute("min", this.min);}
2003 break; 2050 if (this.max != undefined) {node.setAttribute("max", this.max);}
2004 case "checkbox": 2051 break;
2005 case "radio": 2052 case "checkbox":
2006 node.id = this.id; 2053 case "radio":
2007 for (var i=0; i<this.options.length; i++) 2054 for (var i=0; i<this.options.length; i++)
2008 { 2055 {
2009 var option = this.options[i]; 2056 var option = this.options[i];
2010 var optionNode = doc.createElement("option"); 2057 var optionNode = doc.createElement("option");
2011 optionNode.setAttribute("name",option.name); 2058 optionNode.setAttribute("name",option.name);
2012 optionNode.textContent = option.text; 2059 optionNode.textContent = option.text;
2013 node.appendChild(optionNode); 2060 node.appendChild(optionNode);
2014 } 2061 }
2015 break; 2062 break;
2016 } 2063 }
2064 }
2017 return node; 2065 return node;
2018 }; 2066 };
2019 }; 2067 };
2020 this.decode = function(parent,xml) { 2068 this.decode = function(parent,xml) {
2021 this.location = xml.getAttribute('location'); 2069 this.location = xml.getAttribute('location');
2151 this.randomiseOrder = undefined; 2199 this.randomiseOrder = undefined;
2152 this.loop = undefined; 2200 this.loop = undefined;
2153 this.showElementComments = undefined; 2201 this.showElementComments = undefined;
2154 this.outsideReference = null; 2202 this.outsideReference = null;
2155 this.loudness = null; 2203 this.loudness = null;
2204 this.label = null;
2156 this.preTest = null; 2205 this.preTest = null;
2157 this.postTest = null; 2206 this.postTest = null;
2158 this.interfaces = []; 2207 this.interfaces = [];
2159 this.commentBoxPrefix = "Comment on track"; 2208 this.commentBoxPrefix = "Comment on track";
2160 this.audioElements = []; 2209 this.audioElements = [];
2278 return AHNode; 2327 return AHNode;
2279 }; 2328 };
2280 2329
2281 this.commentQuestionNode = function() { 2330 this.commentQuestionNode = function() {
2282 this.id = null; 2331 this.id = null;
2332 this.name = undefined;
2283 this.type = undefined; 2333 this.type = undefined;
2284 this.options = []; 2334 this.options = [];
2285 this.statement = undefined; 2335 this.statement = undefined;
2286 this.schema = specification.schema.getAllElementsByName('commentquestion')[0]; 2336 this.schema = specification.schema.getAllElementsByName('commentquestion')[0];
2287 this.decode = function(parent,xml) 2337 this.decode = function(parent,xml)
2288 { 2338 {
2289 this.id = xml.id; 2339 this.id = xml.id;
2340 this.name = xml.getAttribute('name');
2290 this.type = xml.getAttribute('type'); 2341 this.type = xml.getAttribute('type');
2291 this.statement = xml.getElementsByTagName('statement')[0].textContent; 2342 this.statement = xml.getElementsByTagName('statement')[0].textContent;
2292 var optNodes = xml.getElementsByTagName('option'); 2343 var optNodes = xml.getElementsByTagName('option');
2293 for (var i=0; i<optNodes.length; i++) 2344 for (var i=0; i<optNodes.length; i++)
2294 { 2345 {
2303 this.encode = function(root) 2354 this.encode = function(root)
2304 { 2355 {
2305 var node = root.createElement("commentquestion"); 2356 var node = root.createElement("commentquestion");
2306 node.id = this.id; 2357 node.id = this.id;
2307 node.setAttribute("type",this.type); 2358 node.setAttribute("type",this.type);
2359 if (this.name != undefined){node.setAttribute("name",this.name);}
2308 var statement = root.createElement("statement"); 2360 var statement = root.createElement("statement");
2309 statement.textContent = this.statement; 2361 statement.textContent = this.statement;
2310 node.appendChild(statement); 2362 node.appendChild(statement);
2311 for (var option of this.options) 2363 for (var option of this.options)
2312 { 2364 {
2320 }; 2372 };
2321 2373
2322 this.audioElementNode = function() { 2374 this.audioElementNode = function() {
2323 this.url = null; 2375 this.url = null;
2324 this.id = null; 2376 this.id = null;
2377 this.name = null;
2325 this.parent = null; 2378 this.parent = null;
2326 this.type = null; 2379 this.type = null;
2327 this.marker = null; 2380 this.marker = null;
2328 this.enforce = false; 2381 this.enforce = false;
2329 this.gain = 0.0; 2382 this.gain = 0.0;
3011 } 3064 }
3012 } 3065 }
3013 if (passed == false) 3066 if (passed == false)
3014 { 3067 {
3015 check_pass = false; 3068 check_pass = false;
3016 console.log("Continue listening to track-"+audioEngineContext.audioObjects.interfaceDOM.getPresentedId()); 3069 console.log("Continue listening to track-"+object.interfaceDOM.getPresentedId());
3017 error_obj.push(audioEngineContext.audioObjects.interfaceDOM.getPresentedId()); 3070 error_obj.push(object.interfaceDOM.getPresentedId());
3018 } 3071 }
3019 } 3072 }
3020 if (check_pass == false) 3073 if (check_pass == false)
3021 { 3074 {
3022 var str_start = "You have not completely listened to fragments "; 3075 var str_start = "You have not completely listened to fragments ";
3111 { 3164 {
3112 // Holds results in XML format until ready for collection 3165 // Holds results in XML format until ready for collection
3113 this.globalPreTest = null; 3166 this.globalPreTest = null;
3114 this.globalPostTest = null; 3167 this.globalPostTest = null;
3115 this.testPages = []; 3168 this.testPages = [];
3116 this.document = document.implementation.createDocument(null,"waetresult"); 3169 this.document = null;
3117 this.root = this.document.childNodes[0]; 3170 this.root = null;
3118 this.state = 0; 3171 this.state = 0;
3119 3172
3120 this.initialise = function() 3173 this.initialise = function(existingStore)
3121 { 3174 {
3122 if (specification.preTest != undefined){this.globalPreTest = new this.surveyNode(this,this.root,specification.preTest);} 3175 if (existingStore == undefined) {
3123 if (specification.postTest != undefined){this.globalPostTest = new this.surveyNode(this,this.root,specification.postTest);} 3176 // We need to get the sessionKey
3124 }; 3177 this.SessionKey.generateKey();
3178 this.document = document.implementation.createDocument(null,"waetresult");
3179 this.root = this.document.childNodes[0];
3180 var projectDocument = specification.projectXML;
3181 projectDocument.setAttribute('file-name',url);
3182 this.root.appendChild(projectDocument);
3183 this.root.appendChild(returnDateNode());
3184 this.root.appendChild(interfaceContext.returnNavigator());
3185 } else {
3186 this.document = existingStore;
3187 this.root = existingStore.children[0];
3188 this.SessionKey.key = this.root.getAttribute("key");
3189 }
3190 if (specification.preTest != undefined){this.globalPreTest = new this.surveyNode(this,this.root,specification.preTest);}
3191 if (specification.postTest != undefined){this.globalPostTest = new this.surveyNode(this,this.root,specification.postTest);}
3192 };
3193
3194 this.SessionKey = {
3195 key: null,
3196 request: new XMLHttpRequest(),
3197 parent: this,
3198 handleEvent: function() {
3199 var parse = new DOMParser();
3200 var xml = parse.parseFromString(this.request.response,"text/xml");
3201 if (xml.getAllElementsByTagName("state")[0].textContent == "OK") {
3202 this.key = xml.getAllElementsByTagName("key")[0].textContent;
3203 this.parent.root.setAttribute("key",this.key);
3204 this.parent.root.setAttribute("state","empty");
3205 } else {
3206 this.generateKey();
3207 }
3208 },
3209 generateKey: function() {
3210 var temp_key = randomString(32);
3211 this.request.open("GET","keygen.php?key="+temp_key,true);
3212 this.request.addEventListener("load",this);
3213 this.request.send();
3214 },
3215 update: function() {
3216 this.parent.root.setAttribute("state","update");
3217 var xmlhttp = new XMLHttpRequest();
3218 xmlhttp.open("POST",specification.projectReturn+"?key="+this.key);
3219 xmlhttp.setRequestHeader('Content-Type', 'text/xml');
3220 xmlhttp.onerror = function(){
3221 console.log('Error updating file to server!');
3222 };
3223 var hold = document.createElement("div");
3224 var clone = this.parent.root.cloneNode(true);
3225 hold.appendChild(clone);
3226 xmlhttp.onload = function() {
3227 if (this.status >= 300) {
3228 console.log("WARNING - Could not update at this time");
3229 } else {
3230 var parser = new DOMParser();
3231 var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml");
3232 var response = xmlDoc.getElementsByTagName('response')[0];
3233 if (response.getAttribute("state") == "OK") {
3234 var file = response.getElementsByTagName("file")[0];
3235 console.log("Intermediate save: OK, written "+file.getAttribute("bytes")+"B");
3236 } else {
3237 var message = response.getElementsByTagName("message");
3238 console.log("Intermediate save: Error! "+message.textContent);
3239 }
3240 }
3241 }
3242 xmlhttp.send([hold.innerHTML]);
3243 }
3244 }
3125 3245
3126 this.createTestPageStore = function(specification) 3246 this.createTestPageStore = function(specification)
3127 { 3247 {
3128 var store = new this.pageNode(this,specification); 3248 var store = new this.pageNode(this,specification);
3129 this.testPages.push(store); 3249 this.testPages.push(store);
3132 3252
3133 this.surveyNode = function(parent,root,specification) 3253 this.surveyNode = function(parent,root,specification)
3134 { 3254 {
3135 this.specification = specification; 3255 this.specification = specification;
3136 this.parent = parent; 3256 this.parent = parent;
3257 this.state = "empty";
3137 this.XMLDOM = this.parent.document.createElement('survey'); 3258 this.XMLDOM = this.parent.document.createElement('survey');
3138 this.XMLDOM.setAttribute('location',this.specification.location); 3259 this.XMLDOM.setAttribute('location',this.specification.location);
3260 this.XMLDOM.setAttribute("state",this.state);
3139 for (var optNode of this.specification.options) 3261 for (var optNode of this.specification.options)
3140 { 3262 {
3141 if (optNode.type != 'statement') 3263 if (optNode.type != 'statement')
3142 { 3264 {
3143 var node = this.parent.document.createElement('surveyresult'); 3265 var node = this.parent.document.createElement('surveyresult');
3144 node.id = optNode.id; 3266 node.setAttribute("ref",optNode.id);
3145 node.setAttribute('type',optNode.type); 3267 node.setAttribute('type',optNode.type);
3146 this.XMLDOM.appendChild(node); 3268 this.XMLDOM.appendChild(node);
3147 } 3269 }
3148 } 3270 }
3149 root.appendChild(this.XMLDOM); 3271 root.appendChild(this.XMLDOM);
3151 this.postResult = function(node) 3273 this.postResult = function(node)
3152 { 3274 {
3153 // From popup: node is the popupOption node containing both spec. and results 3275 // From popup: node is the popupOption node containing both spec. and results
3154 // ID is the position 3276 // ID is the position
3155 if (node.specification.type == 'statement'){return;} 3277 if (node.specification.type == 'statement'){return;}
3156 var surveyresult = this.parent.document.getElementById(node.specification.id); 3278 var surveyresult = this.XMLDOM.children[0];
3279 while(surveyresult != null) {
3280 if (surveyresult.getAttribute("ref") == node.specification.id)
3281 {
3282 break;
3283 }
3284 surveyresult = surveyresult.nextElementSibling;
3285 }
3157 switch(node.specification.type) 3286 switch(node.specification.type)
3158 { 3287 {
3159 case "number": 3288 case "number":
3160 case "question": 3289 case "question":
3161 var child = this.parent.document.createElement('response'); 3290 var child = this.parent.document.createElement('response');
3177 surveyresult.appendChild(checkNode); 3306 surveyresult.appendChild(checkNode);
3178 } 3307 }
3179 break; 3308 break;
3180 } 3309 }
3181 }; 3310 };
3311 this.complete = function() {
3312 this.state = "complete";
3313 this.XMLDOM.setAttribute("state",this.state);
3314 }
3182 }; 3315 };
3183 3316
3184 this.pageNode = function(parent,specification) 3317 this.pageNode = function(parent,specification)
3185 { 3318 {
3186 // Create one store per test page 3319 // Create one store per test page
3187 this.specification = specification; 3320 this.specification = specification;
3188 this.parent = parent; 3321 this.parent = parent;
3322 this.state = "empty";
3189 this.XMLDOM = this.parent.document.createElement('page'); 3323 this.XMLDOM = this.parent.document.createElement('page');
3190 this.XMLDOM.setAttribute('id',specification.id); 3324 this.XMLDOM.setAttribute('ref',specification.id);
3191 this.XMLDOM.setAttribute('presentedId',specification.presentedId); 3325 this.XMLDOM.setAttribute('presentedId',specification.presentedId);
3326 this.XMLDOM.setAttribute("state",this.state);
3192 if (specification.preTest != undefined){this.preTest = new this.parent.surveyNode(this.parent,this.XMLDOM,this.specification.preTest);} 3327 if (specification.preTest != undefined){this.preTest = new this.parent.surveyNode(this.parent,this.XMLDOM,this.specification.preTest);}
3193 if (specification.postTest != undefined){this.postTest = new this.parent.surveyNode(this.parent,this.XMLDOM,this.specification.postTest);} 3328 if (specification.postTest != undefined){this.postTest = new this.parent.surveyNode(this.parent,this.XMLDOM,this.specification.postTest);}
3194 3329
3195 // Add any page metrics 3330 // Add any page metrics
3196 var page_metric = this.parent.document.createElement('metric'); 3331 var page_metric = this.parent.document.createElement('metric');
3198 3333
3199 // Add the audioelement 3334 // Add the audioelement
3200 for (var element of this.specification.audioElements) 3335 for (var element of this.specification.audioElements)
3201 { 3336 {
3202 var aeNode = this.parent.document.createElement('audioelement'); 3337 var aeNode = this.parent.document.createElement('audioelement');
3203 aeNode.id = element.id; 3338 aeNode.setAttribute('ref',element.id);
3339 if (element.name != undefined){aeNode.setAttribute('name',element.name)};
3204 aeNode.setAttribute('type',element.type); 3340 aeNode.setAttribute('type',element.type);
3205 aeNode.setAttribute('url', element.url); 3341 aeNode.setAttribute('url', element.url);
3206 aeNode.setAttribute('gain', element.gain); 3342 aeNode.setAttribute('gain', element.gain);
3207 if (element.type == 'anchor' || element.type == 'reference') 3343 if (element.type == 'anchor' || element.type == 'reference')
3208 { 3344 {
3215 aeNode.appendChild(ae_metric); 3351 aeNode.appendChild(ae_metric);
3216 this.XMLDOM.appendChild(aeNode); 3352 this.XMLDOM.appendChild(aeNode);
3217 } 3353 }
3218 3354
3219 this.parent.root.appendChild(this.XMLDOM); 3355 this.parent.root.appendChild(this.XMLDOM);
3220 }; 3356
3357 this.complete = function() {
3358 this.state = "complete";
3359 this.XMLDOM.setAttribute("state","complete");
3360 }
3361 };
3362 this.update = function() {
3363 this.SessionKey.update();
3364 }
3221 this.finish = function() 3365 this.finish = function()
3222 { 3366 {
3223 if (this.state == 0) 3367 if (this.state == 0)
3224 { 3368 {
3225 var projectDocument = specification.projectXML; 3369 this.update();
3226 projectDocument.setAttribute('file-name',url);
3227 this.root.appendChild(projectDocument);
3228 this.root.appendChild(returnDateNode());
3229 this.root.appendChild(interfaceContext.returnNavigator());
3230 } 3370 }
3231 this.state = 1; 3371 this.state = 1;
3232 return this.root; 3372 return this.root;
3233 }; 3373 };
3234 } 3374 }