Mercurial > hg > webaudioevaluationtool
comparison core.js @ 654:37f3359709bd
Merge
author | Nicholas Jillings <n.g.r.jillings@se14.qmul.ac.uk> |
---|---|
date | Thu, 31 Mar 2016 15:48:57 +0100 |
parents | ce3d4d6d01b8 |
children |
comparison
equal
deleted
inserted
replaced
605:716c05000a6e | 654:37f3359709bd |
---|---|
25 AudioBufferSourceNode.prototype.playbackStartTime = undefined; | 25 AudioBufferSourceNode.prototype.playbackStartTime = undefined; |
26 // Add a prototype to the bufferNode to hold the desired LINEAR gain | 26 // Add a prototype to the bufferNode to hold the desired LINEAR gain |
27 AudioBuffer.prototype.playbackGain = undefined; | 27 AudioBuffer.prototype.playbackGain = undefined; |
28 // Add a prototype to the bufferNode to hold the computed LUFS loudness | 28 // Add a prototype to the bufferNode to hold the computed LUFS loudness |
29 AudioBuffer.prototype.lufs = undefined; | 29 AudioBuffer.prototype.lufs = undefined; |
30 | |
31 // Convert relative URLs into absolutes | |
32 function escapeHTML(s) { | |
33 return s.split('&').join('&').split('<').join('<').split('"').join('"'); | |
34 } | |
35 function qualifyURL(url) { | |
36 var el= document.createElement('div'); | |
37 el.innerHTML= '<a href="'+escapeHTML(url)+'">x</a>'; | |
38 return el.firstChild.href; | |
39 } | |
30 | 40 |
31 // Firefox does not have an XMLDocument.prototype.getElementsByName | 41 // Firefox does not have an XMLDocument.prototype.getElementsByName |
32 // and there is no searchAll style command, this custom function will | 42 // and there is no searchAll style command, this custom function will |
33 // search all children recusrively for the name. Used for XSD where all | 43 // search all children recusrively for the name. Used for XSD where all |
34 // element nodes must have a name and therefore can pull the schema node | 44 // element nodes must have a name and therefore can pull the schema node |
180 document.getElementsByTagName('body')[0].appendChild(msg); | 190 document.getElementsByTagName('body')[0].appendChild(msg); |
181 document.getElementsByTagName('body')[0].appendChild(span); | 191 document.getElementsByTagName('body')[0].appendChild(span); |
182 document.getElementsByTagName('body')[0].appendChild(errorNode[0]); | 192 document.getElementsByTagName('body')[0].appendChild(errorNode[0]); |
183 return; | 193 return; |
184 } | 194 } |
195 if (responseDocument == undefined) { | |
196 var msg = document.createElement("h3"); | |
197 msg.textContent = "FATAL ERROR"; | |
198 var span = document.createElement("span"); | |
199 span.textContent = "The project XML was not decoded properly, try refreshing your browser and clearing caches. If the problem persists, contact the test creator."; | |
200 document.getElementsByTagName('body')[0].innerHTML = null; | |
201 document.getElementsByTagName('body')[0].appendChild(msg); | |
202 document.getElementsByTagName('body')[0].appendChild(span); | |
203 return; | |
204 } | |
185 if (responseDocument.children[0].nodeName == "waet") { | 205 if (responseDocument.children[0].nodeName == "waet") { |
186 // document is a specification | 206 // document is a specification |
187 | 207 |
188 // Perform XML schema validation | 208 // Perform XML schema validation |
189 var Module = { | 209 var Module = { |
279 var interfaceJS = document.createElement('script'); | 299 var interfaceJS = document.createElement('script'); |
280 interfaceJS.setAttribute("type","text/javascript"); | 300 interfaceJS.setAttribute("type","text/javascript"); |
281 switch(specification.interface) | 301 switch(specification.interface) |
282 { | 302 { |
283 case "APE": | 303 case "APE": |
284 interfaceJS.setAttribute("src","interfaces/ape.js"); | 304 interfaceJS.setAttribute("src","interfaces/ape.js"); |
285 | 305 |
286 // APE comes with a css file | 306 // APE comes with a css file |
287 var css = document.createElement('link'); | 307 var css = document.createElement('link'); |
288 css.rel = 'stylesheet'; | 308 css.rel = 'stylesheet'; |
289 css.type = 'text/css'; | 309 css.type = 'text/css'; |
290 css.href = 'interfaces/ape.css'; | 310 css.href = 'interfaces/ape.css'; |
291 | 311 |
292 document.getElementsByTagName("head")[0].appendChild(css); | 312 document.getElementsByTagName("head")[0].appendChild(css); |
293 break; | 313 break; |
294 | 314 |
295 case "MUSHRA": | 315 case "MUSHRA": |
296 interfaceJS.setAttribute("src","interfaces/mushra.js"); | 316 interfaceJS.setAttribute("src","interfaces/mushra.js"); |
297 | 317 |
298 // MUSHRA comes with a css file | 318 // MUSHRA comes with a css file |
299 var css = document.createElement('link'); | 319 var css = document.createElement('link'); |
300 css.rel = 'stylesheet'; | 320 css.rel = 'stylesheet'; |
301 css.type = 'text/css'; | 321 css.type = 'text/css'; |
302 css.href = 'interfaces/mushra.css'; | 322 css.href = 'interfaces/mushra.css'; |
303 | 323 |
304 document.getElementsByTagName("head")[0].appendChild(css); | 324 document.getElementsByTagName("head")[0].appendChild(css); |
305 break; | 325 break; |
306 | 326 |
307 case "AB": | 327 case "AB": |
308 interfaceJS.setAttribute("src","interfaces/AB.js"); | 328 interfaceJS.setAttribute("src","interfaces/AB.js"); |
309 | 329 |
310 // AB comes with a css file | 330 // AB comes with a css file |
311 var css = document.createElement('link'); | 331 var css = document.createElement('link'); |
312 css.rel = 'stylesheet'; | 332 css.rel = 'stylesheet'; |
313 css.type = 'text/css'; | 333 css.type = 'text/css'; |
314 css.href = 'interfaces/AB.css'; | 334 css.href = 'interfaces/AB.css'; |
315 | 335 |
316 document.getElementsByTagName("head")[0].appendChild(css); | 336 document.getElementsByTagName("head")[0].appendChild(css); |
317 break; | 337 break; |
338 | |
339 case "ABX": | |
340 interfaceJS.setAttribute("src","interfaces/ABX.js"); | |
341 | |
342 // AB comes with a css file | |
343 var css = document.createElement('link'); | |
344 css.rel = 'stylesheet'; | |
345 css.type = 'text/css'; | |
346 css.href = 'interfaces/ABX.css'; | |
347 | |
348 document.getElementsByTagName("head")[0].appendChild(css); | |
349 break; | |
350 | |
318 case "Bipolar": | 351 case "Bipolar": |
319 case "ACR": | 352 case "ACR": |
320 case "DCR": | 353 case "DCR": |
321 case "CCR": | 354 case "CCR": |
322 case "ABC": | 355 case "ABC": |
323 // Above enumerate to horizontal sliders | 356 // Above enumerate to horizontal sliders |
324 interfaceJS.setAttribute("src","interfaces/horizontal-sliders.js"); | 357 interfaceJS.setAttribute("src","interfaces/horizontal-sliders.js"); |
325 | 358 |
326 // horizontal-sliders comes with a css file | 359 // horizontal-sliders comes with a css file |
327 var css = document.createElement('link'); | 360 var css = document.createElement('link'); |
328 css.rel = 'stylesheet'; | 361 css.rel = 'stylesheet'; |
329 css.type = 'text/css'; | 362 css.type = 'text/css'; |
330 css.href = 'interfaces/horizontal-sliders.css'; | 363 css.href = 'interfaces/horizontal-sliders.css'; |
331 | 364 |
332 document.getElementsByTagName("head")[0].appendChild(css); | 365 document.getElementsByTagName("head")[0].appendChild(css); |
333 break; | 366 break; |
334 case "discrete": | 367 case "discrete": |
335 case "likert": | 368 case "likert": |
336 // Above enumerate to horizontal discrete radios | 369 // Above enumerate to horizontal discrete radios |
337 interfaceJS.setAttribute("src","interfaces/discrete.js"); | 370 interfaceJS.setAttribute("src","interfaces/discrete.js"); |
338 | 371 |
339 // horizontal-sliders comes with a css file | 372 // horizontal-sliders comes with a css file |
340 var css = document.createElement('link'); | 373 var css = document.createElement('link'); |
341 css.rel = 'stylesheet'; | 374 css.rel = 'stylesheet'; |
342 css.type = 'text/css'; | 375 css.type = 'text/css'; |
343 css.href = 'interfaces/discrete.css'; | 376 css.href = 'interfaces/discrete.css'; |
344 | 377 |
345 document.getElementsByTagName("head")[0].appendChild(css); | 378 document.getElementsByTagName("head")[0].appendChild(css); |
346 break; | 379 break; |
347 } | 380 } |
348 document.getElementsByTagName("head")[0].appendChild(interfaceJS); | 381 document.getElementsByTagName("head")[0].appendChild(interfaceJS); |
349 | 382 |
350 // Create the audio engine object | 383 // Create the audio engine object |
351 audioEngineContext = new AudioEngine(specification); | 384 audioEngineContext = new AudioEngine(specification); |
352 } | 385 } |
353 | 386 |
354 function createProjectSave(destURL) { | 387 function createProjectSave(destURL) { |
388 // Clear the window.onbeforeunload | |
389 window.onbeforeunload = null; | |
355 // Save the data from interface into XML and send to destURL | 390 // Save the data from interface into XML and send to destURL |
356 // If destURL is null then download XML in client | 391 // If destURL is null then download XML in client |
357 // Now time to render file locally | 392 // Now time to render file locally |
358 var xmlDoc = interfaceXMLSave(); | 393 var xmlDoc = interfaceXMLSave(); |
359 var parent = document.createElement("div"); | 394 var parent = document.createElement("div"); |
389 var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml"); | 424 var xmlDoc = parser.parseFromString(xmlhttp.responseText, "application/xml"); |
390 var response = xmlDoc.getElementsByTagName('response')[0]; | 425 var response = xmlDoc.getElementsByTagName('response')[0]; |
391 if (response.getAttribute("state") == "OK") { | 426 if (response.getAttribute("state") == "OK") { |
392 var file = response.getElementsByTagName("file")[0]; | 427 var file = response.getElementsByTagName("file")[0]; |
393 console.log("Save: OK, written "+file.getAttribute("bytes")+"B"); | 428 console.log("Save: OK, written "+file.getAttribute("bytes")+"B"); |
394 popup.popupContent.textContent = "Thank you. Your session has been saved."; | 429 popup.popupContent.textContent = specification.exitText; |
395 } else { | 430 } else { |
396 var message = response.getElementsByTagName("message"); | 431 var message = response.getElementsByTagName("message"); |
397 console.log("Save: Error! "+message.textContent); | 432 console.log("Save: Error! "+message.textContent); |
398 createProjectSave("local"); | 433 createProjectSave("local"); |
399 } | 434 } |
515 this.popup.style.zIndex = 3; | 550 this.popup.style.zIndex = 3; |
516 this.popup.style.visibility = 'visible'; | 551 this.popup.style.visibility = 'visible'; |
517 var blank = document.getElementsByClassName('testHalt')[0]; | 552 var blank = document.getElementsByClassName('testHalt')[0]; |
518 blank.style.zIndex = 2; | 553 blank.style.zIndex = 2; |
519 blank.style.visibility = 'visible'; | 554 blank.style.visibility = 'visible'; |
555 this.popupResponse.style.left="0%"; | |
520 }; | 556 }; |
521 | 557 |
522 this.hidePopup = function(){ | 558 this.hidePopup = function(){ |
523 this.popup.style.zIndex = -1; | 559 this.popup.style.zIndex = -1; |
524 this.popup.style.visibility = 'hidden'; | 560 this.popup.style.visibility = 'hidden'; |
574 input.type = 'checkbox'; | 610 input.type = 'checkbox'; |
575 var span = document.createElement('span'); | 611 var span = document.createElement('span'); |
576 span.textContent = option.text; | 612 span.textContent = option.text; |
577 var hold = document.createElement('div'); | 613 var hold = document.createElement('div'); |
578 hold.setAttribute('name','option'); | 614 hold.setAttribute('name','option'); |
579 hold.style.padding = '4px'; | 615 hold.className = "popup-option-checbox"; |
580 hold.appendChild(input); | 616 hold.appendChild(input); |
581 hold.appendChild(span); | 617 hold.appendChild(span); |
582 this.popupResponse.appendChild(hold); | 618 this.popupResponse.appendChild(hold); |
583 if (node.response[index] != undefined){ | 619 if (node.response[index] != undefined){ |
584 if (node.response[index].checked == true) { | 620 if (node.response[index].checked == true) { |
585 input.checked = "true"; | 621 input.checked = "true"; |
586 } | 622 } |
587 } | 623 } |
588 var w = $(span).width(); | 624 var w = $(hold).width(); |
589 if (w > max_w) | 625 if (w > max_w) |
590 max_w = w; | 626 max_w = w; |
591 index++; | 627 index++; |
592 } | 628 } |
593 max_w += 12; | |
594 this.popupResponse.style.textAlign=""; | 629 this.popupResponse.style.textAlign=""; |
595 var leftP = ((max_w/500)/2)*100; | 630 var leftP = 50-(((max_w/$('#popupContent').width())/2)*100); |
596 this.popupResponse.style.left=leftP+"%"; | 631 this.popupResponse.style.left=leftP+"%"; |
597 } else if (node.specification.type == 'radio') { | 632 } else if (node.specification.type == 'radio') { |
598 if (node.response == undefined) { | 633 if (node.response == undefined) { |
599 node.response = {name: "", text: ""}; | 634 node.response = {name: "", text: ""}; |
600 } | 635 } |
607 input.name = node.specification.id; | 642 input.name = node.specification.id; |
608 var span = document.createElement('span'); | 643 var span = document.createElement('span'); |
609 span.textContent = option.text; | 644 span.textContent = option.text; |
610 var hold = document.createElement('div'); | 645 var hold = document.createElement('div'); |
611 hold.setAttribute('name','option'); | 646 hold.setAttribute('name','option'); |
612 hold.style.padding = '4px'; | 647 hold.className = "popup-option-checbox"; |
613 hold.appendChild(input); | 648 hold.appendChild(input); |
614 hold.appendChild(span); | 649 hold.appendChild(span); |
615 this.popupResponse.appendChild(hold); | 650 this.popupResponse.appendChild(hold); |
616 if (input.id == node.response.name) { | 651 if (input.id == node.response.name) { |
617 input.checked = "true"; | 652 input.checked = "true"; |
618 } | 653 } |
619 var w = $(span).width(); | 654 var w = $(hold).width(); |
620 if (w > max_w) | 655 if (w > max_w) |
621 max_w = w; | 656 max_w = w; |
622 } | 657 } |
623 max_w += 12; | |
624 this.popupResponse.style.textAlign=""; | 658 this.popupResponse.style.textAlign=""; |
625 var leftP = ((max_w/500)/2)*100; | 659 var leftP = 50-(((max_w/$('#popupContent').width())/2)*100); |
626 this.popupResponse.style.left=leftP+"%"; | 660 this.popupResponse.style.left=leftP+"%"; |
627 } else if (node.specification.type == 'number') { | 661 } else if (node.specification.type == 'number') { |
628 var input = document.createElement('input'); | 662 var input = document.createElement('input'); |
629 input.type = 'textarea'; | 663 input.type = 'textarea'; |
630 if (node.min != null) {input.min = node.specification.min;} | 664 if (node.min != null) {input.min = node.specification.min;} |
674 } | 708 } |
675 }; | 709 }; |
676 | 710 |
677 this.proceedClicked = function() { | 711 this.proceedClicked = function() { |
678 // Each time the popup button is clicked! | 712 // Each time the popup button is clicked! |
713 if (testState.stateIndex == 0 && specification.calibration) { | |
714 interfaceContext.calibrationModuleObject.collect(); | |
715 advanceState(); | |
716 return; | |
717 } | |
679 var node = this.popupOptions[this.currentIndex]; | 718 var node = this.popupOptions[this.currentIndex]; |
680 if (node.specification.type == 'question') { | 719 if (node.specification.type == 'question') { |
681 // Must extract the question data | 720 // Must extract the question data |
682 var textArea = $(popup.popupContent).find('textarea')[0]; | 721 var textArea = $(popup.popupContent).find('textarea')[0]; |
683 if (node.specification.mandatory == true && textArea.value.length == 0) { | 722 if (node.specification.mandatory == true && textArea.value.length == 0) { |
827 { | 866 { |
828 pageHolder = randomiseOrder(pageHolder); | 867 pageHolder = randomiseOrder(pageHolder); |
829 } | 868 } |
830 for (var i=0; i<pageHolder.length; i++) | 869 for (var i=0; i<pageHolder.length; i++) |
831 { | 870 { |
832 pageHolder[i].presentedId = i; | |
833 } | |
834 for (var i=0; i<specification.pages.length; i++) | |
835 { | |
836 if (specification.testPages <= i && specification.testPages != 0) {break;} | 871 if (specification.testPages <= i && specification.testPages != 0) {break;} |
872 pageHolder[i].presentedId = i; | |
837 this.stateMap.push(pageHolder[i]); | 873 this.stateMap.push(pageHolder[i]); |
838 storage.createTestPageStore(pageHolder[i]); | 874 storage.createTestPageStore(pageHolder[i]); |
839 for (var element of pageHolder[i].audioElements) { | 875 for (var element of pageHolder[i].audioElements) { |
840 var URL = pageHolder[i].hostURL + element.url; | 876 var URL = pageHolder[i].hostURL + element.url; |
841 var buffer = null; | 877 var buffer = null; |
858 | 894 |
859 if (this.stateMap.length > 0) { | 895 if (this.stateMap.length > 0) { |
860 if(this.stateIndex != null) { | 896 if(this.stateIndex != null) { |
861 console.log('NOTE - State already initialise'); | 897 console.log('NOTE - State already initialise'); |
862 } | 898 } |
863 this.stateIndex = -1; | 899 this.stateIndex = -2; |
900 console.log('Starting test...'); | |
864 } else { | 901 } else { |
865 console.log('FATAL - StateMap not correctly constructed. EMPTY_STATE_MAP'); | 902 console.log('FATAL - StateMap not correctly constructed. EMPTY_STATE_MAP'); |
866 } | 903 } |
867 }; | 904 }; |
868 this.advanceState = function(){ | 905 this.advanceState = function(){ |
869 if (this.stateIndex == null) { | 906 if (this.stateIndex == null) { |
870 this.initialise(); | 907 this.initialise(); |
871 } | 908 } |
872 storage.update(); | 909 storage.update(); |
873 if (this.stateIndex == -1) { | 910 if (this.stateIndex == -2) { |
874 this.stateIndex++; | 911 this.stateIndex++; |
875 console.log('Starting test...'); | |
876 if (this.preTestSurvey != null) | 912 if (this.preTestSurvey != null) |
877 { | 913 { |
878 popup.initState(this.preTestSurvey,storage.globalPreTest); | 914 popup.initState(this.preTestSurvey,storage.globalPreTest); |
879 } else { | 915 } else { |
880 this.advanceState(); | 916 this.advanceState(); |
881 } | 917 } |
882 } else if (this.stateIndex == this.stateMap.length) | 918 } else if (this.stateIndex == -1) { |
919 this.stateIndex++; | |
920 if (specification.calibration) { | |
921 popup.showPopup(); | |
922 popup.popupTitle.textContent = "Calibration. Set the levels so all tones are of equal amplitude. Move your mouse over the sliders to hear the tones. The red slider is the reference tone"; | |
923 interfaceContext.calibrationModuleObject = new interfaceContext.calibrationModule(); | |
924 interfaceContext.calibrationModuleObject.build(popup.popupResponse); | |
925 popup.hidePreviousButton(); | |
926 } else { | |
927 this.advanceState(); | |
928 } | |
929 } | |
930 else if (this.stateIndex == this.stateMap.length) | |
883 { | 931 { |
884 // All test pages complete, post test | 932 // All test pages complete, post test |
885 console.log('Ending test ...'); | 933 console.log('Ending test ...'); |
886 this.stateIndex++; | 934 this.stateIndex++; |
887 if (this.postTestSurvey == null) { | 935 if (this.postTestSurvey == null) { |
893 { | 941 { |
894 createProjectSave(specification.projectReturn); | 942 createProjectSave(specification.projectReturn); |
895 } | 943 } |
896 else | 944 else |
897 { | 945 { |
946 popup.hidePopup(); | |
898 if (this.currentStateMap == null) | 947 if (this.currentStateMap == null) |
899 { | 948 { |
900 this.currentStateMap = this.stateMap[this.stateIndex]; | 949 this.currentStateMap = this.stateMap[this.stateIndex]; |
901 if (this.currentStateMap.randomiseOrder) | 950 if (this.currentStateMap.randomiseOrder) |
902 { | 951 { |
1740 } | 1789 } |
1741 console.log(inputSequenceClone.toString()); // print original array to console | 1790 console.log(inputSequenceClone.toString()); // print original array to console |
1742 console.log(outputSequence.toString()); // print randomised array to console | 1791 console.log(outputSequence.toString()); // print randomised array to console |
1743 return holdArr; | 1792 return holdArr; |
1744 } | 1793 } |
1745 | |
1746 function returnDateNode() | |
1747 { | |
1748 // Create an XML Node for the Date and Time a test was conducted | |
1749 // Structure is | |
1750 // <datetime> | |
1751 // <date year="##" month="##" day="##">DD/MM/YY</date> | |
1752 // <time hour="##" minute="##" sec="##">HH:MM:SS</time> | |
1753 // </datetime> | |
1754 var dateTime = new Date(); | |
1755 var year = document.createAttribute('year'); | |
1756 var month = document.createAttribute('month'); | |
1757 var day = document.createAttribute('day'); | |
1758 var hour = document.createAttribute('hour'); | |
1759 var minute = document.createAttribute('minute'); | |
1760 var secs = document.createAttribute('secs'); | |
1761 | |
1762 year.nodeValue = dateTime.getFullYear(); | |
1763 month.nodeValue = dateTime.getMonth()+1; | |
1764 day.nodeValue = dateTime.getDate(); | |
1765 hour.nodeValue = dateTime.getHours(); | |
1766 minute.nodeValue = dateTime.getMinutes(); | |
1767 secs.nodeValue = dateTime.getSeconds(); | |
1768 | |
1769 var hold = document.createElement("datetime"); | |
1770 var date = document.createElement("date"); | |
1771 date.textContent = year.nodeValue+'/'+month.nodeValue+'/'+day.nodeValue; | |
1772 var time = document.createElement("time"); | |
1773 time.textContent = hour.nodeValue+':'+minute.nodeValue+':'+secs.nodeValue; | |
1774 | |
1775 date.setAttributeNode(year); | |
1776 date.setAttributeNode(month); | |
1777 date.setAttributeNode(day); | |
1778 time.setAttributeNode(hour); | |
1779 time.setAttributeNode(minute); | |
1780 time.setAttributeNode(secs); | |
1781 | |
1782 hold.appendChild(date); | |
1783 hold.appendChild(time); | |
1784 return hold; | |
1785 | |
1786 } | |
1787 | |
1788 function Specification() { | |
1789 // Handles the decoding of the project specification XML into a simple JavaScript Object. | |
1790 | |
1791 this.interface = null; | |
1792 this.projectReturn = "null"; | |
1793 this.randomiseOrder = null; | |
1794 this.testPages = null; | |
1795 this.pages = []; | |
1796 this.metrics = null; | |
1797 this.interfaces = null; | |
1798 this.loudness = null; | |
1799 this.errors = []; | |
1800 this.schema = null; | |
1801 | |
1802 this.processAttribute = function(attribute,schema) | |
1803 { | |
1804 // attribute is the string returned from getAttribute on the XML | |
1805 // schema is the <xs:attribute> node | |
1806 if (schema.getAttribute('name') == undefined && schema.getAttribute('ref') != undefined) | |
1807 { | |
1808 schema = this.schema.getAllElementsByName(schema.getAttribute('ref'))[0]; | |
1809 } | |
1810 var defaultOpt = schema.getAttribute('default'); | |
1811 if (attribute == null) { | |
1812 attribute = defaultOpt; | |
1813 } | |
1814 var dataType = schema.getAttribute('type'); | |
1815 if (typeof dataType == "string") { dataType = dataType.substr(3);} | |
1816 else {dataType = "string";} | |
1817 if (attribute == null) | |
1818 { | |
1819 return attribute; | |
1820 } | |
1821 switch(dataType) | |
1822 { | |
1823 case "boolean": | |
1824 if (attribute == 'true'){attribute = true;}else{attribute=false;} | |
1825 break; | |
1826 case "negativeInteger": | |
1827 case "positiveInteger": | |
1828 case "nonNegativeInteger": | |
1829 case "nonPositiveInteger": | |
1830 case "integer": | |
1831 case "decimal": | |
1832 case "short": | |
1833 attribute = Number(attribute); | |
1834 break; | |
1835 case "string": | |
1836 default: | |
1837 attribute = String(attribute); | |
1838 break; | |
1839 } | |
1840 return attribute; | |
1841 }; | |
1842 | |
1843 this.decode = function(projectXML) { | |
1844 this.errors = []; | |
1845 // projectXML - DOM Parsed document | |
1846 this.projectXML = projectXML.childNodes[0]; | |
1847 var setupNode = projectXML.getElementsByTagName('setup')[0]; | |
1848 var schemaSetup = this.schema.getAllElementsByName('setup')[0]; | |
1849 // First decode the attributes | |
1850 var attributes = schemaSetup.getAllElementsByTagName('xs:attribute'); | |
1851 for (var i in attributes) | |
1852 { | |
1853 if (isNaN(Number(i)) == true){break;} | |
1854 var attributeName = attributes[i].getAttribute('name'); | |
1855 var projectAttr = setupNode.getAttribute(attributeName); | |
1856 projectAttr = this.processAttribute(projectAttr,attributes[i]); | |
1857 switch(typeof projectAttr) | |
1858 { | |
1859 case "number": | |
1860 case "boolean": | |
1861 eval('this.'+attributeName+' = '+projectAttr); | |
1862 break; | |
1863 case "string": | |
1864 eval('this.'+attributeName+' = "'+projectAttr+'"'); | |
1865 break; | |
1866 } | |
1867 | |
1868 } | |
1869 | |
1870 this.metrics = new this.metricNode(); | |
1871 | |
1872 this.metrics.decode(this,setupNode.getElementsByTagName('metric')[0]); | |
1873 | |
1874 // Now process the survey node options | |
1875 var survey = setupNode.getElementsByTagName('survey'); | |
1876 for (var i in survey) { | |
1877 if (isNaN(Number(i)) == true){break;} | |
1878 var location = survey[i].getAttribute('location'); | |
1879 if (location == 'pre' || location == 'before') | |
1880 { | |
1881 if (this.preTest != null){this.errors.push("Already a pre/before test survey defined! Ignoring second!!");} | |
1882 else { | |
1883 this.preTest = new this.surveyNode(); | |
1884 this.preTest.decode(this,survey[i]); | |
1885 } | |
1886 } else if (location == 'post' || location == 'after') { | |
1887 if (this.postTest != null){this.errors.push("Already a post/after test survey defined! Ignoring second!!");} | |
1888 else { | |
1889 this.postTest = new this.surveyNode(); | |
1890 this.postTest.decode(this,survey[i]); | |
1891 } | |
1892 } | |
1893 } | |
1894 | |
1895 var interfaceNode = setupNode.getElementsByTagName('interface'); | |
1896 if (interfaceNode.length > 1) | |
1897 { | |
1898 this.errors.push("Only one <interface> node in the <setup> node allowed! Others except first ingnored!"); | |
1899 } | |
1900 this.interfaces = new this.interfaceNode(); | |
1901 if (interfaceNode.length != 0) | |
1902 { | |
1903 interfaceNode = interfaceNode[0]; | |
1904 this.interfaces.decode(this,interfaceNode,this.schema.getAllElementsByName('interface')[1]); | |
1905 } | |
1906 | |
1907 // Page tags | |
1908 var pageTags = projectXML.getElementsByTagName('page'); | |
1909 var pageSchema = this.schema.getAllElementsByName('page')[0]; | |
1910 for (var i=0; i<pageTags.length; i++) | |
1911 { | |
1912 var node = new this.page(); | |
1913 node.decode(this,pageTags[i],pageSchema); | |
1914 this.pages.push(node); | |
1915 } | |
1916 }; | |
1917 | |
1918 this.encode = function() | |
1919 { | |
1920 var RootDocument = document.implementation.createDocument(null,"waet"); | |
1921 var root = RootDocument.children[0]; | |
1922 root.setAttribute("xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); | |
1923 root.setAttribute("xsi:noNamespaceSchemaLocation","test-schema.xsd"); | |
1924 // Build setup node | |
1925 var setup = RootDocument.createElement("setup"); | |
1926 var schemaSetup = this.schema.getAllElementsByName('setup')[0]; | |
1927 // First decode the attributes | |
1928 var attributes = schemaSetup.getAllElementsByTagName('xs:attribute'); | |
1929 for (var i=0; i<attributes.length; i++) | |
1930 { | |
1931 var name = attributes[i].getAttribute("name"); | |
1932 if (name == undefined) { | |
1933 name = attributes[i].getAttribute("ref"); | |
1934 } | |
1935 if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") | |
1936 { | |
1937 eval("setup.setAttribute('"+name+"',this."+name+")"); | |
1938 } | |
1939 } | |
1940 root.appendChild(setup); | |
1941 // Survey node | |
1942 setup.appendChild(this.preTest.encode(RootDocument)); | |
1943 setup.appendChild(this.postTest.encode(RootDocument)); | |
1944 setup.appendChild(this.metrics.encode(RootDocument)); | |
1945 setup.appendChild(this.interfaces.encode(RootDocument)); | |
1946 for (var page of this.pages) | |
1947 { | |
1948 root.appendChild(page.encode(RootDocument)); | |
1949 } | |
1950 return RootDocument; | |
1951 }; | |
1952 | |
1953 this.surveyNode = function() { | |
1954 this.location = null; | |
1955 this.options = []; | |
1956 this.schema = specification.schema.getAllElementsByName('survey')[0]; | |
1957 | |
1958 this.OptionNode = function() { | |
1959 this.type = undefined; | |
1960 this.schema = specification.schema.getAllElementsByName('surveyentry')[0]; | |
1961 this.id = undefined; | |
1962 this.name = undefined; | |
1963 this.mandatory = undefined; | |
1964 this.statement = undefined; | |
1965 this.boxsize = undefined; | |
1966 this.options = []; | |
1967 this.min = undefined; | |
1968 this.max = undefined; | |
1969 this.step = undefined; | |
1970 | |
1971 this.decode = function(parent,child) | |
1972 { | |
1973 var attributeMap = this.schema.getAllElementsByTagName('xs:attribute'); | |
1974 for (var i in attributeMap){ | |
1975 if(isNaN(Number(i)) == true){break;} | |
1976 var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref'); | |
1977 var projectAttr = child.getAttribute(attributeName); | |
1978 projectAttr = parent.processAttribute(projectAttr,attributeMap[i]); | |
1979 switch(typeof projectAttr) | |
1980 { | |
1981 case "number": | |
1982 case "boolean": | |
1983 eval('this.'+attributeName+' = '+projectAttr); | |
1984 break; | |
1985 case "string": | |
1986 eval('this.'+attributeName+' = "'+projectAttr+'"'); | |
1987 break; | |
1988 } | |
1989 } | |
1990 this.statement = child.getElementsByTagName('statement')[0].textContent; | |
1991 if (this.type == "checkbox" || this.type == "radio") { | |
1992 var children = child.getElementsByTagName('option'); | |
1993 if (children.length == null) { | |
1994 console.log('Malformed' +child.nodeName+ 'entry'); | |
1995 this.statement = 'Malformed' +child.nodeName+ 'entry'; | |
1996 this.type = 'statement'; | |
1997 } else { | |
1998 this.options = []; | |
1999 for (var i in children) | |
2000 { | |
2001 if (isNaN(Number(i))==true){break;} | |
2002 this.options.push({ | |
2003 name: children[i].getAttribute('name'), | |
2004 text: children[i].textContent | |
2005 }); | |
2006 } | |
2007 } | |
2008 } | |
2009 }; | |
2010 | |
2011 this.exportXML = function(doc) | |
2012 { | |
2013 var node = doc.createElement('surveyentry'); | |
2014 node.setAttribute('type',this.type); | |
2015 var statement = doc.createElement('statement'); | |
2016 statement.textContent = this.statement; | |
2017 node.appendChild(statement); | |
2018 if (this.type != "statement") { | |
2019 node.id = this.id; | |
2020 if (this.name != undefined) { node.setAttribute("name",this.name);} | |
2021 if (this.mandatory != undefined) { node.setAttribute("mandatory",this.mandatory);} | |
2022 switch(this.type) | |
2023 { | |
2024 case "question": | |
2025 if (this.boxsize != undefined) {node.setAttribute("boxsize",this.boxsize);} | |
2026 break; | |
2027 case "number": | |
2028 if (this.min != undefined) {node.setAttribute("min", this.min);} | |
2029 if (this.max != undefined) {node.setAttribute("max", this.max);} | |
2030 break; | |
2031 case "checkbox": | |
2032 case "radio": | |
2033 for (var i=0; i<this.options.length; i++) | |
2034 { | |
2035 var option = this.options[i]; | |
2036 var optionNode = doc.createElement("option"); | |
2037 optionNode.setAttribute("name",option.name); | |
2038 optionNode.textContent = option.text; | |
2039 node.appendChild(optionNode); | |
2040 } | |
2041 break; | |
2042 } | |
2043 } | |
2044 return node; | |
2045 }; | |
2046 }; | |
2047 this.decode = function(parent,xml) { | |
2048 this.location = xml.getAttribute('location'); | |
2049 if (this.location == 'before'){this.location = 'pre';} | |
2050 else if (this.location == 'after'){this.location = 'post';} | |
2051 for (var i in xml.children) | |
2052 { | |
2053 if(isNaN(Number(i))==true){break;} | |
2054 var node = new this.OptionNode(); | |
2055 node.decode(parent,xml.children[i]); | |
2056 this.options.push(node); | |
2057 } | |
2058 }; | |
2059 this.encode = function(doc) { | |
2060 var node = doc.createElement('survey'); | |
2061 node.setAttribute('location',this.location); | |
2062 for (var i=0; i<this.options.length; i++) | |
2063 { | |
2064 node.appendChild(this.options[i].exportXML(doc)); | |
2065 } | |
2066 return node; | |
2067 }; | |
2068 }; | |
2069 | |
2070 this.interfaceNode = function() | |
2071 { | |
2072 this.title = null; | |
2073 this.name = null; | |
2074 this.options = []; | |
2075 this.scales = []; | |
2076 this.schema = specification.schema.getAllElementsByName('interface')[1]; | |
2077 | |
2078 this.decode = function(parent,xml) { | |
2079 this.name = xml.getAttribute('name'); | |
2080 var titleNode = xml.getElementsByTagName('title'); | |
2081 if (titleNode.length == 1) | |
2082 { | |
2083 this.title = titleNode[0].textContent; | |
2084 } | |
2085 var interfaceOptionNodes = xml.getElementsByTagName('interfaceoption'); | |
2086 // Extract interfaceoption node schema | |
2087 var interfaceOptionNodeSchema = this.schema.getAllElementsByName('interfaceoption')[0]; | |
2088 var attributeMap = interfaceOptionNodeSchema.getAllElementsByTagName('xs:attribute'); | |
2089 for (var i=0; i<interfaceOptionNodes.length; i++) | |
2090 { | |
2091 var ioNode = interfaceOptionNodes[i]; | |
2092 var option = {}; | |
2093 for (var j=0; j<attributeMap.length; j++) | |
2094 { | |
2095 var attributeName = attributeMap[j].getAttribute('name') || attributeMap[j].getAttribute('ref'); | |
2096 var projectAttr = ioNode.getAttribute(attributeName); | |
2097 projectAttr = parent.processAttribute(projectAttr,attributeMap[j]); | |
2098 switch(typeof projectAttr) | |
2099 { | |
2100 case "number": | |
2101 case "boolean": | |
2102 eval('option.'+attributeName+' = '+projectAttr); | |
2103 break; | |
2104 case "string": | |
2105 eval('option.'+attributeName+' = "'+projectAttr+'"'); | |
2106 break; | |
2107 } | |
2108 } | |
2109 this.options.push(option); | |
2110 } | |
2111 | |
2112 // Now the scales nodes | |
2113 var scaleParent = xml.getElementsByTagName('scales'); | |
2114 if (scaleParent.length == 1) { | |
2115 scaleParent = scaleParent[0]; | |
2116 for (var i=0; i<scaleParent.children.length; i++) { | |
2117 var child = scaleParent.children[i]; | |
2118 this.scales.push({ | |
2119 text: child.textContent, | |
2120 position: Number(child.getAttribute('position')) | |
2121 }); | |
2122 } | |
2123 } | |
2124 }; | |
2125 | |
2126 this.encode = function(doc) { | |
2127 var node = doc.createElement("interface"); | |
2128 if (typeof name == "string") | |
2129 node.setAttribute("name",this.name); | |
2130 for (var option of this.options) | |
2131 { | |
2132 var child = doc.createElement("interfaceoption"); | |
2133 child.setAttribute("type",option.type); | |
2134 child.setAttribute("name",option.name); | |
2135 node.appendChild(child); | |
2136 } | |
2137 if (this.scales.length != 0) { | |
2138 var scales = doc.createElement("scales"); | |
2139 for (var scale of this.scales) | |
2140 { | |
2141 var child = doc.createElement("scalelabel"); | |
2142 child.setAttribute("position",scale.position); | |
2143 child.textContent = scale.text; | |
2144 scales.appendChild(child); | |
2145 } | |
2146 node.appendChild(scales); | |
2147 } | |
2148 return node; | |
2149 }; | |
2150 }; | |
2151 | |
2152 this.metricNode = function() { | |
2153 this.enabled = []; | |
2154 this.decode = function(parent, xml) { | |
2155 var children = xml.getElementsByTagName('metricenable'); | |
2156 for (var i in children) { | |
2157 if (isNaN(Number(i)) == true){break;} | |
2158 this.enabled.push(children[i].textContent); | |
2159 } | |
2160 } | |
2161 this.encode = function(doc) { | |
2162 var node = doc.createElement('metric'); | |
2163 for (var i in this.enabled) | |
2164 { | |
2165 if (isNaN(Number(i)) == true){break;} | |
2166 var child = doc.createElement('metricenable'); | |
2167 child.textContent = this.enabled[i]; | |
2168 node.appendChild(child); | |
2169 } | |
2170 return node; | |
2171 } | |
2172 } | |
2173 | |
2174 this.page = function() { | |
2175 this.presentedId = undefined; | |
2176 this.id = undefined; | |
2177 this.hostURL = undefined; | |
2178 this.randomiseOrder = undefined; | |
2179 this.loop = undefined; | |
2180 this.showElementComments = undefined; | |
2181 this.outsideReference = null; | |
2182 this.loudness = null; | |
2183 this.label = null; | |
2184 this.preTest = null; | |
2185 this.postTest = null; | |
2186 this.interfaces = []; | |
2187 this.commentBoxPrefix = "Comment on track"; | |
2188 this.audioElements = []; | |
2189 this.commentQuestions = []; | |
2190 this.schema = specification.schema.getAllElementsByName("page")[0]; | |
2191 | |
2192 this.decode = function(parent,xml) | |
2193 { | |
2194 var attributeMap = this.schema.getAllElementsByTagName('xs:attribute'); | |
2195 for (var i=0; i<attributeMap.length; i++) | |
2196 { | |
2197 var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref'); | |
2198 var projectAttr = xml.getAttribute(attributeName); | |
2199 projectAttr = parent.processAttribute(projectAttr,attributeMap[i]); | |
2200 switch(typeof projectAttr) | |
2201 { | |
2202 case "number": | |
2203 case "boolean": | |
2204 eval('this.'+attributeName+' = '+projectAttr); | |
2205 break; | |
2206 case "string": | |
2207 eval('this.'+attributeName+' = "'+projectAttr+'"'); | |
2208 break; | |
2209 } | |
2210 } | |
2211 | |
2212 // Get the Comment Box Prefix | |
2213 var CBP = xml.getElementsByTagName('commentboxprefix'); | |
2214 if (CBP.length != 0) { | |
2215 this.commentBoxPrefix = CBP[0].textContent; | |
2216 } | |
2217 | |
2218 // Now decode the interfaces | |
2219 var interfaceNode = xml.getElementsByTagName('interface'); | |
2220 for (var i=0; i<interfaceNode.length; i++) | |
2221 { | |
2222 var node = new parent.interfaceNode(); | |
2223 node.decode(this,interfaceNode[i],parent.schema.getAllElementsByName('interface')[1]); | |
2224 this.interfaces.push(node); | |
2225 } | |
2226 | |
2227 // Now process the survey node options | |
2228 var survey = xml.getElementsByTagName('survey'); | |
2229 var surveySchema = parent.schema.getAllElementsByName('survey')[0]; | |
2230 for (var i in survey) { | |
2231 if (isNaN(Number(i)) == true){break;} | |
2232 var location = survey[i].getAttribute('location'); | |
2233 if (location == 'pre' || location == 'before') | |
2234 { | |
2235 if (this.preTest != null){this.errors.push("Already a pre/before test survey defined! Ignoring second!!");} | |
2236 else { | |
2237 this.preTest = new parent.surveyNode(); | |
2238 this.preTest.decode(parent,survey[i],surveySchema); | |
2239 } | |
2240 } else if (location == 'post' || location == 'after') { | |
2241 if (this.postTest != null){this.errors.push("Already a post/after test survey defined! Ignoring second!!");} | |
2242 else { | |
2243 this.postTest = new parent.surveyNode(); | |
2244 this.postTest.decode(parent,survey[i],surveySchema); | |
2245 } | |
2246 } | |
2247 } | |
2248 | |
2249 // Now process the audioelement tags | |
2250 var audioElements = xml.getElementsByTagName('audioelement'); | |
2251 for (var i=0; i<audioElements.length; i++) | |
2252 { | |
2253 var node = new this.audioElementNode(); | |
2254 node.decode(this,audioElements[i]); | |
2255 this.audioElements.push(node); | |
2256 } | |
2257 | |
2258 // Now decode the commentquestions | |
2259 var commentQuestions = xml.getElementsByTagName('commentquestion'); | |
2260 for (var i=0; i<commentQuestions.length; i++) | |
2261 { | |
2262 var node = new this.commentQuestionNode(); | |
2263 node.decode(parent,commentQuestions[i]); | |
2264 this.commentQuestions.push(node); | |
2265 } | |
2266 }; | |
2267 | |
2268 this.encode = function(root) | |
2269 { | |
2270 var AHNode = root.createElement("page"); | |
2271 // First decode the attributes | |
2272 var attributes = this.schema.getAllElementsByTagName('xs:attribute'); | |
2273 for (var i=0; i<attributes.length; i++) | |
2274 { | |
2275 var name = attributes[i].getAttribute("name"); | |
2276 if (name == undefined) { | |
2277 name = attributes[i].getAttribute("ref"); | |
2278 } | |
2279 if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") | |
2280 { | |
2281 eval("AHNode.setAttribute('"+name+"',this."+name+")"); | |
2282 } | |
2283 } | |
2284 if(this.loudness != null) {AHNode.setAttribute("loudness",this.loudness);} | |
2285 // <commentboxprefix> | |
2286 var commentboxprefix = root.createElement("commentboxprefix"); | |
2287 commentboxprefix.textContent = this.commentBoxPrefix; | |
2288 AHNode.appendChild(commentboxprefix); | |
2289 | |
2290 for (var i=0; i<this.interfaces.length; i++) | |
2291 { | |
2292 AHNode.appendChild(this.interfaces[i].encode(root)); | |
2293 } | |
2294 | |
2295 for (var i=0; i<this.audioElements.length; i++) { | |
2296 AHNode.appendChild(this.audioElements[i].encode(root)); | |
2297 } | |
2298 // Create <CommentQuestion> | |
2299 for (var i=0; i<this.commentQuestions.length; i++) | |
2300 { | |
2301 AHNode.appendChild(this.commentQuestions[i].encode(root)); | |
2302 } | |
2303 | |
2304 AHNode.appendChild(this.preTest.encode(root)); | |
2305 AHNode.appendChild(this.postTest.encode(root)); | |
2306 return AHNode; | |
2307 }; | |
2308 | |
2309 this.commentQuestionNode = function() { | |
2310 this.id = null; | |
2311 this.name = undefined; | |
2312 this.type = undefined; | |
2313 this.options = []; | |
2314 this.statement = undefined; | |
2315 this.schema = specification.schema.getAllElementsByName('commentquestion')[0]; | |
2316 this.decode = function(parent,xml) | |
2317 { | |
2318 this.id = xml.id; | |
2319 this.name = xml.getAttribute('name'); | |
2320 this.type = xml.getAttribute('type'); | |
2321 this.statement = xml.getElementsByTagName('statement')[0].textContent; | |
2322 var optNodes = xml.getElementsByTagName('option'); | |
2323 for (var i=0; i<optNodes.length; i++) | |
2324 { | |
2325 var optNode = optNodes[i]; | |
2326 this.options.push({ | |
2327 name: optNode.getAttribute('name'), | |
2328 text: optNode.textContent | |
2329 }); | |
2330 } | |
2331 }; | |
2332 | |
2333 this.encode = function(root) | |
2334 { | |
2335 var node = root.createElement("commentquestion"); | |
2336 node.id = this.id; | |
2337 node.setAttribute("type",this.type); | |
2338 if (this.name != undefined){node.setAttribute("name",this.name);} | |
2339 var statement = root.createElement("statement"); | |
2340 statement.textContent = this.statement; | |
2341 node.appendChild(statement); | |
2342 for (var option of this.options) | |
2343 { | |
2344 var child = root.createElement("option"); | |
2345 child.setAttribute("name",option.name); | |
2346 child.textContent = option.text; | |
2347 node.appendChild(child); | |
2348 } | |
2349 return node; | |
2350 }; | |
2351 }; | |
2352 | |
2353 this.audioElementNode = function() { | |
2354 this.url = null; | |
2355 this.id = null; | |
2356 this.name = null; | |
2357 this.parent = null; | |
2358 this.type = null; | |
2359 this.marker = null; | |
2360 this.enforce = false; | |
2361 this.gain = 0.0; | |
2362 this.schema = specification.schema.getAllElementsByName('audioelement')[0];; | |
2363 this.parent = null; | |
2364 this.decode = function(parent,xml) | |
2365 { | |
2366 this.parent = parent; | |
2367 var attributeMap = this.schema.getAllElementsByTagName('xs:attribute'); | |
2368 for (var i=0; i<attributeMap.length; i++) | |
2369 { | |
2370 var attributeName = attributeMap[i].getAttribute('name') || attributeMap[i].getAttribute('ref'); | |
2371 var projectAttr = xml.getAttribute(attributeName); | |
2372 projectAttr = specification.processAttribute(projectAttr,attributeMap[i]); | |
2373 switch(typeof projectAttr) | |
2374 { | |
2375 case "number": | |
2376 case "boolean": | |
2377 eval('this.'+attributeName+' = '+projectAttr); | |
2378 break; | |
2379 case "string": | |
2380 eval('this.'+attributeName+' = "'+projectAttr+'"'); | |
2381 break; | |
2382 } | |
2383 } | |
2384 | |
2385 }; | |
2386 this.encode = function(root) | |
2387 { | |
2388 var AENode = root.createElement("audioelement"); | |
2389 var attributes = this.schema.getAllElementsByTagName('xs:attribute'); | |
2390 for (var i=0; i<attributes.length; i++) | |
2391 { | |
2392 var name = attributes[i].getAttribute("name"); | |
2393 if (name == undefined) { | |
2394 name = attributes[i].getAttribute("ref"); | |
2395 } | |
2396 if(eval("this."+name+" != undefined") || attributes[i].getAttribute("use") == "required") | |
2397 { | |
2398 eval("AENode.setAttribute('"+name+"',this."+name+")"); | |
2399 } | |
2400 } | |
2401 return AENode; | |
2402 }; | |
2403 }; | |
2404 }; | |
2405 } | |
2406 | 1794 |
2407 function Interface(specificationObject) { | 1795 function Interface(specificationObject) { |
2408 // This handles the bindings between the interface and the audioEngineContext; | 1796 // This handles the bindings between the interface and the audioEngineContext; |
2409 this.specification = specificationObject; | 1797 this.specification = specificationObject; |
2410 this.insertPoint = document.getElementById("topLevelBody"); | 1798 this.insertPoint = document.getElementById("topLevelBody"); |
2457 node.appendChild(vendor); | 1845 node.appendChild(vendor); |
2458 node.appendChild(userAgent); | 1846 node.appendChild(userAgent); |
2459 node.appendChild(screen); | 1847 node.appendChild(screen); |
2460 return node; | 1848 return node; |
2461 }; | 1849 }; |
1850 | |
1851 this.returnDateNode = function() | |
1852 { | |
1853 // Create an XML Node for the Date and Time a test was conducted | |
1854 // Structure is | |
1855 // <datetime> | |
1856 // <date year="##" month="##" day="##">DD/MM/YY</date> | |
1857 // <time hour="##" minute="##" sec="##">HH:MM:SS</time> | |
1858 // </datetime> | |
1859 var dateTime = new Date(); | |
1860 var hold = storage.document.createElement("datetime"); | |
1861 var date = storage.document.createElement("date"); | |
1862 var time = storage.document.createElement("time"); | |
1863 date.setAttribute('year',dateTime.getFullYear()); | |
1864 date.setAttribute('month',dateTime.getMonth()+1); | |
1865 date.setAttribute('day',dateTime.getDate()); | |
1866 time.setAttribute('hour',dateTime.getHours()); | |
1867 time.setAttribute('minute',dateTime.getMinutes()); | |
1868 time.setAttribute('secs',dateTime.getSeconds()); | |
1869 | |
1870 hold.appendChild(date); | |
1871 hold.appendChild(time); | |
1872 return hold; | |
1873 | |
1874 } | |
2462 | 1875 |
2463 this.commentBoxes = new function() { | 1876 this.commentBoxes = new function() { |
2464 this.boxes = []; | 1877 this.boxes = []; |
2465 this.injectPoint = null; | 1878 this.injectPoint = null; |
2466 this.elementCommentBox = function(audioObject) { | 1879 this.elementCommentBox = function(audioObject) { |
2826 | 2239 |
2827 this.deleteCommentQuestions = function() | 2240 this.deleteCommentQuestions = function() |
2828 { | 2241 { |
2829 this.commentQuestions = []; | 2242 this.commentQuestions = []; |
2830 }; | 2243 }; |
2244 | |
2245 this.outsideReferenceDOM = function(audioObject,index,inject) | |
2246 { | |
2247 this.parent = audioObject; | |
2248 this.outsideReferenceHolder = document.createElement('button'); | |
2249 this.outsideReferenceHolder.id = 'outside-reference'; | |
2250 this.outsideReferenceHolder.className = 'outside-reference'; | |
2251 this.outsideReferenceHolder.setAttribute('track-id',index); | |
2252 this.outsideReferenceHolder.textContent = "Play Reference"; | |
2253 this.outsideReferenceHolder.disabled = true; | |
2254 | |
2255 this.outsideReferenceHolder.onclick = function(event) | |
2256 { | |
2257 audioEngineContext.play(event.currentTarget.getAttribute('track-id')); | |
2258 }; | |
2259 inject.appendChild(this.outsideReferenceHolder); | |
2260 this.enable = function() | |
2261 { | |
2262 if (this.parent.state == 1) | |
2263 { | |
2264 this.outsideReferenceHolder.disabled = false; | |
2265 } | |
2266 }; | |
2267 this.updateLoading = function(progress) | |
2268 { | |
2269 if (progress != 100) | |
2270 { | |
2271 progress = String(progress); | |
2272 progress = progress.split('.')[0]; | |
2273 this.outsideReferenceHolder.textContent = progress+'%'; | |
2274 } else { | |
2275 this.outsideReferenceHolder.textContent = "Play Reference"; | |
2276 } | |
2277 }; | |
2278 this.startPlayback = function() | |
2279 { | |
2280 // Called when playback has begun | |
2281 $('.track-slider').removeClass('track-slider-playing'); | |
2282 $('.comment-div').removeClass('comment-box-playing'); | |
2283 this.outsideReferenceHolder.style.backgroundColor = "#FDD"; | |
2284 }; | |
2285 this.stopPlayback = function() | |
2286 { | |
2287 // Called when playback has stopped. This gets called even if playback never started! | |
2288 this.outsideReferenceHolder.style.backgroundColor = ""; | |
2289 }; | |
2290 this.exportXMLDOM = function(audioObject) | |
2291 { | |
2292 return null; | |
2293 }; | |
2294 this.getValue = function() | |
2295 { | |
2296 return 0; | |
2297 }; | |
2298 this.getPresentedId = function() | |
2299 { | |
2300 return 'Reference'; | |
2301 }; | |
2302 this.canMove = function() | |
2303 { | |
2304 return false; | |
2305 }; | |
2306 this.error = function() { | |
2307 // audioObject has an error!! | |
2308 this.outsideReferenceHolder.textContent = "Error"; | |
2309 this.outsideReferenceHolder.style.backgroundColor = "#F00"; | |
2310 } | |
2311 } | |
2831 | 2312 |
2832 this.playhead = new function() | 2313 this.playhead = new function() |
2833 { | 2314 { |
2834 this.object = document.createElement('div'); | 2315 this.object = document.createElement('div'); |
2835 this.object.className = 'playhead'; | 2316 this.object.className = 'playhead'; |
2973 this.object.appendChild(title); | 2454 this.object.appendChild(title); |
2974 | 2455 |
2975 this.object.appendChild(this.slider); | 2456 this.object.appendChild(this.slider); |
2976 this.object.appendChild(this.valueText); | 2457 this.object.appendChild(this.valueText); |
2977 } | 2458 } |
2459 | |
2460 this.calibrationModuleObject = null; | |
2461 this.calibrationModule = function() { | |
2462 // This creates an on-page calibration module | |
2463 this.storeDOM = storage.document.createElement("calibration"); | |
2464 storage.root.appendChild(this.storeDOM); | |
2465 // The calibration is a fixed state module | |
2466 this.calibrationNodes = []; | |
2467 this.holder = null; | |
2468 this.build = function(inject) { | |
2469 var f0 = 62.5; | |
2470 this.holder = document.createElement("div"); | |
2471 this.holder.className = "calibration-holder"; | |
2472 this.calibrationNodes = []; | |
2473 while(f0 < 20000) { | |
2474 var obj = { | |
2475 root: document.createElement("div"), | |
2476 input: document.createElement("input"), | |
2477 oscillator: audioContext.createOscillator(), | |
2478 gain: audioContext.createGain(), | |
2479 f: f0, | |
2480 parent: this, | |
2481 handleEvent: function(event) { | |
2482 switch(event.type) { | |
2483 case "mouseenter": | |
2484 this.oscillator.start(0); | |
2485 break; | |
2486 case "mouseleave": | |
2487 this.oscillator.stop(0); | |
2488 this.oscillator = audioContext.createOscillator(); | |
2489 this.oscillator.connect(this.gain); | |
2490 this.oscillator.frequency.value = this.f; | |
2491 break; | |
2492 case "mousemove": | |
2493 var value = Math.pow(10,this.input.value/20); | |
2494 if (this.f == 1000) { | |
2495 audioEngineContext.outputGain.gain.value = value; | |
2496 interfaceContext.volume.slider.value = this.input.value; | |
2497 } else { | |
2498 this.gain.gain.value = value | |
2499 } | |
2500 break; | |
2501 } | |
2502 }, | |
2503 disconnect: function() { | |
2504 this.gain.disconnect(); | |
2505 } | |
2506 } | |
2507 obj.root.className = "calibration-slider"; | |
2508 obj.root.appendChild(obj.input); | |
2509 obj.oscillator.connect(obj.gain); | |
2510 obj.gain.connect(audioEngineContext.outputGain); | |
2511 obj.gain.gain.value = Math.random()*2; | |
2512 obj.input.value = obj.gain.gain.value; | |
2513 obj.input.setAttribute('orient','vertical'); | |
2514 obj.input.type = "range"; | |
2515 obj.input.min = -6; | |
2516 obj.input.max = 6; | |
2517 obj.input.step = 0.25; | |
2518 if (f0 != 1000) { | |
2519 obj.input.value = (Math.random()*12)-6; | |
2520 } else { | |
2521 obj.input.value = 0; | |
2522 obj.root.style.backgroundColor="rgb(255,125,125)"; | |
2523 } | |
2524 obj.input.addEventListener("mousemove",obj); | |
2525 obj.input.addEventListener("mouseenter",obj); | |
2526 obj.input.addEventListener("mouseleave",obj); | |
2527 obj.gain.gain.value = Math.pow(10,obj.input.value/20); | |
2528 obj.oscillator.frequency.value = f0; | |
2529 this.calibrationNodes.push(obj); | |
2530 this.holder.appendChild(obj.root); | |
2531 f0 *= 2; | |
2532 } | |
2533 inject.appendChild(this.holder); | |
2534 } | |
2535 this.collect = function() { | |
2536 for (var obj of this.calibrationNodes) { | |
2537 var node = storage.document.createElement("calibrationresult"); | |
2538 node.setAttribute("frequency",obj.f); | |
2539 node.setAttribute("range-min",obj.input.min); | |
2540 node.setAttribute("range-max",obj.input.max); | |
2541 node.setAttribute("gain-lin",obj.gain.gain.value); | |
2542 this.storeDOM.appendChild(node); | |
2543 } | |
2544 } | |
2545 } | |
2546 | |
2547 | |
2978 // Global Checkers | 2548 // Global Checkers |
2979 // These functions will help enforce the checkers | 2549 // These functions will help enforce the checkers |
2980 this.checkHiddenAnchor = function() | 2550 this.checkHiddenAnchor = function() |
2981 { | 2551 { |
2982 for (var ao of audioEngineContext.audioObjects) | 2552 for (var ao of audioEngineContext.audioObjects) |
3156 this.SessionKey.generateKey(); | 2726 this.SessionKey.generateKey(); |
3157 this.document = document.implementation.createDocument(null,"waetresult"); | 2727 this.document = document.implementation.createDocument(null,"waetresult"); |
3158 this.root = this.document.childNodes[0]; | 2728 this.root = this.document.childNodes[0]; |
3159 var projectDocument = specification.projectXML; | 2729 var projectDocument = specification.projectXML; |
3160 projectDocument.setAttribute('file-name',url); | 2730 projectDocument.setAttribute('file-name',url); |
2731 projectDocument.setAttribute('url',qualifyURL(url)); | |
3161 this.root.appendChild(projectDocument); | 2732 this.root.appendChild(projectDocument); |
3162 this.root.appendChild(returnDateNode()); | 2733 this.root.appendChild(interfaceContext.returnDateNode()); |
3163 this.root.appendChild(interfaceContext.returnNavigator()); | 2734 this.root.appendChild(interfaceContext.returnNavigator()); |
3164 } else { | 2735 } else { |
3165 this.document = existingStore; | 2736 this.document = existingStore; |
3166 this.root = existingStore.children[0]; | 2737 this.root = existingStore.children[0]; |
3167 this.SessionKey.key = this.root.getAttribute("key"); | 2738 this.SessionKey.key = this.root.getAttribute("key"); |
3316 var aeNode = this.parent.document.createElement('audioelement'); | 2887 var aeNode = this.parent.document.createElement('audioelement'); |
3317 aeNode.setAttribute('ref',element.id); | 2888 aeNode.setAttribute('ref',element.id); |
3318 if (element.name != undefined){aeNode.setAttribute('name',element.name)}; | 2889 if (element.name != undefined){aeNode.setAttribute('name',element.name)}; |
3319 aeNode.setAttribute('type',element.type); | 2890 aeNode.setAttribute('type',element.type); |
3320 aeNode.setAttribute('url', element.url); | 2891 aeNode.setAttribute('url', element.url); |
2892 aeNode.setAttribute('fqurl',qualifyURL(element.url)); | |
3321 aeNode.setAttribute('gain', element.gain); | 2893 aeNode.setAttribute('gain', element.gain); |
3322 if (element.type == 'anchor' || element.type == 'reference') | 2894 if (element.type == 'anchor' || element.type == 'reference') |
3323 { | 2895 { |
3324 if (element.marker > 0) | 2896 if (element.marker > 0) |
3325 { | 2897 { |