# HG changeset patch # User Nicholas Jillings # Date 1476802198 -3600 # Node ID 249a1152e525b5776a898984b85bf7853a4ad867 # Parent b6bc57a2a681dd83570a671168d200980a7b21a1# Parent 9b536838a962568bf5442fd16082db66f8e4d8be Merge branch 'master' into Dev_main # Conflicts: # interfaces/AB.js # js/core.js # js/specification.js diff -r 9b536838a962 -r 249a1152e525 interfaces/timeline.js --- a/interfaces/timeline.js Tue Oct 18 10:33:17 2016 +0100 +++ b/interfaces/timeline.js Tue Oct 18 15:49:58 2016 +0100 @@ -506,7 +506,7 @@ break; } if (checkState == false) { - canContinue == false; + canContinue = false; } } if (!canContinue) { diff -r 9b536838a962 -r 249a1152e525 js/core.js --- a/js/core.js Tue Oct 18 10:33:17 2016 +0100 +++ b/js/core.js Tue Oct 18 15:49:58 2016 +0100 @@ -922,6 +922,33 @@ console.log("Checkbox: " + node.specification.statement); var inputs = this.popupResponse.getElementsByTagName('input'); node.response = []; + var numChecked = 0; + for (var i = 0; i < node.specification.options.length; i++) { + if (inputs[i].checked) { + numChecked++; + } + } + if (node.specification.min != undefined) { + if (node.specification.max == undefined) { + if (numChecked < node.specification.min) { + var msg = "You must select at least " + node.specification.min + " option"; + if (node.specification.min > 1) { + msg += "s"; + } + interfaceContext.lightbox.post("Error", msg); + return; + } + } else { + if (numChecked < node.specification.min || numChecked > node.specification.max) { + if (node.specification.min == node.specification.max) { + interfaceContext.lightbox.post("Error", "You must only select " + node.specification.min); + } else { + interfaceContext.lightbox.post("Error", "You must select between " + node.specification.min + " and " + node.specification.max); + } + return; + } + } + } for (var i = 0; i < node.specification.options.length; i++) { node.response.push({ name: node.specification.options[i].name, @@ -1695,21 +1722,20 @@ }; this.setSynchronousLoop = function () { - // Pads the signals so they are all exactly the same length - // Get the length of the longest signal. - var length = 0; + // Pads the signals so they are all exactly the same duration + // Get the duration of the longest signal. + var duration = 0; var maxId; for (var i = 0; i < this.audioObjects.length; i++) { - if (length < this.audioObjects[i].buffer.buffer.length) { - length = this.audioObjects[i].buffer.buffer.length; + if (duration < this.audioObjects[i].buffer.buffer.duration) { + duration = this.audioObjects[i].buffer.buffer.duration; maxId = i; } } // Extract the audio and zero-pad for (var ao of this.audioObjects) { - var lengthDiff = length - ao.buffer.buffer.length; - if (lengthDiff > 0) { - ao.buffer.buffer = ao.buffer.copyBuffer(0, samplesToSeconds(lengthDiff, ao.buffer.buffer.sampleRate)); + if (ao.buffer.buffer.duration !== duration) { + ao.buffer.buffer = ao.buffer.copyBuffer(0, duration - ao.buffer.buffer.duration); } } }; @@ -3245,8 +3271,10 @@ break; case "radio": var child = this.parent.document.createElement('response'); - child.setAttribute('name', node.response.name); - child.textContent = node.response.text; + if (node.response !== null) { + child.setAttribute('name', node.response.name); + child.textContent = node.response.text; + } surveyresult.appendChild(child); break; case "checkbox": diff -r 9b536838a962 -r 249a1152e525 js/specification.js --- a/js/specification.js Tue Oct 18 10:33:17 2016 +0100 +++ b/js/specification.js Tue Oct 18 15:49:58 2016 +0100 @@ -1,12 +1,12 @@ function Specification() { - // Handles the decoding of the project specification XML into a simple JavaScript Object. - + // Handles the decoding of the project specification XML into a simple JavaScript Object. + // attributes - this.interface = null; - this.projectReturn = null; + this.interface = null; + this.projectReturn = null; this.returnURL = null; - this.randomiseOrder = null; - this.poolSize = null; + this.randomiseOrder = null; + this.poolSize = null; this.loudness = null; this.sampleRate = null; this.calibration = null; @@ -14,32 +14,31 @@ this.preSilence = null; this.postSilence = null; this.playOne = null; - + // nodes this.metrics = null; this.preTest = undefined; this.postTest = undefined; - this.pages = []; - this.interfaces = null; - this.errors = []; - this.schema = null; + this.pages = []; + this.interfaces = null; + this.errors = []; + this.schema = null; this.exitText = "Thank you."; - - this.processAttribute = function(attribute,schema,schemaRoot) - { - // attribute is the string returned from getAttribute on the XML - // schema is the node - if (schema.getAttribute('name') == undefined && schema.getAttribute('ref') != undefined) - { - schema = schemaRoot.getAllElementsByName(schema.getAttribute('ref'))[0]; - } - var defaultOpt = schema.getAttribute('default'); - if (attribute == null) { - attribute = defaultOpt; - } - var dataType = schema.getAttribute('type'); - if (typeof dataType == "string") { dataType = dataType.substr(3);} - else { + + this.processAttribute = function (attribute, schema, schemaRoot) { + // attribute is the string returned from getAttribute on the XML + // schema is the node + if (schema.getAttribute('name') == undefined && schema.getAttribute('ref') != undefined) { + schema = schemaRoot.getAllElementsByName(schema.getAttribute('ref'))[0]; + } + var defaultOpt = schema.getAttribute('default'); + if (attribute == null) { + attribute = defaultOpt; + } + var dataType = schema.getAttribute('type'); + if (typeof dataType == "string") { + dataType = dataType.substr(3); + } else { var rest = schema.getAllElementsByTagName("xs:restriction").concat(schema.getAllElementsByTagName("xs:enumeration")); if (rest.length > 0) { dataType = rest[0].getAttribute("base"); @@ -52,129 +51,122 @@ dataType = "string"; } } - if (attribute == null) - { - return attribute; - } - switch(dataType) - { - case "boolean": - if (attribute == 'true'){attribute = true;}else{attribute=false;} - break; - case "negativeInteger": - case "positiveInteger": - case "nonNegativeInteger": - case "nonPositiveInteger": - case "integer": - case "decimal": - case "short": - attribute = Number(attribute); - break; - case "string": - default: - attribute = String(attribute); - break; - } - return attribute; - }; - - this.decode = function(projectXML) { - this.errors = []; - // projectXML - DOM Parsed document - this.projectXML = projectXML.childNodes[0]; - var setupNode = projectXML.getElementsByTagName('setup')[0]; - var schemaSetup = this.schema.getAllElementsByName('setup')[0]; - // First decode the attributes - var attributes = schemaSetup.getAllElementsByTagName('xs:attribute'); - for (var i=0; i 1) - { - this.errors.push("Only one node in the node allowed! Others except first ingnored!"); - } - this.interfaces = new this.interfaceNode(this); - if (interfaceNode.length != 0) - { - interfaceNode = interfaceNode[0]; - this.interfaces.decode(this,interfaceNode,this.schema.getAllElementsByName('interface')[1]); - } - - // Page tags - var pageTags = projectXML.getElementsByTagName('page'); - var pageSchema = this.schema.getAllElementsByName('page')[0]; - for (var i=0; i 1) { + this.errors.push("Only one node in the node allowed! Others except first ingnored!"); + } + this.interfaces = new this.interfaceNode(this); + if (interfaceNode.length != 0) { + interfaceNode = interfaceNode[0]; + this.interfaces.decode(this, interfaceNode, this.schema.getAllElementsByName('interface')[1]); + } + + // Page tags + var pageTags = projectXML.getElementsByTagName('page'); + var pageSchema = this.schema.getAllElementsByName('page')[0]; + for (var i = 0; i < pageTags.length; i++) { + var node = new this.page(this); + node.decode(this, pageTags[i], pageSchema); + this.pages.push(node); + } + }; + + this.encode = function () { + var RootDocument = document.implementation.createDocument(null, "waet"); + var root = RootDocument.firstChild; + root.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance"); + root.setAttribute("xsi:noNamespaceSchemaLocation", "test-schema.xsd"); + // Build setup node var setup = RootDocument.createElement("setup"); var schemaSetup = this.schema.getAllElementsByName('setup')[0]; // First decode the attributes var attributes = schemaSetup.getAllElementsByTagName('xs:attribute'); - for (var i=0; i var commentboxprefix = root.createElement("commentboxprefix"); commentboxprefix.textContent = this.commentBoxPrefix; AHNode.appendChild(commentboxprefix); - - for (var i=0; i - for (var i=0; i + for (var i = 0; i < this.commentQuestions.length; i++) { + AHNode.appendChild(this.commentQuestions[i].encode(root)); + } + + AHNode.appendChild(this.preTest.encode(root)); AHNode.appendChild(this.postTest.encode(root)); - return AHNode; - }; - - this.commentQuestionNode = function(specification) { - this.id = null; + return AHNode; + }; + + this.commentQuestionNode = function (specification) { + this.id = null; this.name = undefined; - this.type = undefined; - this.options = []; - this.statement = undefined; - this.schema = specification.schema.getAllElementsByName('commentquestion')[0]; - this.decode = function(parent,xml) - { - this.id = xml.id; + this.type = undefined; + this.options = []; + this.statement = undefined; + this.schema = specification.schema.getAllElementsByName('commentquestion')[0]; + this.decode = function (parent, xml) { + this.id = xml.id; this.name = xml.getAttribute('name'); - this.type = xml.getAttribute('type'); - this.statement = xml.getElementsByTagName('statement')[0].textContent; - var optNodes = xml.getElementsByTagName('option'); - for (var i=0; i= 0) { + this.parent.parent.children.splice(index,1); + } + index = this.parent.parent.specification.conditions.findIndex(function(element){ + if (this == element) {return true;} return false; + },this.parent.specification); + if (index >= 0) { + this.parent.parent.specification.conditions.splice(index); + } + } + } + this.deleteNode.root.textContent = "Delete"; + this.deleteNode.root.addEventListener("click",this.deleteNode); + + this.buttonDOM.appendChild(this.deleteNode.root); + } + + this.addConditional = { + root: document.createElement("button"), + parent: this, + handleEvent: function(event) { + var spec = { + check: null, + value: null, + jumpToOnPass: null, + jumpToOnFail: null + }; + this.parent.specification.conditions.push(spec); + var condition = new Conditional(this.parent,spec); + this.parent.children.push(condition); + this.parent.childrenDOM.appendChild(condition.rootDOM); + } + } + this.addConditional.root.addEventListener("click",this.addConditional); + this.addConditional.root.textContent = "Add Condition"; + this.buttonDOM.appendChild(this.addConditional.root); + this.editNode = { root: document.createElement("button"), parent: this, @@ -2017,6 +2192,12 @@ this.moveButtons.root_down.textContent = "Move Down"; this.buttonDOM.appendChild(this.moveButtons.root_up); this.buttonDOM.appendChild(this.moveButtons.root_down); + + for (var condition of this.specification.conditions) { + var newNode = new Conditional(this,condition); + this.children.push(newNode); + this.childrenDOM.appendChild(newNode.rootDOM); + } } this.addNode = { root: document.createElement("button"), diff -r 9b536838a962 -r 249a1152e525 tests/examples/project.xml --- a/tests/examples/project.xml Tue Oct 18 10:33:17 2016 +0100 +++ b/tests/examples/project.xml Tue Oct 18 15:49:58 2016 +0100 @@ -6,7 +6,7 @@ Please enter your name. - + Please select with which activities you have any experience (example checkbox question) diff -r 9b536838a962 -r 249a1152e525 xml/test-schema.xsd --- a/xml/test-schema.xsd Tue Oct 18 10:33:17 2016 +0100 +++ b/xml/test-schema.xsd Tue Oct 18 15:49:58 2016 +0100 @@ -26,8 +26,8 @@ - - + + @@ -96,6 +96,7 @@ + @@ -254,16 +255,16 @@ - - - - + + + + - - - + + + @@ -295,7 +296,7 @@ - +