Mercurial > hg > webaudioevaluationtool
view test_create/test_create.html @ 501:9a8ede168aba Dev_main
New test creator tool. Still WIP, but much more dynamic. Based on XSD and external lists so far easier to modify.
author | Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk> |
---|---|
date | Wed, 10 Feb 2016 12:02:25 +0000 |
parents | db353cc479b8 |
children | 58fd8bcc6620 |
line wrap: on
line source
<html> <head> <!-- This defines the test creator tool for the Web Audio Evaluation Toolbox --> <link rel='stylesheet' type="text/css" href="style.css"/> <script type="text/javascript"> // Copy of Specifiation node from Core.js function Specification() { // Handles the decoding of the project specification XML into a simple JavaScript Object. this.interface = null; this.projectReturn = null; this.randomiseOrder = null; this.testPages = null; this.pages = []; this.metrics = null; this.interfaces = null; this.loudness = null; this.errors = []; this.schema = null; this.randomiseOrder = function(input) { // This takes an array of information and randomises the order var N = input.length; var inputSequence = []; // For safety purposes: keep track of randomisation for (var counter = 0; counter < N; ++counter) inputSequence.push(counter) // Fill array var inputSequenceClone = inputSequence.slice(0); var holdArr = []; var outputSequence = []; for (var n=0; n<N; n++) { // First pick a random number var r = Math.random(); // Multiply and floor by the number of elements left r = Math.floor(r*input.length); // Pick out that element and delete from the array holdArr.push(input.splice(r,1)[0]); // Do the same with sequence outputSequence.push(inputSequence.splice(r,1)[0]); } console.log(inputSequenceClone.toString()); // print original array to console console.log(outputSequence.toString()); // print randomised array to console return holdArr; }; this.processAttribute = function(attribute,schema) { // attribute is the string returned from getAttribute on the XML // schema is the <xs:attribute> node if (schema.getAttribute('name') == undefined && schema.getAttribute('ref') != undefined) { schema = this.schema.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 {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 in attributes) { if (isNaN(Number(i)) == true){break;} var attributeName = attributes[i].getAttribute('name'); var projectAttr = setupNode.getAttribute(attributeName); projectAttr = this.processAttribute(projectAttr,attributes[i]); switch(typeof projectAttr) { case "number": case "boolean": eval('this.'+attributeName+' = '+projectAttr); break; case "string": eval('this.'+attributeName+' = "'+projectAttr+'"'); break; } } this.metrics = new this.metricNode(); this.metrics.decode(this,setupNode.getElementsByTagName('metric')[0]); // Now process the survey node options var survey = setupNode.getElementsByTagName('survey'); for (var i in survey) { if (isNaN(Number(i)) == true){break;} var location = survey[i].getAttribute('location'); if (location == 'pre' || location == 'before') { if (this.preTest != null){this.errors.push("Already a pre/before test survey defined! Ignoring second!!");} else { this.preTest = new this.surveyNode(); this.preTest.decode(this,survey[i]); } } else if (location == 'post' || location == 'after') { if (this.postTest != null){this.errors.push("Already a post/after test survey defined! Ignoring second!!");} else { this.postTest = new this.surveyNode(); this.postTest.decode(this,survey[i]); } } } var interfaceNode = setupNode.getElementsByTagName('interface'); if (interfaceNode.length > 1) { this.errors.push("Only one <interface> node in the <setup> node allowed! Others except first ingnored!"); } this.interfaces = new this.interfaceNode(); 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(); node.decode(this,pageTags[i],pageSchema); this.pages.push(node); } }; this.encode = function() { var root = document.implementation.createDocument(null,"waet"); // Build setup node return root; }; this.surveyNode = function() { this.location = null; this.options = []; this.schema = specification.schema.getAllElementsByName('survey')[0]; this.OptionNode = function() { this.type = undefined; this.schema = specification.schema.getAllElementsByName('surveyentry')[0]; this.id = undefined; this.mandatory = undefined; this.statement = undefined; this.boxsize = undefined; this.options = []; this.min = undefined; this.max = undefined; this.step = undefined; this.decode = function(parent,child) { var attributeMap = this.schema.getAllElementsByTagName('xs:attribute'); for (var i in attributeMap){ if(isNaN(Number(i)) == true){break;} var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref'); var projectAttr = child.getAttribute(attributeName); projectAttr = parent.processAttribute(projectAttr,attributeMap[i]); switch(typeof projectAttr) { case "number": case "boolean": eval('this.'+attributeName+' = '+projectAttr); break; case "string": eval('this.'+attributeName+' = "'+projectAttr+'"'); break; } } this.statement = child.getElementsByTagName('statement')[0].textContent; if (this.type == "checkbox" || this.type == "radio") { var children = child.getElementsByTagName('option'); if (children.length == null) { console.log('Malformed' +child.nodeName+ 'entry'); this.statement = 'Malformed' +child.nodeName+ 'entry'; this.type = 'statement'; } else { this.options = []; for (var i in children) { if (isNaN(Number(i))==true){break;} this.options.push({ name: children[i].getAttribute('name'), text: children[i].textContent }); } } } }; this.exportXML = function(root) { var node = root.createElement('surveyelement'); node.setAttribute('type',this.type); var statement = root.createElement('statement'); statement.textContent = this.statement; node.appendChild(statement); switch(this.type) { case "statement": break; case "question": node.id = this.id; node.setAttribute("mandatory",this.mandatory); node.setAttribute("boxsize",this.boxsize); break; case "number": node.id = this.id; node.setAttribute("mandatory",this.mandatory); node.setAttribute("min", this.min); node.setAttribute("max", this.max); node.setAttribute("step", this.step); break; case "checkbox": case "radio": node.id = this.id; for (var i=0; i<this.options.length; i++) { var option = this.options[i]; var optionNode = root.createElement("option"); optionNode.setAttribute("name",option.name); optionNode.textContent = option.text; node.appendChild(optionNode); } break; } return node; }; }; this.decode = function(parent,xml) { this.location = xml.getAttribute('location'); if (this.location == 'before'){this.location = 'pre';} else if (this.location == 'after'){this.location = 'post';} for (var i in xml.children) { if(isNaN(Number(i))==true){break;} var node = new this.OptionNode(); node.decode(parent,xml.children[i]); this.options.push(node); } }; this.encode = function(root) { var node = root.createElement('survey'); node.setAttribute('location',this.location); for (var i=0; i<this.options.length; i++) { node.appendChild(this.options[i].exportXML()); } return node; }; }; this.interfaceNode = function() { this.title = null; this.name = null; this.options = []; this.scales = []; this.schema = specification.schema.getAllElementsByName('interface')[1]; this.decode = function(parent,xml) { this.name = xml.getAttribute('name'); var titleNode = xml.getElementsByTagName('title'); if (titleNode.length == 1) { this.title = titleNode[0].textContent; } var interfaceOptionNodes = xml.getElementsByTagName('interfaceoption'); // Extract interfaceoption node schema var interfaceOptionNodeSchema = this.schema.getAllElementsByName('interfaceoption')[0]; var attributeMap = interfaceOptionNodeSchema.getAllElementsByTagName('xs:attribute'); for (var i=0; i<interfaceOptionNodes.length; i++) { var ioNode = interfaceOptionNodes[i]; var option = {}; for (var j=0; j<attributeMap.length; j++) { var attributeName = attributeMap[j].getAttribute('name') || attributeMap[j].getAttribute('ref'); var projectAttr = ioNode.getAttribute(attributeName); projectAttr = parent.processAttribute(projectAttr,attributeMap[j]); switch(typeof projectAttr) { case "number": case "boolean": eval('option.'+attributeName+' = '+projectAttr); break; case "string": eval('option.'+attributeName+' = "'+projectAttr+'"'); break; } } this.options.push(option); } // Now the scales nodes var scaleParent = xml.getElementsByTagName('scales'); if (scaleParent.length == 1) { scaleParent = scaleParent[0]; for (var i=0; i<scaleParent.children.length; i++) { var child = scaleParent.children[i]; this.scales.push({ text: child.textContent, position: Number(child.getAttribute('position')) }); } } }; this.encode = function(root) { }; }; this.metricNode = function() { this.enabled = []; this.decode = function(parent, xml) { var children = xml.getElementsByTagName('metricenable'); for (var i in children) { if (isNaN(Number(i)) == true){break;} this.enabled.push(children[i].textContent); } } this.encode = function(root) { var node = root.createElement('metric'); for (var i in this.enabled) { if (isNaN(Number(i)) == true){break;} var child = root.createElement('metricenable'); child.textContent = this.enabled[i]; node.appendChild(child); } return node; } } this.page = function() { this.presentedId = undefined; this.id = undefined; this.hostURL = undefined; this.randomiseOrder = undefined; this.loop = undefined; this.showElementComments = undefined; this.outsideReference = null; this.loudness = null; this.preTest = null; this.postTest = null; this.interfaces = []; this.commentBoxPrefix = "Comment on track"; this.audioElements = []; this.commentQuestions = []; this.schema = specification.schema.getAllElementsByName("page")[0]; this.decode = function(parent,xml) { var attributeMap = this.schema.getAllElementsByTagName('xs:attribute'); for (var i=0; i<attributeMap.length; i++) { var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref'); var projectAttr = xml.getAttribute(attributeName); projectAttr = parent.processAttribute(projectAttr,attributeMap[i]); switch(typeof projectAttr) { case "number": case "boolean": eval('this.'+attributeName+' = '+projectAttr); break; case "string": eval('this.'+attributeName+' = "'+projectAttr+'"'); break; } } // Get the Comment Box Prefix var CBP = xml.getElementsByTagName('commentboxprefix'); if (CBP.length != 0) { this.commentBoxPrefix = CBP[0].textContent; } // Now decode the interfaces var interfaceNode = xml.getElementsByTagName('interface'); for (var i=0; i<interfaceNode.length; i++) { var node = new parent.interfaceNode(); node.decode(this,interfaceNode[i],parent.schema.getAllElementsByName('interface')[1]); this.interfaces.push(node); } // Now process the survey node options var survey = xml.getElementsByTagName('survey'); var surveySchema = parent.schema.getAllElementsByName('survey')[0]; for (var i in survey) { if (isNaN(Number(i)) == true){break;} var location = survey[i].getAttribute('location'); if (location == 'pre' || location == 'before') { if (this.preTest != null){this.errors.push("Already a pre/before test survey defined! Ignoring second!!");} else { this.preTest = new parent.surveyNode(); this.preTest.decode(parent,survey[i],surveySchema); } } else if (location == 'post' || location == 'after') { if (this.postTest != null){this.errors.push("Already a post/after test survey defined! Ignoring second!!");} else { this.postTest = new parent.surveyNode(); this.postTest.decode(parent,survey[i],surveySchema); } } } // Now process the audioelement tags var audioElements = xml.getElementsByTagName('audioelement'); for (var i=0; i<audioElements.length; i++) { var node = new this.audioElementNode(); node.decode(this,audioElements[i]); this.audioElements.push(node); } // Now decode the commentquestions var commentQuestions = xml.getElementsByTagName('commentquestion'); for (var i=0; i<commentQuestions.length; i++) { var node = new this.commentQuestionNode(); node.decode(parent,commentQuestions[i]); this.commentQuestions.push(node); } }; this.encode = function(root) { var AHNode = root.createElement("audioHolder"); AHNode.id = this.id; AHNode.setAttribute("hostURL",this.hostURL); AHNode.setAttribute("sampleRate",this.sampleRate); AHNode.setAttribute("randomiseOrder",this.randomiseOrder); AHNode.setAttribute("repeatCount",this.repeatCount); AHNode.setAttribute("loop",this.loop); AHNode.setAttribute("elementComments",this.elementComments); if(this.loudness != null) {AHNode.setAttribute("loudness",this.loudness);} if(this.initialPosition != null) { AHNode.setAttribute("loudness",this.initialPosition*100); } for (var i=0; i<this.interfaces.length; i++) { AHNode.appendChild(this.interfaces[i].encode(root)); } for (var i=0; i<this.audioElements.length; i++) { AHNode.appendChild(this.audioElements[i].encode(root)); } // Create <CommentQuestion> for (var i=0; i<this.commentQuestions.length; i++) { AHNode.appendChild(this.commentQuestions[i].exportXML(root)); } // Create <PreTest> var AHPreTest = root.createElement("PreTest"); for (var i=0; i<this.preTest.options.length; i++) { AHPreTest.appendChild(this.preTest.options[i].exportXML(root)); } var AHPostTest = root.createElement("PostTest"); for (var i=0; i<this.postTest.options.length; i++) { AHPostTest.appendChild(this.postTest.options[i].exportXML(root)); } AHNode.appendChild(AHPreTest); AHNode.appendChild(AHPostTest); return AHNode; }; this.commentQuestionNode = function() { this.id = null; 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 = xml.getAttribute('type'); this.statement = xml.getElementsByTagName('statement')[0].textContent; var optNodes = xml.getElementsByTagName('option'); for (var i=0; i<optNodes.length; i++) { var optNode = optNodes[i]; this.options.push({ name: optNode.getAttribute('name'), text: optNode.textContent }); } }; this.encode = function(root) { }; }; this.audioElementNode = function() { this.url = null; this.id = null; this.parent = null; this.type = null; this.marker = false; this.enforce = false; this.gain = 1.0; this.schema = specification.schema.getAllElementsByName('audioelement')[0];; this.parent = null; this.decode = function(parent,xml) { this.parent = parent; var attributeMap = this.schema.getAllElementsByTagName('xs:attribute'); for (var i=0; i<attributeMap.length; i++) { var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref'); var projectAttr = xml.getAttribute(attributeName); projectAttr = specification.processAttribute(projectAttr,attributeMap[i]); switch(typeof projectAttr) { case "number": case "boolean": eval('this.'+attributeName+' = '+projectAttr); break; case "string": eval('this.'+attributeName+' = "'+projectAttr+'"'); break; } } }; this.encode = function(root) { var AENode = root.createElement("audioElements"); AENode.id = this.id; AENode.setAttribute("url",this.url); AENode.setAttribute("type",this.type); AENode.setAttribute("gain",linearToDecibel(this.gain)); if (this.marker != false) { AENode.setAttribute("marker",this.marker*100); } return AENode; }; }; }; } </script> <script type="text/javascript" src="test_core.js"/> <script type="text/javascript"> </script> </head> <body> <div id="popupHolder"></div> <div id="blanket"></div> <div id="content"></div> </body> </html>