BrechtDeMan@938: /** BrechtDeMan@938: * ape.js BrechtDeMan@938: * Create the APE interface BrechtDeMan@938: */ BrechtDeMan@938: BrechtDeMan@938: var currentState; // Keep track of the current state (pre/post test, which test, final test? first test?) BrechtDeMan@938: // preTest - In preTest state BrechtDeMan@938: // testRun-ID - In test running, test Id number at the end 'testRun-2' BrechtDeMan@938: // testRunPost-ID - Post test of test ID BrechtDeMan@938: // testRunPre-ID - Pre-test of test ID BrechtDeMan@938: // postTest - End of test, final submission! BrechtDeMan@938: BrechtDeMan@938: BrechtDeMan@938: // Once this is loaded and parsed, begin execution BrechtDeMan@938: loadInterface(projectXML); BrechtDeMan@938: BrechtDeMan@938: function loadInterface(xmlDoc) { BrechtDeMan@938: BrechtDeMan@938: // Get the dimensions of the screen available to the page BrechtDeMan@938: var width = window.innerWidth; BrechtDeMan@938: var height = window.innerHeight; BrechtDeMan@938: BrechtDeMan@938: // The injection point into the HTML page BrechtDeMan@938: var insertPoint = document.getElementById("topLevelBody"); BrechtDeMan@938: var testContent = document.createElement('div'); BrechtDeMan@938: testContent.id = 'testContent'; BrechtDeMan@938: BrechtDeMan@938: BrechtDeMan@938: // Decode parts of the xmlDoc that are needed BrechtDeMan@938: // xmlDoc MUST already be parsed by jQuery! BrechtDeMan@938: var xmlSetup = xmlDoc.find('setup'); BrechtDeMan@938: // Should put in an error function here incase of malprocessed or malformed XML BrechtDeMan@938: BrechtDeMan@938: // Extract the different test XML DOM trees BrechtDeMan@938: var audioHolders = xmlDoc.find('audioHolder'); BrechtDeMan@938: audioHolders.each(function(index,element) { BrechtDeMan@938: var repeatN = element.attributes['repeatCount'].value; BrechtDeMan@938: for (var r=0; r<=repeatN; r++) { BrechtDeMan@938: testXMLSetups[testXMLSetups.length] = element; BrechtDeMan@938: } BrechtDeMan@938: }); BrechtDeMan@938: BrechtDeMan@938: // New check if we need to randomise the test order BrechtDeMan@938: var randomise = xmlSetup[0].attributes['randomiseOrder']; BrechtDeMan@938: if (randomise != undefined) { BrechtDeMan@938: randomise = Boolean(randomise.value); BrechtDeMan@938: } else { BrechtDeMan@938: randomise = false; BrechtDeMan@938: } BrechtDeMan@938: if (randomise) BrechtDeMan@938: { BrechtDeMan@938: testXMLSetups = randomiseOrder(testXMLSetups); BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: // Obtain the metrics enabled BrechtDeMan@938: var metricNode = xmlSetup.find('Metric'); BrechtDeMan@938: var metricNode = metricNode.find('metricEnable'); BrechtDeMan@938: metricNode.each(function(index,node){ BrechtDeMan@938: var enabled = node.textContent; BrechtDeMan@938: switch(enabled) BrechtDeMan@938: { BrechtDeMan@938: case 'testTimer': BrechtDeMan@938: sessionMetrics.prototype.enableTestTimer = true; BrechtDeMan@938: break; BrechtDeMan@938: case 'elementTimer': BrechtDeMan@938: sessionMetrics.prototype.enableElementTimer = true; BrechtDeMan@938: break; BrechtDeMan@938: case 'elementTracker': BrechtDeMan@938: sessionMetrics.prototype.enableElementTracker = true; BrechtDeMan@938: break; BrechtDeMan@938: case 'elementInitalPosition': BrechtDeMan@938: sessionMetrics.prototype.enableElementInitialPosition = true; BrechtDeMan@938: break; BrechtDeMan@938: case 'elementFlagListenedTo': BrechtDeMan@938: sessionMetrics.prototype.enableFlagListenedTo = true; BrechtDeMan@938: break; BrechtDeMan@938: case 'elementFlagMoved': BrechtDeMan@938: sessionMetrics.prototype.enableFlagMoved = true; BrechtDeMan@938: break; BrechtDeMan@938: case 'elementFlagComments': BrechtDeMan@938: sessionMetrics.prototype.enableFlagComments = true; BrechtDeMan@938: break; BrechtDeMan@938: } BrechtDeMan@938: }); BrechtDeMan@938: BrechtDeMan@938: // Create APE specific metric functions BrechtDeMan@938: audioEngineContext.metric.initialiseTest = function() BrechtDeMan@938: { BrechtDeMan@938: var sliders = document.getElementsByClassName('track-slider'); BrechtDeMan@938: for (var i=0; i= 0) BrechtDeMan@938: { BrechtDeMan@938: audioEngineContext.audioObjects[this.lastClicked].metric.listening(time); BrechtDeMan@938: } BrechtDeMan@938: this.lastClicked = id; BrechtDeMan@938: audioEngineContext.audioObjects[id].metric.listening(time); BrechtDeMan@938: } BrechtDeMan@938: }; BrechtDeMan@938: BrechtDeMan@938: // Create the top div for the Title element BrechtDeMan@938: var titleAttr = xmlSetup[0].attributes['title']; BrechtDeMan@938: var title = document.createElement('div'); BrechtDeMan@938: title.className = "title"; BrechtDeMan@938: title.align = "center"; BrechtDeMan@938: var titleSpan = document.createElement('span'); BrechtDeMan@938: BrechtDeMan@938: // Set title to that defined in XML, else set to default BrechtDeMan@938: if (titleAttr != undefined) { BrechtDeMan@938: titleSpan.innerHTML = titleAttr.value; BrechtDeMan@938: } else { BrechtDeMan@938: titleSpan.innerHTML = 'Listening test'; BrechtDeMan@938: } BrechtDeMan@938: // Insert the titleSpan element into the title div element. BrechtDeMan@938: title.appendChild(titleSpan); BrechtDeMan@938: BrechtDeMan@938: var pagetitle = document.createElement('div'); BrechtDeMan@938: pagetitle.className = "pageTitle"; BrechtDeMan@938: pagetitle.align = "center"; BrechtDeMan@938: var titleSpan = document.createElement('span'); BrechtDeMan@938: titleSpan.id = "pageTitle"; BrechtDeMan@938: pagetitle.appendChild(titleSpan); BrechtDeMan@938: BrechtDeMan@938: // Store the return URL path in global projectReturn BrechtDeMan@938: projectReturn = xmlSetup[0].attributes['projectReturn'].value; BrechtDeMan@938: BrechtDeMan@938: // Create Interface buttons! BrechtDeMan@938: var interfaceButtons = document.createElement('div'); BrechtDeMan@938: interfaceButtons.id = 'interface-buttons'; BrechtDeMan@938: BrechtDeMan@938: // MANUAL DOWNLOAD POINT BrechtDeMan@938: // If project return is null, this MUST be specified as the location to create the download link BrechtDeMan@938: var downloadPoint = document.createElement('div'); BrechtDeMan@938: downloadPoint.id = 'download-point'; BrechtDeMan@938: BrechtDeMan@938: // Create playback start/stop points BrechtDeMan@938: var playback = document.createElement("button"); BrechtDeMan@939: playback.innerHTML = 'Stop'; BrechtDeMan@938: playback.id = 'playback-button'; BrechtDeMan@938: // onclick function. Check if it is playing or not, call the correct function in the BrechtDeMan@938: // audioEngine, change the button text to reflect the next state. BrechtDeMan@938: playback.onclick = function() { BrechtDeMan@939: if (audioEngineContext.status == 1) { BrechtDeMan@939: audioEngineContext.stop(); BrechtDeMan@938: this.innerHTML = 'Stop'; BrechtDeMan@938: } BrechtDeMan@938: }; BrechtDeMan@938: // Create Submit (save) button BrechtDeMan@938: var submit = document.createElement("button"); BrechtDeMan@938: submit.innerHTML = 'Submit'; BrechtDeMan@938: submit.onclick = buttonSubmitClick; BrechtDeMan@938: submit.id = 'submit-button'; BrechtDeMan@938: // Append the interface buttons into the interfaceButtons object. BrechtDeMan@938: interfaceButtons.appendChild(playback); BrechtDeMan@938: interfaceButtons.appendChild(submit); BrechtDeMan@938: interfaceButtons.appendChild(downloadPoint); BrechtDeMan@938: BrechtDeMan@938: // Now create the slider and HTML5 canvas boxes BrechtDeMan@938: BrechtDeMan@938: // Create the div box to center align BrechtDeMan@938: var sliderBox = document.createElement('div'); BrechtDeMan@938: sliderBox.className = 'sliderCanvasDiv'; BrechtDeMan@938: sliderBox.id = 'sliderCanvasHolder'; BrechtDeMan@938: sliderBox.align = 'center'; BrechtDeMan@938: BrechtDeMan@938: // Create the slider box to hold the slider elements BrechtDeMan@938: var canvas = document.createElement('div'); BrechtDeMan@938: canvas.id = 'slider'; BrechtDeMan@938: // Must have a known EXACT width, as this is used later to determine the ratings BrechtDeMan@938: canvas.style.width = width - 100 +"px"; BrechtDeMan@938: canvas.align = "left"; BrechtDeMan@938: sliderBox.appendChild(canvas); BrechtDeMan@938: BrechtDeMan@938: // Create the div to hold any scale objects BrechtDeMan@938: var scale = document.createElement('div'); BrechtDeMan@938: scale.className = 'sliderScale'; BrechtDeMan@938: scale.id = 'sliderScaleHolder'; BrechtDeMan@938: scale.align = 'left'; BrechtDeMan@938: sliderBox.appendChild(scale); BrechtDeMan@938: BrechtDeMan@938: // Global parent for the comment boxes on the page BrechtDeMan@938: var feedbackHolder = document.createElement('div'); BrechtDeMan@938: feedbackHolder.id = 'feedbackHolder'; BrechtDeMan@938: BrechtDeMan@938: testContent.style.zIndex = 1; BrechtDeMan@938: insertPoint.innerHTML = null; // Clear the current schema BrechtDeMan@938: BrechtDeMan@938: // Create pre and post test questions BrechtDeMan@938: var blank = document.createElement('div'); BrechtDeMan@938: blank.className = 'testHalt'; BrechtDeMan@938: BrechtDeMan@938: var popupHolder = document.createElement('div'); BrechtDeMan@938: popupHolder.id = 'popupHolder'; BrechtDeMan@938: popupHolder.className = 'popupHolder'; BrechtDeMan@938: popupHolder.style.position = 'absolute'; BrechtDeMan@938: popupHolder.style.left = (window.innerWidth/2)-250 + 'px'; BrechtDeMan@938: popupHolder.style.top = (window.innerHeight/2)-125 + 'px'; BrechtDeMan@938: insertPoint.appendChild(popupHolder); BrechtDeMan@938: insertPoint.appendChild(blank); BrechtDeMan@938: hidePopup(); BrechtDeMan@938: BrechtDeMan@938: var preTest = xmlSetup.find('PreTest'); BrechtDeMan@938: var postTest = xmlSetup.find('PostTest'); BrechtDeMan@938: preTest = preTest[0]; BrechtDeMan@938: postTest = postTest[0]; BrechtDeMan@938: BrechtDeMan@938: currentState = 'preTest'; BrechtDeMan@938: BrechtDeMan@938: // Create Pre-Test Box BrechtDeMan@938: if (preTest != undefined && preTest.children.length >= 1) BrechtDeMan@938: { BrechtDeMan@938: showPopup(); BrechtDeMan@938: preTestPopupStart(preTest); BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: // Inject into HTML BrechtDeMan@938: testContent.appendChild(title); // Insert the title BrechtDeMan@938: testContent.appendChild(pagetitle); BrechtDeMan@938: testContent.appendChild(interfaceButtons); BrechtDeMan@938: testContent.appendChild(sliderBox); BrechtDeMan@938: testContent.appendChild(feedbackHolder); BrechtDeMan@938: insertPoint.appendChild(testContent); BrechtDeMan@938: BrechtDeMan@938: // Load the full interface BrechtDeMan@938: BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function loadTest(id) BrechtDeMan@938: { BrechtDeMan@938: // Used to load a specific test page BrechtDeMan@938: var textXML = testXMLSetups[id]; BrechtDeMan@938: BrechtDeMan@938: var feedbackHolder = document.getElementById('feedbackHolder'); BrechtDeMan@938: var canvas = document.getElementById('slider'); BrechtDeMan@938: feedbackHolder.innerHTML = null; BrechtDeMan@938: canvas.innerHTML = null; BrechtDeMan@938: BrechtDeMan@938: // Setup question title BrechtDeMan@938: var interfaceObj = $(textXML).find('interface'); BrechtDeMan@938: var titleNode = interfaceObj.find('title'); BrechtDeMan@938: if (titleNode[0] != undefined) BrechtDeMan@938: { BrechtDeMan@938: document.getElementById('pageTitle').textContent = titleNode[0].textContent; BrechtDeMan@938: } BrechtDeMan@938: var positionScale = canvas.style.width.substr(0,canvas.style.width.length-2); BrechtDeMan@938: var offset = 50-8; // Half the offset of the slider (window width -100) minus the body padding of 8 BrechtDeMan@938: // TODO: AUTOMATE ABOVE!! BrechtDeMan@938: var scale = document.getElementById('sliderScaleHolder'); BrechtDeMan@938: scale.innerHTML = null; BrechtDeMan@938: interfaceObj.find('scale').each(function(index,scaleObj){ BrechtDeMan@938: var position = Number(scaleObj.attributes['position'].value)*0.01; BrechtDeMan@938: var pixelPosition = (position*positionScale)+offset; BrechtDeMan@938: var scaleDOM = document.createElement('span'); BrechtDeMan@938: scaleDOM.textContent = scaleObj.textContent; BrechtDeMan@938: scale.appendChild(scaleDOM); BrechtDeMan@938: scaleDOM.style.left = Math.floor((pixelPosition-($(scaleDOM).width()/2)))+'px'; BrechtDeMan@938: }); BrechtDeMan@938: BrechtDeMan@938: // Extract the hostURL attribute. If not set, create an empty string. BrechtDeMan@938: var hostURL = textXML.attributes['hostURL']; BrechtDeMan@938: if (hostURL == undefined) { BrechtDeMan@938: hostURL = ""; BrechtDeMan@938: } else { BrechtDeMan@938: hostURL = hostURL.value; BrechtDeMan@938: } BrechtDeMan@938: // Extract the sampleRate. If set, convert the string to a Number. BrechtDeMan@938: var hostFs = textXML.attributes['sampleRate']; BrechtDeMan@938: if (hostFs != undefined) { BrechtDeMan@938: hostFs = Number(hostFs.value); BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: /// CHECK FOR SAMPLE RATE COMPATIBILITY BrechtDeMan@938: if (hostFs != undefined) { BrechtDeMan@938: if (Number(hostFs) != audioContext.sampleRate) { BrechtDeMan@938: var errStr = 'Sample rates do not match! Requested '+Number(hostFs)+', got '+audioContext.sampleRate+'. Please set the sample rate to match before completing this test.'; BrechtDeMan@938: alert(errStr); BrechtDeMan@938: return; BrechtDeMan@938: } BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: var commentShow = textXML.attributes['elementComments']; BrechtDeMan@938: if (commentShow != undefined) { BrechtDeMan@938: if (commentShow.value == 'false') {commentShow = false;} BrechtDeMan@938: else {commentShow = true;} BrechtDeMan@938: } else {commentShow = true;} BrechtDeMan@938: BrechtDeMan@938: var loopPlayback = textXML.attributes['loop']; BrechtDeMan@938: if (loopPlayback != undefined) BrechtDeMan@938: { BrechtDeMan@938: loopPlayback = loopPlayback.value; BrechtDeMan@938: if (loopPlayback == 'true') { BrechtDeMan@938: loopPlayback = true; BrechtDeMan@938: } else { BrechtDeMan@938: loopPlayback = false; BrechtDeMan@938: } BrechtDeMan@938: } else { BrechtDeMan@938: loopPlayback = false; BrechtDeMan@938: } BrechtDeMan@938: audioEngineContext.loopPlayback = loopPlayback; BrechtDeMan@938: BrechtDeMan@938: // Create AudioEngine bindings for playback BrechtDeMan@938: if (loopPlayback) { BrechtDeMan@938: audioEngineContext.play = function() { BrechtDeMan@938: // Send play command to all playback buffers for synchronised start BrechtDeMan@938: // Also start timer callbacks to detect if playback has finished BrechtDeMan@938: if (this.status == 0) { BrechtDeMan@938: this.timer.startTest(); BrechtDeMan@938: // First get current clock BrechtDeMan@938: var timer = audioContext.currentTime; BrechtDeMan@938: // Add 3 seconds BrechtDeMan@938: timer += 3.0; BrechtDeMan@938: // Send play to all tracks BrechtDeMan@938: for (var i=0; i'; BrechtDeMan@938: trackSliderObj.draggable = true; BrechtDeMan@938: trackSliderObj.ondragend = dragEnd; BrechtDeMan@938: trackSliderObj.ondragstart = function() BrechtDeMan@938: { BrechtDeMan@938: var id = Number(this.id.substr(13,2)); // Maximum theoretical tracks is 99! BrechtDeMan@938: audioEngineContext.metric.sliderMoveStart(id); BrechtDeMan@938: }; BrechtDeMan@938: BrechtDeMan@938: // Onclick, switch playback to that track BrechtDeMan@938: trackSliderObj.onclick = function() { BrechtDeMan@938: // Get the track ID from the object ID BrechtDeMan@938: var id = Number(this.id.substr(13,2)); // Maximum theoretical tracks is 99! BrechtDeMan@938: audioEngineContext.metric.sliderPlayed(id); BrechtDeMan@938: audioEngineContext.selectedTrack(id); BrechtDeMan@938: // Currently playing track red, rest green BrechtDeMan@938: document.getElementById('track-slider-'+index).style.backgroundColor = "#FF0000"; BrechtDeMan@938: for (var i = 0; i<$(currentTrackOrder).length; i++) BrechtDeMan@938: { BrechtDeMan@938: if (i!=index) BrechtDeMan@938: { BrechtDeMan@938: document.getElementById('track-slider-'+i).style.backgroundColor = "rgb(100,200,100)"; BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: } BrechtDeMan@939: audioEngineContext.play(); BrechtDeMan@938: }; BrechtDeMan@938: BrechtDeMan@938: canvas.appendChild(trackSliderObj); BrechtDeMan@938: }); BrechtDeMan@938: BrechtDeMan@938: // Append any commentQuestion boxes BrechtDeMan@938: var commentQuestions = $(textXML).find('CommentQuestion'); BrechtDeMan@938: $(commentQuestions).each(function(index,element) { BrechtDeMan@938: // Create document objects to hold the comment boxes BrechtDeMan@938: var trackComment = document.createElement('div'); BrechtDeMan@938: trackComment.className = 'comment-div commentQuestion'; BrechtDeMan@938: trackComment.id = element.attributes['id'].value; BrechtDeMan@938: // Create a string next to each comment asking for a comment BrechtDeMan@938: var trackString = document.createElement('span'); BrechtDeMan@938: trackString.innerHTML = element.textContent; BrechtDeMan@938: // Create the HTML5 comment box 'textarea' BrechtDeMan@938: var trackCommentBox = document.createElement('textarea'); BrechtDeMan@938: trackCommentBox.rows = '4'; BrechtDeMan@938: trackCommentBox.cols = '100'; BrechtDeMan@938: trackCommentBox.name = 'commentQuestion'+index; BrechtDeMan@938: trackCommentBox.className = 'trackComment'; BrechtDeMan@938: var br = document.createElement('br'); BrechtDeMan@938: // Add to the holder. BrechtDeMan@938: trackComment.appendChild(trackString); BrechtDeMan@938: trackComment.appendChild(br); BrechtDeMan@938: trackComment.appendChild(trackCommentBox); BrechtDeMan@938: feedbackHolder.appendChild(trackComment); BrechtDeMan@938: }); BrechtDeMan@938: BrechtDeMan@938: // Now process any pre-test commands BrechtDeMan@938: BrechtDeMan@938: var preTest = $(testXMLSetups[id]).find('PreTest')[0]; BrechtDeMan@938: if (preTest.children.length > 0) BrechtDeMan@938: { BrechtDeMan@938: currentState = 'testRunPre-'+id; BrechtDeMan@938: preTestPopupStart(preTest); BrechtDeMan@938: showPopup(); BrechtDeMan@938: } else { BrechtDeMan@938: currentState = 'testRun-'+id; BrechtDeMan@938: } BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function preTestPopupStart(preTest) BrechtDeMan@938: { BrechtDeMan@938: var popupHolder = document.getElementById('popupHolder'); BrechtDeMan@938: popupHolder.innerHTML = null; BrechtDeMan@938: // Parse the first box BrechtDeMan@938: var preTestOption = document.createElement('div'); BrechtDeMan@938: preTestOption.id = 'preTest'; BrechtDeMan@938: preTestOption.style.marginTop = '25px'; BrechtDeMan@938: preTestOption.align = "center"; BrechtDeMan@938: var child = preTest.children[0]; BrechtDeMan@938: if (child.nodeName == 'statement') BrechtDeMan@938: { BrechtDeMan@938: preTestOption.innerHTML = ''+child.innerHTML+''; BrechtDeMan@938: } else if (child.nodeName == 'question') BrechtDeMan@938: { BrechtDeMan@938: var questionId = child.attributes['id'].value; BrechtDeMan@938: var textHold = document.createElement('span'); BrechtDeMan@938: textHold.innerHTML = child.innerHTML; BrechtDeMan@938: textHold.id = questionId + 'response'; BrechtDeMan@938: var textEnter = document.createElement('textarea'); BrechtDeMan@938: preTestOption.appendChild(textHold); BrechtDeMan@938: preTestOption.appendChild(textEnter); BrechtDeMan@938: } BrechtDeMan@938: var nextButton = document.createElement('button'); BrechtDeMan@938: nextButton.className = 'popupButton'; BrechtDeMan@938: nextButton.value = '0'; BrechtDeMan@938: nextButton.innerHTML = 'Next'; BrechtDeMan@938: nextButton.onclick = popupButtonClick; BrechtDeMan@938: BrechtDeMan@938: popupHolder.appendChild(preTestOption); BrechtDeMan@938: popupHolder.appendChild(nextButton); BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function popupButtonClick() BrechtDeMan@938: { BrechtDeMan@938: // Global call from the 'Next' button click BrechtDeMan@938: if (currentState == 'preTest') BrechtDeMan@938: { BrechtDeMan@938: // At the start of the preTest routine! BrechtDeMan@938: var xmlTree = projectXML.find('setup'); BrechtDeMan@938: var preTest = xmlTree.find('PreTest')[0]; BrechtDeMan@938: this.value = preTestButtonClick(preTest,this.value); BrechtDeMan@938: } else if (currentState.substr(0,10) == 'testRunPre') BrechtDeMan@938: { BrechtDeMan@938: //Specific test pre-test BrechtDeMan@938: var testId = currentState.substr(11,currentState.length-10); BrechtDeMan@938: var preTest = $(testXMLSetups[testId]).find('PreTest')[0]; BrechtDeMan@938: this.value = preTestButtonClick(preTest,this.value); BrechtDeMan@938: } else if (currentState.substr(0,11) == 'testRunPost') BrechtDeMan@938: { BrechtDeMan@938: // Specific test post-test BrechtDeMan@938: var testId = currentState.substr(12,currentState.length-11); BrechtDeMan@938: var preTest = $(testXMLSetups[testId]).find('PostTest')[0]; BrechtDeMan@938: this.value = preTestButtonClick(preTest,this.value); BrechtDeMan@938: } else if (currentState == 'postTest') BrechtDeMan@938: { BrechtDeMan@938: // At the end of the test, running global post test BrechtDeMan@938: var xmlTree = projectXML.find('setup'); BrechtDeMan@938: var PostTest = xmlTree.find('PostTest')[0]; BrechtDeMan@938: this.value = preTestButtonClick(PostTest,this.value); BrechtDeMan@938: } BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function preTestButtonClick(preTest,index) BrechtDeMan@938: { BrechtDeMan@938: // Called on click of pre-test button BrechtDeMan@938: // Need to find and parse preTest again! BrechtDeMan@938: var preTestOption = document.getElementById('preTest'); BrechtDeMan@938: // Check if current state is a question! BrechtDeMan@938: if (preTest.children[index].nodeName == 'question') { BrechtDeMan@938: var questionId = preTest.children[index].attributes['id'].value; BrechtDeMan@938: var questionHold = document.createElement('comment'); BrechtDeMan@938: var questionResponse = document.getElementById(questionId + 'response'); BrechtDeMan@938: var mandatory = preTest.children[index].attributes['mandatory']; BrechtDeMan@938: if (mandatory != undefined){ BrechtDeMan@938: if (mandatory.value == 'true') {mandatory = true;} BrechtDeMan@938: else {mandatory = false;} BrechtDeMan@938: } else {mandatory = false;} BrechtDeMan@938: if (mandatory == true && questionResponse.value.length == 0) { BrechtDeMan@938: return index; BrechtDeMan@938: } BrechtDeMan@938: questionHold.id = questionId; BrechtDeMan@938: questionHold.innerHTML = questionResponse.value; BrechtDeMan@938: postPopupResponse(questionHold); BrechtDeMan@938: } BrechtDeMan@938: index++; BrechtDeMan@938: if (index < preTest.children.length) BrechtDeMan@938: { BrechtDeMan@938: // More to process BrechtDeMan@938: var child = preTest.children[index]; BrechtDeMan@938: if (child.nodeName == 'statement') BrechtDeMan@938: { BrechtDeMan@938: preTestOption.innerHTML = ''+child.innerHTML+''; BrechtDeMan@938: } else if (child.nodeName == 'question') BrechtDeMan@938: { BrechtDeMan@938: var textHold = document.createElement('span'); BrechtDeMan@938: textHold.innerHTML = child.innerHTML; BrechtDeMan@938: var textEnter = document.createElement('textarea'); BrechtDeMan@938: textEnter.id = child.attributes['id'].value + 'response'; BrechtDeMan@938: var br = document.createElement('br'); BrechtDeMan@938: preTestOption.innerHTML = null; BrechtDeMan@938: preTestOption.appendChild(textHold); BrechtDeMan@938: preTestOption.appendChild(br); BrechtDeMan@938: preTestOption.appendChild(textEnter); BrechtDeMan@938: } BrechtDeMan@938: } else { BrechtDeMan@938: // Time to clear BrechtDeMan@938: preTestOption.innerHTML = null; BrechtDeMan@938: if (currentState != 'postTest') { BrechtDeMan@938: hidePopup(); BrechtDeMan@938: // Progress the state! BrechtDeMan@938: advanceState(); BrechtDeMan@938: } else { BrechtDeMan@938: a = createProjectSave(projectReturn); BrechtDeMan@938: preTestOption.appendChild(a); BrechtDeMan@938: } BrechtDeMan@938: } BrechtDeMan@938: return index; BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function postPopupResponse(response) BrechtDeMan@938: { BrechtDeMan@938: if (currentState == 'preTest') { BrechtDeMan@938: preTestQuestions.appendChild(response); BrechtDeMan@938: } else if (currentState == 'postTest') { BrechtDeMan@938: postTestQuestions.appendChild(response); BrechtDeMan@938: } else { BrechtDeMan@938: // Inside a specific test BrechtDeMan@938: if (currentState.substr(0,10) == 'testRunPre') { BrechtDeMan@938: // Pre Test BrechtDeMan@938: var store = $(currentTestHolder).find('preTest'); BrechtDeMan@938: } else { BrechtDeMan@938: // Post Test BrechtDeMan@938: var store = $(currentTestHolder).find('postTest'); BrechtDeMan@938: } BrechtDeMan@938: store[0].appendChild(response); BrechtDeMan@938: } BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function showPopup() BrechtDeMan@938: { BrechtDeMan@938: var popupHolder = document.getElementById('popupHolder'); BrechtDeMan@938: popupHolder.style.zIndex = 3; BrechtDeMan@938: popupHolder.style.visibility = 'visible'; BrechtDeMan@938: var blank = document.getElementsByClassName('testHalt')[0]; BrechtDeMan@938: blank.style.zIndex = 2; BrechtDeMan@938: blank.style.visibility = 'visible'; BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function hidePopup() BrechtDeMan@938: { BrechtDeMan@938: var popupHolder = document.getElementById('popupHolder'); BrechtDeMan@938: popupHolder.style.zIndex = -1; BrechtDeMan@938: popupHolder.style.visibility = 'hidden'; BrechtDeMan@938: var blank = document.getElementsByClassName('testHalt')[0]; BrechtDeMan@938: blank.style.zIndex = -2; BrechtDeMan@938: blank.style.visibility = 'hidden'; BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function dragEnd(ev) { BrechtDeMan@938: // Function call when a div has been dropped BrechtDeMan@938: var slider = document.getElementById('slider'); BrechtDeMan@938: var w = slider.style.width; BrechtDeMan@938: w = Number(w.substr(0,w.length-2)); BrechtDeMan@938: var x = ev.x; BrechtDeMan@938: if (x >= 42 && x < w+42) { BrechtDeMan@938: this.style.left = (x)+'px'; BrechtDeMan@938: } else { BrechtDeMan@938: if (x<42) { BrechtDeMan@938: this.style.left = '42px'; BrechtDeMan@938: } else { BrechtDeMan@938: this.style.left = (w+42) + 'px'; BrechtDeMan@938: } BrechtDeMan@938: } BrechtDeMan@938: audioEngineContext.metric.sliderMoved(); BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function advanceState() BrechtDeMan@938: { BrechtDeMan@938: console.log(currentState); BrechtDeMan@938: if (currentState == 'preTest') BrechtDeMan@938: { BrechtDeMan@938: // End of pre-test, begin the test BrechtDeMan@938: loadTest(0); BrechtDeMan@938: } else if (currentState.substr(0,10) == 'testRunPre') BrechtDeMan@938: { BrechtDeMan@938: // Start the test BrechtDeMan@938: var testId = currentState.substr(11,currentState.length-10); BrechtDeMan@938: currentState = 'testRun-'+testId; BrechtDeMan@938: } else if (currentState.substr(0,11) == 'testRunPost') BrechtDeMan@938: { BrechtDeMan@938: var testId = currentState.substr(12,currentState.length-11); BrechtDeMan@938: testEnded(testId); BrechtDeMan@938: } else if (currentState.substr(0,7) == 'testRun') BrechtDeMan@938: { BrechtDeMan@938: var testId = currentState.substr(8,currentState.length-7); BrechtDeMan@938: // Check if we have any post tests to perform BrechtDeMan@938: var postXML = $(testXMLSetups[testId]).find('PostTest')[0]; BrechtDeMan@938: if (postXML == undefined) { BrechtDeMan@938: testEnded(testId); BrechtDeMan@938: } BrechtDeMan@938: else if (postXML.children.length > 0) BrechtDeMan@938: { BrechtDeMan@938: currentState = 'testRunPost-'+testId; BrechtDeMan@938: showPopup(); BrechtDeMan@938: preTestPopupStart(postXML); BrechtDeMan@938: } BrechtDeMan@938: else { BrechtDeMan@938: BrechtDeMan@938: BrechtDeMan@938: // No post tests, check if we have another test to perform instead BrechtDeMan@938: BrechtDeMan@938: } BrechtDeMan@938: } BrechtDeMan@938: console.log(currentState); BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function testEnded(testId) BrechtDeMan@938: { BrechtDeMan@938: pageXMLSave(testId); BrechtDeMan@938: if (testXMLSetups.length-1 > testId) BrechtDeMan@938: { BrechtDeMan@938: // Yes we have another test to perform BrechtDeMan@938: testId = (Number(testId)+1); BrechtDeMan@938: currentState = 'testRun-'+testId; BrechtDeMan@938: loadTest(testId); BrechtDeMan@938: } else { BrechtDeMan@938: console.log('Testing Completed!'); BrechtDeMan@938: currentState = 'postTest'; BrechtDeMan@938: // Check for any post tests BrechtDeMan@938: var xmlSetup = projectXML.find('setup'); BrechtDeMan@938: var postTest = xmlSetup.find('PostTest')[0]; BrechtDeMan@938: showPopup(); BrechtDeMan@938: preTestPopupStart(postTest); BrechtDeMan@938: } BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@939: function buttonSubmitClick() // TODO: Only when all songs have been played! BrechtDeMan@938: { BrechtDeMan@938: if (audioEngineContext.status == 1) { BrechtDeMan@938: var playback = document.getElementById('playback-button'); BrechtDeMan@938: playback.click(); BrechtDeMan@938: // This function is called when the submit button is clicked. Will check for any further tests to perform, or any post-test options BrechtDeMan@938: } else BrechtDeMan@938: { BrechtDeMan@938: if (audioEngineContext.timer.testStarted == false) BrechtDeMan@938: { BrechtDeMan@938: alert('You have not started the test! Please press start to begin the test!'); BrechtDeMan@938: return; BrechtDeMan@938: } BrechtDeMan@938: } BrechtDeMan@938: if (currentState.substr(0,7) == 'testRun') BrechtDeMan@938: { BrechtDeMan@938: audioEngineContext.timer.stopTest(); BrechtDeMan@938: advanceState(); BrechtDeMan@938: } BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function convSliderPosToRate(id) BrechtDeMan@938: { BrechtDeMan@938: var w = document.getElementById('slider').style.width; BrechtDeMan@938: var maxPix = w.substr(0,w.length-2); BrechtDeMan@938: var slider = document.getElementsByClassName('track-slider')[id]; BrechtDeMan@938: var pix = slider.style.left; BrechtDeMan@938: pix = pix.substr(0,pix.length-2); BrechtDeMan@938: var rate = (pix-42)/maxPix; BrechtDeMan@938: return rate; BrechtDeMan@938: } BrechtDeMan@938: BrechtDeMan@938: function pageXMLSave(testId) BrechtDeMan@938: { BrechtDeMan@938: // Saves a specific test page BrechtDeMan@938: var xmlDoc = currentTestHolder; BrechtDeMan@938: // Check if any session wide metrics are enabled BrechtDeMan@938: BrechtDeMan@938: var commentShow = testXMLSetups[testId].attributes['elementComments']; BrechtDeMan@938: if (commentShow != undefined) { BrechtDeMan@938: if (commentShow.value == 'false') {commentShow = false;} BrechtDeMan@938: else {commentShow = true;} BrechtDeMan@938: } else {commentShow = true;} BrechtDeMan@938: BrechtDeMan@938: var metric = document.createElement('metric'); BrechtDeMan@938: if (audioEngineContext.metric.enableTestTimer) BrechtDeMan@938: { BrechtDeMan@938: var testTime = document.createElement('metricResult'); BrechtDeMan@938: testTime.id = 'testTime'; BrechtDeMan@938: testTime.textContent = audioEngineContext.timer.testDuration; BrechtDeMan@938: metric.appendChild(testTime); BrechtDeMan@938: } BrechtDeMan@938: xmlDoc.appendChild(metric); BrechtDeMan@938: var trackSliderObjects = document.getElementsByClassName('track-slider'); BrechtDeMan@938: var commentObjects = document.getElementsByClassName('comment-div'); BrechtDeMan@938: for (var i=0; i