Mercurial > hg > webaudioevaluationtool
changeset 1581:284251e3a6a3
Everything tied into Specification object which needs information from specification document.
author | Nicholas Jillings <nickjillings@users.noreply.github.com> |
---|---|
date | Thu, 04 Jun 2015 15:54:56 +0100 |
parents | b6c808cac38c |
children | d4b626a4bc76 |
files | ape.js core.js |
diffstat | 2 files changed, 79 insertions(+), 175 deletions(-) [+] |
line wrap: on
line diff
--- a/ape.js Thu Jun 04 14:31:23 2015 +0100 +++ b/ape.js Thu Jun 04 15:54:56 2015 +0100 @@ -11,9 +11,9 @@ // Once this is loaded and parsed, begin execution -loadInterface(projectXML); +loadInterface(); -function loadInterface(xmlDoc) { +function loadInterface() { // Get the dimensions of the screen available to the page var width = window.innerWidth; @@ -24,12 +24,6 @@ var testContent = document.createElement('div'); testContent.id = 'testContent'; - - - // Decode parts of the xmlDoc that are needed - // xmlDoc MUST already be parsed by jQuery! - var xmlSetup = xmlDoc.find('setup'); - // Should put in an error function here incase of malprocessed or malformed XML // Create APE specific metric functions @@ -78,7 +72,7 @@ // Bindings for audioObjects // Create the top div for the Title element - var titleAttr = xmlSetup[0].attributes['title']; + var titleAttr = specification.title; var title = document.createElement('div'); title.className = "title"; title.align = "center"; @@ -86,9 +80,9 @@ // Set title to that defined in XML, else set to default if (titleAttr != undefined) { - titleSpan.innerHTML = titleAttr.value; + titleSpan.textContent = titleAttr; } else { - titleSpan.innerHTML = 'Listening test'; + titleSpan.textContent = 'Listening test'; } // Insert the titleSpan element into the title div element. title.appendChild(titleSpan); @@ -100,24 +94,10 @@ titleSpan.id = "pageTitle"; pagetitle.appendChild(titleSpan); - // Store the return URL path in global projectReturn - projectReturn = xmlSetup[0].attributes['projectReturn']; - if (projectReturn == undefined) { - console.log("WARNING - projectReturn not specified! Will assume null."); - projectReturn = "null"; - } else { - projectReturn = projectReturn.value; - } - // Create Interface buttons! var interfaceButtons = document.createElement('div'); interfaceButtons.id = 'interface-buttons'; - // MANUAL DOWNLOAD POINT - // If project return is null, this MUST be specified as the location to create the download link - var downloadPoint = document.createElement('div'); - downloadPoint.id = 'download-point'; - // Create playback start/stop points var playback = document.createElement("button"); playback.innerHTML = 'Stop'; @@ -140,7 +120,6 @@ // Append the interface buttons into the interfaceButtons object. interfaceButtons.appendChild(playback); interfaceButtons.appendChild(submit); - interfaceButtons.appendChild(downloadPoint); // Now create the slider and HTML5 canvas boxes @@ -194,13 +173,13 @@ } -function loadTest(textXML) +function loadTest(audioHolderObject) { // Reset audioEngineContext.Metric globals for new test audioEngineContext.newTestPage(); - var id = textXML.id; + var id = audioHolderObject.id; var feedbackHolder = document.getElementById('feedbackHolder'); var canvas = document.getElementById('slider'); @@ -208,7 +187,7 @@ canvas.innerHTML = null; // Setup question title - var interfaceObj = $(textXML).find('interface'); + var interfaceObj = $(audioHolderObject).find('interface'); var titleNode = interfaceObj.find('title'); if (titleNode[0] != undefined) { @@ -237,46 +216,19 @@ commentBoxPrefix = "Comment on track"; } - // Extract the hostURL attribute. If not set, create an empty string. - var hostURL = textXML.attributes['hostURL']; - if (hostURL == undefined) { - hostURL = ""; - } else { - hostURL = hostURL.value; - } - // Extract the sampleRate. If set, convert the string to a Number. - var hostFs = textXML.attributes['sampleRate']; - if (hostFs != undefined) { - hostFs = Number(hostFs.value); - } - /// CHECK FOR SAMPLE RATE COMPATIBILITY - if (hostFs != undefined) { - if (Number(hostFs) != audioContext.sampleRate) { + if (audioHolderObject.sampleRate != undefined) { + if (Number(audioHolderObject.sampleRate) != audioContext.sampleRate) { var errStr = 'Sample rates do not match! Requested '+Number(hostFs)+', got '+audioContext.sampleRate+'. Please set the sample rate to match before completing this test.'; alert(errStr); return; } } - var commentShow = textXML.attributes['elementComments']; - if (commentShow != undefined) { - if (commentShow.value == 'false') {commentShow = false;} - else {commentShow = true;} - } else {commentShow = true;} + var commentShow = audioHolderObject.elementComments; - var loopPlayback = textXML.attributes['loop']; - if (loopPlayback != undefined) - { - loopPlayback = loopPlayback.value; - if (loopPlayback == 'true') { - loopPlayback = true; - } else { - loopPlayback = false; - } - } else { - loopPlayback = false; - } + var loopPlayback = audioHolderObject.loop; + audioEngineContext.loopPlayback = loopPlayback; // Create AudioEngine bindings for playback if (loopPlayback) { @@ -305,36 +257,28 @@ } currentTestHolder = document.createElement('audioHolder'); - currentTestHolder.id = textXML.id; - currentTestHolder.repeatCount = textXML.attributes['repeatCount'].value; + currentTestHolder.id = audioHolderObject.id; + currentTestHolder.repeatCount = audioHolderObject.repeatCount; - var randomise = textXML.attributes['randomiseOrder']; - if (randomise != undefined) {randomise = randomise.value;} - else {randomise = false;} + var randomise = audioHolderObject.randomiseOrder; - var audioElements = $(textXML).find('audioElements'); + var audioElements = audioHolderObject.audioElements; currentTrackOrder = []; - audioElements.each(function(index,element){ - // Find any blind-repeats - // Not implemented yet, but just in case - currentTrackOrder[index] = element; - }); if (randomise) { - currentTrackOrder = randomiseOrder(currentTrackOrder); + audioHolderObject.audioElements = randomiseOrder(audioHolderObject.audioElements); } // Delete any previous audioObjects associated with the audioEngine audioEngineContext.audioObjects = []; // Find all the audioElements from the audioHolder - $(currentTrackOrder).each(function(index,element){ + $(audioHolderObject.audioElements).each(function(index,element){ // Find URL of track // In this jQuery loop, variable 'this' holds the current audioElement. // Now load each audio sample. First create the new track by passing the full URL - var trackURL = hostURL + this.attributes['url'].value; + var trackURL = audioHolderObject.hostURL + element.url; var audioObject = audioEngineContext.newTrack(trackURL); - audioObject.id = this.attributes['id'].value; if (commentShow) { // Create document objects to hold the comment boxes @@ -412,15 +356,14 @@ }); // Append any commentQuestion boxes - var commentQuestions = $(textXML).find('CommentQuestion'); - $(commentQuestions).each(function(index,element) { + $(audioHolderObject.commentQuestions).each(function(index,element) { // Create document objects to hold the comment boxes var trackComment = document.createElement('div'); trackComment.className = 'comment-div commentQuestion'; - trackComment.id = element.attributes['id'].value; + trackComment.id = element.id; // Create a string next to each comment asking for a comment var trackString = document.createElement('span'); - trackString.innerHTML = element.textContent; + trackString.innerHTML = element.question; // Create the HTML5 comment box 'textarea' var trackCommentBox = document.createElement('textarea'); trackCommentBox.rows = '4'; @@ -541,17 +484,13 @@ }); } -function pageXMLSave(store, testXML, testId) +function pageXMLSave(store, testXML) { // Saves a specific test page var xmlDoc = store; // Check if any session wide metrics are enabled - var commentShow = testXML.attributes['elementComments']; - if (commentShow != undefined) { - if (commentShow.value == 'false') {commentShow = false;} - else {commentShow = true;} - } else {commentShow = true;} + var commentShow = testXML.elementComments; var metric = document.createElement('metric'); if (audioEngineContext.metric.enableTestTimer)
--- a/core.js Thu Jun 04 14:31:23 2015 +0100 +++ b/core.js Thu Jun 04 15:54:56 2015 +0100 @@ -8,6 +8,7 @@ /* create the web audio API context and store in audioContext*/ var audioContext; // Hold the browser web audio API var projectXML; // Hold the parsed setup XML +var specification; var popup; // Hold the interfacePopup object var testState; var currentTrackOrder = []; // Hold the current XML tracks in their (randomised) order @@ -35,6 +36,9 @@ // Create the popup interface object popup = new interfacePopup(); + + // Create the specification object + specification = new Specification(); }; function interfacePopup() { @@ -45,6 +49,7 @@ this.popupOptions = null; this.currentIndex = null; this.responses = null; + this.createPopup = function(){ // Create popup window interface var insertPoint = document.getElementById("topLevelBody"); @@ -68,12 +73,16 @@ this.popupButton.className = 'popupButton'; this.popupButton.innerHTML = 'Next'; this.popupButton.onclick = function(){popup.buttonClicked();}; + this.popup.style.zIndex = -1; + this.popup.style.visibility = 'hidden'; + blank.style.zIndex = -2; + blank.style.visibility = 'hidden'; insertPoint.appendChild(this.popup); insertPoint.appendChild(blank); }; this.showPopup = function(){ - if (this.popup == null || this.popup == undefined) { + if (this.popup == null) { this.createPopup(); } this.popup.style.zIndex = 3; @@ -95,13 +104,13 @@ // This will take the node from the popupOptions and display it var node = this.popupOptions[this.currentIndex]; this.popupContent.innerHTML = null; - if (node.nodeName == 'statement') { + if (node.type == 'statement') { var span = document.createElement('span'); - span.textContent = node.textContent; + span.textContent = node.statement; this.popupContent.appendChild(span); - } else if (node.nodeName == 'question') { + } else if (node.type == 'question') { var span = document.createElement('span'); - span.textContent = node.textContent; + span.textContent = node.question; var textArea = document.createElement('textarea'); var br = document.createElement('br'); this.popupContent.appendChild(span); @@ -115,11 +124,11 @@ this.initState = function(node) { //Call this with your preTest and postTest nodes when needed to // initialise the popup procedure. - this.popupOptions = $(node).children(); + this.popupOptions = node.options; if (this.popupOptions.length > 0) { - if (node.nodeName == 'preTest' || node.nodeName == 'PreTest') { + if (node.type == 'pretest') { this.responses = document.createElement('PreTest'); - } else if (node.nodeName == 'postTest' || node.nodeName == 'PostTest') { + } else if (node.type == 'posttest') { this.responses = document.createElement('PostTest'); } else { console.log ('WARNING - popup node neither pre or post!'); @@ -128,29 +137,24 @@ this.currentIndex = 0; this.showPopup(); this.postNode(); + } else { + advanceState(); } }; this.buttonClicked = function() { // Each time the popup button is clicked! var node = this.popupOptions[this.currentIndex]; - if (node.nodeName == 'question') { + if (node.type == 'question') { // Must extract the question data - var mandatory = node.attributes['mandatory']; - if (mandatory == undefined) { - mandatory = false; - } else { - if (mandatory.value == 'true'){mandatory = true;} - else {mandatory = false;} - } var textArea = $(popup.popupContent).find('textarea')[0]; - if (mandatory == true && textArea.value.length == 0) { + if (node.mandatory == true && textArea.value.length == 0) { alert('This question is mandatory'); return; } else { // Save the text content var hold = document.createElement('comment'); - hold.id = node.attributes['id'].value; + hold.id = node.id; hold.innerHTML = textArea.value; console.log("Question: "+ node.textContent); console.log("Question Response: "+ textArea.value); @@ -197,11 +201,8 @@ this.stateIndex = -1; var that = this; for (var id=0; id<this.stateMap.length; id++){ - var name = this.stateMap[id].nodeName; + var name = this.stateMap[id].type; var obj = document.createElement(name); - if (name == "audioHolder") { - obj.id = this.stateMap[id].id; - } this.stateResults.push(obj); } } else { @@ -216,7 +217,7 @@ console.log('Starting test...'); } if (this.currentIndex == null){ - if (this.currentStateMap.nodeName == "audioHolder") { + if (this.currentStateMap.type == "audioHolder") { // Save current page this.testPageCompleted(this.stateResults[this.stateIndex],this.currentStateMap,this.currentTestId); this.currentTestId++; @@ -227,12 +228,12 @@ createProjectSave(projectReturn); } else { this.currentStateMap = this.stateMap[this.stateIndex]; - if (this.currentStateMap.nodeName == "audioHolder") { + if (this.currentStateMap.type == "audioHolder") { console.log('Loading test page'); loadTest(this.currentStateMap); this.initialiseInnerState(this.currentStateMap); - } else if (this.currentStateMap.nodeName == "PreTest" || this.currentStateMap.nodeName == "PostTest") { - if (this.currentStateMap.childElementCount >= 1) { + } else if (this.currentStateMap.type == "pretest" || this.currentStateMap.type == "posttest") { + if (this.currentStateMap.options.length >= 1) { popup.initState(this.currentStateMap); } else { this.advanceState(); @@ -250,18 +251,18 @@ // Function called each time a test page has been completed // Can be used to over-rule default behaviour - pageXMLSave(store, testXML, testId); + pageXMLSave(store, testXML); }; - this.initialiseInnerState = function(testXML) { + this.initialiseInnerState = function(node) { // Parses the received testXML for pre and post test options this.currentStateMap = []; - var preTest = $(testXML).find('PreTest')[0]; - var postTest = $(testXML).find('PostTest')[0]; + var preTest = node.preTest; + var postTest = node.postTest; if (preTest == undefined) {preTest = document.createElement("preTest");} if (postTest == undefined){postTest= document.createElement("postTest");} this.currentStateMap.push(preTest); - this.currentStateMap.push(testXML); + this.currentStateMap.push(node); this.currentStateMap.push(postTest); this.currentIndex = -1; this.advanceInnerState(); @@ -274,11 +275,11 @@ this.currentStateMap = this.stateMap[this.stateIndex]; this.advanceState(); } else { - if (this.currentStateMap[this.currentIndex].nodeName == "audioHolder") { + if (this.currentStateMap[this.currentIndex].type == "audioHolder") { console.log("Loading test page"+this.currentTestId); - } else if (this.currentStateMap[this.currentIndex].nodeName == "PreTest") { + } else if (this.currentStateMap[this.currentIndex].type == "pretest") { popup.initState(this.currentStateMap[this.currentIndex]); - } else if (this.currentStateMap[this.currentIndex].nodeName == "PostTest") { + } else if (this.currentStateMap[this.currentIndex].type == "posttest") { popup.initState(this.currentStateMap[this.currentIndex]); } else { this.advanceInnerState(); @@ -327,61 +328,27 @@ var parse = new DOMParser(); projectXML = parse.parseFromString(response,'text/xml'); - // Now extract the setup tag - var xmlSetup = projectXML.find('setup'); + // Build the specification + specification.decode(); - - // Create pre and post test questions - - var preTest = xmlSetup.find('PreTest'); - var postTest = xmlSetup.find('PostTest'); - preTest = preTest[0]; - postTest = postTest[0]; - - if (preTest == undefined) {preTest = document.createElement("preTest");} - if (postTest == undefined){postTest= document.createElement("postTest");} - - testState.stateMap.push(preTest); - - // Extract the different test XML DOM trees - var audioHolders = projectXML.find('audioHolder'); - var testXMLSetups = []; - audioHolders.each(function(index,element) { - var repeatN = element.attributes['repeatCount'].value; - for (var r=0; r<=repeatN; r++) { - testXMLSetups.push(element); - } - }); + testState.stateMap.push(specification.preTest); // New check if we need to randomise the test order - var randomise = xmlSetup[0].attributes['randomiseOrder']; - if (randomise != undefined) { - if (randomise.value === 'true'){ - randomise = true; - } else { - randomise = false; - } - } else { - randomise = false; + if (specification.randomiseOrder) + { + specification.audioHolders = randomiseOrder(specification.audioHolders); } - if (randomise) - { - testXMLSetups = randomiseOrder(testXMLSetups); - } - - $(testXMLSetups).each(function(index,elem){ + $(specification.audioHolders).each(function(index,elem){ testState.stateMap.push(elem); }); - testState.stateMap.push(postTest); + testState.stateMap.push(specification.postTest); // Obtain the metrics enabled - var metricNode = xmlSetup.find('Metric'); - var metricNode = metricNode.find('metricEnable'); - metricNode.each(function(index,node){ + $(specification.metrics).each(function(index,node){ var enabled = node.textContent; - switch(enabled) + switch(node.enabled) { case 'testTimer': sessionMetrics.prototype.enableTestTimer = true; @@ -413,10 +380,9 @@ // Detect the interface to use and load the relevant javascripts. - var interfaceType = xmlSetup[0].attributes['interface']; var interfaceJS = document.createElement('script'); interfaceJS.setAttribute("type","text/javascript"); - if (interfaceType.value == 'APE') { + if (specification.interfaceType == 'APE') { interfaceJS.setAttribute("src","ape.js"); // APE comes with a css file @@ -450,11 +416,9 @@ a.download = "save.xml"; a.textContent = "Save File"; - var submitDiv = document.getElementById('download-point'); - submitDiv.appendChild(a); popup.showPopup(); popup.popupContent.innerHTML = null; - popup.popupContent.appendChild(submitDiv) + popup.popupContent.appendChild(a) } else { var xmlhttp = new XMLHttpRequest; xmlhttp.open("POST",destURL,true); @@ -1003,13 +967,13 @@ } else {this.setup.collectMetrics = false;} var metricCollection = setupNode.getElementsByTagName('Metric'); - this.preTest = new this.prepostNode('pre',setupNode.getElementsByTagName('PreTest')); - this.postTest = new this.prepostNode('post',setupNode.getElementsByTagName('PostTest')); + this.preTest = new this.prepostNode('pretest',setupNode.getElementsByTagName('PreTest')); + this.postTest = new this.prepostNode('posttest',setupNode.getElementsByTagName('PostTest')); if (metricCollection.length > 0) { metricCollection = metricCollection[0].getElementsByTagName('metricEnable'); for (var i=0; i<metricCollection.length; i++) { - this.metrics.push(new this.metricNode(metricCollection[0].textContent)); + this.metrics.push(new this.metricNode(metricCollection[i].textContent)); } } @@ -1033,7 +997,7 @@ else {this.mandatory = false;} this.question = child.textContent; } else if (child.nodeName == "statement") { - this.statment = child.textContent; + this.statement = child.textContent; } }; @@ -1052,6 +1016,7 @@ }; this.audioHolderNode = function(parent,xml) { + this.type = 'audioHolder'; this.interfaceNode = function(DOM) { var title = DOM.getElementsByTagName('title'); if (title.length == 0) {this.title = null;} @@ -1090,8 +1055,8 @@ if (xml.getAttribute('elementComments') == "true") {this.elementComments = true;} else {this.elementComments = false;} - this.preTest = new parent.prepostNode('pre',xml.getElementsByTagName('PreTest')); - this.postTest = new parent.prepostNode('post',xml.getElementsByTagName('PostTest')); + this.preTest = new parent.prepostNode('pretest',xml.getElementsByTagName('PreTest')); + this.postTest = new parent.prepostNode('posttest',xml.getElementsByTagName('PostTest')); this.interfaces = []; var interfaceDOM = xml.getElementsByTagName('interface');