changeset 1294:e7a819fe85bf

Intermediate saves can be used to resume a test. Note, previous saves will NOT work for resumption. To resume, use the save XML as the ?url= option.
author Nicholas Jillings <nickjillings@users.noreply.github.com>
date Thu, 10 Mar 2016 15:33:39 +0000
parents c753706731f2
children ba8c8c7f1de5
files core.js
diffstat 1 files changed, 81 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/core.js	Thu Mar 10 11:49:08 2016 +0000
+++ b/core.js	Thu Mar 10 15:33:39 2016 +0000
@@ -220,12 +220,51 @@
         
     } else if (responseDocument.children[0].nodeName == "waetresult") {
         // document is a result
-        projectXML = responseDocument.getElementsByTagName('waet')[0];
+        projectXML = document.implementation.createDocument(null,"waet");
+        projectXML.children[0].appendChild(responseDocument.getElementsByTagName('waet')[0].getElementsByTagName("setup")[0].cloneNode(true));
+        var child = responseDocument.children[0].children[0];
+        while (child != null) {
+            if (child.nodeName == "survey") {
+                // One of the global survey elements
+                if (child.getAttribute("state") == "complete") {
+                    // We need to remove this survey from <setup>
+                    var location = child.getAttribute("location");
+                    var globalSurveys = projectXML.getElementsByTagName("setup")[0].getElementsByTagName("survey")[0];
+                    while(globalSurveys != null) {
+                        if (location == "pre" || location == "before") {
+                            if (globalSurveys.getAttribute("location") == "pre" || globalSurveys.getAttribute("location") == "before") {
+                                projectXML.getElementsByTagName("setup")[0].removeChild(globalSurveys);
+                                break;
+                            }
+                        } else {
+                            if (globalSurveys.getAttribute("location") == "post" || globalSurveys.getAttribute("location") == "after") {
+                                projectXML.getElementsByTagName("setup")[0].removeChild(globalSurveys);
+                                break;
+                            }
+                        }
+                        globalSurveys = globalSurveys.nextElementSibling;
+                    }
+                } else {
+                    // We need to complete this, so it must be regenerated by store
+                    var copy = child;
+                    child = child.previousElementSibling;
+                    responseDocument.children[0].removeChild(copy);
+                }
+            } else if (child.nodeName == "page") {
+                if (child.getAttribute("state") == "empty") {
+                    // We need to complete this page
+                    projectXML.children[0].appendChild(responseDocument.getElementById(child.getAttribute("ref")).cloneNode(true));
+                    var copy = child;
+                    child = child.previousElementSibling;
+                    responseDocument.children[0].removeChild(copy);
+                }
+            }
+            child = child.nextElementSibling;
+        }
         // Build the specification
 	    specification.decode(projectXML);
-        // Use the session-key
-        var sessionKey = responseDocument.children[0].getAttribute(key);
-        storage.initialise(sessionKey);
+        // Use the original
+        storage.initialise(responseDocument);
     }
 	/// CHECK FOR SAMPLE RATE COMPATIBILITY
 	if (specification.sampleRate != undefined) {
@@ -717,6 +756,7 @@
 			{
 				this.store.postResult(node);
 			}
+            this.store.complete();
 			advanceState();
 		}
 	};
@@ -923,6 +963,7 @@
 			element.exportXMLDOM(storePoint);
 		}
 		pageXMLSave(storePoint.XMLDOM, this.currentStateMap);
+        storePoint.complete();
 	};
 }
 
