Mercurial > hg > webaudioevaluationtool
changeset 2682:0a72855de078
Completing #180 up to the singletons
author | Nicholas Jillings <nicholas.jillings@mail.bcu.ac.uk> |
---|---|
date | Wed, 01 Mar 2017 16:30:59 +0000 |
parents | 95f614a82762 |
children | 15104a43089d |
files | js/core.js |
diffstat | 1 files changed, 156 insertions(+), 117 deletions(-) [+] |
line wrap: on
line diff
--- a/js/core.js Wed Mar 01 15:13:01 2017 +0000 +++ b/js/core.js Wed Mar 01 16:30:59 2017 +0000 @@ -5,6 +5,10 @@ * Also contains all global variables. */ +/*globals window, document, XMLDocument, Element, XMLHttpRequest, DOMParser, console, Blob, $, Promise, navigator */ +/*globals AudioBuffer, AudioBufferSourceNode */ +/*globals Specification, calculateLoudness, WAVE, validateXML, showdown, pageXMLSave, loadTest, resizeWindow */ + /* 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 @@ -156,7 +160,7 @@ var search = window.location.search.split('?')[1]; // Now split the requests into pairs var searchQueries = search.split('&'); - + var url; for (var i in searchQueries) { // Split each key-value pair searchQueries[i] = searchQueries[i].split('='); @@ -165,6 +169,7 @@ switch (key) { case "url": url = value; + specification.url = url; break; case "returnURL": gReturnURL = value; @@ -673,7 +678,7 @@ console.log("Survey Element of type 'question' cannot interpret greaterThan/lessThan conditions. IGNORING"); break; case "contains": - if (textArea.value.includes(condition.value)) { + if (value.includes(condition.value)) { return true; } break; @@ -864,7 +869,7 @@ function processRadioConditional(condition, response) { switch (condition.check) { case "equals": - if (node.response === condition.value) { + if (response === condition.value) { return true; } break; @@ -925,19 +930,20 @@ } function processNumberConditional(condtion, value) { + var condition = condition; switch (condition.check) { case "greaterThan": - if (node.response > Number(condition.value)) { + if (value > Number(condition.value)) { return true; } break; case "lessThan": - if (node.response < Number(condition.value)) { + if (value < Number(condition.value)) { return true; } break; case "equals": - if (node.response == condition.value) { + if (value == condition.value) { return true; } break; @@ -1003,17 +1009,17 @@ console.log("Survey Element of type 'number' cannot interpret contains conditions. IGNORING"); break; case "greaterThan": - if (node.response > Number(condition.value)) { + if (value > Number(condition.value)) { return true; } break; case "lessThan": - if (node.response < Number(condition.value)) { + if (value < Number(condition.value)) { return true; } break; case "equals": - if (node.response == condition.value) { + if (value == condition.value) { return true; } break; @@ -1611,7 +1617,7 @@ // Called by an audioObject to register to the buffer for use // First check if already in the register pool this.users.forEach(function (object) { - if (audioObject.id == objects.id) { + if (audioObject.id == object.id) { return 0; } }); @@ -1766,7 +1772,7 @@ // URLs must either be from the same source OR be setup to 'Access-Control-Allow-Origin' // Create the audioObject with ID of the new track length; - audioObjectId = this.audioObjects.length; + var audioObjectId = this.audioObjects.length; this.audioObjects[audioObjectId] = new audioObject(audioObjectId); // Check if audioObject buffer is currently stored by full URL @@ -1810,7 +1816,7 @@ }; this.checkAllPlayed = function () { - arr = []; + var arr = []; for (var id = 0; id < this.audioObjects.length; id++) { if (this.audioObjects[id].metric.wasListenedTo === false) { arr.push(this.audioObjects[id].id); @@ -2039,11 +2045,7 @@ this.storeDOM.appendChild(this.commentDOM.exportXMLDOM(this)); } } - var nodes = this.metric.exportXMLDOM(); - var mroot = this.storeDOM.getElementsByTagName('metric')[0]; - for (var i = 0; i < nodes.length; i++) { - mroot.appendChild(nodes[i]); - } + this.metric.exportXMLDOM(this.storeDOM.getElementsByTagName('metric')[0]); }; } @@ -2202,64 +2204,90 @@ } }; - this.exportXMLDOM = function () { - var storeDOM = []; + function exportElementTimer(parentElement) { + var mElementTimer = storage.document.createElement('metricresult'); + mElementTimer.setAttribute('name', 'enableElementTimer'); + mElementTimer.textContent = this.listenedTimer; + parentElement.appendChild(mElementTimer); + } + + function exportElementTrack(parentElement) { + var elementTrackerFull = storage.document.createElement('metricresult'); + elementTrackerFull.setAttribute('name', 'elementTrackerFull'); + for (var k = 0; k < this.movementTracker.length; k++) { + var timePos = storage.document.createElement('movement'); + timePos.setAttribute("time", this.movementTracker[k][0]); + timePos.setAttribute("value", this.movementTracker[k][1]); + elementTrackerFull.appendChild(timePos); + } + parentElement.appendChild(elementTrackerFull); + } + + function exportElementListenTracker(parentElement) { + var elementListenTracker = storage.document.createElement('metricresult'); + elementListenTracker.setAttribute('name', 'elementListenTracker'); + for (var k = 0; k < this.listenTracker.length; k++) { + elementListenTracker.appendChild(this.listenTracker[k]); + } + parentElement.appendChild(elementListenTracker); + } + + function exportElementInitialPosition(parentElement) { + var elementInitial = storage.document.createElement('metricresult'); + elementInitial.setAttribute('name', 'elementInitialPosition'); + elementInitial.textContent = this.initialPosition; + parentElement.appendChild(elementInitial); + } + + function exportFlagListenedTo(parentElement) { + var flagListenedTo = storage.document.createElement('metricresult'); + flagListenedTo.setAttribute('name', 'elementFlagListenedTo'); + flagListenedTo.textContent = this.wasListenedTo; + parentElement.appendChild(flagListenedTo); + } + + function exportFlagMoved(parentElement) { + var flagMoved = storage.document.createElement('metricresult'); + flagMoved.setAttribute('name', 'elementFlagMoved'); + flagMoved.textContent = this.wasMoved; + parentElement.appendChild(flagMoved); + } + + function exportFlagComments(parentElement) { + var flagComments = storage.document.createElement('metricresult'); + flagComments.setAttribute('name', 'elementFlagComments'); + if (this.parent.commentDOM === null) { + flagComments.textContent = 'false'; + } else if (this.parent.commentDOM.textContent.length === 0) { + flagComments.textContent = 'false'; + } else { + flagComments.textContet = 'true'; + } + parentElement.appendChild(flagComments); + } + + this.exportXMLDOM = function (parentElement) { if (audioEngineContext.metric.enableElementTimer) { - var mElementTimer = storage.document.createElement('metricresult'); - mElementTimer.setAttribute('name', 'enableElementTimer'); - mElementTimer.textContent = this.listenedTimer; - storeDOM.push(mElementTimer); + exportElementTimer.call(this, parentElement); } if (audioEngineContext.metric.enableElementTracker) { - var elementTrackerFull = storage.document.createElement('metricresult'); - elementTrackerFull.setAttribute('name', 'elementTrackerFull'); - for (var k = 0; k < this.movementTracker.length; k++) { - var timePos = storage.document.createElement('movement'); - timePos.setAttribute("time", this.movementTracker[k][0]); - timePos.setAttribute("value", this.movementTracker[k][1]); - elementTrackerFull.appendChild(timePos); - } - storeDOM.push(elementTrackerFull); + exportElementTrack.call(this, parentElement); } if (audioEngineContext.metric.enableElementListenTracker) { - var elementListenTracker = storage.document.createElement('metricresult'); - elementListenTracker.setAttribute('name', 'elementListenTracker'); - for (var k = 0; k < this.listenTracker.length; k++) { - elementListenTracker.appendChild(this.listenTracker[k]); - } - storeDOM.push(elementListenTracker); + exportElementListenTracker.call(this, parentElement); } if (audioEngineContext.metric.enableElementInitialPosition) { - var elementInitial = storage.document.createElement('metricresult'); - elementInitial.setAttribute('name', 'elementInitialPosition'); - elementInitial.textContent = this.initialPosition; - storeDOM.push(elementInitial); + exportElementInitialPosition.call(this, parentElement); } if (audioEngineContext.metric.enableFlagListenedTo) { - var flagListenedTo = storage.document.createElement('metricresult'); - flagListenedTo.setAttribute('name', 'elementFlagListenedTo'); - flagListenedTo.textContent = this.wasListenedTo; - storeDOM.push(flagListenedTo); + exportFlagListenedTo.call(this, parentElement); } if (audioEngineContext.metric.enableFlagMoved) { - var flagMoved = storage.document.createElement('metricresult'); - flagMoved.setAttribute('name', 'elementFlagMoved'); - flagMoved.textContent = this.wasMoved; - storeDOM.push(flagMoved); + exportFlagMoved.call(this, parentElement); } if (audioEngineContext.metric.enableFlagComments) { - var flagComments = storage.document.createElement('metricresult'); - flagComments.setAttribute('name', 'elementFlagComments'); - if (this.parent.commentDOM === null) { - flag.textContent = 'false'; - } else if (this.parent.commentDOM.textContent.length === 0) { - flag.textContent = 'false'; - } else { - flag.textContet = 'true'; - } - storeDOM.push(flagComments); + exportFlagComments.call(this, parentElement); } - return storeDOM; }; } @@ -2285,12 +2313,12 @@ popup.resize(event); this.volume.resize(); this.lightbox.resize(); - for (var i = 0; i < this.commentBoxes.length; i++) { - this.commentBoxes[i].resize(); - } - for (var i = 0; i < this.commentQuestions.length; i++) { - this.commentQuestions[i].resize(); - } + this.commentBoxes.forEach(function (elem) { + elem.resize(); + }); + this.commentQuestions.forEach(function (elem) { + elem.resize(); + }); try { resizeWindow(event); } catch (err) { @@ -2464,16 +2492,16 @@ if (sort) { this.sortCommentBoxes(); } - for (var box of this.boxes) { + this.boxes.forEach(function (box) { inject.appendChild(box.trackComment); - } + }); }; this.deleteCommentBoxes = function () { if (this.injectPoint !== null) { - for (var box of this.boxes) { + this.boxes.forEach(function (box) { this.injectPoint.removeChild(box.trackComment); - } + }, this); this.injectPoint = null; } this.boxes = []; @@ -2553,7 +2581,7 @@ this.span.className = "comment-radio-span-holder"; var optCount = commentQuestion.options.length; - for (var optNode of commentQuestion.options) { + commentQuestion.options.forEach(function (optNode) { var div = document.createElement('div'); div.style.width = '80px'; div.style.float = 'left'; @@ -2576,7 +2604,7 @@ div.appendChild(span); this.span.appendChild(div); this.options.push(input); - } + }, this); this.holder.appendChild(this.span); this.holder.appendChild(this.inputs); @@ -2619,8 +2647,8 @@ var options = this.holder.getElementsByClassName("comment-radio-inputs-holder")[0]; var optCount = options.childElementCount; var spanMargin = Math.floor(((boxwidth - 20 - (optCount * 80)) / (optCount)) / 2) + 'px'; - var options = options.firstChild; - var text = text.firstChild; + options = options.firstChild; + text = text.firstChild; options.style.marginRight = spanMargin; options.style.marginLeft = spanMargin; text.style.marginRight = spanMargin; @@ -2718,8 +2746,8 @@ var options = this.holder.getElementsByClassName("comment-checkbox-inputs-holder")[0]; var optCount = options.childElementCount; var spanMargin = Math.floor(((boxwidth - 20 - (optCount * 80)) / (optCount)) / 2) + 'px'; - var options = options.firstChild; - var text = text.firstChild; + options = options.firstChild; + text = text.firstChild; options.style.marginRight = spanMargin; options.style.marginLeft = spanMargin; text.style.marginRight = spanMargin; @@ -2888,7 +2916,7 @@ this.timePerPixel = 0; this.maxTime = 0; - this.playbackObject; + this.playbackObject = undefined; this.setTimePerPixel = function (audioObject) { //maxTime must be in seconds @@ -2938,18 +2966,18 @@ this.start = function () { if (this.playbackObject !== undefined && this.interval === undefined) { if (this.maxTime < 60) { - this.interval = setInterval(function () { + this.interval = window.setInterval(function () { interfaceContext.playhead.update(); }, 10); } else { - this.interval = setInterval(function () { + this.interval = window.setInterval(function () { interfaceContext.playhead.update(); }, 100); } } }; this.stop = function () { - clearInterval(this.interval); + window.clearInterval(this.interval); this.interval = undefined; this.scrubberHead.style.left = '0px'; if (this.maxTime < 60) { @@ -3099,14 +3127,14 @@ inject.appendChild(this.holder); }; this.collect = function () { - for (var obj of this.calibrationNodes) { + this.calibrationNodes.forEach(function (obj) { var node = storage.document.createElement("calibrationresult"); node.setAttribute("frequency", obj.f); node.setAttribute("range-min", obj.input.min); node.setAttribute("range-max", obj.input.max); node.setAttribute("gain-lin", obj.gain.gain.value); this.storeDOM.appendChild(node); - } + }, this); }; }; @@ -3114,8 +3142,8 @@ // Global Checkers // These functions will help enforce the checkers this.checkHiddenAnchor = function () { - for (var ao of audioEngineContext.audioObjects) { - if (ao.specification.type == "anchor") { + audioEngineContext.audioObjects.forEach(function (ao) { + if (ao.specification.type === "anchor") { if (ao.interfaceDOM.getValue() > (ao.specification.marker / 100) && ao.specification.marker > 0) { // Anchor is not set below console.log('Anchor node not below marker value'); @@ -3124,12 +3152,12 @@ return false; } } - } + }, this); return true; }; this.checkHiddenReference = function () { - for (var ao of audioEngineContext.audioObjects) { + audioEngineContext.audioObjects.forEach(function (ao) { if (ao.specification.type == "reference") { if (ao.interfaceDOM.getValue() < (ao.specification.marker / 100) && ao.specification.marker > 0) { // Anchor is not set below @@ -3139,7 +3167,7 @@ return false; } } - } + }, this); return true; }; @@ -3151,8 +3179,9 @@ return true; } var check_pass = true; - var error_obj = []; - for (var i = 0; i < audioEngineContext.audioObjects.length; i++) { + var error_obj = [], + i; + for (i = 0; i < audioEngineContext.audioObjects.length; i++) { var object = audioEngineContext.audioObjects[i]; var time = object.buffer.buffer.duration; var metric = object.metric; @@ -3175,7 +3204,7 @@ } if (check_pass === false) { var str_start = "You have not completely listened to fragments "; - for (var i = 0; i < error_obj.length; i++) { + for (i = 0; i < error_obj.length; i++) { str_start += error_obj[i]; if (i != error_obj.length - 1) { str_start += ', '; @@ -3192,11 +3221,11 @@ this.checkAllMoved = function () { var str = "You have not moved "; var failed = []; - for (var ao of audioEngineContext.audioObjects) { + audioEngineContext.audioObjects.forEach(function (ao) { if (ao.metric.wasMoved === false && ao.interfaceDOM.canMove() === true) { failed.push(ao.interfaceDOM.getPresentedId()); } - } + }, this); if (failed.length === 0) { return true; } else if (failed.length == 1) { @@ -3217,11 +3246,11 @@ this.checkAllPlayed = function () { var str = "You have not played "; var failed = []; - for (var ao of audioEngineContext.audioObjects) { + audioEngineContext.audioObjects.forEach(function (ao) { if (ao.metric.wasListenedTo === false) { failed.push(ao.interfaceDOM.getPresentedId()); } - } + }, this); if (failed.length === 0) { return true; } else if (failed.length == 1) { @@ -3262,7 +3291,7 @@ var str = "Please keep listening. "; var minRanking = Infinity; var maxRanking = -Infinity; - for (var ao of audioObjects) { + audioEngineContext.audioObjects.forEach(function (ao) { var rank = ao.interfaceDOM.getValue(); if (rank < minRanking) { minRanking = rank; @@ -3270,7 +3299,7 @@ if (rank > maxRanking) { maxRanking = rank; } - } + }, this); if (minRanking * 100 > min) { str += "At least one fragment must be below the " + min + " mark."; state = false; @@ -3348,7 +3377,6 @@ labelStart = 1; } break; - case "none": default: labelStart = 0; } @@ -3409,8 +3437,8 @@ this.document = document.implementation.createDocument(null, "waetresult", null); this.root = this.document.childNodes[0]; var projectDocument = specification.projectXML; - projectDocument.setAttribute('file-name', url); - projectDocument.setAttribute('url', qualifyURL(url)); + projectDocument.setAttribute('file-name', specification.url); + projectDocument.setAttribute('url', qualifyURL(specification.url)); this.root.appendChild(projectDocument); this.root.appendChild(interfaceContext.returnDateNode()); this.root.appendChild(interfaceContext.returnNavigator()); @@ -3520,17 +3548,38 @@ this.XMLDOM = this.parent.document.createElement('survey'); this.XMLDOM.setAttribute('location', this.specification.location); this.XMLDOM.setAttribute("state", this.state); - for (var optNode of this.specification.options) { + this.specification.options.forEach(function (optNode) { if (optNode.type != 'statement') { var node = this.parent.document.createElement('surveyresult'); node.setAttribute("ref", optNode.id); node.setAttribute('type', optNode.type); this.XMLDOM.appendChild(node); } - } + }, this); root.appendChild(this.XMLDOM); this.postResult = function (node) { + function postNumber(doc, value) { + var child = doc.createElement("response"); + child.textContent = value; + return child; + } + + function postRadio(doc, node) { + var child = doc.createElement('response'); + if (node.response !== null) { + child.setAttribute('name', node.response.name); + child.textContent = node.response.text; + } + return child; + } + + function postCheckbox(doc, node) { + var checkNode = doc.createElement('response'); + checkNode.setAttribute('name', node.name); + checkNode.setAttribute('checked', node.checked); + return checkNode; + } // From popup: node is the popupOption node containing both spec. and results // ID is the position if (node.specification.type == 'statement') { @@ -3547,17 +3596,10 @@ case "number": case "question": case "slider": - var child = this.parent.document.createElement('response'); - child.textContent = node.response; - surveyresult.appendChild(child); + surveyresult.appendChild(postNumber(this.parent.document, node.response)); break; case "radio": - var child = this.parent.document.createElement('response'); - if (node.response !== null) { - child.setAttribute('name', node.response.name); - child.textContent = node.response.text; - } - surveyresult.appendChild(child); + surveyresult.appendChild(postRadio(this.parent.document, node)); break; case "checkbox": if (node.response === undefined) { @@ -3565,10 +3607,7 @@ break; } for (var i = 0; i < node.response.length; i++) { - var checkNode = this.parent.document.createElement('response'); - checkNode.setAttribute('name', node.response[i].name); - checkNode.setAttribute('checked', node.response[i].checked); - surveyresult.appendChild(checkNode); + surveyresult.appendChild(postCheckbox(this.parent.document, node.response[i])); } break; } @@ -3600,7 +3639,7 @@ this.XMLDOM.appendChild(page_metric); // Add the audioelement - for (var element of this.specification.audioElements) { + this.specification.audioElements.forEach(function (element) { var aeNode = this.parent.document.createElement('audioelement'); aeNode.setAttribute('ref', element.id); if (element.name !== undefined) { @@ -3618,7 +3657,7 @@ var ae_metric = this.parent.document.createElement('metric'); aeNode.appendChild(ae_metric); this.XMLDOM.appendChild(aeNode); - } + }, this); this.parent.root.appendChild(this.XMLDOM);