Mercurial > hg > webaudioevaluationtool
comparison js/core.js @ 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 | 66a24a6a0358 |
comparison
equal
deleted
inserted
replaced
2681:95f614a82762 | 2682:0a72855de078 |
---|---|
2 * core.js | 2 * core.js |
3 * | 3 * |
4 * Main script to run, calls all other core functions and manages loading/store to backend. | 4 * Main script to run, calls all other core functions and manages loading/store to backend. |
5 * Also contains all global variables. | 5 * Also contains all global variables. |
6 */ | 6 */ |
7 | |
8 /*globals window, document, XMLDocument, Element, XMLHttpRequest, DOMParser, console, Blob, $, Promise, navigator */ | |
9 /*globals AudioBuffer, AudioBufferSourceNode */ | |
10 /*globals Specification, calculateLoudness, WAVE, validateXML, showdown, pageXMLSave, loadTest, resizeWindow */ | |
7 | 11 |
8 /* create the web audio API context and store in audioContext*/ | 12 /* create the web audio API context and store in audioContext*/ |
9 var audioContext; // Hold the browser web audio API | 13 var audioContext; // Hold the browser web audio API |
10 var projectXML; // Hold the parsed setup XML | 14 var projectXML; // Hold the parsed setup XML |
11 var schemaXSD; // Hold the parsed schema XSD | 15 var schemaXSD; // Hold the parsed schema XSD |
154 | 158 |
155 if (window.location.search.length !== 0) { | 159 if (window.location.search.length !== 0) { |
156 var search = window.location.search.split('?')[1]; | 160 var search = window.location.search.split('?')[1]; |
157 // Now split the requests into pairs | 161 // Now split the requests into pairs |
158 var searchQueries = search.split('&'); | 162 var searchQueries = search.split('&'); |
159 | 163 var url; |
160 for (var i in searchQueries) { | 164 for (var i in searchQueries) { |
161 // Split each key-value pair | 165 // Split each key-value pair |
162 searchQueries[i] = searchQueries[i].split('='); | 166 searchQueries[i] = searchQueries[i].split('='); |
163 var key = searchQueries[i][0]; | 167 var key = searchQueries[i][0]; |
164 var value = decodeURIComponent(searchQueries[i][1]); | 168 var value = decodeURIComponent(searchQueries[i][1]); |
165 switch (key) { | 169 switch (key) { |
166 case "url": | 170 case "url": |
167 url = value; | 171 url = value; |
172 specification.url = url; | |
168 break; | 173 break; |
169 case "returnURL": | 174 case "returnURL": |
170 gReturnURL = value; | 175 gReturnURL = value; |
171 break; | 176 break; |
172 case "saveFilenamePrefix": | 177 case "saveFilenamePrefix": |
671 case "greaterThan": | 676 case "greaterThan": |
672 case "lessThan": | 677 case "lessThan": |
673 console.log("Survey Element of type 'question' cannot interpret greaterThan/lessThan conditions. IGNORING"); | 678 console.log("Survey Element of type 'question' cannot interpret greaterThan/lessThan conditions. IGNORING"); |
674 break; | 679 break; |
675 case "contains": | 680 case "contains": |
676 if (textArea.value.includes(condition.value)) { | 681 if (value.includes(condition.value)) { |
677 return true; | 682 return true; |
678 } | 683 } |
679 break; | 684 break; |
680 } | 685 } |
681 return false; | 686 return false; |
862 } | 867 } |
863 | 868 |
864 function processRadioConditional(condition, response) { | 869 function processRadioConditional(condition, response) { |
865 switch (condition.check) { | 870 switch (condition.check) { |
866 case "equals": | 871 case "equals": |
867 if (node.response === condition.value) { | 872 if (response === condition.value) { |
868 return true; | 873 return true; |
869 } | 874 } |
870 break; | 875 break; |
871 case "contains": | 876 case "contains": |
872 case "greaterThan": | 877 case "greaterThan": |
923 processConditional.call(this, node, node.response); | 928 processConditional.call(this, node, node.response); |
924 return true; | 929 return true; |
925 } | 930 } |
926 | 931 |
927 function processNumberConditional(condtion, value) { | 932 function processNumberConditional(condtion, value) { |
933 var condition = condition; | |
928 switch (condition.check) { | 934 switch (condition.check) { |
929 case "greaterThan": | 935 case "greaterThan": |
930 if (node.response > Number(condition.value)) { | 936 if (value > Number(condition.value)) { |
931 return true; | 937 return true; |
932 } | 938 } |
933 break; | 939 break; |
934 case "lessThan": | 940 case "lessThan": |
935 if (node.response < Number(condition.value)) { | 941 if (value < Number(condition.value)) { |
936 return true; | 942 return true; |
937 } | 943 } |
938 break; | 944 break; |
939 case "equals": | 945 case "equals": |
940 if (node.response == condition.value) { | 946 if (value == condition.value) { |
941 return true; | 947 return true; |
942 } | 948 } |
943 break; | 949 break; |
944 case "contains": | 950 case "contains": |
945 console.log("Survey Element of type 'number' cannot interpret \"contains\" conditions. IGNORING"); | 951 console.log("Survey Element of type 'number' cannot interpret \"contains\" conditions. IGNORING"); |
1001 switch (condition.check) { | 1007 switch (condition.check) { |
1002 case "contains": | 1008 case "contains": |
1003 console.log("Survey Element of type 'number' cannot interpret contains conditions. IGNORING"); | 1009 console.log("Survey Element of type 'number' cannot interpret contains conditions. IGNORING"); |
1004 break; | 1010 break; |
1005 case "greaterThan": | 1011 case "greaterThan": |
1006 if (node.response > Number(condition.value)) { | 1012 if (value > Number(condition.value)) { |
1007 return true; | 1013 return true; |
1008 } | 1014 } |
1009 break; | 1015 break; |
1010 case "lessThan": | 1016 case "lessThan": |
1011 if (node.response < Number(condition.value)) { | 1017 if (value < Number(condition.value)) { |
1012 return true; | 1018 return true; |
1013 } | 1019 } |
1014 break; | 1020 break; |
1015 case "equals": | 1021 case "equals": |
1016 if (node.response == condition.value) { | 1022 if (value == condition.value) { |
1017 return true; | 1023 return true; |
1018 } | 1024 } |
1019 break; | 1025 break; |
1020 default: | 1026 default: |
1021 console.log("Unknown condition. IGNORING"); | 1027 console.log("Unknown condition. IGNORING"); |
1609 | 1615 |
1610 this.registerAudioObject = function (audioObject) { | 1616 this.registerAudioObject = function (audioObject) { |
1611 // Called by an audioObject to register to the buffer for use | 1617 // Called by an audioObject to register to the buffer for use |
1612 // First check if already in the register pool | 1618 // First check if already in the register pool |
1613 this.users.forEach(function (object) { | 1619 this.users.forEach(function (object) { |
1614 if (audioObject.id == objects.id) { | 1620 if (audioObject.id == object.id) { |
1615 return 0; | 1621 return 0; |
1616 } | 1622 } |
1617 }); | 1623 }); |
1618 this.users.push(audioObject); | 1624 this.users.push(audioObject); |
1619 if (this.status == 3 || this.status == -1) { | 1625 if (this.status == 3 || this.status == -1) { |
1764 this.newTrack = function (element) { | 1770 this.newTrack = function (element) { |
1765 // Pull data from given URL into new audio buffer | 1771 // Pull data from given URL into new audio buffer |
1766 // URLs must either be from the same source OR be setup to 'Access-Control-Allow-Origin' | 1772 // URLs must either be from the same source OR be setup to 'Access-Control-Allow-Origin' |
1767 | 1773 |
1768 // Create the audioObject with ID of the new track length; | 1774 // Create the audioObject with ID of the new track length; |
1769 audioObjectId = this.audioObjects.length; | 1775 var audioObjectId = this.audioObjects.length; |
1770 this.audioObjects[audioObjectId] = new audioObject(audioObjectId); | 1776 this.audioObjects[audioObjectId] = new audioObject(audioObjectId); |
1771 | 1777 |
1772 // Check if audioObject buffer is currently stored by full URL | 1778 // Check if audioObject buffer is currently stored by full URL |
1773 var URL = testState.currentStateMap.hostURL + element.url; | 1779 var URL = testState.currentStateMap.hostURL + element.url; |
1774 var buffer = this.buffers.find(function (buffObj) { | 1780 var buffer = this.buffers.find(function (buffObj) { |
1808 this.loopPlayback = audioHolderObject.loop; | 1814 this.loopPlayback = audioHolderObject.loop; |
1809 this.synchPlayback = audioHolderObject.synchronous; | 1815 this.synchPlayback = audioHolderObject.synchronous; |
1810 }; | 1816 }; |
1811 | 1817 |
1812 this.checkAllPlayed = function () { | 1818 this.checkAllPlayed = function () { |
1813 arr = []; | 1819 var arr = []; |
1814 for (var id = 0; id < this.audioObjects.length; id++) { | 1820 for (var id = 0; id < this.audioObjects.length; id++) { |
1815 if (this.audioObjects[id].metric.wasListenedTo === false) { | 1821 if (this.audioObjects[id].metric.wasListenedTo === false) { |
1816 arr.push(this.audioObjects[id].id); | 1822 arr.push(this.audioObjects[id].id); |
1817 } | 1823 } |
1818 } | 1824 } |
2037 } | 2043 } |
2038 if (this.commentDOM !== null) { | 2044 if (this.commentDOM !== null) { |
2039 this.storeDOM.appendChild(this.commentDOM.exportXMLDOM(this)); | 2045 this.storeDOM.appendChild(this.commentDOM.exportXMLDOM(this)); |
2040 } | 2046 } |
2041 } | 2047 } |
2042 var nodes = this.metric.exportXMLDOM(); | 2048 this.metric.exportXMLDOM(this.storeDOM.getElementsByTagName('metric')[0]); |
2043 var mroot = this.storeDOM.getElementsByTagName('metric')[0]; | |
2044 for (var i = 0; i < nodes.length; i++) { | |
2045 mroot.appendChild(nodes[i]); | |
2046 } | |
2047 }; | 2049 }; |
2048 } | 2050 } |
2049 | 2051 |
2050 function timer() { | 2052 function timer() { |
2051 /* Timer object used in audioEngine to keep track of session timings | 2053 /* Timer object used in audioEngine to keep track of session timings |
2200 } | 2202 } |
2201 console.log('slider ' + this.parent.id + ' played for (' + diff + ')'); // DEBUG/SAFETY: show played slider id | 2203 console.log('slider ' + this.parent.id + ' played for (' + diff + ')'); // DEBUG/SAFETY: show played slider id |
2202 } | 2204 } |
2203 }; | 2205 }; |
2204 | 2206 |
2205 this.exportXMLDOM = function () { | 2207 function exportElementTimer(parentElement) { |
2206 var storeDOM = []; | 2208 var mElementTimer = storage.document.createElement('metricresult'); |
2209 mElementTimer.setAttribute('name', 'enableElementTimer'); | |
2210 mElementTimer.textContent = this.listenedTimer; | |
2211 parentElement.appendChild(mElementTimer); | |
2212 } | |
2213 | |
2214 function exportElementTrack(parentElement) { | |
2215 var elementTrackerFull = storage.document.createElement('metricresult'); | |
2216 elementTrackerFull.setAttribute('name', 'elementTrackerFull'); | |
2217 for (var k = 0; k < this.movementTracker.length; k++) { | |
2218 var timePos = storage.document.createElement('movement'); | |
2219 timePos.setAttribute("time", this.movementTracker[k][0]); | |
2220 timePos.setAttribute("value", this.movementTracker[k][1]); | |
2221 elementTrackerFull.appendChild(timePos); | |
2222 } | |
2223 parentElement.appendChild(elementTrackerFull); | |
2224 } | |
2225 | |
2226 function exportElementListenTracker(parentElement) { | |
2227 var elementListenTracker = storage.document.createElement('metricresult'); | |
2228 elementListenTracker.setAttribute('name', 'elementListenTracker'); | |
2229 for (var k = 0; k < this.listenTracker.length; k++) { | |
2230 elementListenTracker.appendChild(this.listenTracker[k]); | |
2231 } | |
2232 parentElement.appendChild(elementListenTracker); | |
2233 } | |
2234 | |
2235 function exportElementInitialPosition(parentElement) { | |
2236 var elementInitial = storage.document.createElement('metricresult'); | |
2237 elementInitial.setAttribute('name', 'elementInitialPosition'); | |
2238 elementInitial.textContent = this.initialPosition; | |
2239 parentElement.appendChild(elementInitial); | |
2240 } | |
2241 | |
2242 function exportFlagListenedTo(parentElement) { | |
2243 var flagListenedTo = storage.document.createElement('metricresult'); | |
2244 flagListenedTo.setAttribute('name', 'elementFlagListenedTo'); | |
2245 flagListenedTo.textContent = this.wasListenedTo; | |
2246 parentElement.appendChild(flagListenedTo); | |
2247 } | |
2248 | |
2249 function exportFlagMoved(parentElement) { | |
2250 var flagMoved = storage.document.createElement('metricresult'); | |
2251 flagMoved.setAttribute('name', 'elementFlagMoved'); | |
2252 flagMoved.textContent = this.wasMoved; | |
2253 parentElement.appendChild(flagMoved); | |
2254 } | |
2255 | |
2256 function exportFlagComments(parentElement) { | |
2257 var flagComments = storage.document.createElement('metricresult'); | |
2258 flagComments.setAttribute('name', 'elementFlagComments'); | |
2259 if (this.parent.commentDOM === null) { | |
2260 flagComments.textContent = 'false'; | |
2261 } else if (this.parent.commentDOM.textContent.length === 0) { | |
2262 flagComments.textContent = 'false'; | |
2263 } else { | |
2264 flagComments.textContet = 'true'; | |
2265 } | |
2266 parentElement.appendChild(flagComments); | |
2267 } | |
2268 | |
2269 this.exportXMLDOM = function (parentElement) { | |
2207 if (audioEngineContext.metric.enableElementTimer) { | 2270 if (audioEngineContext.metric.enableElementTimer) { |
2208 var mElementTimer = storage.document.createElement('metricresult'); | 2271 exportElementTimer.call(this, parentElement); |
2209 mElementTimer.setAttribute('name', 'enableElementTimer'); | |
2210 mElementTimer.textContent = this.listenedTimer; | |
2211 storeDOM.push(mElementTimer); | |
2212 } | 2272 } |
2213 if (audioEngineContext.metric.enableElementTracker) { | 2273 if (audioEngineContext.metric.enableElementTracker) { |
2214 var elementTrackerFull = storage.document.createElement('metricresult'); | 2274 exportElementTrack.call(this, parentElement); |
2215 elementTrackerFull.setAttribute('name', 'elementTrackerFull'); | |
2216 for (var k = 0; k < this.movementTracker.length; k++) { | |
2217 var timePos = storage.document.createElement('movement'); | |
2218 timePos.setAttribute("time", this.movementTracker[k][0]); | |
2219 timePos.setAttribute("value", this.movementTracker[k][1]); | |
2220 elementTrackerFull.appendChild(timePos); | |
2221 } | |
2222 storeDOM.push(elementTrackerFull); | |
2223 } | 2275 } |
2224 if (audioEngineContext.metric.enableElementListenTracker) { | 2276 if (audioEngineContext.metric.enableElementListenTracker) { |
2225 var elementListenTracker = storage.document.createElement('metricresult'); | 2277 exportElementListenTracker.call(this, parentElement); |
2226 elementListenTracker.setAttribute('name', 'elementListenTracker'); | |
2227 for (var k = 0; k < this.listenTracker.length; k++) { | |
2228 elementListenTracker.appendChild(this.listenTracker[k]); | |
2229 } | |
2230 storeDOM.push(elementListenTracker); | |
2231 } | 2278 } |
2232 if (audioEngineContext.metric.enableElementInitialPosition) { | 2279 if (audioEngineContext.metric.enableElementInitialPosition) { |
2233 var elementInitial = storage.document.createElement('metricresult'); | 2280 exportElementInitialPosition.call(this, parentElement); |
2234 elementInitial.setAttribute('name', 'elementInitialPosition'); | |
2235 elementInitial.textContent = this.initialPosition; | |
2236 storeDOM.push(elementInitial); | |
2237 } | 2281 } |
2238 if (audioEngineContext.metric.enableFlagListenedTo) { | 2282 if (audioEngineContext.metric.enableFlagListenedTo) { |
2239 var flagListenedTo = storage.document.createElement('metricresult'); | 2283 exportFlagListenedTo.call(this, parentElement); |
2240 flagListenedTo.setAttribute('name', 'elementFlagListenedTo'); | |
2241 flagListenedTo.textContent = this.wasListenedTo; | |
2242 storeDOM.push(flagListenedTo); | |
2243 } | 2284 } |
2244 if (audioEngineContext.metric.enableFlagMoved) { | 2285 if (audioEngineContext.metric.enableFlagMoved) { |
2245 var flagMoved = storage.document.createElement('metricresult'); | 2286 exportFlagMoved.call(this, parentElement); |
2246 flagMoved.setAttribute('name', 'elementFlagMoved'); | |
2247 flagMoved.textContent = this.wasMoved; | |
2248 storeDOM.push(flagMoved); | |
2249 } | 2287 } |
2250 if (audioEngineContext.metric.enableFlagComments) { | 2288 if (audioEngineContext.metric.enableFlagComments) { |
2251 var flagComments = storage.document.createElement('metricresult'); | 2289 exportFlagComments.call(this, parentElement); |
2252 flagComments.setAttribute('name', 'elementFlagComments'); | 2290 } |
2253 if (this.parent.commentDOM === null) { | |
2254 flag.textContent = 'false'; | |
2255 } else if (this.parent.commentDOM.textContent.length === 0) { | |
2256 flag.textContent = 'false'; | |
2257 } else { | |
2258 flag.textContet = 'true'; | |
2259 } | |
2260 storeDOM.push(flagComments); | |
2261 } | |
2262 return storeDOM; | |
2263 }; | 2291 }; |
2264 } | 2292 } |
2265 | 2293 |
2266 function Interface(specificationObject) { | 2294 function Interface(specificationObject) { |
2267 // This handles the bindings between the interface and the audioEngineContext; | 2295 // This handles the bindings between the interface and the audioEngineContext; |
2283 | 2311 |
2284 this.resizeWindow = function (event) { | 2312 this.resizeWindow = function (event) { |
2285 popup.resize(event); | 2313 popup.resize(event); |
2286 this.volume.resize(); | 2314 this.volume.resize(); |
2287 this.lightbox.resize(); | 2315 this.lightbox.resize(); |
2288 for (var i = 0; i < this.commentBoxes.length; i++) { | 2316 this.commentBoxes.forEach(function (elem) { |
2289 this.commentBoxes[i].resize(); | 2317 elem.resize(); |
2290 } | 2318 }); |
2291 for (var i = 0; i < this.commentQuestions.length; i++) { | 2319 this.commentQuestions.forEach(function (elem) { |
2292 this.commentQuestions[i].resize(); | 2320 elem.resize(); |
2293 } | 2321 }); |
2294 try { | 2322 try { |
2295 resizeWindow(event); | 2323 resizeWindow(event); |
2296 } catch (err) { | 2324 } catch (err) { |
2297 console.log("Warning - Interface does not have Resize option"); | 2325 console.log("Warning - Interface does not have Resize option"); |
2298 console.log(err); | 2326 console.log(err); |
2462 this.showCommentBoxes = function (inject, sort) { | 2490 this.showCommentBoxes = function (inject, sort) { |
2463 this.injectPoint = inject; | 2491 this.injectPoint = inject; |
2464 if (sort) { | 2492 if (sort) { |
2465 this.sortCommentBoxes(); | 2493 this.sortCommentBoxes(); |
2466 } | 2494 } |
2467 for (var box of this.boxes) { | 2495 this.boxes.forEach(function (box) { |
2468 inject.appendChild(box.trackComment); | 2496 inject.appendChild(box.trackComment); |
2469 } | 2497 }); |
2470 }; | 2498 }; |
2471 | 2499 |
2472 this.deleteCommentBoxes = function () { | 2500 this.deleteCommentBoxes = function () { |
2473 if (this.injectPoint !== null) { | 2501 if (this.injectPoint !== null) { |
2474 for (var box of this.boxes) { | 2502 this.boxes.forEach(function (box) { |
2475 this.injectPoint.removeChild(box.trackComment); | 2503 this.injectPoint.removeChild(box.trackComment); |
2476 } | 2504 }, this); |
2477 this.injectPoint = null; | 2505 this.injectPoint = null; |
2478 } | 2506 } |
2479 this.boxes = []; | 2507 this.boxes = []; |
2480 }; | 2508 }; |
2481 }; | 2509 }; |
2551 this.span.align = 'center'; | 2579 this.span.align = 'center'; |
2552 this.span.style.marginTop = '15px'; | 2580 this.span.style.marginTop = '15px'; |
2553 this.span.className = "comment-radio-span-holder"; | 2581 this.span.className = "comment-radio-span-holder"; |
2554 | 2582 |
2555 var optCount = commentQuestion.options.length; | 2583 var optCount = commentQuestion.options.length; |
2556 for (var optNode of commentQuestion.options) { | 2584 commentQuestion.options.forEach(function (optNode) { |
2557 var div = document.createElement('div'); | 2585 var div = document.createElement('div'); |
2558 div.style.width = '80px'; | 2586 div.style.width = '80px'; |
2559 div.style.float = 'left'; | 2587 div.style.float = 'left'; |
2560 var input = document.createElement('input'); | 2588 var input = document.createElement('input'); |
2561 input.type = 'radio'; | 2589 input.type = 'radio'; |
2574 span.textContent = optNode.text; | 2602 span.textContent = optNode.text; |
2575 span.className = 'comment-radio-span'; | 2603 span.className = 'comment-radio-span'; |
2576 div.appendChild(span); | 2604 div.appendChild(span); |
2577 this.span.appendChild(div); | 2605 this.span.appendChild(div); |
2578 this.options.push(input); | 2606 this.options.push(input); |
2579 } | 2607 }, this); |
2580 this.holder.appendChild(this.span); | 2608 this.holder.appendChild(this.span); |
2581 this.holder.appendChild(this.inputs); | 2609 this.holder.appendChild(this.inputs); |
2582 | 2610 |
2583 this.exportXMLDOM = function (storePoint) { | 2611 this.exportXMLDOM = function (storePoint) { |
2584 var root = storePoint.parent.document.createElement('comment'); | 2612 var root = storePoint.parent.document.createElement('comment'); |
2617 this.holder.style.width = boxwidth + "px"; | 2645 this.holder.style.width = boxwidth + "px"; |
2618 var text = this.holder.getElementsByClassName("comment-radio-span-holder")[0]; | 2646 var text = this.holder.getElementsByClassName("comment-radio-span-holder")[0]; |
2619 var options = this.holder.getElementsByClassName("comment-radio-inputs-holder")[0]; | 2647 var options = this.holder.getElementsByClassName("comment-radio-inputs-holder")[0]; |
2620 var optCount = options.childElementCount; | 2648 var optCount = options.childElementCount; |
2621 var spanMargin = Math.floor(((boxwidth - 20 - (optCount * 80)) / (optCount)) / 2) + 'px'; | 2649 var spanMargin = Math.floor(((boxwidth - 20 - (optCount * 80)) / (optCount)) / 2) + 'px'; |
2622 var options = options.firstChild; | 2650 options = options.firstChild; |
2623 var text = text.firstChild; | 2651 text = text.firstChild; |
2624 options.style.marginRight = spanMargin; | 2652 options.style.marginRight = spanMargin; |
2625 options.style.marginLeft = spanMargin; | 2653 options.style.marginLeft = spanMargin; |
2626 text.style.marginRight = spanMargin; | 2654 text.style.marginRight = spanMargin; |
2627 text.style.marginLeft = spanMargin; | 2655 text.style.marginLeft = spanMargin; |
2628 while (options.nextSibling !== undefined) { | 2656 while (options.nextSibling !== undefined) { |
2716 this.holder.style.width = boxwidth + "px"; | 2744 this.holder.style.width = boxwidth + "px"; |
2717 var text = this.holder.getElementsByClassName("comment-checkbox-span-holder")[0]; | 2745 var text = this.holder.getElementsByClassName("comment-checkbox-span-holder")[0]; |
2718 var options = this.holder.getElementsByClassName("comment-checkbox-inputs-holder")[0]; | 2746 var options = this.holder.getElementsByClassName("comment-checkbox-inputs-holder")[0]; |
2719 var optCount = options.childElementCount; | 2747 var optCount = options.childElementCount; |
2720 var spanMargin = Math.floor(((boxwidth - 20 - (optCount * 80)) / (optCount)) / 2) + 'px'; | 2748 var spanMargin = Math.floor(((boxwidth - 20 - (optCount * 80)) / (optCount)) / 2) + 'px'; |
2721 var options = options.firstChild; | 2749 options = options.firstChild; |
2722 var text = text.firstChild; | 2750 text = text.firstChild; |
2723 options.style.marginRight = spanMargin; | 2751 options.style.marginRight = spanMargin; |
2724 options.style.marginLeft = spanMargin; | 2752 options.style.marginLeft = spanMargin; |
2725 text.style.marginRight = spanMargin; | 2753 text.style.marginRight = spanMargin; |
2726 text.style.marginLeft = spanMargin; | 2754 text.style.marginLeft = spanMargin; |
2727 while (options.nextSibling !== undefined) { | 2755 while (options.nextSibling !== undefined) { |
2886 this.object.appendChild(this.scrubberTrack); | 2914 this.object.appendChild(this.scrubberTrack); |
2887 | 2915 |
2888 this.timePerPixel = 0; | 2916 this.timePerPixel = 0; |
2889 this.maxTime = 0; | 2917 this.maxTime = 0; |
2890 | 2918 |
2891 this.playbackObject; | 2919 this.playbackObject = undefined; |
2892 | 2920 |
2893 this.setTimePerPixel = function (audioObject) { | 2921 this.setTimePerPixel = function (audioObject) { |
2894 //maxTime must be in seconds | 2922 //maxTime must be in seconds |
2895 this.playbackObject = audioObject; | 2923 this.playbackObject = audioObject; |
2896 this.maxTime = audioObject.buffer.buffer.duration; | 2924 this.maxTime = audioObject.buffer.buffer.duration; |
2936 this.interval = undefined; | 2964 this.interval = undefined; |
2937 | 2965 |
2938 this.start = function () { | 2966 this.start = function () { |
2939 if (this.playbackObject !== undefined && this.interval === undefined) { | 2967 if (this.playbackObject !== undefined && this.interval === undefined) { |
2940 if (this.maxTime < 60) { | 2968 if (this.maxTime < 60) { |
2941 this.interval = setInterval(function () { | 2969 this.interval = window.setInterval(function () { |
2942 interfaceContext.playhead.update(); | 2970 interfaceContext.playhead.update(); |
2943 }, 10); | 2971 }, 10); |
2944 } else { | 2972 } else { |
2945 this.interval = setInterval(function () { | 2973 this.interval = window.setInterval(function () { |
2946 interfaceContext.playhead.update(); | 2974 interfaceContext.playhead.update(); |
2947 }, 100); | 2975 }, 100); |
2948 } | 2976 } |
2949 } | 2977 } |
2950 }; | 2978 }; |
2951 this.stop = function () { | 2979 this.stop = function () { |
2952 clearInterval(this.interval); | 2980 window.clearInterval(this.interval); |
2953 this.interval = undefined; | 2981 this.interval = undefined; |
2954 this.scrubberHead.style.left = '0px'; | 2982 this.scrubberHead.style.left = '0px'; |
2955 if (this.maxTime < 60) { | 2983 if (this.maxTime < 60) { |
2956 this.curTimeSpan.textContent = '0.00'; | 2984 this.curTimeSpan.textContent = '0.00'; |
2957 } else { | 2985 } else { |
3097 f0 *= 2; | 3125 f0 *= 2; |
3098 } | 3126 } |
3099 inject.appendChild(this.holder); | 3127 inject.appendChild(this.holder); |
3100 }; | 3128 }; |
3101 this.collect = function () { | 3129 this.collect = function () { |
3102 for (var obj of this.calibrationNodes) { | 3130 this.calibrationNodes.forEach(function (obj) { |
3103 var node = storage.document.createElement("calibrationresult"); | 3131 var node = storage.document.createElement("calibrationresult"); |
3104 node.setAttribute("frequency", obj.f); | 3132 node.setAttribute("frequency", obj.f); |
3105 node.setAttribute("range-min", obj.input.min); | 3133 node.setAttribute("range-min", obj.input.min); |
3106 node.setAttribute("range-max", obj.input.max); | 3134 node.setAttribute("range-max", obj.input.max); |
3107 node.setAttribute("gain-lin", obj.gain.gain.value); | 3135 node.setAttribute("gain-lin", obj.gain.gain.value); |
3108 this.storeDOM.appendChild(node); | 3136 this.storeDOM.appendChild(node); |
3109 } | 3137 }, this); |
3110 }; | 3138 }; |
3111 }; | 3139 }; |
3112 | 3140 |
3113 | 3141 |
3114 // Global Checkers | 3142 // Global Checkers |
3115 // These functions will help enforce the checkers | 3143 // These functions will help enforce the checkers |
3116 this.checkHiddenAnchor = function () { | 3144 this.checkHiddenAnchor = function () { |
3117 for (var ao of audioEngineContext.audioObjects) { | 3145 audioEngineContext.audioObjects.forEach(function (ao) { |
3118 if (ao.specification.type == "anchor") { | 3146 if (ao.specification.type === "anchor") { |
3119 if (ao.interfaceDOM.getValue() > (ao.specification.marker / 100) && ao.specification.marker > 0) { | 3147 if (ao.interfaceDOM.getValue() > (ao.specification.marker / 100) && ao.specification.marker > 0) { |
3120 // Anchor is not set below | 3148 // Anchor is not set below |
3121 console.log('Anchor node not below marker value'); | 3149 console.log('Anchor node not below marker value'); |
3122 interfaceContext.lightbox.post("Message", 'Please keep listening'); | 3150 interfaceContext.lightbox.post("Message", 'Please keep listening'); |
3123 this.storeErrorNode('Anchor node not below marker value'); | 3151 this.storeErrorNode('Anchor node not below marker value'); |
3124 return false; | 3152 return false; |
3125 } | 3153 } |
3126 } | 3154 } |
3127 } | 3155 }, this); |
3128 return true; | 3156 return true; |
3129 }; | 3157 }; |
3130 | 3158 |
3131 this.checkHiddenReference = function () { | 3159 this.checkHiddenReference = function () { |
3132 for (var ao of audioEngineContext.audioObjects) { | 3160 audioEngineContext.audioObjects.forEach(function (ao) { |
3133 if (ao.specification.type == "reference") { | 3161 if (ao.specification.type == "reference") { |
3134 if (ao.interfaceDOM.getValue() < (ao.specification.marker / 100) && ao.specification.marker > 0) { | 3162 if (ao.interfaceDOM.getValue() < (ao.specification.marker / 100) && ao.specification.marker > 0) { |
3135 // Anchor is not set below | 3163 // Anchor is not set below |
3136 console.log('Reference node not above marker value'); | 3164 console.log('Reference node not above marker value'); |
3137 this.storeErrorNode('Reference node not above marker value'); | 3165 this.storeErrorNode('Reference node not above marker value'); |
3138 interfaceContext.lightbox.post("Message", 'Please keep listening'); | 3166 interfaceContext.lightbox.post("Message", 'Please keep listening'); |
3139 return false; | 3167 return false; |
3140 } | 3168 } |
3141 } | 3169 } |
3142 } | 3170 }, this); |
3143 return true; | 3171 return true; |
3144 }; | 3172 }; |
3145 | 3173 |
3146 this.checkFragmentsFullyPlayed = function () { | 3174 this.checkFragmentsFullyPlayed = function () { |
3147 // Checks the entire file has been played back | 3175 // Checks the entire file has been played back |
3149 if (audioEngineContext.loopPlayback) { | 3177 if (audioEngineContext.loopPlayback) { |
3150 console.log("WARNING - Looped source: Cannot check fragments are fully played"); | 3178 console.log("WARNING - Looped source: Cannot check fragments are fully played"); |
3151 return true; | 3179 return true; |
3152 } | 3180 } |
3153 var check_pass = true; | 3181 var check_pass = true; |
3154 var error_obj = []; | 3182 var error_obj = [], |
3155 for (var i = 0; i < audioEngineContext.audioObjects.length; i++) { | 3183 i; |
3184 for (i = 0; i < audioEngineContext.audioObjects.length; i++) { | |
3156 var object = audioEngineContext.audioObjects[i]; | 3185 var object = audioEngineContext.audioObjects[i]; |
3157 var time = object.buffer.buffer.duration; | 3186 var time = object.buffer.buffer.duration; |
3158 var metric = object.metric; | 3187 var metric = object.metric; |
3159 var passed = false; | 3188 var passed = false; |
3160 for (var j = 0; j < metric.listenTracker.length; j++) { | 3189 for (var j = 0; j < metric.listenTracker.length; j++) { |
3173 error_obj.push(object.interfaceDOM.getPresentedId()); | 3202 error_obj.push(object.interfaceDOM.getPresentedId()); |
3174 } | 3203 } |
3175 } | 3204 } |
3176 if (check_pass === false) { | 3205 if (check_pass === false) { |
3177 var str_start = "You have not completely listened to fragments "; | 3206 var str_start = "You have not completely listened to fragments "; |
3178 for (var i = 0; i < error_obj.length; i++) { | 3207 for (i = 0; i < error_obj.length; i++) { |
3179 str_start += error_obj[i]; | 3208 str_start += error_obj[i]; |
3180 if (i != error_obj.length - 1) { | 3209 if (i != error_obj.length - 1) { |
3181 str_start += ', '; | 3210 str_start += ', '; |
3182 } | 3211 } |
3183 } | 3212 } |
3190 return true; | 3219 return true; |
3191 }; | 3220 }; |
3192 this.checkAllMoved = function () { | 3221 this.checkAllMoved = function () { |
3193 var str = "You have not moved "; | 3222 var str = "You have not moved "; |
3194 var failed = []; | 3223 var failed = []; |
3195 for (var ao of audioEngineContext.audioObjects) { | 3224 audioEngineContext.audioObjects.forEach(function (ao) { |
3196 if (ao.metric.wasMoved === false && ao.interfaceDOM.canMove() === true) { | 3225 if (ao.metric.wasMoved === false && ao.interfaceDOM.canMove() === true) { |
3197 failed.push(ao.interfaceDOM.getPresentedId()); | 3226 failed.push(ao.interfaceDOM.getPresentedId()); |
3198 } | 3227 } |
3199 } | 3228 }, this); |
3200 if (failed.length === 0) { | 3229 if (failed.length === 0) { |
3201 return true; | 3230 return true; |
3202 } else if (failed.length == 1) { | 3231 } else if (failed.length == 1) { |
3203 str += 'track ' + failed[0]; | 3232 str += 'track ' + failed[0]; |
3204 } else { | 3233 } else { |
3215 return false; | 3244 return false; |
3216 }; | 3245 }; |
3217 this.checkAllPlayed = function () { | 3246 this.checkAllPlayed = function () { |
3218 var str = "You have not played "; | 3247 var str = "You have not played "; |
3219 var failed = []; | 3248 var failed = []; |
3220 for (var ao of audioEngineContext.audioObjects) { | 3249 audioEngineContext.audioObjects.forEach(function (ao) { |
3221 if (ao.metric.wasListenedTo === false) { | 3250 if (ao.metric.wasListenedTo === false) { |
3222 failed.push(ao.interfaceDOM.getPresentedId()); | 3251 failed.push(ao.interfaceDOM.getPresentedId()); |
3223 } | 3252 } |
3224 } | 3253 }, this); |
3225 if (failed.length === 0) { | 3254 if (failed.length === 0) { |
3226 return true; | 3255 return true; |
3227 } else if (failed.length == 1) { | 3256 } else if (failed.length == 1) { |
3228 str += 'track ' + failed[0]; | 3257 str += 'track ' + failed[0]; |
3229 } else { | 3258 } else { |
3260 var audioObjects = audioEngineContext.audioObjects; | 3289 var audioObjects = audioEngineContext.audioObjects; |
3261 var state = true; | 3290 var state = true; |
3262 var str = "Please keep listening. "; | 3291 var str = "Please keep listening. "; |
3263 var minRanking = Infinity; | 3292 var minRanking = Infinity; |
3264 var maxRanking = -Infinity; | 3293 var maxRanking = -Infinity; |
3265 for (var ao of audioObjects) { | 3294 audioEngineContext.audioObjects.forEach(function (ao) { |
3266 var rank = ao.interfaceDOM.getValue(); | 3295 var rank = ao.interfaceDOM.getValue(); |
3267 if (rank < minRanking) { | 3296 if (rank < minRanking) { |
3268 minRanking = rank; | 3297 minRanking = rank; |
3269 } | 3298 } |
3270 if (rank > maxRanking) { | 3299 if (rank > maxRanking) { |
3271 maxRanking = rank; | 3300 maxRanking = rank; |
3272 } | 3301 } |
3273 } | 3302 }, this); |
3274 if (minRanking * 100 > min) { | 3303 if (minRanking * 100 > min) { |
3275 str += "At least one fragment must be below the " + min + " mark."; | 3304 str += "At least one fragment must be below the " + min + " mark."; |
3276 state = false; | 3305 state = false; |
3277 } | 3306 } |
3278 if (maxRanking * 100 < max) { | 3307 if (maxRanking * 100 < max) { |
3346 labelStart = Number(labelStart); | 3375 labelStart = Number(labelStart); |
3347 if (!isFinite(labelStart)) { | 3376 if (!isFinite(labelStart)) { |
3348 labelStart = 1; | 3377 labelStart = 1; |
3349 } | 3378 } |
3350 break; | 3379 break; |
3351 case "none": | |
3352 default: | 3380 default: |
3353 labelStart = 0; | 3381 labelStart = 0; |
3354 } | 3382 } |
3355 if (typeof index == "number") { | 3383 if (typeof index == "number") { |
3356 return calculateLabel(labelType, index, labelStart); | 3384 return calculateLabel(labelType, index, labelStart); |
3407 // We need to get the sessionKey | 3435 // We need to get the sessionKey |
3408 this.SessionKey.requestKey(); | 3436 this.SessionKey.requestKey(); |
3409 this.document = document.implementation.createDocument(null, "waetresult", null); | 3437 this.document = document.implementation.createDocument(null, "waetresult", null); |
3410 this.root = this.document.childNodes[0]; | 3438 this.root = this.document.childNodes[0]; |
3411 var projectDocument = specification.projectXML; | 3439 var projectDocument = specification.projectXML; |
3412 projectDocument.setAttribute('file-name', url); | 3440 projectDocument.setAttribute('file-name', specification.url); |
3413 projectDocument.setAttribute('url', qualifyURL(url)); | 3441 projectDocument.setAttribute('url', qualifyURL(specification.url)); |
3414 this.root.appendChild(projectDocument); | 3442 this.root.appendChild(projectDocument); |
3415 this.root.appendChild(interfaceContext.returnDateNode()); | 3443 this.root.appendChild(interfaceContext.returnDateNode()); |
3416 this.root.appendChild(interfaceContext.returnNavigator()); | 3444 this.root.appendChild(interfaceContext.returnNavigator()); |
3417 } else { | 3445 } else { |
3418 this.document = existingStore; | 3446 this.document = existingStore; |
3518 this.parent = parent; | 3546 this.parent = parent; |
3519 this.state = "empty"; | 3547 this.state = "empty"; |
3520 this.XMLDOM = this.parent.document.createElement('survey'); | 3548 this.XMLDOM = this.parent.document.createElement('survey'); |
3521 this.XMLDOM.setAttribute('location', this.specification.location); | 3549 this.XMLDOM.setAttribute('location', this.specification.location); |
3522 this.XMLDOM.setAttribute("state", this.state); | 3550 this.XMLDOM.setAttribute("state", this.state); |
3523 for (var optNode of this.specification.options) { | 3551 this.specification.options.forEach(function (optNode) { |
3524 if (optNode.type != 'statement') { | 3552 if (optNode.type != 'statement') { |
3525 var node = this.parent.document.createElement('surveyresult'); | 3553 var node = this.parent.document.createElement('surveyresult'); |
3526 node.setAttribute("ref", optNode.id); | 3554 node.setAttribute("ref", optNode.id); |
3527 node.setAttribute('type', optNode.type); | 3555 node.setAttribute('type', optNode.type); |
3528 this.XMLDOM.appendChild(node); | 3556 this.XMLDOM.appendChild(node); |
3529 } | 3557 } |
3530 } | 3558 }, this); |
3531 root.appendChild(this.XMLDOM); | 3559 root.appendChild(this.XMLDOM); |
3532 | 3560 |
3533 this.postResult = function (node) { | 3561 this.postResult = function (node) { |
3562 function postNumber(doc, value) { | |
3563 var child = doc.createElement("response"); | |
3564 child.textContent = value; | |
3565 return child; | |
3566 } | |
3567 | |
3568 function postRadio(doc, node) { | |
3569 var child = doc.createElement('response'); | |
3570 if (node.response !== null) { | |
3571 child.setAttribute('name', node.response.name); | |
3572 child.textContent = node.response.text; | |
3573 } | |
3574 return child; | |
3575 } | |
3576 | |
3577 function postCheckbox(doc, node) { | |
3578 var checkNode = doc.createElement('response'); | |
3579 checkNode.setAttribute('name', node.name); | |
3580 checkNode.setAttribute('checked', node.checked); | |
3581 return checkNode; | |
3582 } | |
3534 // From popup: node is the popupOption node containing both spec. and results | 3583 // From popup: node is the popupOption node containing both spec. and results |
3535 // ID is the position | 3584 // ID is the position |
3536 if (node.specification.type == 'statement') { | 3585 if (node.specification.type == 'statement') { |
3537 return; | 3586 return; |
3538 } | 3587 } |
3545 } | 3594 } |
3546 switch (node.specification.type) { | 3595 switch (node.specification.type) { |
3547 case "number": | 3596 case "number": |
3548 case "question": | 3597 case "question": |
3549 case "slider": | 3598 case "slider": |
3550 var child = this.parent.document.createElement('response'); | 3599 surveyresult.appendChild(postNumber(this.parent.document, node.response)); |
3551 child.textContent = node.response; | |
3552 surveyresult.appendChild(child); | |
3553 break; | 3600 break; |
3554 case "radio": | 3601 case "radio": |
3555 var child = this.parent.document.createElement('response'); | 3602 surveyresult.appendChild(postRadio(this.parent.document, node)); |
3556 if (node.response !== null) { | |
3557 child.setAttribute('name', node.response.name); | |
3558 child.textContent = node.response.text; | |
3559 } | |
3560 surveyresult.appendChild(child); | |
3561 break; | 3603 break; |
3562 case "checkbox": | 3604 case "checkbox": |
3563 if (node.response === undefined) { | 3605 if (node.response === undefined) { |
3564 surveyresult.appendChild(this.parent.document.createElement('response')); | 3606 surveyresult.appendChild(this.parent.document.createElement('response')); |
3565 break; | 3607 break; |
3566 } | 3608 } |
3567 for (var i = 0; i < node.response.length; i++) { | 3609 for (var i = 0; i < node.response.length; i++) { |
3568 var checkNode = this.parent.document.createElement('response'); | 3610 surveyresult.appendChild(postCheckbox(this.parent.document, node.response[i])); |
3569 checkNode.setAttribute('name', node.response[i].name); | |
3570 checkNode.setAttribute('checked', node.response[i].checked); | |
3571 surveyresult.appendChild(checkNode); | |
3572 } | 3611 } |
3573 break; | 3612 break; |
3574 } | 3613 } |
3575 }; | 3614 }; |
3576 this.complete = function () { | 3615 this.complete = function () { |
3598 // Add any page metrics | 3637 // Add any page metrics |
3599 var page_metric = this.parent.document.createElement('metric'); | 3638 var page_metric = this.parent.document.createElement('metric'); |
3600 this.XMLDOM.appendChild(page_metric); | 3639 this.XMLDOM.appendChild(page_metric); |
3601 | 3640 |
3602 // Add the audioelement | 3641 // Add the audioelement |
3603 for (var element of this.specification.audioElements) { | 3642 this.specification.audioElements.forEach(function (element) { |
3604 var aeNode = this.parent.document.createElement('audioelement'); | 3643 var aeNode = this.parent.document.createElement('audioelement'); |
3605 aeNode.setAttribute('ref', element.id); | 3644 aeNode.setAttribute('ref', element.id); |
3606 if (element.name !== undefined) { | 3645 if (element.name !== undefined) { |
3607 aeNode.setAttribute('name', element.name); | 3646 aeNode.setAttribute('name', element.name); |
3608 } | 3647 } |
3616 } | 3655 } |
3617 } | 3656 } |
3618 var ae_metric = this.parent.document.createElement('metric'); | 3657 var ae_metric = this.parent.document.createElement('metric'); |
3619 aeNode.appendChild(ae_metric); | 3658 aeNode.appendChild(ae_metric); |
3620 this.XMLDOM.appendChild(aeNode); | 3659 this.XMLDOM.appendChild(aeNode); |
3621 } | 3660 }, this); |
3622 | 3661 |
3623 this.parent.root.appendChild(this.XMLDOM); | 3662 this.parent.root.appendChild(this.XMLDOM); |
3624 | 3663 |
3625 this.complete = function () { | 3664 this.complete = function () { |
3626 this.state = "complete"; | 3665 this.state = "complete"; |