@@ -1176,7 +1217,7 @@
 		var aeNodes = this.pageStore.XMLDOM.getElementsByTagName('audioelement');
 		for (var i=0; i<aeNodes.length; i++)
 		{
-			if(aeNodes[i].id == element.id)
+			if(aeNodes[i].getAttribute("ref") == element.id)
 			{
 				this.audioObjects[audioObjectId].storeDOM = aeNodes[i];
 				break;
@@ -3103,25 +3144,29 @@
 	this.globalPreTest = null;
 	this.globalPostTest = null;
 	this.testPages = [];
-	this.document = document.implementation.createDocument(null,"waetresult");
-	this.root = this.document.childNodes[0];
+	this.document = null;
+	this.root = null;
 	this.state = 0;
 	
-	this.initialise = function(sessionKey)
+	this.initialise = function(existingStore)
 	{
-        if (sessionKey == undefined) {
+        if (existingStore == undefined) {
             // We need to get the sessionKey
             this.SessionKey.generateKey();
+            this.document = document.implementation.createDocument(null,"waetresult");
+            this.root = this.document.childNodes[0];
             var projectDocument = specification.projectXML;
             projectDocument.setAttribute('file-name',url);
             this.root.appendChild(projectDocument);
             this.root.appendChild(returnDateNode());
             this.root.appendChild(interfaceContext.returnNavigator());
         } else {
-            this.SessionKey.key = sessionKey;
+            this.document = existingStore;
+            this.root = existingStore.children[0];
+            this.SessionKey.key = this.root.getAttribute("key");
         }
         if (specification.preTest != undefined){this.globalPreTest = new this.surveyNode(this,this.root,specification.preTest);}
-		if (specification.postTest != undefined){this.globalPostTest = new this.surveyNode(this,this.root,specification.postTest);}
+        if (specification.postTest != undefined){this.globalPostTest = new this.surveyNode(this,this.root,specification.postTest);}
 	};
     
     this.SessionKey = {
@@ -3187,14 +3232,16 @@
 	{
 		this.specification = specification;
 		this.parent = parent;
+        this.state = "empty";
 		this.XMLDOM = this.parent.document.createElement('survey');
 		this.XMLDOM.setAttribute('location',this.specification.location);
+        this.XMLDOM.setAttribute("state",this.state);
 		for (var optNode of this.specification.options)
 		{
 			if (optNode.type != 'statement')
 			{
 				var node = this.parent.document.createElement('surveyresult');
-				node.id = optNode.id;
+				node.setAttribute("ref",optNode.id);
 				node.setAttribute('type',optNode.type);
 				this.XMLDOM.appendChild(node);
 			}
@@ -3206,7 +3253,14 @@
 			// From popup: node is the popupOption node containing both spec. and results
 			// ID is the position
 			if (node.specification.type == 'statement'){return;}
-			var surveyresult = this.parent.document.getElementById(node.specification.id);
+			var surveyresult = this.XMLDOM.children[0];
+            while(surveyresult != null) {
+                if (surveyresult.getAttribute("ref") == node.specification.id)
+                {
+                    break;
+                }
+                surveyresult = surveyresult.nextElementSibling;
+            }
 			switch(node.specification.type)
 			{
 			case "number":
@@ -3232,6 +3286,10 @@
 				break;
 			}
 		};
+        this.complete = function() {
+            this.state = "complete";
+            this.XMLDOM.setAttribute("state",this.state);
+        }
 	};
 	
 	this.pageNode = function(parent,specification)
@@ -3239,9 +3297,11 @@
 		// Create one store per test page
 		this.specification = specification;
 		this.parent = parent;
+        this.state = "empty";
 		this.XMLDOM = this.parent.document.createElement('page');
-		this.XMLDOM.setAttribute('id',specification.id);
+		this.XMLDOM.setAttribute('ref',specification.id);
 		this.XMLDOM.setAttribute('presentedId',specification.presentedId);
+        this.XMLDOM.setAttribute("state",this.state);
 		if (specification.preTest != undefined){this.preTest = new this.parent.surveyNode(this.parent,this.XMLDOM,this.specification.preTest);}
 		if (specification.postTest != undefined){this.postTest = new this.parent.surveyNode(this.parent,this.XMLDOM,this.specification.postTest);}
 		
@@ -3253,7 +3313,8 @@
 		for (var element of this.specification.audioElements)
 		{
 			var aeNode = this.parent.document.createElement('audioelement');
-			aeNode.id = element.id;
+			aeNode.setAttribute('ref',element.id);
+            if (element.name != undefined){aeNode.setAttribute('name',element.name)};
 			aeNode.setAttribute('type',element.type);
 			aeNode.setAttribute('url', element.url);
 			aeNode.setAttribute('gain', element.gain);
@@ -3270,6 +3331,11 @@
 		}
 		
 		this.parent.root.appendChild(this.XMLDOM);
+        
+        this.complete = function() {
+            this.state = "complete";
+            this.XMLDOM.setAttribute("state","complete");
+        }
 	};
     this.update = function() {
         this.SessionKey.update();