Mercurial > hg > webaudioevaluationtool
changeset 2192:ed5a54029157
Major updates. Specification Nodes now own file (specification.js). Updating Analysis to allow filtering based on survey responses.
author | Nicholas Jillings <nickjillings@users.noreply.github.com> |
---|---|
date | Thu, 31 Mar 2016 13:31:42 +0100 |
parents | dd5a8556235c |
children | f41d6dd8c66e |
files | analysis/analysis.css analysis/analysis.js analysis/index.html core.js index.html scripts/get_filtered_count.php scripts/get_tests.php specification.js test_create/test_create.html |
diffstat | 9 files changed, 1230 insertions(+), 1309 deletions(-) [+] |
line wrap: on
line diff
--- a/analysis/analysis.css Tue Mar 29 14:37:07 2016 +0100 +++ b/analysis/analysis.css Thu Mar 31 13:31:42 2016 +0100 @@ -7,4 +7,10 @@ padding-left: 15px; background-color: rgb(200,200,200); border: 2px dashed black; +} +table td tr{ + padding: 5px; +} +div.filter-entry{ + padding: 5px; } \ No newline at end of file
--- a/analysis/analysis.js Tue Mar 29 14:37:07 2016 +0100 +++ b/analysis/analysis.js Thu Mar 31 13:31:42 2016 +0100 @@ -2,11 +2,119 @@ * Analysis script for WAET */ -var chartContext; +// Firefox does not have an XMLDocument.prototype.getElementsByName +// and there is no searchAll style command, this custom function will +// search all children recusrively for the name. Used for XSD where all +// element nodes must have a name and therefore can pull the schema node +XMLDocument.prototype.getAllElementsByName = function(name) +{ + name = String(name); + var selected = this.documentElement.getAllElementsByName(name); + return selected; +} + +Element.prototype.getAllElementsByName = function(name) +{ + name = String(name); + var selected = []; + var node = this.firstElementChild; + while(node != null) + { + if (node.getAttribute('name') == name) + { + selected.push(node); + } + if (node.childElementCount > 0) + { + selected = selected.concat(node.getAllElementsByName(name)); + } + node = node.nextElementSibling; + } + return selected; +} + +XMLDocument.prototype.getAllElementsByTagName = function(name) +{ + name = String(name); + var selected = this.documentElement.getAllElementsByTagName(name); + return selected; +} + +Element.prototype.getAllElementsByTagName = function(name) +{ + name = String(name); + var selected = []; + var node = this.firstElementChild; + while(node != null) + { + if (node.nodeName == name) + { + selected.push(node); + } + if (node.childElementCount > 0) + { + selected = selected.concat(node.getAllElementsByTagName(name)); + } + node = node.nextElementSibling; + } + return selected; +} + +// Firefox does not have an XMLDocument.prototype.getElementsByName +if (typeof XMLDocument.prototype.getElementsByName != "function") { + XMLDocument.prototype.getElementsByName = function(name) + { + name = String(name); + var node = this.documentElement.firstElementChild; + var selected = []; + while(node != null) + { + if (node.getAttribute('name') == name) + { + selected.push(node); + } + node = node.nextElementSibling; + } + return selected; + } +} + +var chartContext, testData; window.onload = function() { // Load the Visualization API and the corechart package. - google.charts.load('current', {'packages':['corechart']}); + google.charts.load('current', {'packages':['corechart']}); chartContext = new Chart(); + testData = new Data(); +} + +function get(url) { + // Return a new promise. + return new Promise(function(resolve, reject) { + // Do the usual XHR stuff + var req = new XMLHttpRequest(); + req.open('GET', url); + req.onload = function() { + // This is called even on 404 etc + // so check the status + if (req.status == 200) { + // Resolve the promise with the response text + resolve(req.response); + } + else { + // Otherwise reject with the status text + // which will hopefully be a meaningful error + reject(Error(req.statusText)); + } + }; + + // Handle network errors + req.onerror = function() { + reject(Error("Network Error")); + }; + + // Make the request + req.send(); + }); } function arrayMean(values) { @@ -115,30 +223,9 @@ } function Chart() { - this.valueData = null; - this.commentData = null; - this.loadStatus = 0; + this.valueData; this.charts = []; - var XMLHttp = new XMLHttpRequest(); - XMLHttp.parent = this; - XMLHttp.open("GET","../scripts/score_parser.php?format=JSON",true); - XMLHttp.onload = function() { - // Now we have the JSON data, extract - this.parent.valueData = JSON.parse(this.responseText); - this.parent.loadStatus++; - } - XMLHttp.send(); - var XMLHttp2 = new XMLHttpRequest(); - XMLHttp2.parent = this; - XMLHttp2.open("GET","../scripts/comment_parser.php?format=JSON",true); - XMLHttp2.onload = function() { - // Now we have the JSON data, extract - this.parent.commentData = JSON.parse(this.responseText); - this.parent.loadStatus++; - } - XMLHttp2.send(); - this.chartObject = function(name) { // Create the charting object this.name = name; @@ -491,4 +578,226 @@ } } } +} + +function Data() { + // This holds the link between the server side calculations and the client side visualisation of the data + + // Dynamically generate the test filtering / page filterting tools + var self = this; + // Collect the test types and counts + this.testSavedDiv = document.getElementById("test-saved"); + this.testSaves = null; + this.selectURL = null; + + this.specification = new Specification(); + get("../test-schema.xsd").then(function(response){ + var parse = new DOMParser(); + self.specification.schema = parse.parseFromString(response,'text/xml'); + },function(error){ + console.log("ERROR: Could not get Test Schema"); + }); + this.update = function(url) { + var self = this; + get(url).then(function(response){ + var parse = new DOMParser(); + self.specification.decode(parse.parseFromString(response,'text/xml')); + interfaceContext.generateFilters(self.specification); + return true; + },function(error){ + console.log("ERROR: Could not get"+url); + return false; + }); + } + var get_test = new XMLHttpRequest(); + get_test.parent = this; + get_test.open("GET","../scripts/get_tests.php?format=JSON",true); + get_test.onload = function() { + this.parent.testSavedDiv.innerHTML = null; + var table = document.createElement("table"); + table.innerHTML = "<tr><td>Test Filename</td><td>Count</td><td>Include</td></tr>"; + this.parent.testSaves = JSON.parse(this.responseText); + for (var test of this.parent.testSaves.tests) { + var tableRow = document.createElement("tr"); + var tableRowFilename = document.createElement("td"); + tableRowFilename.textContent = test.testName; + var tableRowCount = document.createElement("td"); + tableRowCount.textContent = test.files.length; + tableRow.appendChild(tableRowFilename); + tableRow.appendChild(tableRowCount); + var tableRowInclude = document.createElement("td"); + var tableRowIncludeInput = document.createElement("input"); + tableRowIncludeInput.type = "radio"; + tableRowIncludeInput.name = "test-include"; + tableRowIncludeInput.setAttribute("source",test.testName); + tableRowIncludeInput.addEventListener("change",this.parent); + tableRowInclude.appendChild(tableRowIncludeInput); + tableRow.appendChild(tableRowInclude); + table.appendChild(tableRow); + } + this.parent.testSavedDiv.appendChild(table); + } + get_test.send(); + this.handleEvent = function(event) { + if (event.currentTarget.nodeName == "INPUT" && event.currentTarget.name == "test-include") { + // Changed the test specification + this.selectURL = event.currentTarget.getAttribute("source"); + this.update(this.selectURL); + } + } +} + +var interfaceContext = new function() { + // This creates the interface for the user to connect with the dynamic back-end to retrieve data + this.rootDOM = document.createElement("div"); + this.filterDOM = document.createElement("div"); + this.filterDOM.innerHTML = "<p>PreTest Filters</p><div id='filter-count'></div>"; + this.filterObjects = []; + this.generateFilters = function(specification) { + // Filters are based on the pre and post global surverys + var FilterObject = function(parent,specification) { + this.parent = parent; + this.specification = specification; + this.rootDOM = document.createElement("div"); + this.rootDOM.innerHTML = "<span>ID: "+specification.id+", Type: "+specification.type+"</span>"; + this.rootDOM.className = "filter-entry"; + this.handleEvent = function(event) { + switch(this.specification.type) { + case "number": + var name = event.currentTarget.name; + eval("this."+name+" = event.currentTarget.value"); + break; + case "checkbox": + break; + case "radio": + break; + } + this.parent.getFileCount(); + } + this.getFilterPairs = function() { + var pairs = []; + switch(this.specification.type) { + case "number": + if (this.min != "") { + pairs.push([specification.id+"-min",this.min]); + } + if (this.max != "") { + pairs.push([specification.id+"-max",this.max]); + } + break; + case "radio": + case "checkbox": + for (var i=0; i<this.options.length; i++) { + if (!this.options[i].checked) { + pairs.push([specification.id+"-exclude-"+i,specification.options[i].name]); + } + } + break; + } + return pairs; + } + switch(specification.type) { + case "number": + // Number can be ranged by min/max levels + this.min = ""; + this.max = ""; + this.minDOM = document.createElement("input"); + this.minDOM.type = "number"; + this.minDOM.name = "min"; + this.minDOM.addEventListener("change",this); + this.minDOMText = document.createElement("span"); + this.minDOMText.textContent = "Minimum: "; + var pairHolder = document.createElement("div"); + pairHolder.appendChild(this.minDOMText); + pairHolder.appendChild(this.minDOM); + this.rootDOM.appendChild(pairHolder); + + this.maxDOM = document.createElement("input"); + this.maxDOM.type = "number"; + this.maxDOM.name = "max"; + this.maxDOM.addEventListener("change",this); + this.maxDOMText = document.createElement("span"); + this.maxDOMText.textContent = "Maximum: "; + var pairHolder = document.createElement("div"); + pairHolder.appendChild(this.maxDOMText); + pairHolder.appendChild(this.maxDOM); + this.rootDOM.appendChild(pairHolder); + break; + case "radio": + case "checkbox": + this.options = []; + for (var i=0; i<specification.options.length; i++) { + var option = specification.options[i]; + var pairHolder = document.createElement("div"); + var text = document.createElement("span"); + text.textContent = option.text; + var check = document.createElement("input"); + check.type = "checkbox"; + check.setAttribute("option-index",i); + check.checked = true; + check.addEventListener("click",this); + this.options.push(check); + pairHolder.appendChild(text); + pairHolder.appendChild(check); + this.rootDOM.appendChild(pairHolder); + } + break; + default: + break; + } + } + for (var survey_entry of specification.preTest.options) { + switch(survey_entry.type) { + case "number": + case "radio": + case "checkbox": + var node = new FilterObject(this,survey_entry); + this.filterObjects.push(node); + this.filterDOM.appendChild(node.rootDOM); + break; + default: + break; + } + } + for (var survey_entry of specification.postTest.options) { + switch(survey_entry.type) { + case "number": + case "radio": + case "checkbox": + var node = new FilterObject(this,survey_entry); + this.filterObjects.push(node); + this.filterDOM.appendChild(node.rootDOM); + break; + default: + break; + } + } + document.getElementById("test-saved").appendChild(this.filterDOM); + } + this.getFileCount = function() { + // First we must get the filter pairs + var pairs = []; + for (var obj of this.filterObjects) { + pairs = pairs.concat(obj.getFilterPairs()); + } + var req_str = "../scripts/get_filtered_count.php?url="+testData.selectURL; + var index = 0; + while(pairs[index] != undefined) { + req_str += '&'; + req_str += pairs[index][0]+"="+pairs[index][1]; + index++; + } + get(req_str).then(function(response){ + var urls = JSON.parse(response); + var str = "Filtered to "+urls.urls.length+" file"; + if (urls.urls.length != 1) { + str += "s."; + } else { + str += "."; + } + document.getElementById("filter-count").textContent = str; + },function(error){ + console.error(error); + }); + } } \ No newline at end of file
--- a/analysis/index.html Tue Mar 29 14:37:07 2016 +0100 +++ b/analysis/index.html Thu Mar 31 13:31:42 2016 +0100 @@ -4,9 +4,11 @@ <link rel='stylesheet' href="analysis.css" type="text/css"/> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <script type="text/javascript" src="analysis.js"></script> + <script type="text/javascript" src="../specification.js"></script> </head> <body> <h1>Web Audio Evaluation Toolbox: Analysis</h1> + <div id="test-saved"></div> <button onclick="chartContext.clear();">Clear Charts</button> <div id="test-charts"> <p>Charts per test</p>
--- a/core.js Tue Mar 29 14:37:07 2016 +0100 +++ b/core.js Thu Mar 31 13:31:42 2016 +0100 @@ -28,6 +28,16 @@ // Add a prototype to the bufferNode to hold the computed LUFS loudness AudioBuffer.prototype.lufs = undefined; +// Convert relative URLs into absolutes +function escapeHTML(s) { + return s.split('&').join('&').split('<').join('<').split('"').join('"'); +} +function qualifyURL(url) { + var el= document.createElement('div'); + el.innerHTML= '<a href="'+escapeHTML(url)+'">x</a>'; + return el.firstChild.href; +} + // Firefox does not have an XMLDocument.prototype.getElementsByName // and there is no searchAll style command, this custom function will // search all children recusrively for the name. Used for XSD where all @@ -1781,644 +1791,6 @@ console.log(outputSequence.toString()); // print randomised array to console return holdArr; } - -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.exitText = "Thank you."; - - this.processAttribute = function(attribute,schema,schemaRoot) - { - // 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 = 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 {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') || attributes[i].getAttribute('ref'); - var projectAttr = setupNode.getAttribute(attributeName); - projectAttr = this.processAttribute(projectAttr,attributes[i],this.schema); - switch(typeof projectAttr) - { - case "number": - case "boolean": - eval('this.'+attributeName+' = '+projectAttr); - break; - case "string": - eval('this.'+attributeName+' = "'+projectAttr+'"'); - break; - } - - } - - var exitTextNode = setupNode.getElementsByTagName('exitText'); - if (exitTextNode.length == 1) { - this.exitText = exitTextNode[0].textContent; - } - - 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 RootDocument = document.implementation.createDocument(null,"waet"); - var root = RootDocument.children[0]; - 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<attributes.length; i++) - { - var name = attributes[i].getAttribute("name"); - if (name == undefined) { - name = attributes[i].getAttribute("ref"); - } - if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") - { - eval("setup.setAttribute('"+name+"',this."+name+")"); - } - } - root.appendChild(setup); - // Survey node - if (this.exitText != null) { - var exitTextNode = RootDocument.createElement('exitText'); - exitTextNode.textContent = this.exitText; - setup.appendChild(exitTextNode); - } - setup.appendChild(this.preTest.encode(RootDocument)); - setup.appendChild(this.postTest.encode(RootDocument)); - setup.appendChild(this.metrics.encode(RootDocument)); - setup.appendChild(this.interfaces.encode(RootDocument)); - for (var page of this.pages) - { - root.appendChild(page.encode(RootDocument)); - } - return RootDocument; - }; - - this.surveyNode = function() { - this.location = null; - this.options = []; - this.parent = null; - this.schema = specification.schema.getAllElementsByName('survey')[0]; - - this.OptionNode = function() { - this.type = undefined; - this.schema = specification.schema.getAllElementsByName('surveyentry')[0]; - this.id = undefined; - this.name = 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],parent.schema); - 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(doc) - { - var node = doc.createElement('surveyentry'); - node.setAttribute('type',this.type); - var statement = doc.createElement('statement'); - statement.textContent = this.statement; - node.appendChild(statement); - node.id = this.id; - if (this.name != undefined) { node.setAttribute("name",this.name);} - if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);} - node.id = this.id; - if (this.name != undefined) {node.setAttribute("name",this.name);} - switch(this.type) - { - case "checkbox": - case "radio": - for (var i=0; i<this.options.length; i++) - { - var option = this.options[i]; - var optionNode = doc.createElement("option"); - optionNode.setAttribute("name",option.name); - optionNode.textContent = option.text; - node.appendChild(optionNode); - } - case "number": - if (this.min != undefined) {node.setAttribute("min", this.min);} - if (this.max != undefined) {node.setAttribute("max", this.max);} - case "question": - if (this.boxsize != undefined) {node.setAttribute("boxsize",this.boxsize);} - if (this.mandatory != undefined) {node.setAttribute("mandatory",this.mandatory);} - default: - break; - } - return node; - }; - }; - this.decode = function(parent,xml) { - this.parent = parent; - 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(doc) { - var node = doc.createElement('survey'); - node.setAttribute('location',this.location); - for (var i=0; i<this.options.length; i++) - { - node.appendChild(this.options[i].exportXML(doc)); - } - 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); - if(parent.processAttribute) { - parent.processAttribute(projectAttr, attributeMap[j], parent.schema) - } else { - parent.parent.processAttribute(projectAttr, attributeMap[j], parent.parent.schema) - } - 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(doc) { - var node = doc.createElement("interface"); - if (typeof name == "string") - node.setAttribute("name",this.name); - for (var option of this.options) - { - var child = doc.createElement("interfaceoption"); - child.setAttribute("type",option.type); - child.setAttribute("name",option.name); - node.appendChild(child); - } - if (this.scales.length != 0) { - var scales = doc.createElement("scales"); - for (var scale of this.scales) - { - var child = doc.createElement("scalelabel"); - child.setAttribute("position",scale.position); - child.textContent = scale.text; - scales.appendChild(child); - } - node.appendChild(scales); - } - return node; - }; - }; - - 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(doc) { - var node = doc.createElement('metric'); - for (var i in this.enabled) - { - if (isNaN(Number(i)) == true){break;} - var child = doc.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.label = 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.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 = parent.processAttribute(projectAttr,attributeMap[i],parent.schema); - 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("page"); - // First decode the attributes - var attributes = this.schema.getAllElementsByTagName('xs:attribute'); - for (var i=0; i<attributes.length; i++) - { - var name = attributes[i].getAttribute("name"); - if (name == undefined) { - name = attributes[i].getAttribute("ref"); - } - if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") - { - eval("AHNode.setAttribute('"+name+"',this."+name+")"); - } - } - if(this.loudness != null) {AHNode.setAttribute("loudness",this.loudness);} - // <commentboxprefix> - var commentboxprefix = root.createElement("commentboxprefix"); - commentboxprefix.textContent = this.commentBoxPrefix; - AHNode.appendChild(commentboxprefix); - - 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].encode(root)); - } - - AHNode.appendChild(this.preTest.encode(root)); - AHNode.appendChild(this.postTest.encode(root)); - return AHNode; - }; - - this.commentQuestionNode = function() { - 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.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<optNodes.length; i++) - { - var optNode = optNodes[i]; - this.options.push({ - name: optNode.getAttribute('name'), - text: optNode.textContent - }); - } - }; - - this.encode = function(root) - { - var node = root.createElement("commentquestion"); - node.id = this.id; - node.setAttribute("type",this.type); - if (this.name != undefined){node.setAttribute("name",this.name);} - var statement = root.createElement("statement"); - statement.textContent = this.statement; - node.appendChild(statement); - for (var option of this.options) - { - var child = root.createElement("option"); - child.setAttribute("name",option.name); - child.textContent = option.text; - node.appendChild(child); - } - return node; - }; - }; - - this.audioElementNode = function() { - this.url = null; - this.id = null; - this.name = null; - this.parent = null; - this.type = null; - this.marker = null; - this.enforce = false; - this.gain = 0.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 = parent.parent.processAttribute(projectAttr,attributeMap[i],parent.parent.schema); - 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("audioelement"); - var attributes = this.schema.getAllElementsByTagName('xs:attribute'); - for (var i=0; i<attributes.length; i++) - { - var name = attributes[i].getAttribute("name"); - if (name == undefined) { - name = attributes[i].getAttribute("ref"); - } - if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") - { - eval("AENode.setAttribute('"+name+"',this."+name+")"); - } - } - return AENode; - }; - }; - }; -} function Interface(specificationObject) { // This handles the bindings between the interface and the audioEngineContext; @@ -3356,6 +2728,7 @@ this.root = this.document.childNodes[0]; var projectDocument = specification.projectXML; projectDocument.setAttribute('file-name',url); + projectDocument.setAttribute('url',qualifyURL(url)); this.root.appendChild(projectDocument); this.root.appendChild(interfaceContext.returnDateNode()); this.root.appendChild(interfaceContext.returnNavigator()); @@ -3516,6 +2889,7 @@ if (element.name != undefined){aeNode.setAttribute('name',element.name)}; aeNode.setAttribute('type',element.type); aeNode.setAttribute('url', element.url); + aeNode.setAttribute('fqurl',qualifyURL(element.url)); aeNode.setAttribute('gain', element.gain); if (element.type == 'anchor' || element.type == 'reference') {
--- a/index.html Tue Mar 29 14:37:07 2016 +0100 +++ b/index.html Thu Mar 31 13:31:42 2016 +0100 @@ -16,11 +16,12 @@ <link rel='stylesheet' type='text/css' href='core.css'> <!-- Use jQuery hosted from Google CDN --> <!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>--> - <script src="jquery-2.1.4.js"></script> - <script src='core.js'></script> - <script src='loudness.js'></script> - <script src='xmllint.js'></script> - <script src='WAVE.js'></script> + <script type="text/javascript" src="jquery-2.1.4.js"></script> + <script type="text/javascript" src='specification.js'></script> + <script type="text/javascript" src='core.js'></script> + <script type="text/javascript" src='loudness.js'></script> + <script type="text/javascript" src='xmllint.js'></script> + <script type="text/javascript" src='WAVE.js'></script> <script type="text/javascript"> // SEARCH QUERY: By using the GET Request option ?url=loca/path/to/project.xml in the URL bar, you can load a project quickly if (window.location.search.length != 0)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/get_filtered_count.php Thu Mar 31 13:31:42 2016 +0100 @@ -0,0 +1,134 @@ +<?php +//http://stackoverflow.com/questions/4444475/transfrom-relative-path-into-absolute-url-using-php +function rel2abs($rel, $base) +{ + /* return if already absolute URL */ + if (parse_url($rel, PHP_URL_SCHEME) != '' || substr($rel, 0, 2) == '//') return $rel; + + /* queries and anchors */ + if ($rel[0]=='#' || $rel[0]=='?') return $base.$rel; + + /* parse base URL and convert to local variables: + $scheme, $host, $path */ + extract(parse_url($base)); + + /* remove non-directory element from path */ + $path = preg_replace('#/[^/]*$#', '', $path); + + /* destroy path if relative url points to root */ + if ($rel[0] == '/') $path = ''; + + /* dirty absolute URL */ + $abs = "$host$path/$rel"; + + /* replace '//' or '/./' or '/foo/../' with '/' */ + $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'); + for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {} + + /* absolute URL is ready! */ + return $scheme.'://'.$abs; +} + +/* + This looks for files that pass the filtering response + The filtering system uses key-value pairs + The key is double encoded using a '-'. The first part is the ID of the item to filter, + the second is the method: + min - Minimum Inclusive + max - Maximum Inclusive + exclude-# - exclude, followed by a number to uniquely add, (will create a triple [], ignore the third as random) +*/ +$keys = []; +$waet_url = null; +foreach ($_GET as $key => $value) { + $key = explode("-",$key); + if ($key[0] == "url") { + $waet_url = $value; + } else { + $v_pair = [$key[1],$value]; + if(array_key_exists($key[0],$keys)) { + // We have some data + array_push($keys[$key[0]],$v_pair); + } else { + // Create new key data + $keys[$key[0]] = [$v_pair]; + } + } +} + +$files = []; +$saves = glob("../saves/*.xml"); +if (is_array($saves)) +{ + foreach($saves as $filename) { + $xml_string = file_get_contents($filename, FILE_TEXT); + $xml_object = simplexml_load_string($xml_string); + if ($xml_object) { + // First we must check the URLs match + $waet = $xml_object->waet[0]; + if (urldecode($waet["url"])==$waet_url) { + // It is part of the dataset, so now perform checks + $continue = true; + foreach($keys as $keyId => $keyArr) { + $elem = $xml_object->xpath("//*[@ref='".$keyId."']"); + $elem = $elem[0]; // Can only be one. + switch ($elem["type"]) { + case "number": + // Number, we must check for min/max + $value = (real)$elem->response; + foreach ($keyArr as $keyCheck) { + if ($keyCheck[0] == 'min' && $value < $keyCheck[1]) { + $continue = false; + break; + } else if ($keyCheck[0] == 'max' && $value > $keyCheck[1]) { + $continue = false; + break; + } + } + break; + case "checkbox": + // Will have an array of <response> + foreach ($elem->response as $response) { + foreach ($keyArr as $keyCheck) { + if ($response["name"] == $keyCheck[1]) { + if($response["checked"] == "true" && $keyCheck[0] == "exclude") { + $continue = false; + break; + } + } + } + if($continue == false) { + break; + } + } + break; + case "radio": + foreach ($keyArr as $keyCheck) { + if ($keyCheck[0] == "exclude" && $elem->response["name"] == $keyCheck[1]) { + + $continue = false; + break; + } + } + break; + default: + break; + } + if ($continue == false) { + break; + } + } + if ($continue) { + array_push($files,rel2abs($filename,"http://".$_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'])); + } + } + } + } +} +if (count($files) == 0) { + echo '{"urls": []}'; +} else { + echo '{"urls": ["'.implode('","',$files).'"]}'; +} + +?> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/get_tests.php Thu Mar 31 13:31:42 2016 +0100 @@ -0,0 +1,96 @@ +<?php +/* + Get Tests + + This script returns the XML test names available, plus the number of tests +*/ + +//http://stackoverflow.com/questions/4444475/transfrom-relative-path-into-absolute-url-using-php +function rel2abs($rel, $base) +{ + /* return if already absolute URL */ + if (parse_url($rel, PHP_URL_SCHEME) != '' || substr($rel, 0, 2) == '//') return $rel; + + /* queries and anchors */ + if ($rel[0]=='#' || $rel[0]=='?') return $base.$rel; + + /* parse base URL and convert to local variables: + $scheme, $host, $path */ + extract(parse_url($base)); + + /* remove non-directory element from path */ + $path = preg_replace('#/[^/]*$#', '', $path); + + /* destroy path if relative url points to root */ + if ($rel[0] == '/') $path = ''; + + /* dirty absolute URL */ + $abs = "$host$path/$rel"; + + /* replace '//' or '/./' or '/foo/../' with '/' */ + $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'); + for($n=1; $n>0; $abs=preg_replace($re, '/', $abs, -1, $n)) {} + + /* absolute URL is ready! */ + return $scheme.'://'.$abs; +} + +// XML Saves location - assumes it will be saves/ +$data = []; +$saves = glob("../saves/*.xml"); +if (is_array($saves)) +{ + foreach($saves as $filename) { + $xml_string = file_get_contents($filename, FILE_TEXT); + $xml_object = simplexml_load_string($xml_string); + if ($xml_object) { + $filename = rel2abs($filename,"http://".$_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI']); + $waet = $xml_object->waet[0]; + $testName = urldecode($waet["url"]); + if(array_key_exists($testName,$data)) { + // Key exists + array_push($data[$testName],$filename); + } else { + // Key does not exist + $data[$testName] = [$filename]; + } + } + } +} + +// Now read the format response +$format = "JSON"; +if (array_key_exists("format",$_GET)) { + $format = $_GET["format"]; +} +switch($format) { + case "JSON": + // Return JSON + $doc_root = '{"tests": ['; + $keys = array_keys($data); + $numTests = count($data); + for ($testIndex = 0; $testIndex < $numTests; $testIndex++) { + $test_root = '{"testName": "'.$keys[$testIndex].'", "files": ['; + $numFiles = count($data[$keys[$testIndex]]); + for ($countIndex=0; $countIndex < $numFiles; $countIndex++) { + $test_root = $test_root.'"'.$data[$keys[$testIndex]][$countIndex].'"'; + if ($countIndex == $numFiles-1) { + $test_root = $test_root.']}'; + } else { + $test_root = $test_root.','; + } + } + $doc_root = $doc_root.$test_root; + if ($testIndex == $numTests-1) { + $doc_root = $doc_root.']}'; + } else { + $doc_root = $doc_root.','; + } + } + echo $doc_root; + break; + default: + echo '{"error": "format can only be JSON"}'; +} + +?> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/specification.js Thu Mar 31 13:31:42 2016 +0100 @@ -0,0 +1,639 @@ +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.exitText = "Thank you."; + + this.processAttribute = function(attribute,schema,schemaRoot) + { + // 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 = 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 {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') || attributes[i].getAttribute('ref'); + var projectAttr = setupNode.getAttribute(attributeName); + projectAttr = this.processAttribute(projectAttr,attributes[i],this.schema); + switch(typeof projectAttr) + { + case "number": + case "boolean": + eval('this.'+attributeName+' = '+projectAttr); + break; + case "string": + eval('this.'+attributeName+' = "'+projectAttr+'"'); + break; + } + + } + + var exitTextNode = setupNode.getElementsByTagName('exitText'); + if (exitTextNode.length == 1) { + this.exitText = exitTextNode[0].textContent; + } + + 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); + 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); + 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(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.children[0]; + 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<attributes.length; i++) + { + var name = attributes[i].getAttribute("name"); + if (name == undefined) { + name = attributes[i].getAttribute("ref"); + } + if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") + { + eval("setup.setAttribute('"+name+"',this."+name+")"); + } + } + root.appendChild(setup); + // Survey node + if (this.exitText != null) { + var exitTextNode = RootDocument.createElement('exitText'); + exitTextNode.textContent = this.exitText; + setup.appendChild(exitTextNode); + } + setup.appendChild(this.preTest.encode(RootDocument)); + setup.appendChild(this.postTest.encode(RootDocument)); + setup.appendChild(this.metrics.encode(RootDocument)); + setup.appendChild(this.interfaces.encode(RootDocument)); + for (var page of this.pages) + { + root.appendChild(page.encode(RootDocument)); + } + return RootDocument; + }; + + this.surveyNode = function(specification) { + this.location = null; + this.options = []; + this.parent = null; + this.schema = specification.schema.getAllElementsByName('survey')[0]; + this.specification = specification; + + this.OptionNode = function(specification) { + this.type = undefined; + this.schema = specification.schema.getAllElementsByName('surveyentry')[0]; + this.id = undefined; + this.name = 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],parent.schema); + 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(doc) + { + var node = doc.createElement('surveyentry'); + node.setAttribute('type',this.type); + var statement = doc.createElement('statement'); + statement.textContent = this.statement; + node.appendChild(statement); + node.id = this.id; + if (this.name != undefined) { node.setAttribute("name",this.name);} + if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);} + node.id = this.id; + if (this.name != undefined) {node.setAttribute("name",this.name);} + switch(this.type) + { + case "checkbox": + case "radio": + for (var i=0; i<this.options.length; i++) + { + var option = this.options[i]; + var optionNode = doc.createElement("option"); + optionNode.setAttribute("name",option.name); + optionNode.textContent = option.text; + node.appendChild(optionNode); + } + case "number": + if (this.min != undefined) {node.setAttribute("min", this.min);} + if (this.max != undefined) {node.setAttribute("max", this.max);} + case "question": + if (this.boxsize != undefined) {node.setAttribute("boxsize",this.boxsize);} + if (this.mandatory != undefined) {node.setAttribute("mandatory",this.mandatory);} + default: + break; + } + return node; + }; + }; + this.decode = function(parent,xml) { + this.parent = parent; + 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(this.specification); + node.decode(parent,xml.children[i]); + this.options.push(node); + } + }; + this.encode = function(doc) { + var node = doc.createElement('survey'); + node.setAttribute('location',this.location); + for (var i=0; i<this.options.length; i++) + { + node.appendChild(this.options[i].exportXML(doc)); + } + return node; + }; + }; + + this.interfaceNode = function(specification) + { + 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); + if(parent.processAttribute) { + parent.processAttribute(projectAttr, attributeMap[j], parent.schema) + } else { + parent.parent.processAttribute(projectAttr, attributeMap[j], parent.parent.schema) + } + 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(doc) { + var node = doc.createElement("interface"); + if (typeof name == "string") + node.setAttribute("name",this.name); + for (var option of this.options) + { + var child = doc.createElement("interfaceoption"); + child.setAttribute("type",option.type); + child.setAttribute("name",option.name); + node.appendChild(child); + } + if (this.scales.length != 0) { + var scales = doc.createElement("scales"); + for (var scale of this.scales) + { + var child = doc.createElement("scalelabel"); + child.setAttribute("position",scale.position); + child.textContent = scale.text; + scales.appendChild(child); + } + node.appendChild(scales); + } + return node; + }; + }; + + 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(doc) { + var node = doc.createElement('metric'); + for (var i in this.enabled) + { + if (isNaN(Number(i)) == true){break;} + var child = doc.createElement('metricenable'); + child.textContent = this.enabled[i]; + node.appendChild(child); + } + return node; + } + } + + this.page = function(specification) { + 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.label = 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.specification = specification; + 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 = parent.processAttribute(projectAttr,attributeMap[i],parent.schema); + 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(this.specification); + 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.specification); + 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.specification); + 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(this.specification); + 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(this.specification); + node.decode(parent,commentQuestions[i]); + this.commentQuestions.push(node); + } + }; + + this.encode = function(root) + { + var AHNode = root.createElement("page"); + // First decode the attributes + var attributes = this.schema.getAllElementsByTagName('xs:attribute'); + for (var i=0; i<attributes.length; i++) + { + var name = attributes[i].getAttribute("name"); + if (name == undefined) { + name = attributes[i].getAttribute("ref"); + } + if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") + { + eval("AHNode.setAttribute('"+name+"',this."+name+")"); + } + } + if(this.loudness != null) {AHNode.setAttribute("loudness",this.loudness);} + // <commentboxprefix> + var commentboxprefix = root.createElement("commentboxprefix"); + commentboxprefix.textContent = this.commentBoxPrefix; + AHNode.appendChild(commentboxprefix); + + 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].encode(root)); + } + + AHNode.appendChild(this.preTest.encode(root)); + AHNode.appendChild(this.postTest.encode(root)); + 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.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<optNodes.length; i++) + { + var optNode = optNodes[i]; + this.options.push({ + name: optNode.getAttribute('name'), + text: optNode.textContent + }); + } + }; + + this.encode = function(root) + { + var node = root.createElement("commentquestion"); + node.id = this.id; + node.setAttribute("type",this.type); + if (this.name != undefined){node.setAttribute("name",this.name);} + var statement = root.createElement("statement"); + statement.textContent = this.statement; + node.appendChild(statement); + for (var option of this.options) + { + var child = root.createElement("option"); + child.setAttribute("name",option.name); + child.textContent = option.text; + node.appendChild(child); + } + return node; + }; + }; + + this.audioElementNode = function(specification) { + this.url = null; + this.id = null; + this.name = null; + this.parent = null; + this.type = null; + this.marker = null; + this.enforce = false; + this.gain = 0.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 = parent.parent.processAttribute(projectAttr,attributeMap[i],parent.parent.schema); + 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("audioelement"); + var attributes = this.schema.getAllElementsByTagName('xs:attribute'); + for (var i=0; i<attributes.length; i++) + { + var name = attributes[i].getAttribute("name"); + if (name == undefined) { + name = attributes[i].getAttribute("ref"); + } + if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") + { + eval("AENode.setAttribute('"+name+"',this."+name+")"); + } + } + return AENode; + }; + }; + }; +} \ No newline at end of file
--- a/test_create/test_create.html Tue Mar 29 14:37:07 2016 +0100 +++ b/test_create/test_create.html Thu Mar 31 13:31:42 2016 +0100 @@ -6,650 +6,10 @@ <script type="text/javascript"> window.onbeforeunload = function (e) {var message = 'If you leave the page now, any unsaved changes will be lost', e = e || window.event; if (e) { e.returnValue = message;}return message;}; // 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.exitText = "Thank you."; - - this.processAttribute = function(attribute,schema,schemaRoot) - { - // 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 = 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 {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') || attributes[i].getAttribute('ref'); - var projectAttr = setupNode.getAttribute(attributeName); - projectAttr = this.processAttribute(projectAttr,attributes[i],this.schema); - switch(typeof projectAttr) - { - case "number": - case "boolean": - eval('this.'+attributeName+' = '+projectAttr); - break; - case "string": - eval('this.'+attributeName+' = "'+projectAttr+'"'); - break; - } - - } - - var exitTextNode = setupNode.getElementsByTagName('exitText'); - if (exitTextNode.length == 1) { - this.exitText = exitTextNode[0].textContent; - } - - 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 RootDocument = document.implementation.createDocument(null,"waet"); - var root = RootDocument.children[0]; - 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<attributes.length; i++) - { - var name = attributes[i].getAttribute("name"); - if (name == undefined) { - name = attributes[i].getAttribute("ref"); - } - if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") - { - eval("setup.setAttribute('"+name+"',this."+name+")"); - } - } - root.appendChild(setup); - // Survey node - if (this.exitText != null) { - var exitTextNode = RootDocument.createElement('exitText'); - exitTextNode.textContent = this.exitText; - setup.appendChild(exitTextNode); - } - setup.appendChild(this.preTest.encode(RootDocument)); - setup.appendChild(this.postTest.encode(RootDocument)); - setup.appendChild(this.metrics.encode(RootDocument)); - setup.appendChild(this.interfaces.encode(RootDocument)); - for (var page of this.pages) - { - root.appendChild(page.encode(RootDocument)); - } - return RootDocument; - }; - - this.surveyNode = function() { - this.location = null; - this.options = []; - this.parent = null; - this.schema = specification.schema.getAllElementsByName('survey')[0]; - - this.OptionNode = function() { - this.type = undefined; - this.schema = specification.schema.getAllElementsByName('surveyentry')[0]; - this.id = undefined; - this.name = 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],parent.schema); - 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(doc) - { - var node = doc.createElement('surveyentry'); - node.setAttribute('type',this.type); - var statement = doc.createElement('statement'); - statement.textContent = this.statement; - node.appendChild(statement); - node.id = this.id; - if (this.name != undefined) { node.setAttribute("name",this.name);} - if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);} - node.id = this.id; - if (this.name != undefined) {node.setAttribute("name",this.name);} - switch(this.type) - { - case "checkbox": - case "radio": - for (var i=0; i<this.options.length; i++) - { - var option = this.options[i]; - var optionNode = doc.createElement("option"); - optionNode.setAttribute("name",option.name); - optionNode.textContent = option.text; - node.appendChild(optionNode); - } - case "number": - if (this.min != undefined) {node.setAttribute("min", this.min);} - if (this.max != undefined) {node.setAttribute("max", this.max);} - case "question": - if (this.boxsize != undefined) {node.setAttribute("boxsize",this.boxsize);} - if (this.mandatory != undefined) {node.setAttribute("mandatory",this.mandatory);} - default: - break; - } - return node; - }; - }; - this.decode = function(parent,xml) { - this.parent = parent; - 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(doc) { - var node = doc.createElement('survey'); - node.setAttribute('location',this.location); - for (var i=0; i<this.options.length; i++) - { - node.appendChild(this.options[i].exportXML(doc)); - } - 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); - if(parent.processAttribute) { - parent.processAttribute(projectAttr, attributeMap[j], parent.schema) - } else { - parent.parent.processAttribute(projectAttr, attributeMap[j], parent.parent.schema) - } - 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(doc) { - var node = doc.createElement("interface"); - if (typeof name == "string") - node.setAttribute("name",this.name); - for (var option of this.options) - { - var child = doc.createElement("interfaceoption"); - child.setAttribute("type",option.type); - child.setAttribute("name",option.name); - node.appendChild(child); - } - if (this.scales.length != 0) { - var scales = doc.createElement("scales"); - for (var scale of this.scales) - { - var child = doc.createElement("scalelabel"); - child.setAttribute("position",scale.position); - child.textContent = scale.text; - scales.appendChild(child); - } - node.appendChild(scales); - } - return node; - }; - }; - - 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(doc) { - var node = doc.createElement('metric'); - for (var i in this.enabled) - { - if (isNaN(Number(i)) == true){break;} - var child = doc.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.label = 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.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 = parent.processAttribute(projectAttr,attributeMap[i],parent.schema); - 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("page"); - // First decode the attributes - var attributes = this.schema.getAllElementsByTagName('xs:attribute'); - for (var i=0; i<attributes.length; i++) - { - var name = attributes[i].getAttribute("name"); - if (name == undefined) { - name = attributes[i].getAttribute("ref"); - } - if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") - { - eval("AHNode.setAttribute('"+name+"',this."+name+")"); - } - } - if(this.loudness != null) {AHNode.setAttribute("loudness",this.loudness);} - // <commentboxprefix> - var commentboxprefix = root.createElement("commentboxprefix"); - commentboxprefix.textContent = this.commentBoxPrefix; - AHNode.appendChild(commentboxprefix); - - 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].encode(root)); - } - - AHNode.appendChild(this.preTest.encode(root)); - AHNode.appendChild(this.postTest.encode(root)); - return AHNode; - }; - - this.commentQuestionNode = function() { - 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.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<optNodes.length; i++) - { - var optNode = optNodes[i]; - this.options.push({ - name: optNode.getAttribute('name'), - text: optNode.textContent - }); - } - }; - - this.encode = function(root) - { - var node = root.createElement("commentquestion"); - node.id = this.id; - node.setAttribute("type",this.type); - if (this.name != undefined){node.setAttribute("name",this.name);} - var statement = root.createElement("statement"); - statement.textContent = this.statement; - node.appendChild(statement); - for (var option of this.options) - { - var child = root.createElement("option"); - child.setAttribute("name",option.name); - child.textContent = option.text; - node.appendChild(child); - } - return node; - }; - }; - - this.audioElementNode = function() { - this.url = null; - this.id = null; - this.name = null; - this.parent = null; - this.type = null; - this.marker = null; - this.enforce = false; - this.gain = 0.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 = parent.parent.processAttribute(projectAttr,attributeMap[i],parent.parent.schema); - 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("audioelement"); - var attributes = this.schema.getAllElementsByTagName('xs:attribute'); - for (var i=0; i<attributes.length; i++) - { - var name = attributes[i].getAttribute("name"); - if (name == undefined) { - name = attributes[i].getAttribute("ref"); - } - if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") - { - eval("AENode.setAttribute('"+name+"',this."+name+")"); - } - } - return AENode; - }; - }; - }; - } - </script> <script src="../jquery-2.1.4.js"></script> - <script type="text/javascript" src="test_core.js"/> - <script type="text/javascript"> - - </script> + <script type="text/javascript" src='../specification.js'></script> + <script type="text/javascript" src="test_core.js"></script> </head> <body> <div id="popupHolder"></div>